From ceae29a41166ae524a4fc177b17f3922f3e16a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 4 Nov 2008 13:44:07 +0000 Subject: [PATCH 001/532] Avoid assigning a const char * to a char *. MFC after: 3 weeks --- lib/libutil/login_class.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c index 94cb3aa14e6..507451958d1 100644 --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -142,14 +142,13 @@ substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nle int tildes = 0; int dollas = 0; char *p; + const char *q; if (pwd != NULL) { - /* Count the number of ~'s in var to substitute */ - for (p = (char *)var; (p = strchr(p, '~')) != NULL; p++) - ++tildes; - /* Count the number of $'s in var to substitute */ - for (p = (char *)var; (p = strchr(p, '$')) != NULL; p++) - ++dollas; + for (q = var; *q != '\0'; ++q) { + tildes += (*q == '~'); + dollas += (*q == '$'); + } } np = malloc(strlen(var) + (dollas * nlen) From e37e92fe4cd3149b76061e7b880f462c8c028e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 4 Nov 2008 13:44:43 +0000 Subject: [PATCH 002/532] Avoid assigning a const char * to a char *. MFC after: 3 weeks --- lib/libutil/login_cap.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/libutil/login_cap.c b/lib/libutil/login_cap.c index 529ce822732..8fee76050b0 100644 --- a/lib/libutil/login_cap.c +++ b/lib/libutil/login_cap.c @@ -61,6 +61,8 @@ static char * internal_string = NULL; static size_t internal_arraysz = 0; static const char ** internal_array = NULL; +static char path_login_conf[] = _PATH_LOGIN_CONF; + static char * allocstr(const char *str) { @@ -215,15 +217,14 @@ login_getclassbyname(char const *name, const struct passwd *pwd) if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, _FILE_LOGIN_CONF) < MAXPATHLEN) { - login_dbarray[i] = userpath; if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) - i++; /* only use 'secure' data */ + login_dbarray[i++] = userpath; } /* * XXX: Why to add the system database if the class is `me'? */ - if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1) - login_dbarray[i++] = _PATH_LOGIN_CONF; + if (_secure_path(path_login_conf, 0, 0) != -1) + login_dbarray[i++] = path_login_conf; login_dbarray[i] = NULL; memset(lc, 0, sizeof(login_cap_t)); From 06927900e3ce8e03f2d01e69c5f047739eb421af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 4 Nov 2008 13:49:18 +0000 Subject: [PATCH 003/532] Committed to wrong branch. --- lib/libutil/login_cap.c | 9 ++++----- lib/libutil/login_class.c | 11 ++++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/libutil/login_cap.c b/lib/libutil/login_cap.c index 8fee76050b0..529ce822732 100644 --- a/lib/libutil/login_cap.c +++ b/lib/libutil/login_cap.c @@ -61,8 +61,6 @@ static char * internal_string = NULL; static size_t internal_arraysz = 0; static const char ** internal_array = NULL; -static char path_login_conf[] = _PATH_LOGIN_CONF; - static char * allocstr(const char *str) { @@ -217,14 +215,15 @@ login_getclassbyname(char const *name, const struct passwd *pwd) if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, _FILE_LOGIN_CONF) < MAXPATHLEN) { + login_dbarray[i] = userpath; if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) - login_dbarray[i++] = userpath; + i++; /* only use 'secure' data */ } /* * XXX: Why to add the system database if the class is `me'? */ - if (_secure_path(path_login_conf, 0, 0) != -1) - login_dbarray[i++] = path_login_conf; + if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1) + login_dbarray[i++] = _PATH_LOGIN_CONF; login_dbarray[i] = NULL; memset(lc, 0, sizeof(login_cap_t)); diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c index 507451958d1..94cb3aa14e6 100644 --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -142,13 +142,14 @@ substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nle int tildes = 0; int dollas = 0; char *p; - const char *q; if (pwd != NULL) { - for (q = var; *q != '\0'; ++q) { - tildes += (*q == '~'); - dollas += (*q == '$'); - } + /* Count the number of ~'s in var to substitute */ + for (p = (char *)var; (p = strchr(p, '~')) != NULL; p++) + ++tildes; + /* Count the number of $'s in var to substitute */ + for (p = (char *)var; (p = strchr(p, '$')) != NULL; p++) + ++dollas; } np = malloc(strlen(var) + (dollas * nlen) From ea234e656896e0185f838fa5be93dec0a241c98f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 4 Nov 2008 13:54:07 +0000 Subject: [PATCH 004/532] MFH (r184633, r184635): build at WARNS level 6 --- lib/libutil/Makefile | 2 ++ lib/libutil/login_cap.c | 9 +++++---- lib/libutil/login_class.c | 11 +++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index ce544c320a8..777f95e9a1e 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -15,6 +15,8 @@ SRCS= _secure_path.c auth.c gr_util.c expand_number.c flopen.c fparseln.c \ stub.c trimdomain.c uucplock.c INCS= libutil.h login_cap.h +WARNS?= 6 + CFLAGS+= -DLIBC_SCCS .if ${MK_INET6_SUPPORT} != "no" diff --git a/lib/libutil/login_cap.c b/lib/libutil/login_cap.c index 529ce822732..8fee76050b0 100644 --- a/lib/libutil/login_cap.c +++ b/lib/libutil/login_cap.c @@ -61,6 +61,8 @@ static char * internal_string = NULL; static size_t internal_arraysz = 0; static const char ** internal_array = NULL; +static char path_login_conf[] = _PATH_LOGIN_CONF; + static char * allocstr(const char *str) { @@ -215,15 +217,14 @@ login_getclassbyname(char const *name, const struct passwd *pwd) if (dir && snprintf(userpath, MAXPATHLEN, "%s/%s", dir, _FILE_LOGIN_CONF) < MAXPATHLEN) { - login_dbarray[i] = userpath; if (_secure_path(userpath, pwd->pw_uid, pwd->pw_gid) != -1) - i++; /* only use 'secure' data */ + login_dbarray[i++] = userpath; } /* * XXX: Why to add the system database if the class is `me'? */ - if (_secure_path(_PATH_LOGIN_CONF, 0, 0) != -1) - login_dbarray[i++] = _PATH_LOGIN_CONF; + if (_secure_path(path_login_conf, 0, 0) != -1) + login_dbarray[i++] = path_login_conf; login_dbarray[i] = NULL; memset(lc, 0, sizeof(login_cap_t)); diff --git a/lib/libutil/login_class.c b/lib/libutil/login_class.c index 94cb3aa14e6..507451958d1 100644 --- a/lib/libutil/login_class.c +++ b/lib/libutil/login_class.c @@ -142,14 +142,13 @@ substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nle int tildes = 0; int dollas = 0; char *p; + const char *q; if (pwd != NULL) { - /* Count the number of ~'s in var to substitute */ - for (p = (char *)var; (p = strchr(p, '~')) != NULL; p++) - ++tildes; - /* Count the number of $'s in var to substitute */ - for (p = (char *)var; (p = strchr(p, '$')) != NULL; p++) - ++dollas; + for (q = var; *q != '\0'; ++q) { + tildes += (*q == '~'); + dollas += (*q == '$'); + } } np = malloc(strlen(var) + (dollas * nlen) From 1b3515f39bcd2de8409fb54b2e4355553d016a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 30 Jan 2009 13:54:03 +0000 Subject: [PATCH 005/532] WIP --- lib/libutil/Makefile | 10 +- lib/libutil/libutil.h | 9 + lib/libutil/quotafile.3 | 69 +++++++ lib/libutil/quotafile.c | 272 ++++++++++++++++++++++++++ libexec/rpc.rquotad/Makefile | 4 +- libexec/rpc.rquotad/rquotad.c | 28 +-- sys/ufs/ufs/quota.h | 42 ++++- sys/ufs/ufs/ufs_quota.c | 346 +++++++++++++++++++++++++++++++--- sys/ufs/ufs/ufs_vfsops.c | 12 ++ sys/ufs/ufs/ufsmount.h | 1 + usr.sbin/edquota/Makefile | 3 + usr.sbin/edquota/edquota.c | 99 +++------- 12 files changed, 760 insertions(+), 135 deletions(-) create mode 100644 lib/libutil/quotafile.3 create mode 100644 lib/libutil/quotafile.c diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index 1ea4c73767d..178948d3a16 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -12,8 +12,8 @@ SRCS= _secure_path.c auth.c expand_number.c flopen.c fparseln.c gr_util.c \ hexdump.c humanize_number.c kinfo_getfile.c kinfo_getvmmap.c kld.c \ login.c login_auth.c login_cap.c \ login_class.c login_crypt.c login_ok.c login_times.c login_tty.c \ - logout.c logwtmp.c pidfile.c property.c pty.c pw_util.c realhostname.c \ - stub.c trimdomain.c uucplock.c + logout.c logwtmp.c pidfile.c property.c pty.c pw_util.c quotafile.c \ + realhostname.c stub.c trimdomain.c uucplock.c INCS= libutil.h login_cap.h WARNS?= 6 @@ -30,7 +30,7 @@ MAN+= kld.3 login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \ login_cap.3 login_class.3 login_times.3 login_ok.3 \ _secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \ realhostname_sa.3 trimdomain.3 fparseln.3 humanize_number.3 \ - pidfile.3 flopen.3 expand_number.3 + pidfile.3 flopen.3 expand_number.3 quotafile.3 MAN+= login.conf.5 auth.conf.5 MLINKS+= kld.3 kld_isloaded.3 kld.3 kld_load.3 MLINKS+= property.3 properties_read.3 property.3 properties_free.3 @@ -58,5 +58,9 @@ MLINKS+=pidfile.3 pidfile_open.3 \ pidfile.3 pidfile_write.3 \ pidfile.3 pidfile_close.3 \ pidfile.3 pidfile_remove.3 +MLINKS+=quotafile.3 quota_open.3 \ + quotafile.3 quota_read.3 \ + quotafile.3 quota_write.3 \ + quotafile.3 quota_close.3 .include diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index 3187fb37349..48ab2188c35 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -140,6 +140,15 @@ int pidfile_close(struct pidfh *pfh); int pidfile_remove(struct pidfh *pfh); #endif +#ifdef _UFS_UFS_QUOTA_H_ +struct quotafile; +struct quotafile *quota_open(const char *); +struct quotafile *quota_create(const char *); +void quota_close(struct quotafile *); +int quota_read(struct quotafile *, struct dqblk *, int); +int quota_write(struct quotafile *, const struct dqblk *, int); +#endif + __END_DECLS #define UU_LOCK_INUSE (1) diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 new file mode 100644 index 00000000000..a414a99a027 --- /dev/null +++ b/lib/libutil/quotafile.3 @@ -0,0 +1,69 @@ +.\"- +.\" Copyright (c) 2008 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. +.\" 2. Redistributions in binary form must 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 4, 2008 +.Dt QUOTAFILE 3 +.Os +.Sh NAME +.Nm quota_open +.Nm quota_create +.Nm quota_read +.Nm quota_write +.Nm quota_close +.Nd "Manipulate quota files" +.Sh LIBRARY +.Lb libutil +.Sh SYNOPSIS +.In ufs/ufs/quota.h +.In libutil.h +.Ft "struct quotafile *" +.Fn quota_open "const char *path" +.Ft "struct quotafile *" +.Fn quota_create "const char *path" +.Ft int +.Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int type" +.Ft int +.Fn quota_write "struct quotafile *qf" "const struct dqblk *dqb" "int type" +.Ft int +.Fn quota_close "struct quotafile *qf" +.Sh DESCRIPTION +.Sh RETURN VALUES +.Sh SEE ALSO +.Xr quotactl 2 , +.Xr quota.user 5 , +.Xr quota.group 5 +.Sh HISTORY +The +.Nm +functions first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +functions and this manual page were written by +.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org . diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c new file mode 100644 index 00000000000..a4258b1ef30 --- /dev/null +++ b/lib/libutil/quotafile.c @@ -0,0 +1,272 @@ +/*- + * Copyright (c) 2008 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. + * + * 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct quotafile { + int fd; + int type; /* 32 or 64 */ +}; + +struct quotafile * +quota_open(const char *fn) +{ + struct quotafile *qf; + struct dqhdr64 dqh; + int serrno; + + if ((qf = calloc(1, sizeof(*qf))) == NULL) + return (NULL); + if ((qf->fd = open(fn, O_RDWR)) < 0) { + serrno = errno; + free(qf); + errno = serrno; + return (NULL); + } + qf->type = 32; + switch (read(qf->fd, &dqh, sizeof(dqh))) { + case -1: + serrno = errno; + close(qf->fd); + free(qf); + errno = serrno; + return (NULL); + case sizeof(dqh): + if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) != 0) { + /* no magic, assume 32 bits */ + qf->type = 32; + return (qf); + } + if (be32toh(dqh.dqh_version) != Q_DQHDR64_VERSION || + be32toh(dqh.dqh_hdrlen) != sizeof(struct dqhdr64) || + be32toh(dqh.dqh_reclen) != sizeof(struct dqblk64)) { + /* correct magic, wrong version / lengths */ + close(qf->fd); + free(qf); + errno = EINVAL; + return (NULL); + } + qf->type = 64; + return (qf); + default: + qf->type = 32; + return (qf); + } + /* not reached */ +} + +struct quotafile * +quota_create(const char *fn) +{ + struct quotafile *qf; + struct dqhdr64 dqh; + struct group *grp; + int serrno; + + if ((qf = calloc(1, sizeof(*qf))) == NULL) + return (NULL); + if ((qf->fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) { + serrno = errno; + free(qf); + errno = serrno; + return (NULL); + } + qf->type = 64; + memset(&dqh, 0, sizeof(dqh)); + memcpy(dqh.dqh_magic, Q_DQHDR64_MAGIC, sizeof(dqh.dqh_magic)); + dqh.dqh_version = htobe32(Q_DQHDR64_VERSION); + dqh.dqh_hdrlen = htobe32(sizeof(struct dqhdr64)); + dqh.dqh_reclen = htobe32(sizeof(struct dqblk64)); + if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) { + serrno = errno; + unlink(fn); + close(qf->fd); + free(qf); + errno = serrno; + return (NULL); + } + grp = getgrnam(QUOTAGROUP); + fchown(qf->fd, 0, grp ? grp->gr_gid : 0); + fchmod(qf->fd, 0640); + return (qf); +} + +void +quota_close(struct quotafile *qf) +{ + + close(qf->fd); + free(qf); +} + +static int +quota_read32(struct quotafile *qf, struct dqblk *dqb, int id) +{ + struct dqblk32 dqb32; + off_t off; + + off = id * sizeof(struct dqblk32); + if (lseek(qf->fd, off, SEEK_SET) == -1) + return (-1); + switch (read(qf->fd, &dqb32, sizeof(dqb32))) { + case 0: + memset(&dqb, 0, sizeof(*dqb)); + return (0); + case sizeof(dqb32): + dqb->dqb_bhardlimit = dqb32.dqb_bhardlimit; + dqb->dqb_bsoftlimit = dqb32.dqb_bsoftlimit; + dqb->dqb_curblocks = dqb32.dqb_curblocks; + dqb->dqb_ihardlimit = dqb32.dqb_ihardlimit; + dqb->dqb_isoftlimit = dqb32.dqb_isoftlimit; + dqb->dqb_curinodes = dqb32.dqb_curinodes; + dqb->dqb_btime = dqb32.dqb_btime; + dqb->dqb_itime = dqb32.dqb_itime; + return (0); + default: + return (-1); + } +} + +static int +quota_read64(struct quotafile *qf, struct dqblk *dqb, int id) +{ + struct dqblk64 dqb64; + off_t off; + + off = sizeof(struct dqhdr64) + id * sizeof(struct dqblk64); + if (lseek(qf->fd, off, SEEK_SET) == -1) + return (-1); + switch (read(qf->fd, &dqb64, sizeof(dqb64))) { + case 0: + memset(&dqb, 0, sizeof(*dqb)); + return (0); + case sizeof(dqb64): + dqb->dqb_bhardlimit = be64toh(dqb64.dqb_bhardlimit); + dqb->dqb_bsoftlimit = be64toh(dqb64.dqb_bsoftlimit); + dqb->dqb_curblocks = be64toh(dqb64.dqb_curblocks); + dqb->dqb_ihardlimit = be64toh(dqb64.dqb_ihardlimit); + dqb->dqb_isoftlimit = be64toh(dqb64.dqb_isoftlimit); + dqb->dqb_curinodes = be64toh(dqb64.dqb_curinodes); + dqb->dqb_btime = be64toh(dqb64.dqb_btime); + dqb->dqb_itime = be64toh(dqb64.dqb_itime); + return (0); + default: + return (-1); + } +} + +int +quota_read(struct quotafile *qf, struct dqblk *dqb, int id) +{ + + switch (qf->type) { + case 32: + return quota_read32(qf, dqb, id); + case 64: + return quota_read64(qf, dqb, id); + default: + errno = EINVAL; + return (-1); + } + /* not reached */ +} + +#define CLIP32(u64) ((u64) > UINT32_MAX ? UINT32_MAX : (uint32_t)(u64)) + +static int +quota_write32(struct quotafile *qf, const struct dqblk *dqb, int id) +{ + struct dqblk32 dqb32; + off_t off; + + dqb32.dqb_bhardlimit = CLIP32(dqb->dqb_bhardlimit); + dqb32.dqb_bsoftlimit = CLIP32(dqb->dqb_bsoftlimit); + dqb32.dqb_curblocks = CLIP32(dqb->dqb_curblocks); + dqb32.dqb_ihardlimit = CLIP32(dqb->dqb_ihardlimit); + dqb32.dqb_isoftlimit = CLIP32(dqb->dqb_isoftlimit); + dqb32.dqb_curinodes = CLIP32(dqb->dqb_curinodes); + dqb32.dqb_btime = CLIP32(dqb->dqb_btime); + dqb32.dqb_itime = CLIP32(dqb->dqb_itime); + + off = id * sizeof(struct dqblk32); + if (lseek(qf->fd, off, SEEK_SET) == -1) + return (-1); + return (write(qf->fd, &dqb32, sizeof(dqb32))); +} + +static int +quota_write64(struct quotafile *qf, const struct dqblk *dqb, int id) +{ + struct dqblk64 dqb64; + off_t off; + + dqb64.dqb_bhardlimit = htobe64(dqb->dqb_bhardlimit); + dqb64.dqb_bsoftlimit = htobe64(dqb->dqb_bsoftlimit); + dqb64.dqb_curblocks = htobe64(dqb->dqb_curblocks); + dqb64.dqb_ihardlimit = htobe64(dqb->dqb_ihardlimit); + dqb64.dqb_isoftlimit = htobe64(dqb->dqb_isoftlimit); + dqb64.dqb_curinodes = htobe64(dqb->dqb_curinodes); + dqb64.dqb_btime = htobe64(dqb->dqb_btime); + dqb64.dqb_itime = htobe64(dqb->dqb_itime); + + off = sizeof(struct dqhdr64) + id * sizeof(struct dqblk64); + if (lseek(qf->fd, off, SEEK_SET) == -1) + return (-1); + return (write(qf->fd, &dqb64, sizeof(dqb64))); +} + +int +quota_write(struct quotafile *qf, const struct dqblk *dqb, int id) +{ + + switch (qf->type) { + case 32: + return quota_write32(qf, dqb, id); + case 64: + return quota_write64(qf, dqb, id); + default: + errno = EINVAL; + return (-1); + } + /* not reached */ +} diff --git a/libexec/rpc.rquotad/Makefile b/libexec/rpc.rquotad/Makefile index feacce57ef4..fb3f38bc90c 100644 --- a/libexec/rpc.rquotad/Makefile +++ b/libexec/rpc.rquotad/Makefile @@ -6,7 +6,7 @@ MAN = rpc.rquotad.8 WARNS ?= 6 -DPADD= ${LIBRPCSVC} -LDADD= -lrpcsvc +DPADD= ${LIBRPCSVC} ${LIBUTIL} +LDADD= -lrpcsvc -lutil .include diff --git a/libexec/rpc.rquotad/rquotad.c b/libexec/rpc.rquotad/rquotad.c index 559a57a1f33..63bb0c76be6 100644 --- a/libexec/rpc.rquotad/rquotad.c +++ b/libexec/rpc.rquotad/rquotad.c @@ -23,6 +23,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -247,9 +248,10 @@ initfs(void) int getfsquota(long id, char *path, struct dqblk *dqblk) { + struct quotafile *qf; struct stat st_path; struct fs_stat *fs; - int qcmd, fd, ret = 0; + int qcmd, ret = 0; if (stat(path, &st_path) < 0) return (0); @@ -265,32 +267,16 @@ getfsquota(long id, char *path, struct dqblk *dqblk) if (quotactl(fs->fs_file, qcmd, id, dqblk) == 0) return (1); - if ((fd = open(fs->qfpathname, O_RDONLY)) < 0) { + if ((qf = quota_open(fs->qfpathname)) == NULL) { syslog(LOG_ERR, "open error: %s: %m", fs->qfpathname); return (0); } - if (lseek(fd, (off_t)(id * sizeof(struct dqblk)), L_SET) == (off_t)-1) { - close(fd); - return (1); - } - switch (read(fd, dqblk, sizeof(struct dqblk))) { - case 0: - /* - * Convert implicit 0 quota (EOF) - * into an explicit one (zero'ed dqblk) - */ - bzero(dqblk, sizeof(struct dqblk)); - ret = 1; - break; - case sizeof(struct dqblk): /* OK */ - ret = 1; - break; - default: /* ERROR */ + if (quota_read(qf, dqblk, id) != 0) { syslog(LOG_ERR, "read error: %s: %m", fs->qfpathname); - close(fd); + quota_close(qf); return (0); } - close(fd); + quota_close(qf); } return (ret); } diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h index 28f4e92d8fc..82b0170b036 100644 --- a/sys/ufs/ufs/quota.h +++ b/sys/ufs/ufs/quota.h @@ -81,10 +81,13 @@ #define Q_QUOTAON 0x0100 /* enable quotas */ #define Q_QUOTAOFF 0x0200 /* disable quotas */ -#define Q_GETQUOTA 0x0300 /* get limits and usage */ -#define Q_SETQUOTA 0x0400 /* set limits and usage */ -#define Q_SETUSE 0x0500 /* set usage */ +#define Q_GETQUOTA32 0x0300 /* get limits and usage (32-bit version) */ +#define Q_SETQUOTA32 0x0400 /* set limits and usage (32-bit version) */ +#define Q_SETUSE32 0x0500 /* set usage (32-bit version) */ #define Q_SYNC 0x0600 /* sync disk copy of a filesystems quotas */ +#define Q_GETQUOTA 0x0700 /* get limits and usage (64-bit version) */ +#define Q_SETQUOTA 0x0800 /* set limits and usage (64-bit version) */ +#define Q_SETUSE 0x0900 /* set usage (64-bit version) */ /* * The following structure defines the format of the disk quota file @@ -93,7 +96,7 @@ * the vnode for each quota file (a pointer is retained in the ufsmount * structure). */ -struct dqblk { +struct dqblk32 { u_int32_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ u_int32_t dqb_bsoftlimit; /* preferred limit on disk blks */ u_int32_t dqb_curblocks; /* current block count */ @@ -104,6 +107,30 @@ struct dqblk { int32_t dqb_itime; /* time limit for excessive files */ }; +struct dqblk64 { + u_int64_t dqb_bhardlimit; /* absolute limit on disk blks alloc */ + u_int64_t dqb_bsoftlimit; /* preferred limit on disk blks */ + u_int64_t dqb_curblocks; /* current block count */ + u_int64_t dqb_ihardlimit; /* maximum # allocated inodes + 1 */ + u_int64_t dqb_isoftlimit; /* preferred inode limit */ + u_int64_t dqb_curinodes; /* current # allocated inodes */ + int64_t dqb_btime; /* time limit for excessive disk use */ + int64_t dqb_itime; /* time limit for excessive files */ +}; + +#define dqblk dqblk64 + +#define Q_DQHDR64_MAGIC "QUOTA64" +#define Q_DQHDR64_VERSION 0x20081104 + +struct dqhdr64 { + char dqh_magic[8]; /* Q_DQHDR64_MAGIC */ + uint32_t dqh_version; /* Q_DQHDR64_VERSION */ + uint32_t dqh_hdrlen; /* header length */ + uint32_t dqh_reclen; /* record length */ + char dqh_unused[44]; /* reserved for future extension */ +}; + #ifdef _KERNEL #include @@ -125,7 +152,7 @@ struct dquot { u_int32_t dq_id; /* identifier this applies to */ struct ufsmount *dq_ump; /* (h) filesystem that this is taken from */ - struct dqblk dq_dqb; /* actual usage & quotas */ + struct dqblk64 dq_dqb; /* actual usage & quotas */ }; /* * Flag values. @@ -199,10 +226,13 @@ void dqinit(void); void dqrele(struct vnode *, struct dquot *); void dquninit(void); int getinoquota(struct inode *); -int getquota(struct thread *, struct mount *, u_long, int, void *); int qsync(struct mount *mp); int quotaoff(struct thread *td, struct mount *, int); int quotaon(struct thread *td, struct mount *, int, void *); +int getquota32(struct thread *, struct mount *, u_long, int, void *); +int setquota32(struct thread *, struct mount *, u_long, int, void *); +int setuse32(struct thread *, struct mount *, u_long, int, void *); +int getquota(struct thread *, struct mount *, u_long, int, void *); int setquota(struct thread *, struct mount *, u_long, int, void *); int setuse(struct thread *, struct mount *, u_long, int, void *); vfs_quotactl_t ufs_quotactl; diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index e5cb9562500..2adf7ef8fd7 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -73,6 +74,7 @@ static char *quotatypes[] = INITQFNAMES; static int chkdqchg(struct inode *, ufs2_daddr_t, struct ucred *, int, int *); static int chkiqchg(struct inode *, int, struct ucred *, int, int *); +static int dqopen(struct vnode *, struct ufsmount *, int); static int dqget(struct vnode *, u_long, struct ufsmount *, int, struct dquot **); static int dqsync(struct vnode *, struct dquot *); @@ -80,6 +82,14 @@ static void dqflush(struct vnode *); static int quotaoff1(struct thread *td, struct mount *mp, int type); static int quotaoff_inchange(struct thread *td, struct mount *mp, int type); +/* conversion functions - from_to() */ +static void dqb32_dq(const struct dqblk32 *, struct dquot *); +static void dqb64_dq(const struct dqblk64 *, struct dquot *); +static void dq_dqb32(const struct dquot *, struct dqblk32 *); +static void dq_dqb64(const struct dquot *, struct dqblk64 *); +static void dqb32_dqb64(const struct dqblk32 *, struct dqblk64 *); +static void dqb64_dqb32(const struct dqblk64 *, struct dqblk32 *); + #ifdef DIAGNOSTIC static void dqref(struct dquot *); static void chkdquot(struct inode *); @@ -90,7 +100,7 @@ static void chkdquot(struct inode *); * * This routine completely defines the semantics of quotas. * If other criterion want to be used to establish quotas, the - * MAXQUOTAS value in quotas.h should be increased, and the + * MAXQUOTAS value in quota.h should be increased, and the * additional dquots set up here. */ int @@ -522,6 +532,13 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname) return (EALREADY); } ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING; + if ((error = dqopen(vp, ump, type)) != 0) { + ump->um_qflags[type] &= ~(QTF_OPENING|QTF_CLOSING); + UFS_UNLOCK(ump); + (void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td); + VFS_UNLOCK_GIANT(vfslocked); + return (error); + } MNT_ILOCK(mp); mp->mnt_flag |= MNT_QUOTA; MNT_IUNLOCK(mp); @@ -734,8 +751,9 @@ quotaoff(struct thread *td, struct mount *mp, int type) /* * Q_GETQUOTA - return current values in a dqblk structure. */ -int -getquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +static int +_getquota(struct thread *td, struct mount *mp, u_long id, int type, + struct dqblk64 *dqb) { struct dquot *dq; int error; @@ -766,7 +784,7 @@ getquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) error = dqget(NULLVP, id, VFSTOUFS(mp), type, &dq); if (error) return (error); - error = copyout(&dq->dq_dqb, addr, sizeof (struct dqblk)); + *dqb = dq->dq_dqb; dqrele(NULLVP, dq); return (error); } @@ -774,23 +792,21 @@ getquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) /* * Q_SETQUOTA - assign an entire dqblk structure. */ -int -setquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +static int +_setquota(struct thread *td, struct mount *mp, u_long id, int type, + struct dqblk64 *dqb) { struct dquot *dq; struct dquot *ndq; struct ufsmount *ump; - struct dqblk newlim; + struct dqblk64 newlim; int error; error = priv_check(td, PRIV_VFS_SETQUOTA); if (error) return (error); - ump = VFSTOUFS(mp); - error = copyin(addr, &newlim, sizeof (struct dqblk)); - if (error) - return (error); + newlim = *dqb; ndq = NODQUOT; ump = VFSTOUFS(mp); @@ -839,23 +855,21 @@ setquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) /* * Q_SETUSE - set current inode and block usage. */ -int -setuse(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +static int +_setuse(struct thread *td, struct mount *mp, u_long id, int type, + struct dqblk64 *dqb) { struct dquot *dq; struct ufsmount *ump; struct dquot *ndq; - struct dqblk usage; + struct dqblk64 usage; int error; error = priv_check(td, PRIV_UFS_SETUSE); if (error) return (error); - ump = VFSTOUFS(mp); - error = copyin(addr, &usage, sizeof (struct dqblk)); - if (error) - return (error); + usage = *dqb; ump = VFSTOUFS(mp); ndq = NODQUOT; @@ -888,6 +902,90 @@ setuse(struct thread *td, struct mount *mp, u_long id, int type, void *addr) return (0); } +int +getquota32(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +{ + struct dqblk32 dqb32; + struct dqblk64 dqb64; + int error; + + error = _getquota(td, mp, id, type, &dqb64); + if (error) + return (error); + dqb64_dqb32(&dqb64, &dqb32); + error = copyout(&dqb32, addr, sizeof(dqb32)); + return (error); +} + +int +setquota32(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +{ + struct dqblk32 dqb32; + struct dqblk64 dqb64; + int error; + + error = copyin(addr, &dqb32, sizeof(dqb32)); + if (error) + return (error); + dqb32_dqb64(&dqb32, &dqb64); + error = _setquota(td, mp, id, type, &dqb64); + return (error); +} + +int +setuse32(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +{ + struct dqblk32 dqb32; + struct dqblk64 dqb64; + int error; + + error = copyin(addr, &dqb32, sizeof(dqb32)); + if (error) + return (error); + dqb32_dqb64(&dqb32, &dqb64); + error = _setuse(td, mp, id, type, &dqb64); + return (error); +} + +int +getquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +{ + struct dqblk64 dqb64; + int error; + + error = _getquota(td, mp, id, type, &dqb64); + if (error) + return (error); + error = copyout(&dqb64, addr, sizeof(dqb64)); + return (error); +} + +int +setquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +{ + struct dqblk64 dqb64; + int error; + + error = copyin(addr, &dqb64, sizeof(dqb64)); + if (error) + return (error); + error = _setquota(td, mp, id, type, &dqb64); + return (error); +} + +int +setuse(struct thread *td, struct mount *mp, u_long id, int type, void *addr) +{ + struct dqblk64 dqb64; + int error; + + error = copyin(addr, &dqb64, sizeof(dqb64)); + if (error) + return (error); + error = _setuse(td, mp, id, type, &dqb64); + return (error); +} + /* * Q_SYNC - sync quota files to disk. */ @@ -1024,6 +1122,47 @@ dqhashfind(struct dqhash *dqh, u_long id, struct vnode *dqvp) return (NODQUOT); } +/* + * Determine the quota file type. + */ +static int +dqopen(struct vnode *vp, struct ufsmount *ump, int type) +{ + struct dqhdr64 dqh; + struct iovec aiov; + struct uio auio; + int error, vfslocked; + + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + aiov.iov_base = &dqh; + aiov.iov_len = sizeof(dqh); + auio.uio_resid = sizeof(dqh); + auio.uio_offset = 0; + auio.uio_segflg = UIO_SYSSPACE; + auio.uio_rw = UIO_READ; + auio.uio_td = (struct thread *)0; + vfslocked = VFS_LOCK_GIANT(vp->v_mount); + error = VOP_READ(vp, &auio, 0, ump->um_cred[type]); + VFS_UNLOCK_GIANT(vfslocked); + + if (error != 0) + return (error); + if (auio.uio_resid > 0) { + /* assume 32 bits */ + return (0); + } + + if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) == 0 && + be32toh(dqh.dqh_version) == Q_DQHDR64_VERSION && + be32toh(dqh.dqh_hdrlen) == (uint32_t)sizeof(struct dqhdr64) && + be32toh(dqh.dqh_reclen) == (uint32_t)sizeof(struct dqblk64)) + ump->um_qflags[type] |= QTF_64BIT; + /* XXX: what if the magic matches, but the sizes are wrong? */ + + return (0); +} + /* * Obtain a dquot structure for the specified identifier and quota file * reading the information from the file if necessary. @@ -1032,6 +1171,8 @@ static int dqget(struct vnode *vp, u_long id, struct ufsmount *ump, int type, struct dquot **dqp) { + uint8_t buf[sizeof(struct dqblk64)]; + off_t base, recsize; struct dquot *dq, *dq1; struct dqhash *dqh; struct vnode *dqvp; @@ -1121,8 +1262,7 @@ hfound: DQI_LOCK(dq); if (numdquot < desireddquot) { numdquot++; DQH_UNLOCK(); - dq1 = (struct dquot *)malloc(sizeof *dq, M_DQUOT, - M_WAITOK | M_ZERO); + dq1 = malloc(sizeof *dq1, M_DQUOT, M_WAITOK | M_ZERO); mtx_init(&dq1->dq_lock, "dqlock", NULL, MTX_DEF); DQH_LOCK(); /* @@ -1169,20 +1309,52 @@ hfound: DQI_LOCK(dq); DQREF(dq); DQH_UNLOCK(); + /* + * Read the requested quota record from the quota file, performing + * any necessary conversions. + * + * The record's offset within the file depends on the size of the + * record, which means we need to know whether it's a 32-bit file + * or a 64-bit file. + * + * Luckily, root's record is always at offset 0, and most of it is + * unused, so we can use it to store a magic number indicating the + * file format. Due to an acute lack of imagination, this magic + * number, stored in the first byte of root's record and hence the + * first byte of the file, is 64. + * + * Another lucky break is that quotaon() always loads root's + * record, to get the default values for dq_btime and dq_itime, so + * we will always have a chance to check the file format before + * being asked for a "real" record. + */ + if (id == 0 || (ump->um_qflags[type] & QTF_64BIT)) { + recsize = sizeof(struct dqblk64); + base = sizeof(struct dqhdr64); + } else { + recsize = sizeof(struct dqblk32); + base = 0; + } auio.uio_iov = &aiov; auio.uio_iovcnt = 1; - aiov.iov_base = &dq->dq_dqb; - aiov.iov_len = sizeof (struct dqblk); - auio.uio_resid = sizeof (struct dqblk); - auio.uio_offset = (off_t)id * sizeof (struct dqblk); + aiov.iov_base = buf; + aiov.iov_len = recsize; + auio.uio_resid = recsize; + auio.uio_offset = base + id * recsize; auio.uio_segflg = UIO_SYSSPACE; auio.uio_rw = UIO_READ; auio.uio_td = (struct thread *)0; vfslocked = VFS_LOCK_GIANT(dqvp->v_mount); error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]); - if (auio.uio_resid == sizeof(struct dqblk) && error == 0) - bzero(&dq->dq_dqb, sizeof(struct dqblk)); + if (auio.uio_resid == recsize && error == 0) { + bzero(&dq->dq_dqb, sizeof(dq->dq_dqb)); + } else { + if (ump->um_qflags[type] & QTF_64BIT) + dqb64_dq((struct dqblk64 *)buf, dq); + else + dqb32_dq((struct dqblk32 *)buf, dq); + } if (dqvplocked) vput(dqvp); else @@ -1281,6 +1453,8 @@ dqrele(struct vnode *vp, struct dquot *dq) static int dqsync(struct vnode *vp, struct dquot *dq) { + uint8_t buf[sizeof(struct dqblk64)]; + off_t base, recsize; struct vnode *dqvp; struct iovec aiov; struct uio auio; @@ -1327,12 +1501,26 @@ dqsync(struct vnode *vp, struct dquot *dq) dq->dq_flags |= DQ_LOCK; DQI_UNLOCK(dq); + /* + * Write the quota record to the quota file, performing any + * necessary conversions. See dqget() for additional details. + */ + if (ump->um_qflags[dq->dq_type] & QTF_64BIT) { + dq_dqb64(dq, (struct dqblk64 *)buf); + recsize = sizeof(struct dqblk64); + base = sizeof(struct dqhdr64); + } else { + dq_dqb32(dq, (struct dqblk32 *)buf); + recsize = sizeof(struct dqblk32); + base = 0; + } + auio.uio_iov = &aiov; auio.uio_iovcnt = 1; - aiov.iov_base = &dq->dq_dqb; - aiov.iov_len = sizeof (struct dqblk); - auio.uio_resid = sizeof (struct dqblk); - auio.uio_offset = (off_t)dq->dq_id * sizeof (struct dqblk); + aiov.iov_base = buf; + aiov.iov_len = recsize; + auio.uio_resid = recsize; + auio.uio_offset = base + dq->dq_id * recsize; auio.uio_segflg = UIO_SYSSPACE; auio.uio_rw = UIO_WRITE; auio.uio_td = (struct thread *)0; @@ -1345,7 +1533,8 @@ dqsync(struct vnode *vp, struct dquot *dq) DQI_LOCK(dq); DQI_WAKEUP(dq); dq->dq_flags &= ~DQ_MOD; -out: DQI_UNLOCK(dq); +out: + DQI_UNLOCK(dq); vfslocked = VFS_LOCK_GIANT(dqvp->v_mount); if (vp != dqvp) vput(dqvp); @@ -1384,3 +1573,98 @@ dqflush(struct vnode *vp) } DQH_UNLOCK(); } + +/* + * 32-bit / 64-bit conversion functions. + * + * 32-bit quota records are stored in native byte order. Attention must + * be paid to overflow issues. + * + * 64-bit quota records are stored in network byte order. + */ + +#define CLIP32(u64) (u64 > UINT32_MAX ? UINT32_MAX : (uint32_t)u64) + +static void +dqb32_dq(const struct dqblk32 *dqb32, struct dquot *dq) +{ + + dq->dq_bhardlimit = dqb32->dqb_bhardlimit; + dq->dq_bsoftlimit = dqb32->dqb_bsoftlimit; + dq->dq_curblocks = dqb32->dqb_curblocks; + dq->dq_ihardlimit = dqb32->dqb_ihardlimit; + dq->dq_isoftlimit = dqb32->dqb_isoftlimit; + dq->dq_curinodes = dqb32->dqb_curinodes; + dq->dq_btime = dqb32->dqb_btime; + dq->dq_itime = dqb32->dqb_itime; +} + +static void +dqb64_dq(const struct dqblk64 *dqb64, struct dquot *dq) +{ + + dq->dq_bhardlimit = be64toh(dqb64->dqb_bhardlimit); + dq->dq_bsoftlimit = be64toh(dqb64->dqb_bsoftlimit); + dq->dq_curblocks = be64toh(dqb64->dqb_curblocks); + dq->dq_ihardlimit = be64toh(dqb64->dqb_ihardlimit); + dq->dq_isoftlimit = be64toh(dqb64->dqb_isoftlimit); + dq->dq_curinodes = be64toh(dqb64->dqb_curinodes); + dq->dq_btime = be64toh(dqb64->dqb_btime); + dq->dq_itime = be64toh(dqb64->dqb_itime); +} + +static void +dq_dqb32(const struct dquot *dq, struct dqblk32 *dqb32) +{ + + dqb32->dqb_bhardlimit = CLIP32(dq->dq_bhardlimit); + dqb32->dqb_bsoftlimit = CLIP32(dq->dq_bsoftlimit); + dqb32->dqb_curblocks = CLIP32(dq->dq_curblocks); + dqb32->dqb_ihardlimit = CLIP32(dq->dq_ihardlimit); + dqb32->dqb_isoftlimit = CLIP32(dq->dq_isoftlimit); + dqb32->dqb_curinodes = CLIP32(dq->dq_curinodes); + dqb32->dqb_btime = CLIP32(dq->dq_btime); + dqb32->dqb_itime = CLIP32(dq->dq_itime); +} + +static void +dq_dqb64(const struct dquot *dq, struct dqblk64 *dqb64) +{ + + dqb64->dqb_bhardlimit = htobe64(dq->dq_bhardlimit); + dqb64->dqb_bsoftlimit = htobe64(dq->dq_bsoftlimit); + dqb64->dqb_curblocks = htobe64(dq->dq_curblocks); + dqb64->dqb_ihardlimit = htobe64(dq->dq_ihardlimit); + dqb64->dqb_isoftlimit = htobe64(dq->dq_isoftlimit); + dqb64->dqb_curinodes = htobe64(dq->dq_curinodes); + dqb64->dqb_btime = htobe64(dq->dq_btime); + dqb64->dqb_itime = htobe64(dq->dq_itime); +} + +static void +dqb64_dqb32(const struct dqblk64 *dqb64, struct dqblk32 *dqb32) +{ + + dqb32->dqb_bhardlimit = CLIP32(dqb64->dqb_bhardlimit); + dqb32->dqb_bsoftlimit = CLIP32(dqb64->dqb_bsoftlimit); + dqb32->dqb_curblocks = CLIP32(dqb64->dqb_curblocks); + dqb32->dqb_ihardlimit = CLIP32(dqb64->dqb_ihardlimit); + dqb32->dqb_isoftlimit = CLIP32(dqb64->dqb_isoftlimit); + dqb32->dqb_curinodes = CLIP32(dqb64->dqb_curinodes); + dqb32->dqb_btime = CLIP32(dqb64->dqb_btime); + dqb32->dqb_itime = CLIP32(dqb64->dqb_itime); +} + +static void +dqb32_dqb64(const struct dqblk32 *dqb32, struct dqblk64 *dqb64) +{ + + dqb64->dqb_bhardlimit = dqb32->dqb_bhardlimit; + dqb64->dqb_bsoftlimit = dqb32->dqb_bsoftlimit; + dqb64->dqb_curblocks = dqb32->dqb_curblocks; + dqb64->dqb_ihardlimit = dqb32->dqb_ihardlimit; + dqb64->dqb_isoftlimit = dqb32->dqb_isoftlimit; + dqb64->dqb_curinodes = dqb32->dqb_curinodes; + dqb64->dqb_btime = dqb32->dqb_btime; + dqb64->dqb_itime = dqb32->dqb_itime; +} diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 14ce4c6b033..2ddde018f1a 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -130,6 +130,18 @@ ufs_quotactl(mp, cmds, id, arg, td) error = quotaoff(td, mp, type); break; + case Q_SETQUOTA32: + error = setquota32(td, mp, id, type, arg); + break; + + case Q_SETUSE32: + error = setuse32(td, mp, id, type, arg); + break; + + case Q_GETQUOTA32: + error = getquota32(td, mp, id, type, arg); + break; + case Q_SETQUOTA: error = setquota(td, mp, id, type, arg); break; diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h index 126867baa2e..83f9af06b59 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -120,6 +120,7 @@ struct ufsmount { */ #define QTF_OPENING 0x01 /* Q_QUOTAON in progress */ #define QTF_CLOSING 0x02 /* Q_QUOTAOFF in progress */ +#define QTF_64BIT 0x04 /* 64-bit quota file */ /* Convert mount ptr to ufsmount ptr. */ #define VFSTOUFS(mp) ((struct ufsmount *)((mp)->mnt_data)) diff --git a/usr.sbin/edquota/Makefile b/usr.sbin/edquota/Makefile index e5a3b12559a..82794925397 100644 --- a/usr.sbin/edquota/Makefile +++ b/usr.sbin/edquota/Makefile @@ -6,4 +6,7 @@ MAN= edquota.8 WARNS?= 4 +DPADD= ${LIBUTIL} +LDADD= -lutil + .include diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index f38fa77b39e..76baa0417fa 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -55,17 +55,21 @@ __FBSDID("$FreeBSD$"); #include #include #include + #include #include #include #include #include +#include +#include #include #include #include #include #include #include + #include "pathnames.h" const char *qfname = QUOTAFILENAME; @@ -102,11 +106,11 @@ main(int argc, char *argv[]) { struct quotause *qup, *protoprivs, *curprivs; long id, protoid; - long long lim; + uintmax_t lim; int i, quotatype, range, tmpfd; uid_t startuid, enduid; - u_int32_t *limp; - char *protoname, *cp, *oldoptarg; + u_int64_t *limp; + char *protoname, *cp, *oldoptarg, *end; int eflag = 0, tflag = 0, pflag = 0, ch; char *fspath = NULL; char buf[MAXLOGNAME]; @@ -172,11 +176,10 @@ main(int argc, char *argv[]) break; /* XXX: report an error */ } if (limp != NULL) { - lim = strtoll(cp, NULL, 10); - if (lim < 0 || lim > UINT_MAX) - errx(1, "invalid limit value: " - "%lld", lim); - *limp = (u_int32_t)lim; + lim = strtoumax(cp, &end, 10); + if (end == cp || *end != '\0' || lim > UINT64_MAX) + errx(1, "invalid limit: %s", cp); + *limp = (u_int64_t)lim; } } qup->dqblk.dqb_bsoftlimit = @@ -331,10 +334,11 @@ getentry(const char *name, int quotatype) struct quotause * getprivs(long id, int quotatype, char *fspath) { + struct quotafile *qf; struct fstab *fs; struct quotause *qup, *quptail; struct quotause *quphead; - int qcmd, qupsize, fd; + int qcmd, qupsize; char *qfpathname; static int warned = 0; @@ -358,46 +362,19 @@ getprivs(long id, int quotatype, char *fspath) warnx("warning: quotas are not compiled into this kernel"); sleep(3); } - if ((fd = open(qfpathname, O_RDONLY)) < 0) { - fd = open(qfpathname, O_RDWR|O_CREAT, 0640); - if (fd < 0 && errno != ENOENT) { - warn("%s", qfpathname); - free(qup); - continue; - } - warnx("creating quota file %s", qfpathname); - sleep(3); - (void) fchown(fd, getuid(), - getentry(quotagroup, GRPQUOTA)); - (void) fchmod(fd, 0640); - } - if (lseek(fd, (off_t)id * sizeof(struct dqblk), - L_SET) < 0) { - warn("seek error on %s", qfpathname); - close(fd); + if ((qf = quota_open(qfpathname)) == NULL && + (qf = quota_create(qfpathname)) == NULL) { + warn("%s", qfpathname); free(qup); continue; } - switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) { - case 0: /* EOF */ - /* - * Convert implicit 0 quota (EOF) - * into an explicit one (zero'ed dqblk) - */ - bzero((caddr_t)&qup->dqblk, - sizeof(struct dqblk)); - break; - - case sizeof(struct dqblk): /* OK */ - break; - - default: /* ERROR */ + if (quota_read(qf, &qup->dqblk, id) != 0) { warn("read error in %s", qfpathname); - close(fd); + quota_close(qf); free(qup); continue; } - close(fd); + quota_close(qf); } strcpy(qup->qfname, qfpathname); strcpy(qup->fsname, fs->fs_file); @@ -418,38 +395,22 @@ getprivs(long id, int quotatype, char *fspath) void putprivs(long id, int quotatype, struct quotause *quplist) { + struct quotafile *qf; struct quotause *qup; - int qcmd, fd; + int qcmd; struct dqblk dqbuf; qcmd = QCMD(Q_SETQUOTA, quotatype); for (qup = quplist; qup; qup = qup->next) { if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0) continue; - if ((fd = open(qup->qfname, O_RDWR)) < 0) { + if ((qf = quota_open(qup->qfname)) == NULL) { warn("%s", qup->qfname); continue; } - if (lseek(fd, (off_t)id * sizeof(struct dqblk), L_SET) < 0) { - warn("seek error on %s", qup->qfname); - close(fd); - continue; - } - switch (read(fd, &dqbuf, sizeof(struct dqblk))) { - case 0: /* EOF */ - /* - * Convert implicit 0 quota (EOF) - * into an explicit one (zero'ed dqblk) - */ - bzero(&dqbuf, sizeof(struct dqblk)); - break; - - case sizeof(struct dqblk): /* OK */ - break; - - default: /* ERROR */ + if (quota_read(qf, &dqbuf, id) != 0) { warn("read error in %s", qup->qfname); - close(fd); + quota_close(qf); continue; } /* @@ -474,16 +435,10 @@ putprivs(long id, int quotatype, struct quotause *quplist) qup->dqblk.dqb_itime = 0; qup->dqblk.dqb_curinodes = dqbuf.dqb_curinodes; qup->dqblk.dqb_curblocks = dqbuf.dqb_curblocks; - if (lseek(fd, (off_t)id * sizeof(struct dqblk), L_SET) < 0) { - warn("seek error on %s", qup->qfname); - close(fd); - continue; - } - if (write(fd, &qup->dqblk, sizeof (struct dqblk)) != - sizeof (struct dqblk)) { + if (quota_write(qf, &qup->dqblk, id) != 0) { warn("%s", qup->qfname); - } - close(fd); + } + quota_close(qf); } } From 08dc3a5e5c3a8be3076365832986e7a69d0ae92d Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Wed, 4 Feb 2009 00:21:36 +0000 Subject: [PATCH 006/532] Finish conversion of edquota to work with 64-bit quotas. Add -h option to request "humanized" values such as 1M, 1G, 1T, etc. Discussed with: Dag-Erling Smorgrav Sponsored by: Rsync.net --- usr.sbin/edquota/Makefile | 1 + usr.sbin/edquota/edquota.8 | 13 +++ usr.sbin/edquota/edquota.c | 214 +++++++++++++++++++++++++++---------- 3 files changed, 170 insertions(+), 58 deletions(-) diff --git a/usr.sbin/edquota/Makefile b/usr.sbin/edquota/Makefile index 82794925397..b62221257f5 100644 --- a/usr.sbin/edquota/Makefile +++ b/usr.sbin/edquota/Makefile @@ -4,6 +4,7 @@ PROG= edquota MAN= edquota.8 +CSTD= c99 WARNS?= 4 DPADD= ${LIBUTIL} diff --git a/usr.sbin/edquota/edquota.8 b/usr.sbin/edquota/edquota.8 index 7cf72dd1118..9c90de468b6 100644 --- a/usr.sbin/edquota/edquota.8 +++ b/usr.sbin/edquota/edquota.8 @@ -42,6 +42,7 @@ .Op Fl u .Op Fl f Ar fspath .Op Fl p Ar proto-username +.Op Fl h .Ar username ... .Nm .Op Fl u @@ -55,6 +56,7 @@ .Fl g .Op Fl f Ar fspath .Op Fl p Ar proto-groupname +.Op Fl h .Ar groupname ... .Nm .Fl g @@ -97,6 +99,14 @@ unless the environment variable specifies otherwise. .Pp The quotas may then be modified, new quotas added, etc. +Block quotas can be specified in bytes (B), kilobytes (K), +megabytes (M), terabytes (T), pedabytes (P), or exabytes (E). +If no units are specified, kilobytes are assumed. +If the +.Fl h +flag is specified, the editor will always display the +block usage and limits in a more human readable format +rather than displaying them in the historic kilobyte format. Setting a quota to zero indicates that no quota should be imposed. Setting a hard limit to one indicates that no allocations should be permitted. @@ -159,6 +169,9 @@ and .Ar ihlim values is omitted, it is assumed to be zero, therefore indicating that no particular quota should be imposed. +Block quotas can be specified in bytes (B), kilobytes (K), +megabytes (M), terabytes (T), pedabytes (P), or exabytes (E). +If no units are specified, kilobytes are assumed. .Pp If invoked with the .Fl f diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 76baa0417fa..2798d8a7742 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -72,10 +72,22 @@ __FBSDID("$FreeBSD$"); #include "pathnames.h" +/* Let's be paranoid about block size */ +#if 10 > DEV_BSHIFT +#define dbtokb(db) \ + ((off_t)(db) >> (10-DEV_BSHIFT)) +#elif 10 < DEV_BSHIFT +#define dbtokb(db) \ + ((off_t)(db) << (DEV_BSHIFT-10)) +#else +#define dbtokb(db) (db) +#endif + const char *qfname = QUOTAFILENAME; const char *qfextension[] = INITQFNAMES; const char *quotagroup = QUOTAGROUP; char tmpfil[] = _PATH_TMP; +int hflag; struct quotause { struct quotause *next; @@ -87,9 +99,11 @@ struct quotause { #define FOUND 0x01 int alldigits(const char *s); -int cvtatos(time_t, char *, time_t *); -char *cvtstoa(time_t); +int cvtatos(u_int64_t, char *, u_int64_t *); +char *cvtstoa(u_int64_t); +u_int64_t cvtval(u_int64_t, char); int editit(char *); +char *fmthumanval(int64_t); void freeprivs(struct quotause *); int getentry(const char *, int); struct quotause *getprivs(long, int, char *); @@ -106,11 +120,10 @@ main(int argc, char *argv[]) { struct quotause *qup, *protoprivs, *curprivs; long id, protoid; - uintmax_t lim; int i, quotatype, range, tmpfd; uid_t startuid, enduid; - u_int64_t *limp; - char *protoname, *cp, *oldoptarg, *end; + u_int64_t lim; + char *protoname, *cp, *endpt, *oldoptarg; int eflag = 0, tflag = 0, pflag = 0, ch; char *fspath = NULL; char buf[MAXLOGNAME]; @@ -123,7 +136,7 @@ main(int argc, char *argv[]) protoprivs = NULL; curprivs = NULL; protoname = NULL; - while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) { + while ((ch = getopt(argc, argv, "ughtf:p:e:")) != -1) { switch(ch) { case 'f': fspath = optarg; @@ -135,6 +148,9 @@ main(int argc, char *argv[]) case 'g': quotatype = GRPQUOTA; break; + case 'h': + hflag++; + break; case 'u': quotatype = USRQUOTA; break; @@ -142,45 +158,44 @@ main(int argc, char *argv[]) tflag++; break; case 'e': - if ((qup = malloc(sizeof(*qup))) == NULL) + if ((qup = malloc(sizeof(*qup) + BUFSIZ)) == NULL) errx(2, "out of memory"); - bzero(qup, sizeof(*qup)); + bzero(qup, sizeof(*qup) + BUFSIZ); i = 0; oldoptarg = optarg; for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; - limp = NULL; switch (i) { case 0: strlcpy(qup->fsname, cp, sizeof(qup->fsname)); break; case 1: - limp = &qup->dqblk.dqb_bsoftlimit; - break; + lim = strtoll(cp, &endpt, 10); + qup->dqblk.dqb_bsoftlimit = + cvtval(lim, *endpt); + continue; case 2: - limp = &qup->dqblk.dqb_bhardlimit; - break; + lim = strtoll(cp, &endpt, 10); + qup->dqblk.dqb_bhardlimit = + cvtval(lim, *endpt); + continue; case 3: - limp = &qup->dqblk.dqb_isoftlimit; - break; + qup->dqblk.dqb_isoftlimit = + strtoll(cp, NULL, 10); + continue; case 4: - limp = &qup->dqblk.dqb_ihardlimit; - break; + qup->dqblk.dqb_ihardlimit = + strtoll(cp, NULL, 10); + continue; default: warnx("incorrect quota specification: " "%s", oldoptarg); usage(); break; /* XXX: report an error */ } - if (limp != NULL) { - lim = strtoumax(cp, &end, 10); - if (end == cp || *end != '\0' || lim > UINT64_MAX) - errx(1, "invalid limit: %s", cp); - *limp = (u_int64_t)lim; - } } qup->dqblk.dqb_bsoftlimit = btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); @@ -285,10 +300,10 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", - "usage: edquota [-u] [-f fspath] [-p username] username ...", + "usage: edquota [-u] [-f fspath] [-p username] [-h] username ...", " edquota [-u] -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", " username ...", - " edquota -g [-f fspath] [-p groupname] groupname ...", + " edquota -g [-f fspath] [-p groupname] [-h] groupname ...", " edquota -g -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", " groupname ...", " edquota [-u] -t [-f fspath]", @@ -314,14 +329,17 @@ getentry(const char *name, int quotatype) if ((pw = getpwnam(name))) return (pw->pw_uid); warnx("%s: no such user", name); + sleep(3); break; case GRPQUOTA: if ((gr = getgrnam(name))) return (gr->gr_gid); warnx("%s: no such group", name); + sleep(3); break; default: warnx("%d: unknown quota type", quotatype); + sleep(3); break; } sleep(1); @@ -499,21 +517,36 @@ writeprivs(struct quotause *quplist, int outfd, char *name, int quotatype) err(1, "%s", tmpfil); fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); for (qup = quplist; qup; qup = qup->next) { - fprintf(fd, "%s: %s %lu, limits (soft = %lu, hard = %lu)\n", - qup->fsname, "kbytes in use:", - (unsigned long)(dbtob(qup->dqblk.dqb_curblocks) / 1024), - (unsigned long)(dbtob(qup->dqblk.dqb_bsoftlimit) / 1024), - (unsigned long)(dbtob(qup->dqblk.dqb_bhardlimit) / 1024)); - fprintf(fd, "%s %lu, limits (soft = %lu, hard = %lu)\n", + fprintf(fd, "%s: in use: %s, ", qup->fsname, + fmthumanval(qup->dqblk.dqb_curblocks)); + fprintf(fd, "limits (soft = %s, ", + fmthumanval(qup->dqblk.dqb_bsoftlimit)); + fprintf(fd, "hard = %s)\n", + fmthumanval(qup->dqblk.dqb_bhardlimit)); + fprintf(fd, "%s %llu, limits (soft = %llu, hard = %llu)\n", "\tinodes in use:", - (unsigned long)qup->dqblk.dqb_curinodes, - (unsigned long)qup->dqblk.dqb_isoftlimit, - (unsigned long)qup->dqblk.dqb_ihardlimit); + qup->dqblk.dqb_curinodes, + qup->dqblk.dqb_isoftlimit, + qup->dqblk.dqb_ihardlimit); } fclose(fd); return (1); } +char * +fmthumanval(int64_t blocks) +{ + static char buf[7], numbuf[20]; + + if (hflag) { + humanize_number(buf, sizeof(buf) - (blocks < 0 ? 0 : 1), + dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE); + return (buf); + } + snprintf(numbuf, 20, "%lluK", dbtokb(blocks)); + return(numbuf); +} + /* * Merge changes to an ASCII file into a quotause list. */ @@ -522,8 +555,9 @@ readprivs(struct quotause *quplist, char *inname) { struct quotause *qup; FILE *fd; - unsigned long bhardlimit, bsoftlimit, curblocks; - unsigned long ihardlimit, isoftlimit, curinodes; + u_int64_t ihardlimit, isoftlimit, curinodes; + u_int64_t bhardlimit, bsoftlimit, curblocks; + char bhardunits, bsoftunits, curblockunits; int cnt; char *cp; struct dqblk dqblk; @@ -549,21 +583,40 @@ readprivs(struct quotause *quplist, char *inname) return (0); } cnt = sscanf(cp, - " kbytes in use: %lu, limits (soft = %lu, hard = %lu)", - &curblocks, &bsoftlimit, &bhardlimit); - if (cnt != 3) { + " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)", + &curblocks, &curblockunits, &bsoftlimit, &bsoftunits, + &bhardlimit, &bhardunits); + /* + * The next three check for old-style input formats. + */ + if (cnt != 6) + cnt = sscanf(cp, + " in use: %llu%c, limits (soft = %llu%c hard = %llu%c", + &curblocks, &curblockunits, &bsoftlimit, + &bsoftunits, &bhardlimit, &bhardunits); + if (cnt != 6) + cnt = sscanf(cp, + " in use: %llu%c, limits (soft = %llu%c hard = %llu%c)", + &curblocks, &curblockunits, &bsoftlimit, + &bsoftunits, &bhardlimit, &bhardunits); + if (cnt != 6) + cnt = sscanf(cp, + " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c", + &curblocks, &curblockunits, &bsoftlimit, + &bsoftunits, &bhardlimit, &bhardunits); + if (cnt != 6) { warnx("%s:%s: bad format", fsp, cp); return (0); } - dqblk.dqb_curblocks = btodb((off_t)curblocks * 1024); - dqblk.dqb_bsoftlimit = btodb((off_t)bsoftlimit * 1024); - dqblk.dqb_bhardlimit = btodb((off_t)bhardlimit * 1024); + dqblk.dqb_curblocks = cvtval(curblocks, curblockunits); + dqblk.dqb_bsoftlimit = cvtval(bsoftlimit, bsoftunits); + dqblk.dqb_bhardlimit = cvtval(bhardlimit, bhardunits); if ((cp = strtok(line2, "\n")) == NULL) { warnx("%s: %s: bad format", fsp, line2); return (0); } cnt = sscanf(cp, - "\tinodes in use: %lu, limits (soft = %lu, hard = %lu)", + "\tinodes in use: %llu, limits (soft = %llu, hard = %llu)", &curinodes, &isoftlimit, &ihardlimit); if (cnt != 3) { warnx("%s: %s: bad format", fsp, line2); @@ -598,8 +651,8 @@ readprivs(struct quotause *quplist, char *inname) qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; qup->flags |= FOUND; - if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && - dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) + /* No easy way to check change in curblocks */ + if (dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) break; warnx("%s: cannot change current allocation", fsp); break; @@ -658,8 +711,7 @@ readtimes(struct quotause *quplist, char *inname) FILE *fd; int cnt; char *cp; - time_t itime, btime, iseconds, bseconds; - long l_itime, l_btime; + u_int64_t itime, btime, iseconds, bseconds; char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; fd = fopen(inname, "r"); @@ -682,14 +734,12 @@ readtimes(struct quotause *quplist, char *inname) return (0); } cnt = sscanf(cp, - " block grace period: %ld %s file grace period: %ld %s", - &l_btime, bunits, &l_itime, iunits); + " block grace period: %llu %s file grace period: %llu %s", + &btime, bunits, &itime, iunits); if (cnt != 4) { warnx("%s:%s: bad format", fsp, cp); return (0); } - btime = l_btime; - itime = l_itime; if (cvtatos(btime, bunits, &bseconds) == 0) return (0); if (cvtatos(itime, iunits, &iseconds) == 0) @@ -723,21 +773,21 @@ readtimes(struct quotause *quplist, char *inname) * Convert seconds to ASCII times. */ char * -cvtstoa(time_t secs) +cvtstoa(u_int64_t secs) { static char buf[20]; if (secs % (24 * 60 * 60) == 0) { secs /= 24 * 60 * 60; - sprintf(buf, "%ld day%s", (long)secs, secs == 1 ? "" : "s"); + sprintf(buf, "%llu day%s", secs, secs == 1 ? "" : "s"); } else if (secs % (60 * 60) == 0) { secs /= 60 * 60; - sprintf(buf, "%ld hour%s", (long)secs, secs == 1 ? "" : "s"); + sprintf(buf, "%llu hour%s", secs, secs == 1 ? "" : "s"); } else if (secs % 60 == 0) { secs /= 60; - sprintf(buf, "%ld minute%s", (long)secs, secs == 1 ? "" : "s"); + sprintf(buf, "%llu minute%s", secs, secs == 1 ? "" : "s"); } else - sprintf(buf, "%ld second%s", (long)secs, secs == 1 ? "" : "s"); + sprintf(buf, "%llu second%s", secs, secs == 1 ? "" : "s"); return (buf); } @@ -745,7 +795,7 @@ cvtstoa(time_t secs) * Convert ASCII input times to seconds. */ int -cvtatos(time_t period, char *units, time_t *seconds) +cvtatos(u_int64_t period, char *units, u_int64_t *seconds) { if (bcmp(units, "second", 6) == 0) @@ -757,13 +807,60 @@ cvtatos(time_t period, char *units, time_t *seconds) else if (bcmp(units, "day", 3) == 0) *seconds = period * 24 * 60 * 60; else { - printf("%s: bad units, specify %s\n", units, + warnx("%s: bad units, specify %s\n", units, "days, hours, minutes, or seconds"); return (0); } return (1); } +/* + * Convert a limit to number of disk blocks. + */ +u_int64_t +cvtval(u_int64_t limit, char units) +{ + + switch(units) { + case 'B': + case 'b': + limit = btodb(limit); + break; + case '\0': /* historic behavior */ + case ',': /* historic behavior */ + case ')': /* historic behavior */ + case 'K': + case 'k': + limit *= btodb(1024); + break; + case 'M': + case 'm': + limit *= btodb(1048576); + break; + case 'G': + case 'g': + limit *= btodb(1073741824); + break; + case 'T': + case 't': + limit *= btodb(1099511627776); + break; + case 'P': + case 'p': + limit *= btodb(1125899906842624); + break; + case 'E': + case 'e': + limit *= btodb(1152921504606846976); + break; + default: + warnx("%llu%c: unknown units, specify K, M, G, T, P, or E\n", + limit, units); + break; + } + return (limit); +} + /* * Free a list of quotause structures. */ @@ -833,6 +930,7 @@ hasquota(struct fstab *fs, int type, char **qfnamep) } if (statfs(fs->fs_file, &sfb) != 0) { warn("cannot statfs mount point %s", fs->fs_file); + sleep(3); return (0); } if (strcmp(fs->fs_file, sfb.f_mntonname)) { From b83b5d3b796b885ad19cce99cd7a3ab81e41a2e1 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Thu, 5 Feb 2009 14:06:43 +0000 Subject: [PATCH 007/532] Updates to edquota based on feedback from Dag-Erling Smorgrav. --- usr.sbin/edquota/Makefile | 2 +- usr.sbin/edquota/edquota.8 | 15 ++++--- usr.sbin/edquota/edquota.c | 91 +++++++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/usr.sbin/edquota/Makefile b/usr.sbin/edquota/Makefile index b62221257f5..1196e472141 100644 --- a/usr.sbin/edquota/Makefile +++ b/usr.sbin/edquota/Makefile @@ -4,7 +4,7 @@ PROG= edquota MAN= edquota.8 -CSTD= c99 +CSTD= gnu99 WARNS?= 4 DPADD= ${LIBUTIL} diff --git a/usr.sbin/edquota/edquota.8 b/usr.sbin/edquota/edquota.8 index 9c90de468b6..326c8373c25 100644 --- a/usr.sbin/edquota/edquota.8 +++ b/usr.sbin/edquota/edquota.8 @@ -39,10 +39,9 @@ .Nd edit user quotas .Sh SYNOPSIS .Nm -.Op Fl u +.Op Fl uh .Op Fl f Ar fspath .Op Fl p Ar proto-username -.Op Fl h .Ar username ... .Nm .Op Fl u @@ -54,9 +53,9 @@ .Ar username ... .Nm .Fl g +.Op Fl h .Op Fl f Ar fspath .Op Fl p Ar proto-groupname -.Op Fl h .Ar groupname ... .Nm .Fl g @@ -100,8 +99,11 @@ specifies otherwise. .Pp The quotas may then be modified, new quotas added, etc. Block quotas can be specified in bytes (B), kilobytes (K), -megabytes (M), terabytes (T), pedabytes (P), or exabytes (E). +megabytes (M), terabytes (T), petabytes (P), or exabytes (E). If no units are specified, kilobytes are assumed. +Inode quotas can be specified in kiloinodes (K), +megainodes (M), terainodes (T), petainodes (P), or exainodes (E). +If no units are specified, the number of inodes specified are used. If the .Fl h flag is specified, the editor will always display the @@ -170,8 +172,11 @@ and values is omitted, it is assumed to be zero, therefore indicating that no particular quota should be imposed. Block quotas can be specified in bytes (B), kilobytes (K), -megabytes (M), terabytes (T), pedabytes (P), or exabytes (E). +megabytes (M), terabytes (T), petabytes (P), or exabytes (E). If no units are specified, kilobytes are assumed. +Inode quotas can be specified in kiloinodes (K), +megainodes (M), terainodes (T), petainodes (P), or exainodes (E). +If no units are specified, the number of inodes specified are used. .Pp If invoked with the .Fl f diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 2798d8a7742..3331548c86c 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -158,13 +158,11 @@ main(int argc, char *argv[]) tflag++; break; case 'e': - if ((qup = malloc(sizeof(*qup) + BUFSIZ)) == NULL) + if ((qup = calloc(1, sizeof(*qup) + BUFSIZ)) == NULL) errx(2, "out of memory"); - bzero(qup, sizeof(*qup) + BUFSIZ); - i = 0; oldoptarg = optarg; - for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL; - i++) { + for (i = 0, cp = optarg; + (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; switch (i) { @@ -183,12 +181,14 @@ main(int argc, char *argv[]) cvtval(lim, *endpt); continue; case 3: + lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_isoftlimit = - strtoll(cp, NULL, 10); + cvtval(lim, *endpt); continue; case 4: + lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_ihardlimit = - strtoll(cp, NULL, 10); + cvtval(lim, *endpt); continue; default: warnx("incorrect quota specification: " @@ -300,10 +300,10 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", - "usage: edquota [-u] [-f fspath] [-p username] [-h] username ...", + "usage: edquota [-uh] [-f fspath] [-p username] username ...", " edquota [-u] -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", " username ...", - " edquota -g [-f fspath] [-p groupname] [-h] groupname ...", + " edquota -g [-h] [-f fspath] [-p groupname] groupname ...", " edquota -g -e fspath[:bslim[:bhlim[:islim[:ihlim]]]] [-e ...]", " groupname ...", " edquota [-u] -t [-f fspath]", @@ -536,14 +536,14 @@ writeprivs(struct quotause *quplist, int outfd, char *name, int quotatype) char * fmthumanval(int64_t blocks) { - static char buf[7], numbuf[20]; + static char numbuf[20]; if (hflag) { - humanize_number(buf, sizeof(buf) - (blocks < 0 ? 0 : 1), + humanize_number(numbuf, sizeof(numbuf) - (blocks < 0 ? 0 : 1), dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE); - return (buf); + return (numbuf); } - snprintf(numbuf, 20, "%lluK", dbtokb(blocks)); + snprintf(numbuf, sizeof(numbuf), "%lluk", dbtokb(blocks)); return(numbuf); } @@ -555,9 +555,8 @@ readprivs(struct quotause *quplist, char *inname) { struct quotause *qup; FILE *fd; - u_int64_t ihardlimit, isoftlimit, curinodes; - u_int64_t bhardlimit, bsoftlimit, curblocks; - char bhardunits, bsoftunits, curblockunits; + u_int64_t hardlimit, softlimit, curitems; + char hardunits, softunits, curitemunits; int cnt; char *cp; struct dqblk dqblk; @@ -584,47 +583,66 @@ readprivs(struct quotause *quplist, char *inname) } cnt = sscanf(cp, " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)", - &curblocks, &curblockunits, &bsoftlimit, &bsoftunits, - &bhardlimit, &bhardunits); + &curitems, &curitemunits, &softlimit, &softunits, + &hardlimit, &hardunits); /* * The next three check for old-style input formats. */ if (cnt != 6) cnt = sscanf(cp, " in use: %llu%c, limits (soft = %llu%c hard = %llu%c", - &curblocks, &curblockunits, &bsoftlimit, - &bsoftunits, &bhardlimit, &bhardunits); + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); if (cnt != 6) cnt = sscanf(cp, " in use: %llu%c, limits (soft = %llu%c hard = %llu%c)", - &curblocks, &curblockunits, &bsoftlimit, - &bsoftunits, &bhardlimit, &bhardunits); + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); if (cnt != 6) cnt = sscanf(cp, " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c", - &curblocks, &curblockunits, &bsoftlimit, - &bsoftunits, &bhardlimit, &bhardunits); + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); if (cnt != 6) { warnx("%s:%s: bad format", fsp, cp); return (0); } - dqblk.dqb_curblocks = cvtval(curblocks, curblockunits); - dqblk.dqb_bsoftlimit = cvtval(bsoftlimit, bsoftunits); - dqblk.dqb_bhardlimit = cvtval(bhardlimit, bhardunits); + dqblk.dqb_curblocks = cvtval(curitems, curitemunits); + dqblk.dqb_bsoftlimit = cvtval(softlimit, softunits); + dqblk.dqb_bhardlimit = cvtval(hardlimit, hardunits); if ((cp = strtok(line2, "\n")) == NULL) { warnx("%s: %s: bad format", fsp, line2); return (0); } cnt = sscanf(cp, - "\tinodes in use: %llu, limits (soft = %llu, hard = %llu)", - &curinodes, &isoftlimit, &ihardlimit); + " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)", + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); + /* + * The next three check for old-style input formats. + */ + if (cnt != 6) + cnt = sscanf(cp, + " in use: %llu%c, limits (soft = %llu%c hard = %llu%c", + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); + if (cnt != 6) + cnt = sscanf(cp, + " in use: %llu%c, limits (soft = %llu%c hard = %llu%c)", + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); + if (cnt != 6) + cnt = sscanf(cp, + " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c", + &curitems, &curitemunits, &softlimit, + &softunits, &hardlimit, &hardunits); if (cnt != 3) { warnx("%s: %s: bad format", fsp, line2); return (0); } - dqblk.dqb_curinodes = curinodes; - dqblk.dqb_isoftlimit = isoftlimit; - dqblk.dqb_ihardlimit = ihardlimit; + dqblk.dqb_curinodes = cvtval(curitems, curitemunits); + dqblk.dqb_isoftlimit = cvtval(softlimit, softunits); + dqblk.dqb_ihardlimit = cvtval(hardlimit, hardunits); for (qup = quplist; qup; qup = qup->next) { if (strcmp(fsp, qup->fsname)) continue; @@ -651,8 +669,8 @@ readprivs(struct quotause *quplist, char *inname) qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; qup->flags |= FOUND; - /* No easy way to check change in curblocks */ - if (dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) + if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && + dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) break; warnx("%s: cannot change current allocation", fsp); break; @@ -853,8 +871,11 @@ cvtval(u_int64_t limit, char units) case 'e': limit *= btodb(1152921504606846976); break; + case ' ': + errx(2, "No space permitted between value and units\n"); + break; default: - warnx("%llu%c: unknown units, specify K, M, G, T, P, or E\n", + errx(2, "%llu%c: unknown units, specify K, M, G, T, P, or E\n", limit, units); break; } From cdab8b664d3e54562c025e13b2a69b0abbab991e Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 10 Feb 2009 08:09:03 +0000 Subject: [PATCH 008/532] More updates to edquota based on feedback from Dag-Erling Smorgrav. --- usr.sbin/edquota/edquota.c | 169 +++++++++++++++++++++++++++---------- 1 file changed, 126 insertions(+), 43 deletions(-) diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 3331548c86c..94dff1ef0f7 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -101,9 +101,11 @@ struct quotause { int alldigits(const char *s); int cvtatos(u_int64_t, char *, u_int64_t *); char *cvtstoa(u_int64_t); -u_int64_t cvtval(u_int64_t, char); +u_int64_t cvtblkval(u_int64_t, char, const char *); +u_int64_t cvtinoval(u_int64_t, char, const char *); int editit(char *); -char *fmthumanval(int64_t); +char *fmthumanvalblks(int64_t); +char *fmthumanvalinos(int64_t); void freeprivs(struct quotause *); int getentry(const char *, int); struct quotause *getprivs(long, int, char *); @@ -165,6 +167,12 @@ main(int argc, char *argv[]) (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; + if (i > 0 && !isdigit(*cp)) { + warnx("incorrect quota specification: " + "%s", oldoptarg); + usage(); + /* Not Reached */ + } switch (i) { case 0: strlcpy(qup->fsname, cp, @@ -173,34 +181,34 @@ main(int argc, char *argv[]) case 1: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_bsoftlimit = - cvtval(lim, *endpt); + cvtblkval(lim, *endpt, + "block soft limit"); continue; case 2: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_bhardlimit = - cvtval(lim, *endpt); + cvtblkval(lim, *endpt, + "block hard limit"); continue; case 3: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_isoftlimit = - cvtval(lim, *endpt); + cvtinoval(lim, *endpt, + "inode soft limit"); continue; case 4: lim = strtoll(cp, &endpt, 10); qup->dqblk.dqb_ihardlimit = - cvtval(lim, *endpt); + cvtinoval(lim, *endpt, + "inode hard limit"); continue; default: warnx("incorrect quota specification: " "%s", oldoptarg); usage(); - break; /* XXX: report an error */ + /* Not Reached */ } } - qup->dqblk.dqb_bsoftlimit = - btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); - qup->dqblk.dqb_bhardlimit = - btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024); if (protoprivs == NULL) { protoprivs = curprivs = qup; } else { @@ -212,6 +220,7 @@ main(int argc, char *argv[]) break; default: usage(); + /* Not Reached */ } } argc -= optind; @@ -518,28 +527,29 @@ writeprivs(struct quotause *quplist, int outfd, char *name, int quotatype) fprintf(fd, "Quotas for %s %s:\n", qfextension[quotatype], name); for (qup = quplist; qup; qup = qup->next) { fprintf(fd, "%s: in use: %s, ", qup->fsname, - fmthumanval(qup->dqblk.dqb_curblocks)); + fmthumanvalblks(qup->dqblk.dqb_curblocks)); fprintf(fd, "limits (soft = %s, ", - fmthumanval(qup->dqblk.dqb_bsoftlimit)); + fmthumanvalblks(qup->dqblk.dqb_bsoftlimit)); fprintf(fd, "hard = %s)\n", - fmthumanval(qup->dqblk.dqb_bhardlimit)); - fprintf(fd, "%s %llu, limits (soft = %llu, hard = %llu)\n", - "\tinodes in use:", - qup->dqblk.dqb_curinodes, - qup->dqblk.dqb_isoftlimit, - qup->dqblk.dqb_ihardlimit); + fmthumanvalblks(qup->dqblk.dqb_bhardlimit)); + fprintf(fd, "\tinodes in use: %s, ", + fmthumanvalinos(qup->dqblk.dqb_curinodes)); + fprintf(fd, "limits (soft = %s, ", + fmthumanvalinos(qup->dqblk.dqb_isoftlimit)); + fprintf(fd, "hard = %s)\n", + fmthumanvalinos(qup->dqblk.dqb_ihardlimit)); } fclose(fd); return (1); } char * -fmthumanval(int64_t blocks) +fmthumanvalblks(int64_t blocks) { static char numbuf[20]; if (hflag) { - humanize_number(numbuf, sizeof(numbuf) - (blocks < 0 ? 0 : 1), + humanize_number(numbuf, blocks < 0 ? 7 : 6, dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE); return (numbuf); } @@ -547,6 +557,20 @@ fmthumanval(int64_t blocks) return(numbuf); } +char * +fmthumanvalinos(int64_t inos) +{ + static char numbuf[20]; + + if (hflag) { + humanize_number(numbuf, inos < 0 ? 7 : 6, + inos, "", HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000); + return (numbuf); + } + snprintf(numbuf, sizeof(numbuf), "%llu", inos); + return(numbuf); +} + /* * Merge changes to an ASCII file into a quotause list. */ @@ -607,42 +631,48 @@ readprivs(struct quotause *quplist, char *inname) warnx("%s:%s: bad format", fsp, cp); return (0); } - dqblk.dqb_curblocks = cvtval(curitems, curitemunits); - dqblk.dqb_bsoftlimit = cvtval(softlimit, softunits); - dqblk.dqb_bhardlimit = cvtval(hardlimit, hardunits); + dqblk.dqb_curblocks = cvtblkval(curitems, curitemunits, + "current block count"); + dqblk.dqb_bsoftlimit = cvtblkval(softlimit, softunits, + "block soft limit"); + dqblk.dqb_bhardlimit = cvtblkval(hardlimit, hardunits, + "block hard limit"); if ((cp = strtok(line2, "\n")) == NULL) { warnx("%s: %s: bad format", fsp, line2); return (0); } - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c, hard = %llu%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); /* * The next three check for old-style input formats. */ if (cnt != 6) - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c hard = %llu%c", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c hard = %llu%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c hard = %llu%c)", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c hard = %llu%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) - cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c", + cnt = sscanf(&cp[7], + " in use: %llu%c limits (soft = %llu%c, hard = %llu%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); - if (cnt != 3) { - warnx("%s: %s: bad format", fsp, line2); + if (cnt != 6) { + warnx("%s: %s: bad format cnt %d", fsp, &cp[7], cnt); return (0); } - dqblk.dqb_curinodes = cvtval(curitems, curitemunits); - dqblk.dqb_isoftlimit = cvtval(softlimit, softunits); - dqblk.dqb_ihardlimit = cvtval(hardlimit, hardunits); + dqblk.dqb_curinodes = cvtinoval(curitems, curitemunits, + "current inode count"); + dqblk.dqb_isoftlimit = cvtinoval(softlimit, softunits, + "inode soft limit"); + dqblk.dqb_ihardlimit = cvtinoval(hardlimit, hardunits, + "inode hard limit"); for (qup = quplist; qup; qup = qup->next) { if (strcmp(fsp, qup->fsname)) continue; @@ -669,8 +699,10 @@ readprivs(struct quotause *quplist, char *inname) qup->dqblk.dqb_isoftlimit = dqblk.dqb_isoftlimit; qup->dqblk.dqb_ihardlimit = dqblk.dqb_ihardlimit; qup->flags |= FOUND; - if (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && - dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes) + /* Humanized input returns only approximate counts */ + if (hflag || + (dqblk.dqb_curblocks == qup->dqblk.dqb_curblocks && + dqblk.dqb_curinodes == qup->dqblk.dqb_curinodes)) break; warnx("%s: cannot change current allocation", fsp); break; @@ -836,7 +868,7 @@ cvtatos(u_int64_t period, char *units, u_int64_t *seconds) * Convert a limit to number of disk blocks. */ u_int64_t -cvtval(u_int64_t limit, char units) +cvtblkval(u_int64_t limit, char units, const char *itemname) { switch(units) { @@ -872,11 +904,62 @@ cvtval(u_int64_t limit, char units) limit *= btodb(1152921504606846976); break; case ' ': - errx(2, "No space permitted between value and units\n"); + errx(2, "No space permitted between value and units for %s\n", + itemname); break; default: - errx(2, "%llu%c: unknown units, specify K, M, G, T, P, or E\n", - limit, units); + errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n", + limit, units, itemname); + break; + } + return (limit); +} + +/* + * Convert a limit to number of inodes. + */ +u_int64_t +cvtinoval(u_int64_t limit, char units, const char *itemname) +{ + + switch(units) { + case 'B': + case 'b': + case '\0': /* historic behavior */ + case ',': /* historic behavior */ + case ')': /* historic behavior */ + break; + case 'K': + case 'k': + limit *= 1000; + break; + case 'M': + case 'm': + limit *= 1000000; + break; + case 'G': + case 'g': + limit *= 1000000000; + break; + case 'T': + case 't': + limit *= 1000000000000; + break; + case 'P': + case 'p': + limit *= 1000000000000000; + break; + case 'E': + case 'e': + limit *= 1000000000000000000; + break; + case ' ': + errx(2, "No space permitted between value and units for %s\n", + itemname); + break; + default: + errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n", + limit, units, itemname); break; } return (limit); From 581fce8e7df72f43c9aa9eb4b45815991911b0fb Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 10 Feb 2009 08:11:44 +0000 Subject: [PATCH 009/532] Bug fixes found from using these functions in edquota. --- lib/libutil/quotafile.3 | 4 ++-- lib/libutil/quotafile.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index a414a99a027..d819f619905 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -45,9 +45,9 @@ .Ft "struct quotafile *" .Fn quota_create "const char *path" .Ft int -.Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int type" +.Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int id" .Ft int -.Fn quota_write "struct quotafile *qf" "const struct dqblk *dqb" "int type" +.Fn quota_write "struct quotafile *qf" "const struct dqblk *dqb" "int id" .Ft int .Fn quota_close "struct quotafile *qf" .Sh DESCRIPTION diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index a4258b1ef30..c175df0b21c 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -231,7 +231,7 @@ quota_write32(struct quotafile *qf, const struct dqblk *dqb, int id) off = id * sizeof(struct dqblk32); if (lseek(qf->fd, off, SEEK_SET) == -1) return (-1); - return (write(qf->fd, &dqb32, sizeof(dqb32))); + return (write(qf->fd, &dqb32, sizeof(dqb32)) == -1); } static int @@ -252,7 +252,7 @@ quota_write64(struct quotafile *qf, const struct dqblk *dqb, int id) off = sizeof(struct dqhdr64) + id * sizeof(struct dqblk64); if (lseek(qf->fd, off, SEEK_SET) == -1) return (-1); - return (write(qf->fd, &dqb64, sizeof(dqb64))); + return (write(qf->fd, &dqb64, sizeof(dqb64)) == -1); } int From 916e406eb5992cdb49a4c90f634e3aa398aaad6a Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 13 Feb 2009 06:12:15 +0000 Subject: [PATCH 010/532] Move hasquota() function to libutil. --- lib/libutil/libutil.h | 2 + lib/libutil/quotafile.c | 56 +++++++++++++++++++- usr.sbin/edquota/edquota.c | 101 ++++++++++--------------------------- 3 files changed, 83 insertions(+), 76 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index 48ab2188c35..7796de0ac78 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -142,11 +142,13 @@ int pidfile_remove(struct pidfh *pfh); #ifdef _UFS_UFS_QUOTA_H_ struct quotafile; +struct fstab; struct quotafile *quota_open(const char *); struct quotafile *quota_create(const char *); void quota_close(struct quotafile *); int quota_read(struct quotafile *, struct dqblk *, int); int quota_write(struct quotafile *, const struct dqblk *, int); +int hasquota(struct fstab *, int, char **); #endif __END_DECLS diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index c175df0b21c..2520e9fcc64 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -29,16 +29,19 @@ #include #include +#include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -48,6 +51,8 @@ struct quotafile { int type; /* 32 or 64 */ }; +static const char *qfextension[] = INITQFNAMES; + struct quotafile * quota_open(const char *fn) { @@ -231,7 +236,7 @@ quota_write32(struct quotafile *qf, const struct dqblk *dqb, int id) off = id * sizeof(struct dqblk32); if (lseek(qf->fd, off, SEEK_SET) == -1) return (-1); - return (write(qf->fd, &dqb32, sizeof(dqb32)) == -1); + return (write(qf->fd, &dqb32, sizeof(dqb32)) == sizeof(dqb32)); } static int @@ -252,7 +257,7 @@ quota_write64(struct quotafile *qf, const struct dqblk *dqb, int id) off = sizeof(struct dqhdr64) + id * sizeof(struct dqblk64); if (lseek(qf->fd, off, SEEK_SET) == -1) return (-1); - return (write(qf->fd, &dqb64, sizeof(dqb64)) == -1); + return (write(qf->fd, &dqb64, sizeof(dqb64)) == sizeof(dqb64)); } int @@ -270,3 +275,50 @@ quota_write(struct quotafile *qf, const struct dqblk *dqb, int id) } /* not reached */ } + +/* + * Check to see if a particular quota is to be enabled. + */ +int +hasquota(struct fstab *fs, int type, char **qfnamep) +{ + char *opt; + char *cp; + struct statfs sfb; + static char initname, usrname[100], grpname[100]; + static char buf[BUFSIZ]; + + if (!initname) { + (void)snprintf(usrname, sizeof(usrname), "%s%s", + qfextension[USRQUOTA], QUOTAFILENAME); + (void)snprintf(grpname, sizeof(grpname), "%s%s", + qfextension[GRPQUOTA], QUOTAFILENAME); + initname = 1; + } + strcpy(buf, fs->fs_mntops); + for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { + if ((cp = index(opt, '='))) + *cp++ = '\0'; + if (type == USRQUOTA && strcmp(opt, usrname) == 0) + break; + if (type == GRPQUOTA && strcmp(opt, grpname) == 0) + break; + } + if (!opt) + return (0); + if (cp) + *qfnamep = cp; + else { + (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, + QUOTAFILENAME, qfextension[type]); + *qfnamep = buf; + } + /* + * Ensure that the filesystem is mounted. + */ + if (statfs(fs->fs_file, &sfb) != 0 || + strcmp(fs->fs_file, sfb.f_mntonname)) { + return (0); + } + return (1); +} diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 94dff1ef0f7..16594cff3ab 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -83,7 +83,6 @@ __FBSDID("$FreeBSD$"); #define dbtokb(db) (db) #endif -const char *qfname = QUOTAFILENAME; const char *qfextension[] = INITQFNAMES; const char *quotagroup = QUOTAGROUP; char tmpfil[] = _PATH_TMP; @@ -109,7 +108,6 @@ char *fmthumanvalinos(int64_t); void freeprivs(struct quotause *); int getentry(const char *, int); struct quotause *getprivs(long, int, char *); -int hasquota(struct fstab *, int, char **); void putprivs(long, int, struct quotause *); int readprivs(struct quotause *, char *); int readtimes(struct quotause *, char *); @@ -230,6 +228,8 @@ main(int argc, char *argv[]) if ((protoid = getentry(protoname, quotatype)) == -1) exit(1); protoprivs = getprivs(protoid, quotatype, fspath); + if (protoprivs == NULL) + exit(0); for (qup = protoprivs; qup; qup = qup->next) { qup->dqblk.dqb_btime = 0; qup->dqblk.dqb_itime = 0; @@ -259,20 +259,20 @@ main(int argc, char *argv[]) *argv); if ((id = getentry(buf, quotatype)) < 0) continue; - if (eflag) { - for (qup = protoprivs; qup; - qup = qup->next) { - curprivs = getprivs(id, - quotatype, qup->fsname); - if (curprivs == NULL) - continue; - strcpy(qup->qfname, - curprivs->qfname); - strcpy(qup->fsname, - curprivs->fsname); - } + if (!eflag) { + putprivs(id, quotatype, protoprivs); + continue; + } + for (qup = protoprivs; qup; + qup = qup->next) { + curprivs = getprivs(id, quotatype, + qup->fsname); + if (curprivs == NULL) + continue; + strcpy(qup->qfname, curprivs->qfname); + strcpy(qup->fsname, curprivs->fsname); + putprivs(id, quotatype, protoprivs); } - putprivs(id, quotatype, protoprivs); } } exit(0); @@ -280,12 +280,12 @@ main(int argc, char *argv[]) tmpfd = mkstemp(tmpfil); fchown(tmpfd, getuid(), getgid()); if (tflag) { - protoprivs = getprivs(0, quotatype, fspath); - if (writetimes(protoprivs, tmpfd, quotatype) == 0) - exit(1); - if (editit(tmpfil) && readtimes(protoprivs, tmpfil)) - putprivs(0L, quotatype, protoprivs); - freeprivs(protoprivs); + if ((protoprivs = getprivs(0, quotatype, fspath)) != NULL) { + if (writetimes(protoprivs, tmpfd, quotatype) != 0 && + editit(tmpfil) && readtimes(protoprivs, tmpfil)) + putprivs(0L, quotatype, protoprivs); + freeprivs(protoprivs); + } close(tmpfd); unlink(tmpfil); exit(0); @@ -293,7 +293,8 @@ main(int argc, char *argv[]) for ( ; argc > 0; argc--, argv++) { if ((id = getentry(*argv, quotatype)) == -1) continue; - curprivs = getprivs(id, quotatype, fspath); + if ((curprivs = getprivs(id, quotatype, fspath)) == NULL) + exit(1); if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) continue; if (editit(tmpfil) && readprivs(curprivs, tmpfil)) @@ -412,6 +413,9 @@ getprivs(long id, int quotatype, char *fspath) quptail = qup; qup->next = 0; } + if (quphead == NULL) { + warnx("No quotas on %s", fspath ? fspath : "any filesystems"); + } endfsent(); return (quphead); } @@ -462,7 +466,7 @@ putprivs(long id, int quotatype, struct quotause *quplist) qup->dqblk.dqb_itime = 0; qup->dqblk.dqb_curinodes = dqbuf.dqb_curinodes; qup->dqblk.dqb_curblocks = dqbuf.dqb_curblocks; - if (quota_write(qf, &qup->dqblk, id) != 0) { + if (quota_write(qf, &qup->dqblk, id) == 0) { warn("%s", qup->qfname); } quota_close(qf); @@ -994,54 +998,3 @@ alldigits(const char *s) } while ((c = *s++)); return (1); } - -/* - * Check to see if a particular quota is to be enabled. - */ -int -hasquota(struct fstab *fs, int type, char **qfnamep) -{ - char *opt; - char *cp; - struct statfs sfb; - static char initname, usrname[100], grpname[100]; - static char buf[BUFSIZ]; - - if (!initname) { - (void)snprintf(usrname, sizeof(usrname), "%s%s", - qfextension[USRQUOTA], qfname); - (void)snprintf(grpname, sizeof(grpname), "%s%s", - qfextension[GRPQUOTA], qfname); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - qfname, qfextension[type]); - *qfnamep = buf; - } - if (statfs(fs->fs_file, &sfb) != 0) { - warn("cannot statfs mount point %s", fs->fs_file); - sleep(3); - return (0); - } - if (strcmp(fs->fs_file, sfb.f_mntonname)) { - warnx("%s not mounted for %s quotas", fs->fs_file, - type == USRQUOTA ? "user" : "group"); - sleep(3); - return (0); - } - return (1); -} From 909d0c906fc23065abcf6f3535d7c81b729f74bf Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 13 Feb 2009 06:17:53 +0000 Subject: [PATCH 011/532] Move hasquota() function to libutil. --- lib/libutil/quotafile.3 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index d819f619905..ac6af011703 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -50,6 +50,8 @@ .Fn quota_write "struct quotafile *qf" "const struct dqblk *dqb" "int id" .Ft int .Fn quota_close "struct quotafile *qf" +.Ft int +.Fn hasquota "struct fstab *fs" "int type" "char **qfnamep" .Sh DESCRIPTION .Sh RETURN VALUES .Sh SEE ALSO From a88984f248e353d85b18d6e609e7209fa9fb855f Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 13 Feb 2009 19:56:59 +0000 Subject: [PATCH 012/532] Make hasquota thread safe. --- lib/libutil/libutil.h | 2 +- lib/libutil/quotafile.c | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index 7796de0ac78..b9aec78919d 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -148,7 +148,7 @@ struct quotafile *quota_create(const char *); void quota_close(struct quotafile *); int quota_read(struct quotafile *, struct dqblk *, int); int quota_write(struct quotafile *, const struct dqblk *, int); -int hasquota(struct fstab *, int, char **); +int hasquota(struct fstab *, int, char *, int); #endif __END_DECLS diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 2520e9fcc64..2b43b65a382 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -280,13 +280,13 @@ quota_write(struct quotafile *qf, const struct dqblk *dqb, int id) * Check to see if a particular quota is to be enabled. */ int -hasquota(struct fstab *fs, int type, char **qfnamep) +hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) { char *opt; char *cp; struct statfs sfb; + char buf[BUFSIZ]; static char initname, usrname[100], grpname[100]; - static char buf[BUFSIZ]; if (!initname) { (void)snprintf(usrname, sizeof(usrname), "%s%s", @@ -306,13 +306,6 @@ hasquota(struct fstab *fs, int type, char **qfnamep) } if (!opt) return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - QUOTAFILENAME, qfextension[type]); - *qfnamep = buf; - } /* * Ensure that the filesystem is mounted. */ @@ -320,5 +313,11 @@ hasquota(struct fstab *fs, int type, char **qfnamep) strcmp(fs->fs_file, sfb.f_mntonname)) { return (0); } + if (cp) { + strncpy(qfnamep, cp, qfbufsize); + } else { + (void)snprintf(qfnamep, qfbufsize, "%s/%s.%s", fs->fs_file, + QUOTAFILENAME, qfextension[type]); + } return (1); } From 8bd6a3ab4b32283502a1b58731eb0d0750b4f124 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sat, 14 Feb 2009 08:08:08 +0000 Subject: [PATCH 013/532] Update the quotafile library to manage both active quotas via the quotactl(2) interface and inactive quotas by accessing the quota files directly. Update the edquota program to use this new interface as proof of concept. --- lib/libutil/libutil.h | 7 +- lib/libutil/quotafile.3 | 121 +++++++++++++-- lib/libutil/quotafile.c | 303 +++++++++++++++++++++++++------------ usr.sbin/edquota/edquota.c | 133 ++++++---------- 4 files changed, 359 insertions(+), 205 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index b9aec78919d..afd5db6d228 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -143,12 +143,11 @@ int pidfile_remove(struct pidfh *pfh); #ifdef _UFS_UFS_QUOTA_H_ struct quotafile; struct fstab; -struct quotafile *quota_open(const char *); -struct quotafile *quota_create(const char *); +struct quotafile *quota_open(struct fstab *, int, int); void quota_close(struct quotafile *); int quota_read(struct quotafile *, struct dqblk *, int); -int quota_write(struct quotafile *, const struct dqblk *, int); -int hasquota(struct fstab *, int, char *, int); +int quota_write_limits(struct quotafile *, struct dqblk *, int); +int quota_write_usage(struct quotafile *, struct dqblk *, int); #endif __END_DECLS diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index ac6af011703..07a08a20c18 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -25,35 +25,132 @@ .\" .\" $FreeBSD$ .\" -.Dd November 4, 2008 +.Dd February 14, 2009 .Dt QUOTAFILE 3 .Os .Sh NAME .Nm quota_open -.Nm quota_create .Nm quota_read -.Nm quota_write +.Nm quota_write_limits +.Nm quota_write_usage .Nm quota_close -.Nd "Manipulate quota files" +.Nd "Manipulate quotas" .Sh LIBRARY .Lb libutil .Sh SYNOPSIS .In ufs/ufs/quota.h .In libutil.h +.In fstab.h .Ft "struct quotafile *" -.Fn quota_open "const char *path" -.Ft "struct quotafile *" -.Fn quota_create "const char *path" +.Fn quota_open "struct fstab *fs" "int quotatype" "int openflags" .Ft int .Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int id" .Ft int -.Fn quota_write "struct quotafile *qf" "const struct dqblk *dqb" "int id" +.Fn quota_write_limits "struct quotafile *qf" "struct dqblk *dqb" "int id" +.Ft int +.Fn quota_write_usage "struct quotafile *qf" "struct dqblk *dqb" "int id" .Ft int .Fn quota_close "struct quotafile *qf" -.Ft int -.Fn hasquota "struct fstab *fs" "int type" "char **qfnamep" .Sh DESCRIPTION +These functions are designed to simplify access to filesystem quotas. +If quotas are active on a filesystem, +these functions will access them directly from the kernel using the +.Fn quotactl +system call. +If quotas are not active, +these functions will access them by reading and writing +the quota files directly. +.Pp +The +.Fn quota_open +function takes a pointer to an +.Vt fstab +entry corresponding to the filesystem on which quotas +are to be accessed. +The +.Va quotatype +field indicates the type of quotas being sought, either +.Dv USRQUOTA +or +.Dv GRPQUOTA . +The +.Va openflags +are those used by the +.Fn open +system call, usually either +.Dv O_RDONLY +if the quotas are just to be read, or +.Dv O_RDWR +if the quotas are to be updated. +The +.Dv O_CREAT +flag should be specified if a new quota file of the requested type should +be created if it does not already exist. +.Pp +The +.Fn quota_read +function reads the quota from the filesystem and quota type referenced by +.Va qf +for the user (or group) specified by +.Va id +into the +.Vt dqblk +quota structure pointed to by +.Va dqb . +.Pp +The +.Fn quota_write_limits +function updates the limit fields (but not the usage fields) +for the filesystem and quota type referenced by +.Va qf +for the user (or group) specified by +.Va id +from the +.Vt dqblk +quota structure pointed to by +.Va dqb . +.Pp +The +.Fn quota_write_usage +function updates the usage fields (but not the limit fields) +for the filesystem and quota type referenced by +.Va qf +for the user (or group) specified by +.Va id +from the +.Vt dqblk +quota structure pointed to by +.Va dqb . +.Pp +The +.Fn quota_close +function closes any open file descriptors and frees any storage +associated with the filesystem and quota type referenced by +.Va qf . .Sh RETURN VALUES +If the filesystem has quotas associated with it, +.Fn quota_open +returns a pointer to a +.Vt quotafile +structure used in subsequent quota access calls. +If the filesystem has no quotas, or access permission is denied +.Dv NULL +is returned and +.Va errno +is set to indicate the cause of failure. +.Pp +The +.Fn quota_read , +.Fn quota_write_limits , +.Fn quota_write_usage , +and +.Fn quota_close +functions return zero on success. +On error they return +.Dv -1 +and set +.Va errno +to indicate the cause of failure. .Sh SEE ALSO .Xr quotactl 2 , .Xr quota.user 5 , @@ -68,4 +165,6 @@ functions first appeared in The .Nm functions and this manual page were written by -.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org . +.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org +and +.An Marshall Kirk McKusick . diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 2b43b65a382..58c02b1c169 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2008 Dag-Erling Coïdan Smørgrav + * Copyright (c) 2008 Marshall Kirk McKusick * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,76 +48,132 @@ #include struct quotafile { - int fd; - int type; /* 32 or 64 */ + int fd; /* -1 means using quotactl for access */ + int wordsize; /* 32-bit or 64-bit limits */ + int quotatype; /* USRQUOTA or GRPQUOTA */ + char fsname[MAXPATHLEN + 1]; /* mount point of filesystem */ + char qfname[MAXPATHLEN + 1]; /* quota file if not using quotactl */ }; static const char *qfextension[] = INITQFNAMES; -struct quotafile * -quota_open(const char *fn) +/* + * Check to see if a particular quota is to be enabled. + */ +static int +hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) { - struct quotafile *qf; - struct dqhdr64 dqh; - int serrno; + char *opt; + char *cp; + struct statfs sfb; + char buf[BUFSIZ]; + static char initname, usrname[100], grpname[100]; - if ((qf = calloc(1, sizeof(*qf))) == NULL) - return (NULL); - if ((qf->fd = open(fn, O_RDWR)) < 0) { - serrno = errno; - free(qf); - errno = serrno; - return (NULL); + if (!initname) { + (void)snprintf(usrname, sizeof(usrname), "%s%s", + qfextension[USRQUOTA], QUOTAFILENAME); + (void)snprintf(grpname, sizeof(grpname), "%s%s", + qfextension[GRPQUOTA], QUOTAFILENAME); + initname = 1; } - qf->type = 32; - switch (read(qf->fd, &dqh, sizeof(dqh))) { - case -1: - serrno = errno; - close(qf->fd); - free(qf); - errno = serrno; - return (NULL); - case sizeof(dqh): - if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) != 0) { - /* no magic, assume 32 bits */ - qf->type = 32; - return (qf); - } - if (be32toh(dqh.dqh_version) != Q_DQHDR64_VERSION || - be32toh(dqh.dqh_hdrlen) != sizeof(struct dqhdr64) || - be32toh(dqh.dqh_reclen) != sizeof(struct dqblk64)) { - /* correct magic, wrong version / lengths */ - close(qf->fd); - free(qf); - errno = EINVAL; - return (NULL); - } - qf->type = 64; - return (qf); - default: - qf->type = 32; - return (qf); + strcpy(buf, fs->fs_mntops); + for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { + if ((cp = index(opt, '='))) + *cp++ = '\0'; + if (type == USRQUOTA && strcmp(opt, usrname) == 0) + break; + if (type == GRPQUOTA && strcmp(opt, grpname) == 0) + break; } - /* not reached */ + if (!opt) + return (0); + /* + * Ensure that the filesystem is mounted. + */ + if (statfs(fs->fs_file, &sfb) != 0 || + strcmp(fs->fs_file, sfb.f_mntonname)) { + return (0); + } + if (cp) { + strncpy(qfnamep, cp, qfbufsize); + } else { + (void)snprintf(qfnamep, qfbufsize, "%s/%s.%s", fs->fs_file, + QUOTAFILENAME, qfextension[type]); + } + return (1); } struct quotafile * -quota_create(const char *fn) +quota_open(struct fstab *fs, int quotatype, int openflags) { struct quotafile *qf; struct dqhdr64 dqh; struct group *grp; - int serrno; + int qcmd, serrno; if ((qf = calloc(1, sizeof(*qf))) == NULL) return (NULL); - if ((qf->fd = open(fn, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) { + qf->quotatype = quotatype; + strncpy(qf->fsname, fs->fs_file, sizeof(qf->fsname)); + qcmd = QCMD(Q_GETQUOTA, quotatype); + if (quotactl(fs->fs_file, qcmd, 0, &dqh) == 0) { + qf->wordsize = 64; + qf->fd = -1; + return (qf); + } + if (!hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname))) { + free(qf); + errno = EOPNOTSUPP; + return (NULL); + } + if ((qf->fd = open(qf->qfname, openflags & O_ACCMODE)) < 0 && + (openflags & O_CREAT) == 0) { serrno = errno; free(qf); errno = serrno; return (NULL); } - qf->type = 64; + /* File open worked, so process it */ + if (qf->fd != -1) { + qf->wordsize = 32; + switch (read(qf->fd, &dqh, sizeof(dqh))) { + case -1: + serrno = errno; + close(qf->fd); + free(qf); + errno = serrno; + return (NULL); + case sizeof(dqh): + if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) != 0) { + /* no magic, assume 32 bits */ + qf->wordsize = 32; + return (qf); + } + if (be32toh(dqh.dqh_version) != Q_DQHDR64_VERSION || + be32toh(dqh.dqh_hdrlen) != sizeof(struct dqhdr64) || + be32toh(dqh.dqh_reclen) != sizeof(struct dqblk64)) { + /* correct magic, wrong version / lengths */ + close(qf->fd); + free(qf); + errno = EINVAL; + return (NULL); + } + qf->wordsize = 64; + return (qf); + default: + qf->wordsize = 32; + return (qf); + } + /* not reached */ + } + /* Open failed above, but O_CREAT specified, so create a new file */ + if ((qf->fd = open(qf->qfname, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) { + serrno = errno; + free(qf); + errno = serrno; + return (NULL); + } + qf->wordsize = 64; memset(&dqh, 0, sizeof(dqh)); memcpy(dqh.dqh_magic, Q_DQHDR64_MAGIC, sizeof(dqh.dqh_magic)); dqh.dqh_version = htobe32(Q_DQHDR64_VERSION); @@ -124,7 +181,7 @@ quota_create(const char *fn) dqh.dqh_reclen = htobe32(sizeof(struct dqblk64)); if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) { serrno = errno; - unlink(fn); + unlink(qf->qfname); close(qf->fd); free(qf); errno = serrno; @@ -140,7 +197,8 @@ void quota_close(struct quotafile *qf) { - close(qf->fd); + if (qf->fd != -1) + close(qf->fd); free(qf); } @@ -203,8 +261,13 @@ quota_read64(struct quotafile *qf, struct dqblk *dqb, int id) int quota_read(struct quotafile *qf, struct dqblk *dqb, int id) { + int qcmd; - switch (qf->type) { + if (qf->fd == -1) { + qcmd = QCMD(Q_GETQUOTA, qf->quotatype); + return (quotactl(qf->fsname, qcmd, id, dqb)); + } + switch (qf->wordsize) { case 32: return quota_read32(qf, dqb, id); case 64: @@ -236,7 +299,9 @@ quota_write32(struct quotafile *qf, const struct dqblk *dqb, int id) off = id * sizeof(struct dqblk32); if (lseek(qf->fd, off, SEEK_SET) == -1) return (-1); - return (write(qf->fd, &dqb32, sizeof(dqb32)) == sizeof(dqb32)); + if (write(qf->fd, &dqb32, sizeof(dqb32)) == sizeof(dqb32)) + return (0); + return (-1); } static int @@ -257,14 +322,98 @@ quota_write64(struct quotafile *qf, const struct dqblk *dqb, int id) off = sizeof(struct dqhdr64) + id * sizeof(struct dqblk64); if (lseek(qf->fd, off, SEEK_SET) == -1) return (-1); - return (write(qf->fd, &dqb64, sizeof(dqb64)) == sizeof(dqb64)); + if (write(qf->fd, &dqb64, sizeof(dqb64)) == sizeof(dqb64)) + return (0); + return (-1); } int -quota_write(struct quotafile *qf, const struct dqblk *dqb, int id) +quota_write_usage(struct quotafile *qf, struct dqblk *dqb, int id) { + struct dqblk dqbuf; + int qcmd; - switch (qf->type) { + if (qf->fd == -1) { + qcmd = QCMD(Q_SETUSE, qf->quotatype); + return (quotactl(qf->fsname, qcmd, id, dqb)); + } + /* + * Have to do read-modify-write of quota in file. + */ + if (quota_read(qf, &dqbuf, id) != 0) + return (-1); + /* + * Reset time limit if have a soft limit and were + * previously under it, but are now over it. + */ + if (dqbuf.dqb_bsoftlimit && id != 0 && + dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && + dqb->dqb_curblocks >= dqbuf.dqb_bsoftlimit) + dqbuf.dqb_btime = 0; + if (dqbuf.dqb_isoftlimit && id != 0 && + dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit && + dqb->dqb_curinodes >= dqbuf.dqb_isoftlimit) + dqbuf.dqb_itime = 0; + dqbuf.dqb_curinodes = dqb->dqb_curinodes; + dqbuf.dqb_curblocks = dqb->dqb_curblocks; + /* + * Write it back. + */ + switch (qf->wordsize) { + case 32: + return quota_write32(qf, &dqbuf, id); + case 64: + return quota_write64(qf, &dqbuf, id); + default: + errno = EINVAL; + return (-1); + } + /* not reached */ +} + +int +quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id) +{ + struct dqblk dqbuf; + int qcmd; + + if (qf->fd == -1) { + qcmd = QCMD(Q_SETQUOTA, qf->quotatype); + return (quotactl(qf->fsname, qcmd, id, dqb)); + } + /* + * Have to do read-modify-write of quota in file. + */ + if (quota_read(qf, &dqbuf, id) != 0) + return (-1); + /* + * Reset time limit if have a soft limit and were + * previously under it, but are now over it + * or if there previously was no soft limit, but + * now have one and are over it. + */ + if (dqbuf.dqb_bsoftlimit && id != 0 && + dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= dqb->dqb_bsoftlimit) + dqb->dqb_btime = 0; + if (dqbuf.dqb_bsoftlimit == 0 && id != 0 && + dqb->dqb_bsoftlimit > 0 && + dqbuf.dqb_curblocks >= dqb->dqb_bsoftlimit) + dqb->dqb_btime = 0; + if (dqbuf.dqb_isoftlimit && id != 0 && + dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= dqb->dqb_isoftlimit) + dqb->dqb_itime = 0; + if (dqbuf.dqb_isoftlimit == 0 && id !=0 && + dqb->dqb_isoftlimit > 0 && + dqbuf.dqb_curinodes >= dqb->dqb_isoftlimit) + dqb->dqb_itime = 0; + dqb->dqb_curinodes = dqbuf.dqb_curinodes; + dqb->dqb_curblocks = dqbuf.dqb_curblocks; + /* + * Write it back. + */ + switch (qf->wordsize) { case 32: return quota_write32(qf, dqb, id); case 64: @@ -275,49 +424,3 @@ quota_write(struct quotafile *qf, const struct dqblk *dqb, int id) } /* not reached */ } - -/* - * Check to see if a particular quota is to be enabled. - */ -int -hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) -{ - char *opt; - char *cp; - struct statfs sfb; - char buf[BUFSIZ]; - static char initname, usrname[100], grpname[100]; - - if (!initname) { - (void)snprintf(usrname, sizeof(usrname), "%s%s", - qfextension[USRQUOTA], QUOTAFILENAME); - (void)snprintf(grpname, sizeof(grpname), "%s%s", - qfextension[GRPQUOTA], QUOTAFILENAME); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - /* - * Ensure that the filesystem is mounted. - */ - if (statfs(fs->fs_file, &sfb) != 0 || - strcmp(fs->fs_file, sfb.f_mntonname)) { - return (0); - } - if (cp) { - strncpy(qfnamep, cp, qfbufsize); - } else { - (void)snprintf(qfnamep, qfbufsize, "%s/%s.%s", fs->fs_file, - QUOTAFILENAME, qfextension[type]); - } - return (1); -} diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index 16594cff3ab..b2e57a155ed 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -84,16 +84,15 @@ __FBSDID("$FreeBSD$"); #endif const char *qfextension[] = INITQFNAMES; -const char *quotagroup = QUOTAGROUP; char tmpfil[] = _PATH_TMP; int hflag; struct quotause { struct quotause *next; - long flags; + struct quotafile *qf; struct dqblk dqblk; + int flags; char fsname[MAXPATHLEN + 1]; - char qfname[1]; /* actually longer */ }; #define FOUND 0x01 @@ -108,7 +107,7 @@ char *fmthumanvalinos(int64_t); void freeprivs(struct quotause *); int getentry(const char *, int); struct quotause *getprivs(long, int, char *); -void putprivs(long, int, struct quotause *); +void putprivs(long, struct quotause *); int readprivs(struct quotause *, char *); int readtimes(struct quotause *, char *); static void usage(void); @@ -142,6 +141,11 @@ main(int argc, char *argv[]) fspath = optarg; break; case 'p': + if (eflag) { + warnx("cannot specify both -e and -p"); + usage(); + /* not reached */ + } protoname = optarg; pflag++; break; @@ -158,7 +162,12 @@ main(int argc, char *argv[]) tflag++; break; case 'e': - if ((qup = calloc(1, sizeof(*qup) + BUFSIZ)) == NULL) + if (pflag) { + warnx("cannot specify both -e and -p"); + usage(); + /* not reached */ + } + if ((qup = calloc(1, sizeof(*qup))) == NULL) errx(2, "out of memory"); oldoptarg = optarg; for (i = 0, cp = optarg; @@ -214,7 +223,6 @@ main(int argc, char *argv[]) curprivs = qup; } eflag++; - pflag++; break; default: usage(); @@ -223,8 +231,8 @@ main(int argc, char *argv[]) } argc -= optind; argv += optind; - if (pflag) { - if (protoprivs == NULL) { + if (pflag || eflag) { + if (pflag) { if ((protoid = getentry(protoname, quotatype)) == -1) exit(1); protoprivs = getprivs(protoid, quotatype, fspath); @@ -259,22 +267,23 @@ main(int argc, char *argv[]) *argv); if ((id = getentry(buf, quotatype)) < 0) continue; - if (!eflag) { - putprivs(id, quotatype, protoprivs); + if (pflag) { + putprivs(id, protoprivs); continue; } - for (qup = protoprivs; qup; - qup = qup->next) { + for (qup = protoprivs; qup; qup = qup->next) { curprivs = getprivs(id, quotatype, qup->fsname); if (curprivs == NULL) continue; - strcpy(qup->qfname, curprivs->qfname); - strcpy(qup->fsname, curprivs->fsname); - putprivs(id, quotatype, protoprivs); + curprivs->dqblk = qup->dqblk; + putprivs(id, curprivs); + freeprivs(curprivs); } } } + if (pflag) + freeprivs(protoprivs); exit(0); } tmpfd = mkstemp(tmpfil); @@ -283,7 +292,7 @@ main(int argc, char *argv[]) if ((protoprivs = getprivs(0, quotatype, fspath)) != NULL) { if (writetimes(protoprivs, tmpfd, quotatype) != 0 && editit(tmpfil) && readtimes(protoprivs, tmpfil)) - putprivs(0L, quotatype, protoprivs); + putprivs(0L, protoprivs); freeprivs(protoprivs); } close(tmpfd); @@ -298,7 +307,7 @@ main(int argc, char *argv[]) if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) continue; if (editit(tmpfil) && readprivs(curprivs, tmpfil)) - putprivs(id, quotatype, curprivs); + putprivs(id, curprivs); freeprivs(curprivs); } close(tmpfd); @@ -366,46 +375,29 @@ getprivs(long id, int quotatype, char *fspath) struct fstab *fs; struct quotause *qup, *quptail; struct quotause *quphead; - int qcmd, qupsize; - char *qfpathname; - static int warned = 0; setfsent(); quphead = quptail = NULL; - qcmd = QCMD(Q_GETQUOTA, quotatype); while ((fs = getfsent())) { if (fspath && *fspath && strcmp(fspath, fs->fs_spec) && strcmp(fspath, fs->fs_file)) continue; if (strcmp(fs->fs_vfstype, "ufs")) continue; - if (!hasquota(fs, quotatype, &qfpathname)) + if ((qf = quota_open(fs, quotatype, O_CREAT|O_RDWR)) == NULL) { + if (errno != EOPNOTSUPP) + warn("cannot open quotas on %s", fs->fs_file); + continue; + } + if ((qup = (struct quotause *)calloc(1, sizeof(*qup))) == NULL) + errx(2, "out of memory"); + qup->qf = qf; + strncpy(qup->fsname, fs->fs_file, sizeof(qup->fsname)); + if (quota_read(qf, &qup->dqblk, id) == -1) { + warn("cannot read quotas on %s", fs->fs_file); + freeprivs(qup); continue; - qupsize = sizeof(*qup) + strlen(qfpathname); - if ((qup = (struct quotause *)malloc(qupsize)) == NULL) - errx(2, "out of memory"); - if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) { - if (errno == EOPNOTSUPP && !warned) { - warned++; - warnx("warning: quotas are not compiled into this kernel"); - sleep(3); - } - if ((qf = quota_open(qfpathname)) == NULL && - (qf = quota_create(qfpathname)) == NULL) { - warn("%s", qfpathname); - free(qup); - continue; - } - if (quota_read(qf, &qup->dqblk, id) != 0) { - warn("read error in %s", qfpathname); - quota_close(qf); - free(qup); - continue; - } - quota_close(qf); } - strcpy(qup->qfname, qfpathname); - strcpy(qup->fsname, fs->fs_file); if (quphead == NULL) quphead = qup; else @@ -424,53 +416,13 @@ getprivs(long id, int quotatype, char *fspath) * Store the requested quota information. */ void -putprivs(long id, int quotatype, struct quotause *quplist) +putprivs(long id, struct quotause *quplist) { - struct quotafile *qf; struct quotause *qup; - int qcmd; - struct dqblk dqbuf; - qcmd = QCMD(Q_SETQUOTA, quotatype); - for (qup = quplist; qup; qup = qup->next) { - if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0) - continue; - if ((qf = quota_open(qup->qfname)) == NULL) { - warn("%s", qup->qfname); - continue; - } - if (quota_read(qf, &dqbuf, id) != 0) { - warn("read error in %s", qup->qfname); - quota_close(qf); - continue; - } - /* - * Reset time limit if have a soft limit and were - * previously under it, but are now over it - * or if there previously was no soft limit, but - * now have one and are over it. - */ - if (dqbuf.dqb_bsoftlimit && id != 0 && - dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && - dqbuf.dqb_curblocks >= qup->dqblk.dqb_bsoftlimit) - qup->dqblk.dqb_btime = 0; - if (dqbuf.dqb_bsoftlimit == 0 && id != 0 && - dqbuf.dqb_curblocks >= qup->dqblk.dqb_bsoftlimit) - qup->dqblk.dqb_btime = 0; - if (dqbuf.dqb_isoftlimit && id != 0 && - dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit && - dqbuf.dqb_curinodes >= qup->dqblk.dqb_isoftlimit) - qup->dqblk.dqb_itime = 0; - if (dqbuf.dqb_isoftlimit == 0 && id !=0 && - dqbuf.dqb_curinodes >= qup->dqblk.dqb_isoftlimit) - qup->dqblk.dqb_itime = 0; - qup->dqblk.dqb_curinodes = dqbuf.dqb_curinodes; - qup->dqblk.dqb_curblocks = dqbuf.dqb_curblocks; - if (quota_write(qf, &qup->dqblk, id) == 0) { - warn("%s", qup->qfname); - } - quota_close(qf); - } + for (qup = quplist; qup; qup = qup->next) + if (quota_write_limits(qup->qf, &qup->dqblk, id) == -1) + warn("%s", qup->fsname); } /* @@ -978,6 +930,7 @@ freeprivs(struct quotause *quplist) struct quotause *qup, *nextqup; for (qup = quplist; qup; qup = nextqup) { + quota_close(qup->qf); nextqup = qup->next; free(qup); } From 91b2a3e2047d5ec6b2a753119be9ace40e4a8631 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 25 Sep 2009 18:44:34 +0000 Subject: [PATCH 014/532] Improve comments, and remove a bogus 0 id check. --- sys/ufs/ufs/ufs_quota.c | 51 ++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index ddba6010100..04d28e434d2 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -60,6 +60,8 @@ __FBSDID("$FreeBSD$"); #include #include +CTASSERT(sizeof(struct dqblk64) == sizeof(struct dqhdr64)); + static int unprivileged_get_quota = 0; SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_get_quota, CTLFLAG_RW, &unprivileged_get_quota, 0, @@ -1124,6 +1126,14 @@ dqhashfind(struct dqhash *dqh, u_long id, struct vnode *dqvp) /* * Determine the quota file type. + * + * A 32-bit quota file is simply an array of struct dqblk32. + * + * A 64-bit quota file is a struct dqhdr64 followed by an array of struct + * dqblk64. The header contains various magic bits which allow us to be + * reasonably confident that it is indeeda 64-bit quota file and not just + * a 32-bit quota file that just happens to "look right". + * */ static int dqopen(struct vnode *vp, struct ufsmount *ump, int type) @@ -1312,23 +1322,8 @@ hfound: DQI_LOCK(dq); /* * Read the requested quota record from the quota file, performing * any necessary conversions. - * - * The record's offset within the file depends on the size of the - * record, which means we need to know whether it's a 32-bit file - * or a 64-bit file. - * - * Luckily, root's record is always at offset 0, and most of it is - * unused, so we can use it to store a magic number indicating the - * file format. Due to an acute lack of imagination, this magic - * number, stored in the first byte of root's record and hence the - * first byte of the file, is 64. - * - * Another lucky break is that quotaon() always loads root's - * record, to get the default values for dq_btime and dq_itime, so - * we will always have a chance to check the file format before - * being asked for a "real" record. */ - if (id == 0 || (ump->um_qflags[type] & QTF_64BIT)) { + if (ump->um_qflags[type] & QTF_64BIT) { recsize = sizeof(struct dqblk64); base = sizeof(struct dqhdr64); } else { @@ -1597,6 +1592,10 @@ dqflush(struct vnode *vp) #define CLIP32(u64) (u64 > UINT32_MAX ? UINT32_MAX : (uint32_t)u64) +/* + * Convert on-disk 32-bit host-order structure to in-memory 64-bit + * host-order structure. + */ static void dqb32_dq(const struct dqblk32 *dqb32, struct dquot *dq) { @@ -1611,6 +1610,10 @@ dqb32_dq(const struct dqblk32 *dqb32, struct dquot *dq) dq->dq_itime = dqb32->dqb_itime; } +/* + * Convert on-disk 64-bit network-order structure to in-memory 64-bit + * host-order structure. + */ static void dqb64_dq(const struct dqblk64 *dqb64, struct dquot *dq) { @@ -1625,6 +1628,10 @@ dqb64_dq(const struct dqblk64 *dqb64, struct dquot *dq) dq->dq_itime = be64toh(dqb64->dqb_itime); } +/* + * Convert in-memory 64-bit host-order structure to on-disk 32-bit + * host-order structure. + */ static void dq_dqb32(const struct dquot *dq, struct dqblk32 *dqb32) { @@ -1639,6 +1646,10 @@ dq_dqb32(const struct dquot *dq, struct dqblk32 *dqb32) dqb32->dqb_itime = CLIP32(dq->dq_itime); } +/* + * Convert in-memory host-order 64-bit structure to on-disk 64-bit + * network-order structure. + */ static void dq_dqb64(const struct dquot *dq, struct dqblk64 *dqb64) { @@ -1653,6 +1664,10 @@ dq_dqb64(const struct dquot *dq, struct dqblk64 *dqb64) dqb64->dqb_itime = htobe64(dq->dq_itime); } +/* + * Convert in-memory 64-bit host-order structure to in-memory 32-bit + * host-order structure. + */ static void dqb64_dqb32(const struct dqblk64 *dqb64, struct dqblk32 *dqb32) { @@ -1667,6 +1682,10 @@ dqb64_dqb32(const struct dqblk64 *dqb64, struct dqblk32 *dqb32) dqb32->dqb_itime = CLIP32(dqb64->dqb_itime); } +/* + * Convert in-memory 32-bit host-order structure to in-memory 64-bit + * host-order structure. + */ static void dqb32_dqb64(const struct dqblk32 *dqb32, struct dqblk64 *dqb64) { From 0bb2e5de607991a2c9d5ed9e27956ddd8d60fb35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 25 Sep 2009 18:50:33 +0000 Subject: [PATCH 015/532] Further improve comments. --- sys/ufs/ufs/ufs_quota.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 04d28e434d2..5b1da50b73a 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -1593,8 +1593,7 @@ dqflush(struct vnode *vp) #define CLIP32(u64) (u64 > UINT32_MAX ? UINT32_MAX : (uint32_t)u64) /* - * Convert on-disk 32-bit host-order structure to in-memory 64-bit - * host-order structure. + * Convert 32-bit host-order structure to dquot. */ static void dqb32_dq(const struct dqblk32 *dqb32, struct dquot *dq) @@ -1611,8 +1610,7 @@ dqb32_dq(const struct dqblk32 *dqb32, struct dquot *dq) } /* - * Convert on-disk 64-bit network-order structure to in-memory 64-bit - * host-order structure. + * Convert 64-bit network-order structure to dquot. */ static void dqb64_dq(const struct dqblk64 *dqb64, struct dquot *dq) @@ -1629,8 +1627,7 @@ dqb64_dq(const struct dqblk64 *dqb64, struct dquot *dq) } /* - * Convert in-memory 64-bit host-order structure to on-disk 32-bit - * host-order structure. + * Convert dquot to 32-bit host-order structure. */ static void dq_dqb32(const struct dquot *dq, struct dqblk32 *dqb32) @@ -1647,8 +1644,7 @@ dq_dqb32(const struct dquot *dq, struct dqblk32 *dqb32) } /* - * Convert in-memory host-order 64-bit structure to on-disk 64-bit - * network-order structure. + * Convert dquot to 64-bit network-order structure. */ static void dq_dqb64(const struct dquot *dq, struct dqblk64 *dqb64) @@ -1665,8 +1661,7 @@ dq_dqb64(const struct dquot *dq, struct dqblk64 *dqb64) } /* - * Convert in-memory 64-bit host-order structure to in-memory 32-bit - * host-order structure. + * Convert 64-bit host-order structure to 32-bit host-order structure. */ static void dqb64_dqb32(const struct dqblk64 *dqb64, struct dqblk32 *dqb32) @@ -1683,8 +1678,7 @@ dqb64_dqb32(const struct dqblk64 *dqb64, struct dqblk32 *dqb32) } /* - * Convert in-memory 32-bit host-order structure to in-memory 64-bit - * host-order structure. + * Convert 32-bit host-order structure to 64-bit host-order structure. */ static void dqb32_dqb64(const struct dqblk32 *dqb32, struct dqblk64 *dqb64) From fdd356a8d1e79def831b31494da89efbac6bb028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 25 Sep 2009 23:27:07 +0000 Subject: [PATCH 016/532] Style --- lib/libutil/quotafile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 58c02b1c169..98f6f7c2d68 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -269,9 +269,9 @@ quota_read(struct quotafile *qf, struct dqblk *dqb, int id) } switch (qf->wordsize) { case 32: - return quota_read32(qf, dqb, id); + return (quota_read32(qf, dqb, id)); case 64: - return quota_read64(qf, dqb, id); + return (quota_read64(qf, dqb, id)); default: errno = EINVAL; return (-1); @@ -361,9 +361,9 @@ quota_write_usage(struct quotafile *qf, struct dqblk *dqb, int id) */ switch (qf->wordsize) { case 32: - return quota_write32(qf, &dqbuf, id); + return (quota_write32(qf, &dqbuf, id)); case 64: - return quota_write64(qf, &dqbuf, id); + return (quota_write64(qf, &dqbuf, id)); default: errno = EINVAL; return (-1); @@ -415,9 +415,9 @@ quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id) */ switch (qf->wordsize) { case 32: - return quota_write32(qf, dqb, id); + return (quota_write32(qf, dqb, id)); case 64: - return quota_write64(qf, dqb, id); + return (quota_write64(qf, dqb, id)); default: errno = EINVAL; return (-1); From 5666aadb3ddf92915fa484c460bcf9623d08fcf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 26 Sep 2009 23:16:06 +0000 Subject: [PATCH 017/532] Further extend the quotafile API. --- lib/libutil/Makefile | 6 ++- lib/libutil/libutil.h | 5 +- lib/libutil/quotafile.3 | 67 ++++++++++++++++++++++---- lib/libutil/quotafile.c | 101 +++++++++++++++++++++++++++------------- 4 files changed, 137 insertions(+), 42 deletions(-) diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index d7bd6dc145a..6b489d3b9d3 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -60,8 +60,12 @@ MLINKS+=pidfile.3 pidfile_open.3 \ pidfile.3 pidfile_close.3 \ pidfile.3 pidfile_remove.3 MLINKS+=quotafile.3 quota_open.3 \ + quotafile.3 quota_fsname.3 \ + quotafile.3 quota_qfname.3 \ + quotafile.3 quota_statfs.3 \ quotafile.3 quota_read.3 \ - quotafile.3 quota_write.3 \ + quotafile.3 quota_write_limits.3 \ + quotafile.3 quota_write_usage.3 \ quotafile.3 quota_close.3 .include diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index afd5db6d228..2190a532f79 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -144,10 +144,13 @@ int pidfile_remove(struct pidfh *pfh); struct quotafile; struct fstab; struct quotafile *quota_open(struct fstab *, int, int); -void quota_close(struct quotafile *); +const char *quota_fsname(const struct quotafile *); +const char *quota_qfname(const struct quotafile *); +int quota_check_path(const struct quotafile *, const char *path); int quota_read(struct quotafile *, struct dqblk *, int); int quota_write_limits(struct quotafile *, struct dqblk *, int); int quota_write_usage(struct quotafile *, struct dqblk *, int); +void quota_close(struct quotafile *); #endif __END_DECLS diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index 07a08a20c18..4762bf92558 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -25,11 +25,14 @@ .\" .\" $FreeBSD$ .\" -.Dd February 14, 2009 +.Dd September 26, 2009 .Dt QUOTAFILE 3 .Os .Sh NAME .Nm quota_open +.Nm quota_fsname +.Nm quota_qfname +.Nm quota_check_path .Nm quota_read .Nm quota_write_limits .Nm quota_write_usage @@ -38,11 +41,19 @@ .Sh LIBRARY .Lb libutil .Sh SYNOPSIS +.In sys/param.h +.In sys/mount.h .In ufs/ufs/quota.h .In libutil.h .In fstab.h .Ft "struct quotafile *" .Fn quota_open "struct fstab *fs" "int quotatype" "int openflags" +.Ft "const char *" +.Fn quota_fsname "const struct quotafile *qf" +.Ft "const char *" +.Fn quota_qfname "const struct quotafile *qf" +.Ft int +.Fn quota_check_path "const struct quotafile *qf" "const char *path" .Ft int .Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int id" .Ft int @@ -84,12 +95,42 @@ if the quotas are just to be read, or if the quotas are to be updated. The .Dv O_CREAT -flag should be specified if a new quota file of the requested type should -be created if it does not already exist. +flag should be specified if a new quota file of the requested type +should be created if it does not already exist. +.Pp +The +.Fn quota_fsname +function returns a pointer to a buffer containing the path to the root +of the file system that corresponds to its +.Va qf +argument, as listed in +.Pa /etc/fstab . +Note that this may be a symbolic link to the actual directory. +.Pp +The +.Fn quota_qfname +function returns a pointer to a buffer containing the name of the +quota file that corresponds to its +.Va qf +argument. +Note that this may be a symbolic link to the actual file. +.Pp +The +.Fn quota_check_path +function checks if the specified path is within the filesystem that +corresponds to its +.Va qf +argument. +If the +.Va path +argument refers to a symbolic link, +.Fn quota_check_path +will follow it. .Pp The .Fn quota_read -function reads the quota from the filesystem and quota type referenced by +function reads the quota from the filesystem and quota type referenced +by .Va qf for the user (or group) specified by .Va id @@ -127,6 +168,9 @@ The function closes any open file descriptors and frees any storage associated with the filesystem and quota type referenced by .Va qf . +.Sh IMPLEMENTATION NOTES +If the underlying quota file is in the old 32-bit format, limit and +usage values written to the quota file will be clipped to 32 bits. .Sh RETURN VALUES If the filesystem has quotas associated with it, .Fn quota_open @@ -137,7 +181,15 @@ If the filesystem has no quotas, or access permission is denied .Dv NULL is returned and .Va errno -is set to indicate the cause of failure. +is set to indicate the error. +.Pp +The +.Fn quota_check_path +function returns\~1 for a positive result and\~0 for a negative +result. +If an error occurs, it returns\~-1 and sets +.Va errno +to indicate the error. .Pp The .Fn quota_read , @@ -146,11 +198,10 @@ The and .Fn quota_close functions return zero on success. -On error they return -.Dv -1 +On error they return\~-1 and set .Va errno -to indicate the cause of failure. +to indicate the error. .Sh SEE ALSO .Xr quotactl 2 , .Xr quota.user 5 , diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 98f6f7c2d68..6dcb6979fb1 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -49,8 +49,10 @@ struct quotafile { int fd; /* -1 means using quotactl for access */ + int accmode; /* access mode */ int wordsize; /* 32-bit or 64-bit limits */ int quotatype; /* USRQUOTA or GRPQUOTA */ + dev_t dev; /* device */ char fsname[MAXPATHLEN + 1]; /* mount point of filesystem */ char qfname[MAXPATHLEN + 1]; /* quota file if not using quotactl */ }; @@ -59,6 +61,7 @@ static const char *qfextension[] = INITQFNAMES; /* * Check to see if a particular quota is to be enabled. + * XXX merge into quota_open */ static int hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) @@ -69,6 +72,11 @@ hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) char buf[BUFSIZ]; static char initname, usrname[100], grpname[100]; + /* + * XXX + * 1) we only need one of these + * 2) fstab may specify a different filename + */ if (!initname) { (void)snprintf(usrname, sizeof(usrname), "%s%s", qfextension[USRQUOTA], QUOTAFILENAME); @@ -109,12 +117,17 @@ quota_open(struct fstab *fs, int quotatype, int openflags) struct quotafile *qf; struct dqhdr64 dqh; struct group *grp; + struct stat st; int qcmd, serrno; if ((qf = calloc(1, sizeof(*qf))) == NULL) return (NULL); + qf->fd = -1; qf->quotatype = quotatype; strncpy(qf->fsname, fs->fs_file, sizeof(qf->fsname)); + if (stat(qf->fsname, &st) != 0) + goto error; + qf->dev = st.st_dev; qcmd = QCMD(Q_GETQUOTA, quotatype); if (quotactl(fs->fs_file, qcmd, 0, &dqh) == 0) { qf->wordsize = 64; @@ -122,27 +135,19 @@ quota_open(struct fstab *fs, int quotatype, int openflags) return (qf); } if (!hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname))) { - free(qf); errno = EOPNOTSUPP; - return (NULL); - } - if ((qf->fd = open(qf->qfname, openflags & O_ACCMODE)) < 0 && - (openflags & O_CREAT) == 0) { - serrno = errno; - free(qf); - errno = serrno; - return (NULL); + goto error; } + qf->accmode = openflags & O_ACCMODE; + if ((qf->fd = open(qf->qfname, qf->accmode)) < 0 && + (openflags & O_CREAT) != O_CREAT) + goto error; /* File open worked, so process it */ if (qf->fd != -1) { qf->wordsize = 32; switch (read(qf->fd, &dqh, sizeof(dqh))) { case -1: - serrno = errno; - close(qf->fd); - free(qf); - errno = serrno; - return (NULL); + goto error; case sizeof(dqh): if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) != 0) { /* no magic, assume 32 bits */ @@ -153,10 +158,8 @@ quota_open(struct fstab *fs, int quotatype, int openflags) be32toh(dqh.dqh_hdrlen) != sizeof(struct dqhdr64) || be32toh(dqh.dqh_reclen) != sizeof(struct dqblk64)) { /* correct magic, wrong version / lengths */ - close(qf->fd); - free(qf); errno = EINVAL; - return (NULL); + goto error; } qf->wordsize = 64; return (qf); @@ -166,31 +169,33 @@ quota_open(struct fstab *fs, int quotatype, int openflags) } /* not reached */ } - /* Open failed above, but O_CREAT specified, so create a new file */ - if ((qf->fd = open(qf->qfname, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) { - serrno = errno; - free(qf); - errno = serrno; - return (NULL); - } + /* open failed, but O_CREAT was specified, so create a new file */ + if ((qf->fd = open(qf->qfname, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) + goto error; qf->wordsize = 64; memset(&dqh, 0, sizeof(dqh)); memcpy(dqh.dqh_magic, Q_DQHDR64_MAGIC, sizeof(dqh.dqh_magic)); dqh.dqh_version = htobe32(Q_DQHDR64_VERSION); dqh.dqh_hdrlen = htobe32(sizeof(struct dqhdr64)); dqh.dqh_reclen = htobe32(sizeof(struct dqblk64)); - if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) { - serrno = errno; - unlink(qf->qfname); - close(qf->fd); - free(qf); - errno = serrno; - return (NULL); - } + if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) + goto error; grp = getgrnam(QUOTAGROUP); fchown(qf->fd, 0, grp ? grp->gr_gid : 0); fchmod(qf->fd, 0640); return (qf); +error: + serrno = errno; + /* did we have an open file? */ + if (qf->fd != -1) { + /* was it one we created ourselves? */ + if ((openflags & O_CREAT) == O_CREAT) + unlink(qf->qfname); + close(qf->fd); + } + free(qf); + errno = serrno; + return (NULL); } void @@ -202,6 +207,30 @@ quota_close(struct quotafile *qf) free(qf); } +const char * +quota_fsname(const struct quotafile *qf) +{ + + return (qf->fsname); +} + +const char * +quota_qfname(const struct quotafile *qf) +{ + + return (qf->qfname); +} + +int +quota_check_path(const struct quotafile *qf, const char *path) +{ + struct stat st; + + if (stat(path, &st) == -1) + return (-1); + return (st.st_dev == qf->dev); +} + static int quota_read32(struct quotafile *qf, struct dqblk *dqb, int id) { @@ -333,6 +362,10 @@ quota_write_usage(struct quotafile *qf, struct dqblk *dqb, int id) struct dqblk dqbuf; int qcmd; + if ((qf->accmode & O_RDWR) != O_RDWR) { + errno = EBADF; + return (-1); + } if (qf->fd == -1) { qcmd = QCMD(Q_SETUSE, qf->quotatype); return (quotactl(qf->fsname, qcmd, id, dqb)); @@ -377,6 +410,10 @@ quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id) struct dqblk dqbuf; int qcmd; + if ((qf->accmode & O_RDWR) != O_RDWR) { + errno = EBADF; + return (-1); + } if (qf->fd == -1) { qcmd = QCMD(Q_SETQUOTA, qf->quotatype); return (quotactl(qf->fsname, qcmd, id, dqb)); From 6cfc1c1e184c27e3d9319b2bd9ebafcf50856071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sun, 27 Sep 2009 17:33:26 +0000 Subject: [PATCH 018/532] type / format fixup --- usr.sbin/edquota/edquota.c | 70 +++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/usr.sbin/edquota/edquota.c b/usr.sbin/edquota/edquota.c index b2e57a155ed..69ea497fa52 100644 --- a/usr.sbin/edquota/edquota.c +++ b/usr.sbin/edquota/edquota.c @@ -97,10 +97,10 @@ struct quotause { #define FOUND 0x01 int alldigits(const char *s); -int cvtatos(u_int64_t, char *, u_int64_t *); -char *cvtstoa(u_int64_t); -u_int64_t cvtblkval(u_int64_t, char, const char *); -u_int64_t cvtinoval(u_int64_t, char, const char *); +int cvtatos(uint64_t, char *, uint64_t *); +char *cvtstoa(uint64_t); +uint64_t cvtblkval(uint64_t, char, const char *); +uint64_t cvtinoval(uint64_t, char, const char *); int editit(char *); char *fmthumanvalblks(int64_t); char *fmthumanvalinos(int64_t); @@ -121,7 +121,7 @@ main(int argc, char *argv[]) long id, protoid; int i, quotatype, range, tmpfd; uid_t startuid, enduid; - u_int64_t lim; + uint64_t lim; char *protoname, *cp, *endpt, *oldoptarg; int eflag = 0, tflag = 0, pflag = 0, ch; char *fspath = NULL; @@ -509,7 +509,7 @@ fmthumanvalblks(int64_t blocks) dbtob(blocks), "", HN_AUTOSCALE, HN_NOSPACE); return (numbuf); } - snprintf(numbuf, sizeof(numbuf), "%lluk", dbtokb(blocks)); + snprintf(numbuf, sizeof(numbuf), "%juk", (uintmax_t)dbtokb(blocks)); return(numbuf); } @@ -523,7 +523,7 @@ fmthumanvalinos(int64_t inos) inos, "", HN_AUTOSCALE, HN_NOSPACE | HN_DIVISOR_1000); return (numbuf); } - snprintf(numbuf, sizeof(numbuf), "%llu", inos); + snprintf(numbuf, sizeof(numbuf), "%ju", (uintmax_t)inos); return(numbuf); } @@ -535,7 +535,7 @@ readprivs(struct quotause *quplist, char *inname) { struct quotause *qup; FILE *fd; - u_int64_t hardlimit, softlimit, curitems; + uintmax_t hardlimit, softlimit, curitems; char hardunits, softunits, curitemunits; int cnt; char *cp; @@ -562,7 +562,7 @@ readprivs(struct quotause *quplist, char *inname) return (0); } cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c)", + " in use: %ju%c, limits (soft = %ju%c, hard = %ju%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); /* @@ -570,17 +570,17 @@ readprivs(struct quotause *quplist, char *inname) */ if (cnt != 6) cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c hard = %llu%c", + " in use: %ju%c, limits (soft = %ju%c hard = %ju%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c hard = %llu%c)", + " in use: %ju%c, limits (soft = %ju%c hard = %ju%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) cnt = sscanf(cp, - " in use: %llu%c, limits (soft = %llu%c, hard = %llu%c", + " in use: %ju%c, limits (soft = %ju%c, hard = %ju%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) { @@ -598,7 +598,7 @@ readprivs(struct quotause *quplist, char *inname) return (0); } cnt = sscanf(&cp[7], - " in use: %llu%c limits (soft = %llu%c, hard = %llu%c)", + " in use: %ju%c limits (soft = %ju%c, hard = %ju%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); /* @@ -606,17 +606,17 @@ readprivs(struct quotause *quplist, char *inname) */ if (cnt != 6) cnt = sscanf(&cp[7], - " in use: %llu%c limits (soft = %llu%c hard = %llu%c", + " in use: %ju%c limits (soft = %ju%c hard = %ju%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) cnt = sscanf(&cp[7], - " in use: %llu%c limits (soft = %llu%c hard = %llu%c)", + " in use: %ju%c limits (soft = %ju%c hard = %ju%c)", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) cnt = sscanf(&cp[7], - " in use: %llu%c limits (soft = %llu%c, hard = %llu%c", + " in use: %ju%c limits (soft = %ju%c, hard = %ju%c", &curitems, &curitemunits, &softlimit, &softunits, &hardlimit, &hardunits); if (cnt != 6) { @@ -717,7 +717,7 @@ readtimes(struct quotause *quplist, char *inname) FILE *fd; int cnt; char *cp; - u_int64_t itime, btime, iseconds, bseconds; + uintmax_t itime, btime, iseconds, bseconds; char *fsp, bunits[10], iunits[10], line1[BUFSIZ]; fd = fopen(inname, "r"); @@ -740,7 +740,7 @@ readtimes(struct quotause *quplist, char *inname) return (0); } cnt = sscanf(cp, - " block grace period: %llu %s file grace period: %llu %s", + " block grace period: %ju %s file grace period: %ju %s", &btime, bunits, &itime, iunits); if (cnt != 4) { warnx("%s:%s: bad format", fsp, cp); @@ -779,21 +779,25 @@ readtimes(struct quotause *quplist, char *inname) * Convert seconds to ASCII times. */ char * -cvtstoa(u_int64_t secs) +cvtstoa(uint64_t secs) { static char buf[20]; if (secs % (24 * 60 * 60) == 0) { secs /= 24 * 60 * 60; - sprintf(buf, "%llu day%s", secs, secs == 1 ? "" : "s"); + sprintf(buf, "%ju day%s", (uintmax_t)secs, + secs == 1 ? "" : "s"); } else if (secs % (60 * 60) == 0) { secs /= 60 * 60; - sprintf(buf, "%llu hour%s", secs, secs == 1 ? "" : "s"); + sprintf(buf, "%ju hour%s", (uintmax_t)secs, + secs == 1 ? "" : "s"); } else if (secs % 60 == 0) { secs /= 60; - sprintf(buf, "%llu minute%s", secs, secs == 1 ? "" : "s"); + sprintf(buf, "%ju minute%s", (uintmax_t)secs, + secs == 1 ? "" : "s"); } else - sprintf(buf, "%llu second%s", secs, secs == 1 ? "" : "s"); + sprintf(buf, "%ju second%s", (uintmax_t)secs, + secs == 1 ? "" : "s"); return (buf); } @@ -801,7 +805,7 @@ cvtstoa(u_int64_t secs) * Convert ASCII input times to seconds. */ int -cvtatos(u_int64_t period, char *units, u_int64_t *seconds) +cvtatos(uint64_t period, char *units, uint64_t *seconds) { if (bcmp(units, "second", 6) == 0) @@ -823,8 +827,8 @@ cvtatos(u_int64_t period, char *units, u_int64_t *seconds) /* * Convert a limit to number of disk blocks. */ -u_int64_t -cvtblkval(u_int64_t limit, char units, const char *itemname) +uint64_t +cvtblkval(uint64_t limit, char units, const char *itemname) { switch(units) { @@ -864,8 +868,9 @@ cvtblkval(u_int64_t limit, char units, const char *itemname) itemname); break; default: - errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n", - limit, units, itemname); + errx(2, "%ju%c: unknown units for %s, specify " + "none, K, M, G, T, P, or E\n", + (uintmax_t)limit, units, itemname); break; } return (limit); @@ -874,8 +879,8 @@ cvtblkval(u_int64_t limit, char units, const char *itemname) /* * Convert a limit to number of inodes. */ -u_int64_t -cvtinoval(u_int64_t limit, char units, const char *itemname) +uint64_t +cvtinoval(uint64_t limit, char units, const char *itemname) { switch(units) { @@ -914,8 +919,9 @@ cvtinoval(u_int64_t limit, char units, const char *itemname) itemname); break; default: - errx(2, "%llu%c: unknown units for %s, specify none, K, M, G, T, P, or E\n", - limit, units, itemname); + errx(2, "%ju%c: unknown units for %s, specify " + "none, K, M, G, T, P, or E\n", + (uintmax_t)limit, units, itemname); break; } return (limit); From 6197731d81b1001aa10bd4371c3f0e9e5796a915 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 20 Oct 2009 05:37:54 +0000 Subject: [PATCH 019/532] Add quota_maxid which returns the maximum user (or group) identifier in an associated quotafile. Needed by repquota. Bug fix in quota_read. --- lib/libutil/libutil.h | 1 + lib/libutil/quotafile.3 | 14 +++++++++++++- lib/libutil/quotafile.c | 26 ++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index 2190a532f79..b5ff6fd9e07 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -146,6 +146,7 @@ struct fstab; struct quotafile *quota_open(struct fstab *, int, int); const char *quota_fsname(const struct quotafile *); const char *quota_qfname(const struct quotafile *); +int quota_maxid(struct quotafile *); int quota_check_path(const struct quotafile *, const char *path); int quota_read(struct quotafile *, struct dqblk *, int); int quota_write_limits(struct quotafile *, struct dqblk *, int); diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index 4762bf92558..d0c27d730b8 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -32,6 +32,7 @@ .Nm quota_open .Nm quota_fsname .Nm quota_qfname +.Nm quota_maxid .Nm quota_check_path .Nm quota_read .Nm quota_write_limits @@ -44,8 +45,9 @@ .In sys/param.h .In sys/mount.h .In ufs/ufs/quota.h -.In libutil.h +.In fcntl.h .In fstab.h +.In libutil.h .Ft "struct quotafile *" .Fn quota_open "struct fstab *fs" "int quotatype" "int openflags" .Ft "const char *" @@ -53,6 +55,8 @@ .Ft "const char *" .Fn quota_qfname "const struct quotafile *qf" .Ft int +.Fn quota_maxid "const struct quotafile *qf" +.Ft int .Fn quota_check_path "const struct quotafile *qf" "const char *path" .Ft int .Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int id" @@ -116,6 +120,14 @@ argument. Note that this may be a symbolic link to the actual file. .Pp The +.Fn quota_maxid +function returns the maximum user (or group) +.Va id +contained in the quota file associated with its +.Va qf +argument. +.Pp +The .Fn quota_check_path function checks if the specified path is within the filesystem that corresponds to its diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 6dcb6979fb1..4c63a17b778 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -128,13 +128,13 @@ quota_open(struct fstab *fs, int quotatype, int openflags) if (stat(qf->fsname, &st) != 0) goto error; qf->dev = st.st_dev; + serrno = hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname)); qcmd = QCMD(Q_GETQUOTA, quotatype); if (quotactl(fs->fs_file, qcmd, 0, &dqh) == 0) { qf->wordsize = 64; - qf->fd = -1; return (qf); } - if (!hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname))) { + if (serrno == 0) { errno = EOPNOTSUPP; goto error; } @@ -231,6 +231,24 @@ quota_check_path(const struct quotafile *qf, const char *path) return (st.st_dev == qf->dev); } +int +quota_maxid(struct quotafile *qf) +{ + struct stat st; + + if (stat(qf->qfname, &st) < 0) + return (0); + switch (qf->wordsize) { + case 32: + return (st.st_size / sizeof(struct dqblk32)); + case 64: + return (st.st_size / sizeof(struct dqblk64) - 1); + default: + return (0); + } + /* not reached */ +} + static int quota_read32(struct quotafile *qf, struct dqblk *dqb, int id) { @@ -242,7 +260,7 @@ quota_read32(struct quotafile *qf, struct dqblk *dqb, int id) return (-1); switch (read(qf->fd, &dqb32, sizeof(dqb32))) { case 0: - memset(&dqb, 0, sizeof(*dqb)); + memset(dqb, 0, sizeof(*dqb)); return (0); case sizeof(dqb32): dqb->dqb_bhardlimit = dqb32.dqb_bhardlimit; @@ -270,7 +288,7 @@ quota_read64(struct quotafile *qf, struct dqblk *dqb, int id) return (-1); switch (read(qf->fd, &dqb64, sizeof(dqb64))) { case 0: - memset(&dqb, 0, sizeof(*dqb)); + memset(dqb, 0, sizeof(*dqb)); return (0); case sizeof(dqb64): dqb->dqb_bhardlimit = be64toh(dqb64.dqb_bhardlimit); From 0cf50fd7dc5610695e4246425de60a5f00f389ef Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 20 Oct 2009 05:40:51 +0000 Subject: [PATCH 020/532] Update to work with quotafile functions in -libutil. Add -h flag to provide humanized output. --- usr.sbin/repquota/repquota.8 | 7 +- usr.sbin/repquota/repquota.c | 196 ++++++++++++++--------------------- 2 files changed, 84 insertions(+), 119 deletions(-) diff --git a/usr.sbin/repquota/repquota.8 b/usr.sbin/repquota/repquota.8 index b669fdf8266..8b5ab689ac7 100644 --- a/usr.sbin/repquota/repquota.8 +++ b/usr.sbin/repquota/repquota.8 @@ -39,12 +39,14 @@ .Nd summarize quotas for a file system .Sh SYNOPSIS .Nm +.Op Fl h .Op Fl g .Op Fl n .Op Fl u .Op Fl v .Ar filesystem Ar ... .Nm +.Op Fl h .Op Fl g .Op Fl n .Op Fl u @@ -64,6 +66,9 @@ Print the quotas of all the file systems listed in .It Fl g Print only group quotas (the default is to print both group and user quotas if they exist). +.It Fl h +Display information in a more human readable format +rather than in historic kilobyte format. .It Fl n Display user and group IDs numerically rather than converting to a user or group name. @@ -75,7 +80,7 @@ Print a header line before printing each file system quotas. .El .Pp For each user or group, the current -number files and amount of space (in kilobytes) is +number files and amount of space is printed, along with any quotas created with .Xr edquota 8 . .Pp diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c index 19c185820b1..276a78dc65e 100644 --- a/usr.sbin/repquota/repquota.c +++ b/usr.sbin/repquota/repquota.c @@ -52,8 +52,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include @@ -80,7 +82,6 @@ const char *qfextension[] = INITQFNAMES; struct fileusage { struct fileusage *fu_next; - struct dqblk fu_dqblk; u_long fu_id; char fu_name[1]; /* actually bigger */ @@ -94,11 +95,12 @@ u_long highid[MAXQUOTAS]; /* highest addid()'ed identifier per type */ int vflag; /* verbose */ int aflag; /* all filesystems */ int nflag; /* display user/group by id */ +int hflag; /* display in human readable format */ -int hasquota(struct fstab *, int, char **); int oneof(char *, char *[], int); -int repquota(struct fstab *, int, char *); +int repquota(struct fstab *, int); char *timeprt(time_t); +static void prthumanval(int64_t bytes); static void usage(void); int @@ -109,9 +111,8 @@ main(int argc, char *argv[]) struct group *gr; int ch, gflag = 0, uflag = 0, errs = 0; long i, argnum, done = 0; - char *qfnp; - while ((ch = getopt(argc, argv, "agnuv")) != -1) { + while ((ch = getopt(argc, argv, "aghnuv")) != -1) { switch(ch) { case 'a': aflag++; @@ -119,6 +120,9 @@ main(int argc, char *argv[]) case 'g': gflag++; break; + case 'h': + hflag++; + break; case 'n': nflag++; break; @@ -158,19 +162,19 @@ main(int argc, char *argv[]) if (strcmp(fs->fs_vfstype, "ufs")) continue; if (aflag) { - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) - errs += repquota(fs, GRPQUOTA, qfnp); - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) - errs += repquota(fs, USRQUOTA, qfnp); + if (gflag) + errs += repquota(fs, GRPQUOTA); + if (uflag) + errs += repquota(fs, USRQUOTA); continue; } if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { done |= 1 << argnum; - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) - errs += repquota(fs, GRPQUOTA, qfnp); - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) - errs += repquota(fs, USRQUOTA, qfnp); + if (gflag) + errs += repquota(fs, GRPQUOTA); + if (uflag) + errs += repquota(fs, USRQUOTA); } } endfsent(); @@ -184,87 +188,92 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n", - "usage: repquota [-v] [-g] [-n] [-u] -a", - " repquota [-v] [-g] [-n] [-u] filesystem ..."); + "usage: repquota [-h] [-v] [-g] [-n] [-u] -a", + " repquota [-h] [-v] [-g] [-n] [-u] filesystem ..."); exit(1); } int -repquota(struct fstab *fs, int type, char *qfpathname) +repquota(struct fstab *fs, int type) { struct fileusage *fup; - FILE *qf; - u_long id; + struct quotafile *qf; + u_long id, maxid; struct dqblk dqbuf; - static struct dqblk zerodqblk; - static int warned = 0; static int multiple = 0; - if (quotactl(fs->fs_file, QCMD(Q_SYNC, type), 0, 0) < 0 && - errno == EOPNOTSUPP && !warned && vflag) { - warned++; - fprintf(stdout, - "*** Warning: Quotas are not compiled into this kernel\n"); + if ((qf = quota_open(fs, type, O_RDONLY)) == NULL) { + if (vflag && !aflag) { + if (multiple++) + printf("\n"); + fprintf(stdout, "*** No %s quotas on %s (%s)\n", + qfextension[type], fs->fs_file, fs->fs_spec); + } + return(0); } if (multiple++) printf("\n"); if (vflag) fprintf(stdout, "*** Report for %s quotas on %s (%s)\n", qfextension[type], fs->fs_file, fs->fs_spec); - if ((qf = fopen(qfpathname, "r")) == NULL) { - warn("%s", qfpathname); - return (1); - } - for (id = 0; ; id++) { - fread(&dqbuf, sizeof(struct dqblk), 1, qf); - if (feof(qf)) + printf("%*s Block limits File limits\n", + max(UT_NAMESIZE,10), " "); + printf("User%*s used soft hard grace used soft hard grace\n", + max(UT_NAMESIZE,10), " "); + maxid = quota_maxid(qf); + for (id = 0; id <= maxid; id++) { + if (quota_read(qf, &dqbuf, id) != 0) break; if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) continue; if ((fup = lookup(id, type)) == 0) fup = addid(id, type, (char *)0); - fup->fu_dqblk = dqbuf; - } - fclose(qf); - printf("%*s Block limits File limits\n", - max(UT_NAMESIZE,10), " "); - printf("%s%*s used soft hard grace used soft hard grace\n", - type == USRQUOTA ? "User " : "Group", max(UT_NAMESIZE,10), " "); - for (id = 0; id <= highid[type]; id++) { - fup = lookup(id, type); - if (fup == 0) - continue; - if (fup->fu_dqblk.dqb_curinodes == 0 && - fup->fu_dqblk.dqb_curblocks == 0) - continue; printf("%-*s ", max(UT_NAMESIZE,10), fup->fu_name); - printf("%c%c %8lu %8lu %8lu %6s", - fup->fu_dqblk.dqb_bsoftlimit && - fup->fu_dqblk.dqb_curblocks >= - fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-', - fup->fu_dqblk.dqb_isoftlimit && - fup->fu_dqblk.dqb_curinodes >= - fup->fu_dqblk.dqb_isoftlimit ? '+' : '-', - (u_long)(dbtokb(fup->fu_dqblk.dqb_curblocks)), - (u_long)(dbtokb(fup->fu_dqblk.dqb_bsoftlimit)), - (u_long)(dbtokb(fup->fu_dqblk.dqb_bhardlimit)), - fup->fu_dqblk.dqb_bsoftlimit && - fup->fu_dqblk.dqb_curblocks >= - fup->fu_dqblk.dqb_bsoftlimit ? - timeprt(fup->fu_dqblk.dqb_btime) : "-"); - printf(" %7lu %7lu %7lu %6s\n", - (u_long)fup->fu_dqblk.dqb_curinodes, - (u_long)fup->fu_dqblk.dqb_isoftlimit, - (u_long)fup->fu_dqblk.dqb_ihardlimit, - fup->fu_dqblk.dqb_isoftlimit && - fup->fu_dqblk.dqb_curinodes >= - fup->fu_dqblk.dqb_isoftlimit ? - timeprt(fup->fu_dqblk.dqb_itime) : "-"); - fup->fu_dqblk = zerodqblk; + printf("%c%c", + dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= + dqbuf.dqb_bsoftlimit ? '+' : '-', + dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= + dqbuf.dqb_isoftlimit ? '+' : '-'); + prthumanval(dqbuf.dqb_curblocks); + prthumanval(dqbuf.dqb_bsoftlimit); + prthumanval(dqbuf.dqb_bhardlimit); + printf(" %6s", + dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= + dqbuf.dqb_bsoftlimit ? + timeprt(dqbuf.dqb_btime) : "-"); + printf(" %7llu %7llu %7llu %6s\n", + dqbuf.dqb_curinodes, + dqbuf.dqb_isoftlimit, + dqbuf.dqb_ihardlimit, + dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= + dqbuf.dqb_isoftlimit ? + timeprt(dqbuf.dqb_itime) : "-"); } return (0); } +static void +prthumanval(int64_t blocks) +{ + char buf[7]; + int flags; + + if (!hflag) { + printf("%7llu", dbtokb(blocks)); + return; + } + flags = HN_NOSPACE | HN_DECIMAL; + if (blocks != 0) + flags |= HN_B; + humanize_number(buf, sizeof(buf) - (blocks < 0 ? 0 : 1), + dbtob(blocks), "", HN_AUTOSCALE, flags); + (void)printf("%7s", buf); +} + /* * Check to see if target appears in list of size cnt. */ @@ -279,55 +288,6 @@ oneof(char *target, char *list[], int cnt) return (-1); } -/* - * Check to see if a particular quota is to be enabled. - */ -int -hasquota(struct fstab *fs, int type, char **qfnamep) -{ - char *opt; - char *cp; - struct statfs sfb; - static char initname, usrname[100], grpname[100]; - static char buf[BUFSIZ]; - - if (!initname) { - (void)snprintf(usrname, sizeof(usrname), "%s%s", - qfextension[USRQUOTA], qfname); - (void)snprintf(grpname, sizeof(grpname), "%s%s", - qfextension[GRPQUOTA], qfname); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - qfname, qfextension[type]); - *qfnamep = buf; - } - if (statfs(fs->fs_file, &sfb) != 0) { - warn("cannot statfs mount point %s", fs->fs_file); - return (0); - } - if (strcmp(fs->fs_file, sfb.f_mntonname)) { - warnx("%s not mounted for %s quotas", fs->fs_file, - type == USRQUOTA ? "user" : "group"); - return (0); - } - return (1); -} - /* * Routines to manage the file usage table. * From 88c01c773986ce45a687eea8837a888087fb3e38 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 20 Oct 2009 16:46:39 +0000 Subject: [PATCH 021/532] Update to work with quotafile functions in -libutil. --- usr.sbin/repquota/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr.sbin/repquota/Makefile b/usr.sbin/repquota/Makefile index 087e890ed35..9da22c2fc0f 100644 --- a/usr.sbin/repquota/Makefile +++ b/usr.sbin/repquota/Makefile @@ -3,6 +3,8 @@ PROG= repquota MAN= repquota.8 +DPADD= ${LIBUTIL} +LDADD= -lutil WARNS?= 4 From 4e717eeafc9593cbed1da2216e1bff6241bb25b6 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 20 Oct 2009 17:50:27 +0000 Subject: [PATCH 022/532] Claen up format when doing non-humanized output. --- usr.sbin/repquota/repquota.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c index 276a78dc65e..aa822df09d2 100644 --- a/usr.sbin/repquota/repquota.c +++ b/usr.sbin/repquota/repquota.c @@ -208,6 +208,7 @@ repquota(struct fstab *fs, int type) printf("\n"); fprintf(stdout, "*** No %s quotas on %s (%s)\n", qfextension[type], fs->fs_file, fs->fs_spec); + return(1); } return(0); } @@ -221,7 +222,7 @@ repquota(struct fstab *fs, int type) printf("User%*s used soft hard grace used soft hard grace\n", max(UT_NAMESIZE,10), " "); maxid = quota_maxid(qf); - for (id = 0; id <= maxid; id++) { + for (id = 0; id < maxid; id++) { if (quota_read(qf, &dqbuf, id) != 0) break; if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) @@ -253,6 +254,7 @@ repquota(struct fstab *fs, int type) dqbuf.dqb_isoftlimit ? timeprt(dqbuf.dqb_itime) : "-"); } + quota_close(qf); return (0); } @@ -263,7 +265,7 @@ prthumanval(int64_t blocks) int flags; if (!hflag) { - printf("%7llu", dbtokb(blocks)); + printf(" %6llu", dbtokb(blocks)); return; } flags = HN_NOSPACE | HN_DECIMAL; From 37ed8e48db6cedb3822539f27e09f1d23d45ef8d Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Wed, 21 Oct 2009 04:35:09 +0000 Subject: [PATCH 023/532] Update to work with quotafile functions in -libutil. --- usr.bin/quota/quota.c | 231 +++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 149 deletions(-) diff --git a/usr.bin/quota/quota.c b/usr.bin/quota/quota.c index f504e7c3159..24dcb494230 100644 --- a/usr.bin/quota/quota.c +++ b/usr.bin/quota/quota.c @@ -87,7 +87,7 @@ struct quotause { char fsname[MAXPATHLEN + 1]; }; -static char *timeprt(time_t seconds); +static char *timeprt(int64_t seconds, int *needfree); static struct quotause *getprivs(long id, int quotatype); static void usage(void); static int showuid(u_long uid); @@ -97,7 +97,6 @@ static int showgrpname(char *name); static int showquotas(int type, u_long id, const char *name); static void showrawquotas(int type, u_long id, struct quotause *qup); static void heading(int type, u_long id, const char *name, const char *tag); -static int ufshasquota(struct fstab *fs, int type, char **qfnamep); static int getufsquota(struct fstab *fs, struct quotause *qup, long id, int quotatype); static int getnfsquota(struct statfs *fst, struct quotause *qup, long id, @@ -117,8 +116,7 @@ int main(int argc, char *argv[]) { int ngroups; - long ngroups_max; - gid_t mygid, *gidset; + gid_t mygid, gidset[NGROUPS]; int i, ch, gflag = 0, uflag = 0, errflag = 0; while ((ch = getopt(argc, argv, "f:ghlrquv")) != -1) { @@ -160,18 +158,13 @@ main(int argc, char *argv[]) errflag += showuid(getuid()); if (gflag) { mygid = getgid(); - ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; - if ((gidset = malloc(sizeof(gid_t) * ngroups_max)) - == NULL) - err(1, "malloc"); - ngroups = getgroups(ngroups_max, gidset); + ngroups = getgroups(NGROUPS, gidset); if (ngroups < 0) err(1, "getgroups"); errflag += showgid(mygid); for (i = 0; i < ngroups; i++) if (gidset[i] != mygid) errflag += showgid(gidset[i]); - free(gidset); } return(errflag); } @@ -271,7 +264,7 @@ showgrpname(char *name) } static void -prthumanval(int len, int64_t bytes) +prthumanval(int len, u_int64_t bytes) { char buf[len + 1]; @@ -288,7 +281,8 @@ showquotas(int type, u_long id, const char *name) struct quotause *quplist; const char *msgi, *msgb; const char *nam; - char *bgrace = NULL, *igrace = NULL; + char *bgrace, *igrace; + int bfree, ifree; int lines = 0, overquota = 0; static time_t now; @@ -344,52 +338,46 @@ showquotas(int type, u_long id, const char *name) printf("\t%s %s\n", msgb, qup->fsname); continue; } - if (vflag || - qup->dqblk.dqb_curblocks || - qup->dqblk.dqb_curinodes) { - if (lines++ == 0) - heading(type, id, name, ""); - nam = qup->fsname; - if (strlen(qup->fsname) > 15) { - printf("%s\n", qup->fsname); - nam = ""; - } - printf("%15s", nam); - if (hflag) { - printf(" "); - prthumanval(4, dbtob(qup->dqblk.dqb_curblocks)); - printf("%c ", (msgb == (char *)0) ? ' ' : '*'); - prthumanval(4, dbtob(qup->dqblk.dqb_bsoftlimit)); - printf(" "); - prthumanval(4, dbtob(qup->dqblk.dqb_bhardlimit)); - } else { - printf(" %7ju%c %6ju %7ju", - (uintmax_t)(dbtob(qup->dqblk.dqb_curblocks) - / 1024), - (msgb == NULL) ? ' ' : '*', - (uintmax_t)(dbtob(qup->dqblk.dqb_bsoftlimit) - / 1024), - (uintmax_t)(dbtob(qup->dqblk.dqb_bhardlimit) - / 1024)); - } - if (msgb != NULL) - bgrace = timeprt(qup->dqblk.dqb_btime); - if (msgi != NULL) - igrace = timeprt(qup->dqblk.dqb_itime); - printf(" %7s %7ju%c %6ju %7ju %7s\n", - (msgb == NULL) ? "" : bgrace, - (uintmax_t)qup->dqblk.dqb_curinodes, - (msgi == NULL) ? ' ' : '*', - (uintmax_t)qup->dqblk.dqb_isoftlimit, - (uintmax_t)qup->dqblk.dqb_ihardlimit, - (msgi == NULL) ? "" : igrace - ); - if (msgb != NULL) - free(bgrace); - if (msgi != NULL) - free(igrace); + if (!vflag && + qup->dqblk.dqb_curblocks == 0 && + qup->dqblk.dqb_curinodes == 0) continue; + if (lines++ == 0) + heading(type, id, name, ""); + nam = qup->fsname; + if (strlen(qup->fsname) > 15) { + printf("%s\n", qup->fsname); + nam = ""; + } + printf("%-15s", nam); + if (hflag) { + prthumanval(7, dbtob(qup->dqblk.dqb_curblocks)); + printf("%c", (msgb == (char *)0) ? ' ' : '*'); + prthumanval(7, dbtob(qup->dqblk.dqb_bsoftlimit)); + prthumanval(7, dbtob(qup->dqblk.dqb_bhardlimit)); + } else { + printf(" %7ju%c %7ju %7ju", + dbtob(1024) * (uintmax_t)qup->dqblk.dqb_curblocks, + (msgb == (char *)0) ? ' ' : '*', + dbtob(1024) * (uintmax_t)qup->dqblk.dqb_bsoftlimit, + dbtob(1024) * (uintmax_t)qup->dqblk.dqb_bhardlimit); } + if (msgb != NULL) + bgrace = timeprt(qup->dqblk.dqb_btime, &bfree); + if (msgi != NULL) + igrace = timeprt(qup->dqblk.dqb_itime, &ifree); + printf("%8s %6ju%c %6ju %6ju%8s\n" + , (msgb == (char *)0) ? "" : bgrace + , (uintmax_t)qup->dqblk.dqb_curinodes + , (msgi == (char *)0) ? ' ' : '*' + , (uintmax_t)qup->dqblk.dqb_isoftlimit + , (uintmax_t)qup->dqblk.dqb_ihardlimit + , (msgi == (char *)0) ? "" : igrace + ); + if (msgb != NULL && bfree) + free(bgrace); + if (msgi != NULL && ifree) + free(igrace); } if (!qflag && !rflag && lines == 0) heading(type, id, name, "none"); @@ -399,27 +387,37 @@ showquotas(int type, u_long id, const char *name) static void showrawquotas(int type, u_long id, struct quotause *qup) { - time_t tt; + time_t time; + printf("Raw %s quota information for id %lu on %s\n", type == USRQUOTA ? "user" : "group", id, qup->fsname); - printf("block hard limit: %ju\n", (uintmax_t)qup->dqblk.dqb_bhardlimit); - printf("block soft limit: %ju\n", (uintmax_t)qup->dqblk.dqb_bsoftlimit); - printf("current block count: %ju\n", (uintmax_t)qup->dqblk.dqb_curblocks); - printf("i-node hard limit: %ju\n", (uintmax_t)qup->dqblk.dqb_ihardlimit); - printf("i-node soft limit: %ju\n", (uintmax_t)qup->dqblk.dqb_isoftlimit); - printf("current i-node count: %ju\n", (uintmax_t)qup->dqblk.dqb_curinodes); - printf("block grace time: %jd", (intmax_t)qup->dqblk.dqb_btime); + printf("block hard limit: %ju\n", + (uintmax_t)qup->dqblk.dqb_bhardlimit); + printf("block soft limit: %ju\n", + (uintmax_t)qup->dqblk.dqb_bsoftlimit); + printf("current block count: %ju\n", + (uintmax_t)qup->dqblk.dqb_curblocks); + printf("i-node hard limit: %ju\n", + (uintmax_t)qup->dqblk.dqb_ihardlimit); + printf("i-node soft limit: %ju\n", + (uintmax_t)qup->dqblk.dqb_isoftlimit); + printf("current i-node count: %ju\n", + (uintmax_t)qup->dqblk.dqb_curinodes); + printf("block grace time: %jd", + (intmax_t)qup->dqblk.dqb_btime); if (qup->dqblk.dqb_btime != 0) { - tt = qup->dqblk.dqb_btime; - printf(" %s", ctime(&tt)); - } else + time = qup->dqblk.dqb_btime; + printf(" %s", ctime(&time)); + } else { printf("\n"); + } printf("i-node grace time: %jd", (intmax_t)qup->dqblk.dqb_itime); if (qup->dqblk.dqb_itime != 0) { - tt = qup->dqblk.dqb_itime; - printf(" %s", ctime(&tt)); - } else + time = qup->dqblk.dqb_itime; + printf(" %s", ctime(&time)); + } else { printf("\n"); + } } @@ -430,7 +428,7 @@ heading(int type, u_long id, const char *name, const char *tag) printf("Disk quotas for %s %s (%cid %lu): %s\n", qfextension[type], name, *qfextension[type], id, tag); if (!qflag && tag[0] == '\0') { - printf("%15s %7s %6s %7s %7s %7s %6s %7s %7s\n" + printf("%-15s %7s %8s %7s %7s %6s %7s %6s%8s\n" , "Filesystem" , "usage" , "quota" @@ -448,7 +446,7 @@ heading(int type, u_long id, const char *name, const char *tag) * Calculate the grace period and return a printable string for it. */ static char * -timeprt(time_t seconds) +timeprt(int64_t seconds, int *needfree) { time_t hours, minutes; char *buf; @@ -457,7 +455,8 @@ timeprt(time_t seconds) if (now == 0) time(&now); if (now > seconds) { - return strdup("none"); + *needfree = 0; + return ("none"); } seconds -= now; minutes = (seconds + 30) / 60; @@ -465,16 +464,19 @@ timeprt(time_t seconds) if (hours >= 36) { if (asprintf(&buf, "%lddays", ((long)hours + 12) / 24) < 0) errx(1, "asprintf failed in timeprt(1)"); + *needfree = 1; return (buf); } if (minutes >= 60) { if (asprintf(&buf, "%2ld:%ld", (long)minutes / 60, (long)minutes % 60) < 0) errx(1, "asprintf failed in timeprt(2)"); + *needfree = 1; return (buf); } if (asprintf(&buf, "%2ld", (long)minutes) < 0) errx(1, "asprintf failed in timeprt(3)"); + *needfree = 1; return (buf); } @@ -499,7 +501,7 @@ getprivs(long id, int quotatype) if (nfst == 0) errx(2, "no filesystems mounted!"); setfsent(); - for (i=0; ifs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - qfname, qfextension[type]); - *qfnamep = buf; - } - if (statfs(fs->fs_file, &sfb) != 0) { - warn("cannot statfs mount point %s", fs->fs_file); - return (0); - } - if (strcmp(fs->fs_file, sfb.f_mntonname)) { - warnx("%s not mounted for %s quotas", fs->fs_file, - type == USRQUOTA ? "user" : "group"); - return (0); - } - return (1); -} - static int getufsquota(struct fstab *fs, struct quotause *qup, long id, int quotatype) { - char *qfpathname; - int fd, qcmd; + struct quotafile *qf; - qcmd = QCMD(Q_GETQUOTA, quotatype); - if (!ufshasquota(fs, quotatype, &qfpathname)) + if ((qf = quota_open(fs, quotatype, O_RDONLY)) == NULL) return (0); - - if (quotactl(fs->fs_file, qcmd, id, (char *)&qup->dqblk) != 0) { - if ((fd = open(qfpathname, O_RDONLY)) < 0) { - warn("%s", qfpathname); - return (0); - } - (void) lseek(fd, (off_t)(id * sizeof(struct dqblk)), L_SET); - switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) { - case 0: /* EOF */ - /* - * Convert implicit 0 quota (EOF) - * into an explicit one (zero'ed dqblk) - */ - bzero((caddr_t)&qup->dqblk, sizeof(struct dqblk)); - break; - case sizeof(struct dqblk): /* OK */ - break; - default: /* ERROR */ - warn("read error: %s", qfpathname); - close(fd); - return (0); - } - close(fd); - } + if (quota_read(qf, &qup->dqblk, id) != 0) + return (0); + quota_close(qf); return (1); } From 708a2897f1b3c36dacde8cf534288c05373f7dfd Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Mon, 16 Nov 2009 18:50:51 +0000 Subject: [PATCH 024/532] Convert quotaon/quotaoff to use the new quotafile functions. --- usr.sbin/quotaon/Makefile | 3 + usr.sbin/quotaon/quotaon.c | 122 ++++++++----------------------------- 2 files changed, 29 insertions(+), 96 deletions(-) diff --git a/usr.sbin/quotaon/Makefile b/usr.sbin/quotaon/Makefile index 3f88bd9da33..0a07f065194 100644 --- a/usr.sbin/quotaon/Makefile +++ b/usr.sbin/quotaon/Makefile @@ -8,4 +8,7 @@ MLINKS= quotaon.8 quotaoff.8 WARNS?= 4 +DPADD= ${LIBUTIL} +LDADD= -lutil + .include diff --git a/usr.sbin/quotaon/quotaon.c b/usr.sbin/quotaon/quotaon.c index 314f596bc01..0f8ef98f7cd 100644 --- a/usr.sbin/quotaon/quotaon.c +++ b/usr.sbin/quotaon/quotaon.c @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -66,17 +67,15 @@ int gflag; /* operate on group quotas */ int uflag; /* operate on user quotas */ int vflag; /* verbose */ -int hasquota(struct fstab *, int, char **); int oneof(char *, char *[], int); -int quotaonoff(struct fstab *fs, int, int, char *); -int readonly(struct fstab *); +int quotaonoff(struct fstab *fs, int, int); static void usage(void); int main(int argc, char **argv) { struct fstab *fs; - char *qfnp, *whoami; + char *whoami; long argnum, done = 0; int ch, i, offmode = 0, errs = 0; @@ -119,19 +118,19 @@ main(int argc, char **argv) strcmp(fs->fs_type, FSTAB_RW)) continue; if (aflag) { - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) - errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) - errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); + if (gflag) + errs += quotaonoff(fs, offmode, GRPQUOTA); + if (uflag) + errs += quotaonoff(fs, offmode, USRQUOTA); continue; } if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { done |= 1 << argnum; - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) - errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) - errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); + if (gflag) + errs += quotaonoff(fs, offmode, GRPQUOTA); + if (uflag) + errs += quotaonoff(fs, offmode, USRQUOTA); } } endfsent(); @@ -154,32 +153,33 @@ usage(void) } int -quotaonoff(fs, offmode, type, qfpathname) - register struct fstab *fs; +quotaonoff(fs, offmode, type) + struct fstab *fs; int offmode, type; - char *qfpathname; { + struct quotafile *qf; - if (strcmp(fs->fs_file, "/") && readonly(fs)) - return (1); + if ((qf = quota_open(fs, type, O_RDONLY)) == NULL) + return (0); if (offmode) { - if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) { - warn("%s", fs->fs_file); + if (quota_off(qf) != 0) { + warn("%s", quota_fsname(qf)); return (1); } if (vflag) - printf("%s: quotas turned off\n", fs->fs_file); - return (0); + printf("%s: quotas turned off\n", quota_fsname(qf)); + quota_close(qf); + return(0); } - if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) { - warnx("using %s on", qfpathname); - warn("%s", fs->fs_file); + if (quota_on(qf) != 0) { + warn("using %s on %s", quota_qfname(qf), quota_fsname(qf)); return (1); } if (vflag) printf("%s: %s quotas turned on with data file %s\n", - fs->fs_file, qfextension[type], qfpathname); - return (0); + quota_fsname(qf), qfextension[type], quota_qfname(qf)); + quota_close(qf); + return(0); } /* @@ -195,73 +195,3 @@ oneof(char *target, char *list[], int cnt) return (i); return (-1); } - -/* - * Check to see if a particular quota is to be enabled. - */ -int -hasquota(struct fstab *fs, int type, char **qfnamep) -{ - char *opt; - char *cp; - struct statfs sfb; - static char initname, usrname[100], grpname[100]; - static char buf[BUFSIZ]; - - if (!initname) { - (void)snprintf(usrname, sizeof(usrname), "%s%s", - qfextension[USRQUOTA], qfname); - (void)snprintf(grpname, sizeof(grpname), "%s%s", - qfextension[GRPQUOTA], qfname); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - qfname, qfextension[type]); - *qfnamep = buf; - } - if (statfs(fs->fs_file, &sfb) != 0) { - warn("cannot statfs mount point %s", fs->fs_file); - return (0); - } - if (strcmp(fs->fs_file, sfb.f_mntonname)) { - warnx("%s not mounted for %s quotas", fs->fs_file, - type == USRQUOTA ? "user" : "group"); - return (0); - } - return (1); -} - -/* - * Verify filesystem is mounted and not readonly. - */ -int -readonly(struct fstab *fs) -{ - struct statfs fsbuf; - - if (statfs(fs->fs_file, &fsbuf) < 0 || - strcmp(fsbuf.f_mntonname, fs->fs_file) || - strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { - printf("%s: not mounted\n", fs->fs_file); - return (1); - } - if (fsbuf.f_flags & MNT_RDONLY) { - printf("%s: mounted read-only\n", fs->fs_file); - return (1); - } - return (0); -} From e525d16a80319276894d6737ffb7c4b5a8fda142 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Mon, 16 Nov 2009 18:59:04 +0000 Subject: [PATCH 025/532] Add and document new quoat_on and quota_off functions. --- lib/libutil/libutil.h | 4 +- lib/libutil/quotafile.3 | 149 +++++++++++++++++++++++++--------------- lib/libutil/quotafile.c | 18 ++++- 3 files changed, 113 insertions(+), 58 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index b5ff6fd9e07..3a05d9b56f6 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -144,6 +144,9 @@ int pidfile_remove(struct pidfh *pfh); struct quotafile; struct fstab; struct quotafile *quota_open(struct fstab *, int, int); +void quota_close(struct quotafile *); +int quota_on(struct quotafile *); +int quota_off(struct quotafile *); const char *quota_fsname(const struct quotafile *); const char *quota_qfname(const struct quotafile *); int quota_maxid(struct quotafile *); @@ -151,7 +154,6 @@ int quota_check_path(const struct quotafile *, const char *path); int quota_read(struct quotafile *, struct dqblk *, int); int quota_write_limits(struct quotafile *, struct dqblk *, int); int quota_write_usage(struct quotafile *, struct dqblk *, int); -void quota_close(struct quotafile *); #endif __END_DECLS diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index d0c27d730b8..d2134c50530 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -30,14 +30,16 @@ .Os .Sh NAME .Nm quota_open +.Nm quota_close +.Nm quota_on +.Nm quota_off +.Nm quota_read +.Nm quota_write_limits +.Nm quota_write_usage .Nm quota_fsname .Nm quota_qfname .Nm quota_maxid .Nm quota_check_path -.Nm quota_read -.Nm quota_write_limits -.Nm quota_write_usage -.Nm quota_close .Nd "Manipulate quotas" .Sh LIBRARY .Lb libutil @@ -50,6 +52,18 @@ .In libutil.h .Ft "struct quotafile *" .Fn quota_open "struct fstab *fs" "int quotatype" "int openflags" +.Ft int +.Fn quota_close "struct quotafile *qf" +.Ft int +.Fn quota_on "const struct quotafile *qf" +.Ft int +.Fn quota_off "const struct quotafile *qf" +.Ft int +.Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int id" +.Ft int +.Fn quota_write_limits "struct quotafile *qf" "struct dqblk *dqb" "int id" +.Ft int +.Fn quota_write_usage "struct quotafile *qf" "struct dqblk *dqb" "int id" .Ft "const char *" .Fn quota_fsname "const struct quotafile *qf" .Ft "const char *" @@ -58,14 +72,6 @@ .Fn quota_maxid "const struct quotafile *qf" .Ft int .Fn quota_check_path "const struct quotafile *qf" "const char *path" -.Ft int -.Fn quota_read "struct quotafile *qf" "struct dqblk *dqb" "int id" -.Ft int -.Fn quota_write_limits "struct quotafile *qf" "struct dqblk *dqb" "int id" -.Ft int -.Fn quota_write_usage "struct quotafile *qf" "struct dqblk *dqb" "int id" -.Ft int -.Fn quota_close "struct quotafile *qf" .Sh DESCRIPTION These functions are designed to simplify access to filesystem quotas. If quotas are active on a filesystem, @@ -103,6 +109,81 @@ flag should be specified if a new quota file of the requested type should be created if it does not already exist. .Pp The +.Fn quota_close +function closes any open file descriptors and frees any storage +associated with the filesystem and quota type referenced by +.Va qf . +.Pp +The +.Fn quota_on +function enables quotas for the filesystem associated with its +.Va qf +argument which may have been opened +.Dv O_RDONLY +or +.Dv O_RDWR . +The +.Fn quota_on +function returns 0 if successful; +otherwise the value\~-1 is returned and the global variable +.Va errno +is set to indicate the error, see +.Xr quotactl 2 +for the possible errors. +.Pp +The +.Fn quota_off +function disables quotas for the filesystem associated with its +.Va qf +argument which may have been opened +.Dv O_RDONLY +or +.Dv O_RDWR . +The +.Fn quota_off +function returns 0 if successful; +otherwise the value\~-1 is returned and the global variable +.Va errno +is set to indicate the error, see +.Xr quotactl 2 +for the possible errors. +.Pp +The +.Fn quota_read +function reads the quota from the filesystem and quota type referenced by +.Va qf +for the user (or group) specified by +.Va id +into the +.Vt dqblk +quota structure pointed to by +.Va dqb . +.Pp +The +.Fn quota_write_limits +function updates the limit fields (but not the usage fields) +for the filesystem and quota type referenced by +.Va qf +for the user (or group) specified by +.Va id +from the +.Vt dqblk +quota structure pointed to by +.Va dqb . +.Pp +The +.Fn quota_write_usage +function updates the usage fields (but not the limit fields) +for the filesystem and quota type referenced by +.Va qf +for the user (or group) specified by +.Va id +from the +.Vt dqblk +quota structure pointed to by +.Va dqb . +.Pp +The .Fn quota_fsname function returns a pointer to a buffer containing the path to the root of the file system that corresponds to its @@ -138,48 +219,6 @@ If the argument refers to a symbolic link, .Fn quota_check_path will follow it. -.Pp -The -.Fn quota_read -function reads the quota from the filesystem and quota type referenced -by -.Va qf -for the user (or group) specified by -.Va id -into the -.Vt dqblk -quota structure pointed to by -.Va dqb . -.Pp -The -.Fn quota_write_limits -function updates the limit fields (but not the usage fields) -for the filesystem and quota type referenced by -.Va qf -for the user (or group) specified by -.Va id -from the -.Vt dqblk -quota structure pointed to by -.Va dqb . -.Pp -The -.Fn quota_write_usage -function updates the usage fields (but not the limit fields) -for the filesystem and quota type referenced by -.Va qf -for the user (or group) specified by -.Va id -from the -.Vt dqblk -quota structure pointed to by -.Va dqb . -.Pp -The -.Fn quota_close -function closes any open file descriptors and frees any storage -associated with the filesystem and quota type referenced by -.Va qf . .Sh IMPLEMENTATION NOTES If the underlying quota file is in the old 32-bit format, limit and usage values written to the quota file will be clipped to 32 bits. @@ -230,4 +269,4 @@ The functions and this manual page were written by .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org and -.An Marshall Kirk McKusick . +.An Marshall Kirk McKusick Aq mckusick@mckusick.com . diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 4c63a17b778..9017c4ecd80 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -61,7 +61,6 @@ static const char *qfextension[] = INITQFNAMES; /* * Check to see if a particular quota is to be enabled. - * XXX merge into quota_open */ static int hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) @@ -73,7 +72,6 @@ hasquota(struct fstab *fs, int type, char *qfnamep, int qfbufsize) static char initname, usrname[100], grpname[100]; /* - * XXX * 1) we only need one of these * 2) fstab may specify a different filename */ @@ -207,6 +205,22 @@ quota_close(struct quotafile *qf) free(qf); } +int +quota_on(struct quotafile *qf) +{ + int qcmd; + + qcmd = QCMD(Q_QUOTAON, qf->quotatype); + return (quotactl(qf->fsname, qcmd, 0, qf->qfname)); +} + +int +quota_off(struct quotafile *qf) +{ + + return (quotactl(qf->fsname, QCMD(Q_QUOTAOFF, qf->quotatype), 0, 0)); +} + const char * quota_fsname(const struct quotafile *qf) { From c3616249ab23a2cfd4caa843df95aeb9a17ef5b2 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sun, 27 Dec 2009 06:26:04 +0000 Subject: [PATCH 026/532] Minor bugs turned up during conversion of quotacheck. --- lib/libutil/quotafile.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 9017c4ecd80..652d95a290f 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -118,6 +118,8 @@ quota_open(struct fstab *fs, int quotatype, int openflags) struct stat st; int qcmd, serrno; + if (strcmp(fs->fs_vfstype, "ufs")) + return (NULL); if ((qf = calloc(1, sizeof(*qf))) == NULL) return (NULL); qf->fd = -1; @@ -176,8 +178,11 @@ quota_open(struct fstab *fs, int quotatype, int openflags) dqh.dqh_version = htobe32(Q_DQHDR64_VERSION); dqh.dqh_hdrlen = htobe32(sizeof(struct dqhdr64)); dqh.dqh_reclen = htobe32(sizeof(struct dqblk64)); - if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) + if (write(qf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) { + /* it was one we created ourselves */ + unlink(qf->qfname); goto error; + } grp = getgrnam(QUOTAGROUP); fchown(qf->fd, 0, grp ? grp->gr_gid : 0); fchmod(qf->fd, 0640); @@ -185,12 +190,8 @@ quota_open(struct fstab *fs, int quotatype, int openflags) error: serrno = errno; /* did we have an open file? */ - if (qf->fd != -1) { - /* was it one we created ourselves? */ - if ((openflags & O_CREAT) == O_CREAT) - unlink(qf->qfname); + if (qf->fd != -1) close(qf->fd); - } free(qf); errno = serrno; return (NULL); From 3af26d4abba3ad1858920eedf0710663499167f1 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sun, 27 Dec 2009 06:28:01 +0000 Subject: [PATCH 027/532] Convert quotacheck to use new quotafile functions in libutil. Still to come, conversion between 64-bit and 32-bit quotafile formats. --- sbin/quotacheck/Makefile | 2 + sbin/quotacheck/preen.c | 77 ++++++----- sbin/quotacheck/quotacheck.c | 254 +++++++++-------------------------- sbin/quotacheck/quotacheck.h | 12 +- 4 files changed, 109 insertions(+), 236 deletions(-) diff --git a/sbin/quotacheck/Makefile b/sbin/quotacheck/Makefile index 5184bf261f1..51a88b7681c 100644 --- a/sbin/quotacheck/Makefile +++ b/sbin/quotacheck/Makefile @@ -5,6 +5,8 @@ PROG= quotacheck SRCS= quotacheck.c preen.c fsutil.c utilities.c WARNS?= 2 MAN= quotacheck.8 +DPADD= ${LIBUTIL} +LDADD= -lutil .PATH: ${.CURDIR}/../fsck ${.CURDIR}/../fsck_ffs diff --git a/sbin/quotacheck/preen.c b/sbin/quotacheck/preen.c index a6c4169ee55..1c285ccae9c 100644 --- a/sbin/quotacheck/preen.c +++ b/sbin/quotacheck/preen.c @@ -45,9 +45,13 @@ __RCSID("$NetBSD: preen.c,v 1.18 1998/07/26 20:02:36 mycroft Exp $"); #include #include +#include + #include #include +#include #include +#include #include #include #include @@ -58,9 +62,9 @@ __RCSID("$NetBSD: preen.c,v 1.18 1998/07/26 20:02:36 mycroft Exp $"); struct partentry { TAILQ_ENTRY(partentry) p_entries; char *p_devname; /* device name */ - char *p_mntpt; /* mount point */ - char *p_type; /* file system type */ - struct quotaname *p_quota; /* quota file info ptr */ + const char *p_mntpt; /* mount point */ + struct quotafile *p_qfu; /* user quota file info ptr */ + struct quotafile *p_qfg; /* group quota file info */ }; TAILQ_HEAD(part, partentry) badh; @@ -75,21 +79,19 @@ struct diskentry { TAILQ_HEAD(disk, diskentry) diskh; static struct diskentry *finddisk(const char *); -static void addpart(const char *, const char *, const char *, - struct quotaname *); +static void addpart(struct fstab *, struct quotafile *, struct quotafile *); static int startdisk(struct diskentry *); extern void *emalloc(size_t); extern char *estrdup(const char *); int -checkfstab(void) +checkfstab(int uflag, int gflag) { struct fstab *fs; struct diskentry *d, *nextdisk; struct partentry *p; int ret, pid, retcode, passno, sumstatus, status, nextpass; - char *name; - struct quotaname *qnp; + struct quotafile *qfu, *qfg; TAILQ_INIT(&badh); TAILQ_INIT(&diskh); @@ -104,30 +106,32 @@ checkfstab(void) return (8); } while ((fs = getfsent()) != 0) { - name = fs->fs_spec; if (fs->fs_passno > passno && fs->fs_passno < nextpass) nextpass = fs->fs_passno; if (passno != fs->fs_passno) continue; - if ((qnp = needchk(fs)) == NULL) + qfu = NULL; + if (uflag) + qfu = quota_open(fs, USRQUOTA, O_CREAT|O_RDWR); + qfg = NULL; + if (gflag) + qfg = quota_open(fs, GRPQUOTA, O_CREAT|O_RDWR); + if (qfu == NULL && qfg == NULL) continue; if (passno == 1) { - sumstatus = chkquota(name, fs->fs_file, qnp); - + sumstatus = chkquota(fs->fs_spec, qfu, qfg); + if (qfu) + quota_close(qfu); + if (qfg) + quota_close(qfg); if (sumstatus) return (sumstatus); continue; } - if (name == NULL) { - (void) fprintf(stderr, - "BAD DISK NAME %s\n", fs->fs_spec); - sumstatus |= 8; - continue; - } - addpart(fs->fs_vfstype, name, fs->fs_file, qnp); + addpart(fs, qfu, qfg); } if (passno == 1) @@ -157,8 +161,8 @@ checkfstab(void) if (WIFSIGNALED(status)) { (void) fprintf(stderr, - "%s: %s (%s): EXITED WITH SIGNAL %d\n", - p->p_type, p->p_devname, p->p_mntpt, + "%s: (%s): EXITED WITH SIGNAL %d\n", + p->p_devname, p->p_mntpt, WTERMSIG(status)); retcode = 8; } @@ -169,8 +173,11 @@ checkfstab(void) TAILQ_INSERT_TAIL(&badh, p, p_entries); sumstatus |= retcode; } else { - free(p->p_type); free(p->p_devname); + if (p->p_qfu) + quota_close(p->p_qfu); + if (p->p_qfg) + quota_close(p->p_qfg); free(p); } d->d_pid = 0; @@ -196,8 +203,8 @@ checkfstab(void) for (; p; p = TAILQ_NEXT(p, p_entries)) (void) fprintf(stderr, - "%s: %s (%s)%s", p->p_type, p->p_devname, - p->p_mntpt, TAILQ_NEXT(p, p_entries) ? ", " : "\n"); + "%s: (%s)%s", p->p_devname, p->p_mntpt, + TAILQ_NEXT(p, p_entries) ? ", " : "\n"); return sumstatus; } @@ -242,23 +249,25 @@ finddisk(const char *name) } static void -addpart(const char *type, const char *devname, const char *mntpt, - struct quotaname *qnp) +addpart(struct fstab *fs, struct quotafile *qfu, struct quotafile *qfg) { - struct diskentry *d = finddisk(devname); + struct diskentry *d = finddisk(fs->fs_spec); struct partentry *p; TAILQ_FOREACH(p, &d->d_part, p_entries) - if (strcmp(p->p_devname, devname) == 0) { - warnx("%s in fstab more than once!\n", devname); + if (strcmp(p->p_devname, fs->fs_spec) == 0) { + warnx("%s in fstab more than once!\n", fs->fs_spec); return; } p = emalloc(sizeof(*p)); - p->p_devname = estrdup(devname); - p->p_mntpt = estrdup(mntpt); - p->p_type = estrdup(type); - p->p_quota = qnp; + p->p_devname = estrdup(blockcheck(fs->fs_spec)); + if (qfu != NULL) + p->p_mntpt = quota_fsname(qfu); + else + p->p_mntpt = quota_fsname(qfg); + p->p_qfu = qfu; + p->p_qfg = qfg; TAILQ_INSERT_TAIL(&d->d_part, p, p_entries); } @@ -275,6 +284,6 @@ startdisk(struct diskentry *d) return (8); } if (d->d_pid == 0) - exit(chkquota(p->p_devname, p->p_mntpt, p->p_quota)); + exit(chkquota(p->p_devname, p->p_qfu, p->p_qfg)); return (0); } diff --git a/sbin/quotacheck/quotacheck.c b/sbin/quotacheck/quotacheck.c index 863932a12d2..026608a419b 100644 --- a/sbin/quotacheck/quotacheck.c +++ b/sbin/quotacheck/quotacheck.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -115,21 +116,19 @@ int vflag; /* verbose */ int fi; /* open disk file descriptor */ struct fileusage * - addid(u_long, int, char *, char *); -char *blockcheck(char *); + addid(u_long, int, char *, const char *); void bread(ufs2_daddr_t, char *, long); void freeinodebuf(void); union dinode * getnextinode(ino_t); int getquotagid(void); -int hasquota(struct fstab *, int, char **); struct fileusage * lookup(u_long, int); -struct quotaname *needchk(struct fstab *); int oneof(char *, char*[], int); -void printchanges(char *, int, struct dqblk *, struct fileusage *, u_long); +void printchanges(const char *, int, struct dqblk *, struct fileusage *, + u_long); void setinodebuf(ino_t); -int update(char *, char *, int); +int update(const char *, struct quotafile *, int); void usage(void); int @@ -138,7 +137,7 @@ main(int argc, char *argv[]) struct fstab *fs; struct passwd *pw; struct group *gr; - struct quotaname *qnp; + struct quotafile *qfu, *qfg; int i, argnum, maxrun, errs, ch; long done = 0; char *name; @@ -193,16 +192,27 @@ main(int argc, char *argv[]) if (maxrun > 0) warnx("the -l option is now deprecated"); if (aflag) - exit(checkfstab()); + exit(checkfstab(uflag, gflag)); if (setfsent() == 0) errx(1, "%s: can't open", FSTAB); while ((fs = getfsent()) != NULL) { if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || - (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) && - (qnp = needchk(fs)) && + (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) && (name = blockcheck(fs->fs_spec))) { done |= 1 << argnum; - errs += chkquota(name, fs->fs_file, qnp); + qfu = NULL; + if (uflag) + qfu = quota_open(fs, USRQUOTA, O_CREAT|O_RDWR); + qfg = NULL; + if (gflag) + qfg = quota_open(fs, GRPQUOTA, O_CREAT|O_RDWR); + if (qfu == NULL && qfg == NULL) + continue; + errs += chkquota(name, qfu, qfg); + if (qfu) + quota_close(qfu); + if (qfg) + quota_close(qfg); } } endfsent(); @@ -222,32 +232,6 @@ usage(void) exit(1); } -struct quotaname * -needchk(struct fstab *fs) -{ - struct quotaname *qnp; - char *qfnp; - - if (strcmp(fs->fs_vfstype, "ufs") || - strcmp(fs->fs_type, FSTAB_RW)) - return (NULL); - if ((qnp = malloc(sizeof(*qnp))) == NULL) - errx(1, "malloc failed"); - qnp->flags = 0; - if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) { - strcpy(qnp->grpqfname, qfnp); - qnp->flags |= HASGRP; - } - if (uflag && hasquota(fs, USRQUOTA, &qfnp)) { - strcpy(qnp->usrqfname, qfnp); - qnp->flags |= HASUSR; - } - if (qnp->flags) - return (qnp); - free(qnp); - return (NULL); -} - /* * Possible superblock locations ordered from most to least likely. */ @@ -257,20 +241,25 @@ static int sblock_try[] = SBLOCKSEARCH; * Scan the specified file system to check quota(s) present on it. */ int -chkquota(char *fsname, char *mntpt, struct quotaname *qnp) +chkquota(char *specname, struct quotafile *qfu, struct quotafile *qfg) { struct fileusage *fup; union dinode *dp; int cg, i, mode, errs = 0; ino_t ino, inosused, userino = 0, groupino = 0; dev_t dev, userdev = 0, groupdev = 0; - char *cp; struct stat sb; + const char *mntpt; + char *cp; - if (qnp == NULL) - err(1, "null quota information passed to chkquota()\n"); - if ((fi = open(fsname, O_RDONLY, 0)) < 0) { - warn("%s", fsname); + if (qfu != NULL) + mntpt = quota_fsname(qfu); + else if (qfg != NULL) + mntpt = quota_fsname(qfg); + else + err(1, "null quotafile information passed to chkquota()\n"); + if ((fi = open(specname, O_RDONLY, 0)) < 0) { + warn("%s", specname); return (1); } if ((stat(mntpt, &sb)) < 0) { @@ -280,21 +269,20 @@ chkquota(char *fsname, char *mntpt, struct quotaname *qnp) dev = sb.st_dev; if (vflag) { (void)printf("*** Checking "); - if (qnp->flags & HASUSR) - (void)printf("%s%s", qfextension[USRQUOTA], - (qnp->flags & HASGRP) ? " and " : ""); - if (qnp->flags & HASGRP) - (void)printf("%s", qfextension[GRPQUOTA]); - (void)printf(" quotas for %s (%s)\n", fsname, mntpt); + if (qfu) + (void)printf("user%s", qfg ? " and " : ""); + if (qfg) + (void)printf("group"); + (void)printf(" quotas for %s (%s)\n", specname, mntpt); } - if (qnp->flags & HASUSR) { - if (stat(qnp->usrqfname, &sb) == 0) { + if (qfu) { + if (stat(quota_qfname(qfu), &sb) == 0) { userino = sb.st_ino; userdev = sb.st_dev; } } - if (qnp->flags & HASGRP) { - if (stat(qnp->grpqfname, &sb) == 0) { + if (qfg) { + if (stat(quota_qfname(qfg), &sb) == 0) { groupino = sb.st_ino; groupdev = sb.st_dev; } @@ -382,7 +370,7 @@ chkquota(char *fsname, char *mntpt, struct quotaname *qnp) if ((ino == userino && dev == userdev) || (ino == groupino && dev == groupdev)) continue; - if (qnp->flags & HASGRP) { + if (qfg) { fup = addid((u_long)DIP(dp, di_gid), GRPQUOTA, (char *)0, mntpt); fup->fu_curinodes++; @@ -390,7 +378,7 @@ chkquota(char *fsname, char *mntpt, struct quotaname *qnp) mode == IFLNK) fup->fu_curblocks += DIP(dp, di_blocks); } - if (qnp->flags & HASUSR) { + if (qfu) { fup = addid((u_long)DIP(dp, di_uid), USRQUOTA, (char *)0, mntpt); fup->fu_curinodes++; @@ -401,10 +389,10 @@ chkquota(char *fsname, char *mntpt, struct quotaname *qnp) } } freeinodebuf(); - if (qnp->flags & HASUSR) - errs += update(mntpt, qnp->usrqfname, USRQUOTA); - if (qnp->flags & HASGRP) - errs += update(mntpt, qnp->grpqfname, GRPQUOTA); + if (qfu) + errs += update(mntpt, qfu, USRQUOTA); + if (qfg) + errs += update(mntpt, qfg, GRPQUOTA); close(fi); (void)fflush(stdout); return (errs); @@ -414,63 +402,20 @@ chkquota(char *fsname, char *mntpt, struct quotaname *qnp) * Update a specified quota file. */ int -update(char *fsname, char *quotafile, int type) +update(const char *fsname, struct quotafile *qf, int type) { struct fileusage *fup; - FILE *qfi, *qfo; u_long id, lastid, highid = 0; - off_t offset; - int i; struct dqblk dqbuf; - struct stat sb; - static int warned = 0; static struct dqblk zerodqbuf; static struct fileusage zerofileusage; - if ((qfo = fopen(quotafile, "r+")) == NULL) { - if (errno == ENOENT) - qfo = fopen(quotafile, "w+"); - if (qfo) { - warnx("creating quota file %s", quotafile); -#define MODE (S_IRUSR|S_IWUSR|S_IRGRP) - (void) fchown(fileno(qfo), getuid(), getquotagid()); - (void) fchmod(fileno(qfo), MODE); - } else { - warn("%s", quotafile); - return (1); - } - } - if ((qfi = fopen(quotafile, "r")) == NULL) { - warn("%s", quotafile); - (void) fclose(qfo); - return (1); - } - if (quotactl(fsname, QCMD(Q_SYNC, type), (u_long)0, (caddr_t)0) < 0 && - errno == EOPNOTSUPP && !warned && vflag) { - warned++; - (void)printf("*** Warning: %s\n", - "Quotas are not compiled into this kernel"); - } - if (fstat(fileno(qfi), &sb) < 0) { - warn("Cannot fstat quota file %s\n", quotafile); - (void) fclose(qfo); - (void) fclose(qfi); - return (1); - } - if ((sb.st_size % sizeof(struct dqblk)) != 0) - warn("%s size is not a multiple of dqblk\n", quotafile); - /* * Scan the on-disk quota file and record any usage changes. */ - - if (sb.st_size != 0) - lastid = (sb.st_size / sizeof(struct dqblk)) - 1; - else - lastid = 0; - for (id = 0, offset = 0; id <= lastid; - id++, offset += sizeof(struct dqblk)) { - if (fread((char *)&dqbuf, sizeof(struct dqblk), 1, qfi) == 0) + lastid = quota_maxid(qf); + for (id = 0; id <= lastid; id++) { + if (quota_read(qf, &dqbuf, id) < 0) dqbuf = zerodqbuf; if ((fup = lookup(id, type)) == NULL) fup = &zerofileusage; @@ -485,27 +430,9 @@ update(char *fsname, char *quotafile, int type) continue; } printchanges(fsname, type, &dqbuf, fup, id); - /* - * Reset time limit if have a soft limit and were - * previously under it, but are now over it. - */ - if (dqbuf.dqb_bsoftlimit && id != 0 && - dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit && - fup->fu_curblocks >= dqbuf.dqb_bsoftlimit) - dqbuf.dqb_btime = 0; - if (dqbuf.dqb_isoftlimit && id != 0 && - dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit && - fup->fu_curinodes >= dqbuf.dqb_isoftlimit) - dqbuf.dqb_itime = 0; dqbuf.dqb_curinodes = fup->fu_curinodes; dqbuf.dqb_curblocks = fup->fu_curblocks; - if (fseeko(qfo, offset, SEEK_SET) < 0) { - warn("%s: seek failed", quotafile); - return(1); - } - fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo); - (void) quotactl(fsname, QCMD(Q_SETUSE, type), id, - (caddr_t)&dqbuf); + (void) quota_write_usage(qf, &dqbuf, id); fup->fu_curinodes = 0; fup->fu_curblocks = 0; } @@ -515,9 +442,8 @@ update(char *fsname, char *quotafile, int type) * that are not currently recorded in the quota file. E.g. * ids that are past the end of the current file. */ - - for (i = 0; i < FUHASH; i++) { - for (fup = fuhead[type][i]; fup != NULL; fup = fup->fu_next) { + for (id = 0; id < FUHASH; id++) { + for (fup = fuhead[type][id]; fup != NULL; fup = fup->fu_next) { if (fup->fu_id <= lastid) continue; if (fup->fu_curinodes == 0 && fup->fu_curblocks == 0) @@ -525,26 +451,17 @@ update(char *fsname, char *quotafile, int type) bzero(&dqbuf, sizeof(struct dqblk)); if (fup->fu_id > highid) highid = fup->fu_id; - printchanges(fsname, type, &dqbuf, fup, id); + printchanges(fsname, type, &dqbuf, fup, fup->fu_id); dqbuf.dqb_curinodes = fup->fu_curinodes; dqbuf.dqb_curblocks = fup->fu_curblocks; - offset = (off_t)fup->fu_id * sizeof(struct dqblk); - if (fseeko(qfo, offset, SEEK_SET) < 0) { - warn("%s: seek failed", quotafile); - return(1); - } - fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo); - (void) quotactl(fsname, QCMD(Q_SETUSE, type), id, - (caddr_t)&dqbuf); + (void) quota_write_usage(qf, &dqbuf, fup->fu_id); fup->fu_curinodes = 0; fup->fu_curblocks = 0; } } - fclose(qfi); - fflush(qfo); - ftruncate(fileno(qfo), - (((off_t)highid + 1) * sizeof(struct dqblk))); - fclose(qfo); + if (highid < lastid) + truncate(quota_qfname(qf), + (((off_t)highid + 2) * sizeof(struct dqblk))); return (0); } @@ -575,55 +492,6 @@ getquotagid(void) return (-1); } -/* - * Check to see if a particular quota is to be enabled. - */ -int -hasquota(struct fstab *fs, int type, char **qfnamep) -{ - char *opt; - char *cp; - struct statfs sfb; - static char initname, usrname[100], grpname[100]; - static char buf[BUFSIZ]; - - if (!initname) { - (void)snprintf(usrname, sizeof(usrname), "%s%s", - qfextension[USRQUOTA], qfname); - (void)snprintf(grpname, sizeof(grpname), "%s%s", - qfextension[GRPQUOTA], qfname); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '=')) != NULL) - *cp++ = '\0'; - if (type == USRQUOTA && strcmp(opt, usrname) == 0) - break; - if (type == GRPQUOTA && strcmp(opt, grpname) == 0) - break; - } - if (!opt) - return (0); - if (cp) - *qfnamep = cp; - else { - (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file, - qfname, qfextension[type]); - *qfnamep = buf; - } - if (statfs(fs->fs_file, &sfb) != 0) { - warn("cannot statfs mount point %s", fs->fs_file); - return (0); - } - if (strcmp(fs->fs_file, sfb.f_mntonname)) { - warnx("%s not mounted for %s quotas", fs->fs_file, - type == USRQUOTA ? "user" : "group"); - return (0); - } - return (1); -} - /* * Routines to manage the file usage table. * @@ -644,7 +512,7 @@ lookup(u_long id, int type) * Add a new file usage id if it does not already exist. */ struct fileusage * -addid(u_long id, int type, char *name, char *fsname) +addid(u_long id, int type, char *name, const char *fsname) { struct fileusage *fup, **fhp; int len; @@ -779,7 +647,7 @@ bread(ufs2_daddr_t bno, char *buf, long cnt) * Display updated block and i-node counts. */ void -printchanges(char *fsname, int type, struct dqblk *dp, +printchanges(const char *fsname, int type, struct dqblk *dp, struct fileusage *fup, u_long id) { if (!vflag) diff --git a/sbin/quotacheck/quotacheck.h b/sbin/quotacheck/quotacheck.h index aad9d30a76a..dcff75b68a8 100644 --- a/sbin/quotacheck/quotacheck.h +++ b/sbin/quotacheck/quotacheck.h @@ -32,12 +32,6 @@ * $FreeBSD$ */ -struct quotaname { - long flags; - char grpqfname[PATH_MAX]; - char usrqfname[PATH_MAX]; -}; - -extern int checkfstab(); -extern int chkquota(char *, char *, struct quotaname *); -extern struct quotaname *needchk(struct fstab *); +extern char *blockcheck(char *); +extern int checkfstab(int, int); +extern int chkquota(char *, struct quotafile *, struct quotafile *); From aee785babde44bcfef1d711653a85896dde7324b Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Mon, 28 Dec 2009 22:44:19 +0000 Subject: [PATCH 028/532] Add and document the quota_convert function which converts between the old 32-bit and the new 64-bit formats. --- lib/libutil/libutil.h | 1 + lib/libutil/quotafile.3 | 34 ++++++++++---- lib/libutil/quotafile.c | 99 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 124 insertions(+), 10 deletions(-) diff --git a/lib/libutil/libutil.h b/lib/libutil/libutil.h index 3a05d9b56f6..7a4dc5670bc 100644 --- a/lib/libutil/libutil.h +++ b/lib/libutil/libutil.h @@ -154,6 +154,7 @@ int quota_check_path(const struct quotafile *, const char *path); int quota_read(struct quotafile *, struct dqblk *, int); int quota_write_limits(struct quotafile *, struct dqblk *, int); int quota_write_usage(struct quotafile *, struct dqblk *, int); +int quota_convert(struct quotafile *, int); #endif __END_DECLS diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3 index d2134c50530..5702cec9076 100644 --- a/lib/libutil/quotafile.3 +++ b/lib/libutil/quotafile.3 @@ -1,6 +1,6 @@ .\"- -.\" Copyright (c) 2008 Dag-Erling Coïdan Smørgrav -.\" All rights reserved. +.\" Copyright (c) 2009 Dag-Erling Coïdan Smørgrav and +.\" Marshall Kirk McKusick. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd September 26, 2009 +.Dd December 28, 2009 .Dt QUOTAFILE 3 .Os .Sh NAME @@ -40,6 +40,7 @@ .Nm quota_qfname .Nm quota_maxid .Nm quota_check_path +.Nm quota_convert .Nd "Manipulate quotas" .Sh LIBRARY .Lb libutil @@ -72,6 +73,8 @@ .Fn quota_maxid "const struct quotafile *qf" .Ft int .Fn quota_check_path "const struct quotafile *qf" "const char *path" +.Ft int +.Fn quota_convert "struct quotafile *qf" "int wordsize" .Sh DESCRIPTION These functions are designed to simplify access to filesystem quotas. If quotas are active on a filesystem, @@ -219,9 +222,23 @@ If the argument refers to a symbolic link, .Fn quota_check_path will follow it. +.Pp +The +.Fn quota_convert +function converts the quota file associated with its +.Va qf +argument to the data size specified by its +.Va wordsize +argument. +The supported wordsize arguments are 32 for the old 32-bit +quota file format and 64 for the new 64-bit quota file format. +The +.Fn quota_convert +function may only be called to operate on quota files that +are not currently active. .Sh IMPLEMENTATION NOTES -If the underlying quota file is in the old 32-bit format, limit and -usage values written to the quota file will be clipped to 32 bits. +If the underlying quota file is in or converted to the old 32-bit format, +limit and usage values written to the quota file will be clipped to 32 bits. .Sh RETURN VALUES If the filesystem has quotas associated with it, .Fn quota_open @@ -246,6 +263,7 @@ The .Fn quota_read , .Fn quota_write_limits , .Fn quota_write_usage , +.Fn quota_convert , and .Fn quota_close functions return zero on success. @@ -259,13 +277,13 @@ to indicate the error. .Xr quota.group 5 .Sh HISTORY The -.Nm +.Nm quotafile functions first appeared in -.Fx 8.0 . +.Fx 8.1 . .Sh AUTHORS .An -nosplit The -.Nm +.Nm quotafile functions and this manual page were written by .An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org and diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index 652d95a290f..ab57d662bdc 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -255,9 +255,9 @@ quota_maxid(struct quotafile *qf) return (0); switch (qf->wordsize) { case 32: - return (st.st_size / sizeof(struct dqblk32)); + return (st.st_size / sizeof(struct dqblk32) - 1); case 64: - return (st.st_size / sizeof(struct dqblk64) - 1); + return (st.st_size / sizeof(struct dqblk64) - 2); default: return (0); } @@ -494,3 +494,98 @@ quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id) } /* not reached */ } + +/* + * Convert a quota file from one format to another. + */ +int +quota_convert(struct quotafile *qf, int wordsize) +{ + struct quotafile *newqf; + struct dqhdr64 dqh; + struct dqblk dqblk; + struct group *grp; + int serrno, maxid, id, fd; + + /* + * Quotas must not be active and quotafile must be open + * for reading and writing. + */ + if ((qf->accmode & O_RDWR) != O_RDWR || qf->fd == -1) { + errno = EBADF; + return (-1); + } + if ((wordsize != 32 && wordsize != 64) || + wordsize == qf->wordsize) { + errno = EINVAL; + return (-1); + } + maxid = quota_maxid(qf); + if ((newqf = calloc(1, sizeof(*qf))) == NULL) { + errno = ENOMEM; + return (-1); + } + *newqf = *qf; + snprintf(newqf->qfname, MAXPATHLEN + 1, "%s_%d.orig", qf->qfname, + qf->wordsize); + if (rename(qf->qfname, newqf->qfname) < 0) { + free(newqf); + return (-1); + } + if ((newqf->fd = open(qf->qfname, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) { + serrno = errno; + goto error; + } + newqf->wordsize = wordsize; + if (wordsize == 64) { + memset(&dqh, 0, sizeof(dqh)); + memcpy(dqh.dqh_magic, Q_DQHDR64_MAGIC, sizeof(dqh.dqh_magic)); + dqh.dqh_version = htobe32(Q_DQHDR64_VERSION); + dqh.dqh_hdrlen = htobe32(sizeof(struct dqhdr64)); + dqh.dqh_reclen = htobe32(sizeof(struct dqblk64)); + if (write(newqf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) { + serrno = errno; + goto error; + } + } + grp = getgrnam(QUOTAGROUP); + fchown(newqf->fd, 0, grp ? grp->gr_gid : 0); + fchmod(newqf->fd, 0640); + for (id = 0; id <= maxid; id++) { + if ((quota_read(qf, &dqblk, id)) < 0) + break; + switch (newqf->wordsize) { + case 32: + if ((quota_write32(newqf, &dqblk, id)) < 0) + break; + continue; + case 64: + if ((quota_write64(newqf, &dqblk, id)) < 0) + break; + continue; + default: + errno = EINVAL; + break; + } + } + if (id < maxid) { + serrno = errno; + goto error; + } + /* + * Update the passed in quotafile to reference the new file + * of the converted format size. + */ + fd = qf->fd; + qf->fd = newqf->fd; + newqf->fd = fd; + qf->wordsize = newqf->wordsize; + quota_close(newqf); + return (0); +error: + /* put back the original file */ + (void) rename(newqf->qfname, qf->qfname); + quota_close(newqf); + errno = serrno; + return (-1); +} From 46d2decf1ada39fefc050092012034fabcfaa061 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Mon, 28 Dec 2009 23:01:47 +0000 Subject: [PATCH 029/532] Add the -c option to quotacheck to use the quota_convert(3) function to convert between quota file formats. --- sbin/quotacheck/quotacheck.8 | 18 +++++++++++++ sbin/quotacheck/quotacheck.c | 50 ++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/sbin/quotacheck/quotacheck.8 b/sbin/quotacheck/quotacheck.8 index 5ba2ad76fa3..e8f4d9ca775 100644 --- a/sbin/quotacheck/quotacheck.8 +++ b/sbin/quotacheck/quotacheck.8 @@ -40,10 +40,12 @@ .Sh SYNOPSIS .Nm .Op Fl guv +.Op Fl c Ar 32 | 64 .Op Fl l Ar maxrun .Fl a .Nm .Op Fl guv +.Op Fl c Ar 32 | 64 .Ar filesystem ... .Sh DESCRIPTION The @@ -69,6 +71,22 @@ to be read-write with disk quotas. By default only the types of quotas listed in .Pa /etc/fstab are checked. +.It Fl c Ar 32 | 64 +Before performing its checks, +.Nm +will convert the quota file to the specified word size. +A conversion size of 64 is given to request conversion to +the new 64-bit quota file format. +A conversion size of 32 is given to request conversion back to +the old 32-bit quota file format. +The original quota file is left unchanged and moved aside with an +underscore and its format size plus a +.Pa .orig +extension added to its name. +Thus, the original 32-bit +.Pa quota.user +quota file converted to the 64-bit format quota file will be renamed to +.Pa quota.user_32.orig . .It Fl g Only group quotas listed in .Pa /etc/fstab diff --git a/sbin/quotacheck/quotacheck.c b/sbin/quotacheck/quotacheck.c index 026608a419b..ed9ce753c55 100644 --- a/sbin/quotacheck/quotacheck.c +++ b/sbin/quotacheck/quotacheck.c @@ -110,6 +110,7 @@ struct fileusage { struct fileusage *fuhead[MAXQUOTAS][FUHASH]; int aflag; /* all file systems */ +int cflag; /* convert format to 32 or 64 bit size */ int gflag; /* check group quotas */ int uflag; /* check user quotas */ int vflag; /* verbose */ @@ -143,11 +144,16 @@ main(int argc, char *argv[]) char *name; errs = maxrun = 0; - while ((ch = getopt(argc, argv, "aguvl:")) != -1) { + while ((ch = getopt(argc, argv, "ac:guvl:")) != -1) { switch(ch) { case 'a': aflag++; break; + case 'c': + if (cflag) + usage(); + cflag = atoi(optarg); + break; case 'g': gflag++; break; @@ -168,6 +174,8 @@ main(int argc, char *argv[]) argv += optind; if ((argc == 0 && !aflag) || (argc > 0 && aflag)) usage(); + if (cflag && cflag != 32 && cflag != 64) + usage(); if (!gflag && !uflag) { gflag++; uflag++; @@ -227,8 +235,8 @@ void usage(void) { (void)fprintf(stderr, "%s\n%s\n", - "usage: quotacheck [-guv] [-l maxrun] -a", - " quotacheck [-guv] filesystem ..."); + "usage: quotacheck [-guv] [-c 32 | 64] [-l maxrun] -a", + " quotacheck [-guv] [-c 32 | 64] filesystem ..."); exit(1); } @@ -257,7 +265,31 @@ chkquota(char *specname, struct quotafile *qfu, struct quotafile *qfg) else if (qfg != NULL) mntpt = quota_fsname(qfg); else - err(1, "null quotafile information passed to chkquota()\n"); + errx(1, "null quotafile information passed to chkquota()\n"); + if (cflag) { + if (vflag && qfu != NULL) + printf("%s: convert user quota to %d bits\n", + mntpt, cflag); + if (qfu != NULL && quota_convert(qfu, cflag) < 0) { + if (errno == EBADF) + errx(1, + "%s: cannot convert an active quota file", + mntpt); + err(1, "user quota conversion to size %d failed", + cflag); + } + if (vflag && qfg != NULL) + printf("%s: convert group quota to %d bits\n", + mntpt, cflag); + if (qfg != NULL && quota_convert(qfg, cflag) < 0) { + if (errno == EBADF) + errx(1, + "%s: cannot convert an active quota file", + mntpt); + err(1, "group quota conversion to size %d failed", + cflag); + } + } if ((fi = open(specname, O_RDONLY, 0)) < 0) { warn("%s", specname); return (1); @@ -407,6 +439,7 @@ update(const char *fsname, struct quotafile *qf, int type) struct fileusage *fup; u_long id, lastid, highid = 0; struct dqblk dqbuf; + struct stat sb; static struct dqblk zerodqbuf; static struct fileusage zerofileusage; @@ -459,7 +492,14 @@ update(const char *fsname, struct quotafile *qf, int type) fup->fu_curblocks = 0; } } - if (highid < lastid) + /* + * If this is old format file, then size may be smaller, + * so ensure that we only truncate when it will make things + * smaller, and not if it will grow an old format file. + */ + if (highid < lastid && + stat(quota_qfname(qf), &sb) == 0 && + sb.st_size > (((off_t)highid + 2) * sizeof(struct dqblk))) truncate(quota_qfname(qf), (((off_t)highid + 2) * sizeof(struct dqblk))); return (0); From 9dc9c85fe9f1a06d23981220e362f04789a92d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 4 Mar 2010 00:47:24 +0000 Subject: [PATCH 030/532] WIP: the last missing piece of the quota64 puzzle. Not quite there yet. --- libexec/rpc.rquotad/rquotad.c | 131 ++++++++-------------------------- 1 file changed, 28 insertions(+), 103 deletions(-) diff --git a/libexec/rpc.rquotad/rquotad.c b/libexec/rpc.rquotad/rquotad.c index a2fe04e6f98..3cd129239e7 100644 --- a/libexec/rpc.rquotad/rquotad.c +++ b/libexec/rpc.rquotad/rquotad.c @@ -36,20 +36,9 @@ static void rquota_service(struct svc_req *request, SVCXPRT *transp); static void sendquota(struct svc_req *request, SVCXPRT *transp); static void initfs(void); static int getfsquota(long id, char *path, struct dqblk *dqblk); -static int hasquota(struct fstab *fs, char **qfnamep); - -/* - * structure containing informations about ufs filesystems - * initialised by initfs() - */ -struct fs_stat { - struct fs_stat *fs_next; /* next element */ - char *fs_file; /* mount point of the filesystem */ - char *qfpathname; /* pathname of the quota file */ - dev_t st_dev; /* device of the filesystem */ -} fs_stat; -static struct fs_stat *fs_begin = NULL; +static struct quotafile **qfa; /* array of qfs */ +static int nqf, szqf; /* number of qfs and size of array */ static int from_inetd = 1; static void @@ -75,9 +64,7 @@ main(void) if (!from_inetd) { daemon(0, 0); - (void)rpcb_unset(RQUOTAPROG, RQUOTAVERS, NULL); - (void)signal(SIGINT, cleanup); (void)signal(SIGTERM, cleanup); (void)signal(SIGHUP, cleanup); @@ -119,12 +106,10 @@ rquota_service(struct svc_req *request, SVCXPRT *transp) case NULLPROC: (void)svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL); break; - case RQUOTAPROC_GETQUOTA: case RQUOTAPROC_GETACTIVEQUOTA: sendquota(request, transp); break; - default: svcerr_noproc(transp); break; @@ -183,39 +168,39 @@ sendquota(struct svc_req *request, SVCXPRT *transp) } } -/* initialise the fs_tab list from entries in /etc/fstab */ static void initfs(void) { - struct fs_stat *fs_current = NULL; - struct fs_stat *fs_next = NULL; - char *qfpathname; struct fstab *fs; - struct stat st; setfsent(); + szqf = 8; + if ((qfa = malloc(szqf * sizeof *qfa)) == NULL) + goto enomem; while ((fs = getfsent())) { if (strcmp(fs->fs_vfstype, "ufs")) continue; - if (!hasquota(fs, &qfpathname)) + if (nqf >= szqf) { + szqf *= 2; + if ((qfa = reallocf(qfa, szqf * sizeof *qfa)) == NULL) + goto enomem; + } + if ((qfa[nqf] = quota_open(fs, USRQUOTA, O_RDONLY)) == NULL) { + if (errno != EOPNOTSUPP) + goto fserr; continue; - - fs_current = malloc(sizeof(struct fs_stat)); - fs_current->fs_next = fs_next; /* next element */ - - fs_current->fs_file = malloc(strlen(fs->fs_file) + 1); - strcpy(fs_current->fs_file, fs->fs_file); - - fs_current->qfpathname = malloc(strlen(qfpathname) + 1); - strcpy(fs_current->qfpathname, qfpathname); - - stat(fs_current->fs_file, &st); - fs_current->st_dev = st.st_dev; - - fs_next = fs_current; + } + ++nqf; + /* XXX */ } endfsent(); - fs_begin = fs_current; + return; +enomem: + syslog(LOG_ERR, "out of memory"); + exit(1); +fserr: + syslog(LOG_ERR, "%s: %s", fs->fs_file, strerror(errno)); + exit(1); } /* @@ -225,70 +210,10 @@ initfs(void) static int getfsquota(long id, char *path, struct dqblk *dqblk) { - struct quotafile *qf; - struct stat st_path; - struct fs_stat *fs; - int qcmd, ret = 0; + int i; - if (stat(path, &st_path) < 0) - return (0); - - qcmd = QCMD(Q_GETQUOTA, USRQUOTA); - - for (fs = fs_begin; fs != NULL; fs = fs->fs_next) { - /* where the device is the same as path */ - if (fs->st_dev != st_path.st_dev) - continue; - - /* find the specified filesystem. get and return quota */ - if (quotactl(fs->fs_file, qcmd, id, dqblk) == 0) - return (1); - - if ((qf = quota_open(fs->qfpathname)) == NULL) { - syslog(LOG_ERR, "open error: %s: %m", fs->qfpathname); - return (0); - } - if (quota_read(qf, dqblk, id) != 0) { - syslog(LOG_ERR, "read error: %s: %m", fs->qfpathname); - quota_close(qf); - return (0); - } - quota_close(qf); - } - return (ret); -} - -/* - * Check to see if a particular quota is to be enabled. - * Comes from quota.c, NetBSD 0.9 - */ -static int -hasquota(struct fstab *fs, char **qfnamep) -{ - static char initname, usrname[100]; - static char buf[BUFSIZ]; - char *opt, *cp; - const char *qfextension[] = INITQFNAMES; - - if (!initname) { - sprintf(usrname, "%s%s", qfextension[USRQUOTA], QUOTAFILENAME); - initname = 1; - } - strcpy(buf, fs->fs_mntops); - for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { - if ((cp = index(opt, '='))) - *cp++ = '\0'; - if (strcmp(opt, usrname) == 0) - break; - } - if (!opt) - return (0); - if (cp) { - *qfnamep = cp; - return (1); - } - sprintf(buf, "%s/%s.%s", fs->fs_file, QUOTAFILENAME, - qfextension[USRQUOTA]); - *qfnamep = buf; - return (1); + for (i = 0; i < nqf; ++i) + if (quota_check_path(qfa[i], path) == 1) + return (quota_read(qfa[i], dqblk, id) == 0); + return (0); } From 829b3f6be374043e042dd20b8b2097688820af22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 4 Mar 2010 10:54:29 +0000 Subject: [PATCH 031/532] Fix warnings + minor style issues --- usr.bin/quota/quota.c | 63 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/usr.bin/quota/quota.c b/usr.bin/quota/quota.c index 24dcb494230..240a7564bae 100644 --- a/usr.bin/quota/quota.c +++ b/usr.bin/quota/quota.c @@ -87,7 +87,7 @@ struct quotause { char fsname[MAXPATHLEN + 1]; }; -static char *timeprt(int64_t seconds, int *needfree); +static char *timeprt(int64_t seconds); static struct quotause *getprivs(long id, int quotatype); static void usage(void); static int showuid(u_long uid); @@ -281,8 +281,7 @@ showquotas(int type, u_long id, const char *name) struct quotause *quplist; const char *msgi, *msgb; const char *nam; - char *bgrace, *igrace; - int bfree, ifree; + char *bgrace = NULL, *igrace = NULL; int lines = 0, overquota = 0; static time_t now; @@ -290,7 +289,7 @@ showquotas(int type, u_long id, const char *name) time(&now); quplist = getprivs(id, type); for (qup = quplist; qup; qup = qup->next) { - msgi = (char *)0; + msgi = NULL; if (qup->dqblk.dqb_ihardlimit && qup->dqblk.dqb_curinodes >= qup->dqblk.dqb_ihardlimit) { overquota++; @@ -304,7 +303,7 @@ showquotas(int type, u_long id, const char *name) else msgi = "Over file quota on"; } - msgb = (char *)0; + msgb = NULL; if (qup->dqblk.dqb_bhardlimit && qup->dqblk.dqb_curblocks >= qup->dqblk.dqb_bhardlimit) { overquota++; @@ -329,12 +328,12 @@ showquotas(int type, u_long id, const char *name) qup->dqblk.dqb_bhardlimit == 0) continue; if (qflag) { - if ((msgi != (char *)0 || msgb != (char *)0) && + if ((msgi != NULL || msgb != NULL) && lines++ == 0) heading(type, id, name, ""); - if (msgi != (char *)0) + if (msgi != NULL) printf("\t%s %s\n", msgi, qup->fsname); - if (msgb != (char *)0) + if (msgb != NULL) printf("\t%s %s\n", msgb, qup->fsname); continue; } @@ -352,42 +351,42 @@ showquotas(int type, u_long id, const char *name) printf("%-15s", nam); if (hflag) { prthumanval(7, dbtob(qup->dqblk.dqb_curblocks)); - printf("%c", (msgb == (char *)0) ? ' ' : '*'); + printf("%c", (msgb == NULL) ? ' ' : '*'); prthumanval(7, dbtob(qup->dqblk.dqb_bsoftlimit)); prthumanval(7, dbtob(qup->dqblk.dqb_bhardlimit)); } else { printf(" %7ju%c %7ju %7ju", dbtob(1024) * (uintmax_t)qup->dqblk.dqb_curblocks, - (msgb == (char *)0) ? ' ' : '*', + (msgb == NULL) ? ' ' : '*', dbtob(1024) * (uintmax_t)qup->dqblk.dqb_bsoftlimit, dbtob(1024) * (uintmax_t)qup->dqblk.dqb_bhardlimit); } if (msgb != NULL) - bgrace = timeprt(qup->dqblk.dqb_btime, &bfree); + bgrace = timeprt(qup->dqblk.dqb_btime); if (msgi != NULL) - igrace = timeprt(qup->dqblk.dqb_itime, &ifree); + igrace = timeprt(qup->dqblk.dqb_itime); printf("%8s %6ju%c %6ju %6ju%8s\n" - , (msgb == (char *)0) ? "" : bgrace + , (msgb == NULL) ? "" : bgrace , (uintmax_t)qup->dqblk.dqb_curinodes - , (msgi == (char *)0) ? ' ' : '*' + , (msgi == NULL) ? ' ' : '*' , (uintmax_t)qup->dqblk.dqb_isoftlimit , (uintmax_t)qup->dqblk.dqb_ihardlimit - , (msgi == (char *)0) ? "" : igrace + , (msgi == NULL) ? "" : igrace ); - if (msgb != NULL && bfree) + if (msgb != NULL) free(bgrace); - if (msgi != NULL && ifree) + if (msgi != NULL) free(igrace); } if (!qflag && !rflag && lines == 0) heading(type, id, name, "none"); - return(overquota); + return (overquota); } static void showrawquotas(int type, u_long id, struct quotause *qup) { - time_t time; + time_t t; printf("Raw %s quota information for id %lu on %s\n", type == USRQUOTA ? "user" : "group", id, qup->fsname); @@ -406,15 +405,15 @@ showrawquotas(int type, u_long id, struct quotause *qup) printf("block grace time: %jd", (intmax_t)qup->dqblk.dqb_btime); if (qup->dqblk.dqb_btime != 0) { - time = qup->dqblk.dqb_btime; - printf(" %s", ctime(&time)); + t = qup->dqblk.dqb_btime; + printf(" %s", ctime(&t)); } else { printf("\n"); } printf("i-node grace time: %jd", (intmax_t)qup->dqblk.dqb_itime); if (qup->dqblk.dqb_itime != 0) { - time = qup->dqblk.dqb_itime; - printf(" %s", ctime(&time)); + t = qup->dqblk.dqb_itime; + printf(" %s", ctime(&t)); } else { printf("\n"); } @@ -446,37 +445,35 @@ heading(int type, u_long id, const char *name, const char *tag) * Calculate the grace period and return a printable string for it. */ static char * -timeprt(int64_t seconds, int *needfree) +timeprt(int64_t seconds) { time_t hours, minutes; - char *buf; + char *buf; static time_t now; if (now == 0) time(&now); if (now > seconds) { - *needfree = 0; - return ("none"); + if ((buf = strdup("none")) == NULL) + errx(1, "strdup() failed in timeprt()"); + return (buf); } seconds -= now; minutes = (seconds + 30) / 60; hours = (minutes + 30) / 60; if (hours >= 36) { if (asprintf(&buf, "%lddays", ((long)hours + 12) / 24) < 0) - errx(1, "asprintf failed in timeprt(1)"); - *needfree = 1; + errx(1, "asprintf() failed in timeprt(1)"); return (buf); } if (minutes >= 60) { if (asprintf(&buf, "%2ld:%ld", (long)minutes / 60, (long)minutes % 60) < 0) - errx(1, "asprintf failed in timeprt(2)"); - *needfree = 1; + errx(1, "asprintf() failed in timeprt(2)"); return (buf); } if (asprintf(&buf, "%2ld", (long)minutes) < 0) - errx(1, "asprintf failed in timeprt(3)"); - *needfree = 1; + errx(1, "asprintf() failed in timeprt(3)"); return (buf); } From 7c54172a4f9db27283aaead2ee3c694f109ca497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 4 Mar 2010 10:57:52 +0000 Subject: [PATCH 032/532] Fix warnings + indentation + utmpx --- usr.sbin/repquota/repquota.c | 48 +++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c index aa822df09d2..f90269f173c 100644 --- a/usr.sbin/repquota/repquota.c +++ b/usr.sbin/repquota/repquota.c @@ -49,7 +49,9 @@ __FBSDID("$FreeBSD$"); */ #include #include + #include + #include #include #include @@ -57,12 +59,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include #include -#include /* Let's be paranoid about block size */ #if 10 > DEV_BSHIFT @@ -218,9 +220,9 @@ repquota(struct fstab *fs, int type) fprintf(stdout, "*** Report for %s quotas on %s (%s)\n", qfextension[type], fs->fs_file, fs->fs_spec); printf("%*s Block limits File limits\n", - max(UT_NAMESIZE,10), " "); + max(MAXLOGNAME - 1, 10), " "); printf("User%*s used soft hard grace used soft hard grace\n", - max(UT_NAMESIZE,10), " "); + max(MAXLOGNAME - 1, 10), " "); maxid = quota_maxid(qf); for (id = 0; id < maxid; id++) { if (quota_read(qf, &dqbuf, id) != 0) @@ -229,30 +231,30 @@ repquota(struct fstab *fs, int type) continue; if ((fup = lookup(id, type)) == 0) fup = addid(id, type, (char *)0); - printf("%-*s ", max(UT_NAMESIZE,10), fup->fu_name); + printf("%-*s ", max(MAXLOGNAME - 1, 10), fup->fu_name); printf("%c%c", - dqbuf.dqb_bsoftlimit && - dqbuf.dqb_curblocks >= - dqbuf.dqb_bsoftlimit ? '+' : '-', - dqbuf.dqb_isoftlimit && - dqbuf.dqb_curinodes >= - dqbuf.dqb_isoftlimit ? '+' : '-'); + dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= + dqbuf.dqb_bsoftlimit ? '+' : '-', + dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= + dqbuf.dqb_isoftlimit ? '+' : '-'); prthumanval(dqbuf.dqb_curblocks); prthumanval(dqbuf.dqb_bsoftlimit); prthumanval(dqbuf.dqb_bhardlimit); printf(" %6s", - dqbuf.dqb_bsoftlimit && - dqbuf.dqb_curblocks >= - dqbuf.dqb_bsoftlimit ? - timeprt(dqbuf.dqb_btime) : "-"); - printf(" %7llu %7llu %7llu %6s\n", - dqbuf.dqb_curinodes, - dqbuf.dqb_isoftlimit, - dqbuf.dqb_ihardlimit, - dqbuf.dqb_isoftlimit && - dqbuf.dqb_curinodes >= - dqbuf.dqb_isoftlimit ? - timeprt(dqbuf.dqb_itime) : "-"); + dqbuf.dqb_bsoftlimit && + dqbuf.dqb_curblocks >= + dqbuf.dqb_bsoftlimit ? + timeprt(dqbuf.dqb_btime) : "-"); + printf(" %7ju %7ju %7ju %6s\n", + (uintmax_t)dqbuf.dqb_curinodes, + (uintmax_t)dqbuf.dqb_isoftlimit, + (uintmax_t)dqbuf.dqb_ihardlimit, + dqbuf.dqb_isoftlimit && + dqbuf.dqb_curinodes >= + dqbuf.dqb_isoftlimit ? + timeprt(dqbuf.dqb_itime) : "-"); } quota_close(qf); return (0); @@ -265,7 +267,7 @@ prthumanval(int64_t blocks) int flags; if (!hflag) { - printf(" %6llu", dbtokb(blocks)); + printf(" %6ju", (uintmax_t)dbtokb(blocks)); return; } flags = HN_NOSPACE | HN_DECIMAL; From 516ad57b74be8c0b950e246197c1cd5e091995f3 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Tue, 16 Mar 2010 06:12:30 +0000 Subject: [PATCH 033/532] Debugging nits found while testing the new 64-bit quota code. --- lib/libc/sys/quotactl.2 | 22 ++++++++++++++++---- lib/libutil/quotafile.c | 34 ++++++++++++++++--------------- sys/ufs/ufs/quota.h | 2 ++ sys/ufs/ufs/ufs_quota.c | 39 +++++++++++++++++++++++++++++++++--- sys/ufs/ufs/ufs_vfsops.c | 4 ++++ usr.bin/quota/Makefile | 1 + usr.sbin/repquota/repquota.c | 2 +- 7 files changed, 80 insertions(+), 24 deletions(-) diff --git a/lib/libc/sys/quotactl.2 b/lib/libc/sys/quotactl.2 index 4b4dca5fbcb..ff3cb4b1756 100644 --- a/lib/libc/sys/quotactl.2 +++ b/lib/libc/sys/quotactl.2 @@ -84,7 +84,7 @@ and group identifiers (GRPQUOTA). The .Dq ufs specific commands are: -.Bl -tag -width Q_QUOTAOFFxx +.Bl -tag -width Q_GETQUOTASIZEx .It Dv Q_QUOTAON Enable disk quotas for the file system specified by .Fa path . @@ -110,6 +110,17 @@ and .Fa id arguments are unused. Only the super-user may turn quotas off. +.It Dv Q_GETQUOTASIZE +Get the wordsize used to represent the quotas for the user or group +(as determined by the command type). +Possible values are 32 for the old-style quota file +and 64 for the new-style quota file. +The +.Fa addr +argument is a pointer to an integer into which the size is stored. +The identifier +.Fa id +is not used. .It Dv Q_GETQUOTA Get disk quota limits and current usage for the user or group (as determined by the command type) with identifier @@ -177,9 +188,11 @@ The argument or the command type is invalid. In -.Dv Q_GETQUOTA -and +.Dv Q_GETQUOTASIZE , +.Dv Q_GETQUOTA , .Dv Q_SETQUOTA , +and +.Dv Q_SETUSE , quotas are not currently enabled for this file system. .Pp The @@ -208,7 +221,8 @@ Too many symbolic links were encountered in translating a pathname. .It Bq Er EROFS In .Dv Q_QUOTAON , -the quota file resides on a read-only file system. +either the file system on which quotas are to be enabled is mounted read-only +or the quota file resides on a read-only file system. .It Bq Er EIO An .Tn I/O diff --git a/lib/libutil/quotafile.c b/lib/libutil/quotafile.c index ab57d662bdc..0fda5f62687 100644 --- a/lib/libutil/quotafile.c +++ b/lib/libutil/quotafile.c @@ -129,11 +129,9 @@ quota_open(struct fstab *fs, int quotatype, int openflags) goto error; qf->dev = st.st_dev; serrno = hasquota(fs, quotatype, qf->qfname, sizeof(qf->qfname)); - qcmd = QCMD(Q_GETQUOTA, quotatype); - if (quotactl(fs->fs_file, qcmd, 0, &dqh) == 0) { - qf->wordsize = 64; + qcmd = QCMD(Q_GETQUOTASIZE, quotatype); + if (quotactl(qf->fsname, qcmd, 0, &qf->wordsize) == 0) return (qf); - } if (serrno == 0) { errno = EOPNOTSUPP; goto error; @@ -250,18 +248,22 @@ int quota_maxid(struct quotafile *qf) { struct stat st; + int maxid; if (stat(qf->qfname, &st) < 0) return (0); switch (qf->wordsize) { case 32: - return (st.st_size / sizeof(struct dqblk32) - 1); + maxid = st.st_size / sizeof(struct dqblk32) - 1; + break; case 64: - return (st.st_size / sizeof(struct dqblk64) - 2); + maxid = st.st_size / sizeof(struct dqblk64) - 2; + break; default: - return (0); + maxid = 0; + break; } - /* not reached */ + return (maxid > 0 ? maxid : 0); } static int @@ -395,10 +397,6 @@ quota_write_usage(struct quotafile *qf, struct dqblk *dqb, int id) struct dqblk dqbuf; int qcmd; - if ((qf->accmode & O_RDWR) != O_RDWR) { - errno = EBADF; - return (-1); - } if (qf->fd == -1) { qcmd = QCMD(Q_SETUSE, qf->quotatype); return (quotactl(qf->fsname, qcmd, id, dqb)); @@ -406,6 +404,10 @@ quota_write_usage(struct quotafile *qf, struct dqblk *dqb, int id) /* * Have to do read-modify-write of quota in file. */ + if ((qf->accmode & O_RDWR) != O_RDWR) { + errno = EBADF; + return (-1); + } if (quota_read(qf, &dqbuf, id) != 0) return (-1); /* @@ -443,10 +445,6 @@ quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id) struct dqblk dqbuf; int qcmd; - if ((qf->accmode & O_RDWR) != O_RDWR) { - errno = EBADF; - return (-1); - } if (qf->fd == -1) { qcmd = QCMD(Q_SETQUOTA, qf->quotatype); return (quotactl(qf->fsname, qcmd, id, dqb)); @@ -454,6 +452,10 @@ quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id) /* * Have to do read-modify-write of quota in file. */ + if ((qf->accmode & O_RDWR) != O_RDWR) { + errno = EBADF; + return (-1); + } if (quota_read(qf, &dqbuf, id) != 0) return (-1); /* diff --git a/sys/ufs/ufs/quota.h b/sys/ufs/ufs/quota.h index 82b0170b036..ca0dcced7d2 100644 --- a/sys/ufs/ufs/quota.h +++ b/sys/ufs/ufs/quota.h @@ -88,6 +88,7 @@ #define Q_GETQUOTA 0x0700 /* get limits and usage (64-bit version) */ #define Q_SETQUOTA 0x0800 /* set limits and usage (64-bit version) */ #define Q_SETUSE 0x0900 /* set usage (64-bit version) */ +#define Q_GETQUOTASIZE 0x0A00 /* get bit-size of quota file fields */ /* * The following structure defines the format of the disk quota file @@ -235,6 +236,7 @@ int setuse32(struct thread *, struct mount *, u_long, int, void *); int getquota(struct thread *, struct mount *, u_long, int, void *); int setquota(struct thread *, struct mount *, u_long, int, void *); int setuse(struct thread *, struct mount *, u_long, int, void *); +int getquotasize(struct thread *, struct mount *, u_long, int, void *); vfs_quotactl_t ufs_quotactl; #else /* !_KERNEL */ diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 5b1da50b73a..c5161899aa8 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -508,6 +508,9 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname) if (error) return (error); + if (mp->mnt_flag & MNT_RDONLY) + return (EROFS); + ump = VFSTOUFS(mp); dq = NODQUOT; @@ -534,7 +537,9 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname) return (EALREADY); } ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING; + UFS_UNLOCK(ump); if ((error = dqopen(vp, ump, type)) != 0) { + UFS_LOCK(ump); ump->um_qflags[type] &= ~(QTF_OPENING|QTF_CLOSING); UFS_UNLOCK(ump); (void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td); @@ -544,7 +549,6 @@ quotaon(struct thread *td, struct mount *mp, int type, void *fname) MNT_ILOCK(mp); mp->mnt_flag |= MNT_QUOTA; MNT_IUNLOCK(mp); - UFS_UNLOCK(ump); vpp = &ump->um_quotas[type]; if (*vpp != vp) @@ -988,6 +992,30 @@ setuse(struct thread *td, struct mount *mp, u_long id, int type, void *addr) return (error); } +/* + * Q_GETQUOTASIZE - get bit-size of quota file fields + */ +int +getquotasize(struct thread *td, struct mount *mp, u_long id, int type, + void *sizep) +{ + struct ufsmount *ump = VFSTOUFS(mp); + int bitsize; + + UFS_LOCK(ump); + if (ump->um_quotas[type] == NULLVP || + (ump->um_qflags[type] & QTF_CLOSING)) { + UFS_UNLOCK(ump); + return (EINVAL); + } + if ((ump->um_qflags[type] & QTF_64BIT) != 0) + bitsize = 64; + else + bitsize = 32; + UFS_UNLOCK(ump); + return (copyout(&bitsize, sizep, sizeof(int))); +} + /* * Q_SYNC - sync quota files to disk. */ @@ -1163,12 +1191,17 @@ dqopen(struct vnode *vp, struct ufsmount *ump, int type) return (0); } + UFS_LOCK(ump); if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) == 0 && be32toh(dqh.dqh_version) == Q_DQHDR64_VERSION && be32toh(dqh.dqh_hdrlen) == (uint32_t)sizeof(struct dqhdr64) && - be32toh(dqh.dqh_reclen) == (uint32_t)sizeof(struct dqblk64)) + be32toh(dqh.dqh_reclen) == (uint32_t)sizeof(struct dqblk64)) { + /* XXX: what if the magic matches, but the sizes are wrong? */ ump->um_qflags[type] |= QTF_64BIT; - /* XXX: what if the magic matches, but the sizes are wrong? */ + } else { + ump->um_qflags[type] &= ~QTF_64BIT; + } + UFS_UNLOCK(ump); return (0); } diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 3abd5eb7839..0eeb14fc54e 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -151,6 +151,10 @@ ufs_quotactl(mp, cmds, id, arg) error = getquota(td, mp, id, type, arg); break; + case Q_GETQUOTASIZE: + error = getquotasize(td, mp, id, type, arg); + break; + case Q_SYNC: error = qsync(mp); break; diff --git a/usr.bin/quota/Makefile b/usr.bin/quota/Makefile index a479402878f..26585ae2b72 100644 --- a/usr.bin/quota/Makefile +++ b/usr.bin/quota/Makefile @@ -3,6 +3,7 @@ PROG= quota BINOWN= root +BINMODE=4555 DPADD= ${LIBRPCSVC} ${LIBUTIL} LDADD= -lrpcsvc -lutil diff --git a/usr.sbin/repquota/repquota.c b/usr.sbin/repquota/repquota.c index f90269f173c..8fdea201554 100644 --- a/usr.sbin/repquota/repquota.c +++ b/usr.sbin/repquota/repquota.c @@ -224,7 +224,7 @@ repquota(struct fstab *fs, int type) printf("User%*s used soft hard grace used soft hard grace\n", max(MAXLOGNAME - 1, 10), " "); maxid = quota_maxid(qf); - for (id = 0; id < maxid; id++) { + for (id = 0; id <= maxid; id++) { if (quota_read(qf, &dqbuf, id) != 0) break; if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) From 1a0a89c328dc7176c2058e08087761d0b9957ff8 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 12 Apr 2010 17:43:58 +0000 Subject: [PATCH 034/532] Import zlib 1.2.4.3 (trimmed). --- ChangeLog | 28 ++++++++++++++++++++++++++++ README | 7 ++++--- deflate.c | 2 +- gzguts.h | 12 +++++++----- gzlib.c | 6 ++++-- inftrees.c | 4 ++-- minigzip.c | 5 +++++ zconf.h | 11 ++++++++++- zlib.3 | 4 ++-- zlib.h | 44 ++++++++++++++++++++++++++------------------ zutil.h | 16 +++------------- 11 files changed, 92 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9817f59b7a1..898c197f0cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,34 @@ ChangeLog file for zlib +Changes in 1.2.4.3 (10 Apr 2010) +- Only use CROSS_PREFIX in configure for ar and ranlib if they exist +- Use CROSS_PREFIX for nm [Bar-Lev] +- Assume _LARGEFILE64_SOURCE defined is equivalent to true +- Avoid use of undefined symbols in #if with && and || +- Make *64 prototypes in gzguts.h consistent with functions +- Add -shared load option for MinGW in configure [Bowler] +- Move z_off64_t to public interface, use instead of off64_t +- Remove ! from shell test in configure (not portable to Solaris) +- Change +0 macro tests to -0 for possibly increased portability + +Changes in 1.2.4.2 (9 Apr 2010) +- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 +- Really provide prototypes for *64 functions when building without LFS +- Only define unlink() in minigzip.c if unistd.h not included +- Update README to point to contrib/vstudio project files +- Move projects/vc6 to old/ and remove projects/ +- Include stdlib.h in minigzip.c for setmode() definition under WinCE +- Clean up assembler builds in win32/Makefile.msc [Rowe] +- Include sys/types.h for Microsoft for off_t definition +- Fix memory leak on error in gz_open() +- Symbolize nm as $NM in configure [Weigelt] +- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] +- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined +- Fix bug in gzeof() to take into account unused input data +- Avoid initialization of structures with variables in puff.c +- Updated win32/README-WIN32.txt [Rowe] + Changes in 1.2.4.1 (28 Mar 2010) - Remove the use of [a-z] constructs for sed in configure [gentoo 310225] - Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] diff --git a/README b/README index a3302675ec2..68ff992369c 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.2.4.1 is a general purpose data compression library. All the code is +zlib 1.2.4.3 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) @@ -16,7 +16,8 @@ minigzip.c. To compile all files and run the test program, follow the instructions given at the top of Makefile.in. In short "./configure; make test", and if that goes well, "make install" should work for most flavors of Unix. For Windows, use one -of the special makefiles in win32/ or projects/ . For VMS, use make_vms.com. +of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use +make_vms.com. Questions about zlib should be sent to , or to Gilles Vollant for the Windows DLL version. The zlib home page is @@ -30,7 +31,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at http://marknelson.us/1997/01/01/zlib-engine/ . -The changes made in version 1.2.4.1 are documented in the file ChangeLog. +The changes made in version 1.2.4.3 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . diff --git a/deflate.c b/deflate.c index b7fb9fc6982..efb26bf5d91 100644 --- a/deflate.c +++ b/deflate.c @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.4.1 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.4.3 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot diff --git a/gzguts.h b/gzguts.h index 53857e0a42b..b0a4cbdc336 100644 --- a/gzguts.h +++ b/gzguts.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -#if _LARGEFILE64_SOURCE == 1 +#ifdef _LARGEFILE64_SOURCE # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 # endif @@ -56,10 +56,12 @@ # endif #endif -#if _LARGEFILE64_SOURCE == 1 -# define z_off64_t off64_t -#else -# define z_off64_t z_off_t +/* provide prototypes for these when building zlib without LFS */ +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); #endif /* default i/o buffer size -- double this for output when reading */ diff --git a/gzlib.c b/gzlib.c index 15999aee8b5..18390026905 100644 --- a/gzlib.c +++ b/gzlib.c @@ -5,7 +5,7 @@ #include "gzguts.h" -#if _LARGEFILE64_SOURCE == 1 && _LFS64_LARGEFILE == 1 +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 # define LSEEK lseek64 #else # define LSEEK lseek @@ -172,6 +172,7 @@ local gzFile gz_open(path, fd, mode) O_APPEND))), 0666); if (state->fd == -1) { + free(state->path); free(state); return NULL; } @@ -432,7 +433,8 @@ int ZEXPORT gzeof(file) return 0; /* return end-of-file state */ - return state->mode == GZ_READ ? (state->eof && state->have == 0) : 0; + return state->mode == GZ_READ ? + (state->eof && state->strm.avail_in == 0 && state->have == 0) : 0; } /* -- see zlib.h -- */ diff --git a/inftrees.c b/inftrees.c index 90de8b87f25..430b1741585 100644 --- a/inftrees.c +++ b/inftrees.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.4.1 Copyright 1995-2010 Mark Adler "; + " inflate 1.2.4.3 Copyright 1995-2010 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -62,7 +62,7 @@ unsigned short FAR *work; 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 67, 206}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 195, 66}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/minigzip.c b/minigzip.c index 9677fa07f63..9825ccc3a71 100644 --- a/minigzip.c +++ b/minigzip.c @@ -32,6 +32,9 @@ #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) # include # include +# ifdef UNDER_CE +# include +# endif # define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else # define SET_BINARY_MODE(file) @@ -50,9 +53,11 @@ # include /* for fileno */ #endif +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) #ifndef WIN32 /* unlink already in stdio.h for WIN32 */ extern int unlink OF((const char *)); #endif +#endif #if defined(UNDER_CE) # include diff --git a/zconf.h b/zconf.h index 6ad8a04edae..1988920109f 100644 --- a/zconf.h +++ b/zconf.h @@ -364,8 +364,11 @@ typedef uLong FAR uLongf; # define Z_HAVE_UNISTD_H #endif -#if defined(Z_HAVE_UNISTD_H) || _LARGEFILE64_SOURCE == 1 +#ifdef STDC # include /* for off_t */ +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) # include /* for SEEK_* and off_t */ # ifdef VMS # include /* for off_t */ @@ -385,6 +388,12 @@ typedef uLong FAR uLongf; # define z_off_t long #endif +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define z_off64_t off64_t +#else +# define z_off64_t z_off_t +#endif + #if defined(__OS400__) # define NO_vsnprintf #endif diff --git a/zlib.3 b/zlib.3 index 2c1679d7b27..b5346168d0e 100644 --- a/zlib.3 +++ b/zlib.3 @@ -1,4 +1,4 @@ -.TH ZLIB 3 "28 Mar 2010" +.TH ZLIB 3 "10 Apr 2010" .SH NAME zlib \- compression/decompression library .SH SYNOPSIS @@ -125,7 +125,7 @@ before asking for help. Send questions and/or comments to zlib@gzip.org, or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). .SH AUTHORS -Version 1.2.4.1 +Version 1.2.4.3 Copyright (C) 1995-2010 Jean-loup Gailly (jloup@gzip.org) and Mark Adler (madler@alumni.caltech.edu). .LP diff --git a/zlib.h b/zlib.h index 1fcf6300cc2..699630c1ddc 100644 --- a/zlib.h +++ b/zlib.h @@ -1,5 +1,5 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.4.1, March 28th, 2010 + version 1.2.4.3, April 10th, 2010 Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler @@ -37,12 +37,12 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.4.1" -#define ZLIB_VERNUM 0x1241 +#define ZLIB_VERSION "1.2.4.3" +#define ZLIB_VERNUM 0x1243 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 #define ZLIB_VER_REVISION 4 -#define ZLIB_VER_SUBREVISION 1 +#define ZLIB_VER_SUBREVISION 3 /* The 'zlib' compression library provides in-memory compression and @@ -1556,29 +1556,35 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, inflateBackInit_((strm), (windowBits), (window), \ ZLIB_VERSION, sizeof(z_stream)) -#if _LARGEFILE64_SOURCE == 1 && _LFS64_LARGEFILE == 1 +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN off64_t ZEXPORT gzseek64 OF((gzFile, off64_t, int)); - ZEXTERN off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off64_t)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS == 64 && _LFS64_LARGEFILE == 1 +#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 # define gzopen gzopen64 # define gzseek gzseek64 # define gztell gztell64 # define gzoffset gzoffset64 # define adler32_combine adler32_combine64 # define crc32_combine crc32_combine64 -# if _LARGEFILE64_SOURCE != 1 +# ifdef _LARGEFILE64_SOURCE ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN off_t ZEXPORT gzseek64 OF((gzFile, off_t, int)); - ZEXTERN off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off_t)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); # endif #else ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); @@ -1589,10 +1595,12 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif +/* hack for buggy compilers */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ + struct internal_state {int dummy;}; #endif +/* undocumented functions */ ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); diff --git a/zutil.h b/zutil.h index b21a19cc043..a250088640a 100644 --- a/zutil.h +++ b/zutil.h @@ -154,20 +154,10 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #pragma warn -8066 #endif -#if _LARGEFILE64_SOURCE == 1 && _LFS64_LARGEFILE == 1 -# define z_off64_t off64_t -#else -# define z_off64_t z_off_t -#endif - /* provide prototypes for these when building zlib without LFS */ -#if _LARGEFILE64_SOURCE != 1 || _LFS64_LARGEFILE != 1 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN off_t ZEXPORT gzseek64 OF((gzFile, off_t, int)); - ZEXTERN off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off_t)); +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif /* common defaults */ From 0a5cd2607a04bc91bc394a08dd7b38b7ab75f0c2 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Wed, 14 Apr 2010 01:29:31 +0000 Subject: [PATCH 035/532] Revert the vm_machdep.c part of r205072. This causes a panic in vm_thread_dispose() when it tries to add this kstack to the kstack cache. This happens only when 'td_kstack' is not (PAGE_SIZE * 2) bytes aligned and we have unmapped the page at that address in cpu_thread_alloc. Pointed out by: nwhitehorn@ --- sys/mips/mips/vm_machdep.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 3f8e6cc7f29..57219f638f5 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -214,16 +214,6 @@ cpu_thread_swapin(struct thread *td) { pt_entry_t *pte; int i; - vm_offset_t unused_kstack_page; - - /* - * Unmap the unused kstack page. - */ - unused_kstack_page = td->td_kstack; - if (td->td_md.md_realstack == td->td_kstack) - unused_kstack_page += (KSTACK_PAGES - 1) * PAGE_SIZE; - - pmap_kremove(unused_kstack_page); /* * The kstack may be at a different physical address now. @@ -249,19 +239,13 @@ cpu_thread_swapout(struct thread *td) void cpu_thread_alloc(struct thread *td) { - vm_offset_t unused_kstack_page; pt_entry_t *pte; int i; - if (td->td_kstack & (1 << PAGE_SHIFT)) { + if (td->td_kstack & (1 << PAGE_SHIFT)) td->td_md.md_realstack = td->td_kstack + PAGE_SIZE; - unused_kstack_page = td->td_kstack; - } else { + else td->td_md.md_realstack = td->td_kstack; - unused_kstack_page = td->td_kstack + - (KSTACK_PAGES - 1) * PAGE_SIZE; - } - pmap_kremove(unused_kstack_page); td->td_pcb = (struct pcb *)(td->td_md.md_realstack + (td->td_kstack_pages - 1) * PAGE_SIZE) - 1; From 923ca9167bfee22ed4d3a749ae5e01064d0bae10 Mon Sep 17 00:00:00 2001 From: Neel Natu Date: Wed, 14 Apr 2010 01:57:53 +0000 Subject: [PATCH 036/532] Destroy the pmap 'pm_mutex' in pmap_release() otherwise we will panic subsequently in pmap_pinit() with the following signature: panic: lock "pmap" 0xc7878bc8 already initialized This bug was uncovered by the changes made to vm_map.c in r206140. --- sys/mips/mips/pmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 73f57e4fbee..d5765ea9b0e 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -1263,6 +1263,7 @@ pmap_release(pmap_t pmap) ptdpg->wire_count--; atomic_subtract_int(&cnt.v_wire_count, 1); vm_page_free_zero(ptdpg); + PMAP_LOCK_DESTROY(pmap); } /* From 547f27959bb05d2f5e998cb0fd3d9d68313c6800 Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Wed, 14 Apr 2010 07:07:43 +0000 Subject: [PATCH 037/532] Eliminate duplicate comment --- sys/dev/usb/usbdevs | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 4cf2891af76..a7bac4405e8 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -2515,7 +2515,6 @@ product QUALCOMMINC E0086 0x0086 3G modem product QUALCOMMINC E2002 0x2002 3G modem product QUALCOMMINC E2003 0x2003 3G modem -/* Quanta products */ /* Quanta products */ product QUANTA RW6815_1 0x00ce HP iPAQ rw6815 product QUANTA RT3070 0x0304 RT3070 From 0a6b4947d88bb216a16441ccaa4aa9164efbbbd3 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 14 Apr 2010 13:44:22 +0000 Subject: [PATCH 038/532] Linux puts a blank line between each CPU. --- sys/compat/linprocfs/linprocfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index e6a4f16564a..58d897e9d08 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -274,7 +274,7 @@ linprocfs_docpuinfo(PFS_FILL_ARGS) "cpu family\t: %d\n" "model\t\t: %d\n" "model name\t: %s\n" - "stepping\t: %d\n", + "stepping\t: %d\n\n", i, cpu_vendor, class, cpu, model, cpu_id & 0xf); /* XXX per-cpu vendor / class / model / id? */ } From b9f59cca0d3f142de2acd5426da7bb950c85bb3e Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 14 Apr 2010 15:29:32 +0000 Subject: [PATCH 039/532] For early ALI chips do not announce I/O sizes that require unsupported 48bit DMA commands. --- sys/dev/ata/chipsets/ata-acerlabs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-acerlabs.c b/sys/dev/ata/chipsets/ata-acerlabs.c index b7f11472da2..fee9692ebd5 100644 --- a/sys/dev/ata/chipsets/ata-acerlabs.c +++ b/sys/dev/ata/chipsets/ata-acerlabs.c @@ -184,8 +184,11 @@ ata_ali_ch_attach(device_t dev) if (ctlr->chip->cfg2 & ALI_NEW && ctlr->chip->chiprev < 0xc7) ch->flags |= ATA_CHECKS_CABLE; /* older chips can't do 48bit DMA transfers */ - if (ctlr->chip->chiprev <= 0xc4) + if (ctlr->chip->chiprev <= 0xc4) { ch->flags |= ATA_NO_48BIT_DMA; + if (ch->dma.max_iosize > 256 * 512) + ch->dma.max_iosize = 256 * 512; + } return 0; } From 7ea05bb9a5cf8d64f7479c30ecdc781028f09463 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Wed, 14 Apr 2010 18:29:01 +0000 Subject: [PATCH 040/532] Remove multiqueue stack related stuff form lem, it is unneeded for legacy hardware. Also remove some TSO related cruft. Add some watchdog_time setting that was missing, thanks to Mikolaj Golub for pointing that out. --- sys/dev/e1000/if_lem.c | 164 ++--------------------------------------- 1 file changed, 5 insertions(+), 159 deletions(-) diff --git a/sys/dev/e1000/if_lem.c b/sys/dev/e1000/if_lem.c index cf71f2bb74b..825fb4ee6f0 100644 --- a/sys/dev/e1000/if_lem.c +++ b/sys/dev/e1000/if_lem.c @@ -39,9 +39,6 @@ #include #include -#if __FreeBSD_version >= 800000 -#include -#endif #include #include #include @@ -94,7 +91,7 @@ int lem_display_debug_stats = 0; /********************************************************************* * Legacy Em Driver version: *********************************************************************/ -char lem_driver_version[] = "1.0.0"; +char lem_driver_version[] = "1.0.1"; /********************************************************************* @@ -177,11 +174,6 @@ static int lem_suspend(device_t); static int lem_resume(device_t); static void lem_start(struct ifnet *); static void lem_start_locked(struct ifnet *ifp); -#if __FreeBSD_version >= 800000 -static int lem_mq_start(struct ifnet *, struct mbuf *); -static int lem_mq_start_locked(struct ifnet *, struct mbuf *); -static void lem_qflush(struct ifnet *); -#endif static int lem_ioctl(struct ifnet *, u_long, caddr_t); static void lem_init(void *); static void lem_init_locked(struct adapter *); @@ -304,12 +296,6 @@ MODULE_DEPEND(lem, ether, 1, 1, 1); #define EM_TICKS_TO_USECS(ticks) ((1024 * (ticks) + 500) / 1000) #define EM_USECS_TO_TICKS(usecs) ((1000 * (usecs) + 512) / 1024) -#define M_TSO_LEN 66 - -/* Allow common code without TSO */ -#ifndef CSUM_TSO -#define CSUM_TSO 0 -#endif static int lem_tx_int_delay_dflt = EM_TICKS_TO_USECS(EM_TIDV); static int lem_rx_int_delay_dflt = EM_TICKS_TO_USECS(EM_RDTR); @@ -827,118 +813,6 @@ lem_resume(device_t dev) } -/********************************************************************* - * Transmit entry point - * - * em_start is called by the stack to initiate a transmit. - * The driver will remain in this routine as long as there are - * packets to transmit and transmit resources are available. - * In case resources are not available stack is notified and - * the packet is requeued. - **********************************************************************/ - -#if __FreeBSD_version >= 800000 -static int -lem_mq_start_locked(struct ifnet *ifp, struct mbuf *m) -{ - struct adapter *adapter = ifp->if_softc; - struct mbuf *next; - int error = E1000_SUCCESS; - - EM_TX_LOCK_ASSERT(adapter); - /* To allow being called from a tasklet */ - if (m == NULL) - goto process; - - if (((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING) - || (!adapter->link_active)) { - error = drbr_enqueue(ifp, adapter->br, m); - return (error); - } else if (drbr_empty(ifp, adapter->br) && - (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) { - if ((error = lem_xmit(adapter, &m)) != 0) { - if (m) - error = drbr_enqueue(ifp, adapter->br, m); - return (error); - } else { - /* - * We've bypassed the buf ring so we need to update - * ifp directly - */ - drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags); - /* - ** Send a copy of the frame to the BPF - ** listener and set the watchdog on. - */ - ETHER_BPF_MTAP(ifp, m); - adapter->watchdog_check = TRUE; - } - } else if ((error = drbr_enqueue(ifp, adapter->br, m)) != 0) - return (error); - -process: - if (drbr_empty(ifp, adapter->br)) - return(error); - /* Process the queue */ - while (TRUE) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) - break; - next = drbr_dequeue(ifp, adapter->br); - if (next == NULL) - break; - if ((error = lem_xmit(adapter, &next)) != 0) { - if (next != NULL) - error = drbr_enqueue(ifp, adapter->br, next); - break; - } - drbr_stats_update(ifp, next->m_pkthdr.len, next->m_flags); - ETHER_BPF_MTAP(ifp, next); - /* Set the watchdog */ - adapter->watchdog_check = TRUE; - } - - if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - - return (error); -} - -/* -** Multiqueue capable stack interface, this is not -** yet truely multiqueue, but that is coming... -*/ -static int -lem_mq_start(struct ifnet *ifp, struct mbuf *m) -{ - - struct adapter *adapter = ifp->if_softc; - int error = 0; - - if (EM_TX_TRYLOCK(adapter)) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - error = lem_mq_start_locked(ifp, m); - EM_TX_UNLOCK(adapter); - } else - error = drbr_enqueue(ifp, adapter->br, m); - - return (error); -} - -static void -lem_qflush(struct ifnet *ifp) -{ - struct mbuf *m; - struct adapter *adapter = (struct adapter *)ifp->if_softc; - - EM_TX_LOCK(adapter); - while ((m = buf_ring_dequeue_sc(adapter->br)) != NULL) - m_freem(m); - if_qflush(ifp); - EM_TX_UNLOCK(adapter); -} -#endif /* FreeBSD_version */ - static void lem_start_locked(struct ifnet *ifp) { @@ -975,6 +849,7 @@ lem_start_locked(struct ifnet *ifp) /* Set timeout in case hardware has problems transmitting. */ adapter->watchdog_check = TRUE; + adapter->watchdog_time = ticks; } if (adapter->num_tx_desc_avail <= EM_TX_OP_THRESHOLD) ifp->if_drv_flags |= IFF_DRV_OACTIVE; @@ -1151,12 +1026,6 @@ lem_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_capenable ^= IFCAP_HWCSUM; reinit = 1; } -#if __FreeBSD_version >= 700000 - if (mask & IFCAP_TSO4) { - ifp->if_capenable ^= IFCAP_TSO4; - reinit = 1; - } -#endif if (mask & IFCAP_VLAN_HWTAGGING) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; reinit = 1; @@ -1279,10 +1148,6 @@ lem_init_locked(struct adapter *adapter) if (adapter->hw.mac.type >= e1000_82543) { if (ifp->if_capenable & IFCAP_TXCSUM) ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP); -#if __FreeBSD_version >= 700000 - if (ifp->if_capenable & IFCAP_TSO4) - ifp->if_hwassist |= CSUM_TSO; -#endif } /* Configure for OS presence */ @@ -1394,13 +1259,8 @@ lem_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) EM_TX_LOCK(adapter); lem_txeof(adapter); -#if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, adapter->br)) - lem_mq_start_locked(ifp, NULL); -#else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) lem_start_locked(ifp); -#endif EM_TX_UNLOCK(adapter); return (rx_done); } @@ -1494,14 +1354,8 @@ lem_handle_rxtx(void *context, int pending) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); EM_TX_LOCK(adapter); lem_txeof(adapter); - -#if __FreeBSD_version >= 800000 - if (!drbr_empty(ifp, adapter->br)) - lem_mq_start_locked(ifp, NULL); -#else if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) lem_start_locked(ifp); -#endif EM_TX_UNLOCK(adapter); } @@ -1852,15 +1706,17 @@ lem_xmit(struct adapter *adapter, struct mbuf **m_headp) if (mtag != NULL) { ctxd->upper.fields.special = htole16(VLAN_TAG_VALUE(mtag)); + ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); + } #else /* FreeBSD 7 */ if (m_head->m_flags & M_VLANTAG) { /* Set the vlan id. */ ctxd->upper.fields.special = htole16(m_head->m_pkthdr.ether_vtag); -#endif /* Tell hardware to add tag */ ctxd->lower.data |= htole32(E1000_TXD_CMD_VLE); } +#endif tx_buffer->m_head = m_head; tx_buffer_mapped->map = tx_buffer->map; @@ -2544,12 +2400,6 @@ lem_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capabilities = ifp->if_capenable = 0; -#if __FreeBSD_version >= 800000 - /* Multiqueue tx functions */ - ifp->if_transmit = lem_mq_start; - ifp->if_qflush = lem_qflush; - adapter->br = buf_ring_alloc(4096, M_DEVBUF, M_WAITOK, &adapter->tx_mtx); -#endif if (adapter->hw.mac.type >= e1000_82543) { int version_cap; #if __FreeBSD_version < 700000 @@ -4549,10 +4399,6 @@ lem_print_hw_stats(struct adapter *adapter) (long long)adapter->stats.gprc); device_printf(dev, "Good Packets Xmtd = %lld\n", (long long)adapter->stats.gptc); - device_printf(dev, "TSO Contexts Xmtd = %lld\n", - (long long)adapter->stats.tsctc); - device_printf(dev, "TSO Contexts Failed = %lld\n", - (long long)adapter->stats.tsctfc); } /********************************************************************** From a17c1cc009da9c4c4535c5f1114fdd704f0ad9e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Sp=C3=B6rlein?= Date: Wed, 14 Apr 2010 18:29:26 +0000 Subject: [PATCH 041/532] mdoc: remove .Pp where not needed This trips up mdocml and can simply go away. Reviewed by: ru Approved by: philip, ed (mentors) --- lib/libc/gen/confstr.3 | 1 - lib/libc/gen/sysconf.3 | 4 ---- lib/libc/gen/sysctl.3 | 5 ----- lib/libc/locale/isalnum.3 | 1 - lib/libc/locale/isalpha.3 | 1 - 5 files changed, 12 deletions(-) diff --git a/lib/libc/gen/confstr.3 b/lib/libc/gen/confstr.3 index e97505f07de..3066aae363d 100644 --- a/lib/libc/gen/confstr.3 +++ b/lib/libc/gen/confstr.3 @@ -79,7 +79,6 @@ The copied value is always null terminated. The available values are as follows: .Pp .Bl -tag -width 6n -.Pp .It Li _CS_PATH Return a value for the .Ev PATH diff --git a/lib/libc/gen/sysconf.3 b/lib/libc/gen/sysconf.3 index b17d8a80d5e..05766ccef94 100644 --- a/lib/libc/gen/sysconf.3 +++ b/lib/libc/gen/sysconf.3 @@ -60,9 +60,7 @@ Shell programmers who need access to these parameters should use the utility. .Pp The available values are as follows: -.Pp .Bl -tag -width 6n -.Pp .It Li _SC_ARG_MAX The maximum bytes of argument to .Xr execve 2 . @@ -165,9 +163,7 @@ otherwise \-1. .El .Pp These values also exist, but may not be standard: -.Pp .Bl -tag -width 6n -.Pp .It Li _SC_PHYS_PAGES The number of pages of physical memory. Note that it is possible that the product of this value and the value of diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 index 143be16c436..b7ed09139da 100644 --- a/lib/libc/gen/sysctl.3 +++ b/lib/libc/gen/sysctl.3 @@ -286,7 +286,6 @@ privilege may change the value. .It "HW_MACHINE_ARCH string no" .It "HW_REALMEM integer no" .El -.Pp .Bl -tag -width 6n .It Li HW_MACHINE The machine class. @@ -352,7 +351,6 @@ information. .It "KERN_VERSION string no" .It "KERN_VNODE struct vnode no" .El -.Pp .Bl -tag -width 6n .It Li KERN_ARGMAX The maximum bytes of argument to @@ -543,7 +541,6 @@ privilege may change the value. .It "PF_INET IPv4 values yes" .It "PF_INET6 IPv6 values yes" .El -.Pp .Bl -tag -width 6n .It Li PF_ROUTE Return the entire routing table or a subset of it. @@ -650,7 +647,6 @@ privilege may change the value. .It "USER_TZNAME_MAX integer no" .El .Bl -tag -width 6n -.Pp .It Li USER_BC_BASE_MAX The maximum ibase/obase values in the .Xr bc 1 @@ -740,7 +736,6 @@ privilege may change the value. .It "VM_V_INACTIVE_TARGET integer yes" .It "VM_V_PAGEOUT_FREE_MIN integer yes" .El -.Pp .Bl -tag -width 6n .It Li VM_LOADAVG Return the load average history. diff --git a/lib/libc/locale/isalnum.3 b/lib/libc/locale/isalnum.3 index 624a6e2335d..038c5cf413c 100644 --- a/lib/libc/locale/isalnum.3 +++ b/lib/libc/locale/isalnum.3 @@ -59,7 +59,6 @@ or the value of .Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): -.Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&060\ ``0'' \t061\ ``1'' \t062\ ``2'' \t063\ ``3'' \t064\ ``4''" .It "\&065\ ``5'' \t066\ ``6'' \t067\ ``7'' \t070\ ``8'' \t071\ ``9''" diff --git a/lib/libc/locale/isalpha.3 b/lib/libc/locale/isalpha.3 index 0bd3cda3c72..689b6cd54ad 100644 --- a/lib/libc/locale/isalpha.3 +++ b/lib/libc/locale/isalpha.3 @@ -59,7 +59,6 @@ or the value of .Pp In the ASCII character set, this includes the following characters (with their numeric values shown in octal): -.Pp .Bl -column \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ \&000_``0''__ .It "\&101\ ``A'' \t102\ ``B'' \t103\ ``C'' \t104\ ``D'' \t105\ ``E''" .It "\&106\ ``F'' \t107\ ``G'' \t110\ ``H'' \t111\ ``I'' \t112\ ``J''" From e03aa09b619c8844d1092202f0806464f10b98e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Sp=C3=B6rlein?= Date: Wed, 14 Apr 2010 18:29:34 +0000 Subject: [PATCH 042/532] mdoc: don't abuse Bo/Pc to get what looks like an interval Be explicit and use the general bracketing form plus symbols which are to be interpreted mathematically in this case. Complaint by: mdocml Reviewed by: ru Approved by: philip, ed (mentors) --- lib/libc/gen/frexp.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/gen/frexp.3 b/lib/libc/gen/frexp.3 index 390da750d79..ba33d3dfeba 100644 --- a/lib/libc/gen/frexp.3 +++ b/lib/libc/gen/frexp.3 @@ -70,7 +70,7 @@ such that is a .Vt double with magnitude in the interval -.Bo 1/2 , 1 Pc +.Eo [ 1/2 , 1 Ec ) or zero, and .Fa value equals From 20c3b3fa1c5dd984f6b4ef0a7f2b2b81142be023 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Wed, 14 Apr 2010 18:29:40 +0000 Subject: [PATCH 043/532] Make this code a little more portable by wrapping the mtx calls into macros. MFC after: 1 week --- sys/net80211/ieee80211_freebsd.h | 10 +++++++ sys/net80211/ieee80211_scan_sta.c | 46 +++++++++++++++---------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index 861ac5153e3..abfc2c0a26e 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -147,6 +147,16 @@ typedef struct mtx acl_lock_t; #define ACL_LOCK_ASSERT(_as) \ mtx_assert((&(_as)->as_lock), MA_OWNED) +/* + * Scan table definitions. + */ +typedef struct mtx ieee80211_scan_table_lock_t; +#define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \ + mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF) +#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock) +#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock) +#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock) + /* * Node reference counting definitions. * diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c index e697ad4a1a2..a4808e29671 100644 --- a/sys/net80211/ieee80211_scan_sta.c +++ b/sys/net80211/ieee80211_scan_sta.c @@ -97,7 +97,7 @@ struct sta_entry { CTASSERT(MAX_IEEE_CHAN >= 256); struct sta_table { - struct mtx st_lock; /* on scan table */ + ieee80211_scan_table_lock_t st_lock; /* on scan table */ TAILQ_HEAD(, sta_entry) st_entry; /* all entries */ LIST_HEAD(, sta_entry) st_hash[STA_HASHSIZE]; struct mtx st_scanlock; /* on st_scaniter */ @@ -161,7 +161,7 @@ sta_attach(struct ieee80211_scan_state *ss) M_80211_SCAN, M_NOWAIT | M_ZERO); if (st == NULL) return 0; - mtx_init(&st->st_lock, "scantable", "802.11 scan table", MTX_DEF); + IEEE80211_SCAN_TABLE_LOCK_INIT(st, "scantable"); mtx_init(&st->st_scanlock, "scangen", "802.11 scangen", MTX_DEF); TAILQ_INIT(&st->st_entry); ss->ss_priv = st; @@ -179,7 +179,7 @@ sta_detach(struct ieee80211_scan_state *ss) if (st != NULL) { sta_flush_table(st); - mtx_destroy(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK_DESTROY(st); mtx_destroy(&st->st_scanlock); free(st, M_80211_SCAN); KASSERT(nrefs > 0, ("imbalanced attach/detach")); @@ -196,9 +196,9 @@ sta_flush(struct ieee80211_scan_state *ss) { struct sta_table *st = ss->ss_priv; - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); sta_flush_table(st); - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); ss->ss_last = 0; return 0; } @@ -244,14 +244,14 @@ sta_add(struct ieee80211_scan_state *ss, hash = STA_HASH(macaddr); - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); LIST_FOREACH(se, &st->st_hash[hash], se_hash) if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr)) goto found; se = (struct sta_entry *) malloc(sizeof(struct sta_entry), M_80211_SCAN, M_NOWAIT | M_ZERO); if (se == NULL) { - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); return 0; } se->se_scangen = st->st_scaniter-1; @@ -370,7 +370,7 @@ found: if (rssi > st->st_maxrssi[sp->bchan]) st->st_maxrssi[sp->bchan] = rssi; - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); /* * If looking for a quick choice and nothing's @@ -1132,7 +1132,7 @@ sta_update_notseen(struct sta_table *st) { struct sta_entry *se; - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); TAILQ_FOREACH(se, &st->st_entry, se_list) { /* * If seen the reset and don't bump the count; @@ -1146,7 +1146,7 @@ sta_update_notseen(struct sta_table *st) else se->se_notseen++; } - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); } static void @@ -1154,11 +1154,11 @@ sta_dec_fails(struct sta_table *st) { struct sta_entry *se; - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); TAILQ_FOREACH(se, &st->st_entry, se_list) if (se->se_fails) se->se_fails--; - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); } static struct sta_entry * @@ -1169,7 +1169,7 @@ select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug) IEEE80211_DPRINTF(vap, debug, " %s\n", "macaddr bssid chan rssi rate flag wep essid"); - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); TAILQ_FOREACH(se, &st->st_entry, se_list) { ieee80211_ies_expand(&se->base.se_ies); if (match_bss(vap, ss, se, debug) == 0) { @@ -1179,7 +1179,7 @@ select_bss(struct ieee80211_scan_state *ss, struct ieee80211vap *vap, int debug) selbs = se; } } - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); return selbs; } @@ -1258,11 +1258,11 @@ sta_lookup(struct sta_table *st, const uint8_t macaddr[IEEE80211_ADDR_LEN]) struct sta_entry *se; int hash = STA_HASH(macaddr); - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); LIST_FOREACH(se, &st->st_hash[hash], se_hash) if (IEEE80211_ADDR_EQ(se->base.se_macaddr, macaddr)) break; - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); return se; /* NB: unlocked */ } @@ -1382,18 +1382,18 @@ sta_iterate(struct ieee80211_scan_state *ss, mtx_lock(&st->st_scanlock); gen = st->st_scaniter++; restart: - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); TAILQ_FOREACH(se, &st->st_entry, se_list) { if (se->se_scangen != gen) { se->se_scangen = gen; /* update public state */ se->base.se_age = ticks - se->se_lastupdate; - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); (*f)(arg, &se->base); goto restart; } } - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); mtx_unlock(&st->st_scanlock); } @@ -1510,7 +1510,7 @@ adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags) bestchan = NULL; bestrssi = -1; - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); for (i = 0; i < ss->ss_last; i++) { c = ss->ss_chans[i]; /* never consider a channel with radar */ @@ -1532,7 +1532,7 @@ adhoc_pick_channel(struct ieee80211_scan_state *ss, int flags) if (bestchan == NULL || maxrssi < bestrssi) bestchan = c; } - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); return bestchan; } @@ -1638,7 +1638,7 @@ adhoc_age(struct ieee80211_scan_state *ss) struct sta_table *st = ss->ss_priv; struct sta_entry *se, *next; - mtx_lock(&st->st_lock); + IEEE80211_SCAN_TABLE_LOCK(st); TAILQ_FOREACH_SAFE(se, &st->st_entry, se_list, next) { if (se->se_notseen > STA_PURGE_SCANS) { TAILQ_REMOVE(&st->st_entry, se, se_list); @@ -1647,7 +1647,7 @@ adhoc_age(struct ieee80211_scan_state *ss) free(se, M_80211_SCAN); } } - mtx_unlock(&st->st_lock); + IEEE80211_SCAN_TABLE_UNLOCK(st); } static const struct ieee80211_scanner adhoc_default = { From f672e5fbe21dcf03aff493143e31d92fe6eb340d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 14 Apr 2010 18:56:07 +0000 Subject: [PATCH 044/532] Add note about TARGET_ARCH --- Makefile.inc1 | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.inc1 b/Makefile.inc1 index a772e2861e3..1c5d892468b 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -15,6 +15,7 @@ # -DNO_CTF do not run the DTrace CTF conversion tools on built objects # LOCAL_DIRS="list of dirs" to add additional dirs to the SUBDIR list # TARGET="machine" to crossbuild world for a different machine type +# TARGET_ARCH= may be required when a TARGET supports multiple endians # # The intended user-driven targets are: From 8a07366ec284069c85972597ab0d305fad3e0d47 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 14 Apr 2010 19:03:27 +0000 Subject: [PATCH 045/532] Add armeb-*-freebsd* to the list of known architectures. This is like arm-*-freebsd*, except it defaults to big endian builds instead of little endian builds. --- contrib/binutils/bfd/config.bfd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/binutils/bfd/config.bfd b/contrib/binutils/bfd/config.bfd index 034da18ef8b..5f115f0db2c 100755 --- a/contrib/binutils/bfd/config.bfd +++ b/contrib/binutils/bfd/config.bfd @@ -221,6 +221,10 @@ case "${targ}" in targ_defvec=bfd_elf32_littlearm_vec targ_selvecs=bfd_elf32_bigarm_vec ;; + armeb-*-freebsd*) + targ_defvec=bfd_elf32_bigarm_vec + targ_selvecs=bfd_elf32_littlearm_vec + ;; arm-*-elf | arm-*-freebsd* | arm*-*-linux-gnu* | arm*-*-conix* | \ arm*-*-uclinux* | arm-*-kfreebsd*-gnu | arm-*-vxworks) targ_defvec=bfd_elf32_littlearm_vec From c5ff2cdb99c0a70595a3d13be9c5d88741b5d3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Sp=C3=B6rlein?= Date: Wed, 14 Apr 2010 19:06:39 +0000 Subject: [PATCH 046/532] Add and expand $FreeBSD$ keyword to allow committing to this file. --- usr.bin/csup/cpasswd.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/csup/cpasswd.1 b/usr.bin/csup/cpasswd.1 index 946783f4c25..973dc808f28 100644 --- a/usr.bin/csup/cpasswd.1 +++ b/usr.bin/csup/cpasswd.1 @@ -27,7 +27,7 @@ .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $Id: cvpasswd.1,v 1.4 2003/03/04 18:24:42 jdp Exp $ -.\" $FreeBSD $ +.\" $FreeBSD$ .\" .Dd June 27, 2007 .Os FreeBSD From aa12cea2ccc6e686d6d31cf67d6bc69cbc1ba744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulrich=20Sp=C3=B6rlein?= Date: Wed, 14 Apr 2010 19:08:06 +0000 Subject: [PATCH 047/532] mdoc: order prologue macros consistently by Dd/Dt/Os Although groff_mdoc(7) gives another impression, this is the ordering most widely used and also required by mdocml/mandoc. Reviewed by: ru Approved by: philip, ed (mentors) --- bin/pwait/pwait.1 | 2 +- contrib/com_err/compile_et.1 | 2 +- gnu/usr.bin/gdb/kgdb/kgdb.1 | 2 +- lib/libc/gen/check_utility_compat.3 | 2 +- lib/libc/gen/dladdr.3 | 2 +- lib/libc/gen/dlinfo.3 | 2 +- lib/libc/gen/dllockinit.3 | 2 +- lib/libc/gen/dlopen.3 | 2 +- lib/libc/gen/fmtcheck.3 | 2 +- lib/libc/gen/ftok.3 | 2 +- lib/libc/gen/getutxent.3 | 2 +- lib/libc/gen/setproctitle.3 | 2 +- lib/libc/gen/stringlist.3 | 2 +- lib/libc/posix1e/mac_prepare.3 | 2 +- lib/libc/stdlib/hcreate.3 | 2 +- lib/libc/stdlib/ptsname.3 | 2 +- lib/libcam/cam.3 | 2 +- lib/libcam/cam_cdbparse.3 | 2 +- lib/libcompat/4.1/cftime.3 | 2 +- lib/libcompat/4.4/cuserid.3 | 2 +- lib/libedit/editline.3 | 2 +- lib/libedit/editrc.5 | 2 +- lib/libelf/elf.3 | 2 +- lib/libelf/elf_begin.3 | 2 +- lib/libelf/elf_cntl.3 | 2 +- lib/libelf/elf_end.3 | 2 +- lib/libelf/elf_errmsg.3 | 2 +- lib/libelf/elf_fill.3 | 2 +- lib/libelf/elf_flagdata.3 | 2 +- lib/libelf/elf_getarhdr.3 | 2 +- lib/libelf/elf_getarsym.3 | 2 +- lib/libelf/elf_getbase.3 | 2 +- lib/libelf/elf_getdata.3 | 2 +- lib/libelf/elf_getident.3 | 2 +- lib/libelf/elf_getphnum.3 | 2 +- lib/libelf/elf_getscn.3 | 2 +- lib/libelf/elf_getshnum.3 | 2 +- lib/libelf/elf_getshstrndx.3 | 2 +- lib/libelf/elf_hash.3 | 2 +- lib/libelf/elf_kind.3 | 2 +- lib/libelf/elf_memory.3 | 2 +- lib/libelf/elf_next.3 | 2 +- lib/libelf/elf_rand.3 | 2 +- lib/libelf/elf_rawfile.3 | 2 +- lib/libelf/elf_strptr.3 | 2 +- lib/libelf/elf_update.3 | 2 +- lib/libelf/elf_version.3 | 2 +- lib/libelf/gelf.3 | 2 +- lib/libelf/gelf_checksum.3 | 2 +- lib/libelf/gelf_fsize.3 | 2 +- lib/libelf/gelf_getcap.3 | 2 +- lib/libelf/gelf_getclass.3 | 2 +- lib/libelf/gelf_getdyn.3 | 2 +- lib/libelf/gelf_getehdr.3 | 2 +- lib/libelf/gelf_getmove.3 | 2 +- lib/libelf/gelf_getphdr.3 | 2 +- lib/libelf/gelf_getrel.3 | 2 +- lib/libelf/gelf_getrela.3 | 2 +- lib/libelf/gelf_getshdr.3 | 2 +- lib/libelf/gelf_getsym.3 | 2 +- lib/libelf/gelf_getsyminfo.3 | 2 +- lib/libelf/gelf_getsymshndx.3 | 2 +- lib/libelf/gelf_newehdr.3 | 2 +- lib/libelf/gelf_newphdr.3 | 2 +- lib/libelf/gelf_update_ehdr.3 | 2 +- lib/libelf/gelf_xlatetof.3 | 2 +- lib/libgssapi/gss_accept_sec_context.3 | 2 +- lib/libgssapi/gss_acquire_cred.3 | 2 +- lib/libgssapi/gss_add_cred.3 | 2 +- lib/libgssapi/gss_add_oid_set_member.3 | 2 +- lib/libgssapi/gss_canonicalize_name.3 | 2 +- lib/libgssapi/gss_compare_name.3 | 2 +- lib/libgssapi/gss_context_time.3 | 2 +- lib/libgssapi/gss_create_empty_oid_set.3 | 2 +- lib/libgssapi/gss_delete_sec_context.3 | 2 +- lib/libgssapi/gss_display_name.3 | 2 +- lib/libgssapi/gss_display_status.3 | 2 +- lib/libgssapi/gss_duplicate_name.3 | 2 +- lib/libgssapi/gss_export_name.3 | 2 +- lib/libgssapi/gss_export_sec_context.3 | 2 +- lib/libgssapi/gss_get_mic.3 | 2 +- lib/libgssapi/gss_import_name.3 | 2 +- lib/libgssapi/gss_import_sec_context.3 | 2 +- lib/libgssapi/gss_indicate_mechs.3 | 2 +- lib/libgssapi/gss_init_sec_context.3 | 2 +- lib/libgssapi/gss_inquire_context.3 | 2 +- lib/libgssapi/gss_inquire_cred.3 | 2 +- lib/libgssapi/gss_inquire_cred_by_mech.3 | 2 +- lib/libgssapi/gss_inquire_mechs_for_name.3 | 2 +- lib/libgssapi/gss_inquire_names_for_mech.3 | 2 +- lib/libgssapi/gss_process_context_token.3 | 2 +- lib/libgssapi/gss_release_buffer.3 | 2 +- lib/libgssapi/gss_release_cred.3 | 2 +- lib/libgssapi/gss_release_name.3 | 2 +- lib/libgssapi/gss_release_oid_set.3 | 2 +- lib/libgssapi/gss_test_oid_set_member.3 | 2 +- lib/libgssapi/gss_unwrap.3 | 2 +- lib/libgssapi/gss_verify_mic.3 | 2 +- lib/libgssapi/gss_wrap.3 | 2 +- lib/libgssapi/gss_wrap_size_limit.3 | 2 +- lib/libmemstat/libmemstat.3 | 2 +- lib/libpmc/pmc.3 | 2 +- lib/libpmc/pmc.atom.3 | 2 +- lib/libpmc/pmc.core.3 | 2 +- lib/libpmc/pmc.core2.3 | 2 +- lib/libpmc/pmc.corei7.3 | 2 +- lib/libpmc/pmc.corei7uc.3 | 2 +- lib/libpmc/pmc.iaf.3 | 2 +- lib/libpmc/pmc.k7.3 | 2 +- lib/libpmc/pmc.k8.3 | 2 +- lib/libpmc/pmc.p4.3 | 2 +- lib/libpmc/pmc.p5.3 | 2 +- lib/libpmc/pmc.p6.3 | 2 +- lib/libpmc/pmc.tsc.3 | 2 +- lib/libpmc/pmc.ucf.3 | 2 +- lib/libpmc/pmc.westmere.3 | 2 +- lib/libpmc/pmc.westmereuc.3 | 2 +- lib/libpmc/pmc_allocate.3 | 2 +- lib/libpmc/pmc_attach.3 | 2 +- lib/libpmc/pmc_capabilities.3 | 2 +- lib/libpmc/pmc_configure_logfile.3 | 2 +- lib/libpmc/pmc_disable.3 | 2 +- lib/libpmc/pmc_event_names_of_class.3 | 2 +- lib/libpmc/pmc_get_driver_stats.3 | 2 +- lib/libpmc/pmc_get_msr.3 | 2 +- lib/libpmc/pmc_init.3 | 2 +- lib/libpmc/pmc_name_of_capability.3 | 2 +- lib/libpmc/pmc_read.3 | 2 +- lib/libpmc/pmc_set.3 | 2 +- lib/libpmc/pmc_start.3 | 2 +- lib/libpmc/pmclog.3 | 2 +- lib/libthr/libthr.3 | 2 +- lib/libugidfw/bsde_get_rule.3 | 2 +- lib/libugidfw/bsde_get_rule_count.3 | 2 +- lib/libugidfw/bsde_parse_rule.3 | 2 +- lib/libugidfw/bsde_rule_to_string.3 | 2 +- lib/libugidfw/libugidfw.3 | 2 +- lib/libulog/ulog_login.3 | 2 +- lib/libulog/utempter_add_record.3 | 2 +- lib/libutil/_secure_path.3 | 2 +- lib/libutil/auth.3 | 2 +- lib/libutil/hexdump.3 | 2 +- lib/libutil/kinfo_getfile.3 | 2 +- lib/libutil/kinfo_getvmmap.3 | 2 +- lib/libutil/kld.3 | 2 +- lib/libutil/login_auth.3 | 2 +- lib/libutil/login_cap.3 | 2 +- lib/libutil/login_class.3 | 2 +- lib/libutil/login_ok.3 | 2 +- lib/libutil/login_times.3 | 2 +- lib/libutil/login_tty.3 | 2 +- lib/libutil/property.3 | 2 +- lib/libutil/pty.3 | 2 +- lib/libutil/realhostname.3 | 2 +- lib/libutil/realhostname_sa.3 | 2 +- lib/libutil/trimdomain.3 | 2 +- lib/libutil/uucplock.3 | 2 +- sbin/iscontrol/iscsi.conf.5 | 2 +- sbin/spppcontrol/spppcontrol.8 | 2 +- share/man/man3/sysexits.3 | 2 +- share/man/man3/tgmath.3 | 2 +- share/man/man4/audit.4 | 2 +- share/man/man4/auditpipe.4 | 2 +- share/man/man4/coda.4 | 2 +- share/man/man4/gbde.4 | 2 +- share/man/man4/geom.4 | 2 +- share/man/man4/geom_fox.4 | 2 +- share/man/man4/geom_linux_lvm.4 | 2 +- share/man/man4/geom_uzip.4 | 2 +- share/man/man4/ipw.4 | 2 +- share/man/man4/iscsi_initiator.4 | 2 +- share/man/man4/iwi.4 | 2 +- share/man/man4/iwn.4 | 2 +- share/man/man4/kbdmux.4 | 2 +- share/man/man4/lp.4 | 2 +- share/man/man4/mac.4 | 2 +- share/man/man4/mac_biba.4 | 2 +- share/man/man4/mac_bsdextended.4 | 2 +- share/man/man4/mac_ifoff.4 | 2 +- share/man/man4/mac_lomac.4 | 2 +- share/man/man4/mac_mls.4 | 2 +- share/man/man4/mac_none.4 | 2 +- share/man/man4/mac_partition.4 | 2 +- share/man/man4/mac_seeotheruids.4 | 2 +- share/man/man4/mac_stub.4 | 2 +- share/man/man4/mac_test.4 | 2 +- share/man/man4/ng_netflow.4 | 2 +- share/man/man4/orm.4 | 2 +- share/man/man4/ral.4 | 2 +- share/man/man4/rp.4 | 2 +- share/man/man4/rum.4 | 2 +- share/man/man4/run.4 | 2 +- share/man/man4/sched_4bsd.4 | 2 +- share/man/man4/sched_ule.4 | 2 +- share/man/man4/si.4 | 2 +- share/man/man4/tap.4 | 2 +- share/man/man4/uhso.4 | 2 +- share/man/man4/upgt.4 | 2 +- share/man/man4/ural.4 | 2 +- share/man/man4/vkbd.4 | 2 +- share/man/man4/wpi.4 | 2 +- share/man/man5/ar.5 | 2 +- share/man/man7/clocks.7 | 2 +- share/man/man7/maclabel.7 | 2 +- share/man/man8/picobsd.8 | 2 +- share/man/man8/rescue.8 | 2 +- share/man/man9/CTASSERT.9 | 2 +- share/man/man9/DELAY.9 | 2 +- share/man/man9/KASSERT.9 | 2 +- share/man/man9/VFS.9 | 2 +- share/man/man9/VFS_CHECKEXP.9 | 2 +- share/man/man9/VFS_FHTOVP.9 | 2 +- share/man/man9/VFS_MOUNT.9 | 2 +- share/man/man9/VFS_QUOTACTL.9 | 2 +- share/man/man9/VFS_ROOT.9 | 2 +- share/man/man9/VFS_STATFS.9 | 2 +- share/man/man9/VFS_SYNC.9 | 2 +- share/man/man9/VFS_UNMOUNT.9 | 2 +- share/man/man9/VFS_VGET.9 | 2 +- share/man/man9/VOP_ACCESS.9 | 2 +- share/man/man9/VOP_ACLCHECK.9 | 2 +- share/man/man9/VOP_ADVLOCK.9 | 2 +- share/man/man9/VOP_ATTRIB.9 | 2 +- share/man/man9/VOP_BWRITE.9 | 2 +- share/man/man9/VOP_CREATE.9 | 2 +- share/man/man9/VOP_FSYNC.9 | 2 +- share/man/man9/VOP_GETACL.9 | 2 +- share/man/man9/VOP_GETEXTATTR.9 | 2 +- share/man/man9/VOP_GETPAGES.9 | 2 +- share/man/man9/VOP_GETVOBJECT.9 | 2 +- share/man/man9/VOP_INACTIVE.9 | 2 +- share/man/man9/VOP_IOCTL.9 | 2 +- share/man/man9/VOP_LINK.9 | 2 +- share/man/man9/VOP_LISTEXTATTR.9 | 2 +- share/man/man9/VOP_LOCK.9 | 2 +- share/man/man9/VOP_LOOKUP.9 | 2 +- share/man/man9/VOP_OPENCLOSE.9 | 2 +- share/man/man9/VOP_PATHCONF.9 | 2 +- share/man/man9/VOP_PRINT.9 | 2 +- share/man/man9/VOP_RDWR.9 | 2 +- share/man/man9/VOP_READDIR.9 | 2 +- share/man/man9/VOP_READLINK.9 | 2 +- share/man/man9/VOP_REALLOCBLKS.9 | 2 +- share/man/man9/VOP_REMOVE.9 | 2 +- share/man/man9/VOP_RENAME.9 | 2 +- share/man/man9/VOP_REVOKE.9 | 2 +- share/man/man9/VOP_SETACL.9 | 2 +- share/man/man9/VOP_SETEXTATTR.9 | 2 +- share/man/man9/VOP_STRATEGY.9 | 2 +- share/man/man9/VOP_VPTOCNP.9 | 2 +- share/man/man9/VOP_VPTOFH.9 | 2 +- share/man/man9/accept_filter.9 | 2 +- share/man/man9/accf_data.9 | 2 +- share/man/man9/accf_dns.9 | 2 +- share/man/man9/accf_http.9 | 2 +- share/man/man9/acl.9 | 2 +- share/man/man9/atomic.9 | 2 +- share/man/man9/cr_cansee.9 | 2 +- share/man/man9/cr_seeothergids.9 | 2 +- share/man/man9/cr_seeotheruids.9 | 2 +- share/man/man9/devfs_set_cdevpriv.9 | 2 +- share/man/man9/devtoname.9 | 2 +- share/man/man9/extattr.9 | 2 +- share/man/man9/firmware.9 | 2 +- share/man/man9/hexdump.9 | 2 +- share/man/man9/ifnet.9 | 2 +- share/man/man9/make_dev.9 | 2 +- share/man/man9/namei.9 | 2 +- share/man/man9/p_candebug.9 | 2 +- share/man/man9/p_cansee.9 | 2 +- share/man/man9/pfind.9 | 2 +- share/man/man9/pgfind.9 | 2 +- share/man/man9/prison_check.9 | 2 +- share/man/man9/random.9 | 2 +- share/man/man9/rijndael.9 | 2 +- share/man/man9/rtalloc.9 | 2 +- share/man/man9/rtentry.9 | 2 +- share/man/man9/sleep.9 | 2 +- share/man/man9/spl.9 | 2 +- share/man/man9/uio.9 | 2 +- share/man/man9/usbdi.9 | 2 +- share/man/man9/vaccess.9 | 2 +- share/man/man9/vaccess_acl_nfs4.9 | 2 +- share/man/man9/vaccess_acl_posix1e.9 | 2 +- share/man/man9/vcount.9 | 2 +- share/man/man9/vget.9 | 2 +- share/man/man9/vm_map_entry_resize_free.9 | 2 +- share/man/man9/vnode.9 | 2 +- share/man/man9/vput.9 | 2 +- share/man/man9/vref.9 | 2 +- share/man/man9/vrefcnt.9 | 2 +- share/man/man9/vrele.9 | 2 +- usr.bin/ar/ar.1 | 2 +- usr.bin/c89/c89.1 | 2 +- usr.bin/c99/c99.1 | 2 +- usr.bin/column/column.1 | 2 +- usr.bin/comm/comm.1 | 2 +- usr.bin/csup/cpasswd.1 | 2 +- usr.bin/csup/csup.1 | 2 +- usr.bin/enigma/enigma.1 | 2 +- usr.bin/hexdump/od.1 | 2 +- usr.bin/killall/killall.1 | 2 +- usr.bin/lockf/lockf.1 | 2 +- usr.bin/wtmpcvt/wtmpcvt.1 | 2 +- usr.sbin/asf/asf.8 | 2 +- usr.sbin/burncd/burncd.8 | 2 +- usr.sbin/ctm/ctm/ctm.1 | 2 +- usr.sbin/ctm/ctm/ctm.5 | 2 +- usr.sbin/devinfo/devinfo.8 | 2 +- usr.sbin/fdformat/fdformat.1 | 2 +- usr.sbin/fdread/fdread.1 | 2 +- usr.sbin/fdwrite/fdwrite.1 | 2 +- usr.sbin/fifolog/fifolog_create/fifolog.1 | 2 +- usr.sbin/flowctl/flowctl.8 | 2 +- usr.sbin/mtest/mtest.8 | 2 +- usr.sbin/periodic/periodic.8 | 2 +- usr.sbin/pmcannotate/pmcannotate.8 | 2 +- usr.sbin/pmccontrol/pmccontrol.8 | 2 +- usr.sbin/pmcstat/pmcstat.8 | 2 +- usr.sbin/pppctl/pppctl.8 | 2 +- usr.sbin/setfmac/setfsmac.8 | 2 +- usr.sbin/setpmac/setpmac.8 | 2 +- usr.sbin/uhsoctl/uhsoctl.1 | 2 +- 323 files changed, 323 insertions(+), 323 deletions(-) diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1 index 132d83c98ce..f36090d1ebf 100644 --- a/bin/pwait/pwait.1 +++ b/bin/pwait/pwait.1 @@ -33,8 +33,8 @@ .\" $FreeBSD$ .\" .Dd November 1, 2009 -.Os .Dt PWAIT 1 +.Os .Sh NAME .Nm pwait .Nd wait for processes to terminate diff --git a/contrib/com_err/compile_et.1 b/contrib/com_err/compile_et.1 index bdc608ba6dd..32f2eeece20 100644 --- a/contrib/com_err/compile_et.1 +++ b/contrib/com_err/compile_et.1 @@ -4,8 +4,8 @@ .\" $FreeBSD$ .\" .Dd November 22, 1988 -.Os .Dt COMPILE_ET 1 +.Os .Sh NAME .Nm compile_et .Nd error table compiler diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.1 b/gnu/usr.bin/gdb/kgdb/kgdb.1 index 5b6fea0bace..4073d705f8b 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.1 +++ b/gnu/usr.bin/gdb/kgdb/kgdb.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd October 11, 2006 -.Os .Dt KGDB 1 +.Os .Sh NAME .Nm kgdb .Nd "kernel debugger" diff --git a/lib/libc/gen/check_utility_compat.3 b/lib/libc/gen/check_utility_compat.3 index 7a96bac15c5..57638e50ead 100644 --- a/lib/libc/gen/check_utility_compat.3 +++ b/lib/libc/gen/check_utility_compat.3 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd October 27, 2002 -.Os .Dt CHECK_UTILITY_COMPAT 3 +.Os .Sh NAME .Nm check_utility_compat .Nd "determine whether a utility should be compatible" diff --git a/lib/libc/gen/dladdr.3 b/lib/libc/gen/dladdr.3 index 414fa49a3e9..65662793b59 100644 --- a/lib/libc/gen/dladdr.3 +++ b/lib/libc/gen/dladdr.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd February 5, 1998 -.Os .Dt DLADDR 3 +.Os .Sh NAME .Nm dladdr .Nd find the shared object containing a given address diff --git a/lib/libc/gen/dlinfo.3 b/lib/libc/gen/dlinfo.3 index 9433fb6e9d1..d00f07467af 100644 --- a/lib/libc/gen/dlinfo.3 +++ b/lib/libc/gen/dlinfo.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd February 14, 2003 -.Os .Dt DLINFO 3 +.Os .Sh NAME .Nm dlinfo .Nd information about dynamically loaded object diff --git a/lib/libc/gen/dllockinit.3 b/lib/libc/gen/dllockinit.3 index 98d10749485..be3e2cab87f 100644 --- a/lib/libc/gen/dllockinit.3 +++ b/lib/libc/gen/dllockinit.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd July 5, 2000 -.Os .Dt DLLOCKINIT 3 +.Os .Sh NAME .Nm dllockinit .Nd register thread locking methods with the dynamic linker diff --git a/lib/libc/gen/dlopen.3 b/lib/libc/gen/dlopen.3 index d4b111a1002..45b01397468 100644 --- a/lib/libc/gen/dlopen.3 +++ b/lib/libc/gen/dlopen.3 @@ -33,8 +33,8 @@ .\" $FreeBSD$ .\" .Dd July 7, 2009 -.Os .Dt DLOPEN 3 +.Os .Sh NAME .Nm dlopen , .Nm dlsym , diff --git a/lib/libc/gen/fmtcheck.3 b/lib/libc/gen/fmtcheck.3 index ecd70fb8b30..2fa587b6bd9 100644 --- a/lib/libc/gen/fmtcheck.3 +++ b/lib/libc/gen/fmtcheck.3 @@ -26,8 +26,8 @@ .\" .\" $FreeBSD$ .Dd October 16, 2002 -.Os .Dt FMTCHECK 3 +.Os .Sh NAME .Nm fmtcheck .Nd sanitizes user-supplied diff --git a/lib/libc/gen/ftok.3 b/lib/libc/gen/ftok.3 index 78bfe457c3d..996b2da41c7 100644 --- a/lib/libc/gen/ftok.3 +++ b/lib/libc/gen/ftok.3 @@ -25,8 +25,8 @@ .\" .\" $FreeBSD$ .Dd July 9, 2009 -.Os .Dt FTOK 3 +.Os .Sh NAME .Nm ftok .Nd create IPC identifier from path name diff --git a/lib/libc/gen/getutxent.3 b/lib/libc/gen/getutxent.3 index 5ab21eede74..ccc5d9ed5c3 100644 --- a/lib/libc/gen/getutxent.3 +++ b/lib/libc/gen/getutxent.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd January 8, 2010 -.Os .Dt GETUTXENT 3 +.Os .Sh NAME .Nm endutxent , .Nm getutxent , diff --git a/lib/libc/gen/setproctitle.3 b/lib/libc/gen/setproctitle.3 index fe9f19acde6..73dc8c00cc7 100644 --- a/lib/libc/gen/setproctitle.3 +++ b/lib/libc/gen/setproctitle.3 @@ -21,8 +21,8 @@ .\" .\" The following requests are required for all man pages. .Dd December 16, 1995 -.Os .Dt SETPROCTITLE 3 +.Os .Sh NAME .Nm setproctitle .Nd set process title diff --git a/lib/libc/gen/stringlist.3 b/lib/libc/gen/stringlist.3 index 44d2a36ffa4..c55b77d7802 100644 --- a/lib/libc/gen/stringlist.3 +++ b/lib/libc/gen/stringlist.3 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd November 28, 1999 -.Os .Dt STRINGLIST 3 +.Os .Sh NAME .Nm stringlist , .Nm sl_init , diff --git a/lib/libc/posix1e/mac_prepare.3 b/lib/libc/posix1e/mac_prepare.3 index 1d8522908f9..8e694de133b 100644 --- a/lib/libc/posix1e/mac_prepare.3 +++ b/lib/libc/posix1e/mac_prepare.3 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd August 22, 2003 -.Os .Dt MAC_PREPARE 3 +.Os .Sh NAME .Nm mac_prepare , mac_prepare_type , mac_prepare_file_label , .Nm mac_prepare_ifnet_label , mac_prepare_process_label diff --git a/lib/libc/stdlib/hcreate.3 b/lib/libc/stdlib/hcreate.3 index cd827207694..2466c9f428a 100644 --- a/lib/libc/stdlib/hcreate.3 +++ b/lib/libc/stdlib/hcreate.3 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 6, 2008 -.Os .Dt HCREATE 3 +.Os .Sh NAME .Nm hcreate , hdestroy , hsearch .Nd manage hash search table diff --git a/lib/libc/stdlib/ptsname.3 b/lib/libc/stdlib/ptsname.3 index f674a54bd90..48da3bd81c2 100644 --- a/lib/libc/stdlib/ptsname.3 +++ b/lib/libc/stdlib/ptsname.3 @@ -32,8 +32,8 @@ .\" $FreeBSD$ .\" .Dd August 20, 2008 -.Os .Dt PTSNAME 3 +.Os .Sh NAME .Nm grantpt , .Nm ptsname , diff --git a/lib/libcam/cam.3 b/lib/libcam/cam.3 index 539709f265a..3a857b2fd79 100644 --- a/lib/libcam/cam.3 +++ b/lib/libcam/cam.3 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd October 10, 1998 -.Os .Dt CAM 3 +.Os .Sh NAME .Nm cam_open_device , .Nm cam_open_spec_device , diff --git a/lib/libcam/cam_cdbparse.3 b/lib/libcam/cam_cdbparse.3 index 891652dca92..35a595151f3 100644 --- a/lib/libcam/cam_cdbparse.3 +++ b/lib/libcam/cam_cdbparse.3 @@ -62,8 +62,8 @@ .\" .\" .Dd October 13, 1998 -.Os .Dt CAM_CDBPARSE 3 +.Os .Sh NAME .Nm csio_build , .Nm csio_build_visit , diff --git a/lib/libcompat/4.1/cftime.3 b/lib/libcompat/4.1/cftime.3 index 116f5de5dfa..dd21e781ed7 100644 --- a/lib/libcompat/4.1/cftime.3 +++ b/lib/libcompat/4.1/cftime.3 @@ -35,8 +35,8 @@ .\" $FreeBSD$ .\" .Dd June 15, 1993 -.Os .Dt CFTIME 3 +.Os .Sh NAME .Nm cftime , .Nm ascftime diff --git a/lib/libcompat/4.4/cuserid.3 b/lib/libcompat/4.4/cuserid.3 index 72811d5196d..addd61608ff 100644 --- a/lib/libcompat/4.4/cuserid.3 +++ b/lib/libcompat/4.4/cuserid.3 @@ -32,8 +32,8 @@ .\" $FreeBSD$ .\" .Dd April 10, 1995 -.Os .Dt CUSERID 3 +.Os .Sh NAME .Nm cuserid .Nd get user name associated with effective UID diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3 index d5dfff5e7a4..9794649a56e 100644 --- a/lib/libedit/editline.3 +++ b/lib/libedit/editline.3 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd January 12, 2007 -.Os .Dt EDITLINE 3 +.Os .Sh NAME .Nm editline , .Nm el_init , diff --git a/lib/libedit/editrc.5 b/lib/libedit/editrc.5 index 4b1d4148b8d..2fa1a634dea 100644 --- a/lib/libedit/editrc.5 +++ b/lib/libedit/editrc.5 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd October 18, 2003 -.Os .Dt EDITRC 5 +.Os .Sh NAME .Nm editrc .Nd configuration file for editline library diff --git a/lib/libelf/elf.3 b/lib/libelf/elf.3 index 854e1af1a2f..c649efe72be 100644 --- a/lib/libelf/elf.3 +++ b/lib/libelf/elf.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 21, 2007 -.Os .Dt ELF 3 +.Os .Sh NAME .Nm elf .Nd API for manipulating ELF objects diff --git a/lib/libelf/elf_begin.3 b/lib/libelf/elf_begin.3 index c43766f7bcb..dac49102eaf 100644 --- a/lib/libelf/elf_begin.3 +++ b/lib/libelf/elf_begin.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 21, 2006 -.Os .Dt ELF_BEGIN 3 +.Os .Sh NAME .Nm elf_begin .Nd open an ELF file or ar(1) archive diff --git a/lib/libelf/elf_cntl.3 b/lib/libelf/elf_cntl.3 index 73dca213944..52771701181 100644 --- a/lib/libelf/elf_cntl.3 +++ b/lib/libelf/elf_cntl.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 9, 2006 -.Os .Dt ELF_CNTL 3 +.Os .Sh NAME .Nm elf_cntl .Nd control an elf file descriptor diff --git a/lib/libelf/elf_end.3 b/lib/libelf/elf_end.3 index 0f74a898472..3622fb2e670 100644 --- a/lib/libelf/elf_end.3 +++ b/lib/libelf/elf_end.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 29, 2006 -.Os .Dt ELF_END 3 +.Os .Sh NAME .Nm elf_end .Nd release an ELF descriptor diff --git a/lib/libelf/elf_errmsg.3 b/lib/libelf/elf_errmsg.3 index 1ed70bf9ee6..f01416804b5 100644 --- a/lib/libelf/elf_errmsg.3 +++ b/lib/libelf/elf_errmsg.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 11, 2006 -.Os .Dt ELF_ERRMSG 3 +.Os .Sh NAME .Nm elf_errmsg , .Nm elf_errno diff --git a/lib/libelf/elf_fill.3 b/lib/libelf/elf_fill.3 index 33446b99c48..a635b435a6e 100644 --- a/lib/libelf/elf_fill.3 +++ b/lib/libelf/elf_fill.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 11, 2006 -.Os .Dt ELF_FILL 3 +.Os .Sh NAME .Nm elf_fill .Nd set fill byte for inter-section padding diff --git a/lib/libelf/elf_flagdata.3 b/lib/libelf/elf_flagdata.3 index 30c1111904b..b07e5242681 100644 --- a/lib/libelf/elf_flagdata.3 +++ b/lib/libelf/elf_flagdata.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 22, 2007 -.Os .Dt ELF_FLAGDATA 3 +.Os .Sh NAME .Nm elf_flagdata , .Nm elf_flagehdr , diff --git a/lib/libelf/elf_getarhdr.3 b/lib/libelf/elf_getarhdr.3 index f78fc80bc33..03f911adf3a 100644 --- a/lib/libelf/elf_getarhdr.3 +++ b/lib/libelf/elf_getarhdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 15, 2006 -.Os .Dt ELF_GETARHDR 3 +.Os .Sh NAME .Nm elf_getarhdr .Nd retrieve ar(1) header for an archive member diff --git a/lib/libelf/elf_getarsym.3 b/lib/libelf/elf_getarsym.3 index 1030ea2b6f5..44b28c8c957 100644 --- a/lib/libelf/elf_getarsym.3 +++ b/lib/libelf/elf_getarsym.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 15, 2006 -.Os .Dt ELF_GETARSYM 3 +.Os .Sh NAME .Nm elf_getarsym .Nd retrieve the symbol table of an archive diff --git a/lib/libelf/elf_getbase.3 b/lib/libelf/elf_getbase.3 index 30be6c5c259..be9d103f14e 100644 --- a/lib/libelf/elf_getbase.3 +++ b/lib/libelf/elf_getbase.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 11, 2006 -.Os .Dt ELF_GETBASE 3 +.Os .Sh NAME .Nm elf_getbase .Nd get the base offset for an object file diff --git a/lib/libelf/elf_getdata.3 b/lib/libelf/elf_getdata.3 index 64da4ad9f8c..10f37639563 100644 --- a/lib/libelf/elf_getdata.3 +++ b/lib/libelf/elf_getdata.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 26, 2006 -.Os .Dt ELF_GETDATA 3 +.Os .Sh NAME .Nm elf_getdata , .Nm elf_newdata , diff --git a/lib/libelf/elf_getident.3 b/lib/libelf/elf_getident.3 index f34ab70e373..1031e1d0ebc 100644 --- a/lib/libelf/elf_getident.3 +++ b/lib/libelf/elf_getident.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd July 3, 2006 -.Os .Dt ELF_GETIDENT 3 +.Os .Sh NAME .Nm elf_getident .Nd return the initial bytes of a file diff --git a/lib/libelf/elf_getphnum.3 b/lib/libelf/elf_getphnum.3 index 606ceb0e755..308f87cd4cc 100644 --- a/lib/libelf/elf_getphnum.3 +++ b/lib/libelf/elf_getphnum.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd December 16, 2006 -.Os .Dt ELF_GETPHNUM 3 +.Os .Sh NAME .Nm elf_getphnum .Nd return the number of program headers in an ELF file diff --git a/lib/libelf/elf_getscn.3 b/lib/libelf/elf_getscn.3 index 5b9de412a01..1b1b5f9ef73 100644 --- a/lib/libelf/elf_getscn.3 +++ b/lib/libelf/elf_getscn.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 22, 2007 -.Os .Dt ELF_GETSCN 3 +.Os .Sh NAME .Nm elf_getscn , .Nm elf_ndxscn , diff --git a/lib/libelf/elf_getshnum.3 b/lib/libelf/elf_getshnum.3 index 10a370ce6db..7c8a04c26a5 100644 --- a/lib/libelf/elf_getshnum.3 +++ b/lib/libelf/elf_getshnum.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 31, 2006 -.Os .Dt ELF_GETSHNUM 3 +.Os .Sh NAME .Nm elf_getshnum .Nd return the number of sections in an ELF file diff --git a/lib/libelf/elf_getshstrndx.3 b/lib/libelf/elf_getshstrndx.3 index 115b2dac1c6..71df3ac5192 100644 --- a/lib/libelf/elf_getshstrndx.3 +++ b/lib/libelf/elf_getshstrndx.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 31, 2006 -.Os .Dt ELF_GETSHSTRNDX 3 +.Os .Sh NAME .Nm elf_getshstrndx , .Nm elf_setshstrndx diff --git a/lib/libelf/elf_hash.3 b/lib/libelf/elf_hash.3 index 02095988959..0df2804e2fa 100644 --- a/lib/libelf/elf_hash.3 +++ b/lib/libelf/elf_hash.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 15, 2006 -.Os .Dt ELF_HASH 3 +.Os .Sh NAME .Nm elf_hash .Nd compute a hash value for a string diff --git a/lib/libelf/elf_kind.3 b/lib/libelf/elf_kind.3 index def1582b229..de74e574993 100644 --- a/lib/libelf/elf_kind.3 +++ b/lib/libelf/elf_kind.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 1, 2006 -.Os .Dt ELF_KIND 3 +.Os .Sh NAME .Nm elf_kind .Nd determine ELF file type diff --git a/lib/libelf/elf_memory.3 b/lib/libelf/elf_memory.3 index 9af6c5e30fa..83de5124b21 100644 --- a/lib/libelf/elf_memory.3 +++ b/lib/libelf/elf_memory.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 28, 2006 -.Os .Dt ELF_MEMORY 3 +.Os .Sh NAME .Nm elf_memory .Nd process an ELF or ar(1) archive mapped into memory diff --git a/lib/libelf/elf_next.3 b/lib/libelf/elf_next.3 index da995fc253b..184ab9f44ee 100644 --- a/lib/libelf/elf_next.3 +++ b/lib/libelf/elf_next.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 17, 2006 -.Os .Dt ELF_NEXT 3 +.Os .Sh NAME .Nm elf_next .Nd provide sequential access to the next archive member diff --git a/lib/libelf/elf_rand.3 b/lib/libelf/elf_rand.3 index 46cec6d2895..e4d23d761f1 100644 --- a/lib/libelf/elf_rand.3 +++ b/lib/libelf/elf_rand.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 17, 2006 -.Os .Dt ELF_RAND 3 +.Os .Sh NAME .Nm elf_rand .Nd provide sequential access to the next archive member diff --git a/lib/libelf/elf_rawfile.3 b/lib/libelf/elf_rawfile.3 index 76026e7971b..4458148830b 100644 --- a/lib/libelf/elf_rawfile.3 +++ b/lib/libelf/elf_rawfile.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd July 3, 2006 -.Os .Dt ELF_RAWFILE 3 +.Os .Sh NAME .Nm elf_rawfile .Nd return uninterpreted contents of an ELF file diff --git a/lib/libelf/elf_strptr.3 b/lib/libelf/elf_strptr.3 index bf24cc1f655..a0a9e649bb1 100644 --- a/lib/libelf/elf_strptr.3 +++ b/lib/libelf/elf_strptr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd December 16, 2006 -.Os .Dt ELF_STRPTR 3 +.Os .Sh NAME .Nm elf_strptr .Nd retrieve a string pointer in a string table diff --git a/lib/libelf/elf_update.3 b/lib/libelf/elf_update.3 index 33a14d192bc..7f6f4f09ba5 100644 --- a/lib/libelf/elf_update.3 +++ b/lib/libelf/elf_update.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 19, 2008 -.Os .Dt ELF_UPDATE 3 +.Os .Sh NAME .Nm elf_update .Nd update an ELF descriptor diff --git a/lib/libelf/elf_version.3 b/lib/libelf/elf_version.3 index 25ea62b231c..e9187106174 100644 --- a/lib/libelf/elf_version.3 +++ b/lib/libelf/elf_version.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 1, 2006 -.Os .Dt ELF_VERSION 3 +.Os .Sh NAME .Nm elf_version .Nd retrieve or set ELF library operating version diff --git a/lib/libelf/gelf.3 b/lib/libelf/gelf.3 index 4ab5ff2867c..d541388aee3 100644 --- a/lib/libelf/gelf.3 +++ b/lib/libelf/gelf.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 1, 2006 -.Os .Dt GELF 3 +.Os .Sh NAME .Nm GElf .Nd class-independent API for ELF manipulation diff --git a/lib/libelf/gelf_checksum.3 b/lib/libelf/gelf_checksum.3 index a6f19784b3c..99870f0af13 100644 --- a/lib/libelf/gelf_checksum.3 +++ b/lib/libelf/gelf_checksum.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_CHECKSUM 3 +.Os .Sh NAME .Nm elf32_checksum , .Nm elf64_checksum , diff --git a/lib/libelf/gelf_fsize.3 b/lib/libelf/gelf_fsize.3 index 915d840b638..caefae755fe 100644 --- a/lib/libelf/gelf_fsize.3 +++ b/lib/libelf/gelf_fsize.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd February 5, 2008 -.Os .Dt GELF_FSIZE 3 +.Os .Sh NAME .Nm gelf_fsize , .Nm elf32_fsize , diff --git a/lib/libelf/gelf_getcap.3 b/lib/libelf/gelf_getcap.3 index f6262d81a94..e63a2633753 100644 --- a/lib/libelf/gelf_getcap.3 +++ b/lib/libelf/gelf_getcap.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETCAP 3 +.Os .Sh NAME .Nm gelf_getcap , .Nm gelf_update_cap diff --git a/lib/libelf/gelf_getclass.3 b/lib/libelf/gelf_getclass.3 index cab3e24b832..7f7bc30ce20 100644 --- a/lib/libelf/gelf_getclass.3 +++ b/lib/libelf/gelf_getclass.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd July 3, 2006 -.Os .Dt GELF_GETCLASS 3 +.Os .Sh NAME .Nm gelf_getclass .Nd retrieve the class of an ELF descriptor diff --git a/lib/libelf/gelf_getdyn.3 b/lib/libelf/gelf_getdyn.3 index 11244440ff8..a755d63a09f 100644 --- a/lib/libelf/gelf_getdyn.3 +++ b/lib/libelf/gelf_getdyn.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETDYN 3 +.Os .Sh NAME .Nm gelf_getdyn , .Nm gelf_update_dyn diff --git a/lib/libelf/gelf_getehdr.3 b/lib/libelf/gelf_getehdr.3 index d4c8cb34e53..8e71c2d4945 100644 --- a/lib/libelf/gelf_getehdr.3 +++ b/lib/libelf/gelf_getehdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd December 16, 2006 -.Os .Dt GELF_GETEHDR 3 +.Os .Sh NAME .Nm elf32_getehdr , .Nm elf64_getehdr , diff --git a/lib/libelf/gelf_getmove.3 b/lib/libelf/gelf_getmove.3 index 11fd9cad955..abe398ab374 100644 --- a/lib/libelf/gelf_getmove.3 +++ b/lib/libelf/gelf_getmove.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETMOVE 3 +.Os .Sh NAME .Nm gelf_getmove , .Nm gelf_update_move diff --git a/lib/libelf/gelf_getphdr.3 b/lib/libelf/gelf_getphdr.3 index d6ffb906147..53fab17bba8 100644 --- a/lib/libelf/gelf_getphdr.3 +++ b/lib/libelf/gelf_getphdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 21, 2007 -.Os .Dt GELF_GETPHDR 3 +.Os .Sh NAME .Nm elf32_getphdr , .Nm elf64_getphdr , diff --git a/lib/libelf/gelf_getrel.3 b/lib/libelf/gelf_getrel.3 index 75fa79e9822..6e650a5b7d2 100644 --- a/lib/libelf/gelf_getrel.3 +++ b/lib/libelf/gelf_getrel.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETREL 3 +.Os .Sh NAME .Nm gelf_getrel , .Nm gelf_update_rel diff --git a/lib/libelf/gelf_getrela.3 b/lib/libelf/gelf_getrela.3 index d8968f56129..dc7e5795cbe 100644 --- a/lib/libelf/gelf_getrela.3 +++ b/lib/libelf/gelf_getrela.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETRELA 3 +.Os .Sh NAME .Nm gelf_getrela , .Nm gelf_update_rela diff --git a/lib/libelf/gelf_getshdr.3 b/lib/libelf/gelf_getshdr.3 index c1823b54d52..851f51f00ef 100644 --- a/lib/libelf/gelf_getshdr.3 +++ b/lib/libelf/gelf_getshdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 27, 2006 -.Os .Dt GELF_GETSHDR 3 +.Os .Sh NAME .Nm elf32_getshdr , .Nm elf64_getshdr , diff --git a/lib/libelf/gelf_getsym.3 b/lib/libelf/gelf_getsym.3 index 4e35133648d..56a6783acb1 100644 --- a/lib/libelf/gelf_getsym.3 +++ b/lib/libelf/gelf_getsym.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETSYM 3 +.Os .Sh NAME .Nm gelf_getsym , .Nm gelf_update_sym diff --git a/lib/libelf/gelf_getsyminfo.3 b/lib/libelf/gelf_getsyminfo.3 index 904e6490a2e..12da80f544e 100644 --- a/lib/libelf/gelf_getsyminfo.3 +++ b/lib/libelf/gelf_getsyminfo.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2006 -.Os .Dt GELF_GETSYMINFO 3 +.Os .Sh NAME .Nm gelf_getsyminfo , .Nm gelf_update_syminfo diff --git a/lib/libelf/gelf_getsymshndx.3 b/lib/libelf/gelf_getsymshndx.3 index c254a438259..d79c392959f 100644 --- a/lib/libelf/gelf_getsymshndx.3 +++ b/lib/libelf/gelf_getsymshndx.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 5, 2006 -.Os .Dt GELF_GETSYMSHNDX 3 +.Os .Sh NAME .Nm gelf_getsymshndx , .Nm gelf_update_symshndx diff --git a/lib/libelf/gelf_newehdr.3 b/lib/libelf/gelf_newehdr.3 index 98820e2e06e..6a2edf8f042 100644 --- a/lib/libelf/gelf_newehdr.3 +++ b/lib/libelf/gelf_newehdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 22, 2007 -.Os .Dt GELF_NEWEHDR 3 +.Os .Sh NAME .Nm elf32_newehdr , .Nm elf64_newehdr , diff --git a/lib/libelf/gelf_newphdr.3 b/lib/libelf/gelf_newphdr.3 index 3d669b63aa1..bd13e5df53a 100644 --- a/lib/libelf/gelf_newphdr.3 +++ b/lib/libelf/gelf_newphdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 22, 2007 -.Os .Dt GELF_NEWPHDR 3 +.Os .Sh NAME .Nm elf32_newphdr , .Nm elf64_newphdr , diff --git a/lib/libelf/gelf_update_ehdr.3 b/lib/libelf/gelf_update_ehdr.3 index 82098314e03..df23a0ceb0d 100644 --- a/lib/libelf/gelf_update_ehdr.3 +++ b/lib/libelf/gelf_update_ehdr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 27, 2006 -.Os .Dt GELF_UPDATE_EHDR 3 +.Os .Sh NAME .Nm gelf_update_ehdr , .Nm gelf_update_phdr , diff --git a/lib/libelf/gelf_xlatetof.3 b/lib/libelf/gelf_xlatetof.3 index b7699305ea8..453f56fcc40 100644 --- a/lib/libelf/gelf_xlatetof.3 +++ b/lib/libelf/gelf_xlatetof.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 2006 -.Os .Dt GELF_XLATETOF 3 +.Os .Sh NAME .Nm elf32_xlate , .Nm elf64_xlate , diff --git a/lib/libgssapi/gss_accept_sec_context.3 b/lib/libgssapi/gss_accept_sec_context.3 index 8957831e145..a4c219c164e 100644 --- a/lib/libgssapi/gss_accept_sec_context.3 +++ b/lib/libgssapi/gss_accept_sec_context.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_ACCEPT_SEC_CONTEXT 3 PRM +.Os .Sh NAME .Nm gss_accept_sec_context .Nd Accept a security context initiated by a peer application diff --git a/lib/libgssapi/gss_acquire_cred.3 b/lib/libgssapi/gss_acquire_cred.3 index c48a46838d0..5de9ea0362a 100644 --- a/lib/libgssapi/gss_acquire_cred.3 +++ b/lib/libgssapi/gss_acquire_cred.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_ACQUIRE_CRED 3 PRM +.Os .Sh NAME .Nm gss_acquire_cred .Nd Obtain a GSS-API credential handle for pre-existing credentials diff --git a/lib/libgssapi/gss_add_cred.3 b/lib/libgssapi/gss_add_cred.3 index 53df140d555..67ff1c3dc74 100644 --- a/lib/libgssapi/gss_add_cred.3 +++ b/lib/libgssapi/gss_add_cred.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_ADD_CRED 3 PRM +.Os .Sh NAME .Nm gss_add_cred .Nd Construct credentials incrementally diff --git a/lib/libgssapi/gss_add_oid_set_member.3 b/lib/libgssapi/gss_add_oid_set_member.3 index fb2119cefe8..5839da6717c 100644 --- a/lib/libgssapi/gss_add_oid_set_member.3 +++ b/lib/libgssapi/gss_add_oid_set_member.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_ADD_OID_SET_MEMBER 3 PRM +.Os .Sh NAME .Nm gss_add_oid_set_member .Nd Add an object identifier to a set diff --git a/lib/libgssapi/gss_canonicalize_name.3 b/lib/libgssapi/gss_canonicalize_name.3 index 86957dc0584..036c0eff824 100644 --- a/lib/libgssapi/gss_canonicalize_name.3 +++ b/lib/libgssapi/gss_canonicalize_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_CANONICALIZE_NAME 3 PRM +.Os .Sh NAME .Nm gss_canonicalize_name .Nd Convert an internal name to an MN diff --git a/lib/libgssapi/gss_compare_name.3 b/lib/libgssapi/gss_compare_name.3 index 7f69d430b27..0bafb596408 100644 --- a/lib/libgssapi/gss_compare_name.3 +++ b/lib/libgssapi/gss_compare_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_COMPARE_NAME PRM +.Os .Sh NAME .Nm gss_compare_name .Nd Compare two internal-form names diff --git a/lib/libgssapi/gss_context_time.3 b/lib/libgssapi/gss_context_time.3 index 9fb43eacab0..b6b4157dd94 100644 --- a/lib/libgssapi/gss_context_time.3 +++ b/lib/libgssapi/gss_context_time.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_CONTEXT_TIME 3 PRM +.Os .Sh NAME .Nm gss_context_time .Nd Determine for how long a context will remain valid diff --git a/lib/libgssapi/gss_create_empty_oid_set.3 b/lib/libgssapi/gss_create_empty_oid_set.3 index 08d82f6b2ba..3a84f855c15 100644 --- a/lib/libgssapi/gss_create_empty_oid_set.3 +++ b/lib/libgssapi/gss_create_empty_oid_set.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_CREATE_EMPTY_OID_SET 3 PRM +.Os .Sh NAME .Nm gss_create_empty_oid_set .Nd Create a set containing no object identifiers diff --git a/lib/libgssapi/gss_delete_sec_context.3 b/lib/libgssapi/gss_delete_sec_context.3 index a0c26df7f3e..1c4fa7b6690 100644 --- a/lib/libgssapi/gss_delete_sec_context.3 +++ b/lib/libgssapi/gss_delete_sec_context.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_DELETE_SEC_CONTEXT 3 PRM +.Os .Sh NAME .Nm gss_delete_sec_context .Nd Discard a security context diff --git a/lib/libgssapi/gss_display_name.3 b/lib/libgssapi/gss_display_name.3 index 2441eef4c49..4944995c467 100644 --- a/lib/libgssapi/gss_display_name.3 +++ b/lib/libgssapi/gss_display_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_DISPLAY_NAME 3 PRM +.Os .Sh NAME .Nm gss_display_name .Nd Convert internal-form name to text diff --git a/lib/libgssapi/gss_display_status.3 b/lib/libgssapi/gss_display_status.3 index 2b1affd4e35..4bf908bb1d0 100644 --- a/lib/libgssapi/gss_display_status.3 +++ b/lib/libgssapi/gss_display_status.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_DISPLAY_STATUS 3 PRM +.Os .Sh NAME .Nm gss_display_status .Nd Convert a GSS-API status code to text diff --git a/lib/libgssapi/gss_duplicate_name.3 b/lib/libgssapi/gss_duplicate_name.3 index 334a1268410..5eb4a6284c4 100644 --- a/lib/libgssapi/gss_duplicate_name.3 +++ b/lib/libgssapi/gss_duplicate_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_DUPLICATE_NAME 3 PRM +.Os .Sh NAME .Nm gss_duplicate_name .Nd Create a copy of an internal name diff --git a/lib/libgssapi/gss_export_name.3 b/lib/libgssapi/gss_export_name.3 index e1feee22bd6..5cbf803b949 100644 --- a/lib/libgssapi/gss_export_name.3 +++ b/lib/libgssapi/gss_export_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_EXPORT_NAME 3 PRM +.Os .Sh NAME .Nm gss_export_name .Nd Convert an MN to export form diff --git a/lib/libgssapi/gss_export_sec_context.3 b/lib/libgssapi/gss_export_sec_context.3 index 1f7f01df9d3..7ecbef31717 100644 --- a/lib/libgssapi/gss_export_sec_context.3 +++ b/lib/libgssapi/gss_export_sec_context.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_EXPORT_SEC_CONTEXT 3 PRM +.Os .Sh NAME .Nm gss_export_sec_context .Nd Transfer a security context to another process diff --git a/lib/libgssapi/gss_get_mic.3 b/lib/libgssapi/gss_get_mic.3 index 8892808f022..e5d81fa77f4 100644 --- a/lib/libgssapi/gss_get_mic.3 +++ b/lib/libgssapi/gss_get_mic.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_GET_MIC 3 PRM +.Os .Sh NAME .Nm gss_get_mic , .Nm gss_sign diff --git a/lib/libgssapi/gss_import_name.3 b/lib/libgssapi/gss_import_name.3 index 3119f04534b..aef1ae8cb10 100644 --- a/lib/libgssapi/gss_import_name.3 +++ b/lib/libgssapi/gss_import_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_IMPORT_NAME 3 PRM +.Os .Sh NAME .Nm gss_import_name .Nd Convert a contiguous string name to internal-form diff --git a/lib/libgssapi/gss_import_sec_context.3 b/lib/libgssapi/gss_import_sec_context.3 index a889e2b7fa4..87aaa7872c7 100644 --- a/lib/libgssapi/gss_import_sec_context.3 +++ b/lib/libgssapi/gss_import_sec_context.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_IMPORT_SEC_CONTEXT 3 PRM +.Os .Sh NAME .Nm gss_import_sec_context .Nd Import a transferred context diff --git a/lib/libgssapi/gss_indicate_mechs.3 b/lib/libgssapi/gss_indicate_mechs.3 index 26ffaa60162..3eec8615a17 100644 --- a/lib/libgssapi/gss_indicate_mechs.3 +++ b/lib/libgssapi/gss_indicate_mechs.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INDICATE_MECHS 3 PRM +.Os .Sh NAME .Nm gss_indicate_mechs .Nd Determine available underlying authentication mechanisms diff --git a/lib/libgssapi/gss_init_sec_context.3 b/lib/libgssapi/gss_init_sec_context.3 index 278dd17979b..9d14859fb41 100644 --- a/lib/libgssapi/gss_init_sec_context.3 +++ b/lib/libgssapi/gss_init_sec_context.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INIT_SEC_CONTEXT 3 PRM +.Os .Sh NAME .Nm gss_init_sec_context .Nd Initiate a security context with a peer application diff --git a/lib/libgssapi/gss_inquire_context.3 b/lib/libgssapi/gss_inquire_context.3 index 51fa18db829..ba5d649facd 100644 --- a/lib/libgssapi/gss_inquire_context.3 +++ b/lib/libgssapi/gss_inquire_context.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INQUIRE_CONTEXT 3 PRM +.Os .Sh NAME .Nm gss_inquire_context .Nd Obtain information about a security context diff --git a/lib/libgssapi/gss_inquire_cred.3 b/lib/libgssapi/gss_inquire_cred.3 index 99c20ce01fb..923b3734bea 100644 --- a/lib/libgssapi/gss_inquire_cred.3 +++ b/lib/libgssapi/gss_inquire_cred.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INQUIRE_CRED 3 PRM +.Os .Sh NAME .Nm gss_inquire_cred .Nd Obtain information about a credential diff --git a/lib/libgssapi/gss_inquire_cred_by_mech.3 b/lib/libgssapi/gss_inquire_cred_by_mech.3 index 22319bd4613..c316930cffb 100644 --- a/lib/libgssapi/gss_inquire_cred_by_mech.3 +++ b/lib/libgssapi/gss_inquire_cred_by_mech.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INQUIRE_CRED_BY_MECH 3 PRM +.Os .Sh NAME .Nm gss_inquire_cred_by_mech .Nd Obtain per-mechanism information about a credential diff --git a/lib/libgssapi/gss_inquire_mechs_for_name.3 b/lib/libgssapi/gss_inquire_mechs_for_name.3 index b56e663a18d..d8d94edb482 100644 --- a/lib/libgssapi/gss_inquire_mechs_for_name.3 +++ b/lib/libgssapi/gss_inquire_mechs_for_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INQUIRE_MECHS_FOR_NAME 3 PRM +.Os .Sh NAME .Nm gss_inquire_mechs_for_name .Nd List mechanisms that support the specified name-type diff --git a/lib/libgssapi/gss_inquire_names_for_mech.3 b/lib/libgssapi/gss_inquire_names_for_mech.3 index 8b7f069f915..c1b7528b56e 100644 --- a/lib/libgssapi/gss_inquire_names_for_mech.3 +++ b/lib/libgssapi/gss_inquire_names_for_mech.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_INQUIRE_NAMES_FOR_MECH 3 PRM +.Os .Sh NAME .Nm gss_inquire_names_for_mech .Nd List the name-types supported by the specified mechanism diff --git a/lib/libgssapi/gss_process_context_token.3 b/lib/libgssapi/gss_process_context_token.3 index 85e1029aab0..53f5ebfcc53 100644 --- a/lib/libgssapi/gss_process_context_token.3 +++ b/lib/libgssapi/gss_process_context_token.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_PROCESS_CONTEXT_TOKEN 3 PRM +.Os .Sh NAME .Nm gss_process_context_token .Nd Process a token on a security context from a peer application diff --git a/lib/libgssapi/gss_release_buffer.3 b/lib/libgssapi/gss_release_buffer.3 index 432d42276c5..259db3ba6b8 100644 --- a/lib/libgssapi/gss_release_buffer.3 +++ b/lib/libgssapi/gss_release_buffer.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_RELEASE_BUFFER 3 PRM +.Os .Sh NAME .Nm gss_release_buffer .Nd Discard a buffer diff --git a/lib/libgssapi/gss_release_cred.3 b/lib/libgssapi/gss_release_cred.3 index ca99fc40a8f..38fc7844bea 100644 --- a/lib/libgssapi/gss_release_cred.3 +++ b/lib/libgssapi/gss_release_cred.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_RELEASE_CRED 3 PRM +.Os .Sh NAME .Nm gss_release_cred .Nd Discard a credential handle diff --git a/lib/libgssapi/gss_release_name.3 b/lib/libgssapi/gss_release_name.3 index 7bf1181f22a..ca737e0af3a 100644 --- a/lib/libgssapi/gss_release_name.3 +++ b/lib/libgssapi/gss_release_name.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_RELEASE_NAME 3 PRM +.Os .Sh NAME .Nm gss_release_name .Nd Discard an internal-form name diff --git a/lib/libgssapi/gss_release_oid_set.3 b/lib/libgssapi/gss_release_oid_set.3 index 0142e2feec1..391ad283c79 100644 --- a/lib/libgssapi/gss_release_oid_set.3 +++ b/lib/libgssapi/gss_release_oid_set.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_RELEASE_OID_SET 3 PRM +.Os .Sh NAME .Nm gss_release_oid_set .Nd Discard a set of object identifiers diff --git a/lib/libgssapi/gss_test_oid_set_member.3 b/lib/libgssapi/gss_test_oid_set_member.3 index 86e06b35bb7..c6dad0f2fe7 100644 --- a/lib/libgssapi/gss_test_oid_set_member.3 +++ b/lib/libgssapi/gss_test_oid_set_member.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_TEST_OID_SET_MEMBER 3 PRM +.Os .Sh NAME .Nm gss_test_oid_set_member .Nd Determines whether an object identifier is a member of a set diff --git a/lib/libgssapi/gss_unwrap.3 b/lib/libgssapi/gss_unwrap.3 index cc75782310b..94537a49650 100644 --- a/lib/libgssapi/gss_unwrap.3 +++ b/lib/libgssapi/gss_unwrap.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_UNWRAP 3 PRM +.Os .Sh NAME .Nm gss_unwrap , .Nm gss_unseal diff --git a/lib/libgssapi/gss_verify_mic.3 b/lib/libgssapi/gss_verify_mic.3 index b72f468ce7d..e8a46119422 100644 --- a/lib/libgssapi/gss_verify_mic.3 +++ b/lib/libgssapi/gss_verify_mic.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_VERIFY_MIC 3 PRM +.Os .Sh NAME .Nm gss_verify_mic , .Nm gss_verify diff --git a/lib/libgssapi/gss_wrap.3 b/lib/libgssapi/gss_wrap.3 index c432b482c1b..5732dd24cf8 100644 --- a/lib/libgssapi/gss_wrap.3 +++ b/lib/libgssapi/gss_wrap.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_WRAP 3 PRM +.Os .Sh NAME .Nm gss_wrap , .Nm gss_seal diff --git a/lib/libgssapi/gss_wrap_size_limit.3 b/lib/libgssapi/gss_wrap_size_limit.3 index c1d40da014d..7a1cb599ad2 100644 --- a/lib/libgssapi/gss_wrap_size_limit.3 +++ b/lib/libgssapi/gss_wrap_size_limit.3 @@ -28,8 +28,8 @@ .\" .\" The following commands are required for all man pages. .Dd January 26, 2010 -.Os .Dt GSS_WRAP_SIZE_LIMIT 3 PRM +.Os .Sh NAME .Nm gss_wrap_size_limit .Nd Determine maximum message sizes diff --git a/lib/libmemstat/libmemstat.3 b/lib/libmemstat/libmemstat.3 index 82ec53abee6..9a4877b0aa7 100644 --- a/lib/libmemstat/libmemstat.3 +++ b/lib/libmemstat/libmemstat.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd June 27, 2005 -.Os .Dt LIBMEMSTAT 3 +.Os .Sh NAME .Nm libmemstat .Nd "library interface to retrieve kernel memory allocator statistics" diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3 index f48fe7985e9..5e3236baf9b 100644 --- a/lib/libpmc/pmc.3 +++ b/lib/libpmc/pmc.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 24, 2008 -.Os .Dt PMC 3 +.Os .Sh NAME .Nm pmc .Nd library for accessing hardware performance monitoring counters diff --git a/lib/libpmc/pmc.atom.3 b/lib/libpmc/pmc.atom.3 index bd081f9d27a..a54d1db2b1c 100644 --- a/lib/libpmc/pmc.atom.3 +++ b/lib/libpmc/pmc.atom.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 12, 2008 -.Os .Dt PMC.ATOM 3 +.Os .Sh NAME .Nm pmc.atom .Nd measurement events for diff --git a/lib/libpmc/pmc.core.3 b/lib/libpmc/pmc.core.3 index 3c97e092594..3feadaef2c5 100644 --- a/lib/libpmc/pmc.core.3 +++ b/lib/libpmc/pmc.core.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 12, 2008 -.Os .Dt PMC.CORE 3 +.Os .Sh NAME .Nm pmc.core .Nd measurement events for diff --git a/lib/libpmc/pmc.core2.3 b/lib/libpmc/pmc.core2.3 index 41c16750d62..3dbc0c850e5 100644 --- a/lib/libpmc/pmc.core2.3 +++ b/lib/libpmc/pmc.core2.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd June 8, 2009 -.Os .Dt PMC.CORE2 3 +.Os .Sh NAME .Nm pmc.core2 .Nd measurement events for diff --git a/lib/libpmc/pmc.corei7.3 b/lib/libpmc/pmc.corei7.3 index 1a8b9d9d419..f90b0d3ead8 100644 --- a/lib/libpmc/pmc.corei7.3 +++ b/lib/libpmc/pmc.corei7.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 24, 2010 -.Os .Dt PMC.COREI7 3 +.Os .Sh NAME .Nm pmc.corei7 .Nd measurement events for diff --git a/lib/libpmc/pmc.corei7uc.3 b/lib/libpmc/pmc.corei7uc.3 index 2c1b3dde07f..fc3435b698a 100644 --- a/lib/libpmc/pmc.corei7uc.3 +++ b/lib/libpmc/pmc.corei7uc.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 24, 2010 -.Os .Dt PMC.COREI7UC 3 +.Os .Sh NAME .Nm pmc.corei7uc .Nd uncore measurement events for diff --git a/lib/libpmc/pmc.iaf.3 b/lib/libpmc/pmc.iaf.3 index c6d01eaaa72..ec9f21cb276 100644 --- a/lib/libpmc/pmc.iaf.3 +++ b/lib/libpmc/pmc.iaf.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 14, 2008 -.Os .Dt PMC.IAF 3 +.Os .Sh NAME .Nm pmc.iaf .Nd measurement events for diff --git a/lib/libpmc/pmc.k7.3 b/lib/libpmc/pmc.k7.3 index 8db9020dead..2775d4fd922 100644 --- a/lib/libpmc/pmc.k7.3 +++ b/lib/libpmc/pmc.k7.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 4, 2008 -.Os .Dt PMC.K7 3 +.Os .Sh NAME .Nm pmc.k7 .Nd measurement events for diff --git a/lib/libpmc/pmc.k8.3 b/lib/libpmc/pmc.k8.3 index 3e4afb1ff5b..995bfac958a 100644 --- a/lib/libpmc/pmc.k8.3 +++ b/lib/libpmc/pmc.k8.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 4, 2008 -.Os .Dt PMC.K8 3 +.Os .Sh NAME .Nm pmc.k8 .Nd measurement events for diff --git a/lib/libpmc/pmc.p4.3 b/lib/libpmc/pmc.p4.3 index ecfc6287db8..e13fa6ec5ea 100644 --- a/lib/libpmc/pmc.p4.3 +++ b/lib/libpmc/pmc.p4.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 4, 2008 -.Os .Dt PMC.P4 3 +.Os .Sh NAME .Nm pmc.p4 .Nd measurement events for diff --git a/lib/libpmc/pmc.p5.3 b/lib/libpmc/pmc.p5.3 index 2930f16caac..36ab917dc25 100644 --- a/lib/libpmc/pmc.p5.3 +++ b/lib/libpmc/pmc.p5.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 4, 2008 -.Os .Dt PMC 3 +.Os .Sh NAME .Nm pmc .Nd library for accessing hardware performance monitoring counters diff --git a/lib/libpmc/pmc.p6.3 b/lib/libpmc/pmc.p6.3 index 15a1101bf67..d8cde6427b6 100644 --- a/lib/libpmc/pmc.p6.3 +++ b/lib/libpmc/pmc.p6.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 4, 2008 -.Os .Dt PMC.P6 3 +.Os .Sh NAME .Nm pmc.p6 .Nd measurement events for diff --git a/lib/libpmc/pmc.tsc.3 b/lib/libpmc/pmc.tsc.3 index 3dd0b8859ca..144ff35c3f0 100644 --- a/lib/libpmc/pmc.tsc.3 +++ b/lib/libpmc/pmc.tsc.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd October 4, 2008 -.Os .Dt PMC.TSC 3 +.Os .Sh NAME .Nm pmc.tsc .Nd measurements using the i386 timestamp counter diff --git a/lib/libpmc/pmc.ucf.3 b/lib/libpmc/pmc.ucf.3 index c8f2468cdf8..230a1108578 100644 --- a/lib/libpmc/pmc.ucf.3 +++ b/lib/libpmc/pmc.ucf.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 30, 2010 -.Os .Dt PMC.UCF 3 +.Os .Sh NAME .Nm pmc.ucf .Nd measurement events for diff --git a/lib/libpmc/pmc.westmere.3 b/lib/libpmc/pmc.westmere.3 index 0b87e50230a..98adce6f3af 100644 --- a/lib/libpmc/pmc.westmere.3 +++ b/lib/libpmc/pmc.westmere.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 24, 2010 -.Os .Dt PMC.WESTMERE 3 +.Os .Sh NAME .Nm pmc.westmere .Nd measurement events for diff --git a/lib/libpmc/pmc.westmereuc.3 b/lib/libpmc/pmc.westmereuc.3 index c5fd12dfa66..c77ef9bfa48 100644 --- a/lib/libpmc/pmc.westmereuc.3 +++ b/lib/libpmc/pmc.westmereuc.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 24, 2010 -.Os .Dt PMC.WESTMEREUC 3 +.Os .Sh NAME .Nm pmc.westmere .Nd uncore measurement events for diff --git a/lib/libpmc/pmc_allocate.3 b/lib/libpmc/pmc_allocate.3 index 03f907811a7..6a2a6c0d0f0 100644 --- a/lib/libpmc/pmc_allocate.3 +++ b/lib/libpmc/pmc_allocate.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 22, 2008 -.Os .Dt PMC_ALLOCATE 3 +.Os .Sh NAME .Nm pmc_allocate , .Nm pmc_release diff --git a/lib/libpmc/pmc_attach.3 b/lib/libpmc/pmc_attach.3 index be340a77598..ca725112b0b 100644 --- a/lib/libpmc/pmc_attach.3 +++ b/lib/libpmc/pmc_attach.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 25, 2007 -.Os .Dt PMC_ATTACH 3 +.Os .Sh NAME .Nm pmc_attach , .Nm pmc_detach diff --git a/lib/libpmc/pmc_capabilities.3 b/lib/libpmc/pmc_capabilities.3 index 0d1a99dd602..6aee17f8bfb 100644 --- a/lib/libpmc/pmc_capabilities.3 +++ b/lib/libpmc/pmc_capabilities.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 22, 2008 -.Os .Dt PMC_CAPABILITIES 3 +.Os .Sh NAME .Nm pmc_capabilities , .Nm pmc_cpuinfo , diff --git a/lib/libpmc/pmc_configure_logfile.3 b/lib/libpmc/pmc_configure_logfile.3 index 95c6c28d438..a33688c222c 100644 --- a/lib/libpmc/pmc_configure_logfile.3 +++ b/lib/libpmc/pmc_configure_logfile.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 24, 2007 -.Os .Dt PMC_CONFIGURE_LOGFILE 3 +.Os .Sh NAME .Nm pmc_configure_logfile , .Nm pmc_flush_logfile , diff --git a/lib/libpmc/pmc_disable.3 b/lib/libpmc/pmc_disable.3 index cd837d3a075..a6902ffd463 100644 --- a/lib/libpmc/pmc_disable.3 +++ b/lib/libpmc/pmc_disable.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 22, 2008 -.Os .Dt PMC_ENABLE 3 +.Os .Sh NAME .Nm pmc_disable , .Nm pmc_enable diff --git a/lib/libpmc/pmc_event_names_of_class.3 b/lib/libpmc/pmc_event_names_of_class.3 index fc1c63c3120..5b2c89d1b80 100644 --- a/lib/libpmc/pmc_event_names_of_class.3 +++ b/lib/libpmc/pmc_event_names_of_class.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 23, 2007 -.Os .Dt PMC_EVENT_NAMES_OF_CLASS 3 +.Os .Sh NAME .Nm pmc_event_names_of_class .Nd return a list of event names supported by a PMC class. diff --git a/lib/libpmc/pmc_get_driver_stats.3 b/lib/libpmc/pmc_get_driver_stats.3 index d8bfe233b60..fa214b321a3 100644 --- a/lib/libpmc/pmc_get_driver_stats.3 +++ b/lib/libpmc/pmc_get_driver_stats.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 25, 2007 -.Os .Dt PMC_GET_DRIVER_STATS 3 +.Os .Sh NAME .Nm pmc_get_driver_stats .Nd retrieve driver statistics diff --git a/lib/libpmc/pmc_get_msr.3 b/lib/libpmc/pmc_get_msr.3 index 6a2b94274bd..6361d3adab2 100644 --- a/lib/libpmc/pmc_get_msr.3 +++ b/lib/libpmc/pmc_get_msr.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 25, 2007 -.Os .Dt PMC_GET_MSR 3 +.Os .Sh NAME .Nm pmc_get_msr .Nd x86 architecture-specific PMC operations diff --git a/lib/libpmc/pmc_init.3 b/lib/libpmc/pmc_init.3 index 5113b4aa951..655bfb6f78b 100644 --- a/lib/libpmc/pmc_init.3 +++ b/lib/libpmc/pmc_init.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 24, 2007 -.Os .Dt PMC_INIT 3 +.Os .Sh NAME .Nm pmc_init .Nd initialize library diff --git a/lib/libpmc/pmc_name_of_capability.3 b/lib/libpmc/pmc_name_of_capability.3 index 53ddfdf9075..78efeafd6ac 100644 --- a/lib/libpmc/pmc_name_of_capability.3 +++ b/lib/libpmc/pmc_name_of_capability.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 24, 2007 -.Os .Dt PMC_NAME_OF_CAPABILITY 3 +.Os .Sh NAME .Nm pmc_name_of_capability , .Nm pmc_name_of_class , diff --git a/lib/libpmc/pmc_read.3 b/lib/libpmc/pmc_read.3 index d9fa3ce8b9c..8d718ca3fd1 100644 --- a/lib/libpmc/pmc_read.3 +++ b/lib/libpmc/pmc_read.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 25, 2007 -.Os .Dt PMC_READ 3 +.Os .Sh NAME .Nm pmc_read , .Nm pmc_rw , diff --git a/lib/libpmc/pmc_set.3 b/lib/libpmc/pmc_set.3 index a9e438af9df..e8d65971dd2 100644 --- a/lib/libpmc/pmc_set.3 +++ b/lib/libpmc/pmc_set.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 25, 2007 -.Os .Dt PMC_SET 3 +.Os .Sh NAME .Nm pmc_set .Nd set the reload count of a sampling PMC diff --git a/lib/libpmc/pmc_start.3 b/lib/libpmc/pmc_start.3 index 7fb474a18bf..2272122dd19 100644 --- a/lib/libpmc/pmc_start.3 +++ b/lib/libpmc/pmc_start.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 22, 2008 -.Os .Dt PMC_START 3 +.Os .Sh NAME .Nm pmc_start , .Nm pmc_stop diff --git a/lib/libpmc/pmclog.3 b/lib/libpmc/pmclog.3 index 688445a4524..4438f106d0b 100644 --- a/lib/libpmc/pmclog.3 +++ b/lib/libpmc/pmclog.3 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd March 26, 2006 -.Os .Dt PMCLOG 3 +.Os .Sh NAME .Nm pmclog_open , .Nm pmclog_close , diff --git a/lib/libthr/libthr.3 b/lib/libthr/libthr.3 index 87e5e6475d7..696da17bdcb 100644 --- a/lib/libthr/libthr.3 +++ b/lib/libthr/libthr.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd October 19, 2007 -.Os .Dt LIBTHR 3 +.Os .Sh NAME .Nm libthr .Nd "1:1 POSIX threads library" diff --git a/lib/libugidfw/bsde_get_rule.3 b/lib/libugidfw/bsde_get_rule.3 index a3b6691eaa9..1f37b62613d 100644 --- a/lib/libugidfw/bsde_get_rule.3 +++ b/lib/libugidfw/bsde_get_rule.3 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd February 24, 2004 -.Os .Dt BSDE_GET_RULE 3 +.Os .Sh NAME .Nm bsde_add_rule , .Nm bsde_get_rule , diff --git a/lib/libugidfw/bsde_get_rule_count.3 b/lib/libugidfw/bsde_get_rule_count.3 index bf441e150d9..2ca965f8fd4 100644 --- a/lib/libugidfw/bsde_get_rule_count.3 +++ b/lib/libugidfw/bsde_get_rule_count.3 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd January 7, 2003 -.Os .Dt BSDE_GET_RULE_COUNT 3 +.Os .Sh NAME .Nm bsde_get_rule_count , .Nm bsde_get_rule_slots diff --git a/lib/libugidfw/bsde_parse_rule.3 b/lib/libugidfw/bsde_parse_rule.3 index d510cab26a2..4b177af22ed 100644 --- a/lib/libugidfw/bsde_parse_rule.3 +++ b/lib/libugidfw/bsde_parse_rule.3 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd January 7, 2003 -.Os .Dt BSDE_PARSE_RULE 3 +.Os .Sh NAME .Nm bsde_parse_rule , .Nm bsde_parse_rule_string diff --git a/lib/libugidfw/bsde_rule_to_string.3 b/lib/libugidfw/bsde_rule_to_string.3 index 44144069a52..6279dcfa371 100644 --- a/lib/libugidfw/bsde_rule_to_string.3 +++ b/lib/libugidfw/bsde_rule_to_string.3 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd January 7, 2003 -.Os .Dt BSDE_RULE_TO_STRING 3 +.Os .Sh NAME .Nm bsde_rule_to_string .Nd "convert a ugidfw rule into its text representation" diff --git a/lib/libugidfw/libugidfw.3 b/lib/libugidfw/libugidfw.3 index 3ff407c1609..42d23c68039 100644 --- a/lib/libugidfw/libugidfw.3 +++ b/lib/libugidfw/libugidfw.3 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd February 25, 2004 -.Os .Dt LIBUGIDFW 3 +.Os .Sh NAME .Nm libugidfw .Nd "library interface to the file system firewall MAC policy" diff --git a/lib/libulog/ulog_login.3 b/lib/libulog/ulog_login.3 index ec397c8c0cd..451a4f7a31f 100644 --- a/lib/libulog/ulog_login.3 +++ b/lib/libulog/ulog_login.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd December 5, 2009 -.Os .Dt ULOG_LOGIN 3 +.Os .Sh NAME .Nm ulog_login , .Nm ulog_login_pseudo , diff --git a/lib/libulog/utempter_add_record.3 b/lib/libulog/utempter_add_record.3 index 1553d68c26b..cd8e8f1e69f 100644 --- a/lib/libulog/utempter_add_record.3 +++ b/lib/libulog/utempter_add_record.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd December 6, 2009 -.Os .Dt UTEMPTER_ADD_RECORD 3 +.Os .Sh NAME .Nm utempter_add_record , .Nm utempter_remove_added_record , diff --git a/lib/libutil/_secure_path.3 b/lib/libutil/_secure_path.3 index fe23d12b2b9..cf89315a89e 100644 --- a/lib/libutil/_secure_path.3 +++ b/lib/libutil/_secure_path.3 @@ -20,8 +20,8 @@ .\" $FreeBSD$ .\" .Dd May 2, 1997 -.Os .Dt _SECURE_PATH 3 +.Os .Sh NAME .Nm _secure_path .Nd determine if a file appears to be secure diff --git a/lib/libutil/auth.3 b/lib/libutil/auth.3 index 3a1bb4dd4db..247a0985914 100644 --- a/lib/libutil/auth.3 +++ b/lib/libutil/auth.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd October 7, 1998 -.Os .Dt AUTH_GETVAL 3 +.Os .Sh NAME .Nm auth_getval .Nd functions for reading values from diff --git a/lib/libutil/hexdump.3 b/lib/libutil/hexdump.3 index cc004f61bb3..8e997ac24b4 100644 --- a/lib/libutil/hexdump.3 +++ b/lib/libutil/hexdump.3 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 1, 2008 -.Os .Dt HEXDUMP 3 +.Os .Sh NAME .Nm hexdump .Nd "dump a block of bytes to standard out in hexadecimal form" diff --git a/lib/libutil/kinfo_getfile.3 b/lib/libutil/kinfo_getfile.3 index 5705bf774d6..c0b0b022021 100644 --- a/lib/libutil/kinfo_getfile.3 +++ b/lib/libutil/kinfo_getfile.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 6, 2008 -.Os .Dt KINFO_GETFILE 3 +.Os .Sh NAME .Nm kinfo_getfile .Nd function for getting per-process file descriptor information diff --git a/lib/libutil/kinfo_getvmmap.3 b/lib/libutil/kinfo_getvmmap.3 index 0f12b675ac3..7aa46fc102e 100644 --- a/lib/libutil/kinfo_getvmmap.3 +++ b/lib/libutil/kinfo_getvmmap.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 6, 2008 -.Os .Dt KINFO_GETVMMAP 3 +.Os .Sh NAME .Nm kinfo_getvmmap .Nd function for getting per-process memory map information diff --git a/lib/libutil/kld.3 b/lib/libutil/kld.3 index cc34fa1a040..6b77c47fc0d 100644 --- a/lib/libutil/kld.3 +++ b/lib/libutil/kld.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd February 18, 2006 -.Os .Dt KLD 3 +.Os .Sh NAME .Nm kld_isloaded , .Nm kld_load diff --git a/lib/libutil/login_auth.3 b/lib/libutil/login_auth.3 index 3750bd69182..003f6e92ac0 100644 --- a/lib/libutil/login_auth.3 +++ b/lib/libutil/login_auth.3 @@ -20,8 +20,8 @@ .\" $FreeBSD$ .\" .Dd December 29, 1996 -.Os .Dt LOGIN_AUTH 3 +.Os .Sh NAME .\" .Nm authenticate .\" .Nm auth_script diff --git a/lib/libutil/login_cap.3 b/lib/libutil/login_cap.3 index 7ecefffb2a3..bdab56eba50 100644 --- a/lib/libutil/login_cap.3 +++ b/lib/libutil/login_cap.3 @@ -20,8 +20,8 @@ .\" $FreeBSD$ .\" .Dd June 14, 2007 -.Os .Dt LOGIN_CAP 3 +.Os .Sh NAME .Nm login_close , .Nm login_getcapbool , diff --git a/lib/libutil/login_class.3 b/lib/libutil/login_class.3 index 75ccccc1449..083e94289d1 100644 --- a/lib/libutil/login_class.3 +++ b/lib/libutil/login_class.3 @@ -20,8 +20,8 @@ .\" $FreeBSD$ .\" .Dd October 20, 2008 -.Os .Dt LOGIN_CLASS 3 +.Os .Sh NAME .Nm setclasscontext , .Nm setclasscpumask , diff --git a/lib/libutil/login_ok.3 b/lib/libutil/login_ok.3 index 1bb6236c243..9022ff55d3a 100644 --- a/lib/libutil/login_ok.3 +++ b/lib/libutil/login_ok.3 @@ -20,8 +20,8 @@ .\" $FreeBSD$ .\" .Dd January 2, 1997 -.Os .Dt LOGIN_OK 3 +.Os .Sh NAME .Nm auth_ttyok , .Nm auth_hostok , diff --git a/lib/libutil/login_times.3 b/lib/libutil/login_times.3 index a1444843d42..9d1f88d858c 100644 --- a/lib/libutil/login_times.3 +++ b/lib/libutil/login_times.3 @@ -20,8 +20,8 @@ .\" $FreeBSD$ .\" .Dd October 20, 2008 -.Os .Dt LOGIN_TIMES 3 +.Os .Sh NAME .Nm parse_lt , .Nm in_lt , diff --git a/lib/libutil/login_tty.3 b/lib/libutil/login_tty.3 index 6303d685e03..907b97cd5cf 100644 --- a/lib/libutil/login_tty.3 +++ b/lib/libutil/login_tty.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd December 29, 1996 -.Os .Dt LOGIN_TTY 3 +.Os .Sh NAME .Nm login_tty .Nd prepare a tty for a new login session diff --git a/lib/libutil/property.3 b/lib/libutil/property.3 index 61eb1539909..51f7e14928f 100644 --- a/lib/libutil/property.3 +++ b/lib/libutil/property.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd October 7, 1998 -.Os .Dt PROPERTIES 3 +.Os .Sh NAME .Nm properties_read , .Nm propery_find , diff --git a/lib/libutil/pty.3 b/lib/libutil/pty.3 index 08a5985b684..f71cc5323d7 100644 --- a/lib/libutil/pty.3 +++ b/lib/libutil/pty.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd December 29, 1996 -.Os .Dt PTY 3 +.Os .Sh NAME .Nm openpty , .Nm forkpty diff --git a/lib/libutil/realhostname.3 b/lib/libutil/realhostname.3 index fd64d4c6966..9f5a6c5ddc6 100644 --- a/lib/libutil/realhostname.3 +++ b/lib/libutil/realhostname.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd April 6, 1999 -.Os .Dt REALHOSTNAME 3 +.Os .Sh NAME .Nm realhostname .Nd "convert an IP number to the real host name" diff --git a/lib/libutil/realhostname_sa.3 b/lib/libutil/realhostname_sa.3 index 9f7f0dfb022..3fd44a442b1 100644 --- a/lib/libutil/realhostname_sa.3 +++ b/lib/libutil/realhostname_sa.3 @@ -52,8 +52,8 @@ .\" $FreeBSD$ .\" .Dd January 11, 2000 -.Os .Dt REALHOSTNAME_SA 3 +.Os .Sh NAME .Nm realhostname_sa .Nd "convert a" diff --git a/lib/libutil/trimdomain.3 b/lib/libutil/trimdomain.3 index f01e884e787..8d600c01921 100644 --- a/lib/libutil/trimdomain.3 +++ b/lib/libutil/trimdomain.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd April 7, 1999 -.Os .Dt TRIMDOMAIN 3 +.Os .Sh NAME .Nm trimdomain .Nd "trim the current domain name from a host name" diff --git a/lib/libutil/uucplock.3 b/lib/libutil/uucplock.3 index 5f75c7f94e9..5d8647d0319 100644 --- a/lib/libutil/uucplock.3 +++ b/lib/libutil/uucplock.3 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd March 30, 1997 -.Os .Dt UUCPLOCK 3 +.Os .Sh NAME .Nm uu_lock , .Nm uu_unlock , diff --git a/sbin/iscontrol/iscsi.conf.5 b/sbin/iscontrol/iscsi.conf.5 index 2edcd35742a..0de5122914f 100644 --- a/sbin/iscontrol/iscsi.conf.5 +++ b/sbin/iscontrol/iscsi.conf.5 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd June 5, 2007 -.Os .Dt ISCSI.CONF 5 +.Os .Sh NAME .Nm iscsi.conf .Nd key options to be negotiated in an iSCSI session diff --git a/sbin/spppcontrol/spppcontrol.8 b/sbin/spppcontrol/spppcontrol.8 index 4389c8f66ec..4d948a60651 100644 --- a/sbin/spppcontrol/spppcontrol.8 +++ b/sbin/spppcontrol/spppcontrol.8 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd December 30, 2001 -.Os .Dt SPPPCONTROL 8 +.Os .Sh NAME .Nm spppcontrol .Nd display or set parameters for an sppp interface diff --git a/share/man/man3/sysexits.3 b/share/man/man3/sysexits.3 index 4661c9d9017..2ef3407b325 100644 --- a/share/man/man3/sysexits.3 +++ b/share/man/man3/sysexits.3 @@ -27,8 +27,8 @@ .\" .\" " .Dd March 31, 1996 -.Os .Dt SYSEXITS 3 +.Os .Sh NAME .Nm sysexits .Nd preferable exit codes for programs diff --git a/share/man/man3/tgmath.3 b/share/man/man3/tgmath.3 index 4957c9b2649..f8faf269a7a 100644 --- a/share/man/man3/tgmath.3 +++ b/share/man/man3/tgmath.3 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd August 14, 2004 -.Os .Dt TGMATH 3 +.Os .Sh NAME .Nm tgmath .Nd "type-generic macros" diff --git a/share/man/man4/audit.4 b/share/man/man4/audit.4 index 82bb23fdcac..167248cec5d 100644 --- a/share/man/man4/audit.4 +++ b/share/man/man4/audit.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd May 31, 2009 -.Os .Dt AUDIT 4 +.Os .Sh NAME .Nm audit .Nd Security Event Audit diff --git a/share/man/man4/auditpipe.4 b/share/man/man4/auditpipe.4 index 7ba35afcb47..19db8565b70 100644 --- a/share/man/man4/auditpipe.4 +++ b/share/man/man4/auditpipe.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd May 5, 2006 -.Os .Dt AUDITPIPE 4 +.Os .Sh NAME .Nm auditpipe .Nd "pseudo-device for live audit event tracking" diff --git a/share/man/man4/coda.4 b/share/man/man4/coda.4 index 9fd6cbb8be1..94b12aec4d5 100644 --- a/share/man/man4/coda.4 +++ b/share/man/man4/coda.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd January 21, 2008 -.Os .Dt CODA 4 +.Os .Sh NAME .Nm coda .Nd Coda Distributed File System diff --git a/share/man/man4/gbde.4 b/share/man/man4/gbde.4 index e3bc6c7fb2a..edac1a07316 100644 --- a/share/man/man4/gbde.4 +++ b/share/man/man4/gbde.4 @@ -32,8 +32,8 @@ .\" $FreeBSD$ .\" .Dd October 19, 2002 -.Os .Dt GBDE 4 +.Os .Sh NAME .Nm gbde .Nd Geom Based Disk Encryption diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4 index 38573893357..0a1b24e5ec3 100644 --- a/share/man/man4/geom.4 +++ b/share/man/man4/geom.4 @@ -35,8 +35,8 @@ .\" $FreeBSD$ .\" .Dd May 25, 2006 -.Os .Dt GEOM 4 +.Os .Sh NAME .Nm GEOM .Nd "modular disk I/O request transformation framework" diff --git a/share/man/man4/geom_fox.4 b/share/man/man4/geom_fox.4 index 588e1d7c932..8e262b94ae5 100644 --- a/share/man/man4/geom_fox.4 +++ b/share/man/man4/geom_fox.4 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd January 2, 2005 -.Os .Dt GEOM_FOX 4 +.Os .Sh NAME .Nm geom_fox .Nd "GEOM based basic disk multipathing" diff --git a/share/man/man4/geom_linux_lvm.4 b/share/man/man4/geom_linux_lvm.4 index e41703a489b..30b875edd3e 100644 --- a/share/man/man4/geom_linux_lvm.4 +++ b/share/man/man4/geom_linux_lvm.4 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd February 20, 2008 -.Os .Dt GEOM_LINUX_LVM 4 +.Os .Sh NAME .Nm geom_linux_lvm .Nd "GEOM based Linux LVM logical volume mapping" diff --git a/share/man/man4/geom_uzip.4 b/share/man/man4/geom_uzip.4 index 30d5ab03e81..7275029d062 100644 --- a/share/man/man4/geom_uzip.4 +++ b/share/man/man4/geom_uzip.4 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd October 9, 2006 -.Os .Dt GEOM_UZIP 4 +.Os .Sh NAME .Nm geom_uzip .Nd "GEOM based compressed disk images" diff --git a/share/man/man4/ipw.4 b/share/man/man4/ipw.4 index 30293f0cafe..060058a0981 100644 --- a/share/man/man4/ipw.4 +++ b/share/man/man4/ipw.4 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd April 13, 2008 -.Os .Dt IPW 4 +.Os .Sh NAME .Nm ipw .Nd "Intel PRO/Wireless 2100 IEEE 802.11 driver" diff --git a/share/man/man4/iscsi_initiator.4 b/share/man/man4/iscsi_initiator.4 index 484a2135531..b6c47f0769b 100644 --- a/share/man/man4/iscsi_initiator.4 +++ b/share/man/man4/iscsi_initiator.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd February 23, 2007 -.Os .Dt ISCSI_INITIATOR 4 +.Os .Sh NAME .Nm iscsi_initiator .Nd kernel driver for the iSCSI protocol diff --git a/share/man/man4/iwi.4 b/share/man/man4/iwi.4 index 3c9bdd46608..64f5c0ed13a 100644 --- a/share/man/man4/iwi.4 +++ b/share/man/man4/iwi.4 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd April 13, 2008 -.Os .Dt IWI 4 +.Os .Sh NAME .Nm iwi .Nd "Intel PRO/Wireless 2200BG/2225BG/2915ABG IEEE 802.11 driver" diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4 index b73331a04b5..a229e57c843 100644 --- a/share/man/man4/iwn.4 +++ b/share/man/man4/iwn.4 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd February 8, 2010 -.Os .Dt IWN 4 +.Os .Sh NAME .Nm iwn .Nd Intel Wireless WiFi Link 4965/1000/5000/5150/5300/6000/6050 diff --git a/share/man/man4/kbdmux.4 b/share/man/man4/kbdmux.4 index e29f8cd766e..f92fa4584e9 100644 --- a/share/man/man4/kbdmux.4 +++ b/share/man/man4/kbdmux.4 @@ -2,8 +2,8 @@ .\" $FreeBSD$ .\" .Dd July 12, 2005 -.Os .Dt KBDMUX 4 +.Os .Sh NAME .Nm kbdmux .Nd "keyboard multiplexer" diff --git a/share/man/man4/lp.4 b/share/man/man4/lp.4 index 6976101af2c..f5b628e6ff0 100644 --- a/share/man/man4/lp.4 +++ b/share/man/man4/lp.4 @@ -35,8 +35,8 @@ .\" $FreeBSD$ .\" .Dd March 4, 1996 -.Os .Dt LP 4 +.Os .Sh NAME .Nm lp .Nd printer port Internet Protocol driver diff --git a/share/man/man4/mac.4 b/share/man/man4/mac.4 index 82d7a165aa1..b1ff1d951d8 100644 --- a/share/man/man4/mac.4 +++ b/share/man/man4/mac.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd October 30, 2007 -.Os .Dt MAC 4 +.Os .Sh NAME .Nm mac .Nd Mandatory Access Control diff --git a/share/man/man4/mac_biba.4 b/share/man/man4/mac_biba.4 index 20a66615e5f..265f5710edc 100644 --- a/share/man/man4/mac_biba.4 +++ b/share/man/man4/mac_biba.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd November 18, 2002 -.Os .Dt MAC_BIBA 4 +.Os .Sh NAME .Nm mac_biba .Nd "Biba data integrity policy" diff --git a/share/man/man4/mac_bsdextended.4 b/share/man/man4/mac_bsdextended.4 index 899990c34a1..23b89c04d04 100644 --- a/share/man/man4/mac_bsdextended.4 +++ b/share/man/man4/mac_bsdextended.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd May 21, 2005 -.Os .Dt MAC_BSDEXTENDED 4 +.Os .Sh NAME .Nm mac_bsdextended .Nd "file system firewall policy" diff --git a/share/man/man4/mac_ifoff.4 b/share/man/man4/mac_ifoff.4 index ede13b0fac5..87c73b25088 100644 --- a/share/man/man4/mac_ifoff.4 +++ b/share/man/man4/mac_ifoff.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 10, 2002 -.Os .Dt MAC_IFOFF 4 +.Os .Sh NAME .Nm mac_ifoff .Nd "interface silencing policy" diff --git a/share/man/man4/mac_lomac.4 b/share/man/man4/mac_lomac.4 index 8133ad8a833..8ae8875acb4 100644 --- a/share/man/man4/mac_lomac.4 +++ b/share/man/man4/mac_lomac.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 11, 2002 -.Os .Dt MAC_LOMAC 4 +.Os .Sh NAME .Nm mac_lomac .Nd "Low-watermark Mandatory Access Control data integrity policy" diff --git a/share/man/man4/mac_mls.4 b/share/man/man4/mac_mls.4 index 921781adf1e..b314fb5ca3a 100644 --- a/share/man/man4/mac_mls.4 +++ b/share/man/man4/mac_mls.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 1, 2002 -.Os .Dt MAC_MLS 4 +.Os .Sh NAME .Nm mac_mls .Nd "Multi-Level Security confidentiality policy" diff --git a/share/man/man4/mac_none.4 b/share/man/man4/mac_none.4 index 159151e5338..8f4602935ac 100644 --- a/share/man/man4/mac_none.4 +++ b/share/man/man4/mac_none.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 1, 2002 -.Os .Dt MAC_NONE 4 +.Os .Sh NAME .Nm mac_none .Nd "null MAC policy module" diff --git a/share/man/man4/mac_partition.4 b/share/man/man4/mac_partition.4 index 54abee5ae7b..296635edaf0 100644 --- a/share/man/man4/mac_partition.4 +++ b/share/man/man4/mac_partition.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 9, 2002 -.Os .Dt MAC_PARTITION 4 +.Os .Sh NAME .Nm mac_partition .Nd "process partition policy" diff --git a/share/man/man4/mac_seeotheruids.4 b/share/man/man4/mac_seeotheruids.4 index 4eeb7bba9eb..c870ca00d3e 100644 --- a/share/man/man4/mac_seeotheruids.4 +++ b/share/man/man4/mac_seeotheruids.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd October 6, 2005 -.Os .Dt MAC_SEEOTHERUIDS 4 +.Os .Sh NAME .Nm mac_seeotheruids .Nd "simple policy controlling whether users see other users" diff --git a/share/man/man4/mac_stub.4 b/share/man/man4/mac_stub.4 index ded95e2c081..79326df3649 100644 --- a/share/man/man4/mac_stub.4 +++ b/share/man/man4/mac_stub.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 1, 2002 -.Os .Dt MAC_STUB 4 +.Os .Sh NAME .Nm mac_stub .Nd "MAC policy stub module" diff --git a/share/man/man4/mac_test.4 b/share/man/man4/mac_test.4 index dde744589a2..e86d4bd0f14 100644 --- a/share/man/man4/mac_test.4 +++ b/share/man/man4/mac_test.4 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd December 1, 2002 -.Os .Dt MAC_TEST 4 +.Os .Sh NAME .Nm mac_test .Nd MAC framework testing policy diff --git a/share/man/man4/ng_netflow.4 b/share/man/man4/ng_netflow.4 index d1ef2048226..5c5c8e0ccfd 100644 --- a/share/man/man4/ng_netflow.4 +++ b/share/man/man4/ng_netflow.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd October 8, 2008 -.Os .Dt NG_NETFLOW 4 +.Os .Sh NAME .Nm ng_netflow .Nd Cisco's NetFlow implementation diff --git a/share/man/man4/orm.4 b/share/man/man4/orm.4 index 2ef54a0b5d3..2922cb68ead 100644 --- a/share/man/man4/orm.4 +++ b/share/man/man4/orm.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd December 15, 2000 -.Os .Dt ORM 4 +.Os .Sh NAME .Nm orm .Nd ISA I/O space option ROM(s) driver diff --git a/share/man/man4/ral.4 b/share/man/man4/ral.4 index 2fd8e3355cb..25fb343a0b4 100644 --- a/share/man/man4/ral.4 +++ b/share/man/man4/ral.4 @@ -16,8 +16,8 @@ .\" $FreeBSD$ .\" .Dd July 8, 2009 -.Os .Dt RAL 4 +.Os .Sh NAME .Nm ral .Nd "Ralink Technology IEEE 802.11 wireless network driver" diff --git a/share/man/man4/rp.4 b/share/man/man4/rp.4 index 8f0f425c662..a894f1242c7 100644 --- a/share/man/man4/rp.4 +++ b/share/man/man4/rp.4 @@ -3,8 +3,8 @@ .\" .\" $FreeBSD$ .Dd November 15, 1995 -.Os .Dt RP 4 +.Os .Sh NAME .Nm rp .Nd "driver for Comtrol RocketPort Intelligent Serial Port Cards" diff --git a/share/man/man4/rum.4 b/share/man/man4/rum.4 index cbbbcd0962b..82e25f5c3b9 100644 --- a/share/man/man4/rum.4 +++ b/share/man/man4/rum.4 @@ -17,8 +17,8 @@ .\" $FreeBSD$ .\" .Dd April 13, 2008 -.Os .Dt RUM 4 +.Os .Sh NAME .Nm rum .Nd Ralink Technology USB IEEE 802.11a/b/g wireless network device diff --git a/share/man/man4/run.4 b/share/man/man4/run.4 index e613649e853..a7c6f4deeaf 100644 --- a/share/man/man4/run.4 +++ b/share/man/man4/run.4 @@ -17,8 +17,8 @@ .\" $FreeBSD$ .\" .Dd January 29, 2010 -.Os .Dt RUN 4 +.Os .Sh NAME .Nm run .Nd Ralink Technology USB IEEE 802.11a/g/n wireless network device diff --git a/share/man/man4/sched_4bsd.4 b/share/man/man4/sched_4bsd.4 index 9533cae0055..a02c40eb58a 100644 --- a/share/man/man4/sched_4bsd.4 +++ b/share/man/man4/sched_4bsd.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd January 21, 2008 -.Os .Dt SCHED_4BSD 4 +.Os .Sh NAME .Nm sched_4bsd .Nd "4.4BSD scheduler" diff --git a/share/man/man4/sched_ule.4 b/share/man/man4/sched_ule.4 index c5ce58b57c7..fdb96f1c828 100644 --- a/share/man/man4/sched_ule.4 +++ b/share/man/man4/sched_ule.4 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd January 21, 2008 -.Os .Dt SCHED_ULE 4 +.Os .Sh NAME .Nm sched_ule .Nd ULE scheduler diff --git a/share/man/man4/si.4 b/share/man/man4/si.4 index 65176bdb78b..5eb7629d979 100644 --- a/share/man/man4/si.4 +++ b/share/man/man4/si.4 @@ -1,7 +1,7 @@ .\" $FreeBSD$ .Dd September 16, 1995 -.Os .Dt SI 4 +.Os .Sh NAME .Nm si .Nd "driver for Specialix International SI/XIO or SX intelligent serial card" diff --git a/share/man/man4/tap.4 b/share/man/man4/tap.4 index 9f047257289..a306108af63 100644 --- a/share/man/man4/tap.4 +++ b/share/man/man4/tap.4 @@ -2,8 +2,8 @@ .\" Based on PR#2411 .\" .Dd September 8, 2008 -.Os .Dt TAP 4 +.Os .Sh NAME .Nm tap .Nd Ethernet tunnel software network interface diff --git a/share/man/man4/uhso.4 b/share/man/man4/uhso.4 index 7f10c6212a3..e4d6df5b2aa 100644 --- a/share/man/man4/uhso.4 +++ b/share/man/man4/uhso.4 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd January 14, 2010 -.Os .Dt UHSO 4 +.Os .Sh NAME .Nm uhso .Nd support for several HSxPA devices from Option N.V. diff --git a/share/man/man4/upgt.4 b/share/man/man4/upgt.4 index 39dee55c716..06c5eb57f76 100644 --- a/share/man/man4/upgt.4 +++ b/share/man/man4/upgt.4 @@ -50,8 +50,8 @@ .\" SUCH DAMAGE. .\" .Dd April 17, 2008 -.Os .Dt UPGT 4 +.Os .Sh NAME .Nm upgt .Nd Conexant/Intersil PrismGT SoftMAC USB IEEE 802.11b/g wireless network diff --git a/share/man/man4/ural.4 b/share/man/man4/ural.4 index 053ae704a3c..3825166ffa8 100644 --- a/share/man/man4/ural.4 +++ b/share/man/man4/ural.4 @@ -16,8 +16,8 @@ .\" $FreeBSD$ .\" .Dd April 13, 2008 -.Os .Dt URAL 4 +.Os .Sh NAME .Nm ural .Nd "Ralink Technology RT2500USB IEEE 802.11 driver" diff --git a/share/man/man4/vkbd.4 b/share/man/man4/vkbd.4 index bdaa941531c..079688f6bb0 100644 --- a/share/man/man4/vkbd.4 +++ b/share/man/man4/vkbd.4 @@ -2,8 +2,8 @@ .\" $FreeBSD$ .\" .Dd August 12, 2004 -.Os .Dt VKBD 4 +.Os .Sh NAME .Nm vkbd .Nd the virtual AT keyboard interface diff --git a/share/man/man4/wpi.4 b/share/man/man4/wpi.4 index f424d74a3c7..07e88169827 100644 --- a/share/man/man4/wpi.4 +++ b/share/man/man4/wpi.4 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd October 5, 2008 -.Os .Dt WPI 4 +.Os .Sh NAME .Nm wpi .Nd "Intel 3945ABG Wireless LAN IEEE 802.11 driver" diff --git a/share/man/man5/ar.5 b/share/man/man5/ar.5 index 58d2d788701..dc802cee79c 100644 --- a/share/man/man5/ar.5 +++ b/share/man/man5/ar.5 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 7, 2007 -.Os .Dt AR 5 +.Os .Sh NAME .Nm ar .Nd format of archives managed by ar(1) and ranlib(1) diff --git a/share/man/man7/clocks.7 b/share/man/man7/clocks.7 index 700a79f33da..692796842ed 100644 --- a/share/man/man7/clocks.7 +++ b/share/man/man7/clocks.7 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" " .Dd January 18, 2008 -.Os .Dt CLOCKS 7 +.Os .Sh NAME .Nm clocks .Nd various system timers diff --git a/share/man/man7/maclabel.7 b/share/man/man7/maclabel.7 index 05c3654aa9e..0648fb565c9 100644 --- a/share/man/man7/maclabel.7 +++ b/share/man/man7/maclabel.7 @@ -34,8 +34,8 @@ .\" $FreeBSD$ .\" .Dd October 25, 2002 -.Os .Dt MACLABEL 7 +.Os .Sh NAME .Nm maclabel .Nd Mandatory Access Control label format diff --git a/share/man/man8/picobsd.8 b/share/man/man8/picobsd.8 index 1ce50b3386b..c6c6c948ea8 100644 --- a/share/man/man8/picobsd.8 +++ b/share/man/man8/picobsd.8 @@ -1,8 +1,8 @@ .\" -*- nroff-fill -*- .\" $FreeBSD$ .Dd June 25, 2009 -.Os .Dt PICOBSD 8 +.Os .Sh NAME .Nm picobsd .Nd building small FreeBSD disk images diff --git a/share/man/man8/rescue.8 b/share/man/man8/rescue.8 index 685827f3d59..29218874d67 100644 --- a/share/man/man8/rescue.8 +++ b/share/man/man8/rescue.8 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd July 23, 2003 -.Os .Dt RESCUE 8 +.Os .Sh NAME .Nm rescue .Nd rescue utilities in diff --git a/share/man/man9/CTASSERT.9 b/share/man/man9/CTASSERT.9 index db1ad49ee77..4885d4248b8 100644 --- a/share/man/man9/CTASSERT.9 +++ b/share/man/man9/CTASSERT.9 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd September 5, 2008 -.Os .Dt CTASSERT 9 +.Os .Sh NAME .Nm CTASSERT .Nd compile time assertion macro diff --git a/share/man/man9/DELAY.9 b/share/man/man9/DELAY.9 index ac6231c2bc7..58b2a07e8b6 100644 --- a/share/man/man9/DELAY.9 +++ b/share/man/man9/DELAY.9 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd November 21, 2000 -.Os .Dt DELAY 9 +.Os .Sh NAME .Nm DELAY .Nd busy loop for an interval diff --git a/share/man/man9/KASSERT.9 b/share/man/man9/KASSERT.9 index e53e9b605a8..62c97c44bd5 100644 --- a/share/man/man9/KASSERT.9 +++ b/share/man/man9/KASSERT.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd January 14, 2000 -.Os .Dt KASSERT 9 +.Os .Sh NAME .Nm KASSERT .Nd kernel expression verification macro diff --git a/share/man/man9/VFS.9 b/share/man/man9/VFS.9 index 30f89189bf2..ca3109b5b48 100644 --- a/share/man/man9/VFS.9 +++ b/share/man/man9/VFS.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd February 9, 2010 -.Os .Dt VFS 9 +.Os .Sh NAME .Nm VFS .Nd kernel interface to file systems diff --git a/share/man/man9/VFS_CHECKEXP.9 b/share/man/man9/VFS_CHECKEXP.9 index 92afda86d69..62d545c753e 100644 --- a/share/man/man9/VFS_CHECKEXP.9 +++ b/share/man/man9/VFS_CHECKEXP.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd January 4, 2010 -.Os .Dt VFS_CHECKEXP 9 +.Os .Sh NAME .Nm VFS_CHECKEXP .Nd check if a file system is exported to a client diff --git a/share/man/man9/VFS_FHTOVP.9 b/share/man/man9/VFS_FHTOVP.9 index f6f88d204ee..39a6168f51b 100644 --- a/share/man/man9/VFS_FHTOVP.9 +++ b/share/man/man9/VFS_FHTOVP.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd January 4, 2010 -.Os .Dt VFS_FHTOVP 9 +.Os .Sh NAME .Nm VFS_FHTOVP .Nd turn an NFS filehandle into a vnode diff --git a/share/man/man9/VFS_MOUNT.9 b/share/man/man9/VFS_MOUNT.9 index 4856dc49ea8..e46c71a5825 100644 --- a/share/man/man9/VFS_MOUNT.9 +++ b/share/man/man9/VFS_MOUNT.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd May 23, 2009 -.Os .Dt VFS_MOUNT 9 +.Os .Sh NAME .Nm VFS_MOUNT .Nd mount a file system diff --git a/share/man/man9/VFS_QUOTACTL.9 b/share/man/man9/VFS_QUOTACTL.9 index 48ff866c211..fded4d6b883 100644 --- a/share/man/man9/VFS_QUOTACTL.9 +++ b/share/man/man9/VFS_QUOTACTL.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd May 23, 2009 -.Os .Dt VFS_QUOTACTL 9 +.Os .Sh NAME .Nm VFS_QUOTACTL .Nd manipulate file system quotas diff --git a/share/man/man9/VFS_ROOT.9 b/share/man/man9/VFS_ROOT.9 index 2490cfc0bda..f81a500b3ab 100644 --- a/share/man/man9/VFS_ROOT.9 +++ b/share/man/man9/VFS_ROOT.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd May 23, 2009 -.Os .Dt VFS_ROOT 9 +.Os .Sh NAME .Nm VFS_ROOT .Nd return the root vnode of a file system diff --git a/share/man/man9/VFS_STATFS.9 b/share/man/man9/VFS_STATFS.9 index 80d0d6652a5..7a7e3714112 100644 --- a/share/man/man9/VFS_STATFS.9 +++ b/share/man/man9/VFS_STATFS.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd May 23, 2009 -.Os .Dt VFS_STATFS 9 +.Os .Sh NAME .Nm VFS_STATFS .Nd return file system status diff --git a/share/man/man9/VFS_SYNC.9 b/share/man/man9/VFS_SYNC.9 index 60947a24709..ed510dd7b66 100644 --- a/share/man/man9/VFS_SYNC.9 +++ b/share/man/man9/VFS_SYNC.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd May 23, 2009 -.Os .Dt VFS_SYNC 9 +.Os .Sh NAME .Nm VFS_SYNC .Nd flush unwritten data diff --git a/share/man/man9/VFS_UNMOUNT.9 b/share/man/man9/VFS_UNMOUNT.9 index 676685d4a4b..59113ee174d 100644 --- a/share/man/man9/VFS_UNMOUNT.9 +++ b/share/man/man9/VFS_UNMOUNT.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd May 23, 2009 -.Os .Dt VFS_UNMOUNT 9 +.Os .Sh NAME .Nm VFS_UNMOUNT .Nd unmount a file system diff --git a/share/man/man9/VFS_VGET.9 b/share/man/man9/VFS_VGET.9 index 02b55364127..22c902fd694 100644 --- a/share/man/man9/VFS_VGET.9 +++ b/share/man/man9/VFS_VGET.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd January 7, 2005 -.Os .Dt VFS_VGET 9 +.Os .Sh NAME .Nm VFS_VGET .Nd convert an inode number to a vnode diff --git a/share/man/man9/VOP_ACCESS.9 b/share/man/man9/VOP_ACCESS.9 index 927c1187ce1..005f2e20e57 100644 --- a/share/man/man9/VOP_ACCESS.9 +++ b/share/man/man9/VOP_ACCESS.9 @@ -30,8 +30,8 @@ .\" $FreeBSD$ .\" .Dd September 18, 2009 -.Os .Dt VOP_ACCESS 9 +.Os .Sh NAME .Nm VOP_ACCESS , .Nm VOP_ACCESSX diff --git a/share/man/man9/VOP_ACLCHECK.9 b/share/man/man9/VOP_ACLCHECK.9 index 62102281ce7..36381121337 100644 --- a/share/man/man9/VOP_ACLCHECK.9 +++ b/share/man/man9/VOP_ACLCHECK.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 23, 1999 -.Os .Dt VOP_ACLCHECK 9 +.Os .Sh NAME .Nm VOP_ACLCHECK .Nd check an access control list for a vnode diff --git a/share/man/man9/VOP_ADVLOCK.9 b/share/man/man9/VOP_ADVLOCK.9 index bdb00b7070e..3dabc59ea49 100644 --- a/share/man/man9/VOP_ADVLOCK.9 +++ b/share/man/man9/VOP_ADVLOCK.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd June 30, 1999 -.Os .Dt VOP_ADVLOCK 9 +.Os .Sh NAME .Nm VOP_ADVLOCK .Nd advisory record locking diff --git a/share/man/man9/VOP_ATTRIB.9 b/share/man/man9/VOP_ATTRIB.9 index f14b1a5d20b..e48e4eb9a25 100644 --- a/share/man/man9/VOP_ATTRIB.9 +++ b/share/man/man9/VOP_ATTRIB.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd August 29, 2008 -.Os .Dt VOP_ATTRIB 9 +.Os .Sh NAME .Nm VOP_GETATTR , .Nm VOP_SETATTR diff --git a/share/man/man9/VOP_BWRITE.9 b/share/man/man9/VOP_BWRITE.9 index 0b8f7e0e1c6..d2ee5105166 100644 --- a/share/man/man9/VOP_BWRITE.9 +++ b/share/man/man9/VOP_BWRITE.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_BWRITE 9 +.Os .Sh NAME .Nm VOP_BWRITE .Nd write a file system buffer diff --git a/share/man/man9/VOP_CREATE.9 b/share/man/man9/VOP_CREATE.9 index 2f30328d2b0..b86a88dce11 100644 --- a/share/man/man9/VOP_CREATE.9 +++ b/share/man/man9/VOP_CREATE.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_CREATE 9 +.Os .Sh NAME .Nm VOP_CREATE , .Nm VOP_MKNOD , diff --git a/share/man/man9/VOP_FSYNC.9 b/share/man/man9/VOP_FSYNC.9 index 54398137c44..e457f846640 100644 --- a/share/man/man9/VOP_FSYNC.9 +++ b/share/man/man9/VOP_FSYNC.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_FSYNC 9 +.Os .Sh NAME .Nm VOP_FSYNC .Nd flush file system buffers for a file diff --git a/share/man/man9/VOP_GETACL.9 b/share/man/man9/VOP_GETACL.9 index ba819085bb7..d2303408101 100644 --- a/share/man/man9/VOP_GETACL.9 +++ b/share/man/man9/VOP_GETACL.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 23, 1999 -.Os .Dt VOP_GETACL 9 +.Os .Sh NAME .Nm VOP_GETACL .Nd retrieve access control list for a vnode diff --git a/share/man/man9/VOP_GETEXTATTR.9 b/share/man/man9/VOP_GETEXTATTR.9 index 0971c27a295..cf00d26f48f 100644 --- a/share/man/man9/VOP_GETEXTATTR.9 +++ b/share/man/man9/VOP_GETEXTATTR.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 23, 1999 -.Os .Dt VOP_GETEXTATTR 9 +.Os .Sh NAME .Nm VOP_GETEXTATTR .Nd retrieve named extended attribute from a vnode diff --git a/share/man/man9/VOP_GETPAGES.9 b/share/man/man9/VOP_GETPAGES.9 index ffac609de13..ab0afe8be09 100644 --- a/share/man/man9/VOP_GETPAGES.9 +++ b/share/man/man9/VOP_GETPAGES.9 @@ -30,8 +30,8 @@ .\" $FreeBSD$ .\" .Dd September 27, 2003 -.Os .Dt VOP_GETPAGES 9 +.Os .Sh NAME .Nm VOP_GETPAGES , .Nm VOP_PUTPAGES diff --git a/share/man/man9/VOP_GETVOBJECT.9 b/share/man/man9/VOP_GETVOBJECT.9 index e2e0ba471a8..2490da710b5 100644 --- a/share/man/man9/VOP_GETVOBJECT.9 +++ b/share/man/man9/VOP_GETVOBJECT.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd September 10, 2000 -.Os .Dt VOP_CREATEVOBJECT 9 +.Os .Sh NAME .Nm VOP_CREATEVOBJECT , .Nm VOP_DESTROYVOBJECT , diff --git a/share/man/man9/VOP_INACTIVE.9 b/share/man/man9/VOP_INACTIVE.9 index 75bd53b8919..2f1e4ed60bd 100644 --- a/share/man/man9/VOP_INACTIVE.9 +++ b/share/man/man9/VOP_INACTIVE.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_INACTIVE 9 +.Os .Sh NAME .Nm VOP_INACTIVE , .Nm VOP_RECLAIM diff --git a/share/man/man9/VOP_IOCTL.9 b/share/man/man9/VOP_IOCTL.9 index 7b45484056c..ba1208179fc 100644 --- a/share/man/man9/VOP_IOCTL.9 +++ b/share/man/man9/VOP_IOCTL.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_IOCTL 9 +.Os .Sh NAME .Nm VOP_IOCTL .Nd device specific control diff --git a/share/man/man9/VOP_LINK.9 b/share/man/man9/VOP_LINK.9 index b7fbb7bd227..f5b7c68e704 100644 --- a/share/man/man9/VOP_LINK.9 +++ b/share/man/man9/VOP_LINK.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_LINK 9 +.Os .Sh NAME .Nm VOP_LINK .Nd create a new name for a file diff --git a/share/man/man9/VOP_LISTEXTATTR.9 b/share/man/man9/VOP_LISTEXTATTR.9 index 4c8b744efcf..cca875d68ee 100644 --- a/share/man/man9/VOP_LISTEXTATTR.9 +++ b/share/man/man9/VOP_LISTEXTATTR.9 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd August 19, 2005 -.Os .Dt VOP_LISTEXTATTR 9 +.Os .Sh NAME .Nm VOP_LISTEXTATTR .Nd retrieve a list of named extended attribute from a vnode diff --git a/share/man/man9/VOP_LOCK.9 b/share/man/man9/VOP_LOCK.9 index 6c54a38df5b..b4fdc7ac72b 100644 --- a/share/man/man9/VOP_LOCK.9 +++ b/share/man/man9/VOP_LOCK.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd February 25, 2008 -.Os .Dt VOP_LOCK 9 +.Os .Sh NAME .Nm VOP_LOCK , .Nm VOP_UNLOCK , diff --git a/share/man/man9/VOP_LOOKUP.9 b/share/man/man9/VOP_LOOKUP.9 index ba5a260d36b..64023f4a9e6 100644 --- a/share/man/man9/VOP_LOOKUP.9 +++ b/share/man/man9/VOP_LOOKUP.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd November 24, 1997 -.Os .Dt VOP_LOOKUP 9 +.Os .Sh NAME .Nm VOP_LOOKUP .Nd lookup a component of a pathname diff --git a/share/man/man9/VOP_OPENCLOSE.9 b/share/man/man9/VOP_OPENCLOSE.9 index 7430da70f3e..5442e3277f4 100644 --- a/share/man/man9/VOP_OPENCLOSE.9 +++ b/share/man/man9/VOP_OPENCLOSE.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd December 2, 2009 -.Os .Dt VOP_OPEN 9 +.Os .Sh NAME .Nm VOP_OPEN , .Nm VOP_CLOSE diff --git a/share/man/man9/VOP_PATHCONF.9 b/share/man/man9/VOP_PATHCONF.9 index 056f6479a83..38fed835002 100644 --- a/share/man/man9/VOP_PATHCONF.9 +++ b/share/man/man9/VOP_PATHCONF.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_PATHCONF 9 +.Os .Sh NAME .Nm VOP_PATHCONF .Nd return POSIX pathconf information diff --git a/share/man/man9/VOP_PRINT.9 b/share/man/man9/VOP_PRINT.9 index 2da85f9a9d7..c8188fc0263 100644 --- a/share/man/man9/VOP_PRINT.9 +++ b/share/man/man9/VOP_PRINT.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_PRINT 9 +.Os .Sh NAME .Nm VOP_PRINT .Nd print debugging information diff --git a/share/man/man9/VOP_RDWR.9 b/share/man/man9/VOP_RDWR.9 index b0105236785..eb1af784207 100644 --- a/share/man/man9/VOP_RDWR.9 +++ b/share/man/man9/VOP_RDWR.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_RDWR 9 +.Os .Sh NAME .Nm VOP_READ , .Nm VOP_WRITE diff --git a/share/man/man9/VOP_READDIR.9 b/share/man/man9/VOP_READDIR.9 index 5b944381162..057600e914d 100644 --- a/share/man/man9/VOP_READDIR.9 +++ b/share/man/man9/VOP_READDIR.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_READDIR 9 +.Os .Sh NAME .Nm VOP_READDIR .Nd read contents of a directory diff --git a/share/man/man9/VOP_READLINK.9 b/share/man/man9/VOP_READLINK.9 index f98222f2fb1..c1883c1e99c 100644 --- a/share/man/man9/VOP_READLINK.9 +++ b/share/man/man9/VOP_READLINK.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_READLINK 9 +.Os .Sh NAME .Nm VOP_READLINK .Nd read the target of a symbolic link diff --git a/share/man/man9/VOP_REALLOCBLKS.9 b/share/man/man9/VOP_REALLOCBLKS.9 index 9209844eb8d..d38caf16d72 100644 --- a/share/man/man9/VOP_REALLOCBLKS.9 +++ b/share/man/man9/VOP_REALLOCBLKS.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_REALLOCBLKS 9 +.Os .Sh NAME .Nm VOP_REALLOCBLKS .Nd rearrange blocks in a file to be contiguous diff --git a/share/man/man9/VOP_REMOVE.9 b/share/man/man9/VOP_REMOVE.9 index 0a10ed222dc..38e3b060bc5 100644 --- a/share/man/man9/VOP_REMOVE.9 +++ b/share/man/man9/VOP_REMOVE.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_REMOVE 9 +.Os .Sh NAME .Nm VOP_REMOVE , .Nm VOP_RMDIR diff --git a/share/man/man9/VOP_RENAME.9 b/share/man/man9/VOP_RENAME.9 index 87975852959..76bb0dc1a1c 100644 --- a/share/man/man9/VOP_RENAME.9 +++ b/share/man/man9/VOP_RENAME.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_RENAME 9 +.Os .Sh NAME .Nm VOP_RENAME .Nd rename a file diff --git a/share/man/man9/VOP_REVOKE.9 b/share/man/man9/VOP_REVOKE.9 index 6e040143534..3557ce1109e 100644 --- a/share/man/man9/VOP_REVOKE.9 +++ b/share/man/man9/VOP_REVOKE.9 @@ -35,8 +35,8 @@ .\" $FreeBSD$ .\" .Dd February 5, 2002 -.Os .Dt VOP_REVOKE 9 +.Os .Sh NAME .Nm VOP_REVOKE .Nd "revoke access to a device and its aliases" diff --git a/share/man/man9/VOP_SETACL.9 b/share/man/man9/VOP_SETACL.9 index b6a7003a86b..482d2898034 100644 --- a/share/man/man9/VOP_SETACL.9 +++ b/share/man/man9/VOP_SETACL.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 23, 1999 -.Os .Dt VOP_SETACL 9 +.Os .Sh NAME .Nm VOP_SETACL .Nd set the access control list for a vnode diff --git a/share/man/man9/VOP_SETEXTATTR.9 b/share/man/man9/VOP_SETEXTATTR.9 index ccb8aaad0fb..4bc53877b5a 100644 --- a/share/man/man9/VOP_SETEXTATTR.9 +++ b/share/man/man9/VOP_SETEXTATTR.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 23, 1999 -.Os .Dt VOP_SETEXTATTR 9 +.Os .Sh NAME .Nm VOP_SETEXTATTR .Nd set named extended attribute for a vnode diff --git a/share/man/man9/VOP_STRATEGY.9 b/share/man/man9/VOP_STRATEGY.9 index 8c4fbace42a..33d9fb8c146 100644 --- a/share/man/man9/VOP_STRATEGY.9 +++ b/share/man/man9/VOP_STRATEGY.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VOP_STRATEGY 9 +.Os .Sh NAME .Nm VOP_STRATEGY .Nd read or write a file system buffer diff --git a/share/man/man9/VOP_VPTOCNP.9 b/share/man/man9/VOP_VPTOCNP.9 index 892b4a64ae0..78582151381 100644 --- a/share/man/man9/VOP_VPTOCNP.9 +++ b/share/man/man9/VOP_VPTOCNP.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd December 7, 2008 -.Os .Dt VOP_VPTOCNP 9 +.Os .Sh NAME .Nm VOP_VPTOCNP .Nd translate a vnode to its component name diff --git a/share/man/man9/VOP_VPTOFH.9 b/share/man/man9/VOP_VPTOFH.9 index 36e703d7958..3619a7b065a 100644 --- a/share/man/man9/VOP_VPTOFH.9 +++ b/share/man/man9/VOP_VPTOFH.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd February 16, 2007 -.Os .Dt VOP_VPTOFH 9 +.Os .Sh NAME .Nm VOP_VPTOFH .Nd turn a vnode into an NFS filehandle diff --git a/share/man/man9/accept_filter.9 b/share/man/man9/accept_filter.9 index 4a7d239f86d..3f89a0cdf7d 100644 --- a/share/man/man9/accept_filter.9 +++ b/share/man/man9/accept_filter.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd June 25, 2000 -.Os .Dt ACCEPT_FILTER 9 +.Os .Sh NAME .Nm accept_filter , .Nm accept_filt_add , diff --git a/share/man/man9/accf_data.9 b/share/man/man9/accf_data.9 index 836deba17a6..2d3b7a24d69 100644 --- a/share/man/man9/accf_data.9 +++ b/share/man/man9/accf_data.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd November 15, 2000 -.Os .Dt ACCF_DATA 9 +.Os .Sh NAME .Nm accf_data .Nd buffer incoming connections until data arrives diff --git a/share/man/man9/accf_dns.9 b/share/man/man9/accf_dns.9 index f4b1563bb73..4a2dad25066 100644 --- a/share/man/man9/accf_dns.9 +++ b/share/man/man9/accf_dns.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd July 16, 2008 -.Os .Dt ACCF_DNS 9 +.Os .Sh NAME .Nm accf_dns .Nd buffer incoming DNS requests until the whole first request is present diff --git a/share/man/man9/accf_http.9 b/share/man/man9/accf_http.9 index a75321c9b1b..2a340605ecf 100644 --- a/share/man/man9/accf_http.9 +++ b/share/man/man9/accf_http.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" " .Dd November 15, 2000 -.Os .Dt ACCF_HTTP 9 +.Os .Sh NAME .Nm accf_http .Nd "buffer incoming connections until a certain complete HTTP requests arrive" diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9 index c5192fc8b14..21640bd7b86 100644 --- a/share/man/man9/acl.9 +++ b/share/man/man9/acl.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd September 18, 2009 -.Os .Dt ACL 9 +.Os .Sh NAME .Nm acl .Nd virtual file system access control lists diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9 index 0bc567c4b9b..94c4ba4d0e0 100644 --- a/share/man/man9/atomic.9 +++ b/share/man/man9/atomic.9 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd September 27, 2005 -.Os .Dt ATOMIC 9 +.Os .Sh NAME .Nm atomic_add , .Nm atomic_clear , diff --git a/share/man/man9/cr_cansee.9 b/share/man/man9/cr_cansee.9 index 53823c16371..c4cc2d4a861 100644 --- a/share/man/man9/cr_cansee.9 +++ b/share/man/man9/cr_cansee.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd November 19, 2006 -.Os .Dt CR_CANSEE 9 +.Os .Sh NAME .Nm cr_cansee .Nd "determine visibility of objects given their user credentials" diff --git a/share/man/man9/cr_seeothergids.9 b/share/man/man9/cr_seeothergids.9 index 1f5f4ee05db..87fd1396226 100644 --- a/share/man/man9/cr_seeothergids.9 +++ b/share/man/man9/cr_seeothergids.9 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd November 11, 2003 -.Os .Dt CR_SEEOTHERGIDS 9 +.Os .Sh NAME .Nm cr_seeothergids .Nd determine visibility of objects given their group memberships diff --git a/share/man/man9/cr_seeotheruids.9 b/share/man/man9/cr_seeotheruids.9 index e79363f225e..2066c405e55 100644 --- a/share/man/man9/cr_seeotheruids.9 +++ b/share/man/man9/cr_seeotheruids.9 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd November 11, 2003 -.Os .Dt CR_SEEOTHERUIDS 9 +.Os .Sh NAME .Nm cr_seeotheruids .Nd determine visibility of objects given their user credentials diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9 index 0896d4de081..fcdc5c4fd41 100644 --- a/share/man/man9/devfs_set_cdevpriv.9 +++ b/share/man/man9/devfs_set_cdevpriv.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd September 8, 2008 -.Os .Dt DEVFS_CDEVPRIV +.Os .Sh NAME .Nm devfs_set_cdevpriv , .Nm devfs_get_cdevpriv , diff --git a/share/man/man9/devtoname.9 b/share/man/man9/devtoname.9 index 9a62a5ededb..f93e77bccc0 100644 --- a/share/man/man9/devtoname.9 +++ b/share/man/man9/devtoname.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd September 25, 1999 -.Os .Dt DEVTONAME 9 +.Os .Sh NAME .Nm devtoname .Nd "converts dev_t data into a string indicating the device name" diff --git a/share/man/man9/extattr.9 b/share/man/man9/extattr.9 index 9c74a60bf9b..bf79487f8bf 100644 --- a/share/man/man9/extattr.9 +++ b/share/man/man9/extattr.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 23, 1999 -.Os .Dt EXTATTR 9 +.Os .Sh NAME .Nm extattr .Nd virtual file system named extended attributes diff --git a/share/man/man9/firmware.9 b/share/man/man9/firmware.9 index 87d43e3205a..5254f2448ad 100644 --- a/share/man/man9/firmware.9 +++ b/share/man/man9/firmware.9 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 2, 2008 -.Os .Dt FIRMWARE 9 +.Os .Sh NAME .Nm firmware_register , .Nm firmware_unregister , diff --git a/share/man/man9/hexdump.9 b/share/man/man9/hexdump.9 index 656299cd561..a731ab51ab9 100644 --- a/share/man/man9/hexdump.9 +++ b/share/man/man9/hexdump.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd December 7, 2003 -.Os .Dt HEXDUMP 9 +.Os .Sh NAME .Nm hexdump .Nd "dump a block of bytes to the console in hexadecimal form" diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9 index 7a3a3d9d9e9..55e75418536 100644 --- a/share/man/man9/ifnet.9 +++ b/share/man/man9/ifnet.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd December 1, 2009 -.Os .Dt IFNET 9 +.Os .Sh NAME .Nm ifnet , .Nm ifaddr , diff --git a/share/man/man9/make_dev.9 b/share/man/man9/make_dev.9 index b39ca8b833e..50f7d46fc6c 100644 --- a/share/man/man9/make_dev.9 +++ b/share/man/man9/make_dev.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd September 28, 2008 -.Os .Dt MAKE_DEV 9 +.Os .Sh NAME .Nm make_dev , .Nm make_dev_cred , diff --git a/share/man/man9/namei.9 b/share/man/man9/namei.9 index 0325c36fa58..33f753f1449 100644 --- a/share/man/man9/namei.9 +++ b/share/man/man9/namei.9 @@ -34,8 +34,8 @@ .\" $FreeBSD$ .\" .Dd September 21, 2005 -.Os .Dt NAMEI 9 +.Os .Sh NAME .Nm namei , .Nm NDINIT , diff --git a/share/man/man9/p_candebug.9 b/share/man/man9/p_candebug.9 index 2127fbc4a28..6249a4de410 100644 --- a/share/man/man9/p_candebug.9 +++ b/share/man/man9/p_candebug.9 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd November 19, 2006 -.Os .Dt P_CANDEBUG 9 +.Os .Sh NAME .Nm p_candebug .Nd determine debuggability of a process diff --git a/share/man/man9/p_cansee.9 b/share/man/man9/p_cansee.9 index 92ffeeaaa78..fafe9d3a1fb 100644 --- a/share/man/man9/p_cansee.9 +++ b/share/man/man9/p_cansee.9 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd November 19, 2006 -.Os .Dt P_CANSEE 9 +.Os .Sh NAME .Nm p_cansee .Nd determine visibility of a process diff --git a/share/man/man9/pfind.9 b/share/man/man9/pfind.9 index 58adab3fad3..dfd15b8dcf7 100644 --- a/share/man/man9/pfind.9 +++ b/share/man/man9/pfind.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd July 11, 2001 -.Os .Dt PFIND 9 +.Os .Sh NAME .Nm pfind , zpfind .Nd locate a process by number diff --git a/share/man/man9/pgfind.9 b/share/man/man9/pgfind.9 index 96abd0ae521..a3049876d72 100644 --- a/share/man/man9/pgfind.9 +++ b/share/man/man9/pgfind.9 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd August 8, 2001 -.Os .Dt PGFIND 9 +.Os .Sh NAME .Nm pgfind .Nd "locate a process group by number" diff --git a/share/man/man9/prison_check.9 b/share/man/man9/prison_check.9 index a8ba040131a..68e90fb7fef 100644 --- a/share/man/man9/prison_check.9 +++ b/share/man/man9/prison_check.9 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd December 11, 2003 -.Os .Dt PRISON_CHECK 9 +.Os .Sh NAME .Nm prison_check .Nd determine if two credentials belong to the same jail diff --git a/share/man/man9/random.9 b/share/man/man9/random.9 index 426774e9083..1d7c7daf089 100644 --- a/share/man/man9/random.9 +++ b/share/man/man9/random.9 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" " .Dd September 25, 2000 -.Os .Dt RANDOM 9 +.Os .Sh NAME .Nm arc4rand , .Nm arc4random , diff --git a/share/man/man9/rijndael.9 b/share/man/man9/rijndael.9 index 5ee423971de..48b402bc0f1 100644 --- a/share/man/man9/rijndael.9 +++ b/share/man/man9/rijndael.9 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" " .Dd February 6, 2002 -.Os .Dt RIJNDAEL 9 +.Os .Sh NAME .Nm rijndael_makeKey , .Nm rijndael_cipherInit , diff --git a/share/man/man9/rtalloc.9 b/share/man/man9/rtalloc.9 index cbd2c5eaab5..31d5ebbdf67 100644 --- a/share/man/man9/rtalloc.9 +++ b/share/man/man9/rtalloc.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd December 11, 2008 -.Os .Dt RTALLOC 9 +.Os .Sh NAME .Nm rtalloc , .Nm rtalloc_ign , diff --git a/share/man/man9/rtentry.9 b/share/man/man9/rtentry.9 index 0e25b21acfc..d7e6953f5f8 100644 --- a/share/man/man9/rtentry.9 +++ b/share/man/man9/rtentry.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd December 11, 2008 -.Os .Dt RTENTRY 9 +.Os .Sh NAME .Nm rtentry .Nd structure of an entry in the kernel routing table diff --git a/share/man/man9/sleep.9 b/share/man/man9/sleep.9 index 8fb7f88a320..91a212166bd 100644 --- a/share/man/man9/sleep.9 +++ b/share/man/man9/sleep.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd December 12, 2009 -.Os .Dt SLEEP 9 +.Os .Sh NAME .Nm msleep , .Nm msleep_spin , diff --git a/share/man/man9/spl.9 b/share/man/man9/spl.9 index fe4bec27f57..95a5fc25aff 100644 --- a/share/man/man9/spl.9 +++ b/share/man/man9/spl.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd July 21, 1996 -.Os .Dt SPL 9 +.Os .Sh NAME .Nm splbio , .Nm splclock , diff --git a/share/man/man9/uio.9 b/share/man/man9/uio.9 index b5c12cbe3bd..0ddb2d39f99 100644 --- a/share/man/man9/uio.9 +++ b/share/man/man9/uio.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd March 21, 2010 -.Os .Dt UIO 9 +.Os .Sh NAME .Nm uio , .Nm uiomove diff --git a/share/man/man9/usbdi.9 b/share/man/man9/usbdi.9 index 100c53c439b..a26e026640c 100644 --- a/share/man/man9/usbdi.9 +++ b/share/man/man9/usbdi.9 @@ -25,8 +25,8 @@ .\" .\" $FreeBSD$ .Dd June 24, 2009 -.Os .Dt USBDI 9 +.Os .Sh NAME .Nm usb_fifo_alloc_buffer , .Nm usb_fifo_attach , diff --git a/share/man/man9/vaccess.9 b/share/man/man9/vaccess.9 index a2e2ec5b72a..4bf37740690 100644 --- a/share/man/man9/vaccess.9 +++ b/share/man/man9/vaccess.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd September 18, 2009 -.Os .Dt VACCESS 9 +.Os .Sh NAME .Nm vaccess .Nd generate an access control decision using vnode parameters diff --git a/share/man/man9/vaccess_acl_nfs4.9 b/share/man/man9/vaccess_acl_nfs4.9 index 32cbdb3a940..27b4cfa644b 100644 --- a/share/man/man9/vaccess_acl_nfs4.9 +++ b/share/man/man9/vaccess_acl_nfs4.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd September 18, 2009 -.Os .Dt VACCESS_ACL_NFS4 9 +.Os .Sh NAME .Nm vaccess_acl_nfs4 .Nd generate a NFSv4 ACL access control decision using vnode parameters diff --git a/share/man/man9/vaccess_acl_posix1e.9 b/share/man/man9/vaccess_acl_posix1e.9 index 06105113260..dc857a8ee61 100644 --- a/share/man/man9/vaccess_acl_posix1e.9 +++ b/share/man/man9/vaccess_acl_posix1e.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd August 22, 2001 -.Os .Dt VACCESS_ACL_POSIX1E 9 +.Os .Sh NAME .Nm vaccess_acl_posix1e .Nd generate a POSIX.1e ACL access control decision using vnode parameters diff --git a/share/man/man9/vcount.9 b/share/man/man9/vcount.9 index 610891b6a8d..41263b9a1a3 100644 --- a/share/man/man9/vcount.9 +++ b/share/man/man9/vcount.9 @@ -33,8 +33,8 @@ .\" $FreeBSD$ .\" .Dd February 6, 2001 -.Os .Dt VCOUNT 9 +.Os .Sh NAME .Nm vcount , .Nm count_dev diff --git a/share/man/man9/vget.9 b/share/man/man9/vget.9 index ef8fb10dd05..1a7d16cdc37 100644 --- a/share/man/man9/vget.9 +++ b/share/man/man9/vget.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VGET 9 +.Os .Sh NAME .Nm vget .Nd get a vnode from the free list diff --git a/share/man/man9/vm_map_entry_resize_free.9 b/share/man/man9/vm_map_entry_resize_free.9 index b037bcb4562..eaaec650fb6 100644 --- a/share/man/man9/vm_map_entry_resize_free.9 +++ b/share/man/man9/vm_map_entry_resize_free.9 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd August 17, 2004 -.Os .Dt VM_MAP_ENTRY_RESIZE_FREE 9 +.Os .Sh NAME .Nm vm_map_entry_resize_free .Nd "vm map free space algorithm" diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9 index 49a2cc77d1c..cfc6f7d5f7f 100644 --- a/share/man/man9/vnode.9 +++ b/share/man/man9/vnode.9 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd February 13, 2010 -.Os .Dt VNODE 9 +.Os .Sh NAME .Nm vnode .Nd internal representation of a file or directory diff --git a/share/man/man9/vput.9 b/share/man/man9/vput.9 index 47bee09b75e..d915539d4b7 100644 --- a/share/man/man9/vput.9 +++ b/share/man/man9/vput.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VPUT 9 +.Os .Sh NAME .Nm vput .Nd "decrement the use count for a vnode and unlock it" diff --git a/share/man/man9/vref.9 b/share/man/man9/vref.9 index d979fb3f2c7..f21b9f269f3 100644 --- a/share/man/man9/vref.9 +++ b/share/man/man9/vref.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VREF 9 +.Os .Sh NAME .Nm vref .Nd increment the use count for a vnode diff --git a/share/man/man9/vrefcnt.9 b/share/man/man9/vrefcnt.9 index fbf43df7eed..de7af26fb9c 100644 --- a/share/man/man9/vrefcnt.9 +++ b/share/man/man9/vrefcnt.9 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd February 10, 2008 -.Os .Dt VREFCNT 9 +.Os .Sh NAME .Nm vrefcnt .Nd returns the use count of a vnode diff --git a/share/man/man9/vrele.9 b/share/man/man9/vrele.9 index 249114900b1..be5d5f7ade7 100644 --- a/share/man/man9/vrele.9 +++ b/share/man/man9/vrele.9 @@ -29,8 +29,8 @@ .\" $FreeBSD$ .\" .Dd July 24, 1996 -.Os .Dt VRELE 9 +.Os .Sh NAME .Nm vrele .Nd decrement the use count for a vnode diff --git a/usr.bin/ar/ar.1 b/usr.bin/ar/ar.1 index cb9414e4b7b..250cd20f90b 100644 --- a/usr.bin/ar/ar.1 +++ b/usr.bin/ar/ar.1 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd August 31, 2007 -.Os .Dt AR 1 +.Os .Sh NAME .Nm ar , .Nm ranlib diff --git a/usr.bin/c89/c89.1 b/usr.bin/c89/c89.1 index 302aa321dad..82acf37fbca 100644 --- a/usr.bin/c89/c89.1 +++ b/usr.bin/c89/c89.1 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd September 17, 1997 -.Os .Dt C89 1 +.Os .Sh NAME .Nm c89 .Nd POSIX.2 C language compiler diff --git a/usr.bin/c99/c99.1 b/usr.bin/c99/c99.1 index c56e5856e35..e5207e5a058 100644 --- a/usr.bin/c99/c99.1 +++ b/usr.bin/c99/c99.1 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd October 7, 2002 -.Os .Dt C99 1 +.Os .Sh NAME .Nm c99 .Nd standard C language compiler diff --git a/usr.bin/column/column.1 b/usr.bin/column/column.1 index 5c5a100fe3b..d4418c5ec75 100644 --- a/usr.bin/column/column.1 +++ b/usr.bin/column/column.1 @@ -33,8 +33,8 @@ .\" $FreeBSD$ .\" .Dd July 29, 2004 -.Os .Dt COLUMN 1 +.Os .Sh NAME .Nm column .Nd columnate lists diff --git a/usr.bin/comm/comm.1 b/usr.bin/comm/comm.1 index 02b508cf626..67b5eecca57 100644 --- a/usr.bin/comm/comm.1 +++ b/usr.bin/comm/comm.1 @@ -36,8 +36,8 @@ .\" $FreeBSD$ .\" .Dd December 12, 2009 -.Os .Dt COMM 1 +.Os .Sh NAME .Nm comm .Nd select or reject lines common to two files diff --git a/usr.bin/csup/cpasswd.1 b/usr.bin/csup/cpasswd.1 index 973dc808f28..1f486d18dcd 100644 --- a/usr.bin/csup/cpasswd.1 +++ b/usr.bin/csup/cpasswd.1 @@ -30,8 +30,8 @@ .\" $FreeBSD$ .\" .Dd June 27, 2007 -.Os FreeBSD .Dt CPASSWD 1 +.Os FreeBSD .Sh NAME .Nm cpasswd .Nd scramble passwords for csup authentication diff --git a/usr.bin/csup/csup.1 b/usr.bin/csup/csup.1 index 2690863bde0..02e2edb168f 100644 --- a/usr.bin/csup/csup.1 +++ b/usr.bin/csup/csup.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd February 1, 2006 -.Os FreeBSD .Dt CSUP 1 +.Os FreeBSD .Sh NAME .Nm csup .Nd network distribution package for CVS repositories diff --git a/usr.bin/enigma/enigma.1 b/usr.bin/enigma/enigma.1 index 4fc0b206fe9..e5f65ac4a4d 100644 --- a/usr.bin/enigma/enigma.1 +++ b/usr.bin/enigma/enigma.1 @@ -7,8 +7,8 @@ .\" $FreeBSD$ .\" " .Dd May 14, 2004 -.Os .Dt ENIGMA 1 +.Os .Sh NAME .Nm enigma , .Nm crypt diff --git a/usr.bin/hexdump/od.1 b/usr.bin/hexdump/od.1 index dd67ff58b23..b5b5494a47a 100644 --- a/usr.bin/hexdump/od.1 +++ b/usr.bin/hexdump/od.1 @@ -33,8 +33,8 @@ .\" $FreeBSD$ .\" .Dd February 18, 2010 -.Os .Dt OD 1 +.Os .Sh NAME .Nm od .Nd octal, decimal, hex, ASCII dump diff --git a/usr.bin/killall/killall.1 b/usr.bin/killall/killall.1 index 19362bc6d65..58ffa068b9f 100644 --- a/usr.bin/killall/killall.1 +++ b/usr.bin/killall/killall.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd December 25, 2009 -.Os .Dt KILLALL 1 +.Os .Sh NAME .Nm killall .Nd kill processes by name diff --git a/usr.bin/lockf/lockf.1 b/usr.bin/lockf/lockf.1 index 6e2e06eae58..255a8283a1f 100644 --- a/usr.bin/lockf/lockf.1 +++ b/usr.bin/lockf/lockf.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd July 7, 1998 -.Os .Dt LOCKF 1 +.Os .Sh NAME .Nm lockf .Nd execute a command while holding a file lock diff --git a/usr.bin/wtmpcvt/wtmpcvt.1 b/usr.bin/wtmpcvt/wtmpcvt.1 index fdc995b4d5c..50f89eeb5c5 100644 --- a/usr.bin/wtmpcvt/wtmpcvt.1 +++ b/usr.bin/wtmpcvt/wtmpcvt.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd January 14, 2010 -.Os .Dt WTMPCVT 1 +.Os .Sh NAME .Nm wtmpcvt .Nd convert wtmp files to the utmpx format diff --git a/usr.sbin/asf/asf.8 b/usr.sbin/asf/asf.8 index 25b03089c7a..92edb4b790d 100644 --- a/usr.sbin/asf/asf.8 +++ b/usr.sbin/asf/asf.8 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd December 20, 2006 -.Os .Dt ASF 8 +.Os .Sh NAME .Nm asf .Nd add symbol files diff --git a/usr.sbin/burncd/burncd.8 b/usr.sbin/burncd/burncd.8 index 2501e7209c7..a9c53e62774 100644 --- a/usr.sbin/burncd/burncd.8 +++ b/usr.sbin/burncd/burncd.8 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd December 21, 2009 -.Os .Dt BURNCD 8 +.Os .Sh NAME .Nm burncd .Nd control the ATAPI CD-R/RW driver diff --git a/usr.sbin/ctm/ctm/ctm.1 b/usr.sbin/ctm/ctm/ctm.1 index 732b0b9a968..d5cc6144d1d 100644 --- a/usr.sbin/ctm/ctm/ctm.1 +++ b/usr.sbin/ctm/ctm/ctm.1 @@ -13,8 +13,8 @@ .\" $FreeBSD$ .\" .Dd March 25, 1995 -.Os .Dt CTM 1 +.Os .Sh NAME .Nm ctm .Nd source code mirror program diff --git a/usr.sbin/ctm/ctm/ctm.5 b/usr.sbin/ctm/ctm/ctm.5 index 678837e6182..a51c93b0069 100644 --- a/usr.sbin/ctm/ctm/ctm.5 +++ b/usr.sbin/ctm/ctm/ctm.5 @@ -13,8 +13,8 @@ .\" $FreeBSD$ .\" .Dd March 25, 1995 -.Os .Dt CTM 5 +.Os .Sh NAME .Nm ctm .Nd source code mirror system diff --git a/usr.sbin/devinfo/devinfo.8 b/usr.sbin/devinfo/devinfo.8 index 6c893dc66a5..ecb3b012637 100644 --- a/usr.sbin/devinfo/devinfo.8 +++ b/usr.sbin/devinfo/devinfo.8 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd November 28, 2005 -.Os .Dt DEVINFO 8 +.Os .Sh NAME .Nm devinfo .Nd print information about system device configuration diff --git a/usr.sbin/fdformat/fdformat.1 b/usr.sbin/fdformat/fdformat.1 index 25891c0f003..596b09b6cc0 100644 --- a/usr.sbin/fdformat/fdformat.1 +++ b/usr.sbin/fdformat/fdformat.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd December 25, 2001 -.Os .Dt FDFORMAT 1 +.Os .Sh NAME .Nm fdformat .Nd format floppy disks diff --git a/usr.sbin/fdread/fdread.1 b/usr.sbin/fdread/fdread.1 index 20a79fc1453..d29a4a44dd6 100644 --- a/usr.sbin/fdread/fdread.1 +++ b/usr.sbin/fdread/fdread.1 @@ -27,8 +27,8 @@ .\" .\" .Dd May 14, 2001 -.Os .Dt FDREAD 1 +.Os .Sh NAME .Nm fdread .Nd read floppy disks diff --git a/usr.sbin/fdwrite/fdwrite.1 b/usr.sbin/fdwrite/fdwrite.1 index 28df514f264..e8473983bff 100644 --- a/usr.sbin/fdwrite/fdwrite.1 +++ b/usr.sbin/fdwrite/fdwrite.1 @@ -10,8 +10,8 @@ .\" .\" .Dd September 16, 1993 -.Os .Dt FDWRITE 1 +.Os .Sh NAME .Nm fdwrite .Nd format and write floppy disks diff --git a/usr.sbin/fifolog/fifolog_create/fifolog.1 b/usr.sbin/fifolog/fifolog_create/fifolog.1 index 7db58e71840..d0be0ce9bb3 100644 --- a/usr.sbin/fifolog/fifolog_create/fifolog.1 +++ b/usr.sbin/fifolog/fifolog_create/fifolog.1 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd February 9, 2008 -.Os .Dt FIFOLOG 1 +.Os .Sh NAME .Nm fifolog_create , fifolog_writer , fifolog_reader .Nd "initialize, write, seek and extract data from a fifolog" diff --git a/usr.sbin/flowctl/flowctl.8 b/usr.sbin/flowctl/flowctl.8 index e72486bbf80..75304c45910 100644 --- a/usr.sbin/flowctl/flowctl.8 +++ b/usr.sbin/flowctl/flowctl.8 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd March 23, 2005 -.Os .Dt FLOWCTL 8 +.Os .Sh NAME .Nm flowctl .Nd diff --git a/usr.sbin/mtest/mtest.8 b/usr.sbin/mtest/mtest.8 index b4d3514582c..9a961e01846 100644 --- a/usr.sbin/mtest/mtest.8 +++ b/usr.sbin/mtest/mtest.8 @@ -27,8 +27,8 @@ .\" $FreeBSD$ .\" .Dd April 29, 2009 -.Os .Dt MTEST 8 +.Os .Sh NAME .Nm mtest .Nd test multicast socket operations diff --git a/usr.sbin/periodic/periodic.8 b/usr.sbin/periodic/periodic.8 index 63359308656..22a96a2a647 100644 --- a/usr.sbin/periodic/periodic.8 +++ b/usr.sbin/periodic/periodic.8 @@ -25,8 +25,8 @@ .\" $FreeBSD$ .\" .Dd August 30, 2007 -.Os .Dt PERIODIC 8 +.Os .Sh NAME .Nm periodic .Nd run periodic system functions diff --git a/usr.sbin/pmcannotate/pmcannotate.8 b/usr.sbin/pmcannotate/pmcannotate.8 index adadae437fa..17c7c0ed5d6 100644 --- a/usr.sbin/pmcannotate/pmcannotate.8 +++ b/usr.sbin/pmcannotate/pmcannotate.8 @@ -28,8 +28,8 @@ .\" $FreeBSD$ .\" .Dd November 20, 2008 -.Os .Dt PMCANNOTATE 8 +.Os .Sh NAME .Nm pmcannotate .Nd "sources printout with inlined profiling" diff --git a/usr.sbin/pmccontrol/pmccontrol.8 b/usr.sbin/pmccontrol/pmccontrol.8 index e521a1f4702..f436753dd37 100644 --- a/usr.sbin/pmccontrol/pmccontrol.8 +++ b/usr.sbin/pmccontrol/pmccontrol.8 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd November 9, 2008 -.Os .Dt PMCCONTROL 8 +.Os .Sh NAME .Nm pmccontrol .Nd "control hardware performance monitoring counters" diff --git a/usr.sbin/pmcstat/pmcstat.8 b/usr.sbin/pmcstat/pmcstat.8 index 309eb3eae2d..b033357fa42 100644 --- a/usr.sbin/pmcstat/pmcstat.8 +++ b/usr.sbin/pmcstat/pmcstat.8 @@ -26,8 +26,8 @@ .\" $FreeBSD$ .\" .Dd September 19, 2008 -.Os .Dt PMCSTAT 8 +.Os .Sh NAME .Nm pmcstat .Nd "performance measurement with performance monitoring hardware" diff --git a/usr.sbin/pppctl/pppctl.8 b/usr.sbin/pppctl/pppctl.8 index 245690f17f1..431b7d76c17 100644 --- a/usr.sbin/pppctl/pppctl.8 +++ b/usr.sbin/pppctl/pppctl.8 @@ -1,7 +1,7 @@ .\" $FreeBSD$ .Dd June 26, 1997 -.Os .Dt PPPCTL 8 +.Os .Sh NAME .Nm pppctl .Nd PPP control program diff --git a/usr.sbin/setfmac/setfsmac.8 b/usr.sbin/setfmac/setfsmac.8 index 7d4150f9447..9bdb0e8f7ec 100644 --- a/usr.sbin/setfmac/setfsmac.8 +++ b/usr.sbin/setfmac/setfsmac.8 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd February 17, 2004 -.Os .Dt SETFSMAC 8 +.Os .Sh NAME .Nm setfsmac .Nd set MAC label for a file hierarchy diff --git a/usr.sbin/setpmac/setpmac.8 b/usr.sbin/setpmac/setpmac.8 index e84a8bc6322..c5c2963c557 100644 --- a/usr.sbin/setpmac/setpmac.8 +++ b/usr.sbin/setpmac/setpmac.8 @@ -31,8 +31,8 @@ .\" $FreeBSD$ .\" .Dd January 14, 2003 -.Os .Dt SETPMAC 8 +.Os .Sh NAME .Nm setpmac .Nd "run a command with a different MAC process label" diff --git a/usr.sbin/uhsoctl/uhsoctl.1 b/usr.sbin/uhsoctl/uhsoctl.1 index e01c1a2af49..cd0c5ca66f8 100644 --- a/usr.sbin/uhsoctl/uhsoctl.1 +++ b/usr.sbin/uhsoctl/uhsoctl.1 @@ -24,8 +24,8 @@ .\" $FreeBSD$ .\" .Dd Aug 12, 2009 -.Os .Dt UHSOCTL 1 +.Os .Sh NAME .Nm uhsoctl .Nd connection utility for Option based devices From b71e04d3a8557b54d33fcc1bd4e4fa07cc7f856b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 14 Apr 2010 20:04:55 +0000 Subject: [PATCH 048/532] ld_gs_base is executing with stack containing only the frame, temporary pushed %rflags has been popped already. Pointy hat to: kib MFC after: 3 days --- sys/amd64/amd64/exception.S | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index bbc304a48d6..0d5a50ddc0c 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -815,7 +815,6 @@ fsbase_load_fault: ALIGN_TEXT .globl gsbase_load_fault gsbase_load_fault: - popfq movl $T_PROTFLT,TF_TRAPNO(%rsp) movq %rsp, %rdi call trap From d578fbb66e2c49ea820bdd44730717709c4217b9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 14 Apr 2010 20:31:06 +0000 Subject: [PATCH 049/532] Make this directory more regular. Since it is one we control, use the freebsd-based names for filenames. This allows us to eliminate almost all of the uses of ${MACHINE_ARCH} here to do special things, and instead we use it to include filenames. This makes new architectures easier to support. --- gnu/usr.bin/gdb/gdbserver/Makefile | 17 +++-------------- .../{fbsd-ppc-low.c => fbsd-powerpc-low.c} | 0 .../gdb/gdbserver/{reg-x86-64.c => reg-amd64.c} | 0 .../gdb/gdbserver/{reg-ppc.c => reg-powerpc.c} | 0 4 files changed, 3 insertions(+), 14 deletions(-) rename gnu/usr.bin/gdb/gdbserver/{fbsd-ppc-low.c => fbsd-powerpc-low.c} (100%) rename gnu/usr.bin/gdb/gdbserver/{reg-x86-64.c => reg-amd64.c} (100%) rename gnu/usr.bin/gdb/gdbserver/{reg-ppc.c => reg-powerpc.c} (100%) diff --git a/gnu/usr.bin/gdb/gdbserver/Makefile b/gnu/usr.bin/gdb/gdbserver/Makefile index 390ef32692b..08f25ae61a5 100644 --- a/gnu/usr.bin/gdb/gdbserver/Makefile +++ b/gnu/usr.bin/gdb/gdbserver/Makefile @@ -14,20 +14,9 @@ SRCS= inferiors.c mem-break.c regcache.c remote-utils.c \ server.c signals.c target.c utils.c SRCS+= fbsd-low.c -.if ${MACHINE_ARCH} == "amd64" -SRCS+= fbsd-amd64-low.c i387-fp.c reg-x86-64.c -.endif - -.if ${MACHINE_ARCH} == "arm" -SRCS+= fbsd-arm-low.c reg-arm.c -.endif - -.if ${MACHINE_ARCH} == "i386" -SRCS+= fbsd-i386-low.c i387-fp.c reg-i386.c -.endif - -.if ${MACHINE_ARCH} == "powerpc" -SRCS+= fbsd-ppc-low.c reg-ppc.c +SRCS+= fbsd-${MACHINE_ARCH}-low.c reg-${MACHINE_ARCH}.c +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" +SRCS+= i387-fp.c .endif #CFLAGS+= -I${.CURDIR}/../arch/${MACHINE_ARCH} diff --git a/gnu/usr.bin/gdb/gdbserver/fbsd-ppc-low.c b/gnu/usr.bin/gdb/gdbserver/fbsd-powerpc-low.c similarity index 100% rename from gnu/usr.bin/gdb/gdbserver/fbsd-ppc-low.c rename to gnu/usr.bin/gdb/gdbserver/fbsd-powerpc-low.c diff --git a/gnu/usr.bin/gdb/gdbserver/reg-x86-64.c b/gnu/usr.bin/gdb/gdbserver/reg-amd64.c similarity index 100% rename from gnu/usr.bin/gdb/gdbserver/reg-x86-64.c rename to gnu/usr.bin/gdb/gdbserver/reg-amd64.c diff --git a/gnu/usr.bin/gdb/gdbserver/reg-ppc.c b/gnu/usr.bin/gdb/gdbserver/reg-powerpc.c similarity index 100% rename from gnu/usr.bin/gdb/gdbserver/reg-ppc.c rename to gnu/usr.bin/gdb/gdbserver/reg-powerpc.c From d193ed0bedd2c0f08defb084b803662f8ce6f2cf Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 14 Apr 2010 20:45:33 +0000 Subject: [PATCH 050/532] Add driver for Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet. This driver was written by Alexander Pohoyda and greatly enhanced by Nikolay Denev. I don't have these hardwares but this driver was tested by Nikolay Denev and xclin. Because SiS didn't release data sheet for this controller, programming information came from Linux driver and OpenSolaris. Unlike other open source driver for SiS190/191, sge(4) takes full advantage of TX/RX checksum offloading and does not require additional copy operation in RX handler. The controller seems to have advanced offloading features like VLAN hardware tag insertion/stripping, TCP segmentation offload(TSO) as well as jumbo frame support but these features are not available yet. Special thanks to xclin cs dot nctu dot edu dot tw> who sent fix for receiving VLAN oversized frames. --- sys/amd64/conf/GENERIC | 1 + sys/boot/forth/loader.conf | 1 + sys/conf/NOTES | 2 + sys/conf/files | 1 + sys/dev/sge/if_sge.c | 1745 ++++++++++++++++++++++++++++++++++++ sys/dev/sge/if_sgereg.h | 350 ++++++++ sys/i386/conf/GENERIC | 1 + sys/modules/Makefile | 1 + sys/modules/sge/Makefile | 8 + 9 files changed, 2110 insertions(+) create mode 100644 sys/dev/sge/if_sge.c create mode 100644 sys/dev/sge/if_sgereg.h create mode 100644 sys/modules/sge/Makefile diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 0d5cad781e4..f6d0a600bf2 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -224,6 +224,7 @@ device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') +device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index d7f1323be9b..e0e4409f03b 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -271,6 +271,7 @@ if_rl_load="NO" # RealTek 8129/8139 if_rue_load="NO" # RealTek RTL8150 USB to Fast Ethernet if_sbni_load="NO" # Granch SBNI12 leased line adapters if_sf_load="NO" # Adaptec Duralink PCI (AIC-6915 "starfire") +if_sge_load="NO" # Silicon Integrated Systems SiS190/191 if_sis_load="NO" # Silicon Integrated Systems SiS 900/7016 if_sk_load="NO" # SysKonnect SK-984x series PCI Gigabit Ethernet if_sn_load="NO" # SMC 91Cxx diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 8a2023ddc1c..f0cc9a0bc10 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1952,6 +1952,7 @@ device xmphy # XaQti XMAC II # This includes dual and quad port cards, as well as one 100baseFX card. # Most of these are 64-bit PCI devices, except for one single port # card which is 32-bit. +# sge: Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet adapter # sis: Support for NICs based on the Silicon Integrated Systems SiS 900, # SiS 7016 and NS DP83815 PCI fast ethernet controller chips. # sk: Support for the SysKonnect SK-984x series PCI gigabit ethernet NICs. @@ -2046,6 +2047,7 @@ device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device pcn # AMD Am79C97x PCI 10/100 NICs device sf # Adaptec AIC-6915 (``Starfire'') +device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) diff --git a/sys/conf/files b/sys/conf/files index 7dd1b0ed3cd..6bb1355b919 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1490,6 +1490,7 @@ dev/scd/scd.c optional scd isa dev/scd/scd_isa.c optional scd isa dev/sdhci/sdhci.c optional sdhci pci dev/sf/if_sf.c optional sf pci +dev/sge/if_sge.c optional sge pci dev/si/si.c optional si dev/si/si2_z280.c optional si dev/si/si3_t225.c optional si diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c new file mode 100644 index 00000000000..a26a6a46359 --- /dev/null +++ b/sys/dev/sge/if_sge.c @@ -0,0 +1,1745 @@ +/*- + * Copyright (c) 2008-2010 Nikolay Denev + * Copyright (c) 2007-2008 Alexander Pohoyda + * Copyright (c) 1997, 1998, 1999 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AUTHORS OR + * THE VOICES IN THEIR HEADS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * SiS 190/191 PCI Ethernet NIC driver. + * + * Adapted to SiS 190 NIC by Alexander Pohoyda based on the original + * SiS 900 driver by Bill Paul, using SiS 190/191 Solaris driver by + * Masayuki Murayama and SiS 190/191 GNU/Linux driver by K.M. Liu + * . Thanks to Pyun YongHyeon for + * review and very useful comments. + * + * Adapted to SiS 191 NIC by Nikolay Denev with further ideas from the + * Linux and Solaris drivers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "if_sgereg.h" + +MODULE_DEPEND(sge, pci, 1, 1, 1); +MODULE_DEPEND(sge, ether, 1, 1, 1); +MODULE_DEPEND(sge, miibus, 1, 1, 1); + +/* "device miibus0" required. See GENERIC if you get errors here. */ +#include "miibus_if.h" + +/* + * Various supported device vendors/types and their names. + */ +static struct sge_type sge_devs[] = { + { SIS_VENDORID, SIS_DEVICEID_190, "SiS190 Fast Ethernet" }, + { SIS_VENDORID, SIS_DEVICEID_191, "SiS191 Fast/Gigabit Ethernet" }, + { 0, 0, NULL } +}; + +static int sge_probe(device_t); +static int sge_attach(device_t); +static int sge_detach(device_t); +static int sge_shutdown(device_t); +static int sge_suspend(device_t); +static int sge_resume(device_t); + +static int sge_miibus_readreg(device_t, int, int); +static int sge_miibus_writereg(device_t, int, int, int); +static void sge_miibus_statchg(device_t); + +static int sge_newbuf(struct sge_softc *, int); +static int sge_encap(struct sge_softc *, struct mbuf **); +#ifndef __NO_STRICT_ALIGNMENT +static __inline void + sge_fixup_rx(struct mbuf *); +#endif +static __inline void + sge_discard_rxbuf(struct sge_softc *, int); +static void sge_rxeof(struct sge_softc *); +static void sge_txeof(struct sge_softc *); +static void sge_intr(void *); +static void sge_tick(void *); +static void sge_start(struct ifnet *); +static void sge_start_locked(struct ifnet *); +static int sge_ioctl(struct ifnet *, u_long, caddr_t); +static void sge_init(void *); +static void sge_init_locked(struct sge_softc *); +static void sge_stop(struct sge_softc *); +static void sge_watchdog(struct sge_softc *); +static int sge_ifmedia_upd(struct ifnet *); +static void sge_ifmedia_sts(struct ifnet *, struct ifmediareq *); + +static int sge_get_mac_addr_apc(struct sge_softc *, uint8_t *); +static int sge_get_mac_addr_eeprom(struct sge_softc *, uint8_t *); +static uint16_t sge_read_eeprom(struct sge_softc *, int); + +static void sge_rxfilter(struct sge_softc *); +static void sge_reset(struct sge_softc *); +static int sge_list_rx_init(struct sge_softc *); +static int sge_list_rx_free(struct sge_softc *); +static int sge_list_tx_init(struct sge_softc *); +static int sge_list_tx_free(struct sge_softc *); + +static int sge_dma_alloc(struct sge_softc *); +static void sge_dma_free(struct sge_softc *); +static void sge_dma_map_addr(void *, bus_dma_segment_t *, int, int); + +static device_method_t sge_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, sge_probe), + DEVMETHOD(device_attach, sge_attach), + DEVMETHOD(device_detach, sge_detach), + DEVMETHOD(device_suspend, sge_suspend), + DEVMETHOD(device_resume, sge_resume), + DEVMETHOD(device_shutdown, sge_shutdown), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_driver_added, bus_generic_driver_added), + + /* MII interface */ + DEVMETHOD(miibus_readreg, sge_miibus_readreg), + DEVMETHOD(miibus_writereg, sge_miibus_writereg), + DEVMETHOD(miibus_statchg, sge_miibus_statchg), + + KOBJMETHOD_END +}; + +static driver_t sge_driver = { + "sge", sge_methods, sizeof(struct sge_softc) +}; + +static devclass_t sge_devclass; + +DRIVER_MODULE(sge, pci, sge_driver, sge_devclass, 0, 0); +DRIVER_MODULE(miibus, sge, miibus_driver, miibus_devclass, 0, 0); + +/* + * Register space access macros. + */ +#define CSR_WRITE_4(sc, reg, val) bus_write_4(sc->sge_res, reg, val) +#define CSR_WRITE_2(sc, reg, val) bus_write_2(sc->sge_res, reg, val) +#define CSR_WRITE_1(cs, reg, val) bus_write_1(sc->sge_res, reg, val) + +#define CSR_READ_4(sc, reg) bus_read_4(sc->sge_res, reg) +#define CSR_READ_2(sc, reg) bus_read_2(sc->sge_res, reg) +#define CSR_READ_1(sc, reg) bus_read_1(sc->sge_res, reg) + +/* Define to show Tx/Rx error status. */ +#undef SGE_SHOW_ERRORS + +#define SGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) + +static void +sge_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + bus_addr_t *p; + + if (error != 0) + return; + KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg)); + p = arg; + *p = segs->ds_addr; +} + +/* + * Read a sequence of words from the EEPROM. + */ +static uint16_t +sge_read_eeprom(struct sge_softc *sc, int offset) +{ + uint32_t val; + int i; + + KASSERT(offset <= EI_OFFSET, ("EEPROM offset too big")); + CSR_WRITE_4(sc, ROMInterface, + EI_REQ | EI_OP_RD | (offset << EI_OFFSET_SHIFT)); + DELAY(500); + for (i = 0; i < SGE_TIMEOUT; i++) { + val = CSR_READ_4(sc, ROMInterface); + if ((val & EI_REQ) == 0) + break; + DELAY(100); + } + if (i == SGE_TIMEOUT) { + device_printf(sc->sge_dev, + "EEPROM read timeout : 0x%08x\n", val); + return (0xffff); + } + + return ((val & EI_DATA) >> EI_DATA_SHIFT); +} + +static int +sge_get_mac_addr_eeprom(struct sge_softc *sc, uint8_t *dest) +{ + uint16_t val; + int i; + + val = sge_read_eeprom(sc, EEPROMSignature); + if (val == 0xffff || val == 0) { + device_printf(sc->sge_dev, + "invalid EEPROM signature : 0x%04x\n", val); + return (EINVAL); + } + + for (i = 0; i < ETHER_ADDR_LEN; i += 2) { + val = sge_read_eeprom(sc, EEPROMMACAddr + i / 2); + dest[i + 0] = (uint8_t)val; + dest[i + 1] = (uint8_t)(val >> 8); + } + + if ((sge_read_eeprom(sc, EEPROMInfo) & 0x80) != 0) + sc->sge_flags |= SGE_FLAG_RGMII; + return (0); +} + +/* + * For SiS96x, APC CMOS RAM is used to store ethernet address. + * APC CMOS RAM is accessed through ISA bridge. + */ +static int +sge_get_mac_addr_apc(struct sge_softc *sc, uint8_t *dest) +{ +#if defined(__amd64__) || defined(__i386__) + devclass_t pci; + device_t bus, dev = NULL; + device_t *kids; + struct apc_tbl { + uint16_t vid; + uint16_t did; + } *tp, apc_tbls[] = { + { SIS_VENDORID, 0x0965 }, + { SIS_VENDORID, 0x0966 }, + { SIS_VENDORID, 0x0968 } + }; + uint8_t reg; + int busnum, cnt, i, j, numkids; + + cnt = sizeof(apc_tbls) / sizeof(apc_tbls[0]); + pci = devclass_find("pci"); + for (busnum = 0; busnum < devclass_get_maxunit(pci); busnum++) { + bus = devclass_get_device(pci, busnum); + if (!bus) + continue; + if (device_get_children(bus, &kids, &numkids) != 0) + continue; + for (i = 0; i < numkids; i++) { + dev = kids[i]; + if (pci_get_class(dev) == PCIC_BRIDGE && + pci_get_subclass(dev) == PCIS_BRIDGE_ISA) { + tp = apc_tbls; + for (j = 0; j < cnt; j++) { + if (pci_get_vendor(dev) == tp->vid && + pci_get_device(dev) == tp->did) { + free(kids, M_TEMP); + goto apc_found; + } + tp++; + } + } + } + free(kids, M_TEMP); + } + device_printf(sc->sge_dev, "couldn't find PCI-ISA bridge\n"); + return (EINVAL); +apc_found: + /* Enable port 0x78 and 0x79 to access APC registers. */ + reg = pci_read_config(dev, 0x48, 1); + pci_write_config(dev, 0x48, reg & ~0x02, 1); + DELAY(50); + pci_read_config(dev, 0x48, 1); + /* Read stored ethernet address. */ + for (i = 0; i < ETHER_ADDR_LEN; i++) { + outb(0x78, 0x09 + i); + dest[i] = inb(0x79); + } + outb(0x78, 0x12); + if ((inb(0x79) & 0x80) != 0) + sc->sge_flags |= SGE_FLAG_RGMII; + /* Restore access to APC registers. */ + pci_write_config(dev, 0x48, reg, 1); + + return (0); +#else + return (EINVAL); +#endif +} + +static int +sge_miibus_readreg(device_t dev, int phy, int reg) +{ + struct sge_softc *sc; + uint32_t val; + int i; + + sc = device_get_softc(dev); + CSR_WRITE_4(sc, GMIIControl, (phy << GMI_PHY_SHIFT) | + (reg << GMI_REG_SHIFT) | GMI_OP_RD | GMI_REQ); + DELAY(10); + for (i = 0; i < SGE_TIMEOUT; i++) { + val = CSR_READ_4(sc, GMIIControl); + if ((val & GMI_REQ) == 0) + break; + DELAY(10); + } + if (i == SGE_TIMEOUT) { + device_printf(sc->sge_dev, "PHY read timeout : %d\n", reg); + return (0); + } + return ((val & GMI_DATA) >> GMI_DATA_SHIFT); +} + +static int +sge_miibus_writereg(device_t dev, int phy, int reg, int data) +{ + struct sge_softc *sc; + uint32_t val; + int i; + + sc = device_get_softc(dev); + CSR_WRITE_4(sc, GMIIControl, (phy << GMI_PHY_SHIFT) | + (reg << GMI_REG_SHIFT) | (data << GMI_DATA_SHIFT) | + GMI_OP_WR | GMI_REQ); + DELAY(10); + for (i = 0; i < SGE_TIMEOUT; i++) { + val = CSR_READ_4(sc, GMIIControl); + if ((val & GMI_REQ) == 0) + break; + DELAY(10); + } + if (i == SGE_TIMEOUT) + device_printf(sc->sge_dev, "PHY write timeout : %d\n", reg); + return (0); +} + +static void +sge_miibus_statchg(device_t dev) +{ + struct sge_softc *sc; + struct mii_data *mii; + struct ifnet *ifp; + uint32_t ctl, speed; + + sc = device_get_softc(dev); + mii = device_get_softc(sc->sge_miibus); + ifp = sc->sge_ifp; + if (mii == NULL || ifp == NULL || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + speed = 0; + sc->sge_flags &= ~SGE_FLAG_LINK; + if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == + (IFM_ACTIVE | IFM_AVALID)) { + switch (IFM_SUBTYPE(mii->mii_media_active)) { + case IFM_10_T: + sc->sge_flags |= SGE_FLAG_LINK; + speed = SC_SPEED_10; + break; + case IFM_100_TX: + sc->sge_flags |= SGE_FLAG_LINK; + speed = SC_SPEED_100; + break; + case IFM_1000_T: + if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0) { + sc->sge_flags |= SGE_FLAG_LINK; + speed = SC_SPEED_1000; + } + break; + default: + break; + } + } + if ((sc->sge_flags & SGE_FLAG_LINK) == 0) + return; + /* Reprogram MAC to resolved speed/duplex/flow-control parameters. */ + ctl = CSR_READ_4(sc, StationControl); + ctl &= ~(0x0f000000 | SC_FDX | SC_SPEED_MASK); + if (speed == SC_SPEED_1000) { + ctl |= 0x07000000; + sc->sge_flags |= SGE_FLAG_SPEED_1000; + } else { + ctl |= 0x04000000; + sc->sge_flags &= ~SGE_FLAG_SPEED_1000; + } +#ifdef notyet + if ((sc->sge_flags & SGE_FLAG_GMII) != 0) + ctl |= 0x03000000; +#endif + ctl |= speed; + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { + ctl |= SC_FDX; + sc->sge_flags |= SGE_FLAG_FDX; + } else + sc->sge_flags &= ~SGE_FLAG_FDX; + CSR_WRITE_4(sc, StationControl, ctl); + if ((sc->sge_flags & SGE_FLAG_RGMII) != 0) { + CSR_WRITE_4(sc, RGMIIDelay, 0x0441); + CSR_WRITE_4(sc, RGMIIDelay, 0x0440); + } +} + +static void +sge_rxfilter(struct sge_softc *sc) +{ + struct ifnet *ifp; + struct ifmultiaddr *ifma; + uint32_t crc, hashes[2]; + uint16_t rxfilt; + + SGE_LOCK_ASSERT(sc); + + ifp = sc->sge_ifp; + hashes[0] = hashes[1] = 0; + rxfilt = AcceptMyPhys; + if ((ifp->if_flags & IFF_BROADCAST) != 0) + rxfilt |= AcceptBroadcast; + if ((ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) { + if ((ifp->if_flags & IFF_PROMISC) != 0) + rxfilt |= AcceptAllPhys; + rxfilt |= AcceptMulticast; + hashes[0] = 0xFFFFFFFF; + hashes[1] = 0xFFFFFFFF; + goto done; + } + rxfilt |= AcceptMulticast; + /* Now program new ones. */ + if_maddr_rlock(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + crc = ether_crc32_be(LLADDR((struct sockaddr_dl *) + ifma->ifma_addr), ETHER_ADDR_LEN); + hashes[crc >> 31] |= 1 << ((crc >> 26) & 0x1f); + } + if_maddr_runlock(ifp); +done: + CSR_WRITE_2(sc, RxMacControl, rxfilt | 0x02); + CSR_WRITE_4(sc, RxHashTable, hashes[0]); + CSR_WRITE_4(sc, RxHashTable2, hashes[1]); +} + +static void +sge_reset(struct sge_softc *sc) +{ + + CSR_WRITE_4(sc, IntrMask, 0); + CSR_WRITE_4(sc, IntrStatus, 0xffffffff); + + /* Soft reset. */ + CSR_WRITE_4(sc, IntrControl, 0x8000); + CSR_READ_4(sc, IntrControl); + DELAY(100); + CSR_WRITE_4(sc, IntrControl, 0); + /* Stop MAC. */ + CSR_WRITE_4(sc, TX_CTL, 0x1a00); + CSR_WRITE_4(sc, RX_CTL, 0x1a00); + + CSR_WRITE_4(sc, IntrMask, 0); + CSR_WRITE_4(sc, IntrStatus, 0xffffffff); + + CSR_WRITE_4(sc, GMIIControl, 0); +} + +/* + * Probe for an SiS chip. Check the PCI vendor and device + * IDs against our list and return a device name if we find a match. + */ +static int +sge_probe(device_t dev) +{ + struct sge_type *t; + + t = sge_devs; + while (t->sge_name != NULL) { + if ((pci_get_vendor(dev) == t->sge_vid) && + (pci_get_device(dev) == t->sge_did)) { + device_set_desc(dev, t->sge_name); + return (BUS_PROBE_DEFAULT); + } + t++; + } + + return (ENXIO); +} + +/* + * Attach the interface. Allocate softc structures, do ifmedia + * setup and ethernet/BPF attach. + */ +static int +sge_attach(device_t dev) +{ + struct sge_softc *sc; + struct ifnet *ifp; + uint8_t eaddr[ETHER_ADDR_LEN]; + int error = 0, rid; + + sc = device_get_softc(dev); + sc->sge_dev = dev; + + mtx_init(&sc->sge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF); + callout_init_mtx(&sc->sge_stat_ch, &sc->sge_mtx, 0); + + /* + * Map control/status registers. + */ + pci_enable_busmaster(dev); + + /* Allocate resources. */ + sc->sge_res_id = PCIR_BAR(0); + sc->sge_res_type = SYS_RES_MEMORY; + sc->sge_res = bus_alloc_resource_any(dev, sc->sge_res_type, + &sc->sge_res_id, RF_ACTIVE); + if (sc->sge_res == NULL) { + device_printf(dev, "couldn't allocate resource\n"); + error = ENXIO; + goto fail; + } + + rid = 0; + sc->sge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (sc->sge_irq == NULL) { + device_printf(dev, "couldn't allocate IRQ resources\n"); + error = ENXIO; + goto fail; + } + sc->sge_rev = pci_get_revid(dev); + if (pci_get_device(dev) == SIS_DEVICEID_190) + sc->sge_flags |= SGE_FLAG_FASTETHER; + /* Reset the adapter. */ + sge_reset(sc); + + /* Get MAC address from the EEPROM. */ + if ((pci_read_config(dev, 0x73, 1) & 0x01) != 0) + sge_get_mac_addr_apc(sc, eaddr); + else + sge_get_mac_addr_eeprom(sc, eaddr); + + if ((error = sge_dma_alloc(sc)) != 0) + goto fail; + + ifp = sc->sge_ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + device_printf(dev, "cannot allocate ifnet structure.\n"); + error = ENOSPC; + goto fail; + } + ifp->if_softc = sc; + if_initname(ifp, device_get_name(dev), device_get_unit(dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_ioctl = sge_ioctl; + ifp->if_start = sge_start; + ifp->if_init = sge_init; + ifp->if_snd.ifq_drv_maxlen = SGE_TX_RING_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); + IFQ_SET_READY(&ifp->if_snd); + ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_RXCSUM; + ifp->if_hwassist = SGE_CSUM_FEATURES; + ifp->if_capenable = ifp->if_capabilities; + /* + * Do MII setup. + */ + if (mii_phy_probe(dev, &sc->sge_miibus, sge_ifmedia_upd, + sge_ifmedia_sts)) { + device_printf(dev, "no PHY found!\n"); + error = ENXIO; + goto fail; + } + + /* + * Call MI attach routine. + */ + ether_ifattach(ifp, eaddr); + + /* VLAN setup. */ + ifp->if_capabilities |= IFCAP_VLAN_MTU; + ifp->if_capenable = ifp->if_capabilities; + /* Tell the upper layer(s) we support long frames. */ + ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); + + /* Hook interrupt last to avoid having to lock softc */ + error = bus_setup_intr(dev, sc->sge_irq, INTR_TYPE_NET | INTR_MPSAFE, + NULL, sge_intr, sc, &sc->sge_intrhand); + if (error) { + device_printf(dev, "couldn't set up irq\n"); + ether_ifdetach(ifp); + goto fail; + } + +fail: + if (error) + sge_detach(dev); + + return (error); +} + +/* + * Shutdown hardware and free up resources. This can be called any + * time after the mutex has been initialized. It is called in both + * the error case in attach and the normal detach case so it needs + * to be careful about only freeing resources that have actually been + * allocated. + */ +static int +sge_detach(device_t dev) +{ + struct sge_softc *sc; + struct ifnet *ifp; + + sc = device_get_softc(dev); + ifp = sc->sge_ifp; + /* These should only be active if attach succeeded. */ + if (device_is_attached(dev)) { + ether_ifdetach(ifp); + SGE_LOCK(sc); + sge_stop(sc); + SGE_UNLOCK(sc); + callout_drain(&sc->sge_stat_ch); + } + if (sc->sge_miibus) + device_delete_child(dev, sc->sge_miibus); + bus_generic_detach(dev); + + if (sc->sge_intrhand) + bus_teardown_intr(dev, sc->sge_irq, sc->sge_intrhand); + if (sc->sge_irq) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sge_irq); + if (sc->sge_res) + bus_release_resource(dev, sc->sge_res_type, sc->sge_res_id, + sc->sge_res); + if (ifp) + if_free(ifp); + sge_dma_free(sc); + mtx_destroy(&sc->sge_mtx); + + return (0); +} + +/* + * Stop all chip I/O so that the kernel's probe routines don't + * get confused by errant DMAs when rebooting. + */ +static int +sge_shutdown(device_t dev) +{ + struct sge_softc *sc; + + sc = device_get_softc(dev); + SGE_LOCK(sc); + sge_stop(sc); + SGE_UNLOCK(sc); + return (0); +} + +static int +sge_suspend(device_t dev) +{ + struct sge_softc *sc; + struct ifnet *ifp; + + sc = device_get_softc(dev); + SGE_LOCK(sc); + ifp = sc->sge_ifp; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + sge_stop(sc); + SGE_UNLOCK(sc); + return (0); +} + +static int +sge_resume(device_t dev) +{ + struct sge_softc *sc; + struct ifnet *ifp; + + sc = device_get_softc(dev); + SGE_LOCK(sc); + ifp = sc->sge_ifp; + if ((ifp->if_flags & IFF_UP) != 0) + sge_init_locked(sc); + SGE_UNLOCK(sc); + return (0); +} + +static int +sge_dma_alloc(struct sge_softc *sc) +{ + struct sge_chain_data *cd; + struct sge_list_data *ld; + int error, i; + + cd = &sc->sge_cdata; + ld = &sc->sge_ldata; + error = bus_dma_tag_create(bus_get_dma_tag(sc->sge_dev), + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ + 1, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ + &cd->sge_tag); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create parent DMA tag.\n"); + goto fail; + } + + /* RX descriptor ring */ + error = bus_dma_tag_create(cd->sge_tag, + SGE_DESC_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + SGE_RX_RING_SZ, 1, /* maxsize,nsegments */ + SGE_RX_RING_SZ, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ + &cd->sge_rx_tag); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create Rx ring DMA tag.\n"); + goto fail; + } + /* Allocate DMA'able memory and load DMA map for RX ring. */ + error = bus_dmamem_alloc(cd->sge_rx_tag, (void **)&ld->sge_rx_ring, + BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, + &cd->sge_rx_dmamap); + if (error != 0) { + device_printf(sc->sge_dev, + "could not allocate DMA'able memory for Rx ring.\n"); + goto fail; + } + error = bus_dmamap_load(cd->sge_rx_tag, cd->sge_rx_dmamap, + ld->sge_rx_ring, SGE_RX_RING_SZ, sge_dma_map_addr, + &ld->sge_rx_paddr, BUS_DMA_NOWAIT); + if (error != 0) { + device_printf(sc->sge_dev, + "could not load DMA'able memory for Rx ring.\n"); + } + + /* TX descriptor ring */ + error = bus_dma_tag_create(cd->sge_tag, + SGE_DESC_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + SGE_TX_RING_SZ, 1, /* maxsize,nsegments */ + SGE_TX_RING_SZ, /* maxsegsize */ + 0, /* flags */ + NULL, /* lockfunc */ + NULL, /* lockarg */ + &cd->sge_tx_tag); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create Rx ring DMA tag.\n"); + goto fail; + } + /* Allocate DMA'able memory and load DMA map for TX ring. */ + error = bus_dmamem_alloc(cd->sge_tx_tag, (void **)&ld->sge_tx_ring, + BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, + &cd->sge_tx_dmamap); + if (error != 0) { + device_printf(sc->sge_dev, + "could not allocate DMA'able memory for Tx ring.\n"); + goto fail; + } + error = bus_dmamap_load(cd->sge_tx_tag, cd->sge_tx_dmamap, + ld->sge_tx_ring, SGE_TX_RING_SZ, sge_dma_map_addr, + &ld->sge_tx_paddr, BUS_DMA_NOWAIT); + if (error != 0) { + device_printf(sc->sge_dev, + "could not load DMA'able memory for Rx ring.\n"); + goto fail; + } + + /* Create DMA tag for Tx buffers. */ + error = bus_dma_tag_create(cd->sge_tag, 1, 0, BUS_SPACE_MAXADDR, + BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES * SGE_MAXTXSEGS, + SGE_MAXTXSEGS, MCLBYTES, 0, NULL, NULL, &cd->sge_txmbuf_tag); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create Tx mbuf DMA tag.\n"); + goto fail; + } + + /* Create DMA tag for Rx buffers. */ + error = bus_dma_tag_create(cd->sge_tag, SGE_RX_BUF_ALIGN, 0, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, 1, + MCLBYTES, 0, NULL, NULL, &cd->sge_rxmbuf_tag); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create Rx mbuf DMA tag.\n"); + goto fail; + } + + /* Create DMA maps for Tx buffers. */ + for (i = 0; i < SGE_TX_RING_CNT; i++) { + error = bus_dmamap_create(cd->sge_txmbuf_tag, 0, + &cd->sge_tx_map[i]); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create Tx DMA map.\n"); + goto fail; + } + } + /* Create spare DMA map for Rx buffer. */ + error = bus_dmamap_create(cd->sge_rxmbuf_tag, 0, &cd->sge_rx_spare_map); + if (error != 0) { + device_printf(sc->sge_dev, + "could not create spare Rx DMA map.\n"); + goto fail; + } + /* Create DMA maps for Rx buffers. */ + for (i = 0; i < SGE_RX_RING_CNT; i++) { + error = bus_dmamap_create(cd->sge_rxmbuf_tag, 0, + &cd->sge_rx_map[i]); + if (error) { + device_printf(sc->sge_dev, + "could not create Rx DMA map.\n"); + goto fail; + } + } +fail: + return (error); +} + +static void +sge_dma_free(struct sge_softc *sc) +{ + struct sge_chain_data *cd; + struct sge_list_data *ld; + int i; + + cd = &sc->sge_cdata; + ld = &sc->sge_ldata; + /* Rx ring. */ + if (cd->sge_rx_tag != NULL) { + if (cd->sge_rx_dmamap != NULL) + bus_dmamap_unload(cd->sge_rx_tag, cd->sge_rx_dmamap); + if (cd->sge_rx_dmamap != NULL && ld->sge_rx_ring != NULL) + bus_dmamem_free(cd->sge_rx_tag, ld->sge_rx_ring, + cd->sge_rx_dmamap); + ld->sge_rx_ring = NULL; + cd->sge_rx_dmamap = NULL; + bus_dma_tag_destroy(cd->sge_rx_tag); + cd->sge_rx_tag = NULL; + } + /* Tx ring. */ + if (cd->sge_tx_tag != NULL) { + if (cd->sge_tx_dmamap != NULL) + bus_dmamap_unload(cd->sge_tx_tag, cd->sge_tx_dmamap); + if (cd->sge_tx_dmamap != NULL && ld->sge_tx_ring != NULL) + bus_dmamem_free(cd->sge_tx_tag, ld->sge_tx_ring, + cd->sge_tx_dmamap); + ld->sge_tx_ring = NULL; + cd->sge_tx_dmamap = NULL; + bus_dma_tag_destroy(cd->sge_tx_tag); + cd->sge_tx_tag = NULL; + } + /* Rx buffers. */ + if (cd->sge_rxmbuf_tag != NULL) { + for (i = 0; i < SGE_RX_RING_CNT; i++) { + if (cd->sge_rx_map[i] != NULL) { + bus_dmamap_destroy(cd->sge_rxmbuf_tag, + cd->sge_rx_map[i]); + cd->sge_rx_map[i] = NULL; + } + } + if (cd->sge_rx_spare_map != NULL) { + bus_dmamap_destroy(cd->sge_rxmbuf_tag, + cd->sge_rx_spare_map); + cd->sge_rx_spare_map = NULL; + } + bus_dma_tag_destroy(cd->sge_rxmbuf_tag); + cd->sge_rxmbuf_tag = NULL; + } + /* Tx buffers. */ + if (cd->sge_txmbuf_tag != NULL) { + for (i = 0; i < SGE_TX_RING_CNT; i++) { + if (cd->sge_tx_map[i] != NULL) { + bus_dmamap_destroy(cd->sge_txmbuf_tag, + cd->sge_tx_map[i]); + cd->sge_tx_map[i] = NULL; + } + } + bus_dma_tag_destroy(cd->sge_txmbuf_tag); + cd->sge_txmbuf_tag = NULL; + } + if (cd->sge_tag != NULL) + bus_dma_tag_destroy(cd->sge_tag); + cd->sge_tag = NULL; +} + +/* + * Initialize the TX descriptors. + */ +static int +sge_list_tx_init(struct sge_softc *sc) +{ + struct sge_list_data *ld; + struct sge_chain_data *cd; + + SGE_LOCK_ASSERT(sc); + ld = &sc->sge_ldata; + cd = &sc->sge_cdata; + bzero(ld->sge_tx_ring, SGE_TX_RING_SZ); + ld->sge_tx_ring[SGE_TX_RING_CNT - 1].sge_flags = htole32(RING_END); + bus_dmamap_sync(cd->sge_tx_tag, cd->sge_tx_dmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + cd->sge_tx_prod = 0; + cd->sge_tx_cons = 0; + cd->sge_tx_cnt = 0; + return (0); +} + +static int +sge_list_tx_free(struct sge_softc *sc) +{ + struct sge_chain_data *cd; + int i; + + SGE_LOCK_ASSERT(sc); + cd = &sc->sge_cdata; + for (i = 0; i < SGE_TX_RING_CNT; i++) { + if (cd->sge_tx_mbuf[i] != NULL) { + bus_dmamap_sync(cd->sge_txmbuf_tag, + cd->sge_tx_map[i], BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(cd->sge_txmbuf_tag, + cd->sge_tx_map[i]); + m_free(cd->sge_tx_mbuf[i]); + cd->sge_tx_mbuf[i] = NULL; + } + } + + return (0); +} + +/* + * Initialize the RX descriptors and allocate mbufs for them. Note that + * we arrange the descriptors in a closed ring, so that the last descriptor + * has RING_END flag set. + */ +static int +sge_list_rx_init(struct sge_softc *sc) +{ + struct sge_chain_data *cd; + int i; + + SGE_LOCK_ASSERT(sc); + cd = &sc->sge_cdata; + cd->sge_rx_cons = 0; + bzero(sc->sge_ldata.sge_rx_ring, SGE_RX_RING_SZ); + for (i = 0; i < SGE_RX_RING_CNT; i++) { + if (sge_newbuf(sc, i) != 0) + return (ENOBUFS); + } + bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + return (0); +} + +static int +sge_list_rx_free(struct sge_softc *sc) +{ + struct sge_chain_data *cd; + int i; + + SGE_LOCK_ASSERT(sc); + cd = &sc->sge_cdata; + for (i = 0; i < SGE_RX_RING_CNT; i++) { + if (cd->sge_rx_mbuf[i] != NULL) { + bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[i], + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(cd->sge_rxmbuf_tag, + cd->sge_rx_map[i]); + m_free(cd->sge_rx_mbuf[i]); + cd->sge_rx_mbuf[i] = NULL; + } + } + return (0); +} + +/* + * Initialize an RX descriptor and attach an MBUF cluster. + */ +static int +sge_newbuf(struct sge_softc *sc, int prod) +{ + struct mbuf *m; + struct sge_desc *desc; + struct sge_chain_data *cd; + bus_dma_segment_t segs[1]; + bus_dmamap_t map; + int error, nsegs; + + SGE_LOCK_ASSERT(sc); + + cd = &sc->sge_cdata; + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); + m->m_len = m->m_pkthdr.len = MCLBYTES; + m_adj(m, SGE_RX_BUF_ALIGN); + error = bus_dmamap_load_mbuf_sg(cd->sge_rxmbuf_tag, + cd->sge_rx_spare_map, m, segs, &nsegs, 0); + if (error != 0) { + m_freem(m); + return (error); + } + KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); + if (cd->sge_rx_mbuf[prod] != NULL) { + bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod], + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod]); + } + map = cd->sge_rx_map[prod]; + cd->sge_rx_map[prod] = cd->sge_rx_spare_map; + cd->sge_rx_spare_map = map; + bus_dmamap_sync(cd->sge_rxmbuf_tag, cd->sge_rx_map[prod], + BUS_DMASYNC_PREREAD); + cd->sge_rx_mbuf[prod] = m; + + desc = &sc->sge_ldata.sge_rx_ring[prod]; + desc->sge_sts_size = 0; + desc->sge_ptr = htole32(SGE_ADDR_LO(segs[0].ds_addr)); + desc->sge_flags = htole32(segs[0].ds_len); + if (prod == SGE_RX_RING_CNT - 1) + desc->sge_flags |= htole32(RING_END); + desc->sge_cmdsts = htole32(RDC_OWN | RDC_INTR | RDC_IP_CSUM | + RDC_TCP_CSUM | RDC_UDP_CSUM); + return (0); +} + +#ifndef __NO_STRICT_ALIGNMENT +static __inline void +sge_fixup_rx(struct mbuf *m) +{ + int i; + uint16_t *src, *dst; + + src = mtod(m, uint16_t *); + dst = src - 3; + + for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) + *dst++ = *src++; + + m->m_data -= (SGE_RX_BUF_ALIGN - ETHER_ALIGN); +} +#endif + +static __inline void +sge_discard_rxbuf(struct sge_softc *sc, int index) +{ + struct sge_desc *desc; + + desc = &sc->sge_ldata.sge_rx_ring[index]; + desc->sge_sts_size = 0; + desc->sge_flags = htole32(MCLBYTES - SGE_RX_BUF_ALIGN); + if (index == SGE_RX_RING_CNT - 1) + desc->sge_flags |= htole32(RING_END); + desc->sge_cmdsts = htole32(RDC_OWN | RDC_INTR | RDC_IP_CSUM | + RDC_TCP_CSUM | RDC_UDP_CSUM); +} + +/* + * A frame has been uploaded: pass the resulting mbuf chain up to + * the higher level protocols. + */ +static void +sge_rxeof(struct sge_softc *sc) +{ + struct ifnet *ifp; + struct mbuf *m; + struct sge_chain_data *cd; + struct sge_desc *cur_rx; + uint32_t rxinfo, rxstat; + int cons, prog; + + SGE_LOCK_ASSERT(sc); + + ifp = sc->sge_ifp; + cd = &sc->sge_cdata; + + bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + cons = cd->sge_rx_cons; + for (prog = 0; prog < SGE_RX_RING_CNT; prog++, + SGE_INC(cons, SGE_RX_RING_CNT)) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + cur_rx = &sc->sge_ldata.sge_rx_ring[cons]; + rxinfo = le32toh(cur_rx->sge_cmdsts); + if ((rxinfo & RDC_OWN) != 0) + break; + rxstat = le32toh(cur_rx->sge_sts_size); + if (SGE_RX_ERROR(rxstat) != 0 || SGE_RX_NSEGS(rxstat) != 1) { + /* XXX We don't support multi-segment frames yet. */ +#ifdef SGE_SHOW_ERRORS + device_printf(sc->sge_dev, "Rx error : 0x%b\n", rxstat, + RX_ERR_BITS); +#endif + sge_discard_rxbuf(sc, cons); + ifp->if_ierrors++; + continue; + } + m = cd->sge_rx_mbuf[cons]; + if (sge_newbuf(sc, cons) != 0) { + sge_discard_rxbuf(sc, cons); + ifp->if_iqdrops++; + continue; + } + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) { + if ((rxinfo & RDC_IP_CSUM) != 0 && + (rxinfo & RDC_IP_CSUM_OK) != 0) + m->m_pkthdr.csum_flags |= + CSUM_IP_CHECKED | CSUM_IP_VALID; + if (((rxinfo & RDC_TCP_CSUM) != 0 && + (rxinfo & RDC_TCP_CSUM_OK) != 0) || + ((rxinfo & RDC_UDP_CSUM) != 0 && + (rxinfo & RDC_UDP_CSUM_OK) != 0)) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } + } + /* + * TODO : VLAN hardware tag stripping. + */ + m->m_pkthdr.len = m->m_len = + SGE_RX_BYTES(rxstat) - ETHER_CRC_LEN; +#ifndef __NO_STRICT_ALIGNMENT + sge_fixup_rx(m); +#endif + m->m_pkthdr.rcvif = ifp; + ifp->if_ipackets++; + SGE_UNLOCK(sc); + (*ifp->if_input)(ifp, m); + SGE_LOCK(sc); + } + + if (prog > 0) { + bus_dmamap_sync(cd->sge_rx_tag, cd->sge_rx_dmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + cd->sge_rx_cons = cons; + } +} + +/* + * A frame was downloaded to the chip. It's safe for us to clean up + * the list buffers. + */ +static void +sge_txeof(struct sge_softc *sc) +{ + struct ifnet *ifp; + struct sge_list_data *ld; + struct sge_chain_data *cd; + uint32_t txstat; + int cons, prod; + + SGE_LOCK_ASSERT(sc); + + ifp = sc->sge_ifp; + ld = &sc->sge_ldata; + cd = &sc->sge_cdata; + + if (cd->sge_tx_cnt == 0) + return; + bus_dmamap_sync(cd->sge_tx_tag, cd->sge_tx_dmamap, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + cons = cd->sge_tx_cons; + prod = cd->sge_tx_prod; + for (; cons != prod; SGE_INC(cons, SGE_TX_RING_CNT)) { + txstat = le32toh(ld->sge_tx_ring[cons].sge_cmdsts); + if ((txstat & TDC_OWN) != 0) + break; + cd->sge_tx_cnt--; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + if (cd->sge_tx_mbuf[cons] != NULL) { + bus_dmamap_sync(cd->sge_txmbuf_tag, + cd->sge_tx_map[cons], BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(cd->sge_txmbuf_tag, + cd->sge_tx_map[cons]); + m_freem(cd->sge_tx_mbuf[cons]); + cd->sge_tx_mbuf[cons] = NULL; + if (SGE_TX_ERROR(txstat) != 0) { +#ifdef SGE_SHOW_ERRORS + device_printf(sc->sge_dev, "Tx error : 0x%b\n", + txstat, TX_ERR_BITS); +#endif + ifp->if_oerrors++; + } else { +#ifdef notyet + ifp->if_collisions += (txstat & 0xFFFF) - 1; +#endif + ifp->if_opackets++; + } + } + + } + cd->sge_tx_cons = cons; + if (cd->sge_tx_cnt == 0) + sc->sge_timer = 0; +} + +static void +sge_tick(void *arg) +{ + struct sge_softc *sc; + struct mii_data *mii; + struct ifnet *ifp; + + sc = arg; + SGE_LOCK_ASSERT(sc); + + ifp = sc->sge_ifp; + mii = device_get_softc(sc->sge_miibus); + mii_tick(mii); + if ((sc->sge_flags & SGE_FLAG_LINK) == 0) { + sge_miibus_statchg(sc->sge_dev); + if ((sc->sge_flags & SGE_FLAG_LINK) != 0 && + !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + sge_start_locked(ifp); + } + /* + * Reclaim transmitted frames here as we do not request + * Tx completion interrupt for every queued frames to + * reduce excessive interrupts. + */ + sge_txeof(sc); + sge_watchdog(sc); + callout_reset(&sc->sge_stat_ch, hz, sge_tick, sc); +} + +static void +sge_intr(void *arg) +{ + struct sge_softc *sc; + struct ifnet *ifp; + uint32_t status; + + sc = arg; + SGE_LOCK(sc); + ifp = sc->sge_ifp; + + status = CSR_READ_4(sc, IntrStatus); + if (status == 0xFFFFFFFF || (status & SGE_INTRS) == 0) { + /* Not ours. */ + SGE_UNLOCK(sc); + return; + } + /* Acknowledge interrupts. */ + CSR_WRITE_4(sc, IntrStatus, status); + /* Disable further interrupts. */ + CSR_WRITE_4(sc, IntrMask, 0); + /* + * It seems the controller supports some kind of interrupt + * moderation mechanism but we still don't know how to + * enable that. To reduce number of generated interrupts + * under load we check pending interrupts in a loop. This + * will increase number of register access and is not correct + * way to handle interrupt moderation but there seems to be + * no other way at this time. + */ + for (;;) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + break; + if ((status & (INTR_RX_DONE | INTR_RX_IDLE)) != 0) { + sge_rxeof(sc); + /* Wakeup Rx MAC. */ + if ((status & INTR_RX_IDLE) != 0) + CSR_WRITE_4(sc, RX_CTL, + 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB); + } + if ((status & (INTR_TX_DONE | INTR_TX_IDLE)) != 0) + sge_txeof(sc); + status = CSR_READ_4(sc, IntrStatus); + if ((status & SGE_INTRS) == 0) + break; + /* Acknowledge interrupts. */ + CSR_WRITE_4(sc, IntrStatus, status); + } + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + /* Re-enable interrupts */ + CSR_WRITE_4(sc, IntrMask, SGE_INTRS); + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) + sge_start_locked(ifp); + } + SGE_UNLOCK(sc); +} + +/* + * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data + * pointers to the fragment pointers. + */ +static int +sge_encap(struct sge_softc *sc, struct mbuf **m_head) +{ + struct mbuf *m; + struct sge_desc *desc; + bus_dma_segment_t txsegs[SGE_MAXTXSEGS]; + bus_dmamap_t map; + uint32_t cflags; + int error, nsegs, prod; + + SGE_LOCK_ASSERT(sc); + + prod = sc->sge_cdata.sge_tx_prod; + map = sc->sge_cdata.sge_tx_map[prod]; + /* + * Reading Windows inf file indicates SiS controller supports + * TSO, VLAN hardware tag insertion/stripping, interrupt + * moderation and Tx/Rx checksum offloading. Unfortunately + * vendor didn't release these information so we're guessing + * descriptor usage with trial and errors. + * + * Controller seems to support multi-fragmented buffers but + * don't know how to enable that feature so limit number of + * fragmented Tx buffers to single buffer until we understand + * the controller internals. + * I assume the controller can pad zero bytes if frame length + * is less than 60 bytes and I also think the controller has + * no Tx buffer alignment limitation. - Need testing! + */ + if ((*m_head)->m_next != NULL) { + m = m_defrag(*m_head, M_DONTWAIT); + if (m == NULL) { + m_freem(*m_head); + *m_head = NULL; + return (ENOBUFS); + } + *m_head = m; + } + error = bus_dmamap_load_mbuf_sg(sc->sge_cdata.sge_tx_tag, map, + *m_head, txsegs, &nsegs, 0); + if (error != 0) { + m_freem(*m_head); + *m_head = NULL; + return (error); + } + /* Check descriptor overrun. */ + if (sc->sge_cdata.sge_tx_cnt + nsegs >= SGE_TX_RING_CNT) { + bus_dmamap_unload(sc->sge_cdata.sge_tx_tag, map); + return (ENOBUFS); + } + bus_dmamap_sync(sc->sge_cdata.sge_tx_tag, map, BUS_DMASYNC_PREWRITE); + + cflags = 0; + if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP) + cflags |= TDC_IP_CSUM; + if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP) + cflags |= TDC_TCP_CSUM; + if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP) + cflags |= TDC_UDP_CSUM; + desc = &sc->sge_ldata.sge_tx_ring[prod]; + desc->sge_sts_size = htole32((*m_head)->m_pkthdr.len); + desc->sge_ptr = htole32(SGE_ADDR_LO(txsegs[0].ds_addr)); + desc->sge_flags = htole32(txsegs[0].ds_len); + if (prod == SGE_TX_RING_CNT - 1) + desc->sge_flags |= htole32(RING_END); + desc->sge_cmdsts = htole32(TDC_DEF | TDC_CRC | TDC_PAD | cflags); +#if 1 + if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0) + desc->sge_cmdsts |= htole32(TDC_BST); +#else + if ((sc->sge_flags & SGE_FLAG_FDX) == 0) { + desc->sge_cmdsts |= htole32(TDC_COL | TDC_CRS | TDC_BKF); + if ((sc->sge_flags & SGE_FLAG_SPEED_1000) != 0) + desc->sge_cmdsts |= htole32(TDC_EXT | TDC_BST); + } +#endif + /* Request interrupt and give ownership to controller. */ + if ((prod % SGE_TX_INTR_FRAMES) == 0) + desc->sge_cmdsts |= htole32(TDC_OWN | TDC_INTR); + else + desc->sge_cmdsts |= htole32(TDC_OWN); + sc->sge_cdata.sge_tx_mbuf[prod] = *m_head; + sc->sge_cdata.sge_tx_cnt++; + SGE_INC(sc->sge_cdata.sge_tx_prod, SGE_TX_RING_CNT); + return (0); +} + +static void +sge_start(struct ifnet *ifp) +{ + struct sge_softc *sc; + + sc = ifp->if_softc; + SGE_LOCK(sc); + sge_start_locked(ifp); + SGE_UNLOCK(sc); +} + +static void +sge_start_locked(struct ifnet *ifp) +{ + struct sge_softc *sc; + struct mbuf *m_head; + int queued = 0; + + sc = ifp->if_softc; + SGE_LOCK_ASSERT(sc); + + if ((sc->sge_flags & SGE_FLAG_LINK) == 0 || + (ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING) + return; + + for (queued = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd); ) { + if (sc->sge_cdata.sge_tx_cnt == SGE_TX_RING_CNT - 1) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); + if (m_head == NULL) + break; + if (sge_encap(sc, &m_head)) { + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + queued++; + /* + * If there's a BPF listener, bounce a copy of this frame + * to him. + */ + BPF_MTAP(ifp, m_head); + } + + if (queued > 0) { + bus_dmamap_sync(sc->sge_cdata.sge_tx_tag, + sc->sge_cdata.sge_tx_dmamap, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB | TX_CTL_POLL); + sc->sge_timer = 5; + } +} + +static void +sge_init(void *arg) +{ + struct sge_softc *sc; + + sc = arg; + SGE_LOCK(sc); + sge_init_locked(sc); + SGE_UNLOCK(sc); +} + +static void +sge_init_locked(struct sge_softc *sc) +{ + struct ifnet *ifp; + struct mii_data *mii; + int i; + + SGE_LOCK_ASSERT(sc); + ifp = sc->sge_ifp; + mii = device_get_softc(sc->sge_miibus); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + return; + /* + * Cancel pending I/O and free all RX/TX buffers. + */ + sge_stop(sc); + sge_reset(sc); + + /* Init circular RX list. */ + if (sge_list_rx_init(sc) == ENOBUFS) { + device_printf(sc->sge_dev, "no memory for Rx buffers\n"); + sge_stop(sc); + return; + } + /* Init TX descriptors. */ + sge_list_tx_init(sc); + /* + * Load the address of the RX and TX lists. + */ + CSR_WRITE_4(sc, TX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_tx_paddr)); + CSR_WRITE_4(sc, RX_DESC, SGE_ADDR_LO(sc->sge_ldata.sge_rx_paddr)); + + CSR_WRITE_4(sc, TxMacControl, 0x60); + CSR_WRITE_4(sc, 0x6c, 0); + CSR_WRITE_4(sc, RxWakeOnLan, 0); + CSR_WRITE_4(sc, RxWakeOnLanData, 0); + /* Allow receiving VLAN frames. */ + CSR_WRITE_2(sc, RxMPSControl, ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN); + + for (i = 0; i < ETHER_ADDR_LEN; i++) + CSR_WRITE_1(sc, RxMacAddr + i, IF_LLADDR(ifp)[i]); + sge_rxfilter(sc); + + /* Initialize default speed/duplex information. */ + if ((sc->sge_flags & SGE_FLAG_FASTETHER) == 0) + sc->sge_flags |= SGE_FLAG_SPEED_1000; + sc->sge_flags |= SGE_FLAG_FDX; + if ((sc->sge_flags & SGE_FLAG_RGMII) != 0) + CSR_WRITE_4(sc, StationControl, 0x04008001); + else + CSR_WRITE_4(sc, StationControl, 0x04000001); + /* + * XXX Try to mitigate interrupts. + */ + if (sc->sge_intrcontrol != 0) + CSR_WRITE_4(sc, IntrControl, sc->sge_intrcontrol); + if (sc->sge_intrtimer != 0) + CSR_WRITE_4(sc, IntrTimer, sc->sge_intrtimer); + + /* + * Clear and enable interrupts. + */ + CSR_WRITE_4(sc, IntrStatus, 0xFFFFFFFF); + CSR_WRITE_4(sc, IntrMask, SGE_INTRS); + + /* Enable receiver and transmitter. */ + CSR_WRITE_4(sc, TX_CTL, 0x1a00 | TX_CTL_ENB); + CSR_WRITE_4(sc, RX_CTL, 0x1a00 | 0x000c | RX_CTL_POLL | RX_CTL_ENB); + + ifp->if_drv_flags |= IFF_DRV_RUNNING; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + + sc->sge_flags &= ~SGE_FLAG_LINK; + mii_mediachg(mii); + callout_reset(&sc->sge_stat_ch, hz, sge_tick, sc); +} + +/* + * Set media options. + */ +static int +sge_ifmedia_upd(struct ifnet *ifp) +{ + struct sge_softc *sc; + struct mii_data *mii; + int error; + + sc = ifp->if_softc; + SGE_LOCK(sc); + mii = device_get_softc(sc->sge_miibus); + sc->sge_flags &= ~SGE_FLAG_LINK; + if (mii->mii_instance) { + struct mii_softc *miisc; + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + mii_phy_reset(miisc); + } + error = mii_mediachg(mii); + SGE_UNLOCK(sc); + + return (error); +} + +/* + * Report current media status. + */ +static void +sge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +{ + struct sge_softc *sc; + struct mii_data *mii; + + sc = ifp->if_softc; + SGE_LOCK(sc); + mii = device_get_softc(sc->sge_miibus); + if ((ifp->if_flags & IFF_UP) == 0) { + SGE_UNLOCK(sc); + return; + } + mii_pollstat(mii); + SGE_UNLOCK(sc); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; +} + +static int +sge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) +{ + struct sge_softc *sc; + struct ifreq *ifr; + struct mii_data *mii; + int error = 0, mask; + + sc = ifp->if_softc; + ifr = (struct ifreq *)data; + + switch(command) { + case SIOCSIFFLAGS: + SGE_LOCK(sc); + if ((ifp->if_flags & IFF_UP) != 0) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 && + ((ifp->if_flags ^ sc->sge_if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) != 0) + sge_rxfilter(sc); + else + sge_init_locked(sc); + } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + sge_stop(sc); + sc->sge_if_flags = ifp->if_flags; + SGE_UNLOCK(sc); + break; + case SIOCSIFCAP: + SGE_LOCK(sc); + mask = ifr->ifr_reqcap ^ ifp->if_capenable; + if ((mask & IFCAP_TXCSUM) != 0 && + (ifp->if_capabilities & IFCAP_TXCSUM) != 0) { + ifp->if_capenable ^= IFCAP_TXCSUM; + if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) + ifp->if_hwassist |= SGE_CSUM_FEATURES; + else + ifp->if_hwassist &= ~SGE_CSUM_FEATURES; + } + if ((mask & IFCAP_RXCSUM) != 0 && + (ifp->if_capabilities & IFCAP_RXCSUM) != 0) + ifp->if_capenable ^= IFCAP_RXCSUM; + SGE_UNLOCK(sc); + break; + case SIOCADDMULTI: + case SIOCDELMULTI: + SGE_LOCK(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + sge_rxfilter(sc); + SGE_UNLOCK(sc); + break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + mii = device_get_softc(sc->sge_miibus); + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); + break; + default: + error = ether_ioctl(ifp, command, data); + break; + } + + return (error); +} + +static void +sge_watchdog(struct sge_softc *sc) +{ + struct ifnet *ifp; + + SGE_LOCK_ASSERT(sc); + if (sc->sge_timer == 0 || --sc->sge_timer > 0) + return; + + ifp = sc->sge_ifp; + if ((sc->sge_flags & SGE_FLAG_LINK) == 0) { + if (1 || bootverbose) + device_printf(sc->sge_dev, + "watchdog timeout (lost link)\n"); + ifp->if_oerrors++; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sge_init_locked(sc); + return; + } + device_printf(sc->sge_dev, "watchdog timeout\n"); + ifp->if_oerrors++; + + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + sge_init_locked(sc); + if (!IFQ_DRV_IS_EMPTY(&sc->sge_ifp->if_snd)) + sge_start_locked(ifp); +} + +/* + * Stop the adapter and free any mbufs allocated to the + * RX and TX lists. + */ +static void +sge_stop(struct sge_softc *sc) +{ + struct ifnet *ifp; + + ifp = sc->sge_ifp; + + SGE_LOCK_ASSERT(sc); + + sc->sge_timer = 0; + callout_stop(&sc->sge_stat_ch); + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + CSR_WRITE_4(sc, IntrMask, 0); + CSR_READ_4(sc, IntrMask); + CSR_WRITE_4(sc, IntrStatus, 0xffffffff); + /* Stop TX/RX MAC. */ + CSR_WRITE_4(sc, TX_CTL, 0x1a00); + CSR_WRITE_4(sc, RX_CTL, 0x1a00); + /* XXX Can we assume active DMA cycles gone? */ + DELAY(2000); + CSR_WRITE_4(sc, IntrMask, 0); + CSR_WRITE_4(sc, IntrStatus, 0xffffffff); + + sc->sge_flags &= ~SGE_FLAG_LINK; + sge_list_rx_free(sc); + sge_list_tx_free(sc); +} diff --git a/sys/dev/sge/if_sgereg.h b/sys/dev/sge/if_sgereg.h new file mode 100644 index 00000000000..29253e0f892 --- /dev/null +++ b/sys/dev/sge/if_sgereg.h @@ -0,0 +1,350 @@ +/*- + * Copyright (c) 2008, 2009, 2010 Nikolay Denev + * Copyright (c) 2007, 2008 Alexander Pohoyda + * Copyright (c) 1997, 1998, 1999 + * Bill Paul . All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AUTHORS OR + * THE VOICES IN THEIR HEADS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _IF_SGEREG_H +#define _IF_SGEREG_H + +/* + * SiS PCI vendor ID. + */ +#define SIS_VENDORID 0x1039 + +/* + * SiS PCI device IDs + */ +#define SIS_DEVICEID_190 0x0190 +#define SIS_DEVICEID_191 0x0191 + +#define TX_CTL 0x00 +#define TX_DESC 0x04 +#define Reserved0 0x08 +#define TX_NEXT 0x0c + +#define RX_CTL 0x10 +#define RX_DESC 0x14 +#define Reserved1 0x18 +#define RX_NEXT 0x1c + +#define IntrStatus 0x20 +#define IntrMask 0x24 +#define IntrControl 0x28 +#define IntrTimer 0x2c + +#define PMControl 0x30 +#define Reserved2 0x34 +#define ROMControl 0x38 +#define ROMInterface 0x3c +#define StationControl 0x40 +#define GMIIControl 0x44 +#define GMacIOCR 0x48 +#define GMacIOCTL 0x4c +#define TxMacControl 0x50 +#define TxMacTimeLimit 0x54 +#define RGMIIDelay 0x58 +#define Reserved3 0x5c +#define RxMacControl 0x60 /* 1 WORD */ +#define RxMacAddr 0x62 /* 6x BYTE */ +#define RxHashTable 0x68 /* 1 LONG */ +#define RxHashTable2 0x6c /* 1 LONG */ +#define RxWakeOnLan 0x70 +#define RxWakeOnLanData 0x74 +#define RxMPSControl 0x78 +#define Reserved4 0x7c + +/* + * IntrStatus Register Content + */ +#define INTR_SOFT 0x40000000 +#define INTR_TIMER 0x20000000 +#define INTR_PAUSE_FRAME 0x00080000 +#define INTR_MAGIC_FRAME 0x00040000 +#define INTR_WAKE_FRAME 0x00020000 +#define INTR_LINK 0x00010000 +#define INTR_RX_IDLE 0x00000080 +#define INTR_RX_DONE 0x00000040 +#define INTR_TXQ1_IDLE 0x00000020 +#define INTR_TXQ1_DONE 0x00000010 +#define INTR_TX_IDLE 0x00000008 +#define INTR_TX_DONE 0x00000004 +#define INTR_RX_HALT 0x00000002 +#define INTR_TX_HALT 0x00000001 + +#define SGE_INTRS \ + (INTR_RX_IDLE | INTR_RX_DONE | INTR_TXQ1_IDLE | \ + INTR_TXQ1_DONE |INTR_TX_IDLE | INTR_TX_DONE | \ + INTR_TX_HALT | INTR_RX_HALT) + +/* + * RxStatusDesc Register Content + */ +#define RxRES 0x00200000 +#define RxCRC 0x00080000 +#define RxRUNT 0x00100000 +#define RxRWT 0x00400000 + +/* + * RX_CTL Register Content + */ +#define RX_CTL_POLL 0x00000010 +#define RX_CTL_ENB 0x00000001 + +/* + * TX_CTL Register Content + */ +#define TX_CTL_POLL 0x00000010 +#define TX_CTL_ENB 0x00000001 + +/* + * RxMacControl Register Content + */ +#define AcceptBroadcast 0x0800 +#define AcceptMulticast 0x0400 +#define AcceptMyPhys 0x0200 +#define AcceptAllPhys 0x0100 +#define AcceptErr 0x0020 +#define AcceptRunt 0x0010 + +/* Station control register. */ +#define SC_LOOPBACK 0x80000000 +#define SC_RGMII 0x00008000 +#define SC_FDX 0x00001000 +#define SC_SPEED_MASK 0x00000c00 +#define SC_SPEED_10 0x00000400 +#define SC_SPEED_100 0x00000800 +#define SC_SPEED_1000 0x00000c00 + +/* + * Gigabit Media Independent Interface CTL register + */ +#define GMI_DATA 0xffff0000 +#define GMI_DATA_SHIFT 16 +#define GMI_REG 0x0000f800 +#define GMI_REG_SHIFT 11 +#define GMI_PHY 0x000007c0 +#define GMI_PHY_SHIFT 6 +#define GMI_OP_WR 0x00000020 +#define GMI_OP_RD 0x00000000 +#define GMI_REQ 0x00000010 +#define GMI_MDIO 0x00000008 +#define GMI_MDDIR 0x00000004 +#define GMI_MDC 0x00000002 +#define GMI_MDEN 0x00000001 + +/* Tx descriptor command bits. */ +#define TDC_OWN 0x80000000 +#define TDC_INTR 0x40000000 +#define TDC_THOL3 0x30000000 +#define TDC_THOL2 0x20000000 +#define TDC_THOL1 0x10000000 +#define TDC_THOL0 0x00000000 +#define TDC_LS 0x08000000 +#define TDC_IP_CSUM 0x04000000 +#define TDC_TCP_CSUM 0x02000000 +#define TDC_UDP_CSUM 0x01000000 +#define TDC_BST 0x00800000 +#define TDC_EXT 0x00400000 +#define TDC_DEF 0x00200000 +#define TDC_BKF 0x00100000 +#define TDC_CRS 0x00080000 +#define TDC_COL 0x00040000 +#define TDC_CRC 0x00020000 +#define TDC_PAD 0x00010000 + +#define SGE_TX_INTR_FRAMES 32 + +/* + * TX descriptor status bits. + */ +#define TDS_OWC 0x00080000 +#define TDS_ABT 0x00040000 +#define TDS_FIFO 0x00020000 +#define TDS_CRS 0x00010000 +#define TDS_COLLS 0x0000ffff +#define SGE_TX_ERROR(x) ((x) & (TDS_OWC | TDS_ABT | TDS_FIFO | TDS_CRS)) +#define TX_ERR_BITS "\20" \ + "\21CRS\22FIFO\23ABT\24OWC" + +/* Rx descriptor command bits. */ +#define RDC_OWN 0x80000000 +#define RDC_INTR 0x40000000 +#define RDC_IP_CSUM 0x20000000 +#define RDC_TCP_CSUM 0x10000000 +#define RDC_UDP_CSUM 0x08000000 +#define RDC_IP_CSUM_OK 0x04000000 +#define RDC_TCP_CSUM_OK 0x02000000 +#define RDC_UDP_CSUM_OK 0x01000000 +#define RDC_WAKEUP 0x00400000 +#define RDC_MAGIC 0x00200000 +#define RDC_PAUSE 0x00100000 +#define RDC_BCAST 0x000c0000 +#define RDC_MCAST 0x00080000 +#define RDC_UCAST 0x00040000 +#define RDC_CRCOFF 0x00020000 +#define RDC_PREADD 0x00010000 + +/* + * RX descriptor status bits + */ +#define RDS_TAGON 0x80000000 +#define RDS_DESCS 0x3f000000 +#define RDS_ABORT 0x00800000 +#define RDS_SHORT 0x00400000 +#define RDS_LIMIT 0x00200000 +#define RDS_MIIER 0x00100000 +#define RDS_OVRUN 0x00080000 +#define RDS_NIBON 0x00040000 +#define RDS_COLON 0x00020000 +#define RDS_CRCOK 0x00010000 +#define SGE_RX_ERROR(x) \ + ((x) & (RDS_COLON | RDS_NIBON | RDS_OVRUN | RDS_MIIER | \ + RDS_LIMIT | RDS_SHORT | RDS_ABORT)) +#define SGE_RX_NSEGS(x) (((x) & RDS_DESCS) >> 24) +#define RX_ERR_BITS "\20" \ + "\21CRCOK\22COLON\23NIBON\24OVRUN" \ + "\25MIIER\26LIMIT\27SHORT\30ABORT" \ + "\40TAGON" + +#define RING_END 0x80000000 +#define SGE_RX_BYTES(x) ((x) & 0xFFFF) +#define SGE_INC(x, y) (x) = (((x) + 1) % y) + +/* Taken from Solaris driver */ +#define EI_DATA 0xffff0000 +#define EI_DATA_SHIFT 16 +#define EI_OFFSET 0x0000fc00 +#define EI_OFFSET_SHIFT 10 +#define EI_OP 0x00000300 +#define EI_OP_SHIFT 8 +#define EI_OP_RD (2 << EI_OP_SHIFT) +#define EI_OP_WR (1 << EI_OP_SHIFT) +#define EI_REQ 0x00000080 +#define EI_DO 0x00000008 +#define EI_DI 0x00000004 +#define EI_CLK 0x00000002 +#define EI_CS 0x00000001 + +/* + * EEPROM Addresses + */ +#define EEPROMSignature 0x00 +#define EEPROMCLK 0x01 +#define EEPROMInfo 0x02 +#define EEPROMMACAddr 0x03 + +struct sge_desc { + uint32_t sge_sts_size; + uint32_t sge_cmdsts; + uint32_t sge_ptr; + uint32_t sge_flags; +}; + +#define SGE_RX_RING_CNT 256 /* [8, 1024] */ +#define SGE_TX_RING_CNT 256 /* [8, 8192] */ +#define SGE_DESC_ALIGN 16 +#define SGE_MAXTXSEGS 1 +#define SGE_RX_BUF_ALIGN sizeof(uint64_t) + +#define SGE_RX_RING_SZ (SGE_RX_RING_CNT * sizeof(struct sge_desc)) +#define SGE_TX_RING_SZ (SGE_TX_RING_CNT * sizeof(struct sge_desc)) +#define SGE_ADDR_LO(x) ((uint64_t) (x) & 0xFFFFFFFF) + +struct sge_list_data { + struct sge_desc *sge_rx_ring; + struct sge_desc *sge_tx_ring; + /* physical bus addresses of sge_rx_ring/sge_tx_ring */ + bus_addr_t sge_rx_paddr; + bus_addr_t sge_tx_paddr; +}; + +struct sge_chain_data { + bus_dma_tag_t sge_tag; + bus_dma_tag_t sge_rx_tag; + bus_dma_tag_t sge_tx_tag; + bus_dmamap_t sge_rx_dmamap; + bus_dmamap_t sge_tx_dmamap; + bus_dma_tag_t sge_txmbuf_tag; + bus_dma_tag_t sge_rxmbuf_tag; + struct mbuf *sge_rx_mbuf[SGE_RX_RING_CNT]; + struct mbuf *sge_tx_mbuf[SGE_TX_RING_CNT]; + bus_dmamap_t sge_rx_map[SGE_RX_RING_CNT]; + bus_dmamap_t sge_rx_spare_map; + bus_dmamap_t sge_tx_map[SGE_TX_RING_CNT]; + int sge_rx_cons; + int sge_tx_prod; + int sge_tx_cons; + int sge_tx_cnt; +}; + +struct sge_type { + uint16_t sge_vid; + uint16_t sge_did; + char *sge_name; +}; + +struct sge_softc { + struct ifnet *sge_ifp; /* interface info */ + struct resource *sge_res; + int sge_res_id; + int sge_res_type; + struct resource *sge_irq; + void *sge_intrhand; + device_t sge_dev; + device_t sge_miibus; + uint8_t sge_rev; + struct sge_list_data sge_ldata; + struct sge_chain_data sge_cdata; + struct callout sge_stat_ch; + int sge_timer; + int sge_flags; +#define SGE_FLAG_FASTETHER 0x0001 +#define SGE_FLAG_RGMII 0x0010 +#define SGE_FLAG_SPEED_1000 0x2000 +#define SGE_FLAG_FDX 0x4000 +#define SGE_FLAG_LINK 0x8000 + int sge_if_flags; + int sge_intrcontrol; + int sge_intrtimer; + struct mtx sge_mtx; +}; + +#define SGE_LOCK(_sc) mtx_lock(&(_sc)->sge_mtx) +#define SGE_UNLOCK(_sc) mtx_unlock(&(_sc)->sge_mtx) +#define SGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sge_mtx, MA_OWNED) + +#define SGE_TIMEOUT 1000 + +#endif /* _IF_SGEREG_H */ diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index d40d7c0fa9f..2bc296342c5 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -235,6 +235,7 @@ device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 device sf # Adaptec AIC-6915 (``Starfire'') +device sge # Silicon Integrated Systems SiS190/191 device sis # Silicon Integrated Systems SiS 900/SiS 7016 device sk # SysKonnect SK-984x & SK-982x gigabit Ethernet device ste # Sundance ST201 (D-Link DFE-550TX) diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 3af154c750b..83c7757c7e2 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -252,6 +252,7 @@ SUBDIR= ${_3dfx} \ sdhci \ sem \ sf \ + sge \ siba_bwn \ siis \ sis \ diff --git a/sys/modules/sge/Makefile b/sys/modules/sge/Makefile new file mode 100644 index 00000000000..5f8c5879554 --- /dev/null +++ b/sys/modules/sge/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/sge + +KMOD= if_sge +SRCS= if_sge.c device_if.h bus_if.h pci_if.h miibus_if.h + +.include From dec52eb94cc638ab4e4211d366ecde29b2fbc2b5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 14 Apr 2010 20:50:07 +0000 Subject: [PATCH 051/532] We don't need the definition for in_cksum repeated here since we get it from machine/in_cksum.h. This definition prevents us from using hand-tuned assembler versions of in_cksum. # this fixes the modules build on arm for ipfilter. --- sys/contrib/ipfilter/netinet/ip_compat.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/contrib/ipfilter/netinet/ip_compat.h b/sys/contrib/ipfilter/netinet/ip_compat.h index 31e5b114e00..35c9f68ffc0 100644 --- a/sys/contrib/ipfilter/netinet/ip_compat.h +++ b/sys/contrib/ipfilter/netinet/ip_compat.h @@ -975,7 +975,6 @@ typedef u_int32_t u_32_t; # define SPL_NET(x) ; # define SPL_IMP(x) ; # define SPL_SCHED(x) ; -extern int in_cksum __P((struct mbuf *, int)); # else # define SPL_SCHED(x) x = splhigh() # endif /* __FreeBSD_version >= 500043 */ From 451f0bf403f4a5bf37fdffac4da1ecd4aef7228b Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 14 Apr 2010 20:54:23 +0000 Subject: [PATCH 052/532] Add sge(4) to the list of supported network interface. --- usr.sbin/sysinstall/devices.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.sbin/sysinstall/devices.c b/usr.sbin/sysinstall/devices.c index a2b7939f048..8cf1fb30c49 100644 --- a/usr.sbin/sysinstall/devices.c +++ b/usr.sbin/sysinstall/devices.c @@ -150,6 +150,7 @@ static struct _devname { NETWORK("rue", "RealTek USB Ethernet card"), NETWORK("rum", "Ralink Technology USB IEEE 802.11 wireless adapter"), NETWORK("sf", "Adaptec AIC-6915 PCI Ethernet card"), + NETWORK("sge", "Silicon Integrated Systems SiS190/191 Ethernet"), NETWORK("sis", "SiS 900/SiS 7016 PCI Ethernet card"), #ifdef PC98 NETWORK("snc", "SONIC Ethernet card"), From d43a11879733cf48553f00c7b0029f57a3a59aa5 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Wed, 14 Apr 2010 20:55:33 +0000 Subject: [PATCH 053/532] Add a missing fragment in the tx msix handler to invoke another if all work is not done. Sync the igb driver with changes suggested by yongari and made in em, these made sense to be in both drivers. --- sys/dev/e1000/if_em.c | 11 ++++++++--- sys/dev/e1000/if_igb.c | 36 +++++++++++++++++++++++------------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 834e676a6af..1db90121ddb 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -93,7 +93,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "7.0.4"; +char em_driver_version[] = "7.0.5"; /********************************************************************* @@ -1484,12 +1484,17 @@ em_msix_tx(void *arg) { struct tx_ring *txr = arg; struct adapter *adapter = txr->adapter; + bool more; ++txr->tx_irq; EM_TX_LOCK(txr); - em_txeof(txr); + more = em_txeof(txr); EM_TX_UNLOCK(txr); - E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); + if (more) + taskqueue_enqueue(txr->tq, &txr->tx_task); + else + /* Reenable this interrupt */ + E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); return; } diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index 267590faf0e..e901bc24e2f 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -99,7 +99,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 1.9.4"; +char igb_driver_version[] = "version - 1.9.5"; /********************************************************************* @@ -758,8 +758,15 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) if (!adapter->link_active) return; - while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + /* Call cleanup if number of TX descriptors low */ + if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) + igb_txeof(txr); + while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + if (txr->tx_avail <= IGB_TX_OP_THRESHOLD) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -779,6 +786,7 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp) ETHER_BPF_MTAP(ifp, m_head); /* Set watchdog on */ + txr->watchdog_time = ticks; txr->watchdog_check = TRUE; } } @@ -817,8 +825,6 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m) /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; - else - i = curcpu % adapter->num_queues; txr = &adapter->tx_rings[i]; @@ -847,6 +853,10 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) return (err); } + /* Call cleanup if number of TX descriptors low */ + if (txr->tx_avail <= IGB_TX_CLEANUP_THRESHOLD) + igb_txeof(txr); + enq = 0; if (m == NULL) { next = drbr_dequeue(ifp, txr->br); @@ -856,6 +866,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) next = drbr_dequeue(ifp, txr->br); } else next = m; + /* Process the queue */ while (next != NULL) { if ((err = igb_xmit(txr, &next)) != 0) { @@ -877,6 +888,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) if (enq > 0) { /* Set the watchdog */ txr->watchdog_check = TRUE; + txr->watchdog_time = ticks; } return (err); } @@ -1248,19 +1260,13 @@ igb_handle_que(void *context, int pending) struct adapter *adapter = que->adapter; struct tx_ring *txr = que->txr; struct ifnet *ifp = adapter->ifp; - u32 loop = IGB_MAX_LOOP; bool more; - /* RX first */ - do { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { more = igb_rxeof(que, -1); - } while (loop-- && more); - if (IGB_TX_TRYLOCK(txr)) { - loop = IGB_MAX_LOOP; - do { - more = igb_txeof(txr); - } while (loop-- && more); + IGB_TX_LOCK(txr); + igb_txeof(txr); #if __FreeBSD_version >= 800000 igb_mq_start_locked(ifp, txr, NULL); #else @@ -1268,6 +1274,10 @@ igb_handle_que(void *context, int pending) igb_start_locked(txr, ifp); #endif IGB_TX_UNLOCK(txr); + if (more) { + taskqueue_enqueue(que->tq, &que->que_task); + return; + } } /* Reenable this interrupt */ From 9b00b6e1ee532360ba70ef40fe80232e3719b699 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 14 Apr 2010 21:27:48 +0000 Subject: [PATCH 054/532] Add sge(4) man page and hook up sge(4) to the build. Also add Xr to appropriate man pages. --- share/man/man4/Makefile | 1 + share/man/man4/altq.4 | 3 +- share/man/man4/miibus.4 | 5 +- share/man/man4/sge.4 | 120 ++++++++++++++++++++++++++++++++++++++++ share/man/man4/vlan.4 | 3 +- 5 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 share/man/man4/sge.4 diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 4c499847a02..c71a09740e7 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -350,6 +350,7 @@ MAN= aac.4 \ sem.4 \ ses.4 \ sf.4 \ + sge.4 \ si.4 \ siba.4 \ sio.4 \ diff --git a/share/man/man4/altq.4 b/share/man/man4/altq.4 index 8a568428d40..a618c966e89 100644 --- a/share/man/man4/altq.4 +++ b/share/man/man4/altq.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 26, 2009 +.Dd April 14, 2010 .Dt ALTQ 4 .Os .Sh NAME @@ -151,6 +151,7 @@ They have been applied to the following hardware drivers: .Xr rl 4 , .Xr rum 4 , .Xr sf 4 , +.Xr sge 4 , .Xr sis 4 , .Xr sk 4 , .Xr ste 4 , diff --git a/share/man/man4/miibus.4 b/share/man/man4/miibus.4 index ec939671677..5a385957231 100644 --- a/share/man/man4/miibus.4 +++ b/share/man/man4/miibus.4 @@ -8,7 +8,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 14, 2009 +.Dd April 14, 2010 .Dt MIIBUS 4 .Os .Sh NAME @@ -97,6 +97,8 @@ RealTek 8129/8139 RealTek RTL8150 USB To Fast Ethernet .It Xr sf 4 Adaptec AIC-6915 +.It Xr sge 4 +Silicon Integrated Systems SiS190/191 Ethernet .It Xr sis 4 Silicon Integrated Systems SiS 900/SiS 7016 .It Xr sk 4 @@ -158,6 +160,7 @@ but as a result are not well behaved newbus device drivers. .Xr rl 4 , .Xr rue 4 , .Xr sf 4 , +.Xr sge 4 , .Xr sis 4 , .Xr sk 4 , .Xr ste 4 , diff --git a/share/man/man4/sge.4 b/share/man/man4/sge.4 new file mode 100644 index 00000000000..a3d057d386c --- /dev/null +++ b/share/man/man4/sge.4 @@ -0,0 +1,120 @@ +.\" Copyright (c) 2010 Pyun YongHyeon +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 14, 2010 +.Dt SGE 4 +.Os +.Sh NAME +.Nm sge +.Nd Silicon Integrated Systems SiS190/191 Fast/Gigabit Ethernet driver +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device miibus" +.Cd "device sge" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +if_sge="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +device driver provides support for SiS190 Fast Ethernet +controllers and SiS191 Fast/Gigabit Ethernet controllers. +.Pp +All LOMs supported by the +.Nm +driver have TCP/UDP/IP checksum offload for transmit and receive. +Due to lack of documentation more offloading features like TCP +segmentation offload (TSO), hardware VLAN tag stripping/insertion +features, Wake On Lan (WOL), Jumbo frame and an interrupt moderation +mechanism are not supported yet. +.Pp +The +.Nm +driver supports the following media types: +.Bl -tag -width ".Cm 10baseT/UTP" +.It Cm autoselect +Enable autoselection of the media type and options. +The user can manually override +the autoselected mode by adding media options to +.Xr rc.conf 5 . +.It Cm 10baseT/UTP +Set 10Mbps operation. +.It Cm 100baseTX +Set 100Mbps (Fast Ethernet) operation. +.It Cm 1000baseTX +Set 1000baseTX operation over twisted pair. +.El +.Pp +The +.Nm +driver supports the following media options: +.Bl -tag -width ".Cm full-duplex" +.It Cm full-duplex +Force full duplex operation. +.It Cm half-duplex +Force half duplex operation. +.El +.Pp +For more information on configuring this device, see +.Xr ifconfig 8 . +.Sh HARDWARE +The +.Nm +device driver provides support for the following Ethernet controllers: +.Pp +.Bl -bullet -compact +.It +SiS190 Fast Ethernet controller +.It +SiS191 Fast/Gigabit Ethernet controller +.El +.Sh SEE ALSO +.Xr altq 4 , +.Xr arp 4 , +.Xr miibus 4 , +.Xr netintro 4 , +.Xr ng_ether 4 , +.Xr vlan 4 , +.Xr ifconfig 8 +.Sh HISTORY +The +.Nm +driver was written by +.An Alexander Pohoyda +.Aq alexander.pohoyda@gmx.net . +And enhanced by +.An Nikolay Denev +.Aq ndenev@gmail.com . +It first appeared in +.Fx 8.1 . diff --git a/share/man/man4/vlan.4 b/share/man/man4/vlan.4 index 149d4bc5fcd..f7f7807a86d 100644 --- a/share/man/man4/vlan.4 +++ b/share/man/man4/vlan.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 14, 2009 +.Dd April 14, 2010 .Dt VLAN 4 .Os .Sh NAME @@ -172,6 +172,7 @@ natively: .Xr nve 4 , .Xr rl 4 , .Xr sf 4 , +.Xr sge 4 , .Xr sis 4 , .Xr sk 4 , .Xr ste 4 , From 94a04272dd05c37153769d2283b6d189fbfbf60d Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Wed, 14 Apr 2010 21:42:29 +0000 Subject: [PATCH 055/532] Change the semantics of the debug.ktr.alq_enable control so that when you disable alq, it acts as if alq had not been enabled in the build. in other words, the rest of ktr is still available for use. If you really don't want that as well, set the mask to 0. MFC after:3 weeks --- sys/kern/kern_ktr.c | 54 +++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/sys/kern/kern_ktr.c b/sys/kern/kern_ktr.c index 6117cd6cbba..9586ae65278 100644 --- a/sys/kern/kern_ktr.c +++ b/sys/kern/kern_ktr.c @@ -199,9 +199,8 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format, struct ktr_entry *entry; #ifdef KTR_ALQ struct ale *ale = NULL; -#else - int newindex, saveindex; #endif + int newindex, saveindex; #if defined(KTR_VERBOSE) || defined(KTR_ALQ) struct thread *td; #endif @@ -221,27 +220,30 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format, td->td_pflags |= TDP_INKTR; #endif #ifdef KTR_ALQ - if (ktr_alq_enabled && - td->td_critnest == 0 && - (td->td_flags & TDF_IDLETD) == 0 && - td != ald_thread) { - if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max) - goto done; - if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) { - ktr_alq_failed++; + if (ktr_alq_enabled) { + if (td->td_critnest == 0 && + (td->td_flags & TDF_IDLETD) == 0 && + td != ald_thread) { + if (ktr_alq_max && ktr_alq_cnt > ktr_alq_max) + goto done; + if ((ale = alq_get(ktr_alq, ALQ_NOWAIT)) == NULL) { + ktr_alq_failed++; + goto done; + } + ktr_alq_cnt++; + entry = (struct ktr_entry *)ale->ae_data; + } else { goto done; } - ktr_alq_cnt++; - entry = (struct ktr_entry *)ale->ae_data; } else - goto done; -#else - do { - saveindex = ktr_idx; - newindex = (saveindex + 1) & (KTR_ENTRIES - 1); - } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0); - entry = &ktr_buf[saveindex]; #endif + { + do { + saveindex = ktr_idx; + newindex = (saveindex + 1) & (KTR_ENTRIES - 1); + } while (atomic_cmpset_rel_int(&ktr_idx, saveindex, newindex) == 0); + entry = &ktr_buf[saveindex]; + } entry->ktr_timestamp = KTR_TIME; entry->ktr_cpu = cpu; entry->ktr_thread = curthread; @@ -271,7 +273,7 @@ ktr_tracepoint(u_int mask, const char *file, int line, const char *format, entry->ktr_parms[4] = arg5; entry->ktr_parms[5] = arg6; #ifdef KTR_ALQ - if (ale) + if (ktr_alq_enabled && ale) alq_post(ktr_alq, ale); done: #endif @@ -295,7 +297,9 @@ DB_SHOW_COMMAND(ktr, db_ktr_all) tstate.cur = (ktr_idx - 1) & (KTR_ENTRIES - 1); tstate.first = -1; - db_ktr_verbose = index(modif, 'v') != NULL; + db_ktr_verbose = 0; + db_ktr_verbose |= (index(modif, 'v') != NULL) ? 2 : 0; + db_ktr_verbose |= (index(modif, 'V') != NULL) ? 1 : 0; /* just timestap please */ if (index(modif, 'a') != NULL) { db_disable_pager(); while (cncheckc() != -1) @@ -329,9 +333,11 @@ db_mach_vtrace(void) db_printf(":cpu%d", kp->ktr_cpu); #endif db_printf(")"); - if (db_ktr_verbose) { - db_printf(" %10.10lld %s.%d", (long long)kp->ktr_timestamp, - kp->ktr_file, kp->ktr_line); + if (db_ktr_verbose >= 1) { + db_printf(" %10.10lld", (long long)kp->ktr_timestamp); + } + if (db_ktr_verbose >= 2) { + db_printf(" %s.%d", kp->ktr_file, kp->ktr_line); } db_printf(": "); db_printf(kp->ktr_desc, kp->ktr_parms[0], kp->ktr_parms[1], From f6b93040fd95c76758b371e160dbf6d996b14336 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Wed, 14 Apr 2010 21:44:14 +0000 Subject: [PATCH 056/532] Man page change to documant slight change in ktr_alq behaviour. --- share/man/man4/ktr.4 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/share/man/man4/ktr.4 b/share/man/man4/ktr.4 index 89f530596f5..7da4e373051 100644 --- a/share/man/man4/ktr.4 +++ b/share/man/man4/ktr.4 @@ -122,7 +122,7 @@ option sets the flag to one. The KTR buffer can be examined from within .Xr ddb 4 via the -.Ic show ktr Op Cm /v +.Ic show ktr Op Cm /vV command. This command displays the contents of the trace buffer one page at a time. At the @@ -136,6 +136,10 @@ If the .Cm /v modifier is specified, then they are displayed in addition to the normal output. +If the +.Cm /V +modifier is specified, then just the timestamp is displayed in +addition to the normal output. Note that the events are displayed in reverse chronological order. That is, the most recent events are displayed first. .Ss Logging ktr to Disk @@ -167,7 +171,9 @@ the next invocation. enables logging of .Nm entries to disk if it is set to one. -Setting this to 0 will terminate logging. +Setting this to 0 will terminate logging to disk and revert to +logging to the normal ktr ring buffer. +Data is not sent to the ring buffer while logging to disk. .It Va debug.ktr.alq_max is the maximum number of entries that will be recorded to disk, or 0 for infinite. From 410c7662749344645598007a28d70d283541347d Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Wed, 14 Apr 2010 21:53:27 +0000 Subject: [PATCH 057/532] Move fatal error at the right place. Fix exit from top mode when checking if PMC is available. MFC after: 3 days --- usr.sbin/pmcstat/pmcpl_callgraph.c | 2 ++ usr.sbin/pmcstat/pmcpl_gprof.c | 2 ++ usr.sbin/pmcstat/pmcstat_log.c | 2 -- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/usr.sbin/pmcstat/pmcpl_callgraph.c b/usr.sbin/pmcstat/pmcpl_callgraph.c index 53d342bfdc1..d948b77f43b 100644 --- a/usr.sbin/pmcstat/pmcpl_callgraph.c +++ b/usr.sbin/pmcstat/pmcpl_callgraph.c @@ -581,6 +581,8 @@ pmcpl_cg_topdisplay(void) struct pmcstat_pmcrecord *pmcr; pmcr = pmcstat_pmcindex_to_pmcr(pmcstat_pmcinfilter); + if (!pmcr) + err(EX_SOFTWARE, "ERROR: invalid pmcindex"); /* * We pull out all callgraph nodes in the top-level hash table diff --git a/usr.sbin/pmcstat/pmcpl_gprof.c b/usr.sbin/pmcstat/pmcpl_gprof.c index 9327eb95b62..2027ecf38e7 100644 --- a/usr.sbin/pmcstat/pmcpl_gprof.c +++ b/usr.sbin/pmcstat/pmcpl_gprof.c @@ -171,6 +171,8 @@ pmcstat_gmon_create_name(const char *samplesdir, struct pmcstat_image *image, char fullpath[PATH_MAX]; pmcname = pmcstat_pmcid_to_name(pmcid); + if (!pmcname) + err(EX_SOFTWARE, "ERROR: cannot find pmcid"); (void) snprintf(fullpath, sizeof(fullpath), "%s/%s/%s", samplesdir, pmcname, diff --git a/usr.sbin/pmcstat/pmcstat_log.c b/usr.sbin/pmcstat/pmcstat_log.c index 51f66ca9e25..6d8c57a760a 100644 --- a/usr.sbin/pmcstat/pmcstat_log.c +++ b/usr.sbin/pmcstat/pmcstat_log.c @@ -1050,7 +1050,6 @@ pmcstat_pmcid_to_name(pmc_id_t pmcid) if (pr->pr_pmcid == pmcid) return (pmcstat_string_unintern(pr->pr_pmcname)); - err(EX_SOFTWARE, "ERROR: cannot find pmcid"); return NULL; } @@ -1083,7 +1082,6 @@ pmcstat_pmcindex_to_pmcr(int pmcin) if (pr->pr_pmcin == pmcin) return pr; - err(EX_SOFTWARE, "ERROR: invalid pmcindex"); return NULL; } From 57d848483eb9cb8a270e4355e4634ae940a7d7dd Mon Sep 17 00:00:00 2001 From: Xin LI Date: Wed, 14 Apr 2010 22:02:19 +0000 Subject: [PATCH 058/532] When an underlying ioctl(2) handler returns an error, our ioctl(2) interface considers that it hits a fatal error, and will not copyout the request structure back for _IOW and _IOWR ioctls, keeping them untouched. The previous implementation of the SIOCGIFDESCR ioctl intends to feed the buffer length back to userland. However, if we return an error, the feedback would be defeated and ifconfig(8) would trap into an infinite loop. This commit changes SIOCGIFDESCR to set buffer field to NULL to indicate the previous ENAMETOOLONG case. Reported by: bschmidt MFC after: 2 weeks --- sbin/ifconfig/ifconfig.c | 23 ++++++++++++----------- share/man/man4/netintro.4 | 9 ++++++--- sys/net/if.c | 7 +++---- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 7af3306d68f..aa961755722 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -922,19 +922,20 @@ status(const struct afswtch *afp, const struct sockaddr_dl *sdl, ifr.ifr_buffer.buffer = descr; ifr.ifr_buffer.length = descrlen; if (ioctl(s, SIOCGIFDESCR, &ifr) == 0) { - if (strlen(descr) > 0) - printf("\tdescription: %s\n", descr); - break; - } else if (errno == ENAMETOOLONG) - descrlen = ifr.ifr_buffer.length; - else - break; - } else { + if (ifr.ifr_buffer.buffer == descr) { + if (strlen(descr) > 0) + printf("\tdescription: %s\n", + descr); + } else if (ifr.ifr_buffer.length > descrlen) { + descrlen = ifr.ifr_buffer.length; + continue; + } + } + } else warn("unable to allocate memory for interface" "description"); - break; - } - }; + break; + } if (ioctl(s, SIOCGIFCAP, (caddr_t)&ifr) == 0) { if (ifr.ifr_curcap != 0) { diff --git a/share/man/man4/netintro.4 b/share/man/man4/netintro.4 index 348a13e68fd..3e989401777 100644 --- a/share/man/man4/netintro.4 +++ b/share/man/man4/netintro.4 @@ -32,7 +32,7 @@ .\" @(#)netintro.4 8.2 (Berkeley) 11/30/93 .\" $FreeBSD$ .\" -.Dd January 26, 2010 +.Dd April 14, 2010 .Dt NETINTRO 4 .Os .Sh NAME @@ -292,8 +292,11 @@ field of struct passed in as parameter, and the length would include the terminating nul character. If there is not enough space to hold the interface length, -no copy would be done and an -error would be returned. +no copy would be done and the +.Va buffer +field of +.Va ifru_buffer +would be set to NULL. The kernel will store the buffer length in the .Va length field upon return, regardless whether the buffer itself is diff --git a/sys/net/if.c b/sys/net/if.c index e4a20054963..98c8afa4a2b 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2049,14 +2049,13 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) case SIOCGIFDESCR: error = 0; sx_slock(&ifdescr_sx); - if (ifp->if_description == NULL) { - ifr->ifr_buffer.length = 0; + if (ifp->if_description == NULL) error = ENOMSG; - } else { + else { /* space for terminating nul */ descrlen = strlen(ifp->if_description) + 1; if (ifr->ifr_buffer.length < descrlen) - error = ENAMETOOLONG; + ifr->ifr_buffer.buffer = NULL; else error = copyout(ifp->if_description, ifr->ifr_buffer.buffer, descrlen); From 2d8d6ee437981b190cc77ac7fade864800754239 Mon Sep 17 00:00:00 2001 From: Gavin Atkinson Date: Wed, 14 Apr 2010 22:03:48 +0000 Subject: [PATCH 059/532] Use the UIPROTO_BOOT_KEYBOARD #define from usb.h rather than a local (almost identically named) local #define. Reviewed by: hselasky --- sys/dev/usb/input/ukbd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 8584f8d505d..f446db7a28c 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -102,8 +102,6 @@ TUNABLE_INT("hw.usb.ukbd.debug", &ukbd_debug); TUNABLE_INT("hw.usb.ukbd.no_leds", &ukbd_no_leds); #endif -#define UPROTO_BOOT_KEYBOARD 1 - #define UKBD_EMULATE_ATSCANCODE 1 #define UKBD_DRIVER_NAME "ukbd" #define UKBD_NMOD 8 /* units */ @@ -770,7 +768,7 @@ ukbd_probe(device_t dev) return (ENXIO); if ((uaa->info.bInterfaceSubClass == UISUBCLASS_BOOT) && - (uaa->info.bInterfaceProtocol == UPROTO_BOOT_KEYBOARD)) { + (uaa->info.bInterfaceProtocol == UIPROTO_BOOT_KEYBOARD)) { if (usb_test_quirk(uaa, UQ_KBD_IGNORE)) return (ENXIO); else From 7a90b21212384b51a24738d850302b5cade42b90 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Wed, 14 Apr 2010 23:06:07 +0000 Subject: [PATCH 060/532] Move two copies of the same definition to a common include file. MFC after: 3 weeks --- sys/ddb/db_sym.c | 6 ------ sys/net/vnet.c | 9 --------- sys/net/vnet.h | 9 +++++++++ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c index 99209a89c83..04af1eba535 100644 --- a/sys/ddb/db_sym.c +++ b/sys/ddb/db_sym.c @@ -64,12 +64,6 @@ static boolean_t db_line_at_pc(c_db_sym_t, char **, int *, db_expr_t); static int db_cpu = -1; #ifdef VIMAGE -extern uintptr_t *__start_set_vnet; -extern uintptr_t *__stop_set_vnet; - -#define VNET_START (uintptr_t)&__start_set_vnet -#define VNET_STOP (uintptr_t)&__stop_set_vnet - static void *db_vnet = NULL; #endif diff --git a/sys/net/vnet.c b/sys/net/vnet.c index 1dac03abf1d..8013f5ed594 100644 --- a/sys/net/vnet.c +++ b/sys/net/vnet.c @@ -153,15 +153,6 @@ struct vnet *vnet0; * module will find every network stack instance with proper default values. */ -/* - * Location of the kernel's 'set_vnet' linker set. - */ -extern uintptr_t *__start_set_vnet; -extern uintptr_t *__stop_set_vnet; - -#define VNET_START (uintptr_t)&__start_set_vnet -#define VNET_STOP (uintptr_t)&__stop_set_vnet - /* * Number of bytes of data in the 'set_vnet' linker set, and hence the total * size of all kernel virtualized global variables, and the malloc(9) type diff --git a/sys/net/vnet.h b/sys/net/vnet.h index fb2cc393cb7..4cdfdef3063 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -91,6 +91,15 @@ struct vnet { #include #include +/* + * Location of the kernel's 'set_vnet' linker set. + */ +extern uintptr_t *__start_set_vnet; +extern uintptr_t *__stop_set_vnet; + +#define VNET_START (uintptr_t)&__start_set_vnet +#define VNET_STOP (uintptr_t)&__stop_set_vnet + /* * Functions to allocate and destroy virtual network stacks. */ From a3a86fc3973f7a598beba6b0c04837d095d05a12 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 15 Apr 2010 08:29:14 +0000 Subject: [PATCH 061/532] scsi_cd: CD_FLAG_VALID_MEDIA is sufficient to set d_sectorsize and d_mediasize CD_FLAG_VALID_TOC is not required for setting those media properties. PR: kern/145385 Submitted by: Juergen Lock a slightly different version Tested by: Pavel Sukhoy , Markus Wild , Juergen Lock , uqs MFC after: 1 week --- sys/cam/scsi/scsi_cd.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index 1e5be3c5886..d09d129a947 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -2773,8 +2773,12 @@ cdcheckmedia(struct cam_periph *periph) softc->flags &= ~(CD_FLAG_VALID_MEDIA|CD_FLAG_VALID_TOC); cdprevent(periph, PR_ALLOW); return (error); - } else + } else { softc->flags |= CD_FLAG_VALID_MEDIA; + softc->disk->d_sectorsize = softc->params.blksize; + softc->disk->d_mediasize = + (off_t)softc->params.blksize * softc->params.disksize; + } /* * Now we check the table of contents. This (currently) is only @@ -2863,9 +2867,6 @@ cdcheckmedia(struct cam_periph *periph) } softc->flags |= CD_FLAG_VALID_TOC; - softc->disk->d_sectorsize = softc->params.blksize; - softc->disk->d_mediasize = - (off_t)softc->params.blksize * softc->params.disksize; bailout: From fdfa00ba835ea7dd8128a8ae0ea4f191197a7d06 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 15 Apr 2010 08:32:50 +0000 Subject: [PATCH 062/532] Still reference struct __sigaction with clarification when this form of argument declaration is needed. Discussed with: bde MFC after: 3 days --- lib/libc/sys/sigaction.2 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2 index 9bd4c9e4f36..51b6c47c78f 100644 --- a/lib/libc/sys/sigaction.2 +++ b/lib/libc/sys/sigaction.2 @@ -496,6 +496,16 @@ or .Dv SIG_IGN this way. .Pp +If preprocessing symbol +.Va _POSIX_C_SOURCE +with the value >= 199309 is not defined, the following declaration for +the handler shall be used: +.Bl -tag -offset indent -width short +.It Tn POSIX Dv SA_SIGINFO : +.Ft void +.Fn handler int "struct __sigaction *" "void *" ; +.El +.Pp If the .Dv SA_SIGINFO flag is not set, the handler function should match From 2a842317eb386798cb7a8e14aad7068d5546e259 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 15 Apr 2010 08:39:56 +0000 Subject: [PATCH 063/532] g_io_check: respond to zero pp->mediasize with ENXIO Previsouly this condition was reported with EIO by bio_offset > mediasize check. Perhaps that check should be extended to bio_offset+bio_length > mediasize. MFC after: 1 week --- sys/geom/geom_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index 931b7c30338..1090c0bbf66 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -309,8 +309,8 @@ g_io_check(struct bio *bp) case BIO_READ: case BIO_WRITE: case BIO_DELETE: - /* Zero sectorsize is a probably lack of media */ - if (pp->sectorsize == 0) + /* Zero sectorsize or mediasize is probably a lack of media. */ + if (pp->sectorsize == 0 || pp->mediasize == 0) return (ENXIO); /* Reject I/O not on sector boundary */ if (bp->bio_offset % pp->sectorsize) From 94410af77428e042c74266d1a6d6a3e02a11acd5 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 15 Apr 2010 11:17:33 +0000 Subject: [PATCH 065/532] Explicitly enable PCI busmastering on attach. Now SiI3124 with siis(4) successfully works on sparc64 (SunBlade 100). H/W donated by: Gheorghe Ardelean --- sys/dev/siis/siis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/siis/siis.c b/sys/dev/siis/siis.c index f03fba98027..c9c157226fa 100644 --- a/sys/dev/siis/siis.c +++ b/sys/dev/siis/siis.c @@ -164,6 +164,7 @@ siis_attach(device_t dev) rman_fini(&ctlr->sc_iomem); return (error); } + pci_enable_busmaster(dev); /* Reset controller */ siis_resume(dev); /* Number of HW channels */ From 61f73308d437a7ce14a7c0d1f59dc6d1141a4912 Mon Sep 17 00:00:00 2001 From: VANHULLEBUS Yvan Date: Thu, 15 Apr 2010 12:40:33 +0000 Subject: [PATCH 066/532] Locks SPTREE when setting some SP entries to state DEAD. This can prevent kernel panics when updating SPs while there is some traffic for them. Obtained from: NETASQ MFC after: 1m --- sys/netipsec/key.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index e3a61aced00..2b17fb0d91b 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -1882,7 +1882,9 @@ key_spdadd(so, m, mhp) newsp = key_getsp(&spidx); if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) { if (newsp) { + SPTREE_LOCK(); newsp->state = IPSEC_SPSTATE_DEAD; + SPTREE_UNLOCK(); KEY_FREESP(&newsp); } } else { @@ -2117,7 +2119,9 @@ key_spddelete(so, m, mhp) /* save policy id to buffer to be returned. */ xpl0->sadb_x_policy_id = sp->id; + SPTREE_LOCK(); sp->state = IPSEC_SPSTATE_DEAD; + SPTREE_UNLOCK(); KEY_FREESP(&sp); { @@ -2184,7 +2188,9 @@ key_spddelete2(so, m, mhp) return key_senderror(so, m, EINVAL); } + SPTREE_LOCK(); sp->state = IPSEC_SPSTATE_DEAD; + SPTREE_UNLOCK(); KEY_FREESP(&sp); { From c406ad2ecc2152da2888704513b0a2107de3be4a Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Thu, 15 Apr 2010 13:50:55 +0000 Subject: [PATCH 067/532] Cleanup if_media handling in mxge(4) - Re-probe xfp / sfp+ socket on link events, in case user has changed transceiver - correctly report current media to avoid confusing lagg (reported by Panasas) - Report link speed (submitted by yongari) Reviewed by: yongari (earlier version) MFC after: 7 days --- sys/dev/mxge/if_mxge.c | 115 +++++++++++++++++++++++-------------- sys/dev/mxge/if_mxge_var.h | 8 +++ 2 files changed, 79 insertions(+), 44 deletions(-) diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index d7f58255241..50c9af65794 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -883,6 +883,9 @@ mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data) case MXGEFW_CMD_ERROR_BUSY: err = EBUSY; break; + case MXGEFW_CMD_ERROR_I2C_ABSENT: + err = ENXIO; + break; default: device_printf(sc->dev, "mxge: command %d " @@ -2782,37 +2785,25 @@ static struct mxge_media_type mxge_sfp_media_types[] = }; static void -mxge_set_media(mxge_softc_t *sc, int type) +mxge_media_set(mxge_softc_t *sc, int media_type) { - sc->media_flags |= type; - ifmedia_add(&sc->media, sc->media_flags, 0, NULL); - ifmedia_set(&sc->media, sc->media_flags); + + + ifmedia_add(&sc->media, IFM_ETHER | IFM_FDX | media_type, + 0, NULL); + ifmedia_set(&sc->media, IFM_ETHER | IFM_FDX | media_type); + sc->current_media = media_type; + sc->media.ifm_media = sc->media.ifm_cur->ifm_media; } - -/* - * Determine the media type for a NIC. Some XFPs will identify - * themselves only when their link is up, so this is initiated via a - * link up interrupt. However, this can potentially take up to - * several milliseconds, so it is run via the watchdog routine, rather - * than in the interrupt handler itself. This need only be done - * once, not each time the link is up. - */ static void -mxge_media_probe(mxge_softc_t *sc) +mxge_media_init(mxge_softc_t *sc) { - mxge_cmd_t cmd; - char *cage_type; char *ptr; - struct mxge_media_type *mxge_media_types = NULL; - int i, err, ms, mxge_media_type_entries; - uint32_t byte; + int i; - sc->need_media_probe = 0; - - /* if we've already set a media type, we're done */ - if (sc->media_flags != (IFM_ETHER | IFM_AUTO)) - return; + ifmedia_removeall(&sc->media); + mxge_media_set(sc, IFM_AUTO); /* * parse the product code to deterimine the interface type @@ -2823,6 +2814,7 @@ mxge_media_probe(mxge_softc_t *sc) ptr = sc->product_code_string; if (ptr == NULL) { device_printf(sc->dev, "Missing product code\n"); + return; } for (i = 0; i < 3; i++, ptr++) { @@ -2835,17 +2827,44 @@ mxge_media_probe(mxge_softc_t *sc) } if (*ptr == 'C') { /* -C is CX4 */ - mxge_set_media(sc, IFM_10G_CX4); - return; - } - else if (*ptr == 'Q') { + sc->connector = MXGE_CX4; + mxge_media_set(sc, IFM_10G_CX4); + } else if (*ptr == 'Q') { /* -Q is Quad Ribbon Fiber */ + sc->connector = MXGE_QRF; device_printf(sc->dev, "Quad Ribbon Fiber Media\n"); /* FreeBSD has no media type for Quad ribbon fiber */ - return; + } else if (*ptr == 'R') { + /* -R is XFP */ + sc->connector = MXGE_XFP; + } else if (*ptr == 'S' || *(ptr +1) == 'S') { + /* -S or -2S is SFP+ */ + sc->connector = MXGE_SFP; + } else { + device_printf(sc->dev, "Unknown media type: %c\n", *ptr); } +} - if (*ptr == 'R') { +/* + * Determine the media type for a NIC. Some XFPs will identify + * themselves only when their link is up, so this is initiated via a + * link up interrupt. However, this can potentially take up to + * several milliseconds, so it is run via the watchdog routine, rather + * than in the interrupt handler itself. + */ +static void +mxge_media_probe(mxge_softc_t *sc) +{ + mxge_cmd_t cmd; + char *cage_type; + + struct mxge_media_type *mxge_media_types = NULL; + int i, err, ms, mxge_media_type_entries; + uint32_t byte; + + sc->need_media_probe = 0; + + if (sc->connector == MXGE_XFP) { /* -R is XFP */ mxge_media_types = mxge_xfp_media_types; mxge_media_type_entries = @@ -2853,9 +2872,7 @@ mxge_media_probe(mxge_softc_t *sc) sizeof (mxge_xfp_media_types[0]); byte = MXGE_XFP_COMPLIANCE_BYTE; cage_type = "XFP"; - } - - if (*ptr == 'S' || *(ptr +1) == 'S') { + } else if (sc->connector == MXGE_SFP) { /* -S or -2S is SFP+ */ mxge_media_types = mxge_sfp_media_types; mxge_media_type_entries = @@ -2863,10 +2880,8 @@ mxge_media_probe(mxge_softc_t *sc) sizeof (mxge_sfp_media_types[0]); cage_type = "SFP+"; byte = 3; - } - - if (mxge_media_types == NULL) { - device_printf(sc->dev, "Unknown media type: %c\n", *ptr); + } else { + /* nothing to do; media type cannot change */ return; } @@ -2909,7 +2924,10 @@ mxge_media_probe(mxge_softc_t *sc) if (mxge_verbose) device_printf(sc->dev, "%s:%s\n", cage_type, mxge_media_types[0].name); - mxge_set_media(sc, mxge_media_types[0].flag); + if (sc->current_media != mxge_media_types[0].flag) { + mxge_media_init(sc); + mxge_media_set(sc, mxge_media_types[0].flag); + } return; } for (i = 1; i < mxge_media_type_entries; i++) { @@ -2919,12 +2937,16 @@ mxge_media_probe(mxge_softc_t *sc) cage_type, mxge_media_types[i].name); - mxge_set_media(sc, mxge_media_types[i].flag); + if (sc->current_media != mxge_media_types[i].flag) { + mxge_media_init(sc); + mxge_media_set(sc, mxge_media_types[i].flag); + } return; } } - device_printf(sc->dev, "%s media 0x%x unknown\n", cage_type, - cmd.data0); + if (mxge_verbose) + device_printf(sc->dev, "%s media 0x%x unknown\n", + cage_type, cmd.data0); return; } @@ -2988,10 +3010,12 @@ mxge_intr(void *arg) sc->link_state = stats->link_up; if (sc->link_state) { if_link_state_change(sc->ifp, LINK_STATE_UP); + sc->ifp->if_baudrate = IF_Gbps(10UL); if (mxge_verbose) device_printf(sc->dev, "link up\n"); } else { if_link_state_change(sc->ifp, LINK_STATE_DOWN); + sc->ifp->if_baudrate = 0; if (mxge_verbose) device_printf(sc->dev, "link down\n"); } @@ -4026,9 +4050,9 @@ mxge_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) if (sc == NULL) return; ifmr->ifm_status = IFM_AVALID; + ifmr->ifm_active = IFM_ETHER | IFM_FDX; ifmr->ifm_status |= sc->link_state ? IFM_ACTIVE : 0; - ifmr->ifm_active = IFM_AUTO | IFM_ETHER; - ifmr->ifm_active |= sc->link_state ? IFM_FDX : 0; + ifmr->ifm_active |= sc->current_media; } static int @@ -4135,6 +4159,9 @@ mxge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; case SIOCGIFMEDIA: + mtx_lock(&sc->driver_mtx); + mxge_media_probe(sc); + mtx_unlock(&sc->driver_mtx); err = ifmedia_ioctl(ifp, (struct ifreq *)data, &sc->media, command); break; @@ -4766,7 +4793,7 @@ mxge_attach(device_t dev) /* Initialise the ifmedia structure */ ifmedia_init(&sc->media, 0, mxge_media_change, mxge_media_status); - mxge_set_media(sc, IFM_ETHER | IFM_AUTO); + mxge_media_init(sc); mxge_media_probe(sc); sc->dying = 0; ether_ifattach(ifp, sc->mac_addr); diff --git a/sys/dev/mxge/if_mxge_var.h b/sys/dev/mxge/if_mxge_var.h index 5c1627f71e5..c85a29bfb58 100644 --- a/sys/dev/mxge/if_mxge_var.h +++ b/sys/dev/mxge/if_mxge_var.h @@ -268,6 +268,8 @@ struct mxge_softc { int num_slices; int rx_ring_size; int dying; + int connector; + int current_media; mxge_dma_t dmabench_dma; struct callout co_hdl; struct taskqueue *tq; @@ -293,6 +295,12 @@ struct mxge_softc { #define MXGE_MIN_THROTTLE 416 #define MXGE_MAX_THROTTLE 4096 +/* Types of connectors on NICs supported by this driver */ +#define MXGE_CX4 0 +#define MXGE_XFP 1 +#define MXGE_SFP 2 +#define MXGE_QRF 3 + #define MXGE_HIGHPART_TO_U32(X) \ (sizeof (X) == 8) ? ((uint32_t)((uint64_t)(X) >> 32)) : (0) #define MXGE_LOWPART_TO_U32(X) ((uint32_t)(X)) From 2a29e09f38ba94e8dfa61195ef79d1c45ecc4a6a Mon Sep 17 00:00:00 2001 From: Andrew Gallatin Date: Thu, 15 Apr 2010 14:26:52 +0000 Subject: [PATCH 068/532] Add missing IFCAP_LINKSTATE to mxge Submitted by: yongari --- sys/dev/mxge/if_mxge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/mxge/if_mxge.c b/sys/dev/mxge/if_mxge.c index 50c9af65794..956b1aa2dbb 100644 --- a/sys/dev/mxge/if_mxge.c +++ b/sys/dev/mxge/if_mxge.c @@ -4759,7 +4759,7 @@ mxge_attach(device_t dev) ifp->if_baudrate = IF_Gbps(10UL); ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4 | - IFCAP_VLAN_MTU; + IFCAP_VLAN_MTU | IFCAP_LINKSTATE; #ifdef INET ifp->if_capabilities |= IFCAP_LRO; #endif From e1a4e3fa37d5e5fd069f75f0c5842714d9b9728b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Thu, 15 Apr 2010 15:10:46 +0000 Subject: [PATCH 069/532] Allow option aliasing. Lines of the form: OLD_OPT = NEW_OPT in options* files will now map OLD_OPT to NEW_OPT with a friendly message. This is indented for situations where we need to preserve an interface in the config file in an upwards compatible fashion on a stable branch. Reviewed by: nwhitehorn@ MFC after: 3 days --- usr.sbin/config/config.h | 2 ++ usr.sbin/config/mkoptions.c | 27 ++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/usr.sbin/config/config.h b/usr.sbin/config/config.h index d55c96b00a9..ec199862ae7 100644 --- a/usr.sbin/config/config.h +++ b/usr.sbin/config/config.h @@ -129,6 +129,8 @@ SLIST_HEAD(opt_head, opt) opt, mkopt, rmopts; struct opt_list { char *o_name; char *o_file; + int o_flags; +#define OL_ALIAS 1 SLIST_ENTRY(opt_list) o_next; }; diff --git a/usr.sbin/config/mkoptions.c b/usr.sbin/config/mkoptions.c index 5cd9d61a824..1a6ccc8fec0 100644 --- a/usr.sbin/config/mkoptions.c +++ b/usr.sbin/config/mkoptions.c @@ -94,6 +94,17 @@ options(void) SLIST_INSERT_HEAD(&opt, op, op_next); read_options(); + SLIST_FOREACH(op, &opt, op_next) { + SLIST_FOREACH(ol, &otab, o_next) { + if (eq(op->op_name, ol->o_name) && + (ol->o_flags & OL_ALIAS)) { + printf("Mapping option %s to %s.\n", + op->op_name, ol->o_file); + op->op_name = ol->o_file; + break; + } + } + } SLIST_FOREACH(ol, &otab, o_next) do_option(ol->o_name); SLIST_FOREACH(op, &opt, op_next) { @@ -124,7 +135,6 @@ do_option(char *name) int tidy; file = tooption(name); - /* * Check to see if the option was specified.. */ @@ -292,6 +302,7 @@ read_options(void) struct opt_list *po; int first = 1; char genopt[MAXPATHLEN]; + int flags = 0; SLIST_INIT(&otab); (void) snprintf(fname, sizeof(fname), "../../conf/options"); @@ -301,6 +312,7 @@ openit: return; } next: + flags = 0; wd = get_word(fp); if (wd == (char *)EOF) { (void) fclose(fp); @@ -332,6 +344,18 @@ next: (void) snprintf(genopt, sizeof(genopt), "opt_%s.h", lower(s)); val = genopt; free(s); + } else if (eq(val, "=")) { + val = get_word(fp); + if (val == (char *)EOF) { + printf("%s: unexpected end of file\n", fname); + exit(1); + } + if (val == 0) { + printf("%s: Expected a right hand side at %s\n", fname, + this); + exit(1); + } + flags |= OL_ALIAS; } val = ns(val); @@ -348,6 +372,7 @@ next: err(EXIT_FAILURE, "calloc"); po->o_name = this; po->o_file = val; + po->o_flags = flags; SLIST_INSERT_HEAD(&otab, po, o_next); goto next; From 31c4cef715a139f573d9fc3da1c93c63308f5426 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 15 Apr 2010 16:34:06 +0000 Subject: [PATCH 070/532] Use lower priority for GELI worker threads. This improves system responsiveness under heavy GELI load. MFC after: 3 days --- sys/geom/eli/g_eli.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/geom/eli/g_eli.c b/sys/geom/eli/g_eli.c index 2a405c5b502..a3746c09e1a 100644 --- a/sys/geom/eli/g_eli.c +++ b/sys/geom/eli/g_eli.c @@ -340,7 +340,7 @@ g_eli_worker(void *arg) } #endif thread_lock(curthread); - sched_prio(curthread, PRIBIO); + sched_prio(curthread, PUSER); if (sc->sc_crypto == G_ELI_CRYPTO_SW && g_eli_threads == 0) sched_bind(curthread, wr->w_number); thread_unlock(curthread); @@ -361,8 +361,7 @@ g_eli_worker(void *arg) mtx_unlock(&sc->sc_queue_mtx); kproc_exit(0); } - msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, - "geli:w", 0); + msleep(sc, &sc->sc_queue_mtx, PDROP, "geli:w", 0); continue; } mtx_unlock(&sc->sc_queue_mtx); From 54ddff9dfa43eafbbb9b99bd6e9f612d6fea6908 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 15 Apr 2010 16:35:34 +0000 Subject: [PATCH 071/532] Flush disk write cache after storing and clearing metadata. --- sbin/geom/misc/subr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sbin/geom/misc/subr.c b/sbin/geom/misc/subr.c index 64df7c6845e..21deac8bf52 100644 --- a/sbin/geom/misc/subr.c +++ b/sbin/geom/misc/subr.c @@ -236,6 +236,7 @@ g_metadata_store(const char *name, u_char *md, size_t size) error = errno; goto out; } + (void)ioctl(fd, DIOCGFLUSH, NULL); out: if (sector != NULL) free(sector); @@ -293,6 +294,7 @@ g_metadata_clear(const char *name, const char *magic) error = errno; goto out; } + (void)ioctl(fd, DIOCGFLUSH, NULL); out: if (sector != NULL) free(sector); From 40c7da090ff2d263824c0089a508868452977c87 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 15 Apr 2010 16:40:54 +0000 Subject: [PATCH 072/532] Fix 3-way deadlock that can happen because of ZFS and vnode lock order reversal. thread0 (vfs_fhtovp) thread1 (vop_getattr) thread2 (zfs_recv) -------------------- --------------------- ------------------ vn_lock rrw_enter_read rrw_enter_write (hangs) rrw_enter_read (hangs) vn_lock (hangs) Submitted by: Attila Nagy MFC after: 3 days --- .../opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 11 +++++++---- .../contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 6 +++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index ad8165b3157..07c9b61bd32 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -868,13 +868,15 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) ZFS_ENTER_NOERROR(zfsvfs); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); + + ZFS_EXIT(zfsvfs); + if (error == 0) { *vpp = ZTOV(rootzp); error = vn_lock(*vpp, flags); (*vpp)->v_vflag |= VV_ROOT; } - ZFS_EXIT(zfsvfs); return (error); } @@ -1143,13 +1145,13 @@ zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp) VN_RELE(ZTOV(zp)); err = EINVAL; } + ZFS_EXIT(zfsvfs); if (err != 0) *vpp = NULL; else { *vpp = ZTOV(zp); vn_lock(*vpp, flags); } - ZFS_EXIT(zfsvfs); return (err); } @@ -1237,8 +1239,8 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp) } else { VN_HOLD(*vpp); } - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); ZFS_EXIT(zfsvfs); + vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); return (0); } @@ -1259,10 +1261,11 @@ zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp) return (EINVAL); } + ZFS_EXIT(zfsvfs); + *vpp = ZTOV(zp); vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); vnode_create_vobject(*vpp, zp->z_phys->zp_size, curthread); - ZFS_EXIT(zfsvfs); return (0); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 4f61f5f3f5e..59a58dd7a5a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -1209,15 +1209,17 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, ltype = VOP_ISLOCKED(dvp); VOP_UNLOCK(dvp, 0); } + ZFS_EXIT(zfsvfs); error = vn_lock(*vpp, cnp->cn_lkflags); if (cnp->cn_flags & ISDOTDOT) vn_lock(dvp, ltype | LK_RETRY); if (error != 0) { VN_RELE(*vpp); *vpp = NULL; - ZFS_EXIT(zfsvfs); return (error); } + } else { + ZFS_EXIT(zfsvfs); } #ifdef FREEBSD_NAMECACHE @@ -1237,8 +1239,6 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp, } #endif - ZFS_EXIT(zfsvfs); - return (error); } From ceab1828a000fa0f165997499325670c7ac8b320 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 15 Apr 2010 16:43:43 +0000 Subject: [PATCH 073/532] Use spaces instead of tab for indent here. --- etc/mtree/BSD.include.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 78240112c9b..1ec71719ac4 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -104,8 +104,8 @@ .. lmc .. - mfi - .. + mfi + .. mpt mpilib .. From 20b77db949cfb020f933039e76bbf06667b93c71 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Thu, 15 Apr 2010 17:04:08 +0000 Subject: [PATCH 074/532] Increase ggate queue size to maximum value. HAST was not able to stand heavy random load. Reported by: Hiroyuki Yamagami MFC after: 3 days --- sbin/hastd/primary.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c index 20af0b983c1..09151546772 100644 --- a/sbin/hastd/primary.c +++ b/sbin/hastd/primary.c @@ -682,7 +682,7 @@ init_ggate(struct hast_resource *res) ggiocreate.gctl_mediasize = res->hr_datasize; ggiocreate.gctl_sectorsize = res->hr_local_sectorsize; ggiocreate.gctl_flags = 0; - ggiocreate.gctl_maxcount = 128; + ggiocreate.gctl_maxcount = G_GATE_MAX_QUEUE_SIZE; ggiocreate.gctl_timeout = 0; ggiocreate.gctl_unit = G_GATE_NAME_GIVEN; snprintf(ggiocreate.gctl_name, sizeof(ggiocreate.gctl_name), "hast/%s", From 3e22320c434f2f2c6e442c4d8c5cb11a9810f9e2 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 15 Apr 2010 17:17:02 +0000 Subject: [PATCH 075/532] Fix typo. MFC after: 3 days --- sys/kern/vfs_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 78548033ea2..533ec97875d 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -610,7 +610,7 @@ cache_enter(dvp, vp, cnp) CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr); VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp, - ("cahe_enter: Adding a doomed vnode")); + ("cache_enter: Adding a doomed vnode")); if (!doingcache) return; From c6491946d820c02b41e8438e82a6a4089b21075a Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 15 Apr 2010 17:24:21 +0000 Subject: [PATCH 076/532] Fix include path. --- sys/dev/sge/if_sge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c index a26a6a46359..c4fb5c9bc8b 100644 --- a/sys/dev/sge/if_sge.c +++ b/sys/dev/sge/if_sge.c @@ -81,7 +81,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include "if_sgereg.h" +#include MODULE_DEPEND(sge, pci, 1, 1, 1); MODULE_DEPEND(sge, ether, 1, 1, 1); From 55e999851d94e1b109c0f83cd1d84911775c17e2 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 15 Apr 2010 19:15:05 +0000 Subject: [PATCH 077/532] Diff reduction with OpenBSD: - Remove unused locally added variable; - Deprecate -o: it's the default behavior on OpenBSD. X-MFC: along with nc 4.7. --- contrib/netcat/nc.1 | 13 ++----------- contrib/netcat/netcat.c | 18 ++++++------------ 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1 index fc2c8af3857..ac6aa475fbd 100644 --- a/contrib/netcat/nc.1 +++ b/contrib/netcat/nc.1 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd February 23, 2010 +.Dd April 15, 2010 .Dt NC 1 .Os .Sh NAME @@ -36,7 +36,7 @@ .Sh SYNOPSIS .Nm nc .Bk -words -.Op Fl 46DdEhklnorStUuvz +.Op Fl 46DdEhklnrStUuvz .Op Fl e Ar IPsec_policy .Op Fl I Ar length .Op Fl i Ar interval @@ -159,15 +159,6 @@ socket option. .It Fl O Ar length Specifies the size of the TCP send buffer. When -.It Fl o -.Dq Once-only mode . -By default, -.Nm -does not terminate on EOF condition on input, -but continues until the network side has been closed down. -Specifying -.Fl o -will make it terminate on EOF as well. .It Fl P Ar proxy_username Specifies a username to present to a proxy server that requires authentication. If no username is specified then authentication will not be attempted. diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c index c83f62293d3..8faaeb06851 100644 --- a/contrib/netcat/netcat.c +++ b/contrib/netcat/netcat.c @@ -72,14 +72,12 @@ #define PORT_MAX_LEN 6 /* Command Line Options */ -int Eflag; /* Use IPsec ESP */ int dflag; /* detached, no stdin */ unsigned int iflag; /* Interval Flag */ int jflag; /* use jumbo frames if we can */ int kflag; /* More than one connect */ int lflag; /* Bind to local port */ int nflag; /* Don't do name look up */ -int oflag; /* Once only: stop on EOF */ int FreeBSD_Oflag; /* Do not use TCP options */ char *Pflag; /* Proxy username */ char *pflag; /* Localport flag */ @@ -151,7 +149,7 @@ main(int argc, char *argv[]) sv = NULL; while ((ch = getopt_long(argc, argv, - "46DdEe:hI:i:jklnO:oP:p:rSs:tT:UuV:vw:X:x:z", + "46DdEe:hI:i:jklnoO:P:p:rSs:tT:UuV:vw:X:x:z", longopts, NULL)) != -1) { switch (ch) { case '4': @@ -214,7 +212,7 @@ main(int argc, char *argv[]) nflag = 1; break; case 'o': - oflag = 1; + fprintf(stderr, "option -o is deprecated.\n"); break; case 'P': Pflag = optarg; @@ -282,8 +280,6 @@ main(int argc, char *argv[]) case 'T': Tflag = parse_iptos(optarg); break; - case 0: - break; default: usage(1); } @@ -729,10 +725,9 @@ readwrite(int nfd) } if (!dflag && pfd[1].revents & POLLIN) { - if ((n = read(wfd, buf, plen)) < 0 || - (oflag && n == 0)) { + if ((n = read(wfd, buf, plen)) < 0) return; - } else if (n == 0) { + else if (n == 0) { shutdown(nfd, SHUT_WR); pfd[1].fd = -1; pfd[1].events = 0; @@ -945,7 +940,6 @@ help(void) \t-n Suppress name/port resolutions\n\ \t--no-tcpopt Disable TCP options\n\ \t-O length TCP send buffer length\n\ - \t-o Terminate on EOF on input\n\ \t-P proxyuser\tUsername for proxy authentication\n\ \t-p port\t Specify local port for remote connects\n\ \t-r Randomize remote ports\n\ @@ -995,9 +989,9 @@ usage(int ret) { fprintf(stderr, #ifdef IPSEC - "usage: nc [-46DdEhklnorStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n" + "usage: nc [-46DdEhklnrStUuvz] [-e policy] [-I length] [-i interval] [-O length]\n" #else - "usage: nc [-46DdhklnorStUuvz] [-I length] [-i interval] [-O length]\n" + "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n" #endif "\t [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n" "\t [-V fib] [-w timeout] [-X proxy_protocol]\n" From 5d0848e9c67a570760d6420d9a3f6df99ec20d6d Mon Sep 17 00:00:00 2001 From: Fabien Thomas Date: Thu, 15 Apr 2010 19:45:03 +0000 Subject: [PATCH 078/532] - Fix a typo OFFCORE_REQUESTS.ANY.RFO is B0H10H and not 80H10H. - Enable missing PARTIAL_ADDRESS_ALIAS for Core i7. MFC after: 3 days --- sys/dev/hwpmc/hwpmc_core.c | 3 ++- sys/dev/hwpmc/pmc_events.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c index 90d7c8bc23f..e7de09915b3 100644 --- a/sys/dev/hwpmc/hwpmc_core.c +++ b/sys/dev/hwpmc/hwpmc_core.c @@ -603,7 +603,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(06H_0FH, 0x06, 0x0F, IAP_F_FM | IAP_F_I7O), IAPDESCR(07H_00H, 0x07, 0x00, IAP_F_FM | IAP_F_CC | IAP_F_CC2), - IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_WM), + IAPDESCR(07H_01H, 0x07, 0x01, IAP_F_FM | IAP_F_ALLCPUSCORE2 | IAP_F_I7 | IAP_F_WM), IAPDESCR(07H_02H, 0x07, 0x02, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(07H_03H, 0x07, 0x03, IAP_F_FM | IAP_F_ALLCPUSCORE2), IAPDESCR(07H_06H, 0x07, 0x06, IAP_F_FM | IAP_F_CA), @@ -1053,6 +1053,7 @@ static struct iap_event_descr iap_events[] = { IAPDESCR(B0H_02H, 0xB0, 0x02, IAP_F_FM | IAP_F_WM | IAP_F_I7O), IAPDESCR(B0H_04H, 0xB0, 0x04, IAP_F_FM | IAP_F_WM | IAP_F_I7O), IAPDESCR(B0H_08H, 0xB0, 0x08, IAP_F_FM | IAP_F_WM | IAP_F_I7O), + IAPDESCR(B0H_10H, 0xB0, 0x10, IAP_F_FM | IAP_F_WM | IAP_F_I7O), IAPDESCR(B0H_20H, 0xB0, 0x20, IAP_F_FM | IAP_F_I7O), IAPDESCR(B0H_40H, 0xB0, 0x40, IAP_F_FM | IAP_F_I7 | IAP_F_WM), IAPDESCR(B0H_80H, 0xB0, 0x80, IAP_F_FM | IAP_F_CA | IAP_F_WM | IAP_F_I7O), diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h index e38772cd95d..df2d3efd7bf 100644 --- a/sys/dev/hwpmc/pmc_events.h +++ b/sys/dev/hwpmc/pmc_events.h @@ -2207,7 +2207,7 @@ __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.ANY.RFO", IAP_EVENT_B0H_10H) \ __PMC_EV_ALIAS("OFFCORE_REQUESTS.L1D_WRITEBACK", IAP_EVENT_B0H_40H) \ __PMC_EV_ALIAS("OFFCORE_REQUESTS.ANY", IAP_EVENT_B0H_80H) \ __PMC_EV_ALIAS("UOPS_EXECUTED.PORT0", IAP_EVENT_B1H_01H) \ From d52bba9301b45a85101914647396c9a92e26aad8 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Thu, 15 Apr 2010 21:18:24 +0000 Subject: [PATCH 079/532] If a service is running, make 'stop' work even if ${name}_enable is not set. PR: conf/130414 Submitted by: Dominic Fandrey Reviewed by: freebsd-rc@ --- etc/rc.subr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/rc.subr b/etc/rc.subr index 18273be83ab..397af1d7907 100644 --- a/etc/rc.subr +++ b/etc/rc.subr @@ -646,12 +646,12 @@ run_rc_command() if [ "$_elem" != "$rc_arg" ]; then continue fi - # if ${rcvar} is set, and $1 is not - # "rcvar", then run + # if ${rcvar} is set, $1 is not "rcvar" + # and ${rc_pid} is not set, then run # checkyesno ${rcvar} # and return if that failed # - if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" ]; then + if [ -n "${rcvar}" -a "$rc_arg" != "rcvar" -a -z "${rc_pid}" ]; then if ! checkyesno ${rcvar}; then if [ -n "${rc_quiet}" ]; then return 0 From c27b391b3f5fece33f763f040e229ed603e560bb Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 15 Apr 2010 21:41:07 +0000 Subject: [PATCH 080/532] indent(1): don't treat bare '_t' as a type name when -ta is used It seems that identifier "_t" is sometimes used as a variable name, even in our tree. Not that I endorse that, but still it's better to require at least one character before _t suffix to consider an identifier to be a type name. Reported by: Alex Vasylenko MFC after: 1 week --- usr.bin/indent/lexi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/usr.bin/indent/lexi.c b/usr.bin/indent/lexi.c index 3d415d074dc..b3604c64205 100644 --- a/usr.bin/indent/lexi.c +++ b/usr.bin/indent/lexi.c @@ -251,9 +251,10 @@ lexi(void) if (auto_typedefs) { const char *q = s_token; + size_t q_len = strlen(q); /* Check if we have an "_t" in the end */ - if (q[0] && q[1] && - (strcmp(q + strlen(q) - 2, "_t") == 0)) { + if (q_len > 2 && + (strcmp(q + q_len - 2, "_t") == 0)) { ps.its_a_keyword = true; ps.last_u_d = true; goto found_auto_typedef; From 55909abf07e4069f4c4e176c320dbec548dd60ab Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 15 Apr 2010 22:57:30 +0000 Subject: [PATCH 081/532] The experimental NFS client was not filling in recovery credentials for opens done locally in the client when a delegation for the file was held. This could cause the client to crash in crsetgroups() when recovering from a server crash/reboot. This patch fills in the recovery credentials for this case, in order to avoid the client crash. Also, add KASSERT()s to the credential copy functions, to catch any other cases where the credentials aren't filled in correctly. MFC after: 1 week --- sys/fs/nfs/nfs_commonport.c | 2 ++ sys/fs/nfs/nfsclstate.h | 1 + sys/fs/nfsclient/nfs_clport.c | 2 ++ sys/fs/nfsclient/nfs_clrpcops.c | 8 +++++++- sys/fs/nfsclient/nfs_clstate.c | 9 +++++++-- 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index a65ebde881c..2849163837d 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -225,6 +225,8 @@ void newnfs_copycred(struct nfscred *nfscr, struct ucred *cr) { + KASSERT(nfscr->nfsc_ngroups >= 0, + ("newnfs_copycred: negative nfsc_ngroups")); cr->cr_uid = nfscr->nfsc_uid; crsetgroups(cr, nfscr->nfsc_ngroups, nfscr->nfsc_groups); } diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h index 10747af5a64..edd479cf2ce 100644 --- a/sys/fs/nfs/nfsclstate.h +++ b/sys/fs/nfs/nfsclstate.h @@ -140,6 +140,7 @@ struct nfsclopen { #define NFSCLOPEN_OK 0 #define NFSCLOPEN_DOOPEN 1 #define NFSCLOPEN_DOOPENDOWNGRADE 2 +#define NFSCLOPEN_SETCRED 3 struct nfscllockowner { LIST_ENTRY(nfscllockowner) nfsl_list; diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index e81c3bf805b..f39666db68e 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -978,6 +978,8 @@ newnfs_copyincred(struct ucred *cr, struct nfscred *nfscr) { int i; + KASSERT(cr->cr_ngroups >= 0, + ("newnfs_copyincred: negative cr_ngroups")); nfscr->nfsc_uid = cr->cr_uid; nfscr->nfsc_ngroups = MIN(cr->cr_ngroups, NFS_MAXGRPS + 1); for (i = 0; i < nfscr->nfsc_ngroups; i++) diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 95943a9660b..a7015f5226b 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -278,7 +278,13 @@ else printf(" fhl=0\n"); error = EIO; } newnfs_copyincred(cred, &op->nfso_cred); - } + } else if (ret == NFSCLOPEN_SETCRED) + /* + * This is a new local open on a delegation. It needs + * to have credentials so that an open can be done + * against the server during recovery. + */ + newnfs_copyincred(cred, &op->nfso_cred); /* * nfso_opencnt is the count of how many VOP_OPEN()s have diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 568c5de640a..08150a7228e 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -274,8 +274,13 @@ nfscl_open(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t amode, int usedeleg, *owpp = owp; if (opp != NULL) *opp = op; - if (retp != NULL) - *retp = NFSCLOPEN_OK; + if (retp != NULL) { + if (nfhp != NULL && dp != NULL && nop == NULL) + /* new local open on delegation */ + *retp = NFSCLOPEN_SETCRED; + else + *retp = NFSCLOPEN_OK; + } /* * Now, check the mode on the open and return the appropriate From 6856a5e345c29381f081beef5529bbd35f769b86 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 15 Apr 2010 23:21:24 +0000 Subject: [PATCH 082/532] Utilize IP_BINDANY which provided the same semantics of OpenBSD's SO_BINDANY. --- contrib/netcat/netcat.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c index 8faaeb06851..28a98238676 100644 --- a/contrib/netcat/netcat.c +++ b/contrib/netcat/netcat.c @@ -570,10 +570,8 @@ remote_connect(const char *host, const char *port, struct addrinfo hints) if (sflag || pflag) { struct addrinfo ahints, *ares; -#ifdef SO_BINDANY - /* try SO_BINDANY, but don't insist */ - setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); -#endif + /* try IP_BINDANY, but don't insist */ + setsockopt(s, IPPROTO_IP, IP_BINDANY, &on, sizeof(on)); memset(&ahints, 0, sizeof(struct addrinfo)); ahints.ai_family = res0->ai_family; ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; From 0ac68bd339575e74d26a008fe6cf913e38651b9e Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 15 Apr 2010 23:56:05 +0000 Subject: [PATCH 083/532] Add mutex lock calls to 2 cases in the experimental NFS client's renew thread where they were missing. MFC after: 1 week --- sys/fs/nfsclient/nfs_clstate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 08150a7228e..7bccbfcc5d7 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -2318,7 +2318,9 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p) int error, cbpathdown, islept, igotlock, ret, clearok; cred = newnfs_getcred(); + NFSLOCKCLSTATE(); clp->nfsc_flags |= NFSCLFLAGS_HASTHREAD; + NFSUNLOCKCLSTATE(); for(;;) { newnfs_setroot(cred); cbpathdown = 0; @@ -2331,9 +2333,11 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p) error = nfsrpc_renew(clp, cred, p); if (error == NFSERR_CBPATHDOWN) cbpathdown = 1; - else if (error == NFSERR_STALECLIENTID) + else if (error == NFSERR_STALECLIENTID) { + NFSLOCKCLSTATE(); clp->nfsc_flags |= NFSCLFLAGS_RECOVER; - else if (error == NFSERR_EXPIRED) + NFSUNLOCKCLSTATE(); + } else if (error == NFSERR_EXPIRED) (void) nfscl_hasexpired(clp, clidrev, p); } From 4076170459d487877d3c99cdabb26b861bc6033b Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Fri, 16 Apr 2010 02:56:24 +0000 Subject: [PATCH 084/532] Remove some unused header files. --- ObsoleteFiles.inc | 8 ++ sys/mips/include/archtype.h | 49 ------- sys/mips/include/defs.h | 256 ------------------------------------ sys/mips/include/queue.h | 171 ------------------------ sys/mips/include/rm7000.h | 95 ------------- sys/mips/include/segments.h | 40 ------ sys/mips/mips/trap.c | 2 - 7 files changed, 8 insertions(+), 613 deletions(-) delete mode 100644 sys/mips/include/archtype.h delete mode 100644 sys/mips/include/defs.h delete mode 100644 sys/mips/include/queue.h delete mode 100644 sys/mips/include/rm7000.h delete mode 100644 sys/mips/include/segments.h diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index b18c0ea52d3..0844d714693 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,14 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20100415: [mips] removed unused headers +.if ${TARGET_ARCH} == "mips" +OLD_FILES+=usr/include/machine/archtype.h +OLD_FILES+=usr/include/machine/segments.h +OLD_FILES+=usr/include/machine/rm7000.h +OLD_FILES+=usr/include/machine/defs.h +OLD_FILES+=usr/include/machine/queue.h +.endif # 20100326: [ia64] removed .if ${TARGET_ARCH} == "ia64" OLD_FILES+=usr/include/machine/nexusvar.h diff --git a/sys/mips/include/archtype.h b/sys/mips/include/archtype.h deleted file mode 100644 index ed1b5ea6b8f..00000000000 --- a/sys/mips/include/archtype.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $OpenBSD: archtype.h,v 1.6 1999/01/27 04:46:04 imp Exp $ */ -/* - * Copyright (c) 1997 Per Fogelstrom - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed under OpenBSD by - * Per Fogelstrom. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * JNPR: archtype.h,v 1.6 2007/08/09 11:23:32 katta - * - * $FreeBSD$ - */ - -#ifndef _MACHINE_ARCHTYPE_H_ -#define _MACHINE_ARCHTYPE_H_ -/* - * Define architectural identitys for the different Mips machines. - */ - -/* - * FREEBSD_DEVELOPERS_FIXME - * Define constants for the supported MIPS CPU's - */ -#define MIPS_CLASS_UNKNOWN 0x00 - -#endif /* !_MACHINE_ARCHTYPE_H_ */ diff --git a/sys/mips/include/defs.h b/sys/mips/include/defs.h deleted file mode 100644 index 20d093e029b..00000000000 --- a/sys/mips/include/defs.h +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 1996, 2001-2003, 2005, Juniper Networks, Inc. - * All rights reserved. - * - * defs.h -- Simple universal types and definitions for use by the microkernel - * Jim Hayes, November 1996 - * - * JNPR: defs.h,v 1.3.2.1 2007/09/10 08:16:32 girish - * $FreeBSD$ - */ - -#ifndef __DEFS_H__ -#define __DEFS_H__ - -/* - * Paranoid compilation. If defined, the PARANOID flag will enable asserts, - * data structure magic stamping and a suite of other debug tools. To disable - * it, comment out its definition. - */ -#define PARANOID - -/* - * This is the ONLY place you should see hardware specific information - * encoded as #ifdefs. (Well, except for stdarg.h, perhaps.) - * I apologize in advance! - */ -#include -#define CPU_GOT_ONE - -#if !defined(CPU_GOT_ONE) -#error "YOU NEED TO SPECIFY ONE CPU TYPE TO USE THIS FILE" -#endif - -#ifdef TRUE -#undef TRUE -#endif - -#ifdef FALSE -#undef FALSE -#endif - -typedef enum boolean_ -{ - FALSE = 0, - TRUE = 1 -} boolean; - -/* - * Make NULL a pointer within the microkernel environment to catch - * pointer semantic miscreants. - * - * The reason it's conditional here is that some of the BSD includes - * define it multiple times as a straight integer and GCC barfs on - * the alternative prototypes. - */ - -#ifndef NULL -#define NULL (void *)0 -#endif - -/* - * Define some standard sized types. (Defined in cpu-specific type files - * included above.) - */ - -#define MAX_U8 255 -#define MAX_S8 128 -#define MIN_S8 -127 - -#define MAX_U16 0xffff -#define MIN_S16 ((int16_t)(1 << 15)) -#define MAX_S16 ((int16_t)~MIN_S16) - -#define MAX_U32 0xffffffff -#define MIN_S32 ((int32_t)(1 << 31)) -#define MAX_S32 ((int32_t)~MIN_S32) - -#define MAX_U64 ((u_int64_t)0 - 1) -#define MAX_S64 ((int64_t)(MAX_U64 >> 1)) -#define MIN_S64 (-MAX_S64-1) - -/* - * Solaris uses _SIZE_T to mark the fact that "size_t" has already - * been defined. _SYS_TYPES_H_ is used by BSD. - * - */ -#if !defined(_SYS_TYPES_H_) && !defined(_SIZE_T) -typedef UNSIGNED_32 size_t; -#define _SIZE_T -#endif - -#if !defined(_SYS_TYPES_H_) -typedef char * caddr_t; - -typedef UNSIGNED_8 u_int8_t; -typedef SIGNED_8 int8_t; - -typedef UNSIGNED_16 u_int16_t; -typedef SIGNED_16 int16_t; - -typedef UNSIGNED_32 u_int32_t; -typedef SIGNED_32 int32_t; - -typedef UNSIGNED_64 u_int64_t; -typedef SIGNED_64 int64_t; - -typedef UNSIGNED_32 u_long; -typedef UNSIGNED_16 u_short; -typedef UNSIGNED_8 u_char; - - -/* - * Define the standard terminology used in the diag software - * with regards to bytes, words, etc. - * BYTE = 8 bits - * HWORD (halfword) = 2 bytes or 16 bits - * WORD = 4 bytes or 32 bits - * QUAD = 8 bytes or 64 bits - * - * (The term QUAD seems less-than-intuitive here, but it is - * derived from BSD sources where it is defined as int64_t.) - * - * For consistency use the following defines wherever appropriate. - */ - -typedef enum { - NBI_BYTE = (sizeof(u_int8_t) * 8), - NBI_HWORD = (sizeof(u_int16_t) * 8), - NBI_WORD = (sizeof(u_int32_t) * 8), - NBI_QUAD = (sizeof(u_int64_t) * 8) -} num_bits_t; - -typedef enum { - NBY_BYTE = sizeof(u_int8_t), - NBY_HWORD = sizeof(u_int16_t), - NBY_WORD = sizeof(u_int32_t), - NBY_QUAD = sizeof(u_int64_t) -} num_bytes_t; - -/* - * We assume that pid values are 16 bit integers - */ - -typedef u_int16_t pid_t; - -#endif /* _SYS_TYPES_H_ */ - -typedef UNSIGNED_32 magic_t; -typedef int status_t; - -#define BITS_IN_BYTE 8 - -/* - * Packed definition. We use this for fields in network frames where we - * don't want the compiler to pack out to even alignment - */ - -#ifdef PACKED -#undef PACKED -#endif -#define PACKED(x) x __attribute__ ((packed)) - -/* - * __unused is a FreeBSDism that prevents the compiler from choking - * on function parameters that remain unused through the life of a - * function. This is not an issue for the Cygnus toolchain. In general - * it SHOULD NOT BE USED in the martini embedded software repository. - * It should only be used inside of shared code. - */ -#ifndef __unused -#define __unused __attribute__ ((__unused__)) -#endif - -/* - * Basic memory multiples - */ - -#define SIZE_1K 0x00000400 -#define SIZE_2K 0x00000800 -#define SIZE_4K 0x00001000 -#define SIZE_8K 0x00002000 -#define SIZE_16K 0x00004000 -#define SIZE_32K 0x00008000 -#define SIZE_64K 0x00010000 -#define SIZE_128K 0x00020000 -#define SIZE_256K 0x00040000 -#define SIZE_512K 0x00080000 -#define SIZE_1M 0x00100000 -#define SIZE_2M 0x00200000 -#define SIZE_4M 0x00400000 -#define SIZE_8M 0x00800000 -#define SIZE_16M 0x01000000 -#define SIZE_32M 0x02000000 -#define SIZE_64M 0x04000000 -#define SIZE_128M 0x08000000 -#define SIZE_256M 0x10000000 -#define SIZE_512M 0x20000000 -#define SIZE_1G 0x40000000 -#define SIZE_2G 0x80000000 - -/* - * swap16_inline - * swap32_inline - * - * Byteswap a 16 and 32 bit quantities - */ - -static inline u_int16_t -swap16_inline(u_int16_t data) -{ - return(((data & 0x00ff) << 8) | - ((data & 0xff00) >> 8)); -} - -static inline u_int32_t -swap32_inline(u_int32_t data) -{ - return(((data & 0x000000ff) << 24) | - ((data & 0x0000ff00) << 8) | - ((data & 0x00ff0000) >> 8) | - ((data & 0xff000000) >> 24)); -} - -/* - * Define errno_t here as it is needed by the rom and ukernel - */ -typedef u_int32_t errno_t; - -#define EOK 0 - -/* - * Define the main communication structure used for passing - * information from the rom to the ukernel (done here as it is - * used by them both) - */ -typedef struct rom_info_ rom_info_t; - -/* - * Typedef the return code from the ukernel to the ROM - */ -typedef u_int32_t rom_return_t; - -/* - * Pull in the relevant global environment header file - * - * This file is shared by the uKernel and the system simulation effort. - */ -#if defined(ENV_UKERN) || defined (ENV_SYS_SIM) -#include "ukern.h" -#endif /* ENV_UKERN */ - -#if defined(ENV_ROM) -#include "rom.h" -#endif - -#endif /* __DEFS_H__ */ diff --git a/sys/mips/include/queue.h b/sys/mips/include/queue.h deleted file mode 100644 index d992332c84e..00000000000 --- a/sys/mips/include/queue.h +++ /dev/null @@ -1,171 +0,0 @@ -/*- - * Copyright (c) 1996-1997, 2001, 2005, Juniper Networks, Inc. - * All rights reserved. - * Jim Hayes, November 1996 - * - * queue.h - Description of uKernel queues, for the Juniper Kernel - * - * JNPR: queue.h,v 1.1 2006/08/07 05:38:57 katta - * $FreeBSD$ - * - */ - -#ifndef __QUEUE_H__ -#define __QUEUE_H__ - -/*--------------------------------------------------------------------------- - * QUEUE MANAGEMENT DOCUMENTATION - */ - -/* - -------- - Q_INIT() - -------- - - void q_init(void) - - Initialize the queue management system for the microkernel. - This initializes the debugging flags and sets up accounting. - - --------- - Q_ALLOC() - --------- - - queue_t *q_alloc() - - Allocates a queue from kernel memory, and initializes it for you. - - The default initialization provides a queue that is unbounded. - - If you want to be bounded with special features, use q_control - after initialization. - - q_alloc() returns NULL in the face of peril or low memory. - - -------- - Q_FREE() - -------- - - void *q_free(queue_t *queue_pointer) - - Returns a queue to kernel memory, and frees the queue contents - for you using free() and complains (with a traceback) that you - tried to kill of a non-empty queue. - - If any threads are waiting on the queue, wake them up. - - ----------- - Q_CONTROL() - ----------- - void q_control(queue_t *queue_pointer, queue_size_t max_queue_size); - - For now, allows you to limit queue growth. - - ---------------- - Q_DEQUEUE_WAIT() ** MAY CAUSE THREAD TO BLOCK/CANNOT BE CALLED FROM ISRs ** - ---------------- - - void *q_dequeue_wait(queue_t *queue_pointer, wakeup_mask_t *mask) - - Removes and returns a pointer to the next message in the specified - queue. If the queue is empty, the calling thread goes to sleep - until something is queued to the queue. If this call returns NULL, - then an extraordinary event requires this thread's attention-- - check errno in this case. - - --------- - Q_DEQUEUE ** CAN BE CALLED FROM ISRs ** - --------- - - void *q_dequeue(queue_t *queue_pointer) - - Just like q_dequeue_wait(), but instead of blocking, return NULL. - - ----------- - Q_ENQUEUE() ** CAN BE CALLED FROM ISRs ** - ----------- - - boolean q_enqueue(queue_t *queue_pointer, void *element_pointer) - - Add the element to the end of the named queue. If the add fails - because a limit has been reached, return TRUE. Otherwise return - FALSE if everything went OK. - - ---------- - Q_URGENT() - ---------- - - boolean q_urgent(queue_t *queue_pointer, void *element_pointer) - - Same as q_enqueue(), except this element will be placed at the top - of the queue, and will be picked off at the next q_dequeue_wait() - operation. - - -------- - Q_PEEK() ** CAN BE CALLED FROM ISRs ** - -------- - - void *q_peek(queue_t *queue_pointer) - - Returns a pointer to the top element of the queue without actually - dequeuing it. Returns NULL of the queue is empty. - - This routine will never block. - - ---------- - Q_DELETE() - ---------- - - void q_delete(queue_t *queue_pointer, void *element_pointer) - - Delete the element_pointer from the queue, if it exists. This - isn't speedy, and isn't meant for tasks requiring performance. - It's primary use is to pull something off the queue when you know - in the common case that it's gonna be at or near the top of the - list. (I.e. waking a thread from a wake list when extraordinary - conditions exist, and you have to pluck it from the middle of the - list.) - - This routine does not block or return anything. - - -------- - Q_SIZE() - -------- - - queue_size_t q_size(queue_t *queue_pointer) - - Returns the number of elements in the queue. - - ------------ - Q_MAX_SIZE() - ------------ - - queue_size_t q_max_size(queue_t *queue_pointer); - - Returns the maximum size of this queue, or 0 if this queue is - unbounded. - -*/ - -/*------------------------------------------------------------------------- - * Basic queue management structures. - */ - -/* - * Typedefs - */ - -typedef u_int32_t queue_size_t; - -/* - * Prototypes - */ - -void q_init(void); -queue_t *q_alloc(void); -void *q_peek(queue_t *queue); -void *q_dequeue(queue_t *queue); -boolean q_enqueue(queue_t *queue, void *item); -boolean q_urgent(queue_t *queue, void *item); - -#endif /* __QUEUE_H__ */ diff --git a/sys/mips/include/rm7000.h b/sys/mips/include/rm7000.h deleted file mode 100644 index f1c0c44a0db..00000000000 --- a/sys/mips/include/rm7000.h +++ /dev/null @@ -1,95 +0,0 @@ -/* $OpenBSD$ */ - -/* - * Copyright (c) 2000 Opsycon Open System Consulting AB (www.opsycon.se) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Opsycon Open System - * Consulting AB, Sweden under contract to QED, Inc. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * JNPR: rm7000.h,v 1.2.4.1 2007/08/29 12:06:30 girish - * $FreeBSD$ - */ - -#ifndef _MACHINE_RM7000_H_ -#define _MACHINE_RM7000_H_ - -/* - * QED RM7000 specific defines. - */ - -/* - * Performance counters. - */ - -#define PCNT_SRC_CLOCKS 0x00 /* Clock cycles */ -#define PCNT_SRC_INSTR 0x01 /* Total instructions issued */ -#define PCNT_SRC_FPINSTR 0x02 /* Float instructions issued */ -#define PCNT_SRC_IINSTR 0x03 /* Integer instructions issued */ -#define PCNT_SRC_LOAD 0x04 /* Load instructions issued */ -#define PCNT_SRC_STORE 0x05 /* Store instructions issued */ -#define PCNT_SRC_DUAL 0x06 /* Dual issued pairs */ -#define PCNT_SRC_BRPREF 0x07 /* Branch prefetches */ -#define PCNT_SRC_EXTMISS 0x08 /* External cache misses */ -#define PCNT_SRC_STALL 0x09 /* Stall cycles */ -#define PCNT_SRC_SECMISS 0x0a /* Secondary cache misses */ -#define PCNT_SRC_INSMISS 0x0b /* Instruction cache misses */ -#define PCNT_SRC_DTAMISS 0x0c /* Data cache misses */ -#define PCNT_SRC_DTLBMISS 0x0d /* Data TLB misses */ -#define PCNT_SRC_ITLBMISS 0x0e /* Instruction TLB misses */ -#define PCNT_SRC_JTLBIMISS 0x0f /* Joint TLB instruction misses */ -#define PCNT_SRC_JTLBDMISS 0x10 /* Joint TLB data misses */ -#define PCNT_SRC_BRTAKEN 0x11 /* Branches taken */ -#define PCNT_SRC_BRISSUED 0x12 /* Branches issued */ -#define PCNT_SRC_SECWBACK 0x13 /* Secondary cache writebacks */ -#define PCNT_SRC_PRIWBACK 0x14 /* Primary cache writebacks */ -#define PCNT_SRC_DCSTALL 0x15 /* Dcache miss stall cycles */ -#define PCNT_SRC_MISS 0x16 /* Cache misses */ -#define PCNT_SRC_FPEXC 0x17 /* FP possible execption cycles */ -#define PCNT_SRC_MULSLIP 0x18 /* Slip cycles due to mult. busy */ -#define PCNT_SRC_CP0SLIP 0x19 /* CP0 Slip cycles */ -#define PCNT_SRC_LDSLIP 0x1a /* Slip cycles due to pend. non-b ld */ -#define PCNT_SRC_WBFULL 0x1b /* Write buffer full stall cycles */ -#define PCNT_SRC_CISTALL 0x1c /* Cache instruction stall cycles */ -#define PCNT_SRC_MULSTALL 0x1d /* Multiplier stall cycles */ -#define PCNT_SRC_ELDSTALL 0x1d /* Excepion stall due to non-b ld */ -#define PCNT_SRC_MAX 0x1d /* Maximum PCNT select code */ - -/* - * Counter control bits. - */ - -#define PCNT_CE 0x0400 /* Count enable */ -#define PCNT_UM 0x0200 /* Count in User mode */ -#define PCNT_KM 0x0100 /* Count in kernel mode */ - -/* - * Performance counter system call function codes. - */ -#define PCNT_FNC_SELECT 0x0001 /* Select counter source */ -#define PCNT_FNC_READ 0x0002 /* Read current value of counter */ - -#endif /* _MACHINE_RM7000_H_ */ diff --git a/sys/mips/include/segments.h b/sys/mips/include/segments.h deleted file mode 100644 index 406b965f2e0..00000000000 --- a/sys/mips/include/segments.h +++ /dev/null @@ -1,40 +0,0 @@ -/*- - * Copyright (c) 1989, 1990 William F. Jolitz - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * William Jolitz. - * - * 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. - * - * from: @(#)segments.h 7.1 (Berkeley) 5/9/91 - * $FreeBSD$ - */ - -#ifndef _MACHINE_SEGMENTS_H_ -#define _MACHINE_SEGMENTS_H_ - -#endif /* !_MACHINE_SEGMENTS_H_ */ diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 124087cc039..8bfc6e7f4d5 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -83,8 +83,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include #ifdef DDB From 09398e9bd42e66e6e6693460f5cd995c1d794da8 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Fri, 16 Apr 2010 06:47:29 +0000 Subject: [PATCH 085/532] Fix control socket leak when worker process exits. Submitted by: Mikolaj Golub MFC after: 3 days --- sbin/hastd/hastd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c index 19f08936c2d..957885d7ac1 100644 --- a/sbin/hastd/hastd.c +++ b/sbin/hastd/hastd.c @@ -137,6 +137,7 @@ child_exit(void) pjdlog_error("Worker process failed (pid=%u, status=%d).", (unsigned int)pid, WEXITSTATUS(status)); } + proto_close(res->hr_ctrl); res->hr_workerpid = 0; if (res->hr_role == HAST_ROLE_PRIMARY) { sleep(1); From 20ec52dc4bee544f948a29e8a31976302216cb69 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Fri, 16 Apr 2010 06:49:12 +0000 Subject: [PATCH 086/532] Fix log size calculation which caused message truncation. Submitted by: Mikolaj Golub MFC after: 3 days --- sbin/hastd/pjdlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/hastd/pjdlog.c b/sbin/hastd/pjdlog.c index 38c5539ad0c..9f8b3f499de 100644 --- a/sbin/hastd/pjdlog.c +++ b/sbin/hastd/pjdlog.c @@ -228,7 +228,7 @@ pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt, len = snprintf(log, sizeof(log), "%s", pjdlog_prefix); if ((size_t)len < sizeof(log)) - len = vsnprintf(log + len, sizeof(log) - len, fmt, ap); + len += vsnprintf(log + len, sizeof(log) - len, fmt, ap); if (error != -1 && (size_t)len < sizeof(log)) { (void)snprintf(log + len, sizeof(log) - len, ": %s.", strerror(error)); From 17f820725e8ef038ae1d08cb75a1781eb8ad8cc3 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Fri, 16 Apr 2010 07:02:28 +0000 Subject: [PATCH 087/532] Revert r206560. The change doesn't work correctly in all cases with multiple devfs mounts. --- sys/fs/devfs/devfs_devs.c | 23 ----------------------- sys/fs/devfs/devfs_int.h | 1 - 2 files changed, 24 deletions(-) diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 79037ba6313..81b2752583e 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -408,9 +408,6 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) continue; KASSERT((cdp->cdp_flags & CDP_ACTIVE), ("Bogons, I tell ya'!")); - if (cdp->cdp_flags & CDP_INVALID) - continue; - if (dm->dm_idx <= cdp->cdp_maxdirent && cdp->cdp_dirents[dm->dm_idx] != NULL) { de = cdp->cdp_dirents[dm->dm_idx]; @@ -428,8 +425,6 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) dd = dm->dm_rootdir; s = cdp->cdp_c.si_name; for (;;) { - while (*s == '/') - s++; for (q = s; *q != '/' && *q != '\0'; q++) continue; if (*q != '/') @@ -439,24 +434,6 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) de = devfs_vmkdir(dm, s, q - s, dd, 0); s = q + 1; dd = de; - if (dd->de_flags & (DE_DOT | DE_DOTDOT)) - break; - } - - /* - * XXX: Ignore duplicate and empty device names. - * XXX: Currently there is no way to report the error to - * XXX: the make_dev(9) caller. - */ - if (dd->de_dirent->d_type != DT_DIR || - dd->de_flags & (DE_DOT | DE_DOTDOT) || q - s < 1 || - devfs_find(dd, s, q - s) != NULL) { - dev_lock(); - cdp->cdp_flags |= CDP_INVALID; - dev_unlock(); - printf("%s: %s: invalid or duplicate device name\n", - __func__, cdp->cdp_c.si_name); - return (1); } de = devfs_newdirent(s, q - s); diff --git a/sys/fs/devfs/devfs_int.h b/sys/fs/devfs/devfs_int.h index a998061513f..5a61dd4a79b 100644 --- a/sys/fs/devfs/devfs_int.h +++ b/sys/fs/devfs/devfs_int.h @@ -55,7 +55,6 @@ struct cdev_priv { u_int cdp_flags; #define CDP_ACTIVE (1 << 0) #define CDP_SCHED_DTR (1 << 1) -#define CDP_INVALID (1 << 2) u_int cdp_inuse; u_int cdp_maxdirent; From c99cdece4efc95b389db21957dc2a9c39e744299 Mon Sep 17 00:00:00 2001 From: Jack F Vogel Date: Fri, 16 Apr 2010 16:33:05 +0000 Subject: [PATCH 088/532] Remove the tx queue selection based on the cpu whe no flowid is present, this was causing some bad reordering, now just use 0. Also, add a few watchdog bits, and tx handler bits that were corrected in igb. --- sys/dev/ixgbe/ixgbe.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index f8338e9aee4..9cc392db955 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -759,6 +759,7 @@ ixgbe_start_locked(struct tx_ring *txr, struct ifnet * ifp) /* Set watchdog on */ txr->watchdog_check = TRUE; + txr->watchdog_time = ticks; } return; @@ -798,8 +799,6 @@ ixgbe_mq_start(struct ifnet *ifp, struct mbuf *m) /* Which queue to use */ if ((m->m_flags & M_FLOWID) != 0) i = m->m_pkthdr.flowid % adapter->num_queues; - else /* use the cpu we're on */ - i = curcpu % adapter->num_queues; txr = &adapter->tx_rings[i]; @@ -856,8 +855,11 @@ ixgbe_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m) next = drbr_dequeue(ifp, txr->br); } - if (enqueued > 0) + if (enqueued > 0) { + /* Set watchdog on */ txr->watchdog_check = TRUE; + txr->watchdog_time = ticks; + } return (err); } @@ -1251,16 +1253,12 @@ ixgbe_handle_que(void *context, int pending) struct adapter *adapter = que->adapter; struct tx_ring *txr = que->txr; struct ifnet *ifp = adapter->ifp; - u32 loop = MAX_LOOP; - bool more_rx, more_tx; - - IXGBE_TX_LOCK(txr); - do { - more_rx = ixgbe_rxeof(que, adapter->rx_process_limit); - more_tx = ixgbe_txeof(txr); - } while (loop-- && (more_rx || more_tx)); + bool more; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + more = ixgbe_rxeof(que, adapter->rx_process_limit); + IXGBE_TX_LOCK(txr); + ixgbe_txeof(txr); #if __FreeBSD_version >= 800000 if (!drbr_empty(ifp, txr->br)) ixgbe_mq_start_locked(ifp, txr, NULL); @@ -1268,11 +1266,16 @@ ixgbe_handle_que(void *context, int pending) if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) ixgbe_start_locked(txr, ifp); #endif + IXGBE_TX_UNLOCK(txr); + if (more) { + taskqueue_enqueue(que->tq, &que->que_task); + return; + } } - IXGBE_TX_UNLOCK(txr); /* Reenable this interrupt */ ixgbe_enable_queue(adapter, que->msix); + return; } @@ -1718,7 +1721,6 @@ ixgbe_xmit(struct tx_ring *txr, struct mbuf **m_headp) * hardware that this frame is available to transmit. */ ++txr->total_packets; - txr->watchdog_time = ticks; IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), i); /* Do a clean if descriptors are low */ From 7a246d0b1457b7cb94c0393b9924940ffa6d4360 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Fri, 16 Apr 2010 16:49:42 +0000 Subject: [PATCH 089/532] Add ubthidhci. MFC after: 2 days --- etc/rc.d/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 17f76348664..802d7179b8e 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -50,6 +50,10 @@ FILES+= sshd FILES+= nscd .endif +.if ${MK_BLUETOOTH} != "no" +FILES+= ubthidhci +.endif + FILESDIR= /etc/rc.d FILESMODE= ${BINMODE} From 0c5aed59ee17fba47e089a089a822ac07af83009 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 16 Apr 2010 20:07:24 +0000 Subject: [PATCH 090/532] Expose a few symbols as public interface rather than private. Note: the *64 interfaces are no longer exposed via zlib.h but were keep as public interfaces; Note 2: this commit would break applications that uses the moved symbols directly. --- lib/libz/Symbol.map | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/libz/Symbol.map b/lib/libz/Symbol.map index 714606b5949..2651efc70fa 100644 --- a/lib/libz/Symbol.map +++ b/lib/libz/Symbol.map @@ -4,11 +4,13 @@ ZLIB_1.2.4.0 { adler32; + adler32_combine; adler32_combine64; compress; compress2; compressBound; crc32; + crc32_combine; crc32_combine64; deflate; deflateBound; @@ -35,15 +37,19 @@ ZLIB_1.2.4.0 { gzflush; gzgetc; gzgets; + gzoffset; gzoffset64; + gzopen; gzopen64; gzprintf; gzputc; gzputs; gzread; gzrewind; + gzseek; gzseek64; gzsetparams; + gztell; gztell64; gzungetc; gzwrite; @@ -80,13 +86,7 @@ ZLIBprivate_1.0 { _tr_init; _tr_stored_block; _tr_tally; - adler32_combine; - crc32_combine; gz_error; - gzoffset; - gzopen; - gzseek; - gztell; inflate_fast; inflate_table; longest_match; From bfbe51816a5449beec27c58e62cf0cb50e44bce7 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 16 Apr 2010 22:15:26 +0000 Subject: [PATCH 091/532] Add some tests for fnmatch(3). MFC after: 1 week --- tools/regression/lib/libc/gen/Makefile | 2 +- tools/regression/lib/libc/gen/test-fnmatch.c | 335 +++++++++++++++++++ 2 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 tools/regression/lib/libc/gen/test-fnmatch.c diff --git a/tools/regression/lib/libc/gen/Makefile b/tools/regression/lib/libc/gen/Makefile index 3dbe803a7be..3e911e4fc42 100644 --- a/tools/regression/lib/libc/gen/Makefile +++ b/tools/regression/lib/libc/gen/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -TESTS= test-fmtcheck test-fpclassify test-wordexp +TESTS= test-fmtcheck test-fnmatch test-fpclassify test-wordexp .PHONY: tests tests: ${TESTS} diff --git a/tools/regression/lib/libc/gen/test-fnmatch.c b/tools/regression/lib/libc/gen/test-fnmatch.c new file mode 100644 index 00000000000..ffb8c6c7800 --- /dev/null +++ b/tools/regression/lib/libc/gen/test-fnmatch.c @@ -0,0 +1,335 @@ +/*- + * Copyright (c) 2010 Jilles Tjoelker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +struct testcase { + const char *pattern; + const char *string; + int flags; + int result; +} testcases[] = { + "", "", 0, 0, + "a", "a", 0, 0, + "a", "b", 0, FNM_NOMATCH, + "a", "A", 0, FNM_NOMATCH, + "*", "a", 0, 0, + "*", "aa", 0, 0, + "*a", "a", 0, 0, + "*a", "b", 0, FNM_NOMATCH, + "*a*", "b", 0, FNM_NOMATCH, + "*a*b*", "ab", 0, 0, + "*a*b*", "qaqbq", 0, 0, + "*a*bb*", "qaqbqbbq", 0, 0, + "*a*bc*", "qaqbqbcq", 0, 0, + "*a*bb*", "qaqbqbb", 0, 0, + "*a*bc*", "qaqbqbc", 0, 0, + "*a*bb", "qaqbqbb", 0, 0, + "*a*bc", "qaqbqbc", 0, 0, + "*a*bb", "qaqbqbbq", 0, FNM_NOMATCH, + "*a*bc", "qaqbqbcq", 0, FNM_NOMATCH, + "*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaa", 0, FNM_NOMATCH, + "*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaaa", 0, 0, + "*a*a*a*a*a*a*a*a*a*a*", "aaaaaaaaaaa", 0, 0, + ".*.*.*.*.*.*.*.*.*.*", ".........", 0, FNM_NOMATCH, + ".*.*.*.*.*.*.*.*.*.*", "..........", 0, 0, + ".*.*.*.*.*.*.*.*.*.*", "...........", 0, 0, + "*?*?*?*?*?*?*?*?*?*?*", "123456789", 0, FNM_NOMATCH, + "??????????*", "123456789", 0, FNM_NOMATCH, + "*??????????", "123456789", 0, FNM_NOMATCH, + "*?*?*?*?*?*?*?*?*?*?*", "1234567890", 0, 0, + "??????????*", "1234567890", 0, 0, + "*??????????", "1234567890", 0, 0, + "*?*?*?*?*?*?*?*?*?*?*", "12345678901", 0, 0, + "??????????*", "12345678901", 0, 0, + "*??????????", "12345678901", 0, 0, + "[x]", "x", 0, 0, + "[*]", "*", 0, 0, + "[?]", "?", 0, 0, + "[", "[", 0, 0, + "[[]", "[", 0, 0, + "[[]", "x", 0, FNM_NOMATCH, + "[*]", "", 0, FNM_NOMATCH, + "[*]", "x", 0, FNM_NOMATCH, + "[?]", "x", 0, FNM_NOMATCH, + "*[*]*", "foo*foo", 0, 0, + "*[*]*", "foo", 0, FNM_NOMATCH, + "[0-9]", "0", 0, 0, + "[0-9]", "5", 0, 0, + "[0-9]", "9", 0, 0, + "[0-9]", "/", 0, FNM_NOMATCH, + "[0-9]", ":", 0, FNM_NOMATCH, + "[0-9]", "*", 0, FNM_NOMATCH, + "[!0-9]", "0", 0, FNM_NOMATCH, + "[!0-9]", "5", 0, FNM_NOMATCH, + "[!0-9]", "9", 0, FNM_NOMATCH, + "[!0-9]", "/", 0, 0, + "[!0-9]", ":", 0, 0, + "[!0-9]", "*", 0, 0, + "*[0-9]", "a0", 0, 0, + "*[0-9]", "a5", 0, 0, + "*[0-9]", "a9", 0, 0, + "*[0-9]", "a/", 0, FNM_NOMATCH, + "*[0-9]", "a:", 0, FNM_NOMATCH, + "*[0-9]", "a*", 0, FNM_NOMATCH, + "*[!0-9]", "a0", 0, FNM_NOMATCH, + "*[!0-9]", "a5", 0, FNM_NOMATCH, + "*[!0-9]", "a9", 0, FNM_NOMATCH, + "*[!0-9]", "a/", 0, 0, + "*[!0-9]", "a:", 0, 0, + "*[!0-9]", "a*", 0, 0, + "*[0-9]", "a00", 0, 0, + "*[0-9]", "a55", 0, 0, + "*[0-9]", "a99", 0, 0, + "*[0-9]", "a0a0", 0, 0, + "*[0-9]", "a5a5", 0, 0, + "*[0-9]", "a9a9", 0, 0, + "\\*", "*", 0, 0, + "\\?", "?", 0, 0, + "\\[x]", "[x]", 0, 0, + "\\[", "[", 0, 0, + "\\\\", "\\", 0, 0, + "*\\**", "foo*foo", 0, 0, + "*\\**", "foo", 0, FNM_NOMATCH, + "*\\\\*", "foo\\foo", 0, 0, + "*\\\\*", "foo", 0, FNM_NOMATCH, + "\\(", "(", 0, 0, + "\\a", "a", 0, 0, + "\\*", "a", 0, FNM_NOMATCH, + "\\?", "a", 0, FNM_NOMATCH, + "\\*", "\\*", 0, FNM_NOMATCH, + "\\?", "\\?", 0, FNM_NOMATCH, + "\\[x]", "\\[x]", 0, FNM_NOMATCH, + "\\[x]", "\\x", 0, FNM_NOMATCH, + "\\[", "\\[", 0, FNM_NOMATCH, + "\\(", "\\(", 0, FNM_NOMATCH, + "\\a", "\\a", 0, FNM_NOMATCH, + "\\*", "\\*", FNM_NOESCAPE, 0, + "\\?", "\\?", FNM_NOESCAPE, 0, + "\\", "\\", FNM_NOESCAPE, 0, + "\\\\", "\\", FNM_NOESCAPE, FNM_NOMATCH, + "\\\\", "\\\\", FNM_NOESCAPE, 0, + "*\\*", "foo\\foo", FNM_NOESCAPE, 0, + "*\\*", "foo", FNM_NOESCAPE, FNM_NOMATCH, + "*", ".", FNM_PERIOD, FNM_NOMATCH, + "?", ".", FNM_PERIOD, FNM_NOMATCH, + ".*", ".", 0, 0, + ".*", "..", 0, 0, + ".*", ".a", 0, 0, + "[0-9]", ".", FNM_PERIOD, FNM_NOMATCH, + "a*", "a.", 0, 0, + "a/a", "a/a", FNM_PATHNAME, 0, + "a/*", "a/a", FNM_PATHNAME, 0, + "*/a", "a/a", FNM_PATHNAME, 0, + "*/*", "a/a", FNM_PATHNAME, 0, + "a*b/*", "abbb/x", FNM_PATHNAME, 0, + "a*b/*", "abbb/.x", FNM_PATHNAME, 0, + "*", "a/a", FNM_PATHNAME, FNM_NOMATCH, + "*/*", "a/a/a", FNM_PATHNAME, FNM_NOMATCH, + "b/*", "b/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH, + "b*/*", "a/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH, + "b/.*", "b/.x", FNM_PATHNAME | FNM_PERIOD, 0, + "b*/.*", "b/.x", FNM_PATHNAME | FNM_PERIOD, 0, + "a", "A", FNM_CASEFOLD, 0, + "A", "a", FNM_CASEFOLD, 0, + "[a]", "A", FNM_CASEFOLD, 0, + "[A]", "a", FNM_CASEFOLD, 0, + "a", "b", FNM_CASEFOLD, FNM_NOMATCH, + "a", "a/b", FNM_PATHNAME, FNM_NOMATCH, + "*", "a/b", FNM_PATHNAME, FNM_NOMATCH, + "*b", "a/b", FNM_PATHNAME, FNM_NOMATCH, + "a", "a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0, + "*", "a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0, + "*", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0, + "*a", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0, + "*", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH, + "*a", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH, +}; + +static const char * +flags_to_string(int flags) +{ + static const int flagvalues[] = { FNM_NOESCAPE, FNM_PATHNAME, + FNM_PERIOD, FNM_LEADING_DIR, FNM_CASEFOLD, 0 }; + static const char flagnames[] = "FNM_NOESCAPE\0FNM_PATHNAME\0FNM_PERIOD\0FNM_LEADING_DIR\0FNM_CASEFOLD\0"; + static char result[sizeof(flagnames) + 3 * sizeof(int) + 2]; + char *p; + size_t i, len; + const char *fp; + + p = result; + fp = flagnames; + for (i = 0; flagvalues[i] != 0; i++) { + len = strlen(fp); + if (flags & flagvalues[i]) { + if (p != result) + *p++ = '|'; + memcpy(p, fp, len); + p += len; + flags &= ~flagvalues[i]; + } + fp += len + 1; + } + if (p == result) + memcpy(p, "0", 2); + else if (flags != 0) + sprintf(p, "%d", flags); + else + *p = '\0'; + return result; +} + +int +main(int argc, char *argv[]) +{ + size_t i, n; + int flags, result, extra, errors; + struct testcase *t; + + n = sizeof(testcases) / sizeof(testcases[0]); + errors = 0; + printf("1..%zu\n", n); + for (i = 0; i < n; i++) { + t = &testcases[i]; + flags = t->flags; + extra = 0; + do { + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + if (strchr(t->pattern, '\\') == NULL && + !(flags & FNM_NOESCAPE)) { + flags |= FNM_NOESCAPE; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if (strchr(t->pattern, '\\') != NULL && + strchr(t->string, '\\') == NULL && + t->result == FNM_NOMATCH && + !(flags & (FNM_NOESCAPE | FNM_LEADING_DIR))) { + flags |= FNM_NOESCAPE; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if ((t->string[0] != '.' || t->pattern[0] == '.' || + t->result == FNM_NOMATCH) && + !(flags & (FNM_PATHNAME | FNM_PERIOD))) { + flags |= FNM_PERIOD; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if ((strchr(t->string, '/') == NULL || + t->result == FNM_NOMATCH) && + !(flags & FNM_PATHNAME)) { + flags |= FNM_PATHNAME; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if ((((t->string[0] != '.' || t->pattern[0] == '.') && + strstr(t->string, "/.") == NULL) || + t->result == FNM_NOMATCH) && + flags & FNM_PATHNAME && !(flags & FNM_PERIOD)) { + flags |= FNM_PERIOD; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if ((((t->string[0] != '.' || t->pattern[0] == '.') && + strchr(t->string, '/') == NULL) || + t->result == FNM_NOMATCH) && + !(flags & (FNM_PATHNAME | FNM_PERIOD))) { + flags |= FNM_PATHNAME | FNM_PERIOD; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if ((strchr(t->string, '/') == NULL || t->result == 0) + && !(flags & FNM_LEADING_DIR)) { + flags |= FNM_LEADING_DIR; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if (t->result == 0 && !(flags & FNM_CASEFOLD)) { + flags |= FNM_CASEFOLD; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + if (strchr(t->pattern, '\\') == NULL && + t->result == 0 && + !(flags & (FNM_NOESCAPE | FNM_CASEFOLD))) { + flags |= FNM_NOESCAPE | FNM_CASEFOLD; + result = fnmatch(t->pattern, t->string, flags); + if (result != t->result) + break; + flags = t->flags; + extra++; + } + } while (0); + if (result == t->result) + printf("ok %zu - fnmatch(\"%s\", \"%s\", %s) = %d (+%d)\n", + i + 1, t->pattern, t->string, + flags_to_string(flags), + result, extra); + else { + printf("not ok %zu - fnmatch(\"%s\", \"%s\", %s) = %d != %d\n", + i + 1, t->pattern, t->string, + flags_to_string(flags), + result, t->result); + errors = 1; + } + } + + return (errors); +} From 139ac6b23976252cbbc61df7ac4a49afa3431d1c Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 16 Apr 2010 22:29:24 +0000 Subject: [PATCH 092/532] fnmatch: Fix bad FNM_PERIOD disabling if an asterisk has been seen. Example: fnmatch("a*b/*", "abbb/.x", FNM_PATHNAME | FNM_PERIOD) PR: 116074 MFC after: 1 week --- lib/libc/gen/fnmatch.c | 16 ++++++++-------- tools/regression/lib/libc/gen/test-fnmatch.c | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/libc/gen/fnmatch.c b/lib/libc/gen/fnmatch.c index e697bdcedf2..3acbc3b1647 100644 --- a/lib/libc/gen/fnmatch.c +++ b/lib/libc/gen/fnmatch.c @@ -67,7 +67,8 @@ __FBSDID("$FreeBSD$"); #define RANGE_ERROR (-1) static int rangematch(const char *, wchar_t, int, char **, mbstate_t *); -static int fnmatch1(const char *, const char *, int, mbstate_t, mbstate_t); +static int fnmatch1(const char *, const char *, const char *, int, mbstate_t, + mbstate_t); int fnmatch(pattern, string, flags) @@ -76,22 +77,21 @@ fnmatch(pattern, string, flags) { static const mbstate_t initial; - return (fnmatch1(pattern, string, flags, initial, initial)); + return (fnmatch1(pattern, string, string, flags, initial, initial)); } static int -fnmatch1(pattern, string, flags, patmbs, strmbs) - const char *pattern, *string; +fnmatch1(pattern, string, stringstart, flags, patmbs, strmbs) + const char *pattern, *string, *stringstart; int flags; mbstate_t patmbs, strmbs; { - const char *stringstart; char *newp; char c; wchar_t pc, sc; size_t pclen, sclen; - for (stringstart = string;;) { + for (;;) { pclen = mbrtowc(&pc, pattern, MB_LEN_MAX, &patmbs); if (pclen == (size_t)-1 || pclen == (size_t)-2) return (FNM_NOMATCH); @@ -145,8 +145,8 @@ fnmatch1(pattern, string, flags, patmbs, strmbs) /* General case, use recursion. */ while (sc != EOS) { - if (!fnmatch1(pattern, string, - flags & ~FNM_PERIOD, patmbs, strmbs)) + if (!fnmatch1(pattern, string, stringstart, + flags, patmbs, strmbs)) return (0); sclen = mbrtowc(&sc, string, MB_LEN_MAX, &strmbs); diff --git a/tools/regression/lib/libc/gen/test-fnmatch.c b/tools/regression/lib/libc/gen/test-fnmatch.c index ffb8c6c7800..6cbf8eeef70 100644 --- a/tools/regression/lib/libc/gen/test-fnmatch.c +++ b/tools/regression/lib/libc/gen/test-fnmatch.c @@ -174,6 +174,7 @@ struct testcase { "*a", ".a/b", FNM_PATHNAME | FNM_LEADING_DIR, 0, "*", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH, "*a", ".a/b", FNM_PATHNAME | FNM_PERIOD | FNM_LEADING_DIR, FNM_NOMATCH, + "a*b/*", "abbb/.x", FNM_PATHNAME | FNM_PERIOD, FNM_NOMATCH, }; static const char * From 4e859425ae287fde522d93b98f5df53814d1a9d9 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Fri, 16 Apr 2010 23:42:19 +0000 Subject: [PATCH 093/532] Set KERNLOADADDR and TARGET_BIG_ENDIAN for SWARM. --- sys/mips/conf/SWARM | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/mips/conf/SWARM b/sys/mips/conf/SWARM index 3189bcbcb9c..455e2986f9c 100644 --- a/sys/mips/conf/SWARM +++ b/sys/mips/conf/SWARM @@ -19,8 +19,13 @@ options CFE_CONSOLE options CFE_ENV options ALT_BREAK_TO_DEBUGGER +# Don't build any modules yet. +makeoptions MODULES_OVERRIDE="" +makeoptions TARGET_BIG_ENDIAN=defined makeoptions LDSCRIPT_NAME= ldscript.mips.cfe +makeoptions KERNLOADADDR=0x81000000 + #cpu CPU_MIPS64 #options ISA_MIPS64 #makeoptions ARCH_FLAGS="-march=mips64 -mgp64 -mabi=o64" From d0985cfb4121e3e5552101aa5b1789431ee70910 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Fri, 16 Apr 2010 23:46:30 +0000 Subject: [PATCH 094/532] o) Fix the intr_* functions to not spam the whole status register, just the IE bit. o) Remove some unused inlines. o) Generate CP0 access functions for 64-bit TLB registers when building for n64. o) Add an inline function version of the COP0_SYNC macro. --- sys/mips/include/cpufunc.h | 101 +++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index f9100eaeb32..9c34e3152d8 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -1,5 +1,29 @@ /* $OpenBSD: pio.h,v 1.2 1998/09/15 10:50:12 pefo Exp $ */ +/*- + * Copyright (c) 2002-2004 Juli Mallett. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ /* * Copyright (c) 1995-1999 Per Fogelstrom. All rights reserved. * @@ -58,15 +82,17 @@ mips_barrier(void) : : : "memory"); } +static __inline void +mips_cp0_sync(void) +{ + __asm __volatile (__XSTRING(COP0_SYNC)); +} + static __inline void mips_wbflush(void) { __asm __volatile ("sync" : : : "memory"); mips_barrier(); -#if 0 - __asm __volatile("mtc0 %0, $12\n" /* MIPS_COP_0_STATUS */ - : : "r" (flag)); -#endif } static __inline void @@ -82,54 +108,7 @@ mips_write_membar(void) } #ifdef _KERNEL - -static __inline void -mips_tlbp(void) -{ - __asm __volatile ("tlbp"); - mips_barrier(); -#if 0 - register_t ret; - register_t tmp; - - __asm __volatile("mfc0 %0, $12\n" /* MIPS_COP_0_STATUS */ - "and %1, %0, $~1\n" /* MIPS_SR_INT_IE */ - "mtc0 %1, $12\n" /* MIPS_COP_0_STATUS */ - : "=r" (ret), "=r" (tmp)); - return (ret); -#endif -} - -static __inline void -mips_tlbr(void) -{ - __asm __volatile ("tlbr"); - mips_barrier(); -} - -static __inline void -mips_tlbwi(void) -{ - __asm __volatile ("tlbwi"); - mips_barrier(); -#if 0 - __asm __volatile("mfc %0, $12\n" /* MIPS_COP_0_STATUS */ - "or %0, %0, $1\n" /* MIPS_SR_INT_IE */ - "mtc0 %0, $12\n" /* MIPS_COP_0_STATUS */ - : "=r" (tmp)); -#endif -} - -static __inline void -mips_tlbwr(void) -{ - __asm __volatile ("tlbwr"); - mips_barrier(); -} - - -#if 0 /* XXX mips64 */ - +#if defined(__mips_n32) || defined(__mips_n64) #define MIPS_RDRW64_COP0(n,r) \ static __inline uint64_t \ mips_rd_ ## n (void) \ @@ -152,10 +131,12 @@ mips_wr_ ## n (uint64_t a0) \ mips_barrier(); \ } struct __hack +#if defined(__mips_n64) MIPS_RDRW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0); MIPS_RDRW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1); MIPS_RDRW64_COP0(entryhi, MIPS_COP_0_TLB_HI); MIPS_RDRW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); +#endif MIPS_RDRW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT); #undef MIPS_RDRW64_COP0 @@ -230,12 +211,15 @@ MIPS_RDRW32_COP0(cause, MIPS_COP_0_CAUSE); MIPS_RDRW32_COP0(status, MIPS_COP_0_STATUS); /* XXX: Some of these registers are specific to MIPS32. */ +#if !defined(__mips_n64) MIPS_RDRW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0); MIPS_RDRW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1); -MIPS_RDRW32_COP0(entrylow, MIPS_COP_0_TLB_LOW); MIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI); MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); +#endif MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); +/* XXX 64-bit? */ +MIPS_RDRW32_COP0_SEL(prid, MIPS_COP_0_PRID, 1); MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1); MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2); @@ -250,7 +234,6 @@ MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 1); MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 2); MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 3); - #undef MIPS_RDRW32_COP0 static __inline register_t @@ -261,7 +244,7 @@ intr_disable(void) s = mips_rd_status(); mips_wr_status(s & ~MIPS_SR_INT_IE); - return (s); + return (s & MIPS_SR_INT_IE); } static __inline register_t @@ -275,7 +258,13 @@ intr_enable(void) return (s); } -#define intr_restore(s) mips_wr_status((s)) +static __inline void +intr_restore(register_t ie) +{ + if (ie == MIPS_SR_INT_IE) { + intr_enable(); + } +} static __inline void breakpoint(void) From 11484eb34fb91bbaa34cb1b811443f2a6107ec70 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Fri, 16 Apr 2010 23:48:28 +0000 Subject: [PATCH 095/532] o) Use the direct map where possible for uiomove_fromphys, based on code from sparc64. o) Use uiomove_fromphys rather than the broken fpage mechanism for /dev/mem. o) Update sf_buf allocator to not share buffers and to do a pmap_qremove when done with an sf_buf so as to better track valid mappings. --- sys/mips/include/sf_buf.h | 15 +-- sys/mips/mips/mem.c | 196 ++++++++++++++++-------------------- sys/mips/mips/uio_machdep.c | 34 ++++--- sys/mips/mips/vm_machdep.c | 117 ++++++++------------- 4 files changed, 150 insertions(+), 212 deletions(-) diff --git a/sys/mips/include/sf_buf.h b/sys/mips/include/sf_buf.h index 0a9980cf3d7..b6ee1cc20b6 100644 --- a/sys/mips/include/sf_buf.h +++ b/sys/mips/include/sf_buf.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2005 Alan L. Cox + * Copyright (c) 2003 Alan L. Cox * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,29 +23,20 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * from: src/sys/i386/include/sf_buf.h,v 1.4 2005/02/13 06:23:13 alc * $FreeBSD$ */ #ifndef _MACHINE_SF_BUF_H_ -#define _MACHINE_SF_BUF_H_ +#define _MACHINE_SF_BUF_H_ #include -#include -#include -#include struct vm_page; struct sf_buf { - LIST_ENTRY(sf_buf) list_entry; /* list of buffers */ - TAILQ_ENTRY(sf_buf) free_entry; /* list of buffers */ + SLIST_ENTRY(sf_buf) free_list; /* list of free buffer slots */ struct vm_page *m; /* currently mapped page */ vm_offset_t kva; /* va of mapping */ - int ref_count; /* usage of this mapping */ -#ifdef SMP - cpumask_t cpumask; /* cpus on which mapping is valid */ -#endif }; static __inline vm_offset_t diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c index c0e88e08e0c..a7f8244385a 100644 --- a/sys/mips/mips/mem.c +++ b/sys/mips/mips/mem.c @@ -1,13 +1,12 @@ -/* $OpenBSD: mem.c,v 1.2 1998/08/31 17:42:34 millert Exp $ */ -/* $NetBSD: mem.c,v 1.6 1995/04/10 11:55:03 mycroft Exp $ */ -/* +/*- * Copyright (c) 1988 University of Utah. - * Copyright (c) 1982, 1986, 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. + * All rights reserved. * * This code is derived from software contributed to Berkeley by * the Systems Programming Group of the University of Utah Computer - * Science Department and Ralph Campbell. + * Science Department, and code derived from software contributed to + * Berkeley by William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,161 +32,136 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)mem.c 8.3 (Berkeley) 1/12/94 - * JNPR: mem.c,v 1.3 2007/08/09 11:23:32 katta Exp $ - */ - -/* - * Memory special file + * from: Utah $Hdr: mem.c 1.13 89/10/08$ + * from: @(#)mem.c 7.2 (Berkeley) 5/9/91 */ #include __FBSDID("$FreeBSD$"); +/* + * Memory special file + */ + #include -#include #include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include #include -#include -#include +#include #include -#include -#include -#include -#include + #include -#include +#include + +#include +#include +#include +#include + #include +struct mem_range_softc mem_range_softc; -extern struct sysmaps sysmaps_pcpu[]; -/*ARGSUSED*/ +/* ARGSUSED */ int -memrw(dev, uio, flags) - struct cdev *dev; - struct uio *uio; - int flags; +memrw(struct cdev *dev, struct uio *uio, int flags) { - register vm_offset_t v; - register int c; - register struct iovec *iov; + struct iovec *iov; int error = 0; + vm_offset_t va, eva, off, v; + vm_prot_t prot; + struct vm_page m; + vm_page_t marr; + vm_size_t cnt; - while (uio->uio_resid > 0 && error == 0) { + cnt = 0; + error = 0; + + GIANT_REQUIRED; + + while (uio->uio_resid > 0 && !error) { iov = uio->uio_iov; if (iov->iov_len == 0) { uio->uio_iov++; uio->uio_iovcnt--; if (uio->uio_iovcnt < 0) - panic("mmrw"); + panic("memrw"); continue; } - - /* minor device 0 is physical memory */ if (dev2unit(dev) == CDEV_MINOR_MEM) { v = uio->uio_offset; - c = iov->iov_len; - vm_offset_t va; - vm_paddr_t pa; - register int o; + off = uio->uio_offset & PAGE_MASK; + cnt = PAGE_SIZE - ((vm_offset_t)iov->iov_base & + PAGE_MASK); + cnt = min(cnt, PAGE_SIZE - off); + cnt = min(cnt, iov->iov_len); - if (is_cacheable_mem(v) && - is_cacheable_mem(v + c - 1)) { - struct fpage *fp; - struct sysmaps *sysmaps; - - sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; - mtx_lock(&sysmaps->lock); - sched_pin(); - - fp = &sysmaps->fp[PMAP_FPAGE1]; - pa = uio->uio_offset & ~PAGE_MASK; - va = pmap_map_fpage(pa, fp, FALSE); - o = (int)uio->uio_offset & PAGE_MASK; - c = (u_int)(PAGE_SIZE - - ((uintptr_t)iov->iov_base & PAGE_MASK)); - c = min(c, (u_int)(PAGE_SIZE - o)); - c = min(c, (u_int)iov->iov_len); - error = uiomove((caddr_t)(va + o), (int)c, uio); - pmap_unmap_fpage(pa, fp); - sched_unpin(); - mtx_unlock(&sysmaps->lock); - } else - return (EFAULT); - continue; + m.phys_addr = trunc_page(v); + marr = &m; + error = uiomove_fromphys(&marr, off, cnt, uio); } - - /* minor device 1 is kernel memory */ else if (dev2unit(dev) == CDEV_MINOR_KMEM) { - v = uio->uio_offset; - c = min(iov->iov_len, MAXPHYS); + va = uio->uio_offset; - vm_offset_t addr, eaddr; - vm_offset_t wired_tlb_virtmem_end; + va = trunc_page(uio->uio_offset); + eva = round_page(uio->uio_offset + + iov->iov_len); - /* - * Make sure that all of the pages are currently - * resident so that we don't create any zero-fill pages. + /* + * Make sure that all the pages are currently resident + * so that we don't create any zero-fill pages. */ - addr = trunc_page(uio->uio_offset); - eaddr = round_page(uio->uio_offset + c); - if (addr > (vm_offset_t) VM_MIN_KERNEL_ADDRESS) { - wired_tlb_virtmem_end = VM_MIN_KERNEL_ADDRESS + - VM_KERNEL_ALLOC_OFFSET; - if ((addr < wired_tlb_virtmem_end) && - (eaddr >= wired_tlb_virtmem_end)) - addr = wired_tlb_virtmem_end; - - if (addr >= wired_tlb_virtmem_end) { - for (; addr < eaddr; addr += PAGE_SIZE) - if (pmap_extract(kernel_pmap, - addr) == 0) - return EFAULT; - - if (!kernacc( - (caddr_t)(uintptr_t)uio->uio_offset, c, - uio->uio_rw == UIO_READ ? - VM_PROT_READ : VM_PROT_WRITE)) - return (EFAULT); - } - } - else if (MIPS_IS_KSEG0_ADDR(v)) { - if (MIPS_KSEG0_TO_PHYS(v + c) >= ctob(physmem)) + for (; va < eva; va += PAGE_SIZE) + if (pmap_extract(kernel_pmap, va) == 0) return (EFAULT); - } - else if (MIPS_IS_KSEG1_ADDR(v)) { - if (MIPS_KSEG1_TO_PHYS(v + c) >= ctob(physmem)) - return (EFAULT); - } - else + + prot = (uio->uio_rw == UIO_READ) + ? VM_PROT_READ : VM_PROT_WRITE; + + va = uio->uio_offset; + if (kernacc((void *) va, iov->iov_len, prot) + == FALSE) return (EFAULT); + error = uiomove((void *)va, iov->iov_len, uio); - error = uiomove((caddr_t)v, c, uio); continue; } - } + return (error); } -/*ARGSUSED*/ +/* + * allow user processes to MMAP some memory sections + * instead of going through read/write + */ int -memmmap(struct cdev *dev, vm_ooffset_t off, vm_paddr_t *paddr, +memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot, vm_memattr_t *memattr) { + /* + * /dev/mem is the only one that makes sense through this + * interface. For /dev/kmem any physaddr we return here + * could be transient and hence incorrect or invalid at + * a later time. + */ + if (dev2unit(dev) != CDEV_MINOR_MEM) + return (-1); - return (EOPNOTSUPP); + *paddr = offset; + + return (0); } void diff --git a/sys/mips/mips/uio_machdep.c b/sys/mips/mips/uio_machdep.c index 0872b4d388e..10deff667e5 100644 --- a/sys/mips/mips/uio_machdep.c +++ b/sys/mips/mips/uio_machdep.c @@ -32,8 +32,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94 - * from: src/sys/i386/i386/uio_machdep.c,v 1.8 2005/02/13 23:09:36 alc + * @(#)kern_subr.c 8.3 (Berkeley) 1/21/94 */ #include @@ -44,17 +43,18 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include #include #include +#include /* - * Implement uiomove(9) from physical memory using sf_bufs to reduce - * the creation and destruction of ephemeral mappings. + * Implement uiomove(9) from physical memory using a combination + * of the direct mapping and sf_bufs to reduce the creation and + * destruction of ephemeral mappings. */ int uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) @@ -64,6 +64,8 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) struct iovec *iov; void *cp; vm_offset_t page_offset; + vm_paddr_t pa; + vm_page_t m; size_t cnt; int error = 0; int save = 0; @@ -85,10 +87,16 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) if (cnt > n) cnt = n; page_offset = offset & PAGE_MASK; - cnt = min(cnt, PAGE_SIZE - page_offset); - sched_pin(); - sf = sf_buf_alloc(ma[offset >> PAGE_SHIFT], SFB_CPUPRIVATE); - cp = (char *)sf_buf_kva(sf) + page_offset; + cnt = ulmin(cnt, PAGE_SIZE - page_offset); + m = ma[offset >> PAGE_SHIFT]; + pa = VM_PAGE_TO_PHYS(m); + if (pa < MIPS_KSEG0_LARGEST_PHYS) { + cp = (char *)MIPS_PHYS_TO_KSEG0(pa); + sf = NULL; + } else { + sf = sf_buf_alloc(m, 0); + cp = (char *)sf_buf_kva(sf) + page_offset; + } switch (uio->uio_segflg) { case UIO_USERSPACE: if (ticks - PCPU_GET(switchticks) >= hogticks) @@ -98,8 +106,8 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) else error = copyin(iov->iov_base, cp, cnt); if (error) { - sf_buf_free(sf); - sched_unpin(); + if (sf != NULL) + sf_buf_free(sf); goto out; } break; @@ -112,8 +120,8 @@ uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) case UIO_NOCOPY: break; } - sf_buf_free(sf); - sched_unpin(); + if (sf != NULL) + sf_buf_free(sf); iov->iov_base = (char *)iov->iov_base + cnt; iov->iov_len -= cnt; uio->uio_resid -= cnt; diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 57219f638f5..3b7a1a1b18c 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -56,6 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -63,12 +64,15 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -81,25 +85,17 @@ __FBSDID("$FreeBSD$"); static void sf_buf_init(void *arg); SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL); -LIST_HEAD(sf_head, sf_buf); - - /* - * A hash table of active sendfile(2) buffers + * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the + * sf_freelist head with the sf_lock mutex. */ -static struct sf_head *sf_buf_active; -static u_long sf_buf_hashmask; +static struct { + SLIST_HEAD(, sf_buf) sf_head; + struct mtx sf_lock; +} sf_freelist; -#define SF_BUF_HASH(m) (((m) - vm_page_array) & sf_buf_hashmask) - -static TAILQ_HEAD(, sf_buf) sf_buf_freelist; static u_int sf_buf_alloc_want; -/* - * A lock used to synchronize access to the hash table and free list - */ -static struct mtx sf_buf_lock; - /* * Finish a fork operation, with process p2 nearly set up. * Copy and update the pcb, set up the stack so that the child @@ -471,56 +467,34 @@ sf_buf_init(void *arg) nsfbufs = NSFBUFS; TUNABLE_INT_FETCH("kern.ipc.nsfbufs", &nsfbufs); - sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask); - TAILQ_INIT(&sf_buf_freelist); + mtx_init(&sf_freelist.sf_lock, "sf_bufs list lock", NULL, MTX_DEF); + SLIST_INIT(&sf_freelist.sf_head); sf_base = kmem_alloc_nofault(kernel_map, nsfbufs * PAGE_SIZE); sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP, M_NOWAIT | M_ZERO); for (i = 0; i < nsfbufs; i++) { sf_bufs[i].kva = sf_base + i * PAGE_SIZE; - TAILQ_INSERT_TAIL(&sf_buf_freelist, &sf_bufs[i], free_entry); + SLIST_INSERT_HEAD(&sf_freelist.sf_head, &sf_bufs[i], free_list); } sf_buf_alloc_want = 0; - mtx_init(&sf_buf_lock, "sf_buf", NULL, MTX_DEF); } /* - * Allocate an sf_buf for the given vm_page. On this machine, however, there - * is no sf_buf object. Instead, an opaque pointer to the given vm_page is - * returned. + * Get an sf_buf from the freelist. Will block if none are available. */ struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags) { - struct sf_head *hash_list; struct sf_buf *sf; int error; - hash_list = &sf_buf_active[SF_BUF_HASH(m)]; - mtx_lock(&sf_buf_lock); - LIST_FOREACH(sf, hash_list, list_entry) { - if (sf->m == m) { - sf->ref_count++; - if (sf->ref_count == 1) { - TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry); - nsfbufsused++; - nsfbufspeak = imax(nsfbufspeak, nsfbufsused); - } - /* - * Flush all mappings in order to have up to date - * physycal memory - */ - pmap_flush_pvcache(sf->m); - mips_dcache_inv_range(sf->kva, PAGE_SIZE); - goto done; - } - } - while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) { + mtx_lock(&sf_freelist.sf_lock); + while ((sf = SLIST_FIRST(&sf_freelist.sf_head)) == NULL) { if (flags & SFB_NOWAIT) - goto done; + break; sf_buf_alloc_want++; mbstat.sf_allocwait++; - error = msleep(&sf_buf_freelist, &sf_buf_lock, + error = msleep(&sf_freelist, &sf_freelist.sf_lock, (flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0); sf_buf_alloc_want--; @@ -528,42 +502,33 @@ sf_buf_alloc(struct vm_page *m, int flags) * If we got a signal, don't risk going back to sleep. */ if (error) - goto done; + break; } - TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry); - if (sf->m != NULL) - LIST_REMOVE(sf, list_entry); - LIST_INSERT_HEAD(hash_list, sf, list_entry); - sf->ref_count = 1; - sf->m = m; - nsfbufsused++; - nsfbufspeak = imax(nsfbufspeak, nsfbufsused); - pmap_qenter(sf->kva, &sf->m, 1); -done: - mtx_unlock(&sf_buf_lock); + if (sf != NULL) { + SLIST_REMOVE_HEAD(&sf_freelist.sf_head, free_list); + sf->m = m; + nsfbufsused++; + nsfbufspeak = imax(nsfbufspeak, nsfbufsused); + pmap_qenter(sf->kva, &sf->m, 1); + } + mtx_unlock(&sf_freelist.sf_lock); return (sf); } /* - * Free the sf_buf. In fact, do nothing because there are no resources - * associated with the sf_buf. + * Release resources back to the system. */ void sf_buf_free(struct sf_buf *sf) { - mtx_lock(&sf_buf_lock); - sf->ref_count--; - /* - * Make sure all changes in KVA end up in physical memory - */ - mips_dcache_wbinv_range(sf->kva, PAGE_SIZE); - if (sf->ref_count == 0) { - TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry); - nsfbufsused--; - if (sf_buf_alloc_want > 0) - wakeup_one(&sf_buf_freelist); - } - mtx_unlock(&sf_buf_lock); + + pmap_qremove(sf->kva, 1); + mtx_lock(&sf_freelist.sf_lock); + SLIST_INSERT_HEAD(&sf_freelist.sf_head, sf, free_list); + nsfbufsused--; + if (sf_buf_alloc_want > 0) + wakeup_one(&sf_freelist); + mtx_unlock(&sf_freelist.sf_lock); } /* From 2ae5ecf8a2070f3235255bcb39df8d241eef834f Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Fri, 16 Apr 2010 23:54:56 +0000 Subject: [PATCH 096/532] Adjust limits and formats for ABIs with 64-bit longs. --- sys/mips/include/_inttypes.h | 94 +++++++++++++++++++----------------- sys/mips/include/_limits.h | 8 ++- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/sys/mips/include/_inttypes.h b/sys/mips/include/_inttypes.h index 7b14b9b83cb..79664e4f383 100644 --- a/sys/mips/include/_inttypes.h +++ b/sys/mips/include/_inttypes.h @@ -38,177 +38,183 @@ * Macros for format specifiers. */ +#if defined(__mips_n64) +#define PRI64 "l" +#else +#define PRI64 "ll" +#endif + /* fprintf(3) macros for signed integers. */ #define PRId8 "d" /* int8_t */ #define PRId16 "d" /* int16_t */ #define PRId32 "d" /* int32_t */ -#define PRId64 "lld" /* int64_t */ +#define PRId64 PRI64"d" /* int64_t */ #define PRIdLEAST8 "d" /* int_least8_t */ #define PRIdLEAST16 "d" /* int_least16_t */ #define PRIdLEAST32 "d" /* int_least32_t */ -#define PRIdLEAST64 "lld" /* int_least64_t */ +#define PRIdLEAST64 PRI64"d" /* int_least64_t */ #define PRIdFAST8 "d" /* int_fast8_t */ #define PRIdFAST16 "d" /* int_fast16_t */ #define PRIdFAST32 "d" /* int_fast32_t */ -#define PRIdFAST64 "lld" /* int_fast64_t */ +#define PRIdFAST64 PRI64"d" /* int_fast64_t */ #define PRIdMAX "jd" /* intmax_t */ -#define PRIdPTR "d" /* intptr_t */ +#define PRIdPTR "ld" /* intptr_t */ #define PRIi8 "i" /* int8_t */ #define PRIi16 "i" /* int16_t */ #define PRIi32 "i" /* int32_t */ -#define PRIi64 "lli" /* int64_t */ +#define PRIi64 PRI64"i" /* int64_t */ #define PRIiLEAST8 "i" /* int_least8_t */ #define PRIiLEAST16 "i" /* int_least16_t */ #define PRIiLEAST32 "i" /* int_least32_t */ -#define PRIiLEAST64 "lli" /* int_least64_t */ +#define PRIiLEAST64 PRI64"i" /* int_least64_t */ #define PRIiFAST8 "i" /* int_fast8_t */ #define PRIiFAST16 "i" /* int_fast16_t */ #define PRIiFAST32 "i" /* int_fast32_t */ -#define PRIiFAST64 "lli" /* int_fast64_t */ +#define PRIiFAST64 PRI64"i" /* int_fast64_t */ #define PRIiMAX "ji" /* intmax_t */ -#define PRIiPTR "i" /* intptr_t */ +#define PRIiPTR "li" /* intptr_t */ /* fprintf(3) macros for unsigned integers. */ #define PRIo8 "o" /* uint8_t */ #define PRIo16 "o" /* uint16_t */ #define PRIo32 "o" /* uint32_t */ -#define PRIo64 "llo" /* uint64_t */ +#define PRIo64 PRI64"o" /* uint64_t */ #define PRIoLEAST8 "o" /* uint_least8_t */ #define PRIoLEAST16 "o" /* uint_least16_t */ #define PRIoLEAST32 "o" /* uint_least32_t */ -#define PRIoLEAST64 "llo" /* uint_least64_t */ +#define PRIoLEAST64 PRI64"o" /* uint_least64_t */ #define PRIoFAST8 "o" /* uint_fast8_t */ #define PRIoFAST16 "o" /* uint_fast16_t */ #define PRIoFAST32 "o" /* uint_fast32_t */ -#define PRIoFAST64 "llo" /* uint_fast64_t */ +#define PRIoFAST64 PRI64"o" /* uint_fast64_t */ #define PRIoMAX "jo" /* uintmax_t */ -#define PRIoPTR "o" /* uintptr_t */ +#define PRIoPTR "lo" /* uintptr_t */ #define PRIu8 "u" /* uint8_t */ #define PRIu16 "u" /* uint16_t */ #define PRIu32 "u" /* uint32_t */ -#define PRIu64 "llu" /* uint64_t */ +#define PRIu64 PRI64"u" /* uint64_t */ #define PRIuLEAST8 "u" /* uint_least8_t */ #define PRIuLEAST16 "u" /* uint_least16_t */ #define PRIuLEAST32 "u" /* uint_least32_t */ -#define PRIuLEAST64 "llu" /* uint_least64_t */ +#define PRIuLEAST64 PRI64"u" /* uint_least64_t */ #define PRIuFAST8 "u" /* uint_fast8_t */ #define PRIuFAST16 "u" /* uint_fast16_t */ #define PRIuFAST32 "u" /* uint_fast32_t */ -#define PRIuFAST64 "llu" /* uint_fast64_t */ +#define PRIuFAST64 PRI64"u" /* uint_fast64_t */ #define PRIuMAX "ju" /* uintmax_t */ -#define PRIuPTR "u" /* uintptr_t */ +#define PRIuPTR "lu" /* uintptr_t */ #define PRIx8 "x" /* uint8_t */ #define PRIx16 "x" /* uint16_t */ #define PRIx32 "x" /* uint32_t */ -#define PRIx64 "llx" /* uint64_t */ +#define PRIx64 PRI64"x" /* uint64_t */ #define PRIxLEAST8 "x" /* uint_least8_t */ #define PRIxLEAST16 "x" /* uint_least16_t */ #define PRIxLEAST32 "x" /* uint_least32_t */ -#define PRIxLEAST64 "llx" /* uint_least64_t */ +#define PRIxLEAST64 PRI64"x" /* uint_least64_t */ #define PRIxFAST8 "x" /* uint_fast8_t */ #define PRIxFAST16 "x" /* uint_fast16_t */ #define PRIxFAST32 "x" /* uint_fast32_t */ -#define PRIxFAST64 "llx" /* uint_fast64_t */ +#define PRIxFAST64 PRI64"x" /* uint_fast64_t */ #define PRIxMAX "jx" /* uintmax_t */ -#define PRIxPTR "x" /* uintptr_t */ +#define PRIxPTR "lx" /* uintptr_t */ #define PRIX8 "X" /* uint8_t */ #define PRIX16 "X" /* uint16_t */ #define PRIX32 "X" /* uint32_t */ -#define PRIX64 "llX" /* uint64_t */ +#define PRIX64 PRI64"X" /* uint64_t */ #define PRIXLEAST8 "X" /* uint_least8_t */ #define PRIXLEAST16 "X" /* uint_least16_t */ #define PRIXLEAST32 "X" /* uint_least32_t */ -#define PRIXLEAST64 "llX" /* uint_least64_t */ +#define PRIXLEAST64 PRI64"X" /* uint_least64_t */ #define PRIXFAST8 "X" /* uint_fast8_t */ #define PRIXFAST16 "X" /* uint_fast16_t */ #define PRIXFAST32 "X" /* uint_fast32_t */ -#define PRIXFAST64 "llX" /* uint_fast64_t */ +#define PRIXFAST64 PRI64"X" /* uint_fast64_t */ #define PRIXMAX "jX" /* uintmax_t */ -#define PRIXPTR "X" /* uintptr_t */ +#define PRIXPTR "lX" /* uintptr_t */ /* fscanf(3) macros for signed integers. */ #define SCNd8 "hhd" /* int8_t */ #define SCNd16 "hd" /* int16_t */ #define SCNd32 "d" /* int32_t */ -#define SCNd64 "lld" /* int64_t */ +#define SCNd64 PRI64"d" /* int64_t */ #define SCNdLEAST8 "hhd" /* int_least8_t */ #define SCNdLEAST16 "hd" /* int_least16_t */ #define SCNdLEAST32 "d" /* int_least32_t */ -#define SCNdLEAST64 "lld" /* int_least64_t */ +#define SCNdLEAST64 PRI64"d" /* int_least64_t */ #define SCNdFAST8 "d" /* int_fast8_t */ #define SCNdFAST16 "d" /* int_fast16_t */ #define SCNdFAST32 "d" /* int_fast32_t */ -#define SCNdFAST64 "lld" /* int_fast64_t */ +#define SCNdFAST64 PRI64"d" /* int_fast64_t */ #define SCNdMAX "jd" /* intmax_t */ -#define SCNdPTR "d" /* intptr_t */ +#define SCNdPTR "ld" /* intptr_t */ #define SCNi8 "hhi" /* int8_t */ #define SCNi16 "hi" /* int16_t */ #define SCNi32 "i" /* int32_t */ -#define SCNi64 "lli" /* int64_t */ +#define SCNi64 PRI64"i" /* int64_t */ #define SCNiLEAST8 "hhi" /* int_least8_t */ #define SCNiLEAST16 "hi" /* int_least16_t */ #define SCNiLEAST32 "i" /* int_least32_t */ -#define SCNiLEAST64 "lli" /* int_least64_t */ +#define SCNiLEAST64 PRI64"i" /* int_least64_t */ #define SCNiFAST8 "i" /* int_fast8_t */ #define SCNiFAST16 "i" /* int_fast16_t */ #define SCNiFAST32 "i" /* int_fast32_t */ -#define SCNiFAST64 "lli" /* int_fast64_t */ +#define SCNiFAST64 PRI64"i" /* int_fast64_t */ #define SCNiMAX "ji" /* intmax_t */ -#define SCNiPTR "i" /* intptr_t */ +#define SCNiPTR "li" /* intptr_t */ /* fscanf(3) macros for unsigned integers. */ #define SCNo8 "hho" /* uint8_t */ #define SCNo16 "ho" /* uint16_t */ #define SCNo32 "o" /* uint32_t */ -#define SCNo64 "llo" /* uint64_t */ +#define SCNo64 PRI64"o" /* uint64_t */ #define SCNoLEAST8 "hho" /* uint_least8_t */ #define SCNoLEAST16 "ho" /* uint_least16_t */ #define SCNoLEAST32 "o" /* uint_least32_t */ -#define SCNoLEAST64 "llo" /* uint_least64_t */ +#define SCNoLEAST64 PRI64"o" /* uint_least64_t */ #define SCNoFAST8 "o" /* uint_fast8_t */ #define SCNoFAST16 "o" /* uint_fast16_t */ #define SCNoFAST32 "o" /* uint_fast32_t */ -#define SCNoFAST64 "llo" /* uint_fast64_t */ +#define SCNoFAST64 PRI64"o" /* uint_fast64_t */ #define SCNoMAX "jo" /* uintmax_t */ -#define SCNoPTR "o" /* uintptr_t */ +#define SCNoPTR "lo" /* uintptr_t */ #define SCNu8 "hhu" /* uint8_t */ #define SCNu16 "hu" /* uint16_t */ #define SCNu32 "u" /* uint32_t */ -#define SCNu64 "llu" /* uint64_t */ +#define SCNu64 PRI64"u" /* uint64_t */ #define SCNuLEAST8 "hhu" /* uint_least8_t */ #define SCNuLEAST16 "hu" /* uint_least16_t */ #define SCNuLEAST32 "u" /* uint_least32_t */ -#define SCNuLEAST64 "llu" /* uint_least64_t */ +#define SCNuLEAST64 PRI64"u" /* uint_least64_t */ #define SCNuFAST8 "u" /* uint_fast8_t */ #define SCNuFAST16 "u" /* uint_fast16_t */ #define SCNuFAST32 "u" /* uint_fast32_t */ -#define SCNuFAST64 "llu" /* uint_fast64_t */ +#define SCNuFAST64 PRI64"u" /* uint_fast64_t */ #define SCNuMAX "ju" /* uintmax_t */ -#define SCNuPTR "u" /* uintptr_t */ +#define SCNuPTR "lu" /* uintptr_t */ #define SCNx8 "hhx" /* uint8_t */ #define SCNx16 "hx" /* uint16_t */ #define SCNx32 "x" /* uint32_t */ -#define SCNx64 "llx" /* uint64_t */ +#define SCNx64 PRI64"x" /* uint64_t */ #define SCNxLEAST8 "hhx" /* uint_least8_t */ #define SCNxLEAST16 "hx" /* uint_least16_t */ #define SCNxLEAST32 "x" /* uint_least32_t */ -#define SCNxLEAST64 "llx" /* uint_least64_t */ +#define SCNxLEAST64 PRI64"x" /* uint_least64_t */ #define SCNxFAST8 "x" /* uint_fast8_t */ #define SCNxFAST16 "x" /* uint_fast16_t */ #define SCNxFAST32 "x" /* uint_fast32_t */ -#define SCNxFAST64 "llx" /* uint_fast64_t */ +#define SCNxFAST64 PRI64"x" /* uint_fast64_t */ #define SCNxMAX "jx" /* uintmax_t */ -#define SCNxPTR "x" /* uintptr_t */ +#define SCNxPTR "lx" /* uintptr_t */ #endif /* !_MACHINE_INTTYPES_H_ */ diff --git a/sys/mips/include/_limits.h b/sys/mips/include/_limits.h index d544305ce8e..e160a7f4a1d 100644 --- a/sys/mips/include/_limits.h +++ b/sys/mips/include/_limits.h @@ -34,6 +34,10 @@ #ifndef _MACHINE__LIMITS_H_ #define _MACHINE__LIMITS_H_ +#if _MIPS_SZLONG == 64 +#define _LARGE_LONG +#endif + /* * According to ANSI (section 2.2.4.2), the values below must be usable by * #if preprocessing directives. Additionally, the expression must have the @@ -76,9 +80,9 @@ #define __LLONG_MAX 0x7fffffffffffffffLL /* max value for a long long */ #define __LLONG_MIN (-0x7fffffffffffffffLL - 1) /* min for a long long */ -#define __SSIZE_MAX __INT_MAX /* max value for a ssize_t */ +#define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */ -#define __SIZE_T_MAX __UINT_MAX /* max value for a size_t */ +#define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */ #define __OFF_MAX __LLONG_MAX /* max value for an off_t */ #define __OFF_MIN __LLONG_MIN /* min value for an off_t */ From e586cf9a2847c8f7f1d61cfef3b531536e0bb219 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 17 Apr 2010 00:05:22 +0000 Subject: [PATCH 097/532] o) Remove code related to VM_ALLOC_WIRED_TLB_PG_POOL, VM_KERNEL_ALLOC_OFFSET and floating pages. They are unused and unsupported. --- sys/mips/include/pmap.h | 37 ---- sys/mips/include/vmparam.h | 6 +- sys/mips/mips/genassym.c | 1 - sys/mips/mips/machdep.c | 4 - sys/mips/mips/pmap.c | 351 +++++++------------------------------ sys/mips/mips/swtch.S | 2 +- 6 files changed, 61 insertions(+), 340 deletions(-) diff --git a/sys/mips/include/pmap.h b/sys/mips/include/pmap.h index 51ff5512e79..80772d97ee9 100644 --- a/sys/mips/include/pmap.h +++ b/sys/mips/include/pmap.h @@ -160,14 +160,8 @@ typedef struct pv_entry { extern vm_offset_t phys_avail[PHYS_AVAIL_ENTRIES + 2]; extern vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; -extern char *ptvmmap; /* poor name! */ extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; -extern pd_entry_t *segbase; - -extern vm_paddr_t mips_wired_tlb_physmem_start; -extern vm_paddr_t mips_wired_tlb_physmem_end; -extern u_int need_wired_tlb_page_pool; #define pmap_page_get_memattr(m) VM_MEMATTR_DEFAULT #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) @@ -188,37 +182,6 @@ int pmap_compute_pages_to_dump(void); void pmap_update_page(pmap_t pmap, vm_offset_t va, pt_entry_t pte); void pmap_flush_pvcache(vm_page_t m); -/* - * floating virtual pages (FPAGES) - * - * These are the reserved virtual memory areas which can be - * mapped to any physical memory. - */ -#define FPAGES 2 -#define FPAGES_SHARED 2 -#define FSPACE ((FPAGES * MAXCPU + FPAGES_SHARED) * PAGE_SIZE) -#define PMAP_FPAGE1 0x00 /* Used by pmap_zero_page & - * pmap_copy_page */ -#define PMAP_FPAGE2 0x01 /* Used by pmap_copy_page */ - -#define PMAP_FPAGE3 0x00 /* Used by pmap_zero_page_idle */ -#define PMAP_FPAGE_KENTER_TEMP 0x01 /* Used by coredump */ - -struct fpage { - vm_offset_t kva; - u_int state; -}; - -struct sysmaps { - struct mtx lock; - struct fpage fp[FPAGES]; -}; - -vm_offset_t -pmap_map_fpage(vm_paddr_t pa, struct fpage *fp, - boolean_t check_unmaped); -void pmap_unmap_fpage(vm_paddr_t pa, struct fpage *fp); - /* * Function to save TLB contents so that they may be inspected in the debugger. */ diff --git a/sys/mips/include/vmparam.h b/sys/mips/include/vmparam.h index a5242934019..d4bc7fa07b0 100644 --- a/sys/mips/include/vmparam.h +++ b/sys/mips/include/vmparam.h @@ -101,12 +101,8 @@ #define VM_MAX_MMAP_ADDR VM_MAXUSER_ADDRESS #define VM_MAX_ADDRESS ((vm_offset_t)0x80000000) -#ifndef VM_KERNEL_ALLOC_OFFSET -#define VM_KERNEL_ALLOC_OFFSET ((vm_offset_t)0x00000000) -#endif - #define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0xC0000000) -#define VM_KERNEL_WIRED_ADDR_END (VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET) +#define VM_KERNEL_WIRED_ADDR_END (VM_MIN_KERNEL_ADDRESS) #define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xFFFFC000) /* diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index 62da8f1f501..f59ef6854ba 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -87,7 +87,6 @@ ASSYM(PC_CURPMAP, offsetof(struct pcpu, pc_curpmap)); ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS); ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); -ASSYM(VM_KERNEL_ALLOC_OFFSET, VM_KERNEL_ALLOC_OFFSET); ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); ASSYM(SIGFPE, SIGFPE); ASSYM(PAGE_SHIFT, PAGE_SHIFT); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index ad1dab52206..4f728d56c05 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -142,10 +142,6 @@ vm_offset_t physmem_desc[PHYS_AVAIL_ENTRIES + 2]; struct platform platform; #endif -vm_paddr_t mips_wired_tlb_physmem_start; -vm_paddr_t mips_wired_tlb_physmem_end; -u_int need_wired_tlb_page_pool; - static void cpu_startup(void *); SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index d5765ea9b0e..9f01f8a88c4 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -161,10 +161,6 @@ static uma_zone_t pvzone; static struct vm_object pvzone_obj; static int pv_entry_count = 0, pv_entry_max = 0, pv_entry_high_water = 0; -struct fpage fpages_shared[FPAGES_SHARED]; - -struct sysmaps sysmaps_pcpu[MAXCPU]; - static PMAP_INLINE void free_pv_entry(pv_entry_t pv); static pv_entry_t get_pv_entry(pmap_t locked_pmap); static __inline void pmap_changebit(vm_page_t m, int bit, boolean_t setem); @@ -188,7 +184,6 @@ static int pmap_unuse_pt(pmap_t, vm_offset_t, vm_page_t); static int init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot); static void pmap_TLB_invalidate_kernel(vm_offset_t); static void pmap_TLB_update_kernel(vm_offset_t, pt_entry_t); -static void pmap_init_fpage(void); #ifdef SMP static void pmap_invalidate_page_action(void *arg); @@ -355,7 +350,7 @@ again: kstack0 = pmap_steal_memory(KSTACK_PAGES << PAGE_SHIFT); - virtual_avail = VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET; + virtual_avail = VM_MIN_KERNEL_ADDRESS; virtual_end = VM_MAX_KERNEL_ADDRESS; #ifdef SMP @@ -480,8 +475,6 @@ void pmap_init(void) { - if (need_wired_tlb_page_pool) - pmap_init_fpage(); /* * Initialize the address space (zone) for the pv entries. Set a * high water mark so that the system can recover from excessive @@ -805,136 +798,6 @@ pmap_qremove(vm_offset_t va, int count) * Page table page management routines..... ***************************************************/ -/* - * floating pages (FPAGES) management routines - * - * FPAGES are the reserved virtual memory areas which can be - * mapped to any physical memory. This gets used typically - * in the following functions: - * - * pmap_zero_page - * pmap_copy_page - */ - -/* - * Create the floating pages, aka FPAGES! - */ -static void -pmap_init_fpage() -{ - vm_offset_t kva; - int i, j; - struct sysmaps *sysmaps; - - /* - * We allocate a total of (FPAGES*MAXCPU + FPAGES_SHARED + 1) pages - * at first. FPAGES & FPAGES_SHARED should be EVEN Then we'll adjust - * 'kva' to be even-page aligned so that the fpage area can be wired - * in the TLB with a single TLB entry. - */ - kva = kmem_alloc_nofault(kernel_map, - (FPAGES * MAXCPU + 1 + FPAGES_SHARED) * PAGE_SIZE); - if ((void *)kva == NULL) - panic("pmap_init_fpage: fpage allocation failed"); - - /* - * Make up start at an even page number so we can wire down the - * fpage area in the tlb with a single tlb entry. - */ - if ((((vm_offset_t)kva) >> PGSHIFT) & 1) { - /* - * 'kva' is not even-page aligned. Adjust it and free the - * first page which is unused. - */ - kmem_free(kernel_map, (vm_offset_t)kva, NBPG); - kva = ((vm_offset_t)kva) + NBPG; - } else { - /* - * 'kva' is even page aligned. We don't need the last page, - * free it. - */ - kmem_free(kernel_map, ((vm_offset_t)kva) + FSPACE, NBPG); - } - - for (i = 0; i < MAXCPU; i++) { - sysmaps = &sysmaps_pcpu[i]; - mtx_init(&sysmaps->lock, "SYSMAPS", NULL, MTX_DEF); - - /* Assign FPAGES pages to the CPU */ - for (j = 0; j < FPAGES; j++) - sysmaps->fp[j].kva = kva + (j) * PAGE_SIZE; - kva = ((vm_offset_t)kva) + (FPAGES * PAGE_SIZE); - } - - /* - * An additional 2 pages are needed, one for pmap_zero_page_idle() - * and one for coredump. These pages are shared by all cpu's - */ - fpages_shared[PMAP_FPAGE3].kva = kva; - fpages_shared[PMAP_FPAGE_KENTER_TEMP].kva = kva + PAGE_SIZE; -} - -/* - * Map the page to the fpage virtual address as specified thru' fpage id - */ -vm_offset_t -pmap_map_fpage(vm_paddr_t pa, struct fpage *fp, boolean_t check_unmaped) -{ - vm_offset_t kva; - register pt_entry_t *pte; - pt_entry_t npte; - - KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); - /* - * Check if the fpage is free - */ - if (fp->state) { - if (check_unmaped == TRUE) - pmap_unmap_fpage(pa, fp); - else - panic("pmap_map_fpage: fpage is busy"); - } - fp->state = TRUE; - kva = fp->kva; - - npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pte = pmap_pte(kernel_pmap, kva); - *pte = npte; - - pmap_TLB_update_kernel(kva, npte); - - return (kva); -} - -/* - * Unmap the page from the fpage virtual address as specified thru' fpage id - */ -void -pmap_unmap_fpage(vm_paddr_t pa, struct fpage *fp) -{ - vm_offset_t kva; - register pt_entry_t *pte; - - KASSERT(curthread->td_pinned > 0, ("curthread not pinned")); - /* - * Check if the fpage is busy - */ - if (!(fp->state)) { - panic("pmap_unmap_fpage: fpage is free"); - } - kva = fp->kva; - - pte = pmap_pte(kernel_pmap, kva); - *pte = PTE_G; - pmap_TLB_invalidate_kernel(kva); - - fp->state = FALSE; - - /* - * Should there be any flush operation at the end? - */ -} - /* Revision 1.507 * * Simplify the reference counting of page table pages. Specifically, use @@ -1051,10 +914,6 @@ pmap_pinit(pmap_t pmap) req = VM_ALLOC_NOOBJ | VM_ALLOC_NORMAL | VM_ALLOC_WIRED | VM_ALLOC_ZERO; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) - req |= VM_ALLOC_WIRED_TLB_PG_POOL; -#endif /* * allocate the page directory page */ @@ -1105,10 +964,6 @@ _pmap_allocpte(pmap_t pmap, unsigned ptepindex, int flags) ("_pmap_allocpte: flags is neither M_NOWAIT nor M_WAITOK")); req = VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_NOOBJ; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) - req |= VM_ALLOC_WIRED_TLB_PG_POOL; -#endif /* * Find or fabricate a new pagetable page */ @@ -1279,7 +1134,7 @@ pmap_growkernel(vm_offset_t addr) mtx_assert(&kernel_map->system_mtx, MA_OWNED); if (kernel_vm_end == 0) { - kernel_vm_end = VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET; + kernel_vm_end = VM_MIN_KERNEL_ADDRESS; nkpt = 0; while (segtab_pde(kernel_segmap, kernel_vm_end)) { kernel_vm_end = (kernel_vm_end + PAGE_SIZE * NPTEPG) & @@ -1308,10 +1163,6 @@ pmap_growkernel(vm_offset_t addr) * This index is bogus, but out of the way */ req = VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED | VM_ALLOC_NOOBJ; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) - req |= VM_ALLOC_WIRED_TLB_PG_POOL; -#endif nkpg = vm_page_alloc(NULL, nkpt, req); if (!nkpg) panic("pmap_growkernel: no memory to grow kernel"); @@ -2155,12 +2006,6 @@ pmap_kenter_temporary(vm_paddr_t pa, int i) printf("%s: ERROR!!! More than one page of virtual address mapping not supported\n", __func__); -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) { - va = pmap_map_fpage(pa, &fpages_shared[PMAP_FPAGE_KENTER_TEMP], - TRUE); - } else -#endif if (pa < MIPS_KSEG0_LARGEST_PHYS) { va = MIPS_PHYS_TO_KSEG0(pa); } else { @@ -2312,26 +2157,7 @@ pmap_zero_page(vm_page_t m) vm_offset_t va; vm_paddr_t phys = VM_PAGE_TO_PHYS(m); int int_level; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) { - struct fpage *fp1; - struct sysmaps *sysmaps; - sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; - mtx_lock(&sysmaps->lock); - sched_pin(); - - fp1 = &sysmaps->fp[PMAP_FPAGE1]; - va = pmap_map_fpage(phys, fp1, FALSE); - bzero((caddr_t)va, PAGE_SIZE); - pmap_unmap_fpage(phys, fp1); - sched_unpin(); - mtx_unlock(&sysmaps->lock); - /* - * Should you do cache flush? - */ - } else -#endif if (phys < MIPS_KSEG0_LARGEST_PHYS) { va = MIPS_PHYS_TO_KSEG0(phys); @@ -2358,7 +2184,6 @@ pmap_zero_page(vm_page_t m) sched_unpin(); PMAP_LGMEM_UNLOCK(sysm); } - } /* @@ -2373,24 +2198,7 @@ pmap_zero_page_area(vm_page_t m, int off, int size) vm_offset_t va; vm_paddr_t phys = VM_PAGE_TO_PHYS(m); int int_level; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) { - struct fpage *fp1; - struct sysmaps *sysmaps; - sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; - mtx_lock(&sysmaps->lock); - sched_pin(); - - fp1 = &sysmaps->fp[PMAP_FPAGE1]; - va = pmap_map_fpage(phys, fp1, FALSE); - bzero((caddr_t)va + off, size); - pmap_unmap_fpage(phys, fp1); - - sched_unpin(); - mtx_unlock(&sysmaps->lock); - } else -#endif if (phys < MIPS_KSEG0_LARGEST_PHYS) { va = MIPS_PHYS_TO_KSEG0(phys); bzero((char *)(caddr_t)va + off, size); @@ -2423,15 +2231,7 @@ pmap_zero_page_idle(vm_page_t m) vm_offset_t va; vm_paddr_t phys = VM_PAGE_TO_PHYS(m); int int_level; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) { - sched_pin(); - va = pmap_map_fpage(phys, &fpages_shared[PMAP_FPAGE3], FALSE); - bzero((caddr_t)va, PAGE_SIZE); - pmap_unmap_fpage(phys, &fpages_shared[PMAP_FPAGE3]); - sched_unpin(); - } else -#endif + if (phys < MIPS_KSEG0_LARGEST_PHYS) { va = MIPS_PHYS_TO_KSEG0(phys); bzero((caddr_t)va, PAGE_SIZE); @@ -2472,95 +2272,67 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) vm_paddr_t phy_src = VM_PAGE_TO_PHYS(src); vm_paddr_t phy_dst = VM_PAGE_TO_PHYS(dst); int int_level; -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - if (need_wired_tlb_page_pool) { - struct fpage *fp1, *fp2; - struct sysmaps *sysmaps; - - sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; - mtx_lock(&sysmaps->lock); - sched_pin(); - - fp1 = &sysmaps->fp[PMAP_FPAGE1]; - fp2 = &sysmaps->fp[PMAP_FPAGE2]; - - va_src = pmap_map_fpage(phy_src, fp1, FALSE); - va_dst = pmap_map_fpage(phy_dst, fp2, FALSE); - - bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); - - pmap_unmap_fpage(phy_src, fp1); - pmap_unmap_fpage(phy_dst, fp2); - sched_unpin(); - mtx_unlock(&sysmaps->lock); + if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) { + /* easy case, all can be accessed via KSEG0 */ /* - * Should you flush the cache? + * Flush all caches for VA that are mapped to this page + * to make sure that data in SDRAM is up to date */ - } else -#endif - { - if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) { - /* easy case, all can be accessed via KSEG0 */ - /* - * Flush all caches for VA that are mapped to this page - * to make sure that data in SDRAM is up to date - */ - pmap_flush_pvcache(src); - mips_dcache_wbinv_range_index( - MIPS_PHYS_TO_KSEG0(phy_dst), NBPG); - va_src = MIPS_PHYS_TO_KSEG0(phy_src); - va_dst = MIPS_PHYS_TO_KSEG0(phy_dst); - bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); - mips_dcache_wbinv_range(va_dst, PAGE_SIZE); - } else { - int cpu; - struct local_sysmaps *sysm; + pmap_flush_pvcache(src); + mips_dcache_wbinv_range_index( + MIPS_PHYS_TO_KSEG0(phy_dst), NBPG); + va_src = MIPS_PHYS_TO_KSEG0(phy_src); + va_dst = MIPS_PHYS_TO_KSEG0(phy_dst); + bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); + mips_dcache_wbinv_range(va_dst, PAGE_SIZE); + } else { + int cpu; + struct local_sysmaps *sysm; - cpu = PCPU_GET(cpuid); - sysm = &sysmap_lmem[cpu]; - PMAP_LGMEM_LOCK(sysm); - sched_pin(); - int_level = disableintr(); - if (phy_src < MIPS_KSEG0_LARGEST_PHYS) { - /* one side needs mapping - dest */ - va_src = MIPS_PHYS_TO_KSEG0(phy_src); - sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2); - sysm->valid2 = 1; - va_dst = (vm_offset_t)sysm->CADDR2; - } else if (phy_dst < MIPS_KSEG0_LARGEST_PHYS) { - /* one side needs mapping - src */ - va_dst = MIPS_PHYS_TO_KSEG0(phy_dst); - sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - va_src = (vm_offset_t)sysm->CADDR1; - sysm->valid1 = 1; - } else { - /* all need mapping */ - sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2); - sysm->valid1 = sysm->valid2 = 1; - va_src = (vm_offset_t)sysm->CADDR1; - va_dst = (vm_offset_t)sysm->CADDR2; - } - bcopy((void *)va_src, (void *)va_dst, PAGE_SIZE); - if (sysm->valid1) { - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); - sysm->CMAP1 = 0; - sysm->valid1 = 0; - } - if (sysm->valid2) { - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR2); - sysm->CMAP2 = 0; - sysm->valid2 = 0; - } - restoreintr(int_level); - sched_unpin(); - PMAP_LGMEM_UNLOCK(sysm); + cpu = PCPU_GET(cpuid); + sysm = &sysmap_lmem[cpu]; + PMAP_LGMEM_LOCK(sysm); + sched_pin(); + int_level = disableintr(); + if (phy_src < MIPS_KSEG0_LARGEST_PHYS) { + /* one side needs mapping - dest */ + va_src = MIPS_PHYS_TO_KSEG0(phy_src); + sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; + pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2); + sysm->valid2 = 1; + va_dst = (vm_offset_t)sysm->CADDR2; + } else if (phy_dst < MIPS_KSEG0_LARGEST_PHYS) { + /* one side needs mapping - src */ + va_dst = MIPS_PHYS_TO_KSEG0(phy_dst); + sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; + pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); + va_src = (vm_offset_t)sysm->CADDR1; + sysm->valid1 = 1; + } else { + /* all need mapping */ + sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; + sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; + pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); + pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2); + sysm->valid1 = sysm->valid2 = 1; + va_src = (vm_offset_t)sysm->CADDR1; + va_dst = (vm_offset_t)sysm->CADDR2; } + bcopy((void *)va_src, (void *)va_dst, PAGE_SIZE); + if (sysm->valid1) { + pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); + sysm->CMAP1 = 0; + sysm->valid1 = 0; + } + if (sysm->valid2) { + pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR2); + sysm->CMAP2 = 0; + sysm->valid2 = 0; + } + restoreintr(int_level); + sched_unpin(); + PMAP_LGMEM_UNLOCK(sysm); } } @@ -3308,11 +3080,6 @@ pmap_kextract(vm_offset_t va) else if (va >= MIPS_KSEG1_START && va < MIPS_KSEG2_START) pa = MIPS_KSEG1_TO_PHYS(va); -#ifdef VM_ALLOC_WIRED_TLB_PG_POOL - else if (need_wired_tlb_page_pool && ((va >= VM_MIN_KERNEL_ADDRESS) && - (va < (VM_MIN_KERNEL_ADDRESS + VM_KERNEL_ALLOC_OFFSET)))) - pa = MIPS_KSEG0_TO_PHYS(va); -#endif else if (va >= MIPS_KSEG2_START && va < VM_MAX_KERNEL_ADDRESS) { pt_entry_t *ptep; diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index dd66ecec684..4fc3cbd6cb9 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -340,7 +340,7 @@ blocked_loop: lw a2, TD_PCB(a1) sw a2, PC_CURPCB(a3) lw v0, TD_REALKSTACK(a1) - li s0, (MIPS_KSEG2_START+VM_KERNEL_ALLOC_OFFSET) # If Uarea addr is below kseg2, + li s0, MIPS_KSEG2_START # If Uarea addr is below kseg2, bltu v0, s0, sw2 # no need to insert in TLB. lw a1, TD_UPTE+0(s7) # t0 = first u. pte lw a2, TD_UPTE+4(s7) # t1 = 2nd u. pte From b92f01b79c1c926a46299ca5f4c85574acc7da3e Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 17 Apr 2010 01:17:31 +0000 Subject: [PATCH 098/532] o) Use inline functions to access coprocessor 0 registers rather than external ones implemented using assembly. o) Use TRAPF_USERMODE() consistently rather than USERMODE(). Eliminate as a result. o) Use intr_*() rather than *intr(), consistently. o) Use register_t instead of u_int in some trap code. o) Merge some more endian-related macros to machine/asm.h from NetBSD. o) Add PTR_LI macro, which loads an address with the correct sign-extension for a pointer. o) Restore interrupts when bailing out due to an excessive IRQ in nexus_setup_intr(). o) Remove unused functions from psraccess.S. o) Enter temporary virtual entries for large memory access into the page tables rather than simply hoping they stay resident in the TLB and we don't need to do a refill for them. o) Abstract out large memory mapping setup/teardown using some macros. o) Do mips_dcache_wbinv_range() when using temporary virtual addresses just like we do when we can use the direct map. --- ObsoleteFiles.inc | 4 + sys/mips/include/asm.h | 84 +++++++---- sys/mips/include/cpu.h | 21 +-- sys/mips/include/db_machdep.h | 1 - sys/mips/include/param.h | 4 +- sys/mips/include/profile.h | 8 +- sys/mips/include/psl.h | 50 ------- sys/mips/include/trap.h | 20 +-- sys/mips/mips/machdep.c | 20 +-- sys/mips/mips/mp_machdep.c | 2 +- sys/mips/mips/nexus.c | 9 +- sys/mips/mips/pmap.c | 254 ++++++++++++++-------------------- sys/mips/mips/psraccess.S | 117 ---------------- sys/mips/mips/tick.c | 8 +- sys/mips/mips/trap.c | 17 ++- sys/mips/rmi/clock.c | 12 +- 16 files changed, 214 insertions(+), 417 deletions(-) delete mode 100644 sys/mips/include/psl.h diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 0844d714693..2d4624dc984 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,10 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20100416: [mips] removed +.if ${TARGET_ARCH} == "mips" +OLD_FILES+=usr/include/machine/psl.h +.endif # 20100415: [mips] removed unused headers .if ${TARGET_ARCH} == "mips" OLD_FILES+=usr/include/machine/archtype.h diff --git a/sys/mips/include/asm.h b/sys/mips/include/asm.h index 0a9c518e929..23bfde148d6 100644 --- a/sys/mips/include/asm.h +++ b/sys/mips/include/asm.h @@ -98,23 +98,6 @@ #define _C_LABEL(x) x -/* - * Endian-independent assembly-code aliases for unaligned memory accesses. - */ -#if BYTE_ORDER == LITTLE_ENDIAN -#define LWLO lwl -#define LWHI lwr -#define SWLO swl -#define SWHI swr -#endif - -#if BYTE_ORDER == BIG_ENDIAN -#define LWLO lwr -#define LWHI lwl -#define SWLO swr -#define SWHI swl -#endif - #ifdef USE_AENT #define AENT(x) \ .aent x, 0 @@ -306,28 +289,32 @@ _C_LABEL(x): /* * Call ast if required + * + * XXX Do we really need to disable interrupts? */ #define DO_AST \ 44: \ - PTR_LA s0, _C_LABEL(disableintr) ;\ - jalr s0 ;\ - nop ;\ - move a0, v0 ;\ + mfc0 t0, MIPS_COP_0_STATUS ;\ + and a0, t0, MIPS_SR_INT_IE ;\ + xor t0, a0, t0 ;\ + mtc0 t0, MIPS_COP_0_STATUS ;\ + COP0_SYNC ;\ GET_CPU_PCPU(s1) ;\ - lw s3, PC_CURPCB(s1) ;\ - lw s1, PC_CURTHREAD(s1) ;\ + PTR_L s3, PC_CURPCB(s1) ;\ + PTR_L s1, PC_CURTHREAD(s1) ;\ lw s2, TD_FLAGS(s1) ;\ li s0, TDF_ASTPENDING | TDF_NEEDRESCHED;\ and s2, s0 ;\ - PTR_LA s0, _C_LABEL(restoreintr) ;\ - jalr s0 ;\ - nop ;\ + mfc0 t0, MIPS_COP_0_STATUS ;\ + or t0, a0, t0 ;\ + mtc0 t0, MIPS_COP_0_STATUS ;\ + COP0_SYNC ;\ beq s2, zero, 4f ;\ nop ;\ PTR_LA s0, _C_LABEL(ast) ;\ jalr s0 ;\ PTR_ADDU a0, s3, U_PCB_REGS ;\ - j 44b ;\ + j 44b ;\ nop ;\ 4: @@ -382,6 +369,45 @@ _C_LABEL(x): #define CALLFRAME_SP (CALLFRAME_SIZ - 2 * SZREG) #define CALLFRAME_RA (CALLFRAME_SIZ - 1 * SZREG) +/* + * Endian-independent assembly-code aliases for unaligned memory accesses. + */ +#if _BYTE_ORDER == _LITTLE_ENDIAN +# define LWHI lwr +# define LWLO lwl +# define SWHI swr +# define SWLO swl +# if SZREG == 4 +# define REG_LHI lwr +# define REG_LLO lwl +# define REG_SHI swr +# define REG_SLO swl +# else +# define REG_LHI ldr +# define REG_LLO ldl +# define REG_SHI sdr +# define REG_SLO sdl +# endif +#endif + +#if _BYTE_ORDER == _BIG_ENDIAN +# define LWHI lwl +# define LWLO lwr +# define SWHI swl +# define SWLO swr +# if SZREG == 4 +# define REG_LHI lwl +# define REG_LLO lwr +# define REG_SHI swl +# define REG_SLO swr +# else +# define REG_LHI ldl +# define REG_LLO ldr +# define REG_SHI sdl +# define REG_SLO sdr +# endif +#endif + /* * While it would be nice to be compatible with the SGI * REG_L and REG_S macros, because they do not take parameters, it @@ -402,6 +428,7 @@ _C_LABEL(x): #define PTR_SUBIU subu #define PTR_L lw #define PTR_LA la +#define PTR_LI li #define PTR_S sw #define PTR_SLL sll #define PTR_SLLV sllv @@ -424,6 +451,7 @@ _C_LABEL(x): #define PTR_SUBIU dsubu #define PTR_L ld #define PTR_LA dla +#define PTR_LI dli #define PTR_S sd #define PTR_SLL dsll #define PTR_SLLV dsllv @@ -765,7 +793,7 @@ _C_LABEL(x): #endif #define GET_CPU_PCPU(reg) \ - lw reg, _C_LABEL(pcpup); + PTR_L reg, _C_LABEL(pcpup); /* * Description of the setjmp buffer diff --git a/sys/mips/include/cpu.h b/sys/mips/include/cpu.h index 1ec1cfc8a86..5c5e5e5e92b 100644 --- a/sys/mips/include/cpu.h +++ b/sys/mips/include/cpu.h @@ -47,7 +47,6 @@ #ifndef _MACHINE_CPU_H_ #define _MACHINE_CPU_H_ -#include #include #define MIPS_KSEG0_LARGEST_PHYS 0x20000000 @@ -334,6 +333,7 @@ #define cpu_swapout(p) panic("cpu_swapout: can't get here"); #ifndef _LOCORE +#include #include /* * Arguments to hardclock and gatherstats encapsulate the previous @@ -342,7 +342,6 @@ #define clockframe trapframe /* Use normal trap frame */ #define CLKF_USERMODE(framep) ((framep)->sr & SR_KSU_USER) -#define CLKF_BASEPRI(framep) ((framep)->cpl == 0) #define CLKF_PC(framep) ((framep)->pc) #define CLKF_INTR(framep) (0) #define MIPS_CLKF_INTR() (intr_nesting_level >= 1) @@ -350,6 +349,11 @@ #define TRAPF_PC(framep) ((framep)->pc) #define cpu_getstack(td) ((td)->td_frame->sp) +/* + * A machine-independent interface to the CPU's counter. + */ +#define get_cyclecount() mips_rd_count() + /* * CPU identification, from PRID register. */ @@ -542,18 +546,6 @@ extern int intr_nesting_level; * Low level access routines to CPU registers */ -void setsoftintr0(void); -void clearsoftintr0(void); -void setsoftintr1(void); -void clearsoftintr1(void); - - -u_int32_t mips_cp0_status_read(void); -void mips_cp0_status_write(u_int32_t); - -int disableintr(void); -void restoreintr(int); -int enableintr(void); int Mips_TLBGetPID(void); void swi_vm(void *); @@ -562,7 +554,6 @@ void cpu_reset(void); u_int32_t set_intr_mask(u_int32_t); u_int32_t get_intr_mask(void); -u_int32_t get_cyclecount(void); #define cpu_spinwait() /* nothing */ diff --git a/sys/mips/include/db_machdep.h b/sys/mips/include/db_machdep.h index d7bf69a427d..f0a84d2ee9a 100644 --- a/sys/mips/include/db_machdep.h +++ b/sys/mips/include/db_machdep.h @@ -38,7 +38,6 @@ #define _MIPS_DB_MACHDEP_H_ #include -#include #include #include diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index 9d487022439..0f380852609 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -46,9 +46,7 @@ #include #ifdef _KERNEL -#ifdef _LOCORE -#include -#else +#ifndef _LOCORE #include #endif #endif diff --git a/sys/mips/include/profile.h b/sys/mips/include/profile.h index 728a468dbf4..6d976d90e77 100644 --- a/sys/mips/include/profile.h +++ b/sys/mips/include/profile.h @@ -84,17 +84,17 @@ #ifdef SMP extern int mcount_lock; #define MCOUNT_ENTER(s) { \ - s = disable_intr(); \ + s = intr_disable(); \ while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1)) \ /* nothing */ ; \ } #define MCOUNT_EXIT(s) { \ atomic_store_rel_int(&mcount_lock, 0); \ - enableintr(s); \ + intr_restore(s); \ } #else -#define MCOUNT_ENTER(s) { s = disable_intr(); } -#define MCOUNT_EXIT(s) (enableintr(s)) +#define MCOUNT_ENTER(s) { s = intr_disable(); } +#define MCOUNT_EXIT(s) (intr_restore(s)) #endif /* REVISIT for mips */ diff --git a/sys/mips/include/psl.h b/sys/mips/include/psl.h deleted file mode 100644 index f02a1a95fa9..00000000000 --- a/sys/mips/include/psl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $OpenBSD: psl.h,v 1.2 1998/01/28 13:46:25 pefo Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Ralph Campbell. - * - * 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. - * - * from: @(#)psl.h 8.1 (Berkeley) 6/10/93 - * JNPR: psl.h,v 1.1 2006/08/07 05:38:57 katta - * $FreeBSD$ - */ - -#ifndef _MACHINE_PSL_H_ -#define _MACHINE_PSL_H_ - -#include - -/* - * Macros to decode processor status word. - */ -#define USERMODE(ps) (((ps) & SR_KSU_MASK) == SR_KSU_USER) -#define BASEPRI(ps) (((ps) & (INT_MASK | SR_INT_ENA_PREV)) \ - == (INT_MASK | SR_INT_ENA_PREV)) -#endif /* _MACHINE_PSL_H_ */ diff --git a/sys/mips/include/trap.h b/sys/mips/include/trap.h index f382e70f488..d8042382157 100644 --- a/sys/mips/include/trap.h +++ b/sys/mips/include/trap.h @@ -74,17 +74,17 @@ #if !defined(SMP) && (defined(DDB) || defined(DEBUG)) struct trapdebug { /* trap history buffer for debugging */ - u_int status; - u_int cause; - u_int vadr; - u_int pc; - u_int ra; - u_int sp; - u_int code; + register_t status; + register_t cause; + register_t vadr; + register_t pc; + register_t ra; + register_t sp; + register_t code; }; #define trapdebug_enter(x, cd) { \ - intrmask_t s = disableintr(); \ + register_t s = intr_disable(); \ trp->status = x->sr; \ trp->cause = x->cause; \ trp->vadr = x->badvaddr; \ @@ -94,7 +94,7 @@ struct trapdebug { /* trap history buffer for debugging */ trp->code = cd; \ if (++trp == &trapdebug[TRAPSIZE]) \ trp = trapdebug; \ - restoreintr(s); \ + intr_restore(s); \ } #define TRAPSIZE 10 /* Trap log buffer length */ @@ -116,7 +116,7 @@ void MipsTLBMissException(void); void MipsUserGenException(void); void MipsUserIntr(void); -u_int trap(struct trapframe *); +register_t trap(struct trapframe *); #ifndef LOCORE /* XXX */ int check_address(void *); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 4f728d56c05..6ca4ec9409a 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -370,11 +370,10 @@ mips_vector_init(void) * when handler is installed for it */ set_intr_mask(ALL_INT_MASK); - enableintr(); + intr_enable(); /* Clear BEV in SR so we start handling our own exceptions */ - mips_cp0_status_write(mips_cp0_status_read() & ~SR_BOOT_EXC_VEC); - + mips_wr_status(mips_rd_status() & ~SR_BOOT_EXC_VEC); } /* @@ -471,7 +470,7 @@ spinlock_enter(void) td = curthread; if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_intr = disableintr(); + td->td_md.md_saved_intr = intr_disable(); td->td_md.md_spinlock_count++; critical_enter(); } @@ -485,16 +484,7 @@ spinlock_exit(void) critical_exit(); td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - restoreintr(td->td_md.md_saved_intr); -} - -u_int32_t -get_cyclecount(void) -{ - u_int32_t count; - - mfc0_macro(count, 9); - return (count); + intr_restore(td->td_md.md_saved_intr); } /* @@ -503,7 +493,7 @@ get_cyclecount(void) void cpu_idle(int busy) { - if (mips_cp0_status_read() & SR_INT_ENAB) + if (mips_rd_status() & SR_INT_ENAB) __asm __volatile ("wait"); else panic("ints disabled in idleproc!"); diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c index f65db9bd6b4..52d05fad711 100644 --- a/sys/mips/mips/mp_machdep.c +++ b/sys/mips/mips/mp_machdep.c @@ -296,7 +296,7 @@ smp_init_secondary(u_int32_t cpuid) */ mips_wr_compare(mips_rd_count() + counter_freq / hz); - enableintr(); + intr_enable(); /* enter the scheduler */ sched_throw(NULL); diff --git a/sys/mips/mips/nexus.c b/sys/mips/mips/nexus.c index 6600980bb02..10b38b5ff86 100644 --- a/sys/mips/mips/nexus.c +++ b/sys/mips/mips/nexus.c @@ -166,16 +166,19 @@ static int nexus_setup_intr(device_t dev, device_t child, struct resource *res, int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, void **cookiep) { + register_t s; int irq; - intrmask_t s = disableintr(); + s = intr_disable(); irq = rman_get_start(res); - if (irq >= NUM_MIPS_IRQS) + if (irq >= NUM_MIPS_IRQS) { + intr_restore(s); return (0); + } cpu_establish_hardintr(device_get_nameunit(child), filt, intr, arg, irq, flags, cookiep); - restoreintr(s); + intr_restore(s); return (0); } diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 9f01f8a88c4..f1056fdcb46 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -194,10 +194,7 @@ static void pmap_update_page_action(void *arg); struct local_sysmaps { struct mtx lock; - pt_entry_t CMAP1; - pt_entry_t CMAP2; - caddr_t CADDR1; - caddr_t CADDR2; + vm_offset_t base; uint16_t valid1, valid2; }; @@ -211,6 +208,59 @@ struct local_sysmaps { static struct local_sysmaps sysmap_lmem[MAXCPU]; caddr_t virtual_sys_start = (caddr_t)0; +#define PMAP_LMEM_MAP1(va, phys) \ + int cpu; \ + struct local_sysmaps *sysm; \ + pt_entry_t *pte, npte; \ + \ + cpu = PCPU_GET(cpuid); \ + sysm = &sysmap_lmem[cpu]; \ + PMAP_LGMEM_LOCK(sysm); \ + intr = intr_disable(); \ + sched_pin(); \ + va = sysm->base; \ + npte = mips_paddr_to_tlbpfn(phys) | \ + PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; \ + pte = pmap_pte(kernel_pmap, va); \ + *pte = npte; \ + sysm->valid1 = 1; + +#define PMAP_LMEM_MAP2(va1, phys1, va2, phys2) \ + int cpu; \ + struct local_sysmaps *sysm; \ + pt_entry_t *pte, npte; \ + \ + cpu = PCPU_GET(cpuid); \ + sysm = &sysmap_lmem[cpu]; \ + PMAP_LGMEM_LOCK(sysm); \ + intr = intr_disable(); \ + sched_pin(); \ + va1 = sysm->base; \ + va2 = sysm->base + PAGE_SIZE; \ + npte = mips_paddr_to_tlbpfn(phys2) | \ + PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; \ + pte = pmap_pte(kernel_pmap, va1); \ + *pte = npte; \ + npte = mips_paddr_to_tlbpfn(phys2) | \ + PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; \ + pte = pmap_pte(kernel_pmap, va2); \ + *pte = npte; \ + sysm->valid1 = 1; \ + sysm->valid2 = 1; + +#define PMAP_LMEM_UNMAP() \ + pte = pmap_pte(kernel_pmap, sysm->base); \ + *pte = PTE_G; \ + pmap_invalidate_page(kernel_pmap, sysm->base); \ + sysm->valid1 = 0; \ + pte = pmap_pte(kernel_pmap, sysm->base + PAGE_SIZE); \ + *pte = PTE_G; \ + pmap_invalidate_page(kernel_pmap, sysm->base + PAGE_SIZE); \ + sysm->valid2 = 0; \ + sched_unpin(); \ + intr_restore(intr); \ + PMAP_LGMEM_UNLOCK(sysm); + pd_entry_t pmap_segmap(pmap_t pmap, vm_offset_t va) { @@ -382,12 +432,8 @@ again: */ if (memory_larger_than_512meg) { for (i = 0; i < MAXCPU; i++) { - sysmap_lmem[i].CMAP1 = PTE_G; - sysmap_lmem[i].CMAP2 = PTE_G; - sysmap_lmem[i].CADDR1 = (caddr_t)virtual_avail; - virtual_avail += PAGE_SIZE; - sysmap_lmem[i].CADDR2 = (caddr_t)virtual_avail; - virtual_avail += PAGE_SIZE; + sysmap_lmem[i].base = virtual_avail; + virtual_avail += PAGE_SIZE * 2; sysmap_lmem[i].valid1 = sysmap_lmem[i].valid2 = 0; PMAP_LGMEM_LOCK_INIT(&sysmap_lmem[i]); } @@ -2001,7 +2047,7 @@ void * pmap_kenter_temporary(vm_paddr_t pa, int i) { vm_offset_t va; - int int_level; + register_t intr; if (i != 0) printf("%s: ERROR!!! More than one page of virtual address mapping not supported\n", __func__); @@ -2011,20 +2057,24 @@ pmap_kenter_temporary(vm_paddr_t pa, int i) } else { int cpu; struct local_sysmaps *sysm; + pt_entry_t *pte, npte; + /* If this is used other than for dumps, we may need to leave * interrupts disasbled on return. If crash dumps don't work when * we get to this point, we might want to consider this (leaving things * disabled as a starting point ;-) */ - int_level = disableintr(); + intr = intr_disable(); cpu = PCPU_GET(cpuid); sysm = &sysmap_lmem[cpu]; /* Since this is for the debugger, no locks or any other fun */ - sysm->CMAP1 = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; + npte = mips_paddr_to_tlbpfn(pa) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; + pte = pmap_pte(kernel_pmap, sysm->base); + *pte = npte; sysm->valid1 = 1; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - va = (vm_offset_t)sysm->CADDR1; - restoreintr(int_level); + pmap_update_page(kernel_pmap, sysm->base, npte); + va = sysm->base; + intr_restore(intr); } return ((void *)va); } @@ -2033,7 +2083,7 @@ void pmap_kenter_temporary_free(vm_paddr_t pa) { int cpu; - int int_level; + register_t intr; struct local_sysmaps *sysm; if (pa < MIPS_KSEG0_LARGEST_PHYS) { @@ -2043,10 +2093,13 @@ pmap_kenter_temporary_free(vm_paddr_t pa) cpu = PCPU_GET(cpuid); sysm = &sysmap_lmem[cpu]; if (sysm->valid1) { - int_level = disableintr(); - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); - restoreintr(int_level); - sysm->CMAP1 = 0; + pt_entry_t *pte; + + intr = intr_disable(); + pte = pmap_pte(kernel_pmap, sysm->base); + *pte = PTE_G; + pmap_invalidate_page(kernel_pmap, sysm->base); + intr_restore(intr); sysm->valid1 = 0; } } @@ -2156,33 +2209,20 @@ pmap_zero_page(vm_page_t m) { vm_offset_t va; vm_paddr_t phys = VM_PAGE_TO_PHYS(m); - int int_level; + register_t intr; if (phys < MIPS_KSEG0_LARGEST_PHYS) { - va = MIPS_PHYS_TO_KSEG0(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); } else { - int cpu; - struct local_sysmaps *sysm; + PMAP_LMEM_MAP1(va, phys); - cpu = PCPU_GET(cpuid); - sysm = &sysmap_lmem[cpu]; - PMAP_LGMEM_LOCK(sysm); - sched_pin(); - int_level = disableintr(); - sysm->CMAP1 = mips_paddr_to_tlbpfn(phys) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - sysm->valid1 = 1; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - bzero(sysm->CADDR1, PAGE_SIZE); - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); - restoreintr(int_level); - sysm->CMAP1 = 0; - sysm->valid1 = 0; - sched_unpin(); - PMAP_LGMEM_UNLOCK(sysm); + bzero((caddr_t)va, PAGE_SIZE); + mips_dcache_wbinv_range(va, PAGE_SIZE); + + PMAP_LMEM_UNMAP(); } } @@ -2197,31 +2237,19 @@ pmap_zero_page_area(vm_page_t m, int off, int size) { vm_offset_t va; vm_paddr_t phys = VM_PAGE_TO_PHYS(m); - int int_level; + register_t intr; if (phys < MIPS_KSEG0_LARGEST_PHYS) { va = MIPS_PHYS_TO_KSEG0(phys); bzero((char *)(caddr_t)va + off, size); mips_dcache_wbinv_range(va + off, size); } else { - int cpu; - struct local_sysmaps *sysm; + PMAP_LMEM_MAP1(va, phys); - cpu = PCPU_GET(cpuid); - sysm = &sysmap_lmem[cpu]; - PMAP_LGMEM_LOCK(sysm); - int_level = disableintr(); - sched_pin(); - sysm->CMAP1 = mips_paddr_to_tlbpfn(phys) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - sysm->valid1 = 1; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - bzero((char *)sysm->CADDR1 + off, size); - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); - restoreintr(int_level); - sysm->CMAP1 = 0; - sysm->valid1 = 0; - sched_unpin(); - PMAP_LGMEM_UNLOCK(sysm); + bzero((char *)va + off, size); + mips_dcache_wbinv_range(va + off, size); + + PMAP_LMEM_UNMAP(); } } @@ -2230,33 +2258,20 @@ pmap_zero_page_idle(vm_page_t m) { vm_offset_t va; vm_paddr_t phys = VM_PAGE_TO_PHYS(m); - int int_level; + register_t intr; if (phys < MIPS_KSEG0_LARGEST_PHYS) { va = MIPS_PHYS_TO_KSEG0(phys); bzero((caddr_t)va, PAGE_SIZE); mips_dcache_wbinv_range(va, PAGE_SIZE); } else { - int cpu; - struct local_sysmaps *sysm; + PMAP_LMEM_MAP1(va, phys); - cpu = PCPU_GET(cpuid); - sysm = &sysmap_lmem[cpu]; - PMAP_LGMEM_LOCK(sysm); - int_level = disableintr(); - sched_pin(); - sysm->CMAP1 = mips_paddr_to_tlbpfn(phys) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - sysm->valid1 = 1; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - bzero(sysm->CADDR1, PAGE_SIZE); - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); - restoreintr(int_level); - sysm->CMAP1 = 0; - sysm->valid1 = 0; - sched_unpin(); - PMAP_LGMEM_UNLOCK(sysm); + bzero((caddr_t)va, PAGE_SIZE); + mips_dcache_wbinv_range(va, PAGE_SIZE); + + PMAP_LMEM_UNMAP(); } - } /* @@ -2271,7 +2286,7 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) vm_offset_t va_src, va_dst; vm_paddr_t phy_src = VM_PAGE_TO_PHYS(src); vm_paddr_t phy_dst = VM_PAGE_TO_PHYS(dst); - int int_level; + register_t intr; if ((phy_src < MIPS_KSEG0_LARGEST_PHYS) && (phy_dst < MIPS_KSEG0_LARGEST_PHYS)) { /* easy case, all can be accessed via KSEG0 */ @@ -2281,58 +2296,18 @@ pmap_copy_page(vm_page_t src, vm_page_t dst) */ pmap_flush_pvcache(src); mips_dcache_wbinv_range_index( - MIPS_PHYS_TO_KSEG0(phy_dst), NBPG); + MIPS_PHYS_TO_KSEG0(phy_dst), PAGE_SIZE); va_src = MIPS_PHYS_TO_KSEG0(phy_src); va_dst = MIPS_PHYS_TO_KSEG0(phy_dst); bcopy((caddr_t)va_src, (caddr_t)va_dst, PAGE_SIZE); mips_dcache_wbinv_range(va_dst, PAGE_SIZE); } else { - int cpu; - struct local_sysmaps *sysm; + PMAP_LMEM_MAP2(va_src, phy_src, va_dst, phy_dst); - cpu = PCPU_GET(cpuid); - sysm = &sysmap_lmem[cpu]; - PMAP_LGMEM_LOCK(sysm); - sched_pin(); - int_level = disableintr(); - if (phy_src < MIPS_KSEG0_LARGEST_PHYS) { - /* one side needs mapping - dest */ - va_src = MIPS_PHYS_TO_KSEG0(phy_src); - sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2); - sysm->valid2 = 1; - va_dst = (vm_offset_t)sysm->CADDR2; - } else if (phy_dst < MIPS_KSEG0_LARGEST_PHYS) { - /* one side needs mapping - src */ - va_dst = MIPS_PHYS_TO_KSEG0(phy_dst); - sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - va_src = (vm_offset_t)sysm->CADDR1; - sysm->valid1 = 1; - } else { - /* all need mapping */ - sysm->CMAP1 = mips_paddr_to_tlbpfn(phy_src) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - sysm->CMAP2 = mips_paddr_to_tlbpfn(phy_dst) | PTE_RW | PTE_V | PTE_G | PTE_W | PTE_CACHE; - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR1, sysm->CMAP1); - pmap_TLB_update_kernel((vm_offset_t)sysm->CADDR2, sysm->CMAP2); - sysm->valid1 = sysm->valid2 = 1; - va_src = (vm_offset_t)sysm->CADDR1; - va_dst = (vm_offset_t)sysm->CADDR2; - } bcopy((void *)va_src, (void *)va_dst, PAGE_SIZE); - if (sysm->valid1) { - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR1); - sysm->CMAP1 = 0; - sysm->valid1 = 0; - } - if (sysm->valid2) { - pmap_TLB_invalidate_kernel((vm_offset_t)sysm->CADDR2); - sysm->CMAP2 = 0; - sysm->valid2 = 0; - } - restoreintr(int_level); - sched_unpin(); - PMAP_LGMEM_UNLOCK(sysm); + mips_dcache_wbinv_range(va_dst, PAGE_SIZE); + + PMAP_LMEM_UNMAP(); } } @@ -3085,34 +3060,11 @@ pmap_kextract(vm_offset_t va) /* Is the kernel pmap initialized? */ if (kernel_pmap->pm_active) { - if (va >= (vm_offset_t)virtual_sys_start) { - /* Its inside the virtual address range */ - ptep = pmap_pte(kernel_pmap, va); - if (ptep) - pa = mips_tlbpfn_to_paddr(*ptep) | - (va & PAGE_MASK); - } else { - int i; - - /* - * its inside the special mapping area, I - * don't think this should happen, but if it - * does I want it toa all work right :-) - * Note if it does happen, we assume the - * caller has the lock? FIXME, this needs to - * be checked FIXEM - RRS. - */ - for (i = 0; i < MAXCPU; i++) { - if ((sysmap_lmem[i].valid1) && ((vm_offset_t)sysmap_lmem[i].CADDR1 == va)) { - pa = mips_tlbpfn_to_paddr(sysmap_lmem[i].CMAP1); - break; - } - if ((sysmap_lmem[i].valid2) && ((vm_offset_t)sysmap_lmem[i].CADDR2 == va)) { - pa = mips_tlbpfn_to_paddr(sysmap_lmem[i].CMAP2); - break; - } - } - } + /* Its inside the virtual address range */ + ptep = pmap_pte(kernel_pmap, va); + if (ptep) + pa = mips_tlbpfn_to_paddr(*ptep) | + (va & PAGE_MASK); } } return pa; diff --git a/sys/mips/mips/psraccess.S b/sys/mips/mips/psraccess.S index 0bcb04d3d33..9b40a234458 100644 --- a/sys/mips/mips/psraccess.S +++ b/sys/mips/mips/psraccess.S @@ -53,109 +53,6 @@ .set noreorder # Noreorder is default style! -/* - * Set/clear software interrupt. - */ - -LEAF(setsoftintr0) - mfc0 v0, COP_0_CAUSE_REG # read cause register - nop - or v0, v0, SOFT_INT_MASK_0 # set soft clock interrupt - mtc0 v0, COP_0_CAUSE_REG # save it - j ra - nop -END(setsoftintr0) - -LEAF(clearsoftintr0) - mfc0 v0, COP_0_CAUSE_REG # read cause register - nop - and v0, v0, ~SOFT_INT_MASK_0 # clear soft clock interrupt - mtc0 v0, COP_0_CAUSE_REG # save it - j ra - nop -END(clearsoftintr0) - -LEAF(setsoftintr1) - mfc0 v0, COP_0_CAUSE_REG # read cause register - nop - or v0, v0, SOFT_INT_MASK_1 # set soft net interrupt - mtc0 v0, COP_0_CAUSE_REG # save it - j ra - nop -END(setsoftintr1) - -LEAF(clearsoftintr1) - mfc0 v0, COP_0_CAUSE_REG # read cause register - nop - and v0, v0, ~SOFT_INT_MASK_1 # clear soft net interrupt - mtc0 v0, COP_0_CAUSE_REG # save it - j ra - nop -END(clearsoftintr1) - -/* - * Set/change interrupt priority routines. - * These routines return the previous state. - */ -LEAF(restoreintr) - mfc0 t0,COP_0_STATUS_REG - and t1,t0,SR_INT_ENAB - beq a0,t1,1f - xor t0,SR_INT_ENAB - - .set noreorder - - mtc0 t0,COP_0_STATUS_REG - nop - nop - nop - nop -1: - j ra - nop -END(restoreintr) - -/* - * Set/change interrupt priority routines. - * These routines return the previous state. - */ - -LEAF(enableintr) -#ifdef TARGET_OCTEON - .set mips64r2 - ei v0 - and v0, SR_INT_ENAB # return old interrupt enable bit - .set mips0 -#else - mfc0 v0, COP_0_STATUS_REG # read status register - nop - or v1, v0, SR_INT_ENAB - mtc0 v1, COP_0_STATUS_REG # enable all interrupts - and v0, SR_INT_ENAB # return old interrupt enable -#endif - j ra - nop -END(enableintr) - - -LEAF(disableintr) -#ifdef TARGET_OCTEON - .set mips64r2 - di v0 - and v0, SR_INT_ENAB # return old interrupt enable bit - .set mips0 -#else - mfc0 v0, COP_0_STATUS_REG # read status register - nop - and v1, v0, ~SR_INT_ENAB - mtc0 v1, COP_0_STATUS_REG # disable all interrupts - MIPS_CPU_NOP_DELAY - and v0, SR_INT_ENAB # return old interrupt enable -#endif - j ra - nop -END(disableintr) - LEAF(set_intr_mask) li t0, SR_INT_MASK # 1 means masked so invert. not a0, a0 # 1 means masked so invert. @@ -182,17 +79,3 @@ LEAF(get_intr_mask) nop END(get_intr_mask) - -/* - * u_int32_t mips_cp0_config1_read(void) - * - * Return the current value of the CP0 Config (Select 1) register. - */ -LEAF(mips_cp0_config1_read) - .set push - .set mips32 - mfc0 v0, COP_0_CONFIG, 1 - j ra - nop - .set pop -END(mips_cp0_config1_read) diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c index 60b3511e0c0..d2678b1f637 100644 --- a/sys/mips/mips/tick.c +++ b/sys/mips/mips/tick.c @@ -301,16 +301,16 @@ clock_intr(void *arg) if (cpu_ticks->hard_ticks >= cycles_per_hz) { cpu_ticks->hard_ticks -= cycles_per_hz; if (PCPU_GET(cpuid) == 0) - hardclock(USERMODE(tf->sr), tf->pc); + hardclock(TRAPF_USERMODE(tf), tf->pc); else - hardclock_cpu(USERMODE(tf->sr)); + hardclock_cpu(TRAPF_USERMODE(tf)); } /* Fire statclock at stathz. */ cpu_ticks->stat_ticks += delta; if (cpu_ticks->stat_ticks >= cycles_per_stathz) { cpu_ticks->stat_ticks -= cycles_per_stathz; - statclock(USERMODE(tf->sr)); + statclock(TRAPF_USERMODE(tf)); } /* Fire profclock at profhz, but only when needed. */ @@ -318,7 +318,7 @@ clock_intr(void *arg) if (cpu_ticks->prof_ticks >= cycles_per_profhz) { cpu_ticks->prof_ticks -= cycles_per_profhz; if (profprocs != 0) - profclock(USERMODE(tf->sr), tf->pc); + profclock(TRAPF_USERMODE(tf), tf->pc); } critical_exit(); #if 0 /* TARGET_OCTEON */ diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 8bfc6e7f4d5..de4bd01bf29 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -75,7 +75,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include @@ -272,7 +271,7 @@ extern char *syscallnames[]; * In the case of a kernel trap, we return the pc where to resume if * p->p_addr->u_pcb.pcb_onfault is set, otherwise, return old pc. */ -u_int +register_t trap(struct trapframe *trapframe) { int type, usermode; @@ -293,7 +292,7 @@ trap(struct trapframe *trapframe) trapdebug_enter(trapframe, 0); type = (trapframe->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT; - if (USERMODE(trapframe->sr)) { + if (TRAPF_USERMODE(trapframe)) { type |= T_USER; usermode = 1; } else { @@ -307,9 +306,9 @@ trap(struct trapframe *trapframe) */ if (trapframe->sr & SR_INT_ENAB) { set_intr_mask(~(trapframe->sr & ALL_INT_MASK)); - enableintr(); + intr_enable(); } else { - disableintr(); + intr_disable(); } #ifdef TRAP_DEBUG @@ -983,9 +982,10 @@ out: void trapDump(char *msg) { - int i, s; + register_t s; + int i; - s = disableintr(); + s = intr_disable(); printf("trapDump(%s)\n", msg); for (i = 0; i < TRAPSIZE; i++) { if (trp == trapdebug) { @@ -1003,9 +1003,8 @@ trapDump(char *msg) printf(" RA %x SP %x code %d\n", trp->ra, trp->sp, trp->code); } - restoreintr(s); + intr_restore(s); } - #endif diff --git a/sys/mips/rmi/clock.c b/sys/mips/rmi/clock.c index 6964522e9c9..c123edf589e 100644 --- a/sys/mips/rmi/clock.c +++ b/sys/mips/rmi/clock.c @@ -116,11 +116,11 @@ count_compare_clockhandler(struct trapframe *tf) cycles += XLR_CPU_HZ / hz; mips_wr_compare(cycles); - hardclock_cpu(USERMODE(tf->sr)); + hardclock_cpu(TRAPF_USERMODE(tf)); if (count_scale_factor[cpu] == STAT_PROF_CLOCK_SCALE_FACTOR) { - statclock(USERMODE(tf->sr)); + statclock(TRAPF_USERMODE(tf)); if (profprocs != 0) { - profclock(USERMODE(tf->sr), tf->pc); + profclock(TRAPF_USERMODE(tf), tf->pc); } count_scale_factor[cpu] = 0; } @@ -148,11 +148,11 @@ pic_hardclockhandler(struct trapframe *tf) printf("Clock tick foo at %ld\n", clock_tick_foo); } */ - hardclock(USERMODE(tf->sr), tf->pc); + hardclock(TRAPF_USERMODE(tf), tf->pc); if (scale_factor == STAT_PROF_CLOCK_SCALE_FACTOR) { - statclock(USERMODE(tf->sr)); + statclock(TRAPF_USERMODE(tf)); if (profprocs != 0) { - profclock(USERMODE(tf->sr), tf->pc); + profclock(TRAPF_USERMODE(tf), tf->pc); } scale_factor = 0; } From a97a1ee3d98b706bc84c8d89ff76ffb316f9fb1c Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 17 Apr 2010 01:49:50 +0000 Subject: [PATCH 099/532] o) Back out my previous change to SWARM; some of it was to address an issue that turned out to be unrelated, and the rest was, as pointed out by Neel, just wrong-headed. o) Tweak mem.c to fix use of /dev/kmem for direct-mapped addresses. --- sys/mips/conf/SWARM | 5 ----- sys/mips/mips/mem.c | 22 ++++++++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/sys/mips/conf/SWARM b/sys/mips/conf/SWARM index 455e2986f9c..3189bcbcb9c 100644 --- a/sys/mips/conf/SWARM +++ b/sys/mips/conf/SWARM @@ -19,13 +19,8 @@ options CFE_CONSOLE options CFE_ENV options ALT_BREAK_TO_DEBUGGER -# Don't build any modules yet. -makeoptions MODULES_OVERRIDE="" -makeoptions TARGET_BIG_ENDIAN=defined makeoptions LDSCRIPT_NAME= ldscript.mips.cfe -makeoptions KERNLOADADDR=0x81000000 - #cpu CPU_MIPS64 #options ISA_MIPS64 #makeoptions ARCH_FLAGS="-march=mips64 -mgp64 -mabi=o64" diff --git a/sys/mips/mips/mem.c b/sys/mips/mips/mem.c index a7f8244385a..9db282e4206 100644 --- a/sys/mips/mips/mem.c +++ b/sys/mips/mips/mem.c @@ -120,21 +120,23 @@ memrw(struct cdev *dev, struct uio *uio, int flags) * Make sure that all the pages are currently resident * so that we don't create any zero-fill pages. */ + if (va >= VM_MIN_KERNEL_ADDRESS && + eva <= VM_MAX_KERNEL_ADDRESS) { + for (; va < eva; va += PAGE_SIZE) + if (pmap_extract(kernel_pmap, va) == 0) + return (EFAULT); - for (; va < eva; va += PAGE_SIZE) - if (pmap_extract(kernel_pmap, va) == 0) + prot = (uio->uio_rw == UIO_READ) + ? VM_PROT_READ : VM_PROT_WRITE; + + va = uio->uio_offset; + if (kernacc((void *) va, iov->iov_len, prot) + == FALSE) return (EFAULT); - - prot = (uio->uio_rw == UIO_READ) - ? VM_PROT_READ : VM_PROT_WRITE; + } va = uio->uio_offset; - if (kernacc((void *) va, iov->iov_len, prot) - == FALSE) - return (EFAULT); - error = uiomove((void *)va, iov->iov_len, uio); - continue; } } From b6777295a6a08f4e5d76402dc98804aaa7cd76ee Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 17 Apr 2010 03:08:13 +0000 Subject: [PATCH 100/532] o) Add SMP support for Octeon using U-Boot to launch all the processors at the same time. o) Remove some unused trivial uart functions from octeon_machdep now that the uart part is fully working and they are unused. o) Use __func__ instead of __FUNCTION__. o) Use intr_*() instead of other routines that do the same thing. o) Remove some duplicate printfs from the Octeon port, as well as duplicate setting of Maxmem. o) Use the right frequency divider on Octeon. o) Use PCPU_GET(cpuid) consistently to get the cpuid of the running core. o) Remove some unused macros in the Octeon port. o) Use mips_sync() around use of the global dpcpu, whose value may not be visible to APs at first. o) When loading the first thread's stack, use macros to make the code correct for n64 as well. o) Remove stub, do-nothing FAU init/enable/disable functions from the RGMX driver. --- sys/mips/cavium/asm_octeon.S | 216 ++++++------------------ sys/mips/cavium/dev/rgmii/octeon_fau.c | 83 --------- sys/mips/cavium/dev/rgmii/octeon_fau.h | 5 - sys/mips/cavium/dev/rgmii/octeon_rgmx.c | 2 +- sys/mips/cavium/files.octeon1 | 4 +- sys/mips/cavium/octeon_machdep.c | 184 +++----------------- sys/mips/cavium/octeon_mp.c | 102 +++++++++++ sys/mips/cavium/octeon_pcmap_regs.h | 90 ---------- sys/mips/mips/locore.S | 18 +- sys/mips/mips/mp_machdep.c | 4 + sys/mips/mips/mpboot.S | 15 +- 11 files changed, 210 insertions(+), 513 deletions(-) delete mode 100644 sys/mips/cavium/dev/rgmii/octeon_fau.c create mode 100644 sys/mips/cavium/octeon_mp.c diff --git a/sys/mips/cavium/asm_octeon.S b/sys/mips/cavium/asm_octeon.S index d9f79f134ff..94ac875a199 100644 --- a/sys/mips/cavium/asm_octeon.S +++ b/sys/mips/cavium/asm_octeon.S @@ -1,182 +1,66 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. +/*- + * Copyright (c) 2004-2010 Juli Mallett + * All rights reserved. * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/* $FreeBSD$ */ + * $FreeBSD$ + */ #include -#include -#include -#include -#include -#include "assym.s" - + .set noreorder - -#define CPU_DISABLE_INTERRUPTS(reg, reg2, reg3) \ - mfc0 reg, MIPS_COP_0_STATUS; \ - nop; \ - move reg3, reg; \ - li reg2, ~MIPS_SR_INT_IE; \ - and reg, reg2, reg; \ - mtc0 reg, MIPS_COP_0_STATUS; \ - COP0_SYNC - - - -#define CPU_ENABLE_INTERRUPTS(reg, reg3) \ - mfc0 reg, MIPS_COP_0_STATUS; \ - nop; \ - or reg, reg, reg3; \ - mtc0 reg, MIPS_COP_0_STATUS; \ - COP0_SYNC - - -#define PUSHR(reg) \ - addiu sp,sp,-16 ; \ - sd reg, 8(sp) ; \ - nop ; - -#define POPR(reg) \ - ld reg, 8(sp) ; \ - addiu sp,sp,16 ; \ - nop ; - - - - +#ifdef SMP /* - * octeon_ciu_get_interrupt_reg_addr - * - * Given Int-X, En-X combination, return the CIU Interrupt Enable Register addr - * a0 = ciu Int-X: 0/1 - * a1 = ciu EN-0: 0/1 + * This function must be implemented in assembly because it is called early + * in AP boot without a valid stack. */ -LEAF(octeon_ciu_get_interrupt_reg_addr) - .set noreorder - .set mips3 +LEAF(platform_processor_id) + .set push + .set mips32r2 + jr ra + rdhwr v0, $0 + .set pop +END(platform_processor_id) - beqz a0, ciu_get_interrupt_reg_addr_Int_0 - nop - -ciu_get_interrupt_reg_addr_Int_1: - beqz a1, ciu_get_interrupt_reg_addr_Int_1_En_0 - nop - -ciu_get_interrupt_reg_addr_Int_1_En1: - li a0, OCTEON_CIU_ADDR_HI - dsll32 a0, a0, 0 - nop - ori a0, OCTEON_CIU_EN1_INT1_LO - j ciu_get_interrupt_reg_addr_ret - nop - -ciu_get_interrupt_reg_addr_Int_1_En_0: - li a0, OCTEON_CIU_ADDR_HI - dsll32 a0, a0, 0 - nop - ori a0, OCTEON_CIU_EN0_INT1_LO - j ciu_get_interrupt_reg_addr_ret - nop - -ciu_get_interrupt_reg_addr_Int_0: - beqz a1, ciu_get_interrupt_reg_addr_Int_0_En_0 - nop - -ciu_get_interrupt_reg_addr_Int_0_En_1: - li a0, OCTEON_CIU_ADDR_HI - dsll32 a0, a0, 0 - nop - ori a0, OCTEON_CIU_EN1_INT0_LO - j ciu_get_interrupt_reg_addr_ret - nop - -ciu_get_interrupt_reg_addr_Int_0_En_0: - li a0, OCTEON_CIU_ADDR_HI - dsll32 a0, a0, 0 - nop - ori a0, OCTEON_CIU_EN0_INT0_LO - - -ciu_get_interrupt_reg_addr_ret: - j ra - nop - - .set mips0 - .set reorder -END(octeon_ciu_get_interrupt_reg_addr) - - - /* - * octeon_ciu_mask_all_interrupts - * - * a0 = ciu Interrupt-X: 0/1 - * a1 = ciu Enable-X: 0/1 + * Called on APs to wait until they are told to launch. */ -LEAF(octeon_ciu_mask_all_interrupts) - .set noreorder - .set mips3 +LEAF(octeon_ap_wait) + jal platform_processor_id + nop - PUSHR(ra) - PUSHR(s0) - - move t0, a0 - move t1, a1 - li a0, MIPS_SR_INT_IE - CPU_DISABLE_INTERRUPTS(a2, a1, s0) - move a0, t0 - move t1, a1 - jal octeon_ciu_get_interrupt_reg_addr - nop - ld a2, 0(a0) # Dummy read - nop - move a2, zero # Clear all - sd a2, 0(a0) # Write new Enable bits - nop - CPU_ENABLE_INTERRUPTS(a2, s0) +1: ll t0, octeon_ap_boot + bne v0, t0, 1b + nop - POPR(s0) - POPR(ra) - j ra # Return - nop # (bd slot) + move t0, zero + sc t0, octeon_ap_boot - .set mips0 - .set reorder -END(octeon_ciu_mask_all_interrupts) + beqz t0, 1b + nop + j mpentry + nop +END(octeon_ap_wait) +#endif diff --git a/sys/mips/cavium/dev/rgmii/octeon_fau.c b/sys/mips/cavium/dev/rgmii/octeon_fau.c deleted file mode 100644 index fb4c0ad3a80..00000000000 --- a/sys/mips/cavium/dev/rgmii/octeon_fau.c +++ /dev/null @@ -1,83 +0,0 @@ -/***********************license start*************** - * Copyright (c) 2003-2008 Cavium Networks (support@cavium.com). All rights - * reserved. - * - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * * Neither the name of Cavium Networks nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" - * AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS - * OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH - * RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY - * REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT - * DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES - * OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR - * PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET - * POSSESSION OR CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT - * OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU. - * - * - * For any questions regarding licensing please contact marketing@caviumnetworks.com - * - ***********************license end**************************************/ - -/*------------------------------------------------------------------ - * octeon_fau.c Fetch & Add Block - * - *------------------------------------------------------------------ - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include -#include "octeon_fau.h" - -/* - * oct_fau_init - * - * How do we initialize FAU unit. I don't even think we can reset it. - */ -void octeon_fau_init (void) -{ -} - - -/* - * oct_fau_enable - * - * Let the Fetch/Add unit roll - */ -void octeon_fau_enable (void) -{ -} - - -/* - * oct_fau_disable - * - * disable fau - * - * Don't know if we can even do that. - */ -void octeon_fau_disable (void) -{ -} diff --git a/sys/mips/cavium/dev/rgmii/octeon_fau.h b/sys/mips/cavium/dev/rgmii/octeon_fau.h index 1683ff55e00..acf5132e2e8 100644 --- a/sys/mips/cavium/dev/rgmii/octeon_fau.h +++ b/sys/mips/cavium/dev/rgmii/octeon_fau.h @@ -217,9 +217,4 @@ static inline void octeon_fau_atomic_add64 (octeon_fau_reg_64_t reg, int64_t val } -extern void octeon_fau_init(void); -extern void octeon_fau_enable(void); -extern void octeon_fau_disable(void); - - #endif /* ___OCTEON_FAU__H___ */ diff --git a/sys/mips/cavium/dev/rgmii/octeon_rgmx.c b/sys/mips/cavium/dev/rgmii/octeon_rgmx.c index ada09461778..5b84af5dcaa 100644 --- a/sys/mips/cavium/dev/rgmii/octeon_rgmx.c +++ b/sys/mips/cavium/dev/rgmii/octeon_rgmx.c @@ -1481,7 +1481,7 @@ static void octeon_config_hw_units_post_ports (void) oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64); #endif - ciu_enable_interrupts(OCTEON_CORE_ID, OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX, + ciu_enable_interrupts(PCPU_GET(cpuid), OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX, (OCTEON_POW_RX_GROUP_MASK | CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)), CIU_MIPS_IP2); diff --git a/sys/mips/cavium/files.octeon1 b/sys/mips/cavium/files.octeon1 index c10988c46c1..4cf31f84310 100644 --- a/sys/mips/cavium/files.octeon1 +++ b/sys/mips/cavium/files.octeon1 @@ -1,8 +1,7 @@ # $FreeBSD$ # Octeon Support Files # -mips/mips/mp_machdep.c optional smp -mips/cavium/dev/rgmii/octeon_fau.c optional rgmii +mips/cavium/asm_octeon.S optional smp mips/cavium/dev/rgmii/octeon_fpa.c optional rgmii mips/cavium/dev/rgmii/octeon_ipd.c optional rgmii mips/cavium/dev/rgmii/octeon_pko.c optional rgmii @@ -10,6 +9,7 @@ mips/cavium/dev/rgmii/octeon_rgmx.c optional rgmii mips/cavium/obio.c optional uart mips/cavium/octeon_ebt3000_cf.c optional cf mips/cavium/octeon_machdep.c standard +mips/cavium/octeon_mp.c optional smp mips/cavium/uart_bus_octeonusart.c optional uart mips/cavium/uart_cpu_octeonusart.c optional uart mips/cavium/uart_dev_oct16550.c optional uart diff --git a/sys/mips/cavium/octeon_machdep.c b/sys/mips/cavium/octeon_machdep.c index f55c7ea4dfb..c796071a385 100644 --- a/sys/mips/cavium/octeon_machdep.c +++ b/sys/mips/cavium/octeon_machdep.c @@ -111,25 +111,6 @@ platform_reset(void) oct_write64(OCTEON_CIU_SOFT_RST, 1); } - -static inline uint32_t -octeon_disable_interrupts(void) -{ - uint32_t status_bits; - - status_bits = mips_rd_status(); - mips_wr_status(status_bits & ~MIPS_SR_INT_IE); - return (status_bits); -} - - -static inline void -octeon_set_interrupts(uint32_t status_bits) -{ - mips_wr_status(status_bits); -} - - void octeon_led_write_char(int char_position, char val) { @@ -203,82 +184,6 @@ octeon_led_run_wheel(int *prog_count, int led_position) *prog_count &= 0x7; } -#define LSR_DATAREADY 0x01 /* Data ready */ -#define LSR_THRE 0x20 /* Transmit holding register empty */ -#define LSR_TEMT 0x40 /* Transmitter Empty. THR, TSR & FIFO */ -#define USR_TXFIFO_NOTFULL 0x02 /* Uart TX FIFO Not full */ - -/* - * octeon_uart_write_byte - * - * Put out a single byte off of uart port. - */ - -void -octeon_uart_write_byte(int uart_index, uint8_t ch) -{ - uint64_t val, val2; - if (uart_index < 0 || uart_index > 1) - return; - - while (1) { - val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); - val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400)); - if ((((uint8_t) val) & LSR_THRE) || - (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { - break; - } - } - - /* Write the byte */ - oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch); - - /* Force Flush the IOBus */ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); -} - - -void -octeon_uart_write_byte0(uint8_t ch) -{ - uint64_t val, val2; - - while (1) { - val = oct_read64(OCTEON_MIO_UART0_LSR); - val2 = oct_read64(OCTEON_MIO_UART0_USR); - if ((((uint8_t) val) & LSR_THRE) || - (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) { - break; - } - } - - /* Write the byte */ - oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch); - - /* Force Flush the IOBus */ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); -} - -/* - * octeon_uart_write_string - * - */ -void -octeon_uart_write_string(int uart_index, const char *str) -{ - /* Just loop writing one byte at a time */ - - while (*str) { - octeon_uart_write_byte(uart_index, *str); - if (*str == '\n') { - octeon_uart_write_byte(uart_index, '\r'); - } - str++; - } -} - -static char wstr[30]; - void octeon_led_write_hex(uint32_t wl) { @@ -289,44 +194,6 @@ octeon_led_write_hex(uint32_t wl) } -void octeon_uart_write_hex2(uint32_t wl, uint32_t wh) -{ - sprintf(wstr, "0x%X-0x%X ", wh, wl); - octeon_uart_write_string(0, wstr); -} - -void -octeon_uart_write_hex(uint32_t wl) -{ - sprintf(wstr, " 0x%X ", wl); - octeon_uart_write_string(0, wstr); -} - -/* - * octeon_wait_uart_flush - */ -void -octeon_wait_uart_flush(int uart_index, uint8_t ch) -{ - uint64_t val; - int64_t val3; - uint32_t cpu_status_bits; - - if (uart_index < 0 || uart_index > 1) - return; - - cpu_status_bits = octeon_disable_interrupts(); - /* Force Flush the IOBus */ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); - for (val3 = 0xfffffffff; val3 > 0; val3--) { - val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400)); - if (((uint8_t) val) & LSR_TEMT) - break; - } - octeon_set_interrupts(cpu_status_bits); -} - - /* * octeon_debug_symbol * @@ -450,17 +317,17 @@ ciu_get_en_reg_addr_new(int corenum, int intx, int enx, int ciu_ip) /* XXX kasserts? */ if (enx < CIU_EN_0 || enx > CIU_EN_1) { printf("%s: invalid enx value %d, should be %d or %d\n", - __FUNCTION__, enx, CIU_EN_0, CIU_EN_1); + __func__, enx, CIU_EN_0, CIU_EN_1); return 0; } if (intx < CIU_INT_0 || intx > CIU_INT_1) { printf("%s: invalid intx value %d, should be %d or %d\n", - __FUNCTION__, enx, CIU_INT_0, CIU_INT_1); + __func__, enx, CIU_INT_0, CIU_INT_1); return 0; } if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) { printf("%s: invalid ciu_ip value %d, should be %d or %d\n", - __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3); + __func__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3); return 0; } @@ -517,7 +384,7 @@ ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits) core_num, intx, enx, write_bits); #endif - cpu_status_bits = octeon_disable_interrupts(); + cpu_status_bits = intr_disable(); ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx); @@ -535,7 +402,7 @@ ciu_clear_int_summary(int core_num, int intx, int enx, uint64_t write_bits) printf(" Readback: 0x%llX\n\n ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr)); #endif - octeon_set_interrupts(cpu_status_bits); + intr_restore(cpu_status_bits); } /* @@ -550,7 +417,7 @@ ciu_disable_intr(int core_num, int intx, int enx) if (core_num == CIU_THIS_CORE) core_num = octeon_get_core_num(); - cpu_status_bits = octeon_disable_interrupts(); + cpu_status_bits = intr_disable(); ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); @@ -559,7 +426,7 @@ ciu_disable_intr(int core_num, int intx, int enx) oct_write64(ciu_intr_reg_addr, 0LL); oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ - octeon_set_interrupts(cpu_status_bits); + intr_restore(cpu_status_bits); } void @@ -580,7 +447,7 @@ ciu_dump_interrutps_enabled(int core_num, int intx, int enx, int ciu_ip) #endif if (!ciu_intr_reg_addr) { - printf("Bad call to %s\n", __FUNCTION__); + printf("Bad call to %s\n", __func__); while(1); return; } @@ -612,7 +479,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx, core_num, intx, enx, ciu_ip, set_these_interrupt_bits); #endif - cpu_status_bits = octeon_disable_interrupts(); + cpu_status_bits = intr_disable(); #ifndef OCTEON_SMP_1 ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx); @@ -621,7 +488,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx, #endif if (!ciu_intr_reg_addr) { - printf("Bad call to %s\n", __FUNCTION__); + printf("Bad call to %s\n", __func__); while(1); return; /* XXX */ } @@ -634,7 +501,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx, #endif ciu_intr_bits |= set_these_interrupt_bits; oct_write64(ciu_intr_reg_addr, ciu_intr_bits); -#ifdef OCTEON_SMP +#ifdef SMP mips_wbflush(); #endif oct_read64(OCTEON_MIO_BOOT_BIST_STAT); /* Bus Barrier */ @@ -644,7 +511,7 @@ void ciu_enable_interrupts(int core_num, int intx, int enx, (uint64_t)oct_read64(ciu_intr_reg_addr)); #endif - octeon_set_interrupts(cpu_status_bits); + intr_restore(cpu_status_bits); } unsigned long @@ -659,12 +526,8 @@ octeon_memory_init(void) uint32_t realmem_bytes; if (octeon_board_real()) { - printf("octeon_dram == %jx\n", (intmax_t)octeon_dram); - printf("reduced to ram: %u MB", (uint32_t)octeon_dram >> 20); - realmem_bytes = (octeon_dram - PAGE_SIZE); realmem_bytes &= ~(PAGE_SIZE - 1); - printf("Real memory bytes is %x\n", realmem_bytes); } else { /* Simulator we limit to 96 meg */ realmem_bytes = (96 << 20); @@ -678,8 +541,6 @@ octeon_memory_init(void) phys_avail[1] = realmem_bytes; realmem_bytes -= OCTEON_DRAM_FIRST_256_END; realmem_bytes &= ~(PAGE_SIZE - 1); - printf("phys_avail[0] = %#lx phys_avail[1] = %#lx\n", - (long)phys_avail[0], (long)phys_avail[1]); } else { /* Simulator gets 96Meg period. */ phys_avail[1] = (96 << 20); @@ -705,23 +566,14 @@ octeon_memory_init(void) realmem_bytes &= ~(PAGE_SIZE - 1); /* Now map the rest of the memory */ phys_avail[2] = 0x20000000; - printf("realmem_bytes is now at %x\n", realmem_bytes); phys_avail[3] = ((uint32_t) 0x20000000 + realmem_bytes); - printf("Next block of memory goes from %#lx to %#lx\n", - (long)phys_avail[2], (long)phys_avail[3]); physmem += btoc(phys_avail[3] - phys_avail[2]); - } else { - printf("realmem_bytes is %d\n", realmem_bytes); } realmem = physmem; printf("Total DRAM Size %#X\n", (uint32_t) octeon_dram); printf("Bank 0 = %#08lX -> %#08lX\n", (long)phys_avail[0], (long)phys_avail[1]); printf("Bank 1 = %#08lX -> %#08lX\n", (long)phys_avail[2], (long)phys_avail[3]); - printf("physmem: %#lx\n", physmem); - - Maxmem = physmem; - } void @@ -760,7 +612,15 @@ platform_start(__register_t a0, __register_t a1, __register_t a2 __unused, kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif platform_counter_freq = octeon_get_clock_rate(); - mips_timer_init_params(platform_counter_freq, 1); + mips_timer_init_params(platform_counter_freq, 0); + +#ifdef SMP + /* + * Clear any pending IPIs and enable the IPI interrupt. + */ + oct_write64(OCTEON_CIU_MBOX_CLRX(0), 0xffffffff); + ciu_enable_interrupts(0, CIU_INT_1, CIU_EN_0, OCTEON_CIU_ENABLE_MBOX_INTR, CIU_MIPS_IP3); +#endif } /* impSTART: This stuff should move back into the Cavium SDK */ @@ -982,7 +842,7 @@ octeon_boot_params_init(register_t ptr) printf("Boot Descriptor Ver: %u -> %u/%u", octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100); - printf(" CPU clock: %uMHz\n", octeon_cpu_clock/1000000); + printf(" CPU clock: %uMHz Core Mask: %#x\n", octeon_cpu_clock/1000000, octeon_core_mask); printf(" Dram: %u MB", (uint32_t)(octeon_dram >> 20)); printf(" Board Type: %u Revision: %u/%u\n", octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor); diff --git a/sys/mips/cavium/octeon_mp.c b/sys/mips/cavium/octeon_mp.c new file mode 100644 index 00000000000..85cdc45dadd --- /dev/null +++ b/sys/mips/cavium/octeon_mp.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2004-2010 Juli Mallett + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include + +unsigned octeon_ap_boot = ~0; + +void +platform_ipi_send(int cpuid) +{ + oct_write64(OCTEON_CIU_MBOX_SETX(cpuid), 1); + mips_wbflush(); +} + +void +platform_ipi_clear(void) +{ + uint64_t action; + + action = oct_read64(OCTEON_CIU_MBOX_CLRX(PCPU_GET(cpuid))); + KASSERT(action == 1, ("unexpected IPIs: %#jx", (uintmax_t)action)); + oct_write64(OCTEON_CIU_MBOX_CLRX(PCPU_GET(cpuid)), action); +} + +int +platform_ipi_intrnum(void) +{ + return (1); +} + +void +platform_init_ap(int cpuid) +{ + /* + * Set the exception base. + */ + mips_wr_prid1(0x80000000 | cpuid); + + /* + * Set up interrupts, clear IPIs and unmask the IPI interrupt. + */ + octeon_ciu_reset(); + + oct_write64(OCTEON_CIU_MBOX_CLRX(cpuid), 0xffffffff); + ciu_enable_interrupts(cpuid, CIU_INT_1, CIU_EN_0, OCTEON_CIU_ENABLE_MBOX_INTR, CIU_MIPS_IP3); + + mips_wbflush(); +} + +int +platform_num_processors(void) +{ + return (fls(octeon_core_mask)); +} + +int +platform_start_ap(int cpuid) +{ + if (atomic_cmpset_32(&octeon_ap_boot, ~0, cpuid) == 0) + return (-1); + for (;;) { + DELAY(1000); + if (atomic_cmpset_32(&octeon_ap_boot, 0, ~0) != 0) + return (0); + printf("Waiting for cpu%d to start\n", cpuid); + } +} diff --git a/sys/mips/cavium/octeon_pcmap_regs.h b/sys/mips/cavium/octeon_pcmap_regs.h index 16dff5b35c9..0ee1a73ea8a 100644 --- a/sys/mips/cavium/octeon_pcmap_regs.h +++ b/sys/mips/cavium/octeon_pcmap_regs.h @@ -54,14 +54,6 @@ #ifndef LOCORE -/* XXXimp: From Cavium's include/pcpu.h, need to port that over */ -#ifndef OCTEON_SMP -#define OCTEON_CORE_ID 0 -#else -extern struct pcpu *cpuid_to_pcpu[]; -#define OCTEON_CORE_ID (mips_rd_coreid()) -#endif - /* * Utility inlines & macros */ @@ -324,62 +316,6 @@ static inline void oct_write32 (uint64_t csr_addr, uint32_t val32) #define OCTEON_SCRATCH_2 32 -static inline uint64_t oct_mf_chord (void) -{ - uint64_t dest; - - __asm __volatile ( ".set push\n" - ".set noreorder\n" - ".set noat\n" - ".set mips64\n" - "dmfc2 $1, 0x400\n" - "move %0, $1\n" - ".set pop\n" - : "=r" (dest) : : "$1"); - return dest; -} - - -#define MIPS64_DMFCz(cop,regnum,cp0reg,select) \ - .word (0x40200000 | (cop << 25) | (regnum << 16) | (cp0reg << 11) | select) - - -#define mips64_getcpz_xstr(s) mips64_getcpz_str(s) -#define mips64_getcpz_str(s) #s - -#define mips64_dgetcpz(cop,cpzreg,sel,val_ptr) \ - ({ __asm __volatile( \ - ".set push\n" \ - ".set mips3\n" \ - ".set noreorder\n" \ - ".set noat\n" \ - mips64_getcpz_xstr(MIPS64_DMFCz(cop,1,cpzreg,sel)) "\n" \ - "nop\n" \ - "nop\n" \ - "nop\n" \ - "nop\n" \ - "sd $1,0(%0)\n" \ - ".set pop" \ - : /* no outputs */ : "r" (val_ptr) : "$1"); \ - }) - - -#define mips64_dgetcp2(cp2reg,sel,retval_ptr) \ - mips64_dgetcpz(2,cp2reg,sel,retval_ptr) - - -#define OCTEON_MF_CHORD(dest) mips64_dgetcp2(0x400, 0, &dest) - - - -#define OCTEON_RDHWR(result, regstr) \ - __asm __volatile ( \ - ".set mips3\n" \ - "rdhwr %0,$" OCTEON_TMP_STR(regstr) "\n" \ - ".set mips\n" \ - : "=d" (result)); - -#define CVMX_MF_CHORD(dest) OCTEON_RDHWR(dest, 30) #define OCTEON_CHORD_HEX(dest_ptr) \ ({ __asm __volatile( \ @@ -397,15 +333,6 @@ static inline uint64_t oct_mf_chord (void) : /* no outputs */ : "r" (dest_ptr) : "$2"); \ }) - - -#define OCTEON_MF_CHORD_BAD(dest) \ - __asm __volatile ( \ - ".set mips3\n" \ - "dmfc2 %0, 0x400\n" \ - ".set mips0\n" \ - : "=&r" (dest) : ) - static inline uint64_t oct_scratch_read64 (uint64_t address) { return(*((volatile uint64_t *)(OCTEON_SCRATCH_BASE + address))); @@ -417,17 +344,6 @@ static inline void oct_scratch_write64 (uint64_t address, uint64_t value) } -#define OCTEON_READ_CSR32(addr, val) \ - addr_ptr = addr; \ - oct_read_32_ptr(&addr_ptr, &val); - -#define OCTEON_WRITE_CSR32(addr, val, val_dummy) \ - addr_ptr = addr; \ - oct_write_32_ptr(&addr_ptr, &val); \ - oct_read64(OCTEON_MIO_BOOT_BIST_STAT); - - - /* * Octeon Address Space Definitions */ @@ -791,12 +707,6 @@ extern void octeon_led_write_hexchar(int char_position, char hexval); extern void octeon_led_write_hex(uint32_t wl); extern void octeon_led_write_string(const char *str); extern void octeon_reset(void); -extern void octeon_uart_write_byte(int uart_index, uint8_t ch); -extern void octeon_uart_write_string(int uart_index, const char *str); -extern void octeon_uart_write_hex(uint32_t wl); -extern void octeon_uart_write_hex2(uint32_t wl, uint32_t wh); -extern void octeon_wait_uart_flush(int uart_index, uint8_t ch); -extern void octeon_uart_write_byte0(uint8_t ch); extern void octeon_led_write_char0(char val); extern void octeon_led_run_wheel(int *pos, int led_position); extern void octeon_debug_symbol(void); diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index 1574d7542a1..697b81884f5 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -162,6 +162,18 @@ VECTOR(_locore, unknown) sw a2, _C_LABEL(fenvp) #endif +#if defined(TARGET_OCTEON) && defined(SMP) + .set push + .set mips32r2 + rdhwr t2, $0 + beqz t2, 1f + nop + j octeon_ap_wait + nop + .set pop +1: +#endif + /* * Initialize stack and call machine startup. */ @@ -178,10 +190,10 @@ VECTOR(_locore, unknown) nop PTR_LA sp, _C_LABEL(thread0) - lw a0, TD_PCB(sp) - li t0, ~7 + PTR_L a0, TD_PCB(sp) + REG_LI t0, ~7 and a0, a0, t0 - subu sp, a0, CALLFRAME_SIZ + PTR_SUBU sp, a0, CALLFRAME_SIZ jal _C_LABEL(mi_startup) # mi_startup(frame) sw zero, CALLFRAME_SIZ - 8(sp) # Zero out old fp for debugger diff --git a/sys/mips/mips/mp_machdep.c b/sys/mips/mips/mp_machdep.c index 52d05fad711..f0c142f0c3a 100644 --- a/sys/mips/mips/mp_machdep.c +++ b/sys/mips/mips/mp_machdep.c @@ -157,6 +157,8 @@ start_ap(int cpuid) cpus = mp_naps; dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE); + mips_sync(); + if (platform_start_ap(cpuid) != 0) return (-1); /* could not start AP */ @@ -246,6 +248,8 @@ smp_init_secondary(u_int32_t cpuid) mips_dcache_wbinv_all(); mips_icache_sync_all(); + mips_sync(); + MachSetPID(0); pcpu_init(PCPU_ADDR(cpuid), cpuid, sizeof(struct pcpu)); diff --git a/sys/mips/mips/mpboot.S b/sys/mips/mips/mpboot.S index ce2982d4005..e1c578a7961 100644 --- a/sys/mips/mips/mpboot.S +++ b/sys/mips/mips/mpboot.S @@ -36,8 +36,21 @@ .set noat .set noreorder +#ifdef TARGET_OCTEON +#define CLEAR_STATUS \ + mfc0 a0, COP_0_STATUS_REG ;\ + li a2, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) ; \ + or a0, a0, a2 ; \ + li a2, ~(MIPS_SR_INT_IE | MIPS_SR_EXL | SR_KSU_USER | MIPS_SR_BEV) ; \ + and a0, a0, a2 ; \ + mtc0 a0, COP_0_STATUS_REG +#else +#define CLEAR_STATUS \ + mtc0 zero, COP_0_STATUS_REG +#endif + GLOBAL(mpentry) - mtc0 zero, COP_0_STATUS_REG /* disable interrupts */ + CLEAR_STATUS /* disable interrupts */ mtc0 zero, COP_0_CAUSE_REG /* clear soft interrupts */ From 2ab78e3ca5e86ce64742020d09b4dcecd067c23c Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 17 Apr 2010 07:20:01 +0000 Subject: [PATCH 101/532] o) Add NPDEPG, like NPTEPG but for PDEs. o) Remove NBPG, PGOFSET and PGSHIFT. Use the standard names. o) Remove some unused macros and move things from param.h to vmparam.h that belong in the latter. (Actually, all of the kernel segment values, virtual addresses, etc., belong in one place, but this is a step in the right direction.) --- sys/mips/include/param.h | 40 +++++++++++++------------------------- sys/mips/include/pte.h | 2 +- sys/mips/include/vmparam.h | 31 +++++++++++------------------ sys/mips/mips/exception.S | 6 +++--- sys/mips/mips/genassym.c | 3 +-- sys/mips/mips/locore.S | 2 +- sys/mips/mips/mpboot.S | 2 +- sys/mips/mips/pmap.c | 18 ++++++++--------- sys/mips/mips/support.S | 2 +- sys/mips/mips/tlb.S | 8 ++++---- sys/mips/mips/trap.c | 12 ++++++------ sys/mips/mips/vm_machdep.c | 4 ++-- 12 files changed, 53 insertions(+), 77 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index 0f380852609..0edb8b93d55 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -100,28 +100,14 @@ #define CACHE_LINE_SHIFT 6 #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) -#define NBPG 4096 /* bytes/page */ -#define PGOFSET (NBPG-1) /* byte offset into page */ -#define PGSHIFT 12 /* LOG2(NBPG) */ - #define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */ #define PAGE_SIZE (1<> PGSHIFT) - #define BLKDEV_IOSIZE 2048 /* xxx: Why is this 1/2 page? */ #define MAXDUMPPGS 1 /* xxx: why is this only one? */ @@ -137,8 +123,8 @@ #define UPAGES 2 /* pages ("clicks") (4096 bytes) to disk blocks */ -#define ctod(x) ((x) << (PGSHIFT - DEV_BSHIFT)) -#define dtoc(x) ((x) >> (PGSHIFT - DEV_BSHIFT)) +#define ctod(x) ((x) << (PAGE_SHIFT - DEV_BSHIFT)) +#define dtoc(x) ((x) >> (PAGE_SHIFT - DEV_BSHIFT)) /* * Map a ``block device block'' to a file system block. @@ -149,18 +135,18 @@ #define bdbtofsb(bn) ((bn) / (BLKDEV_IOSIZE/DEV_BSIZE)) /* - * Conversion macros + * Mach derived conversion macros */ -#define mips_round_page(x) ((((unsigned long)(x)) + NBPG - 1) & ~(NBPG-1)) -#define mips_trunc_page(x) ((unsigned long)(x) & ~(NBPG-1)) -#define mips_btop(x) ((unsigned long)(x) >> PGSHIFT) -#define mips_ptob(x) ((unsigned long)(x) << PGSHIFT) -#define round_page mips_round_page -#define trunc_page mips_trunc_page -#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) -#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT) +#define round_page(x) (((unsigned long)(x) + PAGE_MASK) & ~PAGE_MASK) +#define trunc_page(x) ((unsigned long)(x) & ~PAGE_MASK) -#define pgtok(x) ((x) * (PAGE_SIZE / 1024)) +#define atop(x) ((unsigned long)(x) >> PAGE_SHIFT) +#define ptoa(x) ((unsigned long)(x) << PAGE_SHIFT) + +#define mips_btop(x) ((unsigned long)(x) >> PAGE_SHIFT) +#define mips_ptob(x) ((unsigned long)(x) << PAGE_SHIFT) + +#define pgtok(x) ((unsigned long)(x) * (PAGE_SIZE / 1024)) #ifndef _KERNEL #define DELAY(n) { register int N = (n); while (--N > 0); } diff --git a/sys/mips/include/pte.h b/sys/mips/include/pte.h index db26cbb0929..31b08449711 100644 --- a/sys/mips/include/pte.h +++ b/sys/mips/include/pte.h @@ -126,7 +126,7 @@ typedef pt_entry_t *pd_entry_t; #define pfn_to_vad(x) (((x) & PTE_FRAME) << PTE_SHIFT) /* User virtual to pte offset in page table */ -#define vad_to_pte_offset(adr) (((adr) >> PGSHIFT) & (NPTEPG -1)) +#define vad_to_pte_offset(adr) (((adr) >> PAGE_SHIFT) & (NPTEPG -1)) #define mips_pg_v(entry) ((entry) & PTE_V) #define mips_pg_wired(entry) ((entry) & PTE_WIRED) diff --git a/sys/mips/include/vmparam.h b/sys/mips/include/vmparam.h index d4bc7fa07b0..bed5e36398e 100644 --- a/sys/mips/include/vmparam.h +++ b/sys/mips/include/vmparam.h @@ -97,13 +97,19 @@ /* user/kernel map constants */ #define VM_MIN_ADDRESS ((vm_offset_t)0x00000000) +#define VM_MAX_ADDRESS ((vm_offset_t)(intptr_t)(int32_t)0xffffffff) + +#define VM_MINUSER_ADDRESS ((vm_offset_t)0x00000000) #define VM_MAXUSER_ADDRESS ((vm_offset_t)0x80000000) #define VM_MAX_MMAP_ADDR VM_MAXUSER_ADDRESS -#define VM_MAX_ADDRESS ((vm_offset_t)0x80000000) #define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)0xC0000000) -#define VM_KERNEL_WIRED_ADDR_END (VM_MIN_KERNEL_ADDRESS) -#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xFFFFC000) +#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)0xFFFFC000) +#if 0 +#define KERNBASE (VM_MIN_KERNEL_ADDRESS) +#else +#define KERNBASE ((vm_offset_t)(intptr_t)(int32_t)0x80000000) +#endif /* * Disable superpage reservations. (not sure if this is right @@ -175,23 +181,8 @@ */ #define VM_NFREEORDER 9 -/* - * XXXMIPS: This values need to be changed!!! - */ -#if 0 -#define VM_MIN_ADDRESS ((vm_offset_t)0x0000000000010000) -#define VM_MAXUSER_ADDRESS ((vm_offset_t)MIPS_KSEG0_START-1) -#define VM_MAX_ADDRESS ((vm_offset_t)0x0000000100000000) -#define VM_MIN_KERNEL_ADDRESS ((vm_offset_t)MIPS_KSEG3_START) -#define VM_MAX_KERNEL_ADDRESS ((vm_offset_t)MIPS_KSEG3_END) -#define KERNBASE (VM_MIN_KERNEL_ADDRESS) - -/* virtual sizes (bytes) for various kernel submaps */ -#define VM_KMEM_SIZE (16*1024*1024) /* XXX ??? */ -#endif - -#define NBSEG 0x400000 /* bytes/segment */ -#define SEGOFSET (NBSEG-1) /* byte offset into segment */ #define SEGSHIFT 22 /* LOG2(NBSEG) */ +#define NBSEG (1 << SEGSHIFT) /* bytes/segment */ +#define SEGOFSET (NBSEG-1) /* byte offset into segment */ #endif /* !_MACHINE_VMPARAM_H_ */ diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 161e9475eff..8c32b582c3c 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -158,7 +158,7 @@ MipsDoTLBMiss: lw k1, 0(k1) #08: k1=seg entry mfc0 k0, COP_0_BAD_VADDR #09: k0=bad address (again) beq k1, zero, 2f #0a: ==0 -- no page table - srl k0, PGSHIFT - 2 #0b: k0=VPN (aka va>>10) + srl k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10) andi k0, k0, ((NPTEPG/2) - 1) << 3 #0c: k0=page tab offset #xxx mips64 unsafe? @@ -860,7 +860,7 @@ NLEAF(MipsTLBInvalidException) nop mfc0 k0, COP_0_BAD_VADDR - srl k0, PGSHIFT - 2 + srl k0, PAGE_SHIFT - 2 andi k0, 0xffc addu k1, k1, k0 @@ -944,7 +944,7 @@ tlb_insert_random: sll k1, k1, PAGE_SHIFT + 1 PTR_LA k0, _C_LABEL(pcpu_space) - addiu k0, (NBPG * 2) + addiu k0, (PAGE_SIZE * 2) addu k0, k0, k1 /* diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index f59ef6854ba..6cec2b79435 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -90,8 +90,7 @@ ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS); ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); ASSYM(SIGFPE, SIGFPE); ASSYM(PAGE_SHIFT, PAGE_SHIFT); -ASSYM(PGSHIFT, PGSHIFT); -ASSYM(NBPG, NBPG); +ASSYM(PAGE_SIZE, PAGE_SIZE); ASSYM(SEGSHIFT, SEGSHIFT); ASSYM(NPTEPG, NPTEPG); ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index 697b81884f5..d626add4215 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -178,7 +178,7 @@ VECTOR(_locore, unknown) * Initialize stack and call machine startup. */ PTR_LA sp, _C_LABEL(pcpu_space) - addiu sp, (NBPG * 2) - CALLFRAME_SIZ + addiu sp, (PAGE_SIZE * 2) - CALLFRAME_SIZ sw zero, CALLFRAME_SIZ - 4(sp) # Zero out old ra for debugger sw zero, CALLFRAME_SIZ - 8(sp) # Zero out old fp for debugger diff --git a/sys/mips/mips/mpboot.S b/sys/mips/mips/mpboot.S index e1c578a7961..631099c5964 100644 --- a/sys/mips/mips/mpboot.S +++ b/sys/mips/mips/mpboot.S @@ -66,7 +66,7 @@ GLOBAL(mpentry) * Initialize stack and call machine startup */ PTR_LA sp, _C_LABEL(pcpu_space) - addiu sp, (NBPG * 2) - CALLFRAME_SIZ + addiu sp, (PAGE_SIZE * 2) - CALLFRAME_SIZ sll t0, s0, PAGE_SHIFT + 1 addu sp, sp, t0 diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index f1056fdcb46..80418a79f2a 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -609,7 +609,7 @@ pmap_invalidate_page_action(void *arg) pmap->pm_asid[PCPU_GET(cpuid)].gen = 0; return; } - va = pmap_va_asid(pmap, (va & ~PGOFSET)); + va = pmap_va_asid(pmap, (va & ~PAGE_MASK)); mips_TBIS(va); } @@ -765,7 +765,7 @@ pmap_kremove(vm_offset_t va) /* * Write back all caches from the page being destroyed */ - mips_dcache_wbinv_range_index(va, NBPG); + mips_dcache_wbinv_range_index(va, PAGE_SIZE); pte = pmap_pte(kernel_pmap, va); *pte = PTE_G; @@ -1516,7 +1516,7 @@ pmap_remove_page(struct pmap *pmap, vm_offset_t va) /* * Write back all caches from the page being destroyed */ - mips_dcache_wbinv_range_index(va, NBPG); + mips_dcache_wbinv_range_index(va, PAGE_SIZE); /* * get a local va for mappings for this pmap. @@ -1603,7 +1603,7 @@ pmap_remove_all(vm_page_t m) * the page being destroyed */ if (m->md.pv_list_count == 1) - mips_dcache_wbinv_range_index(pv->pv_va, NBPG); + mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); pv->pv_pmap->pm_stats.resident_count--; @@ -1902,8 +1902,8 @@ validate: */ if (!is_kernel_pmap(pmap) && (pmap == &curproc->p_vmspace->vm_pmap) && (prot & VM_PROT_EXECUTE)) { - mips_icache_sync_range(va, NBPG); - mips_dcache_wbinv_range(va, NBPG); + mips_icache_sync_range(va, PAGE_SIZE); + mips_dcache_wbinv_range(va, PAGE_SIZE); } vm_page_unlock_queues(); PMAP_UNLOCK(pmap); @@ -2032,8 +2032,8 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, * unresolvable TLB miss may occur. */ if (pmap == &curproc->p_vmspace->vm_pmap) { va &= ~PAGE_MASK; - mips_icache_sync_range(va, NBPG); - mips_dcache_wbinv_range(va, NBPG); + mips_icache_sync_range(va, PAGE_SIZE); + mips_dcache_wbinv_range(va, PAGE_SIZE); } } return (mpte); @@ -3078,7 +3078,7 @@ pmap_flush_pvcache(vm_page_t m) if (m != NULL) { for (pv = TAILQ_FIRST(&m->md.pv_list); pv; pv = TAILQ_NEXT(pv, pv_list)) { - mips_dcache_wbinv_range_index(pv->pv_va, NBPG); + mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); } } } diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index 2aed3e613fd..d0a06b6d68b 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -210,7 +210,7 @@ END(fillw) * mem_zero_page(addr); */ LEAF(mem_zero_page) - li v0, NBPG + li v0, PAGE_SIZE 1: subu v0, 8 sd zero, 0(a0) diff --git a/sys/mips/mips/tlb.S b/sys/mips/mips/tlb.S index 46a15f81ca4..f6e7934ed3e 100644 --- a/sys/mips/mips/tlb.S +++ b/sys/mips/mips/tlb.S @@ -240,7 +240,7 @@ LEAF(Mips_TLBFlush) # MIPS_KSEG0_START + 2 * i * PAGE_SIZE; # One bogus value for every TLB entry might cause MCHECK exception # - sll t3, t1, PGSHIFT + 1 + sll t3, t1, PAGE_SHIFT + 1 li v0, MIPS_KSEG0_START # invalid address addu v0, t3 /* @@ -299,7 +299,7 @@ LEAF(Mips_TLBFlushAddr) # address calculated by following expression: # MIPS_KSEG0_START + 2 * i * PAGE_SIZE; # One bogus value for every TLB entry might cause MCHECK exception - sll v0, PGSHIFT + 1 + sll v0, PAGE_SHIFT + 1 addu t1, v0 _MTC0 t1, COP_0_TLB_HI # Mark entry high as invalid @@ -482,7 +482,7 @@ LEAF(mips_TBIAP) # MIPS_KSEG0_START + 2 * i * PAGE_SIZE; # One bogus value for every TLB entry might cause MCHECK exception # - sll t3, t1, PGSHIFT + 1 + sll t3, t1, PAGE_SHIFT + 1 li v0, MIPS_KSEG0_START # invalid address addu v0, t3 @@ -507,7 +507,7 @@ LEAF(mips_TBIAP) tlbwi # invalidate the TLB entry 2: addu t1, t1, 1 - addu v0, 1 << (PGSHIFT + 1) + addu v0, 1 << (PAGE_SHIFT + 1) bne t1, t2, 1b nop diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index de4bd01bf29..1e28188330b 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -378,12 +378,12 @@ trap(struct trapframe *trapframe) if (!(pte = pmap_segmap(kernel_pmap, trapframe->badvaddr))) panic("trap: ktlbmod: invalid segmap"); - pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1); + pte += (trapframe->badvaddr >> PAGE_SHIFT) & (NPTEPG - 1); entry = *pte; #ifdef SMP /* It is possible that some other CPU changed m-bit */ if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) { - trapframe->badvaddr &= ~PGOFSET; + trapframe->badvaddr &= ~PAGE_MASK; pmap_update_page(kernel_pmap, trapframe->badvaddr, entry); PMAP_UNLOCK(kernel_pmap); @@ -401,7 +401,7 @@ trap(struct trapframe *trapframe) } entry |= mips_pg_m_bit(); *pte = entry; - trapframe->badvaddr &= ~PGOFSET; + trapframe->badvaddr &= ~PAGE_MASK; pmap_update_page(kernel_pmap, trapframe->badvaddr, entry); pa = mips_tlbpfn_to_paddr(entry); if (!page_is_managed(pa)) @@ -421,12 +421,12 @@ trap(struct trapframe *trapframe) PMAP_LOCK(pmap); if (!(pte = pmap_segmap(pmap, trapframe->badvaddr))) panic("trap: utlbmod: invalid segmap"); - pte += (trapframe->badvaddr >> PGSHIFT) & (NPTEPG - 1); + pte += (trapframe->badvaddr >> PAGE_SHIFT) & (NPTEPG - 1); entry = *pte; #ifdef SMP /* It is possible that some other CPU changed m-bit */ if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) { - trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET); + trapframe->badvaddr = (trapframe->badvaddr & ~PAGE_MASK); pmap_update_page(pmap, trapframe->badvaddr, entry); PMAP_UNLOCK(pmap); goto out; @@ -445,7 +445,7 @@ trap(struct trapframe *trapframe) } entry |= mips_pg_m_bit(); *pte = entry; - trapframe->badvaddr = (trapframe->badvaddr & ~PGOFSET); + trapframe->badvaddr = (trapframe->badvaddr & ~PAGE_MASK); pmap_update_page(pmap, trapframe->badvaddr, entry); trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT); pa = mips_tlbpfn_to_paddr(entry); diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 3b7a1a1b18c..10321dac4bf 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -219,7 +219,7 @@ cpu_thread_swapin(struct thread *td) */ if (!(pte = pmap_segmap(kernel_pmap, td->td_md.md_realstack))) panic("cpu_thread_swapin: invalid segmap"); - pte += ((vm_offset_t)td->td_md.md_realstack >> PGSHIFT) & (NPTEPG - 1); + pte += ((vm_offset_t)td->td_md.md_realstack >> PAGE_SHIFT) & (NPTEPG - 1); for (i = 0; i < KSTACK_PAGES - 1; i++) { td->td_md.md_upte[i] = *pte & ~(PTE_RO|PTE_WIRED); @@ -249,7 +249,7 @@ cpu_thread_alloc(struct thread *td) if (!(pte = pmap_segmap(kernel_pmap, td->td_md.md_realstack))) panic("cpu_thread_alloc: invalid segmap"); - pte += ((vm_offset_t)td->td_md.md_realstack >> PGSHIFT) & (NPTEPG - 1); + pte += ((vm_offset_t)td->td_md.md_realstack >> PAGE_SHIFT) & (NPTEPG - 1); for (i = 0; i < KSTACK_PAGES - 1; i++) { td->td_md.md_upte[i] = *pte & ~(PTE_RO|PTE_WIRED); From a27e66e8f5d73b57c16fa07d19072d353c944d95 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sat, 17 Apr 2010 09:42:07 +0000 Subject: [PATCH 102/532] o) Make pcb_onfault a pointer rather than an obscure integer value. o) Mask off PAGE_MASK bits in pmap_update_page, etc., rather than modifying the badvaddr in trapframe. Some nearby interfaces already did this. o) Make PTEs "unsigned int" for now, not "unsigned long" -- we are only ready for them to be 32-bit on 64-bit platforms. o) Rather than using pmap_segmap and calculating the offset into the page table by hand in trap.c, use pmap_pte(). o) Remove unused quad_syscall variable in trap.c. o) Log things for illegal instructions like we do for bad page faults. o) Various cast cleanups related to how to print registers. o) When logging page faults, show the page table information not just for the program counter, but for the fault address. o) Modify support.S to use ABI-neutral macros for operating on pointers. o) Consistently use CALLFRAME_SIZ rather than STAND_FRAME_SIZE, etc. o) Remove unused insque/remque functions. o) Remove some coprocessor 0 accessor functions implemented in assembly that are unused and have inline assembly counterparts. --- sys/mips/include/cpu.h | 4 - sys/mips/include/pcb.h | 2 +- sys/mips/include/pte.h | 2 +- sys/mips/mips/pmap.c | 8 +- sys/mips/mips/support.S | 670 +++++++++++++++---------------------- sys/mips/mips/trap.c | 319 ++++++++++-------- sys/mips/mips/vm_machdep.c | 2 +- 7 files changed, 459 insertions(+), 548 deletions(-) diff --git a/sys/mips/include/cpu.h b/sys/mips/include/cpu.h index 5c5e5e5e92b..83b6a85fe31 100644 --- a/sys/mips/include/cpu.h +++ b/sys/mips/include/cpu.h @@ -458,13 +458,9 @@ extern union cpuprid fpu_id; struct tlb; struct user; -u_int32_t mips_cp0_config1_read(void); int Mips_ConfigCache(void); void Mips_SetWIRED(int); void Mips_SetPID(int); -u_int Mips_GetCOUNT(void); -void Mips_SetCOMPARE(u_int); -u_int Mips_GetCOMPARE(void); void Mips_SyncCache(void); void Mips_SyncDCache(vm_offset_t, int); diff --git a/sys/mips/include/pcb.h b/sys/mips/include/pcb.h index f95ef4d8d4a..e0982e35f24 100644 --- a/sys/mips/include/pcb.h +++ b/sys/mips/include/pcb.h @@ -51,7 +51,7 @@ struct pcb { struct trapframe pcb_regs; /* saved CPU and registers */ __register_t pcb_context[14]; /* kernel context for resume */ - int pcb_onfault; /* for copyin/copyout faults */ + void *pcb_onfault; /* for copyin/copyout faults */ register_t pcb_tpc; }; diff --git a/sys/mips/include/pte.h b/sys/mips/include/pte.h index 31b08449711..e3b46ca80d5 100644 --- a/sys/mips/include/pte.h +++ b/sys/mips/include/pte.h @@ -83,7 +83,7 @@ struct tlb { int tlb_lo1; }; -typedef unsigned long pt_entry_t; +typedef unsigned int pt_entry_t; typedef pt_entry_t *pd_entry_t; #define PDESIZE sizeof(pd_entry_t) /* for assembly files */ diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 80418a79f2a..6bb38d47e3b 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -660,7 +660,7 @@ pmap_update_page_action(void *arg) pmap->pm_asid[PCPU_GET(cpuid)].gen = 0; return; } - va = pmap_va_asid(pmap, va); + va = pmap_va_asid(pmap, (va & ~PAGE_MASK)); MachTLBUpdate(va, pte); } @@ -669,6 +669,8 @@ pmap_TLB_update_kernel(vm_offset_t va, pt_entry_t pte) { u_int32_t pid; + va &= ~PAGE_MASK; + MachTLBGetPID(pid); va = va | (pid << VMTLB_PID_SHIFT); @@ -1885,7 +1887,7 @@ validate: if (origpte & PTE_M) { KASSERT((origpte & PTE_RW), ("pmap_enter: modified page not writable:" - " va: %p, pte: 0x%lx", (void *)va, origpte)); + " va: %p, pte: 0x%x", (void *)va, origpte)); if (page_is_managed(opa)) vm_page_dirty(om); } @@ -2381,7 +2383,7 @@ pmap_remove_pages(pmap_t pmap) m = PHYS_TO_VM_PAGE(mips_tlbpfn_to_paddr(tpte)); KASSERT(m < &vm_page_array[vm_page_array_size], - ("pmap_remove_pages: bad tpte %lx", tpte)); + ("pmap_remove_pages: bad tpte %x", tpte)); pv->pv_pmap->pm_stats.resident_count--; diff --git a/sys/mips/mips/support.S b/sys/mips/mips/support.S index d0a06b6d68b..9cbc9982293 100644 --- a/sys/mips/mips/support.S +++ b/sys/mips/mips/support.S @@ -103,47 +103,22 @@ * Primitives */ -/* - * This table is indexed by u.u_pcb.pcb_onfault in trap(). - * The reason for using this table rather than storing an address in - * u.u_pcb.pcb_onfault is simply to make the code faster. - */ - .globl onfault_table - .data - .align 3 -onfault_table: - .word 0 # invalid index number -#define BADERR 1 - .word baderr -#define COPYERR 2 - .word copyerr -#define FSWBERR 3 - .word fswberr -#define FSWINTRBERR 4 - .word fswintrberr -#if defined(DDB) || defined(DEBUG) -#define DDBERR 5 - .word ddberr -#else - .word 0 -#endif - .text /* * See if access to addr with a len type instruction causes a machine check. - * len is length of access (1=byte, 2=short, 4=long) + * len is length of access (1=byte, 2=short, 4=int) * * badaddr(addr, len) * char *addr; * int len; */ LEAF(badaddr) - li v0, BADERR + PTR_LA v0, baderr GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) + PTR_L v1, PC_CURPCB(v1) bne a1, 1, 2f - sw v0, U_PCB_ONFAULT(v1) + PTR_S v0, U_PCB_ONFAULT(v1) b 5f lbu v0, (a0) 2: @@ -154,7 +129,7 @@ LEAF(badaddr) 4: lw v0, (a0) 5: - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra move v0, zero # made it w/o errors baderr: @@ -169,24 +144,24 @@ END(badaddr) * string is too long, return ENAMETOOLONG; else return 0. */ LEAF(copystr) - move t0, a2 - beq a2, zero, 4f + move t0, a2 + beq a2, zero, 4f 1: - lbu v0, 0(a0) - subu a2, a2, 1 - beq v0, zero, 2f - sb v0, 0(a1) # each byte until NIL - addu a0, a0, 1 - bne a2, zero, 1b # less than maxlen - addu a1, a1, 1 + lbu v0, 0(a0) + PTR_SUBU a2, a2, 1 + beq v0, zero, 2f + sb v0, 0(a1) # each byte until NIL + PTR_ADDU a0, a0, 1 + bne a2, zero, 1b # less than maxlen + PTR_ADDU a1, a1, 1 4: - li v0, ENAMETOOLONG # run out of space + li v0, ENAMETOOLONG # run out of space 2: - beq a3, zero, 3f # return num. of copied bytes - subu a2, t0, a2 # if the 4th arg was non-NULL - sw a2, 0(a3) + beq a3, zero, 3f # return num. of copied bytes + PTR_SUBU a2, t0, a2 # if the 4th arg was non-NULL + PTR_S a2, 0(a3) 3: - j ra # v0 is 0 or ENAMETOOLONG + j ra # v0 is 0 or ENAMETOOLONG nop END(copystr) @@ -196,12 +171,12 @@ END(copystr) */ LEAF(fillw) 1: - addiu a2, a2, -1 - sh a0, 0(a1) - bne a2,zero, 1b - addiu a1, a1, 2 + PTR_ADDU a2, a2, -1 + sh a0, 0(a1) + bne a2,zero, 1b + PTR_ADDU a1, a1, 2 - jr ra + jr ra nop END(fillw) @@ -210,13 +185,13 @@ END(fillw) * mem_zero_page(addr); */ LEAF(mem_zero_page) - li v0, PAGE_SIZE + li v0, PAGE_SIZE 1: - subu v0, 8 - sd zero, 0(a0) - bne zero, v0, 1b - addu a0, 8 - jr ra + PTR_SUBU v0, 8 + sd zero, 0(a0) + bne zero, v0, 1b + PTR_ADDU a0, 8 + jr ra nop END(mem_zero_page) @@ -228,56 +203,56 @@ END(mem_zero_page) * a2 = count */ LEAF(insb) - beq a2, zero, 2f - addu a2, a1 + beq a2, zero, 2f + PTR_ADDU a2, a1 1: - lbu v0, 0(a0) - addiu a1, 1 - bne a1, a2, 1b - sb v0, -1(a1) + lbu v0, 0(a0) + PTR_ADDU a1, 1 + bne a1, a2, 1b + sb v0, -1(a1) 2: - jr ra + jr ra nop END(insb) LEAF(insw) - beq a2, zero, 2f - addu a2, a2 - addu a2, a1 + beq a2, zero, 2f + PTR_ADDU a2, a2 + PTR_ADDU a2, a1 1: - lhu v0, 0(a0) - addiu a1, 2 - bne a1, a2, 1b - sh v0, -2(a1) + lhu v0, 0(a0) + PTR_ADDU a1, 2 + bne a1, a2, 1b + sh v0, -2(a1) 2: - jr ra + jr ra nop END(insw) LEAF(insl) - beq a2, zero, 2f - sll a2, 2 - addu a2, a1 + beq a2, zero, 2f + sll a2, 2 + PTR_ADDU a2, a1 1: - lw v0, 0(a0) - addiu a1, 4 - bne a1, a2, 1b - sw v0, -4(a1) + lw v0, 0(a0) + PTR_ADDU a1, 4 + bne a1, a2, 1b + sw v0, -4(a1) 2: - jr ra + jr ra nop END(insl) LEAF(outsb) - beq a2, zero, 2f - addu a2, a1 + beq a2, zero, 2f + PTR_ADDU a2, a1 1: - lbu v0, 0(a1) - addiu a1, 1 - bne a1, a2, 1b - sb v0, 0(a0) + lbu v0, 0(a1) + PTR_ADDU a1, 1 + bne a1, a2, 1b + sb v0, 0(a0) 2: - jr ra + jr ra nop END(outsb) @@ -343,22 +318,22 @@ END(outsl) * u_int maxlength; * u_int *lencopied; */ -NON_LEAF(copyinstr, STAND_FRAME_SIZE, ra) - subu sp, sp, STAND_FRAME_SIZE - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) - sw ra, STAND_RA_OFFSET(sp) +NON_LEAF(copyinstr, CALLFRAME_SIZ, ra) + PTR_SUBU sp, sp, CALLFRAME_SIZ + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + PTR_LA v0, copyerr blt a0, zero, _C_LABEL(copyerr) # make sure address is in user space - li v0, COPYERR + REG_S ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) + PTR_L v1, PC_CURPCB(v1) jal _C_LABEL(copystr) - sw v0, U_PCB_ONFAULT(v1) - lw ra, STAND_RA_OFFSET(sp) + PTR_S v0, U_PCB_ONFAULT(v1) + REG_L ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw zero, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra - addu sp, sp, STAND_FRAME_SIZE + PTR_ADDU sp, sp, CALLFRAME_SIZ END(copyinstr) /* @@ -371,22 +346,22 @@ END(copyinstr) * u_int maxlength; * u_int *lencopied; */ -NON_LEAF(copyoutstr, STAND_FRAME_SIZE, ra) - subu sp, sp, STAND_FRAME_SIZE - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) - sw ra, STAND_RA_OFFSET(sp) +NON_LEAF(copyoutstr, CALLFRAME_SIZ, ra) + PTR_SUBU sp, sp, CALLFRAME_SIZ + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + PTR_LA v0, copyerr blt a1, zero, _C_LABEL(copyerr) # make sure address is in user space - li v0, COPYERR + REG_S ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) + PTR_L v1, PC_CURPCB(v1) jal _C_LABEL(copystr) - sw v0, U_PCB_ONFAULT(v1) - lw ra, STAND_RA_OFFSET(sp) + PTR_S v0, U_PCB_ONFAULT(v1) + REG_L ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw zero, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra - addu sp, sp, STAND_FRAME_SIZE + PTR_ADDU sp, sp, CALLFRAME_SIZ END(copyoutstr) /* @@ -396,21 +371,21 @@ END(copyoutstr) * caddr_t *to; (kernel destination address) * unsigned len; */ -NON_LEAF(copyin, STAND_FRAME_SIZE, ra) - subu sp, sp, STAND_FRAME_SIZE - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) - sw ra, STAND_RA_OFFSET(sp) +NON_LEAF(copyin, CALLFRAME_SIZ, ra) + PTR_SUBU sp, sp, CALLFRAME_SIZ + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + PTR_LA v0, copyerr blt a0, zero, _C_LABEL(copyerr) # make sure address is in user space - li v0, COPYERR + REG_S ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) + PTR_L v1, PC_CURPCB(v1) jal _C_LABEL(bcopy) - sw v0, U_PCB_ONFAULT(v1) - lw ra, STAND_RA_OFFSET(sp) + PTR_S v0, U_PCB_ONFAULT(v1) + REG_L ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) # bcopy modified v1, so reload - sw zero, U_PCB_ONFAULT(v1) - addu sp, sp, STAND_FRAME_SIZE + PTR_L v1, PC_CURPCB(v1) # bcopy modified v1, so reload + PTR_S zero, U_PCB_ONFAULT(v1) + PTR_ADDU sp, sp, CALLFRAME_SIZ j ra move v0, zero END(copyin) @@ -422,31 +397,28 @@ END(copyin) * caddr_t *to; (user destination address) * unsigned len; */ -NON_LEAF(copyout, STAND_FRAME_SIZE, ra) - subu sp, sp, STAND_FRAME_SIZE - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) - sw ra, STAND_RA_OFFSET(sp) +NON_LEAF(copyout, CALLFRAME_SIZ, ra) + PTR_SUBU sp, sp, CALLFRAME_SIZ + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) + PTR_LA v0, copyerr blt a1, zero, _C_LABEL(copyerr) # make sure address is in user space - li v0, COPYERR + REG_S ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) + PTR_L v1, PC_CURPCB(v1) jal _C_LABEL(bcopy) - sw v0, U_PCB_ONFAULT(v1) - lw ra, STAND_RA_OFFSET(sp) + PTR_S v0, U_PCB_ONFAULT(v1) + REG_L ra, CALLFRAME_RA(sp) GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) # bcopy modified v1, so reload - sw zero, U_PCB_ONFAULT(v1) - addu sp, sp, STAND_FRAME_SIZE + PTR_L v1, PC_CURPCB(v1) # bcopy modified v1, so reload + PTR_S zero, U_PCB_ONFAULT(v1) + PTR_ADDU sp, sp, CALLFRAME_SIZ j ra move v0, zero END(copyout) LEAF(copyerr) - lw ra, STAND_RA_OFFSET(sp) - GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw zero, U_PCB_ONFAULT(v1) - addu sp, sp, STAND_FRAME_SIZE + REG_L ra, CALLFRAME_RA(sp) + PTR_ADDU sp, sp, CALLFRAME_SIZ j ra li v0, EFAULT # return error END(copyerr) @@ -460,51 +432,55 @@ END(copyerr) LEAF(fuword) ALEAF(fuword32) ALEAF(fuiword) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) lw v0, 0(a0) # fetch word j ra - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) END(fuword) LEAF(fusword) ALEAF(fuisword) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) lhu v0, 0(a0) # fetch short j ra - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) END(fusword) LEAF(fubyte) ALEAF(fuibyte) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) lbu v0, 0(a0) # fetch byte j ra - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) END(fubyte) LEAF(suword32) #ifndef __mips_n64 XLEAF(suword) #endif + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) sw a1, 0(a0) # store word - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra move v0, zero END(suword32) @@ -512,13 +488,14 @@ END(suword32) #ifdef __mips_n64 LEAF(suword64) XLEAF(suword) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) sd a1, 0(a0) # store word - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra move v0, zero END(suword64) @@ -537,11 +514,12 @@ LEAF(casuword32) #ifndef __mips_n64 XLEAF(casuword) #endif + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) 1: move t0, a2 ll v0, 0(a0) @@ -555,7 +533,7 @@ XLEAF(casuword) 2: li v0, -1 3: - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) jr ra nop END(casuword32) @@ -563,11 +541,12 @@ END(casuword32) #ifdef __mips_n64 LEAF(casuword64) XLEAF(casuword) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) 1: move t0, a2 lld v0, 0(a0) @@ -581,7 +560,7 @@ XLEAF(casuword) 2: li v0, -1 3: - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) jr ra nop END(casuword64) @@ -593,13 +572,14 @@ END(casuword64) * Have to flush instruction cache afterwards. */ LEAF(suiword) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) sw a1, 0(a0) # store word - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j _C_LABEL(Mips_SyncICache) # FlushICache sets v0 = 0. (Ugly) li a1, 4 # size of word END(suiword) @@ -610,26 +590,28 @@ END(suiword) */ LEAF(susword) ALEAF(suisword) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) sh a1, 0(a0) # store short - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra move v0, zero END(susword) LEAF(subyte) ALEAF(suibyte) + PTR_LA v0, fswberr blt a0, zero, fswberr # make sure address is in user space - li v0, FSWBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) sb a1, 0(a0) # store byte - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra move v0, zero END(subyte) @@ -645,24 +627,26 @@ END(fswberr) * The important thing is to prevent sleep() and switch(). */ LEAF(fuswintr) + PTR_LA v0, fswintrberr blt a0, zero, fswintrberr # make sure address is in user space - li v0, FSWINTRBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) lhu v0, 0(a0) # fetch short j ra - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) END(fuswintr) LEAF(suswintr) + PTR_LA v0, fswintrberr blt a0, zero, fswintrberr # make sure address is in user space - li v0, FSWINTRBERR + nop GET_CPU_PCPU(v1) - lw v1, PC_CURPCB(v1) - sw v0, U_PCB_ONFAULT(v1) + PTR_L v1, PC_CURPCB(v1) + PTR_S v0, U_PCB_ONFAULT(v1) sh a1, 0(a0) # store short - sw zero, U_PCB_ONFAULT(v1) + PTR_S zero, U_PCB_ONFAULT(v1) j ra move v0, zero END(suswintr) @@ -672,111 +656,6 @@ LEAF(fswintrberr) li v0, -1 END(fswintrberr) -/* - * Insert 'p' after 'q'. - * _insque(p, q) - * caddr_t p, q; - */ -LEAF(_insque) - lw v0, 0(a1) # v0 = q->next - sw a1, 4(a0) # p->prev = q - sw v0, 0(a0) # p->next = q->next - sw a0, 4(v0) # q->next->prev = p - j ra - sw a0, 0(a1) # q->next = p -END(_insque) - -/* - * Remove item 'p' from queue. - * _remque(p) - * caddr_t p; - */ -LEAF(_remque) - lw v0, 0(a0) # v0 = p->next - lw v1, 4(a0) # v1 = p->prev - nop - sw v0, 0(v1) # p->prev->next = p->next - j ra - sw v1, 4(v0) # p->next->prev = p->prev -END(_remque) - -/*-------------------------------------------------------------------------- - * - * Mips_GetCOUNT -- - * - * Mips_GetCOUNT() - * - * Results: - * Returns the current COUNT reg. - * - * Side effects: - * None. - * - *-------------------------------------------------------------------------- - */ -LEAF(Mips_GetCOUNT) - mfc0 v0, COP_0_COUNT - nop #??? - nop #??? - j ra - nop -END(Mips_GetCOUNT) - -/*-------------------------------------------------------------------------- - * - * Mips_SetCOMPARE -- - * - * Mips_SetCOMPARE() - * - * Results: - * Sets a new value to the COMPARE register. - * - * Side effects: - * The COMPARE equal interrupt is acknowledged. - * - *-------------------------------------------------------------------------- - */ -LEAF(Mips_SetCOMPARE) - mtc0 a0, COP_0_COMPARE - j ra - nop -END(Mips_SetCOMPARE) - -LEAF(Mips_GetCOMPARE) - mfc0 v0, COP_0_COMPARE - j ra - nop -END(Mips_GetCOMPARE) - -/* - * u_int32_t mips_cp0_status_read(void) - * - * Return the current value of the CP0 Status register. - */ -LEAF(mips_cp0_status_read) - mfc0 v0, COP_0_STATUS_REG - j ra - nop -END(mips_cp0_status_read) - -/* - * void mips_cp0_status_write(u_int32_t) - * - * Set the value of the CP0 Status register. - * - * Note: This is almost certainly not the way you want to write a - * "permanent" value to to the CP0 Status register, since it gets - * saved in trap frames and restores. - */ -LEAF(mips_cp0_status_write) - mtc0 a0, COP_0_STATUS_REG - nop - nop - j ra - nop -END(mips_cp0_status_write) - - /* * memcpy(to, from, len) * {ov}bcopy(from, to, len) @@ -789,7 +668,7 @@ LEAF(memcpy) ALEAF(bcopy) ALEAF(ovbcopy) .set noreorder - addu t0, a0, a2 # t0 = end of s1 region + PTR_ADDU t0, a0, a2 # t0 = end of s1 region sltu t1, a1, t0 sltu t2, a0, a1 and t1, t1, t2 # t1 = true if from < to < (from+len) @@ -797,11 +676,11 @@ ALEAF(ovbcopy) slt t2, a2, 12 # check for small copy ble a2, zero, 2f - addu t1, a1, a2 # t1 = end of to region + PTR_ADDU t1, a1, a2 # t1 = end of to region 1: lb v1, -1(t0) # copy bytes backwards, - subu t0, t0, 1 # doesnt happen often so do slow way - subu t1, t1, 1 + PTR_SUBU t0, t0, 1 # doesnt happen often so do slow way + PTR_SUBU t1, t1, 1 bne t0, a0, 1b sb v1, 0(t1) 2: @@ -811,59 +690,59 @@ forward: bne t2, zero, smallcpy # do a small bcopy xor v1, a0, a1 # compare low two bits of addresses and v1, v1, 3 - subu a3, zero, a1 # compute # bytes to word align address + PTR_SUBU a3, zero, a1 # compute # bytes to word align address beq v1, zero, aligned # addresses can be word aligned and a3, a3, 3 beq a3, zero, 1f - subu a2, a2, a3 # subtract from remaining count + PTR_SUBU a2, a2, a3 # subtract from remaining count LWHI v1, 0(a0) # get next 4 bytes (unaligned) LWLO v1, 3(a0) - addu a0, a0, a3 + PTR_ADDU a0, a0, a3 SWHI v1, 0(a1) # store 1, 2, or 3 bytes to align a1 - addu a1, a1, a3 + PTR_ADDU a1, a1, a3 1: and v1, a2, 3 # compute number of words left - subu a3, a2, v1 + PTR_SUBU a3, a2, v1 move a2, v1 - addu a3, a3, a0 # compute ending address + PTR_ADDU a3, a3, a0 # compute ending address 2: LWHI v1, 0(a0) # copy words a0 unaligned, a1 aligned LWLO v1, 3(a0) - addu a0, a0, 4 + PTR_ADDU a0, a0, 4 sw v1, 0(a1) - addu a1, a1, 4 + PTR_ADDU a1, a1, 4 bne a0, a3, 2b nop # We have to do this mmu-bug. b smallcpy nop aligned: beq a3, zero, 1f - subu a2, a2, a3 # subtract from remaining count + PTR_SUBU a2, a2, a3 # subtract from remaining count LWHI v1, 0(a0) # copy 1, 2, or 3 bytes to align - addu a0, a0, a3 + PTR_ADDU a0, a0, a3 SWHI v1, 0(a1) - addu a1, a1, a3 + PTR_ADDU a1, a1, a3 1: and v1, a2, 3 # compute number of whole words left - subu a3, a2, v1 + PTR_SUBU a3, a2, v1 move a2, v1 - addu a3, a3, a0 # compute ending address + PTR_ADDU a3, a3, a0 # compute ending address 2: lw v1, 0(a0) # copy words - addu a0, a0, 4 + PTR_ADDU a0, a0, 4 sw v1, 0(a1) bne a0, a3, 2b - addu a1, a1, 4 + PTR_ADDU a1, a1, 4 smallcpy: ble a2, zero, 2f - addu a3, a2, a0 # compute ending address + PTR_ADDU a3, a2, a0 # compute ending address 1: lbu v1, 0(a0) # copy bytes - addu a0, a0, 1 + PTR_ADDU a0, a0, 1 sb v1, 0(a1) bne a0, a3, 1b - addu a1, a1, 1 # MMU BUG ? can not do -1(a1) at 0x80000000!! + PTR_ADDU a1, a1, 1 # MMU BUG ? can not do -1(a1) at 0x80000000!! 2: j ra nop @@ -883,19 +762,19 @@ LEAF(memset) sll t2, t1, 16 # shift that left 16 or t1, t2, t1 # or together - subu t0, zero, a0 # compute # bytes to word align address + PTR_SUBU t0, zero, a0 # compute # bytes to word align address and t0, t0, 3 beq t0, zero, 1f # skip if word aligned - subu a2, a2, t0 # subtract from remaining count + PTR_SUBU a2, a2, t0 # subtract from remaining count SWHI t1, 0(a0) # store 1, 2, or 3 bytes to align - addu a0, a0, t0 + PTR_ADDU a0, a0, t0 1: and v1, a2, 3 # compute number of whole words left - subu t0, a2, v1 - subu a2, a2, t0 - addu t0, t0, a0 # compute ending address + PTR_SUBU t0, a2, v1 + PTR_SUBU a2, a2, t0 + PTR_ADDU t0, t0, a0 # compute ending address 2: - addu a0, a0, 4 # clear words + PTR_ADDU a0, a0, 4 # clear words #ifdef MIPS3_5900 nop nop @@ -907,9 +786,9 @@ LEAF(memset) memsetsmallclr: ble a2, zero, 2f - addu t0, a2, a0 # compute ending address + PTR_ADDU t0, a2, a0 # compute ending address 1: - addu a0, a0, 1 # clear bytes + PTR_ADDU a0, a0, 1 # clear bytes #ifdef MIPS3_5900 nop nop @@ -931,26 +810,26 @@ LEAF(bzero) ALEAF(blkclr) .set noreorder blt a1, 12, smallclr # small amount to clear? - subu a3, zero, a0 # compute # bytes to word align address + PTR_SUBU a3, zero, a0 # compute # bytes to word align address and a3, a3, 3 beq a3, zero, 1f # skip if word aligned - subu a1, a1, a3 # subtract from remaining count + PTR_SUBU a1, a1, a3 # subtract from remaining count SWHI zero, 0(a0) # clear 1, 2, or 3 bytes to align - addu a0, a0, a3 + PTR_ADDU a0, a0, a3 1: and v0, a1, 3 # compute number of words left - subu a3, a1, v0 + PTR_SUBU a3, a1, v0 move a1, v0 - addu a3, a3, a0 # compute ending address + PTR_ADDU a3, a3, a0 # compute ending address 2: - addu a0, a0, 4 # clear words + PTR_ADDU a0, a0, 4 # clear words bne a0, a3, 2b # unrolling loop does not help sw zero, -4(a0) # since we are limited by memory speed smallclr: ble a1, zero, 2f - addu a3, a1, a0 # compute ending address + PTR_ADDU a3, a1, a0 # compute ending address 1: - addu a0, a0, 1 # clear bytes + PTR_ADDU a0, a0, 1 # clear bytes bne a0, a3, 1b sb zero, -1(a0) 2: @@ -967,66 +846,66 @@ LEAF(bcmp) blt a2, 16, smallcmp # is it worth any trouble? xor v0, a0, a1 # compare low two bits of addresses and v0, v0, 3 - subu a3, zero, a1 # compute # bytes to word align address + PTR_SUBU a3, zero, a1 # compute # bytes to word align address bne v0, zero, unalignedcmp # not possible to align addresses and a3, a3, 3 beq a3, zero, 1f - subu a2, a2, a3 # subtract from remaining count + PTR_SUBU a2, a2, a3 # subtract from remaining count move v0, v1 # init v0,v1 so unmodified bytes match LWHI v0, 0(a0) # read 1, 2, or 3 bytes LWHI v1, 0(a1) - addu a1, a1, a3 + PTR_ADDU a1, a1, a3 bne v0, v1, nomatch - addu a0, a0, a3 + PTR_ADDU a0, a0, a3 1: and a3, a2, ~3 # compute number of whole words left - subu a2, a2, a3 # which has to be >= (16-3) & ~3 - addu a3, a3, a0 # compute ending address + PTR_SUBU a2, a2, a3 # which has to be >= (16-3) & ~3 + PTR_ADDU a3, a3, a0 # compute ending address 2: lw v0, 0(a0) # compare words lw v1, 0(a1) - addu a0, a0, 4 + PTR_ADDU a0, a0, 4 bne v0, v1, nomatch - addu a1, a1, 4 + PTR_ADDU a1, a1, 4 bne a0, a3, 2b nop b smallcmp # finish remainder nop unalignedcmp: beq a3, zero, 2f - subu a2, a2, a3 # subtract from remaining count - addu a3, a3, a0 # compute ending address + PTR_SUBU a2, a2, a3 # subtract from remaining count + PTR_ADDU a3, a3, a0 # compute ending address 1: lbu v0, 0(a0) # compare bytes until a1 word aligned lbu v1, 0(a1) - addu a0, a0, 1 + PTR_ADDU a0, a0, 1 bne v0, v1, nomatch - addu a1, a1, 1 + PTR_ADDU a1, a1, 1 bne a0, a3, 1b nop 2: and a3, a2, ~3 # compute number of whole words left - subu a2, a2, a3 # which has to be >= (16-3) & ~3 - addu a3, a3, a0 # compute ending address + PTR_SUBU a2, a2, a3 # which has to be >= (16-3) & ~3 + PTR_ADDU a3, a3, a0 # compute ending address 3: LWHI v0, 0(a0) # compare words a0 unaligned, a1 aligned LWLO v0, 3(a0) lw v1, 0(a1) - addu a0, a0, 4 + PTR_ADDU a0, a0, 4 bne v0, v1, nomatch - addu a1, a1, 4 + PTR_ADDU a1, a1, 4 bne a0, a3, 3b nop smallcmp: ble a2, zero, match - addu a3, a2, a0 # compute ending address + PTR_ADDU a3, a2, a0 # compute ending address 1: lbu v0, 0(a0) lbu v1, 0(a1) - addu a0, a0, 1 + PTR_ADDU a0, a0, 1 bne v0, v1, nomatch - addu a1, a1, 1 + PTR_ADDU a1, a1, 1 bne a0, a3, 1b nop match: @@ -1367,9 +1246,6 @@ END(atomic_subtract_8) */ .set noreorder # Noreorder is default style! -#ifndef _MIPS_ARCH_XLR - .set mips3 -#endif #if !defined(__mips_n64) && !defined(__mips_n32) /* @@ -1426,22 +1302,22 @@ END(atomic_load_64) #if defined(DDB) || defined(DEBUG) LEAF(kdbpeek) - li v1, DDBERR + PTR_LA v1, ddberr and v0, a0, 3 # unaligned ? GET_CPU_PCPU(t1) - lw t1, PC_CURPCB(t1) + PTR_L t1, PC_CURPCB(t1) bne v0, zero, 1f - sw v1, U_PCB_ONFAULT(t1) + PTR_S v1, U_PCB_ONFAULT(t1) lw v0, (a0) jr ra - sw zero, U_PCB_ONFAULT(t1) + PTR_S zero, U_PCB_ONFAULT(t1) 1: LWHI v0, 0(a0) LWLO v0, 3(a0) jr ra - sw zero, U_PCB_ONFAULT(t1) + PTR_S zero, U_PCB_ONFAULT(t1) END(kdbpeek) ddberr: @@ -1450,44 +1326,31 @@ ddberr: #if defined(DDB) LEAF(kdbpoke) - li v1, DDBERR + PTR_LA v1, ddberr and v0, a0, 3 # unaligned ? GET_CPU_PCPU(t1) - lw t1, PC_CURPCB(t1) + PTR_L t1, PC_CURPCB(t1) bne v0, zero, 1f - sw v1, U_PCB_ONFAULT(t1) + PTR_S v1, U_PCB_ONFAULT(t1) sw a1, (a0) jr ra - sw zero, U_PCB_ONFAULT(t1) + PTR_S zero, U_PCB_ONFAULT(t1) 1: SWHI a1, 0(a0) SWLO a1, 3(a0) jr ra - sw zero, U_PCB_ONFAULT(t1) + PTR_S zero, U_PCB_ONFAULT(t1) END(kdbpoke) .data .globl esym esym: .word 0 -#ifndef _MIPS_ARCH_XLR - .set mips2 -#endif #endif /* DDB */ #endif /* DDB || DEBUG */ -#ifndef MIPS_ISAIII -#define STORE sw /* 32 bit mode regsave instruction */ -#define LOAD lw /* 32 bit mode regload instruction */ -#define RSIZE 4 /* 32 bit mode register size */ -#else -#define STORE sd /* 64 bit mode regsave instruction */ -#define LOAD ld /* 64 bit mode regload instruction */ -#define RSIZE 8 /* 64 bit mode register size */ -#endif - #define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; .text @@ -1499,35 +1362,35 @@ LEAF(breakpoint) LEAF(setjmp) mfc0 v0, COP_0_STATUS_REG # Later the "real" spl value! - STORE s0, (RSIZE * PREG_S0)(a0) - STORE s1, (RSIZE * PREG_S1)(a0) - STORE s2, (RSIZE * PREG_S2)(a0) - STORE s3, (RSIZE * PREG_S3)(a0) - STORE s4, (RSIZE * PREG_S4)(a0) - STORE s5, (RSIZE * PREG_S5)(a0) - STORE s6, (RSIZE * PREG_S6)(a0) - STORE s7, (RSIZE * PREG_S7)(a0) - STORE s8, (RSIZE * PREG_S8)(a0) - STORE sp, (RSIZE * PREG_SP)(a0) - STORE ra, (RSIZE * PREG_RA)(a0) - STORE v0, (RSIZE * PREG_SR)(a0) + REG_S s0, (SZREG * PREG_S0)(a0) + REG_S s1, (SZREG * PREG_S1)(a0) + REG_S s2, (SZREG * PREG_S2)(a0) + REG_S s3, (SZREG * PREG_S3)(a0) + REG_S s4, (SZREG * PREG_S4)(a0) + REG_S s5, (SZREG * PREG_S5)(a0) + REG_S s6, (SZREG * PREG_S6)(a0) + REG_S s7, (SZREG * PREG_S7)(a0) + REG_S s8, (SZREG * PREG_S8)(a0) + REG_S sp, (SZREG * PREG_SP)(a0) + REG_S ra, (SZREG * PREG_RA)(a0) + REG_S v0, (SZREG * PREG_SR)(a0) jr ra li v0, 0 # setjmp return END(setjmp) LEAF(longjmp) - LOAD v0, (RSIZE * PREG_SR)(a0) - LOAD ra, (RSIZE * PREG_RA)(a0) - LOAD s0, (RSIZE * PREG_S0)(a0) - LOAD s1, (RSIZE * PREG_S1)(a0) - LOAD s2, (RSIZE * PREG_S2)(a0) - LOAD s3, (RSIZE * PREG_S3)(a0) - LOAD s4, (RSIZE * PREG_S4)(a0) - LOAD s5, (RSIZE * PREG_S5)(a0) - LOAD s6, (RSIZE * PREG_S6)(a0) - LOAD s7, (RSIZE * PREG_S7)(a0) - LOAD s8, (RSIZE * PREG_S8)(a0) - LOAD sp, (RSIZE * PREG_SP)(a0) + REG_L v0, (SZREG * PREG_SR)(a0) + REG_L ra, (SZREG * PREG_RA)(a0) + REG_L s0, (SZREG * PREG_S0)(a0) + REG_L s1, (SZREG * PREG_S1)(a0) + REG_L s2, (SZREG * PREG_S2)(a0) + REG_L s3, (SZREG * PREG_S3)(a0) + REG_L s4, (SZREG * PREG_S4)(a0) + REG_L s5, (SZREG * PREG_S5)(a0) + REG_L s6, (SZREG * PREG_S6)(a0) + REG_L s7, (SZREG * PREG_S7)(a0) + REG_L s8, (SZREG * PREG_S8)(a0) + REG_L sp, (SZREG * PREG_SP)(a0) mtc0 v0, COP_0_STATUS_REG # Later the "real" spl value! ITLBNOPFIX jr ra @@ -1538,7 +1401,6 @@ LEAF(fusufault) GET_CPU_PCPU(t0) lw t0, PC_CURTHREAD(t0) lw t0, TD_PCB(t0) - sw zero, U_PCB_ONFAULT(t0) li v0, -1 j ra END(fusufault) @@ -1547,8 +1409,7 @@ END(fusufault) a pointer that is in user space. It will be used as the basic primitive for a kernel supported user space lock implementation. */ LEAF(casuptr) - - li t0, VM_MAXUSER_ADDRESS /* verify address validity */ + PTR_LI t0, VM_MAXUSER_ADDRESS /* verify address validity */ blt a0, t0, fusufault /* trap faults */ nop @@ -1556,8 +1417,8 @@ LEAF(casuptr) lw t1, PC_CURTHREAD(t1) lw t1, TD_PCB(t1) - lw t2, fusufault - sw t2, U_PCB_ONFAULT(t1) + PTR_LA t2, fusufault + PTR_S t2, U_PCB_ONFAULT(t1) 1: ll v0, 0(a0) /* try to load the old value */ beq v0, a1, 2f /* compare */ @@ -1565,7 +1426,7 @@ LEAF(casuptr) sc t0, 0(a0) /* write if address still locked */ beq t0, zero, 1b /* if it failed, spin */ 2: - sw zero, U_PCB_ONFAULT(t1) /* clean up */ + PTR_S zero, U_PCB_ONFAULT(t1) /* clean up */ j ra END(casuptr) @@ -1593,7 +1454,7 @@ END(octeon_get_shadow) * octeon_set_control(addr, uint32_t val) */ LEAF(octeon_set_control) - .set mips64r2 + .set push or t1, a1, zero /* dmfc0 a1, 9, 7*/ .word 0x40254807 @@ -1603,20 +1464,21 @@ LEAF(octeon_set_control) .word 0x40a54807 jr ra nop - .set mips0 + .set pop END(octeon_set_control) /* * octeon_get_control(addr) */ LEAF(octeon_get_control) + .set push .set mips64r2 /* dmfc0 a1, 9, 7 */ .word 0x40254807 sd a1, 0(a0) jr ra nop - .set mips0 + .set pop END(octeon_get_control) #endif diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 1e28188330b..17a6be5e7fd 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -99,8 +99,7 @@ __FBSDID("$FreeBSD$"); int trap_debug = 1; #endif -extern unsigned onfault_table[]; - +static void log_illegal_instruction(const char *, struct trapframe *); static void log_bad_page_fault(char *, struct trapframe *, int); static void log_frame_dump(struct trapframe *frame); static void get_mapping_info(vm_offset_t, pd_entry_t **, pt_entry_t **); @@ -226,8 +225,8 @@ void stacktrace(struct trapframe *); void logstacktrace(struct trapframe *); #endif -#define KERNLAND(x) ((int)(x) < 0) -#define DELAYBRANCH(x) ((int)(x) < 0) +#define KERNLAND(x) ((vm_offset_t)(x) >= VM_MIN_KERNEL_ADDRESS && (vm_offset_t)(x) < VM_MAX_KERNEL_ADDRESS) +#define DELAYBRANCH(x) ((int)(x) < 0) /* * MIPS load/store access type @@ -263,6 +262,7 @@ SYSCTL_INT(_vm, OID_AUTO, allow_unaligned_acc, CTLFLAG_RW, static int emulate_unaligned_access(struct trapframe *frame); extern char *syscallnames[]; +extern void fswintrberr(void); /* XXX */ /* * Handle an exception. @@ -281,13 +281,12 @@ trap(struct trapframe *trapframe) struct proc *p = curproc; vm_prot_t ftype; pt_entry_t *pte; - unsigned int entry; pmap_t pmap; - int quad_syscall = 0; int access_type; ksiginfo_t ksi; char *msg = NULL; - register_t addr = 0; + intptr_t addr = 0; + register_t pc; trapdebug_enter(trapframe, 0); @@ -330,9 +329,9 @@ trap(struct trapframe *trapframe) printf("cpuid = %d\n", PCPU_GET(cpuid)); #endif MachTLBGetPID(pid); - printf("badaddr = 0x%0x, pc = 0x%0x, ra = 0x%0x, sp = 0x%0x, sr = 0x%x, pid = %d, ASID = 0x%x\n", - trapframe->badvaddr, trapframe->pc, trapframe->ra, - trapframe->sp, trapframe->sr, + printf("badaddr = %#jx, pc = %#jx, ra = %#jx, sp = %#jx, sr = %jx, pid = %d, ASID = %u\n", + (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra, + (intmax_t)trapframe->sp, (intmax_t)trapframe->sr, (curproc ? curproc->p_pid : -1), pid); switch (type & ~T_USER) { @@ -354,7 +353,7 @@ trap(struct trapframe *trapframe) ((type & ~T_USER) != T_SYSCALL)) { if (++count == 3) { trap_frame_dump(trapframe); - panic("too many faults at %x\n", last_badvaddr); + panic("too many faults at %p\n", (void *)last_badvaddr); } } else { last_badvaddr = this_badvaddr; @@ -375,35 +374,30 @@ trap(struct trapframe *trapframe) vm_offset_t pa; PMAP_LOCK(kernel_pmap); - if (!(pte = pmap_segmap(kernel_pmap, - trapframe->badvaddr))) - panic("trap: ktlbmod: invalid segmap"); - pte += (trapframe->badvaddr >> PAGE_SHIFT) & (NPTEPG - 1); - entry = *pte; + pte = pmap_pte(kernel_pmap, trapframe->badvaddr); + if (pte == NULL) + panic("trap: ktlbmod: can't find PTE"); #ifdef SMP /* It is possible that some other CPU changed m-bit */ - if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) { - trapframe->badvaddr &= ~PAGE_MASK; + if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) { pmap_update_page(kernel_pmap, - trapframe->badvaddr, entry); + trapframe->badvaddr, *pte); PMAP_UNLOCK(kernel_pmap); return (trapframe->pc); } #else - if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) + if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) panic("trap: ktlbmod: invalid pte"); #endif - if (entry & mips_pg_ro_bit()) { + if (*pte & mips_pg_ro_bit()) { /* write to read only page in the kernel */ ftype = VM_PROT_WRITE; PMAP_UNLOCK(kernel_pmap); goto kernel_fault; } - entry |= mips_pg_m_bit(); - *pte = entry; - trapframe->badvaddr &= ~PAGE_MASK; - pmap_update_page(kernel_pmap, trapframe->badvaddr, entry); - pa = mips_tlbpfn_to_paddr(entry); + *pte |= mips_pg_m_bit(); + pmap_update_page(kernel_pmap, trapframe->badvaddr, *pte); + pa = mips_tlbpfn_to_paddr(*pte); if (!page_is_managed(pa)) panic("trap: ktlbmod: unmanaged page"); pmap_set_modified(pa); @@ -419,36 +413,30 @@ trap(struct trapframe *trapframe) pmap = &p->p_vmspace->vm_pmap; PMAP_LOCK(pmap); - if (!(pte = pmap_segmap(pmap, trapframe->badvaddr))) - panic("trap: utlbmod: invalid segmap"); - pte += (trapframe->badvaddr >> PAGE_SHIFT) & (NPTEPG - 1); - entry = *pte; + pte = pmap_pte(pmap, trapframe->badvaddr); + if (pte == NULL) + panic("trap: utlbmod: can't find PTE"); #ifdef SMP /* It is possible that some other CPU changed m-bit */ - if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) { - trapframe->badvaddr = (trapframe->badvaddr & ~PAGE_MASK); - pmap_update_page(pmap, trapframe->badvaddr, entry); + if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) { + pmap_update_page(pmap, trapframe->badvaddr, *pte); PMAP_UNLOCK(pmap); goto out; } #else - if (!mips_pg_v(entry) || (entry & mips_pg_m_bit())) { + if (!mips_pg_v(*pte) || (*pte & mips_pg_m_bit())) panic("trap: utlbmod: invalid pte"); - } #endif - if (entry & mips_pg_ro_bit()) { + if (*pte & mips_pg_ro_bit()) { /* write to read only page */ ftype = VM_PROT_WRITE; PMAP_UNLOCK(pmap); goto dofault; } - entry |= mips_pg_m_bit(); - *pte = entry; - trapframe->badvaddr = (trapframe->badvaddr & ~PAGE_MASK); - pmap_update_page(pmap, trapframe->badvaddr, entry); - trapframe->badvaddr |= (pmap->pm_asid[PCPU_GET(cpuid)].asid << VMTLB_PID_SHIFT); - pa = mips_tlbpfn_to_paddr(entry); + *pte |= mips_pg_m_bit(); + pmap_update_page(pmap, trapframe->badvaddr, *pte); + pa = mips_tlbpfn_to_paddr(*pte); if (!page_is_managed(pa)) panic("trap: utlbmod: unmanaged page"); pmap_set_modified(pa); @@ -473,22 +461,29 @@ trap(struct trapframe *trapframe) rv = vm_fault(kernel_map, va, ftype, VM_FAULT_NORMAL); if (rv == KERN_SUCCESS) return (trapframe->pc); - if ((i = td->td_pcb->pcb_onfault) != 0) { - td->td_pcb->pcb_onfault = 0; - return (onfault_table[i]); + if (td->td_pcb->pcb_onfault != NULL) { + pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; + td->td_pcb->pcb_onfault = NULL; + return (pc); } goto err; } - /* + + /* * It is an error for the kernel to access user space except * through the copyin/copyout routines. */ - if ((i = td->td_pcb->pcb_onfault) == 0) + if (td->td_pcb->pcb_onfault == NULL) goto err; + /* check for fuswintr() or suswintr() getting a page fault */ - if (i == 4) { - return (onfault_table[i]); + /* XXX There must be a nicer way to do this. */ + if (td->td_pcb->pcb_onfault == fswintrberr) { + pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; + td->td_pcb->pcb_onfault = NULL; + return (pc); } + goto dofault; case T_TLB_LD_MISS + T_USER: @@ -507,7 +502,7 @@ dofault: vm = p->p_vmspace; map = &vm->vm_map; va = trunc_page((vm_offset_t)trapframe->badvaddr); - if ((vm_offset_t)trapframe->badvaddr >= VM_MIN_KERNEL_ADDRESS) { + if (KERNLAND(trapframe->badvaddr)) { /* * Don't allow user-mode faults in kernel * address space. @@ -529,9 +524,9 @@ dofault: --p->p_lock; PROC_UNLOCK(p); #ifdef VMFAULT_TRACE - printf("vm_fault(%p (pmap %p), %x (%x), %x, %d) -> %x at pc %x\n", - map, &vm->vm_pmap, va, trapframe->badvaddr, ftype, VM_FAULT_NORMAL, - rv, trapframe->pc); + printf("vm_fault(%p (pmap %p), %p (%p), %x, %d) -> %x at pc %p\n", + map, &vm->vm_pmap, (void *)va, (void *)(intptr_t)trapframe->badvaddr, + ftype, VM_FAULT_NORMAL, rv, (void *)(intptr_t)trapframe->pc); #endif if (rv == KERN_SUCCESS) { @@ -542,9 +537,10 @@ dofault: } nogo: if (!usermode) { - if ((i = td->td_pcb->pcb_onfault) != 0) { - td->td_pcb->pcb_onfault = 0; - return (onfault_table[i]); + if (td->td_pcb->pcb_onfault != NULL) { + pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; + td->td_pcb->pcb_onfault = NULL; + return (pc); } goto err; } @@ -606,6 +602,8 @@ dofault: int nargs, nsaved; register_t args[8]; + bzero(args, sizeof args); + /* * note: PCPU_LAZY_INC() can only be used if we can * afford occassional inaccuracy in the count. @@ -654,7 +652,6 @@ dofault: args[0] = locr0->a2; args[1] = locr0->a3; nsaved = 2; - quad_syscall = 1; break; default: @@ -679,7 +676,7 @@ dofault: nargs = callp->sy_narg; if (nargs > nsaved) { - i = copyin((caddr_t)(locr0->sp + + i = copyin((caddr_t)(intptr_t)(locr0->sp + 4 * sizeof(register_t)), (caddr_t)&args[nsaved], (u_int)(nargs - nsaved) * sizeof(register_t)); if (i) { @@ -770,7 +767,8 @@ dofault: case T_BREAK + T_USER: { - uintptr_t va, instr; + intptr_t va; + uint32_t instr; /* compute address of break instruction */ va = trapframe->pc; @@ -803,7 +801,7 @@ dofault: case T_IWATCH + T_USER: case T_DWATCH + T_USER: { - uintptr_t va; + intptr_t va; /* compute address of trapped instruction */ va = trapframe->pc; @@ -817,7 +815,8 @@ dofault: case T_TRAP + T_USER: { - uintptr_t va, instr; + intptr_t va; + uint32_t instr; struct trapframe *locr0 = td->td_frame; /* compute address of trap instruction */ @@ -839,6 +838,7 @@ dofault: } case T_RES_INST + T_USER: + log_illegal_instruction("RES_INST", trapframe); i = SIGILL; addr = trapframe->pc; break; @@ -853,11 +853,13 @@ dofault: #if !defined(CPU_HAVEFPU) /* FP (COP1) instruction */ if ((trapframe->cause & CR_COP_ERR) == 0x10000000) { + log_illegal_instruction("COP1_UNUSABLE", trapframe); i = SIGILL; break; } #endif if ((trapframe->cause & CR_COP_ERR) != 0x10000000) { + log_illegal_instruction("COPn_UNUSABLE", trapframe); i = SIGILL; /* only FPU instructions allowed */ break; } @@ -872,13 +874,13 @@ dofault: #if !defined(SMP) && (defined(DDB) || defined(DEBUG)) trapDump("fpintr"); #else - printf("FPU Trap: PC %x CR %x SR %x\n", - trapframe->pc, trapframe->cause, trapframe->sr); + printf("FPU Trap: PC %#jx CR %x SR %x\n", + (intmax_t)trapframe->pc, (unsigned)trapframe->cause, (unsigned)trapframe->sr); goto err; #endif case T_FPE + T_USER: - MachFPTrap(trapframe->sr, trapframe->cause, trapframe->pc); + MipsFPTrap(trapframe->sr, trapframe->cause, trapframe->pc); goto out; case T_OVFLOW + T_USER: @@ -889,8 +891,8 @@ dofault: case T_ADDR_ERR_LD: /* misaligned access */ case T_ADDR_ERR_ST: /* misaligned access */ #ifdef TRAP_DEBUG - printf("+++ ADDR_ERR: type = %d, badvaddr = %x\n", type, - trapframe->badvaddr); + printf("+++ ADDR_ERR: type = %d, badvaddr = %#jx\n", type, + (intmax_t)trapframe->badvaddr); #endif /* Only allow emulation on a user address */ if (allow_unaligned_acc && @@ -922,10 +924,12 @@ dofault: /* FALLTHROUGH */ case T_BUS_ERR_LD_ST: /* BERR asserted to cpu */ - if ((i = td->td_pcb->pcb_onfault) != 0) { - td->td_pcb->pcb_onfault = 0; - return (onfault_table[i]); + if (td->td_pcb->pcb_onfault != NULL) { + pc = (register_t)(intptr_t)td->td_pcb->pcb_onfault; + td->td_pcb->pcb_onfault = NULL; + return (pc); } + /* FALLTHROUGH */ default: @@ -947,9 +951,9 @@ err: printf("kernel mode)\n"); #ifdef TRAP_DEBUG - printf("badvaddr = %x, pc = %x, ra = %x, sr = 0x%x\n", - trapframe->badvaddr, trapframe->pc, trapframe->ra, - trapframe->sr); + printf("badvaddr = %#jx, pc = %#jx, ra = %#jx, sr = %#jxx\n", + (intmax_t)trapframe->badvaddr, (intmax_t)trapframe->pc, (intmax_t)trapframe->ra, + (intmax_t)trapframe->sr); #endif #ifdef KDB @@ -997,11 +1001,11 @@ trapDump(char *msg) if (trp->cause == 0) break; - printf("%s: ADR %x PC %x CR %x SR %x\n", + printf("%s: ADR %jx PC %jx CR %jx SR %jx\n", trap_type[(trp->cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT], - trp->vadr, trp->pc, trp->cause, trp->status); + (intmax_t)trp->vadr, (intmax_t)trp->pc, (intmax_t)trp->cause, (intmax_t)trp->status); - printf(" RA %x SP %x code %d\n", trp->ra, trp->sp, trp->code); + printf(" RA %jx SP %jx code %d\n", (intmax_t)trp->ra, (intmax_t)trp->sp, (int)trp->code); } intr_restore(s); } @@ -1165,39 +1169,39 @@ static void log_frame_dump(struct trapframe *frame) { log(LOG_ERR, "Trapframe Register Dump:\n"); - log(LOG_ERR, "\tzero: %p\tat: %p\tv0: %p\tv1: %p\n", - (void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1); + log(LOG_ERR, "\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n", + (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1); - log(LOG_ERR, "\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n", - (void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3); + log(LOG_ERR, "\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n", + (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3); - log(LOG_ERR, "\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n", - (void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3); + log(LOG_ERR, "\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n", + (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3); - log(LOG_ERR, "\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n", - (void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7); + log(LOG_ERR, "\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n", + (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7); - log(LOG_ERR, "\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n", - (void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1); + log(LOG_ERR, "\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n", + (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1); - log(LOG_ERR, "\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n", - (void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5); + log(LOG_ERR, "\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n", + (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5); - log(LOG_ERR, "\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n", - (void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1); + log(LOG_ERR, "\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n", + (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1); - log(LOG_ERR, "\tgp: %p\tsp: %p\ts8: %p\tra: %p\n", - (void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra); + log(LOG_ERR, "\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n", + (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra); - log(LOG_ERR, "\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n", - (void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr); + log(LOG_ERR, "\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n", + (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr); #ifdef IC_REG - log(LOG_ERR, "\tcause: %p\tpc: %p\tic: %p\n", - (void *)frame->cause, (void *)frame->pc, (void *)frame->ic); + log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\tic: %#jx\n", + (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic); #else - log(LOG_ERR, "\tcause: %p\tpc: %p\n", - (void *)frame->cause, (void *)frame->pc); + log(LOG_ERR, "\tcause: %#jx\tpc: %#jx\n", + (intmax_t)frame->cause, (intmax_t)frame->pc); #endif } @@ -1206,39 +1210,39 @@ static void trap_frame_dump(struct trapframe *frame) { printf("Trapframe Register Dump:\n"); - printf("\tzero: %p\tat: %p\tv0: %p\tv1: %p\n", - (void *)0, (void *)frame->ast, (void *)frame->v0, (void *)frame->v1); + printf("\tzero: %#jx\tat: %#jx\tv0: %#jx\tv1: %#jx\n", + (intmax_t)0, (intmax_t)frame->ast, (intmax_t)frame->v0, (intmax_t)frame->v1); - printf("\ta0: %p\ta1: %p\ta2: %p\ta3: %p\n", - (void *)frame->a0, (void *)frame->a1, (void *)frame->a2, (void *)frame->a3); + printf("\ta0: %#jx\ta1: %#jx\ta2: %#jx\ta3: %#jx\n", + (intmax_t)frame->a0, (intmax_t)frame->a1, (intmax_t)frame->a2, (intmax_t)frame->a3); - printf("\tt0: %p\tt1: %p\tt2: %p\tt3: %p\n", - (void *)frame->t0, (void *)frame->t1, (void *)frame->t2, (void *)frame->t3); + printf("\tt0: %#jx\tt1: %#jx\tt2: %#jx\tt3: %#jx\n", + (intmax_t)frame->t0, (intmax_t)frame->t1, (intmax_t)frame->t2, (intmax_t)frame->t3); - printf("\tt4: %p\tt5: %p\tt6: %p\tt7: %p\n", - (void *)frame->t4, (void *)frame->t5, (void *)frame->t6, (void *)frame->t7); + printf("\tt4: %#jx\tt5: %#jx\tt6: %#jx\tt7: %#jx\n", + (intmax_t)frame->t4, (intmax_t)frame->t5, (intmax_t)frame->t6, (intmax_t)frame->t7); - printf("\tt8: %p\tt9: %p\ts0: %p\ts1: %p\n", - (void *)frame->t8, (void *)frame->t9, (void *)frame->s0, (void *)frame->s1); + printf("\tt8: %#jx\tt9: %#jx\ts0: %#jx\ts1: %#jx\n", + (intmax_t)frame->t8, (intmax_t)frame->t9, (intmax_t)frame->s0, (intmax_t)frame->s1); - printf("\ts2: %p\ts3: %p\ts4: %p\ts5: %p\n", - (void *)frame->s2, (void *)frame->s3, (void *)frame->s4, (void *)frame->s5); + printf("\ts2: %#jx\ts3: %#jx\ts4: %#jx\ts5: %#jx\n", + (intmax_t)frame->s2, (intmax_t)frame->s3, (intmax_t)frame->s4, (intmax_t)frame->s5); - printf("\ts6: %p\ts7: %p\tk0: %p\tk1: %p\n", - (void *)frame->s6, (void *)frame->s7, (void *)frame->k0, (void *)frame->k1); + printf("\ts6: %#jx\ts7: %#jx\tk0: %#jx\tk1: %#jx\n", + (intmax_t)frame->s6, (intmax_t)frame->s7, (intmax_t)frame->k0, (intmax_t)frame->k1); - printf("\tgp: %p\tsp: %p\ts8: %p\tra: %p\n", - (void *)frame->gp, (void *)frame->sp, (void *)frame->s8, (void *)frame->ra); + printf("\tgp: %#jx\tsp: %#jx\ts8: %#jx\tra: %#jx\n", + (intmax_t)frame->gp, (intmax_t)frame->sp, (intmax_t)frame->s8, (intmax_t)frame->ra); - printf("\tsr: %p\tmullo: %p\tmulhi: %p\tbadvaddr: %p\n", - (void *)frame->sr, (void *)frame->mullo, (void *)frame->mulhi, (void *)frame->badvaddr); + printf("\tsr: %#jx\tmullo: %#jx\tmulhi: %#jx\tbadvaddr: %#jx\n", + (intmax_t)frame->sr, (intmax_t)frame->mullo, (intmax_t)frame->mulhi, (intmax_t)frame->badvaddr); #ifdef IC_REG - printf("\tcause: %p\tpc: %p\tic: %p\n", - (void *)frame->cause, (void *)frame->pc, (void *)frame->ic); + printf("\tcause: %#jx\tpc: %#jx\tic: %#jx\n", + (intmax_t)frame->cause, (intmax_t)frame->pc, (intmax_t)frame->ic); #else - printf("\tcause: %p\tpc: %p\n", - (void *)frame->cause, (void *)frame->pc); + printf("\tcause: %#jx\tpc: %#jx\n", + (intmax_t)frame->cause, (intmax_t)frame->pc); #endif } @@ -1252,7 +1256,7 @@ get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp) pd_entry_t *pdep; struct proc *p = curproc; - pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[va >> SEGSHIFT])); + pdep = (&(p->p_vmspace->vm_pmap.pm_segtab[(va >> SEGSHIFT) & (NPDEPG - 1)])); if (*pdep) ptep = pmap_pte(&p->p_vmspace->vm_pmap, va); else @@ -1262,6 +1266,50 @@ get_mapping_info(vm_offset_t va, pd_entry_t **pdepp, pt_entry_t **ptepp) *ptepp = ptep; } +static void +log_illegal_instruction(const char *msg, struct trapframe *frame) +{ + pt_entry_t *ptep; + pd_entry_t *pdep; + unsigned int *addr; + struct proc *p = curproc; + register_t pc; + +#ifdef SMP + printf("cpuid = %d\n", PCPU_GET(cpuid)); +#endif + pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); + log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx ra %#jx\n", + msg, p->p_pid, p->p_comm, + p->p_ucred ? p->p_ucred->cr_uid : -1, + (intmax_t)pc, + (intmax_t)frame->ra); + + /* log registers in trap frame */ + log_frame_dump(frame); + + get_mapping_info((vm_offset_t)pc, &pdep, &ptep); + + /* + * Dump a few words around faulting instruction, if the addres is + * valid. + */ + if (!(pc & 3) && + useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { + /* dump page table entry for faulting instruction */ + log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n", + (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0); + + addr = (unsigned int *)(intptr_t)pc; + log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", + addr); + log(LOG_ERR, "%08x %08x %08x %08x\n", + addr[0], addr[1], addr[2], addr[3]); + } else { + log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n", + (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0); + } +} static void log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) @@ -1293,12 +1341,12 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) } pc = frame->pc + (DELAYBRANCH(frame->cause) ? 4 : 0); - log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %p got a %s fault at %p\n", + log(LOG_ERR, "%s: pid %d (%s), uid %d: pc %#jx got a %s fault at %#jx\n", msg, p->p_pid, p->p_comm, p->p_ucred ? p->p_ucred->cr_uid : -1, - (void *)pc, + (intmax_t)pc, read_or_write, - (void *)frame->badvaddr); + (intmax_t)frame->badvaddr); /* log registers in trap frame */ log_frame_dump(frame); @@ -1311,21 +1359,24 @@ log_bad_page_fault(char *msg, struct trapframe *frame, int trap_type) */ if (!(pc & 3) && (pc != frame->badvaddr) && (trap_type != T_BUS_ERR_IFETCH) && - useracc((caddr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { + useracc((caddr_t)(intptr_t)pc, sizeof(int) * 4, VM_PROT_READ)) { /* dump page table entry for faulting instruction */ - log(LOG_ERR, "Page table info for pc address %p: pde = %p, pte = 0x%lx\n", - (void *)pc, *pdep, ptep ? *ptep : 0); + log(LOG_ERR, "Page table info for pc address %#jx: pde = %p, pte = %#x\n", + (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0); - addr = (unsigned int *)pc; + addr = (unsigned int *)(intptr_t)pc; log(LOG_ERR, "Dumping 4 words starting at pc address %p: \n", addr); log(LOG_ERR, "%08x %08x %08x %08x\n", addr[0], addr[1], addr[2], addr[3]); } else { - log(LOG_ERR, "pc address %p is inaccessible, pde = 0x%p, pte = 0x%lx\n", - (void *)pc, *pdep, ptep ? *ptep : 0); + log(LOG_ERR, "pc address %#jx is inaccessible, pde = %p, pte = %#x\n", + (intmax_t)pc, (void *)(intptr_t)*pdep, ptep ? *ptep : 0); } - /* panic("Bad trap");*/ + + get_mapping_info((vm_offset_t)frame->badvaddr, &pdep, &ptep); + log(LOG_ERR, "Page table info for bad address %#jx: pde = %p, pte = %#x\n", + (intmax_t)frame->badvaddr, (void *)(intptr_t)*pdep, ptep ? *ptep : 0); } @@ -1336,7 +1387,7 @@ static int mips_unaligned_load_store(struct trapframe *frame, register_t addr, register_t pc) { register_t *reg = (register_t *) frame; - u_int32_t inst = *((u_int32_t *) pc); + u_int32_t inst = *((u_int32_t *)(intptr_t)pc); u_int32_t value_msb, value; int access_type = 0; @@ -1432,9 +1483,9 @@ emulate_unaligned_access(struct trapframe *frame) else frame->pc += 4; - log(LOG_INFO, "Unaligned %s: pc=%p, badvaddr=%p\n", - access_name[access_type - 1], (void *)pc, - (void *)frame->badvaddr); + log(LOG_INFO, "Unaligned %s: pc=%#jx, badvaddr=%#jx\n", + access_name[access_type - 1], (intmax_t)pc, + (intmax_t)frame->badvaddr); } } return access_type; diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index 10321dac4bf..cb8a8d90a1a 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -647,7 +647,7 @@ DB_SHOW_COMMAND(pcb, ddb_dump_pcb) DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_GP); DB_PRINT_REG_ARRAY(pcb, pcb_context, PCB_REG_PC); - db_printf("PCB onfault = %d\n", pcb->pcb_onfault); + db_printf("PCB onfault = %p\n", pcb->pcb_onfault); db_printf("md_saved_intr = 0x%0lx\n", (long)td->td_md.md_saved_intr); db_printf("md_spinlock_count = %d\n", td->td_md.md_spinlock_count); From 25eb6a7d87e4085a8a205dffee2a3730883617b2 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 17 Apr 2010 11:40:39 +0000 Subject: [PATCH 103/532] Add another ICH7M chipset that works. MFC after: 1 week --- sys/dev/ahci/ahci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index 5d399683945..a35fbacdab6 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -126,6 +126,7 @@ static struct { {0x26838086, 0x00, "Intel ESB2", 0}, {0x27c18086, 0x00, "Intel ICH7", 0}, {0x27c38086, 0x00, "Intel ICH7", 0}, + {0x27c48086, 0x00, "Intel ICH7M", 0}, {0x27c58086, 0x00, "Intel ICH7M", 0}, {0x27c68086, 0x00, "Intel ICH7M", 0}, {0x28218086, 0x00, "Intel ICH8", 0}, From 37f144eb5dcee9f71e4d683031bb555f827dea80 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 17 Apr 2010 12:22:44 +0000 Subject: [PATCH 104/532] Fix a bug where SACKs are not sent when they should. Move some protection code to INVARIANTS. Cleanups. MFC after: 3 days. --- sys/netinet/sctp_indata.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 53dcf8f2a6f..a7e6c087fb4 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -1466,7 +1466,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, asoc->send_sack = 1; } protocol_id = ch->dp.protocol_id; - ordered = ((ch->ch.chunk_flags & SCTP_DATA_UNORDERED) == 0); + ordered = ((chunk_flags & SCTP_DATA_UNORDERED) == 0); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) { sctp_log_map(tsn, asoc->cumulative_tsn, asoc->highest_tsn_inside_map, SCTP_MAP_TSN_ENTERS); } @@ -2300,7 +2300,12 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb) if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) { /* The complete array was completed by a single FR */ /* highest becomes the cum-ack */ - int clr, i; + int clr; + +#ifdef INVARIANTS + unsigned int i; + +#endif /* clear the array */ clr = ((at + 7) >> 3); @@ -2309,12 +2314,14 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb) } memset(asoc->mapping_array, 0, clr); memset(asoc->nr_mapping_array, 0, clr); +#ifdef INVARIANTS for (i = 0; i < asoc->mapping_array_size; i++) { if ((asoc->mapping_array[i]) || (asoc->nr_mapping_array[i])) { printf("Error Mapping array's not clean at clear\n"); sctp_print_mapping_array(asoc); } } +#endif asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1; asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map = asoc->cumulative_tsn; } else if (at >= 8) { @@ -2371,10 +2378,8 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb) int ii; for (ii = 0; ii < distance; ii++) { - asoc->mapping_array[ii] = - asoc->mapping_array[slide_from + ii]; - asoc->nr_mapping_array[ii] = - asoc->nr_mapping_array[slide_from + ii]; + asoc->mapping_array[ii] = asoc->mapping_array[slide_from + ii]; + asoc->nr_mapping_array[ii] = asoc->nr_mapping_array[slide_from + ii]; } for (ii = distance; ii < asoc->mapping_array_size; ii++) { @@ -2808,8 +2813,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length, stcb->asoc.send_sack = 1; } /* Start a sack timer or QUEUE a SACK for sending */ - if ((stcb->asoc.cumulative_tsn == stcb->asoc.highest_tsn_inside_map) && - (stcb->asoc.mapping_array[0] != 0xff)) { + if ((stcb->asoc.cumulative_tsn == stcb->asoc.highest_tsn_inside_nr_map) && + (stcb->asoc.nr_mapping_array[0] != 0xff)) { if ((stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) || (stcb->asoc.delayed_ack == 0) || (stcb->asoc.numduptsns) || From 8eac1f947715c47f877e577515a3289aba705513 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 17 Apr 2010 14:35:46 +0000 Subject: [PATCH 105/532] sh: On startup of the shell, use PWD from the environment if it is valid. Unset PWD if it is incorrect and no value for it can be determined. This preserves the logical current directory across shell invocations. Example (assuming /home is a symlink): $ cd $ pwd /home/foo $ sh $ pwd /home/foo Formerly the second pwd would show the physical path (symlinks resolved). --- bin/sh/cd.c | 27 ++++++++++++++++++----- bin/sh/cd.h | 2 +- bin/sh/main.c | 5 +---- tools/regression/bin/sh/parameters/pwd2.0 | 24 ++++++++++++++++++++ 4 files changed, 48 insertions(+), 10 deletions(-) create mode 100644 tools/regression/bin/sh/parameters/pwd2.0 diff --git a/bin/sh/cd.c b/bin/sh/cd.c index 40801ba2c97..aee06e8fb00 100644 --- a/bin/sh/cd.c +++ b/bin/sh/cd.c @@ -70,6 +70,7 @@ STATIC int docd(char *, int, int); STATIC char *getcomponent(void); STATIC char *findcwd(char *); STATIC void updatepwd(char *); +STATIC char *getpwd(void); STATIC char *getpwd2(void); STATIC char *curdir = NULL; /* current working directory */ @@ -351,7 +352,7 @@ pwdcmd(int argc, char **argv) /* * Get the current directory and cache the result in curdir. */ -char * +STATIC char * getpwd(void) { char *p; @@ -374,7 +375,6 @@ getpwd(void) STATIC char * getpwd2(void) { - struct stat stdot, stpwd; char *pwd; int i; @@ -387,12 +387,29 @@ getpwd2(void) break; } - pwd = getenv("PWD"); + return NULL; +} + +/* + * Initialize PWD in a new shell. + * If the shell is interactive, we need to warn if this fails. + */ +void +pwd_init(int warn) +{ + char *pwd; + struct stat stdot, stpwd; + + pwd = lookupvar("PWD"); if (pwd && *pwd == '/' && stat(".", &stdot) != -1 && stat(pwd, &stpwd) != -1 && stdot.st_dev == stpwd.st_dev && stdot.st_ino == stpwd.st_ino) { - return pwd; + if (curdir) + ckfree(curdir); + curdir = savestr(pwd); } - return NULL; + if (getpwd() == NULL && warn) + out2fmt_flush("sh: cannot determine working directory\n"); + setvar("PWD", curdir, VEXPORT); } diff --git a/bin/sh/cd.h b/bin/sh/cd.h index 0a2d48999e7..f88ce26ad4c 100644 --- a/bin/sh/cd.h +++ b/bin/sh/cd.h @@ -29,6 +29,6 @@ * $FreeBSD$ */ -char *getpwd(void); +void pwd_init(int); int cdcmd (int, char **); int pwdcmd(int, char **); diff --git a/bin/sh/main.c b/bin/sh/main.c index 50a88132ab3..ecbb12dc640 100644 --- a/bin/sh/main.c +++ b/bin/sh/main.c @@ -153,10 +153,7 @@ main(int argc, char *argv[]) init(); setstackmark(&smark); procargs(argc, argv); - if (getpwd() == NULL && iflag) - out2fmt_flush("sh: cannot determine working directory\n"); - if (getpwd() != NULL) - setvar ("PWD", getpwd(), VEXPORT); + pwd_init(iflag); if (iflag) chkmail(1); if (argv[0] && argv[0][0] == '-') { diff --git a/tools/regression/bin/sh/parameters/pwd2.0 b/tools/regression/bin/sh/parameters/pwd2.0 new file mode 100644 index 00000000000..29b5531aaa8 --- /dev/null +++ b/tools/regression/bin/sh/parameters/pwd2.0 @@ -0,0 +1,24 @@ +# $FreeBSD$ +# Check that PWD is exported and accepted from the environment. +set -e + +T=$(mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX) +trap 'rm -rf $T' 0 +cd -P $T +TP=$(pwd) +mkdir test1 +ln -s test1 link +cd link +[ "$PWD" = "$TP/link" ] +[ "$(pwd)" = "$TP/link" ] +[ "$(pwd -P)" = "$TP/test1" ] +[ "$(sh -c pwd)" = "$TP/link" ] +[ "$(sh -c pwd\ -P)" = "$TP/test1" ] +cd .. +[ "$(pwd)" = "$TP" ] +cd -P link +[ "$PWD" = "$TP/test1" ] +[ "$(pwd)" = "$TP/test1" ] +[ "$(pwd -P)" = "$TP/test1" ] +[ "$(sh -c pwd)" = "$TP/test1" ] +[ "$(sh -c pwd\ -P)" = "$TP/test1" ] From 702f62fb48f1cd993cfdfb7d84e17e3874f11635 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 17 Apr 2010 15:52:50 +0000 Subject: [PATCH 106/532] getcwd(3): Clarify that EACCES may or may not be checked. POSIX permits but does not require checking access on the current and parent directories. Because various programs do not like it if getcwd(3) fails, it seems best to avoid checking access as much as possible. There are various reports in GNATS about this (search for getcwd). Our getcwd(3) implementation first queries the kernel for the pathname directly, which does not check any permissions but sometimes fails, and then falls back to reading all parent directories for the names. PR: standards/44425 MFC after: 2 weeks --- lib/libc/gen/getcwd.3 | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/libc/gen/getcwd.3 b/lib/libc/gen/getcwd.3 index 12a2bd664af..88291c3e2ee 100644 --- a/lib/libc/gen/getcwd.3 +++ b/lib/libc/gen/getcwd.3 @@ -28,7 +28,7 @@ .\" @(#)getcwd.3 8.2 (Berkeley) 12/11/93 .\" $FreeBSD$ .\" -.Dd November 24, 1997 +.Dd April 17, 2010 .Dt GETCWD 3 .Os .Sh NAME @@ -108,8 +108,6 @@ The function will fail if: .Bl -tag -width Er -.It Bq Er EACCES -Read or search permission was denied for a component of the pathname. .It Bq Er EINVAL The .Fa size @@ -124,6 +122,16 @@ The argument is greater than zero but smaller than the length of the pathname plus 1. .El +.Pp +The +.Fn getcwd +function +may fail if: +.Bl -tag -width Er +.It Bq Er EACCES +Read or search permission was denied for a component of the pathname. +This is only checked in limited cases, depending on implementation details. +.El .Sh SEE ALSO .Xr chdir 2 , .Xr fchdir 2 , From 0b6ace474376f863982bec0c04b1498ff74b0c1d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 17 Apr 2010 17:02:17 +0000 Subject: [PATCH 107/532] Setting PG_REFERENCED on the requested page in swap_pager_getpages() is either redundant or harmful, depending on the caller. For example, when called by vm_fault(), it is redundant. However, when called by vm_thread_swapin(), it is harmful. Specifically, if the thread is later swapped out, having PG_REFERENCED set on its stack pages leads the page daemon to reactivate these stack pages and delay their reclamation. Reviewed by: kib MFC after: 3 weeks --- sys/vm/swap_pager.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index ef64b31ae09..f1d89d5e030 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -1101,8 +1101,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) * happen. Note that blk, iblk & jblk can be SWAPBLK_NONE, but the * loops are set up such that the case(s) are handled implicitly. * - * The swp_*() calls must be made at splvm(). vm_page_free() does - * not need to be, but it will go a little faster if it is. + * The swp_*() calls must be made with the object locked. */ blk = swp_pager_meta_ctl(mreq->object, mreq->pindex, 0); @@ -1212,9 +1211,6 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int reqpage) VM_OBJECT_LOCK(object); while ((mreq->oflags & VPO_SWAPINPROG) != 0) { mreq->oflags |= VPO_WANTED; - vm_page_lock_queues(); - vm_page_flag_set(mreq, PG_REFERENCED); - vm_page_unlock_queues(); PCPU_INC(cnt.v_intrans); if (msleep(mreq, VM_OBJECT_MTX(object), PSWP, "swread", hz*20)) { printf( From d02ae91a4c13ee1cd599ccd96566b84259ec15c2 Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Sat, 17 Apr 2010 18:13:52 +0000 Subject: [PATCH 108/532] Fix comment about ipw_assoc and remove some whitespaces; no functional changes. Approved by: rpaulo (mentor) --- sys/dev/ipw/if_ipw.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 0b217583f24..dc2a61f009d 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -888,10 +888,10 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) /* * XXX when joining an ibss network we are called * with a SCAN -> RUN transition on scan complete. - * Use that to call ipw_auth_and_assoc. On completing - * the join we are then called again with an - * AUTH -> RUN transition and we want to do nothing. - * This is all totally bogus and needs to be redone. + * Use that to call ipw_assoc. On completing the + * join we are then called again with an AUTH -> RUN + * transition and we want to do nothing. This is + * all totally bogus and needs to be redone. */ if (ostate == IEEE80211_S_SCAN) ipw_assoc(ic, vap); @@ -909,7 +909,7 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) case IEEE80211_S_ASSOC: /* - * If we are not transitioning from AUTH the resend the + * If we are not transitioning from AUTH then resend the * association request. */ if (ostate != IEEE80211_S_AUTH) @@ -1070,7 +1070,7 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) case IPW_STATE_DISABLED: /* XXX? is this right? */ - sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING | + sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING | IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n", IEEESTATE(vap), sc->flags)); From 892d2e9d9bb81d56487590e7780a4229df8bbaef Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Sat, 17 Apr 2010 18:14:49 +0000 Subject: [PATCH 109/532] Pass correct RSSI to ieee80211_input*(). Approved by: rpaulo (mentor) --- sys/dev/ipw/if_ipw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index dc2a61f009d..3a8d85d7ca6 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -1234,10 +1234,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, IPW_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, nf); + (void) ieee80211_input(ni, m, rssi - nf, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, nf); + (void) ieee80211_input_all(ic, m, rssi - nf, nf); IPW_LOCK(sc); bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE); From 557c25b48fe48116f27951dc263cd4fbf133b388 Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Sat, 17 Apr 2010 18:16:14 +0000 Subject: [PATCH 110/532] - Make ipw usable again by moving directly into ASSOC state. - No need to manually switch to RUN state, assoc response takes care of that. Approved by: rpaulo (mentor) --- sys/dev/ipw/if_ipw.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 3a8d85d7ca6..2e62949a4bb 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -904,6 +904,13 @@ ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) break; case IEEE80211_S_AUTH: + /* + * Move to ASSOC state after the ipw_assoc() call. Firmware + * takes care of authentication, after the call we'll receive + * only an assoc response which would otherwise be discared + * if we are still in AUTH state. + */ + nstate = IEEE80211_S_ASSOC; ipw_assoc(ic, vap); break; @@ -1021,7 +1028,6 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) } sc->flags &= ~IPW_FLAG_ASSOCIATING; sc->flags |= IPW_FLAG_ASSOCIATED; - ieee80211_new_state(vap, IEEE80211_S_RUN, -1); break; case IPW_STATE_SCANNING: From 6e4c30c9cdebd9bd441d57a8884babcd40e2df79 Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Sat, 17 Apr 2010 18:17:25 +0000 Subject: [PATCH 111/532] Use iv_appie_wpa, with this commit WPA works again. Approved by: rpaulo (mentor) --- sys/dev/ipw/if_ipw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 2e62949a4bb..9a17e6173c8 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -2266,8 +2266,8 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) if (error != 0) goto done; - if (vap->iv_appie_assocreq != NULL) { - struct ieee80211_appie *ie = vap->iv_appie_assocreq; + if (vap->iv_appie_wpa != NULL) { + struct ieee80211_appie *ie = vap->iv_appie_wpa; error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len); if (error != 0) goto done; From 82ff07c047997e086c6ad79595d97b31dc555813 Mon Sep 17 00:00:00 2001 From: Bernhard Schmidt Date: Sat, 17 Apr 2010 18:18:46 +0000 Subject: [PATCH 112/532] Remove IPW_LOCK_DECL and fix various LORs. Approved by: rpaulo (mentor) --- sys/dev/ipw/if_ipw.c | 27 ++++++++++++++------------- sys/dev/ipw/if_ipwvar.h | 11 ++--------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 9a17e6173c8..3315d654b1c 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -1040,8 +1040,10 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) * we checked the 802.11 layer state. */ if (sc->flags & IPW_FLAG_ASSOCIATED) { + IPW_UNLOCK(sc); /* XXX probably need to issue disassoc to fw */ ieee80211_beacon_miss(ic); + IPW_LOCK(sc); } break; @@ -1060,7 +1062,9 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) break; } if (sc->flags & IPW_FLAG_SCANNING) { + IPW_UNLOCK(sc); ieee80211_scan_done(vap); + IPW_LOCK(sc); sc->flags &= ~IPW_FLAG_SCANNING; sc->sc_scan_timer = 0; } @@ -1070,8 +1074,11 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) DPRINTFN(2, ("Association lost (%s flags 0x%x)\n", IEEESTATE(vap), sc->flags)); sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); - if (vap->iv_state == IEEE80211_S_RUN) + if (vap->iv_state == IEEE80211_S_RUN) { + IPW_UNLOCK(sc); ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); + IPW_LOCK(sc); + } break; case IPW_STATE_DISABLED: @@ -1170,7 +1177,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, bus_addr_t physaddr; int error; int8_t rssi, nf; - IPW_LOCK_DECL; DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len), status->rssi)); @@ -1384,8 +1390,11 @@ ipw_fatal_error_intr(struct ipw_softc *sc) struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); - if (vap != NULL) + if (vap != NULL) { + IPW_UNLOCK(sc); ieee80211_cancel_scan(vap); + IPW_LOCK(sc); + } ieee80211_runtask(ic, &sc->sc_init_task); } @@ -1394,7 +1403,6 @@ ipw_intr(void *arg) { struct ipw_softc *sc = arg; uint32_t r; - IPW_LOCK_DECL; IPW_LOCK(sc); @@ -1724,7 +1732,6 @@ static void ipw_start(struct ifnet *ifp) { struct ipw_softc *sc = ifp->if_softc; - IPW_LOCK_DECL; IPW_LOCK(sc); ipw_start_locked(ifp); @@ -1781,7 +1788,9 @@ ipw_watchdog(void *arg) DPRINTFN(3, ("Scan timeout\n")); /* End the scan */ if (sc->flags & IPW_FLAG_SCANNING) { + IPW_UNLOCK(sc); ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); + IPW_LOCK(sc); sc->flags &= ~IPW_FLAG_SCANNING; } } @@ -1797,7 +1806,6 @@ ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ieee80211com *ic = ifp->if_l2com; struct ifreq *ifr = (struct ifreq *) data; int error = 0, startall = 0; - IPW_LOCK_DECL; switch (cmd) { case SIOCSIFFLAGS: @@ -2207,7 +2215,6 @@ ipw_assoc(struct ieee80211com *ic, struct ieee80211vap *vap) struct ipw_security security; uint32_t data; int error; - IPW_LOCK_DECL; IPW_LOCK(sc); error = ipw_disable(sc); @@ -2297,7 +2304,6 @@ ipw_disassoc(struct ieee80211com *ic, struct ieee80211vap *vap) struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ieee80211_node *ni = vap->iv_bss; struct ipw_softc *sc = ifp->if_softc; - IPW_LOCK_DECL; IPW_LOCK(sc); DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); @@ -2333,7 +2339,6 @@ ipw_init(void *priv) struct ipw_softc *sc = priv; struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - IPW_LOCK_DECL; IPW_LOCK(sc); ipw_init_locked(sc); @@ -2540,7 +2545,6 @@ static void ipw_stop(void *priv) { struct ipw_softc *sc = priv; - IPW_LOCK_DECL; IPW_LOCK(sc); ipw_stop_locked(sc); @@ -2667,7 +2671,6 @@ ipw_scan_start(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; - IPW_LOCK_DECL; IPW_LOCK(sc); ipw_scan(sc); @@ -2679,7 +2682,6 @@ ipw_set_channel(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; - IPW_LOCK_DECL; IPW_LOCK(sc); if (ic->ic_opmode == IEEE80211_M_MONITOR) { @@ -2707,7 +2709,6 @@ ipw_scan_end(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; - IPW_LOCK_DECL; IPW_LOCK(sc); sc->flags &= ~IPW_FLAG_SCANNING; diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h index 8d9e049ccfb..89702d0c634 100644 --- a/sys/dev/ipw/if_ipwvar.h +++ b/sys/dev/ipw/if_ipwvar.h @@ -164,13 +164,6 @@ struct ipw_softc { * NB.: This models the only instance of async locking in ipw_init_locked * and must be kept in sync. */ -#define IPW_LOCK_DECL int __waslocked = 0 -#define IPW_LOCK(sc) do { \ - if (!(__waslocked = mtx_owned(&(sc)->sc_mtx))) \ - mtx_lock(&sc->sc_mtx); \ -} while (0) -#define IPW_UNLOCK(sc) do { \ - if (!__waslocked) \ - mtx_unlock(&sc->sc_mtx); \ -} while (0) +#define IPW_LOCK(sc) mtx_lock(&sc->sc_mtx); +#define IPW_UNLOCK(sc) mtx_unlock(&sc->sc_mtx); #define IPW_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) From aefea7f519b1c2aee4f74acd1ecaf1216956fdf7 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 17 Apr 2010 18:35:07 +0000 Subject: [PATCH 113/532] In vm_object_backing_scan(), setting PG_REFERENCED on a page before sleeping on that page is nonsensical. Doing so reduces the likelihood that the page daemon will reclaim the page before the thread waiting in vm_object_backing_scan() is reawakened. However, it does not guarantee that the page is not reclaimed, so vm_object_backing_scan() restarts after reawakening. More importantly, this muddles the meaning of PG_REFERENCED. There is no reason to believe that the caller of vm_object_backing_scan() is going to use (i.e., access) the contents of the page. There is especially no reason to believe that an access is more likely because vm_object_backing_scan() had to sleep on the page. Discussed with: kib MFC after: 3 weeks --- sys/vm/vm_object.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 399cb10a1f9..7e84e58e35f 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1553,9 +1553,6 @@ vm_object_backing_scan(vm_object_t object, int op) } } else if (op & OBSC_COLLAPSE_WAIT) { if ((p->oflags & VPO_BUSY) || p->busy) { - vm_page_lock_queues(); - vm_page_flag_set(p, PG_REFERENCED); - vm_page_unlock_queues(); VM_OBJECT_UNLOCK(object); p->oflags |= VPO_WANTED; msleep(p, VM_OBJECT_MTX(backing_object), From 1a5873681676b938759aee294c9a98c8845a593a Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 17 Apr 2010 18:48:18 +0000 Subject: [PATCH 114/532] In case a user wants to configure only an IPv6 link-local address add an example that shows how to do it. --- etc/defaults/rc.conf | 1 + share/man/man5/rc.conf.5 | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index a5da7c2417e..48233bdb1cf 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -211,6 +211,7 @@ ifconfig_lo0="inet 127.0.0.1" # default loopback device configuration. #ifconfig_lo0_alias0="inet 127.0.0.254 netmask 0xffffffff" # Sample alias entry. #ifconfig_ed0_ipx="ipx 0x00010010" # Sample IPX address family entry. #ifconfig_ed0_ipv6="RTADV" # Sample IPv6 entry for RA/rtsol(8) +#ifconfig_ed0_ipv6="inet6 auto_linklocal" # To configure only link-local #ifconfig_ed0_ipv6="inet6 2001:db8:1::1 prefixlen 64" # Sample IPv6 addr entry #ifconfig_ed0_alias0="inet6 2001:db8:2::1 prefixlen 64" # Sample IPv6 alias #ifconfig_fxp0_name="net0" # Change interface name from fxp0 to net0. diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index c0b358d4499..e93205be539 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -1303,6 +1303,13 @@ interface: ifconfig_ed0_ipv6="RTADV" .Ed .Pp +To configure only a link-local address on the +.Dq Li ed0 +interface: +.Bd -literal +ifconfig_ed0_ipv6="inet6 auto_linklocal" +.Ed +.Pp To disable RA the .Dq Li NORTADV option is available, although not required if manual From b11b56b55b0fef3215817f1d4b99661809e9afea Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 17 Apr 2010 21:14:37 +0000 Subject: [PATCH 115/532] In vm_object_madvise() setting PG_REFERENCED on a page before sleeping on that page only makes sense if the advice is MADV_WILLNEED. In that case, the intention is to activate the page, so discouraging the page daemon from reclaiming the page makes sense. In contrast, in the other cases, MADV_DONTNEED and MADV_FREE, it makes no sense whatsoever to discourage the page daemon from reclaiming the page by setting PG_REFERENCED. Wrap a nearby line. Discussed with: kib MFC after: 3 weeks --- sys/vm/vm_object.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 7e84e58e35f..1f9ba6d4956 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1205,12 +1205,19 @@ shadowlookup: goto unlock_tobject; } if ((m->oflags & VPO_BUSY) || m->busy) { - vm_page_flag_set(m, PG_REFERENCED); + if (advise == MADV_WILLNEED) + /* + * Reference the page before unlocking and + * sleeping so that the page daemon is less + * likely to reclaim it. + */ + vm_page_flag_set(m, PG_REFERENCED); vm_page_unlock_queues(); if (object != tobject) VM_OBJECT_UNLOCK(object); m->oflags |= VPO_WANTED; - msleep(m, VM_OBJECT_MTX(tobject), PDROP | PVM, "madvpo", 0); + msleep(m, VM_OBJECT_MTX(tobject), PDROP | PVM, "madvpo", + 0); VM_OBJECT_LOCK(object); goto relookup; } From 9eb448a7e634f3edde2ca41327e4a7a0dcac564e Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sat, 17 Apr 2010 21:31:42 +0000 Subject: [PATCH 116/532] Use ubthidhci_enable="NO" to avoid the bootup warning. Submitted by: Jilles Tjoelker MFC after: 3 days --- etc/defaults/rc.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 48233bdb1cf..ab50920dccb 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -437,7 +437,7 @@ rfcomm_pppd_server_two_channel="3" # Override local channel for 'two' #rfcomm_pppd_server_two_register_sp="NO" # Override SP and DUN register #rfcomm_pppd_server_two_register_dun="NO" # for 'two' -#ubthidhci_enable="YES" # Switch an USB BT controller present on +ubthidhci_enable="NO" # Switch an USB BT controller present on #ubthidhci_busnum="3" # bus 3 and addr 2 from HID mode to HCI mode. #ubthidhci_addr="2" # Check usbconfig list to find the correct # numbers for your system. From 5d66b54e27eb01b2bbea010f559c4c985c67886a Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 17 Apr 2010 22:39:53 +0000 Subject: [PATCH 117/532] ln: Refuse deleting a directory entry by hardlinking it to itself. Two pathnames refer to the same directory entry iff the directories match and the final components' names match. Example: (assuming file1 is an existing file) ln -f file1 file1 This now fails while leaving file1 intact. It used to delete file1 and then complain it cannot be linked because it is gone. With -i, this error is detected before the question is asked. MFC after: 2 weeks --- bin/ln/ln.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/bin/ln/ln.c b/bin/ln/ln.c index e946646775e..d77939291f7 100644 --- a/bin/ln/ln.c +++ b/bin/ln/ln.c @@ -172,6 +172,52 @@ main(int argc, char *argv[]) exit(exitval); } +/* + * Two pathnames refer to the same directory entry if the directories match + * and the final components' names match. + */ +static int +samedirent(const char *path1, const char *path2) +{ + const char *file1, *file2; + char pathbuf[PATH_MAX]; + struct stat sb1, sb2; + + if (strcmp(path1, path2) == 0) + return 1; + file1 = strrchr(path1, '/'); + if (file1 != NULL) + file1++; + else + file1 = path1; + file2 = strrchr(path2, '/'); + if (file2 != NULL) + file2++; + else + file2 = path2; + if (strcmp(file1, file2) != 0) + return 0; + if (file1 - path1 >= PATH_MAX || file2 - path2 >= PATH_MAX) + return 0; + if (file1 == path1) + memcpy(pathbuf, ".", 2); + else { + memcpy(pathbuf, path1, file1 - path1); + pathbuf[file1 - path1] = '\0'; + } + if (stat(pathbuf, &sb1) != 0) + return 0; + if (file2 == path2) + memcpy(pathbuf, ".", 2); + else { + memcpy(pathbuf, path2, file2 - path2); + pathbuf[file2 - path2] = '\0'; + } + if (stat(pathbuf, &sb2) != 0) + return 0; + return sb1.st_dev == sb2.st_dev && sb1.st_ino == sb2.st_ino; +} + int linkit(const char *source, const char *target, int isdir) { @@ -215,7 +261,6 @@ linkit(const char *source, const char *target, int isdir) target = path; } - exists = !lstat(target, &sb); /* * If the link source doesn't exist, and a symbolic link was * requested, and -w was specified, give a warning. @@ -242,8 +287,20 @@ linkit(const char *source, const char *target, int isdir) warn("warning: %s", source); } } + /* - * If the file exists, then unlink it forcibly if -f was specified + * If the file exists, first check it is not the same directory entry. + */ + exists = !lstat(target, &sb); + if (exists) { + if (!sflag && samedirent(source, target)) { + warnx("%s and %s are the same directory entry", + source, target); + return (1); + } + } + /* + * Then unlink it forcibly if -f was specified * and interactively if -i was specified. */ if (fflag && exists) { From 5195ca23073524c7c25453d289c451040c15af41 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 12:20:33 +0000 Subject: [PATCH 118/532] Set ARC_L2_WRITING on L2ARC header creation. Obtained from: OpenSolaris --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index ca8ffb1ea13..e7043c99160 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -4562,6 +4562,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) hdrl2->b_dev = dev; hdrl2->b_daddr = dev->l2ad_hand; + ab->b_flags |= ARC_L2_WRITING; ab->b_l2hdr = hdrl2; list_insert_head(dev->l2ad_buflist, ab); buf_data = ab->b_buf->b_data; From 57a81a8bbc37dadcc96dd6ed12c802e7ef99a7c8 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 12:21:52 +0000 Subject: [PATCH 119/532] Remove racy assertion. Obtained from: OpenSolaris --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index e7043c99160..4cd1cff2ecf 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -2731,7 +2731,6 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf, uint32_t *arc_flags, const zbookmark_t *zb) { int err; - arc_buf_hdr_t *hdr = pbuf->b_hdr; ASSERT(!refcount_is_zero(&pbuf->b_hdr->b_refcnt)); ASSERT3U((char *)bp - (char *)pbuf->b_data, <, pbuf->b_hdr->b_size); @@ -2739,8 +2738,6 @@ arc_read(zio_t *pio, spa_t *spa, blkptr_t *bp, arc_buf_t *pbuf, err = arc_read_nolock(pio, spa, bp, done, private, priority, zio_flags, arc_flags, zb); - - ASSERT3P(hdr, ==, pbuf->b_hdr); rw_exit(&pbuf->b_lock); return (err); } From ad3cb80827341a867218b67720a64ca41f5135bb Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 12:25:40 +0000 Subject: [PATCH 120/532] Extend locks scope to match OpenSolaris. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 4cd1cff2ecf..7d218a44dc6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1106,8 +1106,6 @@ add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) mutex_enter(lock); ASSERT(list_link_active(&ab->b_arc_node)); list_remove(list, ab); - mutex_exit(lock); - if (GHOST_STATE(ab->b_state)) { ASSERT3U(ab->b_datacnt, ==, 0); ASSERT3P(ab->b_buf, ==, NULL); @@ -1116,6 +1114,7 @@ add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) ASSERT(delta > 0); ASSERT3U(*size, >=, delta); atomic_add_64(size, -delta); + mutex_exit(lock); /* remove the prefetch flag if we get a reference */ if (ab->b_flags & ARC_PREFETCH) ab->b_flags &= ~ARC_PREFETCH; @@ -1138,15 +1137,13 @@ remove_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) kmutex_t *lock; get_buf_info(ab, state, &list, &lock); - ASSERT(!MUTEX_HELD(lock)); mutex_enter(lock); ASSERT(!list_link_active(&ab->b_arc_node)); list_insert_head(list, ab); - mutex_exit(lock); - ASSERT(ab->b_datacnt > 0); atomic_add_64(size, ab->b_size * ab->b_datacnt); + mutex_exit(lock); } return (cnt); } From eb998be67d2bd8509b9c37c66c9a18f81253deaf Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 12:27:07 +0000 Subject: [PATCH 121/532] Add missing list and lock destruction. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 7d218a44dc6..740a0a57f3e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -3850,12 +3850,14 @@ arc_fini(void) list_destroy(&arc_mru_ghost->arcs_lists[i]); list_destroy(&arc_mfu->arcs_lists[i]); list_destroy(&arc_mfu_ghost->arcs_lists[i]); + list_destroy(&arc_l2c_only->arcs_lists[i]); mutex_destroy(&arc_anon->arcs_locks[i].arcs_lock); mutex_destroy(&arc_mru->arcs_locks[i].arcs_lock); mutex_destroy(&arc_mru_ghost->arcs_locks[i].arcs_lock); mutex_destroy(&arc_mfu->arcs_locks[i].arcs_lock); mutex_destroy(&arc_mfu_ghost->arcs_locks[i].arcs_lock); + mutex_destroy(&arc_l2c_only->arcs_locks[i].arcs_lock); } mutex_destroy(&zfs_write_limit_lock); From 224329fb6b7aa08f0384ee0ec7c1a6fa6dd9828c Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 12:36:53 +0000 Subject: [PATCH 122/532] Style fixes. --- .../opensolaris/uts/common/fs/zfs/arc.c | 120 ++++++++---------- 1 file changed, 54 insertions(+), 66 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 740a0a57f3e..ceb4c87f2f6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -131,7 +131,6 @@ #include #include -#include #include static kmutex_t arc_reclaim_thr_lock; @@ -238,7 +237,7 @@ struct arcs_lock { */ #define ARC_BUFC_NUMDATALISTS 16 #define ARC_BUFC_NUMMETADATALISTS 16 -#define ARC_BUFC_NUMLISTS (ARC_BUFC_NUMMETADATALISTS+ARC_BUFC_NUMDATALISTS) +#define ARC_BUFC_NUMLISTS (ARC_BUFC_NUMMETADATALISTS + ARC_BUFC_NUMDATALISTS) typedef struct arc_state { uint64_t arcs_lsize[ARC_BUFC_NUMTYPES]; /* amount of evictable data */ @@ -247,7 +246,7 @@ typedef struct arc_state { struct arcs_lock arcs_locks[ARC_BUFC_NUMLISTS] __aligned(CACHE_LINE_SIZE); } arc_state_t; -#define ARCS_LOCK(s, i) &((s)->arcs_locks[(i)].arcs_lock) +#define ARCS_LOCK(s, i) (&((s)->arcs_locks[(i)].arcs_lock)) /* The 6 states: */ static arc_state_t ARC_anon; @@ -307,9 +306,9 @@ typedef struct arc_stats { kstat_named_t arcstat_l2_hdr_size; kstat_named_t arcstat_memory_throttle_count; kstat_named_t arcstat_l2_write_trylock_fail; - kstat_named_t arcstat_l2_write_in_l2; kstat_named_t arcstat_l2_write_passed_headroom; kstat_named_t arcstat_l2_write_spa_mismatch; + kstat_named_t arcstat_l2_write_in_l2; kstat_named_t arcstat_l2_write_hdr_io_in_progress; kstat_named_t arcstat_l2_write_not_cacheable; kstat_named_t arcstat_l2_write_full; @@ -370,19 +369,19 @@ static arc_stats_t arc_stats = { { "l2_size", KSTAT_DATA_UINT64 }, { "l2_hdr_size", KSTAT_DATA_UINT64 }, { "memory_throttle_count", KSTAT_DATA_UINT64 }, - { "l2_write_trylock_fail", KSTAT_DATA_UINT64 }, - { "l2_write_in_l2", KSTAT_DATA_UINT64 }, - { "l2_write_passed_headroom", KSTAT_DATA_UINT64 }, - { "l2_write_spa_mismatch", KSTAT_DATA_UINT64 }, - { "l2_write_io_in_progress", KSTAT_DATA_UINT64 }, - { "l2_write_not_cacheable", KSTAT_DATA_UINT64 }, - { "l2_write_full", KSTAT_DATA_UINT64 }, - { "l2_write_buffer_iter", KSTAT_DATA_UINT64 }, - { "l2_write_pios", KSTAT_DATA_UINT64 }, - { "l2_write_bytes_written", KSTAT_DATA_UINT64 }, - { "l2_write_buffer_bytes_scanned", KSTAT_DATA_UINT64 }, - { "l2_write_buffer_list_iter", KSTAT_DATA_UINT64 }, - { "l2_write_buffer_list_null_iter", KSTAT_DATA_UINT64 } + { "l2_write_trylock_fail", KSTAT_DATA_UINT64 }, + { "l2_write_passed_headroom", KSTAT_DATA_UINT64 }, + { "l2_write_spa_mismatch", KSTAT_DATA_UINT64 }, + { "l2_write_in_l2", KSTAT_DATA_UINT64 }, + { "l2_write_io_in_progress", KSTAT_DATA_UINT64 }, + { "l2_write_not_cacheable", KSTAT_DATA_UINT64 }, + { "l2_write_full", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_iter", KSTAT_DATA_UINT64 }, + { "l2_write_pios", KSTAT_DATA_UINT64 }, + { "l2_write_bytes_written", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_bytes_scanned", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_list_iter", KSTAT_DATA_UINT64 }, + { "l2_write_buffer_list_null_iter", KSTAT_DATA_UINT64 } }; #define ARCSTAT(stat) (arc_stats.stat.value.ui64) @@ -390,7 +389,7 @@ static arc_stats_t arc_stats = { #define ARCSTAT_INCR(stat, val) \ atomic_add_64(&arc_stats.stat.value.ui64, (val)); -#define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1) +#define ARCSTAT_BUMP(stat) ARCSTAT_INCR(stat, 1) #define ARCSTAT_BUMPDOWN(stat) ARCSTAT_INCR(stat, -1) #define ARCSTAT_MAX(stat, val) { \ @@ -424,7 +423,7 @@ static arc_stats_t arc_stats = { } kstat_t *arc_ksp; -static arc_state_t *arc_anon; +static arc_state_t *arc_anon; static arc_state_t *arc_mru; static arc_state_t *arc_mru_ghost; static arc_state_t *arc_mfu; @@ -1076,10 +1075,10 @@ get_buf_info(arc_buf_hdr_t *ab, arc_state_t *state, list_t **list, kmutex_t **lo { uint64_t buf_hashid = buf_hash(ab->b_spa, &ab->b_dva, ab->b_birth); - if (ab->b_type == ARC_BUFC_METADATA) - buf_hashid &= (ARC_BUFC_NUMMETADATALISTS-1); + if (ab->b_type == ARC_BUFC_METADATA) + buf_hashid &= (ARC_BUFC_NUMMETADATALISTS - 1); else { - buf_hashid &= (ARC_BUFC_NUMDATALISTS-1); + buf_hashid &= (ARC_BUFC_NUMDATALISTS - 1); buf_hashid += ARC_BUFC_NUMMETADATALISTS; } @@ -1096,10 +1095,10 @@ add_reference(arc_buf_hdr_t *ab, kmutex_t *hash_lock, void *tag) if ((refcount_add(&ab->b_refcnt, tag) == 1) && (ab->b_state != arc_anon)) { - list_t *list; - kmutex_t *lock; uint64_t delta = ab->b_size * ab->b_datacnt; uint64_t *size = &ab->b_state->arcs_lsize[ab->b_type]; + list_t *list; + kmutex_t *lock; get_buf_info(ab, ab->b_state, &list, &lock); ASSERT(!MUTEX_HELD(lock)); @@ -1179,7 +1178,6 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) get_buf_info(ab, old_state, &list, &lock); use_mutex = !MUTEX_HELD(lock); - if (use_mutex) mutex_enter(lock); @@ -1202,13 +1200,11 @@ arc_change_state(arc_state_t *new_state, arc_buf_hdr_t *ab, kmutex_t *hash_lock) mutex_exit(lock); } if (new_state != arc_anon) { - int use_mutex; + int use_mutex; uint64_t *size = &new_state->arcs_lsize[ab->b_type]; get_buf_info(ab, new_state, &list, &lock); use_mutex = !MUTEX_HELD(lock); - - if (use_mutex) mutex_enter(lock); @@ -1626,7 +1622,7 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, ASSERT(state == arc_mru || state == arc_mfu); evicted_state = (state == arc_mru) ? arc_mru_ghost : arc_mfu_ghost; - + if (type == ARC_BUFC_METADATA) { offset = 0; list_count = ARC_BUFC_NUMMETADATALISTS; @@ -1635,7 +1631,6 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, idx = evict_metadata_offset; } else { offset = ARC_BUFC_NUMMETADATALISTS; - list_start = &state->arcs_lists[offset]; evicted_list_start = &evicted_state->arcs_lists[offset]; list_count = ARC_BUFC_NUMDATALISTS; @@ -1643,12 +1638,12 @@ arc_evict(arc_state_t *state, spa_t *spa, int64_t bytes, boolean_t recycle, } bytes_remaining = evicted_state->arcs_lsize[type]; count = 0; - + evict_start: list = &list_start[idx]; evicted_list = &evicted_list_start[idx]; lock = ARCS_LOCK(state, (offset + idx)); - evicted_lock = ARCS_LOCK(evicted_state, (offset + idx)); + evicted_lock = ARCS_LOCK(evicted_state, (offset + idx)); mutex_enter(lock); mutex_enter(evicted_lock); @@ -1718,7 +1713,7 @@ evict_start: if (bytes_remaining > 0) { mutex_exit(evicted_lock); mutex_exit(lock); - idx = ((idx + 1)&(list_count-1)); + idx = ((idx + 1) & (list_count - 1)); count++; goto evict_start; } @@ -1729,8 +1724,8 @@ evict_start: mutex_exit(evicted_lock); mutex_exit(lock); - - idx = ((idx + 1)&(list_count-1)); + + idx = ((idx + 1) & (list_count - 1)); count++; if (bytes_evicted < bytes) { @@ -1740,11 +1735,11 @@ evict_start: dprintf("only evicted %lld bytes from %x", (longlong_t)bytes_evicted, state); } - if (type == ARC_BUFC_METADATA) + if (type == ARC_BUFC_METADATA) evict_metadata_offset = idx; else evict_data_offset = idx; - + if (skipped) ARCSTAT_INCR(arcstat_evict_skip, skipped); @@ -1801,7 +1796,7 @@ arc_evict_ghost(arc_state_t *state, spa_t *spa, int64_t bytes) list_start = &state->arcs_lists[ARC_BUFC_NUMMETADATALISTS]; list_count = ARC_BUFC_NUMDATALISTS; offset = ARC_BUFC_NUMMETADATALISTS; - + evict_start: list = &list_start[idx]; lock = ARCS_LOCK(state, idx + offset); @@ -1848,12 +1843,12 @@ evict_start: } } mutex_exit(lock); - idx = ((idx + 1)&(ARC_BUFC_NUMDATALISTS-1)); + idx = ((idx + 1) & (ARC_BUFC_NUMDATALISTS - 1)); count++; - + if (count < list_count) goto evict_start; - + evict_offset = idx; if ((uintptr_t)list > (uintptr_t)&state->arcs_lists[ARC_BUFC_NUMMETADATALISTS] && (bytes < 0 || bytes_deleted < bytes)) { @@ -1942,7 +1937,7 @@ arc_do_user_evicts(void) /* * Move list over to avoid LOR */ -restart: +restart: mutex_enter(&arc_eviction_mtx); tmp_arc_eviction_list = arc_eviction_list; arc_eviction_list = NULL; @@ -2053,7 +2048,7 @@ arc_reclaim_needed(void) return (0); /* - * If pages are needed or we're within 2048 pages + * If pages are needed or we're within 2048 pages * of needing to page need to reclaim */ if (vm_pages_needed || (vm_paging_target() > -2048)) @@ -2611,10 +2606,7 @@ arc_read_done(zio_t *zio) hdr->b_flags &= ~ARC_L2_EVICTED; if (l2arc_noprefetch && (hdr->b_flags & ARC_PREFETCH)) hdr->b_flags &= ~ARC_L2CACHE; -#if 0 - else if ((hdr->b_flags & ARC_PREFETCH) == 0) - hdr->b_flags |= ARC_L2CACHE; -#endif + /* byteswap if necessary */ callback_list = hdr->b_acb; ASSERT(callback_list != NULL); @@ -2951,7 +2943,7 @@ top: * released by l2arc_read_done(). */ rzio = zio_read_phys(pio, vd, addr, size, - buf->b_data, ZIO_CHECKSUM_OFF, + buf->b_data, ZIO_CHECKSUM_OFF, l2arc_read_done, cb, priority, zio_flags | ZIO_FLAG_DONT_CACHE | ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | @@ -3048,7 +3040,7 @@ arc_buf_evict(arc_buf_t *buf) arc_buf_t **bufp; list_t *list, *evicted_list; kmutex_t *lock, *evicted_lock; - + rw_enter(&buf->b_lock, RW_WRITER); hdr = buf->b_hdr; if (hdr == NULL) { @@ -3723,7 +3715,6 @@ arc_init(void) arc_size = 0; for (i = 0; i < ARC_BUFC_NUMLISTS; i++) { - mutex_init(&arc_anon->arcs_locks[i].arcs_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&arc_mru->arcs_locks[i].arcs_lock, @@ -3736,7 +3727,7 @@ arc_init(void) NULL, MUTEX_DEFAULT, NULL); mutex_init(&arc_l2c_only->arcs_locks[i].arcs_lock, NULL, MUTEX_DEFAULT, NULL); - + list_create(&arc_mru->arcs_lists[i], sizeof (arc_buf_hdr_t), offsetof(arc_buf_hdr_t, b_arc_node)); list_create(&arc_mru_ghost->arcs_lists[i], @@ -3786,7 +3777,7 @@ arc_init(void) #ifdef _KERNEL if (TUNABLE_INT_FETCH("vfs.zfs.prefetch_disable", &zfs_prefetch_disable)) prefetch_tunable_set = 1; - + #ifdef __i386__ if (prefetch_tunable_set == 0) { printf("ZFS NOTICE: Prefetch is disabled by default on i386 " @@ -3795,7 +3786,7 @@ arc_init(void) "to /boot/loader.conf.\n"); zfs_prefetch_disable=1; } -#else +#else if ((((uint64_t)physmem * PAGESIZE) < (1ULL << 32)) && prefetch_tunable_set == 0) { printf("ZFS NOTICE: Prefetch is disabled by default if less " @@ -3804,7 +3795,7 @@ arc_init(void) "to /boot/loader.conf.\n"); zfs_prefetch_disable=1; } -#endif +#endif /* Warn about ZFS memory and address space requirements. */ if (((uint64_t)physmem * PAGESIZE) < (256 + 128 + 64) * (1 << 20)) { printf("ZFS WARNING: Recommended minimum RAM size is 512MB; " @@ -3824,7 +3815,7 @@ void arc_fini(void) { int i; - + mutex_enter(&arc_reclaim_thr_lock); arc_thread_exit = 1; cv_signal(&arc_reclaim_thr_cv); @@ -3859,7 +3850,7 @@ arc_fini(void) mutex_destroy(&arc_mfu_ghost->arcs_locks[i].arcs_lock); mutex_destroy(&arc_l2c_only->arcs_locks[i].arcs_lock); } - + mutex_destroy(&zfs_write_limit_lock); buf_fini(); @@ -4255,18 +4246,18 @@ l2arc_list_locked(int list_num, kmutex_t **lock) { list_t *list; int idx; - - ASSERT(list_num >= 0 && list_num < 2*ARC_BUFC_NUMLISTS); + + ASSERT(list_num >= 0 && list_num < 2 * ARC_BUFC_NUMLISTS); if (list_num < ARC_BUFC_NUMMETADATALISTS) { idx = list_num; list = &arc_mfu->arcs_lists[idx]; *lock = ARCS_LOCK(arc_mfu, idx); - } else if (list_num < ARC_BUFC_NUMMETADATALISTS*2) { + } else if (list_num < ARC_BUFC_NUMMETADATALISTS * 2) { idx = list_num - ARC_BUFC_NUMMETADATALISTS; list = &arc_mru->arcs_lists[idx]; *lock = ARCS_LOCK(arc_mru, idx); - } else if (list_num < (ARC_BUFC_NUMMETADATALISTS*2 + + } else if (list_num < (ARC_BUFC_NUMMETADATALISTS * 2 + ARC_BUFC_NUMDATALISTS)) { idx = list_num - ARC_BUFC_NUMMETADATALISTS; list = &arc_mfu->arcs_lists[idx]; @@ -4277,8 +4268,6 @@ l2arc_list_locked(int list_num, kmutex_t **lock) *lock = ARCS_LOCK(arc_mru, idx); } - CTR3(KTR_SPARE2, "list=%p list_num=%d idx=%d", - list, list_num, idx); ASSERT(!(MUTEX_HELD(*lock))); mutex_enter(*lock); return (list); @@ -4448,7 +4437,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) * Copy buffers for L2ARC writing. */ mutex_enter(&l2arc_buflist_mtx); - for (try = 0; try < 2*ARC_BUFC_NUMLISTS; try++) { + for (try = 0; try < 2 * ARC_BUFC_NUMLISTS; try++) { list = l2arc_list_locked(try, &list_lock); passed_sz = 0; ARCSTAT_BUMP(arcstat_l2_write_buffer_list_iter); @@ -4464,9 +4453,8 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) ab = list_head(list); else ab = list_tail(list); - if (ab == NULL) { + if (ab == NULL) ARCSTAT_BUMP(arcstat_l2_write_buffer_list_null_iter); - } for (; ab; ab = ab_prev) { if (arc_warm == B_FALSE) @@ -4474,7 +4462,7 @@ l2arc_write_buffers(spa_t *spa, l2arc_dev_t *dev, uint64_t target_sz) else ab_prev = list_prev(list, ab); ARCSTAT_INCR(arcstat_l2_write_buffer_bytes_scanned, ab->b_size); - + hash_lock = HDR_LOCK(ab); have_lock = MUTEX_HELD(hash_lock); if (!have_lock && !mutex_tryenter(hash_lock)) { From bd7226a57219b0e1d6d68c2cab87dace5f40ee1b Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Sun, 18 Apr 2010 12:43:33 +0000 Subject: [PATCH 123/532] Restore previous order. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h index 3ca7249305a..f3e00877a8e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/arc.h @@ -55,8 +55,8 @@ struct arc_buf { }; typedef enum arc_buf_contents { - ARC_BUFC_METADATA, /* buffer contains metadata */ ARC_BUFC_DATA, /* buffer contains data */ + ARC_BUFC_METADATA, /* buffer contains metadata */ ARC_BUFC_NUMTYPES } arc_buf_contents_t; /* From 4b9dd5d53737effedae23defa9bda6f0c74320a5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 18 Apr 2010 17:50:09 +0000 Subject: [PATCH 124/532] There is no justification for vm_object_split() setting PG_REFERENCED on a page that it is going to sleep on. Eliminate it. MFC after: 3 weeks --- sys/vm/vm_object.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 1f9ba6d4956..7e4dbc85350 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -1422,7 +1422,6 @@ retry: * not be changed by this operation. */ if ((m->oflags & VPO_BUSY) || m->busy) { - vm_page_flag_set(m, PG_REFERENCED); vm_page_unlock_queues(); VM_OBJECT_UNLOCK(new_object); m->oflags |= VPO_WANTED; From 8d0331993042102b34533c1e0e91fe1f5f8783c9 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 18 Apr 2010 18:23:11 +0000 Subject: [PATCH 125/532] Revert r206649. Simplify the presented declaration of struct sigaction, noting the caveat in the text. Real layout of the structure and exposed implementation namespace only obfuscates the usage. Submitted by: bde MFC after: 3 days --- lib/libc/sys/sigaction.2 | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2 index 51b6c47c78f..3b4f2f0196d 100644 --- a/lib/libc/sys/sigaction.2 +++ b/lib/libc/sys/sigaction.2 @@ -28,7 +28,7 @@ .\" From: @(#)sigaction.2 8.2 (Berkeley) 4/3/94 .\" $FreeBSD$ .\" -.Dd April 13, 2010 +.Dd April 18, 2010 .Dt SIGACTION 2 .Os .Sh NAME @@ -40,16 +40,11 @@ .In signal.h .Bd -literal struct sigaction { - union { - void (*__sa_handler)(int); - void (*__sa_sigaction)(int, siginfo_t *, void *); - } __sigaction_u; /* signal handler */ + void (*sa_handler)(int); + void (*sa_sigaction)(int, siginfo_t *, void *); int sa_flags; /* see signal options below */ sigset_t sa_mask; /* signal mask to apply */ }; - -#define sa_handler __sigaction_u.__sa_handler -#define sa_sigaction __sigaction_u.__sa_sigaction .Ed .Ft int .Fo sigaction @@ -148,6 +143,16 @@ If is non-zero, the previous handling information for the signal is returned to the user. .Pp +The above declaration of +.Vt "struct sigaction" +is not literal. +It is provided only to list the accessible members. +See +.In sys/signal.h +for the actual definition. +In particular, the storage occupied by sa_handler and sa_sigaction overlaps, +and an application can not use both simultaneously. +.Pp Once a signal handler is installed, it normally remains installed until another .Fn sigaction @@ -496,16 +501,6 @@ or .Dv SIG_IGN this way. .Pp -If preprocessing symbol -.Va _POSIX_C_SOURCE -with the value >= 199309 is not defined, the following declaration for -the handler shall be used: -.Bl -tag -offset indent -width short -.It Tn POSIX Dv SA_SIGINFO : -.Ft void -.Fn handler int "struct __sigaction *" "void *" ; -.El -.Pp If the .Dv SA_SIGINFO flag is not set, the handler function should match From 685b0bb81486270480e6cdf7748769d28eb7e7c3 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Sun, 18 Apr 2010 18:43:36 +0000 Subject: [PATCH 126/532] Delete svn:executable prop. --- sys/mips/rmi/dev/sec/desc.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 sys/mips/rmi/dev/sec/desc.h diff --git a/sys/mips/rmi/dev/sec/desc.h b/sys/mips/rmi/dev/sec/desc.h old mode 100755 new mode 100644 From b28889a2fc4a6f08ffc0c3b2991310c270df854b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 18 Apr 2010 21:29:28 +0000 Subject: [PATCH 127/532] Remove a nonsensical test from vm_pageout_clean(). A page can't be in the inactive queue and have a non-zero wire count. Reviewed by: kib MFC after: 3 weeks --- sys/vm/vm_pageout.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index dc2b3b77d56..d5ede5a7503 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -350,7 +350,6 @@ more: vm_page_test_dirty(p); if (p->dirty == 0 || p->queue != PQ_INACTIVE || - p->wire_count != 0 || /* may be held by buf cache */ p->hold_count != 0) { /* may be undergoing I/O */ ib = 0; break; @@ -378,7 +377,6 @@ more: vm_page_test_dirty(p); if (p->dirty == 0 || p->queue != PQ_INACTIVE || - p->wire_count != 0 || /* may be held by buf cache */ p->hold_count != 0) { /* may be undergoing I/O */ break; } From 348c81a032e288731dbe9891650ff8cbac6dbe9e Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 18 Apr 2010 22:13:45 +0000 Subject: [PATCH 128/532] sh: Add testcases for double-quotes within quoted ${var+-...} (non-POSIX). POSIX leaves things like "${var+"word"}" undefined. We follow traditional ash behaviour here. Hence, these testcases also work on stable/8. --- .../regression/bin/sh/expansion/plus-minus3.0 | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 tools/regression/bin/sh/expansion/plus-minus3.0 diff --git a/tools/regression/bin/sh/expansion/plus-minus3.0 b/tools/regression/bin/sh/expansion/plus-minus3.0 new file mode 100644 index 00000000000..49fcdc2f8f5 --- /dev/null +++ b/tools/regression/bin/sh/expansion/plus-minus3.0 @@ -0,0 +1,44 @@ +# $FreeBSD$ + +e= q='?' a='*' t=texttext s='ast*que?non' p='/et[c]/' w='a b c' b='{{(#)}}' +h='##' +failures='' +ok='' + +testcase() { + code="$1" + expected="$2" + oIFS="$IFS" + eval "$code" + IFS='|' + result="$#|$*" + IFS="$oIFS" + if [ "x$result" = "x$expected" ]; then + ok=x$ok + else + failures=x$failures + echo "For $code, expected $expected actual $result" + fi +} + +# We follow original ash behaviour for quoted ${var+-=?} expansions: +# a double-quote in one switches back to unquoted state. +# This allows expanding a variable as a single word if it is set +# and substituting multiple words otherwise. +# It is also close to the Bourne and Korn shells. +# POSIX leaves this undefined, and various other shells treat +# such double-quotes as introducing a second level of quoting +# which does not do much except quoting close braces. + +testcase 'set -- "${p+"/et[c]/"}"' '1|/etc/' +testcase 'set -- "${p-"/et[c]/"}"' '1|/et[c]/' +testcase 'set -- "${p+"$p"}"' '1|/etc/' +testcase 'set -- "${p-"$p"}"' '1|/et[c]/' +testcase 'set -- "${p+"""/et[c]/"}"' '1|/etc/' +testcase 'set -- "${p-"""/et[c]/"}"' '1|/et[c]/' +testcase 'set -- "${p+"""$p"}"' '1|/etc/' +testcase 'set -- "${p-"""$p"}"' '1|/et[c]/' +testcase 'set -- "${p+"\@"}"' '1|@' +testcase 'set -- "${p+"'\''/et[c]/'\''"}"' '1|/et[c]/' + +test "x$failures" = x From 7ea710b3b174504918463bbe3456c5cf057baafe Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 18 Apr 2010 22:21:23 +0000 Subject: [PATCH 129/532] Avoid extraneous recovery cycles in the experimental NFS client when an NFSv4 server reboots, by doing two things. 1 - Make the function that acquires a stateid for I/O operations block until recovery is complete, so that it doesn't acquire out of date stateids. 2 - Only allow a recovery once every 1/2 of a lease duration, since the NFSv4 server must provide a recovery grace period of at least a lease duration. This should avoid recoveries caused by an out of date stateid that was acquired for an I/O op. just before a recovery cycle started. MFC after: 1 week --- sys/fs/nfs/nfsclstate.h | 1 + sys/fs/nfsclient/nfs_clstate.c | 33 +++++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/sys/fs/nfs/nfsclstate.h b/sys/fs/nfs/nfsclstate.h index edd479cf2ce..72d8eebfc39 100644 --- a/sys/fs/nfs/nfsclstate.h +++ b/sys/fs/nfs/nfsclstate.h @@ -74,6 +74,7 @@ struct nfsclclient { #define NFSCLFLAGS_EXPIREIT 0x0040 #define NFSCLFLAGS_FIRSTDELEG 0x0080 #define NFSCLFLAGS_GOTDELEG 0x0100 +#define NFSCLFLAGS_RECVRINPROG 0x0200 struct nfsclowner { LIST_ENTRY(nfsclowner) nfsow_list; diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 7bccbfcc5d7..6a189635ff7 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -480,6 +480,13 @@ nfscl_getstateid(vnode_t vp, u_int8_t *nfhp, int fhlen, u_int32_t mode, return (EACCES); } + /* + * Wait for recovery to complete. + */ + while ((clp->nfsc_flags & NFSCLFLAGS_RECVRINPROG)) + (void) nfsmsleep(&clp->nfsc_flags, NFSCLSTATEMUTEXPTR, + PZERO, "nfsrecvr", NULL); + /* * First, look for a delegation. */ @@ -1778,6 +1785,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p) * block when trying to use state. */ NFSLOCKCLSTATE(); + clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG; do { igotlock = nfsv4_lock(&clp->nfsc_lock, 1, NULL, NFSCLSTATEMUTEXPTR); @@ -1794,9 +1802,10 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p) error == NFSERR_STALEDONTRECOVER) && --trycnt > 0); if (error) { nfscl_cleanclient(clp); - clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID | - NFSCLFLAGS_RECOVER); NFSLOCKCLSTATE(); + clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID | + NFSCLFLAGS_RECOVER | NFSCLFLAGS_RECVRINPROG); + wakeup(&clp->nfsc_flags); nfsv4_unlock(&clp->nfsc_lock, 0); NFSUNLOCKCLSTATE(); return; @@ -2057,6 +2066,8 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p) } NFSLOCKCLSTATE(); + clp->nfsc_flags &= ~NFSCLFLAGS_RECVRINPROG; + wakeup(&clp->nfsc_flags); nfsv4_unlock(&clp->nfsc_lock, 0); NFSUNLOCKCLSTATE(); NFSFREECRED(tcred); @@ -2316,6 +2327,7 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p) struct ucred *cred; u_int32_t clidrev; int error, cbpathdown, islept, igotlock, ret, clearok; + uint32_t recover_done_time = 0; cred = newnfs_getcred(); NFSLOCKCLSTATE(); @@ -2324,8 +2336,21 @@ nfscl_renewthread(struct nfsclclient *clp, NFSPROC_T *p) for(;;) { newnfs_setroot(cred); cbpathdown = 0; - if (clp->nfsc_flags & NFSCLFLAGS_RECOVER) - nfscl_recover(clp, cred, p); + if (clp->nfsc_flags & NFSCLFLAGS_RECOVER) { + /* + * Only allow one recover within 1/2 of the lease + * duration (nfsc_renew). + */ + if (recover_done_time < NFSD_MONOSEC) { + recover_done_time = NFSD_MONOSEC + + clp->nfsc_renew; + nfscl_recover(clp, cred, p); + } else { + NFSLOCKCLSTATE(); + clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER; + NFSUNLOCKCLSTATE(); + } + } if (clp->nfsc_expire <= NFSD_MONOSEC && (clp->nfsc_flags & NFSCLFLAGS_HASCLIENTID)) { clp->nfsc_expire = NFSD_MONOSEC + clp->nfsc_renew; From ca596a25f07f94a05515cd150b1d7e6f81c1894d Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Sun, 18 Apr 2010 22:32:07 +0000 Subject: [PATCH 130/532] o) Add a VM find-space option, VMFS_TLB_ALIGNED_SPACE, which searches the address space for an address as aligned by the new pmap_align_tlb() function, which is for constraints imposed by the TLB. [1] o) Add a kmem_alloc_nofault_space() function, which acts like kmem_alloc_nofault() but allows the caller to specify which find-space option to use. [1] o) Use kmem_alloc_nofault_space() with VMFS_TLB_ALIGNED_SPACE to allocate the kernel stack address on MIPS. [1] o) Make pmap_align_tlb() on MIPS align addresses so that they do not start on an odd boundary within the TLB, so that they are suitable for insertion as wired entries and do not have to share a TLB entry with another mapping, assuming they are appropriately-sized. o) Eliminate md_realstack now that the kstack will be appropriately-aligned on MIPS. o) Increase the number of guard pages to 2 so that we retain the proper alignment of the kstack address. Reviewed by: [1] alc X-MFC-after: Making sure alc has not come up with a better interface. --- sys/mips/include/param.h | 7 ++----- sys/mips/include/proc.h | 3 +-- sys/mips/mips/exception.S | 4 ++-- sys/mips/mips/genassym.c | 2 +- sys/mips/mips/machdep.c | 5 ++--- sys/mips/mips/pmap.c | 15 +++++++++++++++ sys/mips/mips/swtch.S | 2 +- sys/mips/mips/vm_machdep.c | 26 +++++++------------------- sys/vm/pmap.h | 3 +++ sys/vm/vm_extern.h | 1 + sys/vm/vm_glue.c | 9 +++++++++ sys/vm/vm_kern.c | 29 +++++++++++++++++++++++++++++ sys/vm/vm_map.c | 13 ++++++++++++- sys/vm/vm_map.h | 3 +++ 14 files changed, 88 insertions(+), 34 deletions(-) diff --git a/sys/mips/include/param.h b/sys/mips/include/param.h index 0edb8b93d55..06cdeac0483 100644 --- a/sys/mips/include/param.h +++ b/sys/mips/include/param.h @@ -113,12 +113,9 @@ /* * The kernel stack needs to be aligned on a (PAGE_SIZE * 2) boundary. - * - * Although we allocate 3 pages for the kernel stack we end up using - * only the 2 pages that are aligned on a (PAGE_SIZE * 2) boundary. */ -#define KSTACK_PAGES 3 /* kernel stack*/ -#define KSTACK_GUARD_PAGES 1 /* pages of kstack guard; 0 disables */ +#define KSTACK_PAGES 2 /* kernel stack*/ +#define KSTACK_GUARD_PAGES 2 /* pages of kstack guard; 0 disables */ #define UPAGES 2 diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h index 99dab78e165..0491b11b02e 100644 --- a/sys/mips/include/proc.h +++ b/sys/mips/include/proc.h @@ -44,7 +44,7 @@ */ struct mdthread { int md_flags; /* machine-dependent flags */ - int md_upte[KSTACK_PAGES - 1]; /* ptes for mapping u pcb */ + int md_upte[KSTACK_PAGES]; /* ptes for mapping u pcb */ int md_ss_addr; /* single step address for ptrace */ int md_ss_instr; /* single step instruction for ptrace */ register_t md_saved_intr; @@ -53,7 +53,6 @@ struct mdthread { int md_pc_ctrl; /* performance counter control */ int md_pc_count; /* performance counter */ int md_pc_spill; /* performance counter spill */ - vm_offset_t md_realstack; void *md_tls; }; diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 8c32b582c3c..aa775ea5d83 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -928,7 +928,7 @@ tlb_insert_random: */ GET_CPU_PCPU(k1) lw k0, PC_CURTHREAD(k1) - lw k0, TD_REALKSTACK(k0) + lw k0, TD_KSTACK(k0) sltu k0, k0, sp bnez k0, _C_LABEL(MipsKernGenException) nop @@ -975,7 +975,7 @@ tlb_insert_random: */ GET_CPU_PCPU(k1) lw k0, PC_CURTHREAD(k1) - sw zero, TD_REALKSTACK(k0) + sw zero, TD_KSTACK(k0) move a1, a0 PANIC("kernel stack overflow - trapframe at %p") diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index 6cec2b79435..b10a5e2327b 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$"); ASSYM(TD_PCB, offsetof(struct thread, td_pcb)); ASSYM(TD_UPTE, offsetof(struct thread, td_md.md_upte)); -ASSYM(TD_REALKSTACK, offsetof(struct thread, td_md.md_realstack)); +ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack)); ASSYM(TD_FLAGS, offsetof(struct thread, td_flags)); ASSYM(TD_LOCK, offsetof(struct thread, td_lock)); ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 6ca4ec9409a..b3f36e53fe6 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -298,14 +298,13 @@ mips_proc0_init(void) (long)kstack0)); thread0.td_kstack = kstack0; thread0.td_kstack_pages = KSTACK_PAGES; - thread0.td_md.md_realstack = roundup2(thread0.td_kstack, PAGE_SIZE * 2); /* * Do not use cpu_thread_alloc to initialize these fields * thread0 is the only thread that has kstack located in KSEG0 * while cpu_thread_alloc handles kstack allocated in KSEG2. */ - thread0.td_pcb = (struct pcb *)(thread0.td_md.md_realstack + - (thread0.td_kstack_pages - 1) * PAGE_SIZE) - 1; + thread0.td_pcb = (struct pcb *)(thread0.td_kstack + + thread0.td_kstack_pages * PAGE_SIZE) - 1; thread0.td_frame = &thread0.td_pcb->pcb_regs; /* Steal memory for the dynamic per-cpu area. */ diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 6bb38d47e3b..e3b7daf2ba7 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -2813,6 +2813,21 @@ pmap_align_superpage(vm_object_t object, vm_ooffset_t offset, *addr = ((*addr + SEGOFSET) & ~SEGOFSET) + superpage_offset; } +/* + * Increase the starting virtual address of the given mapping so + * that it is aligned to not be the second page in a TLB entry. + * This routine assumes that the length is appropriately-sized so + * that the allocation does not share a TLB entry at all if required. + */ +void +pmap_align_tlb(vm_offset_t *addr) +{ + if ((*addr & PAGE_SIZE) == 0) + return; + *addr += PAGE_SIZE; + return; +} + int pmap_pid_dump(int pid); int diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index 4fc3cbd6cb9..2919d21e5f3 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -339,7 +339,7 @@ blocked_loop: sw a1, PC_CURTHREAD(a3) lw a2, TD_PCB(a1) sw a2, PC_CURPCB(a3) - lw v0, TD_REALKSTACK(a1) + lw v0, TD_KSTACK(a1) li s0, MIPS_KSEG2_START # If Uarea addr is below kseg2, bltu v0, s0, sw2 # no need to insert in TLB. lw a1, TD_UPTE+0(s7) # t0 = first u. pte diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index cb8a8d90a1a..d385fddd9c4 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -217,13 +217,9 @@ cpu_thread_swapin(struct thread *td) * part of the thread struct so cpu_switch() can quickly map in * the pcb struct and kernel stack. */ - if (!(pte = pmap_segmap(kernel_pmap, td->td_md.md_realstack))) - panic("cpu_thread_swapin: invalid segmap"); - pte += ((vm_offset_t)td->td_md.md_realstack >> PAGE_SHIFT) & (NPTEPG - 1); - - for (i = 0; i < KSTACK_PAGES - 1; i++) { + for (i = 0; i < KSTACK_PAGES; i++) { + pte = pmap_pte(kernel_pmap, td->td_kstack + i * PAGE_SIZE); td->td_md.md_upte[i] = *pte & ~(PTE_RO|PTE_WIRED); - pte++; } } @@ -238,22 +234,14 @@ cpu_thread_alloc(struct thread *td) pt_entry_t *pte; int i; - if (td->td_kstack & (1 << PAGE_SHIFT)) - td->td_md.md_realstack = td->td_kstack + PAGE_SIZE; - else - td->td_md.md_realstack = td->td_kstack; - - td->td_pcb = (struct pcb *)(td->td_md.md_realstack + - (td->td_kstack_pages - 1) * PAGE_SIZE) - 1; + KASSERT((td->td_kstack & (1 << PAGE_SHIFT)) == 0, ("kernel stack must be aligned.")); + td->td_pcb = (struct pcb *)(td->td_kstack + + td->td_kstack_pages * PAGE_SIZE) - 1; td->td_frame = &td->td_pcb->pcb_regs; - if (!(pte = pmap_segmap(kernel_pmap, td->td_md.md_realstack))) - panic("cpu_thread_alloc: invalid segmap"); - pte += ((vm_offset_t)td->td_md.md_realstack >> PAGE_SHIFT) & (NPTEPG - 1); - - for (i = 0; i < KSTACK_PAGES - 1; i++) { + for (i = 0; i < KSTACK_PAGES; i++) { + pte = pmap_pte(kernel_pmap, td->td_kstack + i * PAGE_SIZE); td->td_md.md_upte[i] = *pte & ~(PTE_RO|PTE_WIRED); - pte++; } } diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 02fda073aea..51a3bbe4c7c 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -98,6 +98,9 @@ extern vm_offset_t kernel_vm_end; void pmap_align_superpage(vm_object_t, vm_ooffset_t, vm_offset_t *, vm_size_t); +#if defined(__mips__) +void pmap_align_tlb(vm_offset_t *); +#endif void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t); void pmap_clear_modify(vm_page_t m); void pmap_clear_reference(vm_page_t m); diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 83c468e0801..ca6d49c18f2 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -47,6 +47,7 @@ vm_offset_t kmem_alloc_contig(vm_map_t map, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, unsigned long alignment, unsigned long boundary, vm_memattr_t memattr); vm_offset_t kmem_alloc_nofault(vm_map_t, vm_size_t); +vm_offset_t kmem_alloc_nofault_space(vm_map_t, vm_size_t, int); vm_offset_t kmem_alloc_wait(vm_map_t, vm_size_t); void kmem_free(vm_map_t, vm_offset_t, vm_size_t); void kmem_free_wakeup(vm_map_t, vm_offset_t, vm_size_t); diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index c080ca04c6c..bcdfd343e1a 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -373,8 +373,17 @@ vm_thread_new(struct thread *td, int pages) /* * Get a kernel virtual address for this thread's kstack. */ +#if defined(__mips__) + /* + * We need to align the kstack's mapped address to fit within + * a single TLB entry. + */ + ks = kmem_alloc_nofault_space(kernel_map, + (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE, VMFS_TLB_ALIGNED_SPACE); +#else ks = kmem_alloc_nofault(kernel_map, (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); +#endif if (ks == 0) { printf("vm_thread_new: kstack allocation failed\n"); vm_object_deallocate(ksobj); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 90065721da8..739d289b613 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -118,6 +118,35 @@ kmem_alloc_nofault(map, size) return (addr); } +/* + * kmem_alloc_nofault_space: + * + * Allocate a virtual address range with no underlying object and + * no initial mapping to physical memory within the specified + * address space. Any mapping from this range to physical memory + * must be explicitly created prior to its use, typically with + * pmap_qenter(). Any attempt to create a mapping on demand + * through vm_fault() will result in a panic. + */ +vm_offset_t +kmem_alloc_nofault_space(map, size, find_space) + vm_map_t map; + vm_size_t size; + int find_space; +{ + vm_offset_t addr; + int result; + + size = round_page(size); + addr = vm_map_min(map); + result = vm_map_find(map, NULL, 0, &addr, size, find_space, + VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); + if (result != KERN_SUCCESS) { + return (0); + } + return (addr); +} + /* * Allocate wired-down memory in the kernel's address map * or a submap. diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c index fe0c0f51378..1d22fa6b116 100644 --- a/sys/vm/vm_map.c +++ b/sys/vm/vm_map.c @@ -1394,9 +1394,20 @@ vm_map_find(vm_map_t map, vm_object_t object, vm_ooffset_t offset, vm_map_unlock(map); return (KERN_NO_SPACE); } - if (find_space == VMFS_ALIGNED_SPACE) + switch (find_space) { + case VMFS_ALIGNED_SPACE: pmap_align_superpage(object, offset, addr, length); + break; +#ifdef VMFS_TLB_ALIGNED_SPACE + case VMFS_TLB_ALIGNED_SPACE: + pmap_align_tlb(addr); + break; +#endif + default: + break; + } + start = *addr; } result = vm_map_insert(map, object, offset, start, start + diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h index 5454ce6ed15..d5c5b511c43 100644 --- a/sys/vm/vm_map.h +++ b/sys/vm/vm_map.h @@ -326,6 +326,9 @@ long vmspace_wired_count(struct vmspace *vmspace); #define VMFS_NO_SPACE 0 /* don't find; use the given range */ #define VMFS_ANY_SPACE 1 /* find a range with any alignment */ #define VMFS_ALIGNED_SPACE 2 /* find a superpage-aligned range */ +#if defined(__mips__) +#define VMFS_TLB_ALIGNED_SPACE 3 /* find a TLB entry aligned range */ +#endif /* * vm_map_wire and vm_map_unwire option flags From 7b7d5b6c5829b4840dd666f5e887122f70c10d29 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 19 Apr 2010 00:18:14 +0000 Subject: [PATCH 131/532] vm_thread_swapout() can safely dirty the page before rather than after acquiring the page queues lock. --- sys/vm/vm_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index bcdfd343e1a..dbd5065d8b0 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -523,8 +523,8 @@ vm_thread_swapout(struct thread *td) m = vm_page_lookup(ksobj, i); if (m == NULL) panic("vm_thread_swapout: kstack already missing?"); - vm_page_lock_queues(); vm_page_dirty(m); + vm_page_lock_queues(); vm_page_unwire(m, 0); vm_page_unlock_queues(); } From 5f3173b5176c1a702f16c6fb1a021e7e7be405c6 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Mon, 19 Apr 2010 06:01:58 +0000 Subject: [PATCH 132/532] o) Fix XKPHYS physical address extraction. Also define cache coherency attributes for XKPHYS. o) Make coprocessor 0 accessor function macros for register+selector registers take the full name so that e.g. (as done in this commit), prid selector 1 can be written through mips_wr_ebase() rather than mips_wr_prid1(). o) Allow for sign extension of 32-bit segment addresses. o) Remove an unused MIPS-I register number. --- sys/mips/cavium/octeon_machdep.c | 10 -------- sys/mips/cavium/octeon_mp.c | 2 +- sys/mips/include/cpufunc.h | 32 ++++++++++++------------- sys/mips/include/cpuregs.h | 40 ++++++++++++++++++++------------ sys/mips/mips/genassym.c | 6 +++++ 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/sys/mips/cavium/octeon_machdep.c b/sys/mips/cavium/octeon_machdep.c index c796071a385..d5df4b426ea 100644 --- a/sys/mips/cavium/octeon_machdep.c +++ b/sys/mips/cavium/octeon_machdep.c @@ -86,16 +86,6 @@ static void octeon_boot_params_init(register_t ptr); static uint64_t ciu_get_intr_sum_reg_addr(int core_num, int intx, int enx); static uint64_t ciu_get_intr_en_reg_addr(int core_num, int intx, int enx); -static __inline void -mips_wr_ebase(u_int32_t a0) -{ - __asm __volatile("mtc0 %[a0], $15, 1 ;" - : - : [a0] "r"(a0)); - - mips_barrier(); -} - void platform_cpu_init() { diff --git a/sys/mips/cavium/octeon_mp.c b/sys/mips/cavium/octeon_mp.c index 85cdc45dadd..8ded87ee282 100644 --- a/sys/mips/cavium/octeon_mp.c +++ b/sys/mips/cavium/octeon_mp.c @@ -69,7 +69,7 @@ platform_init_ap(int cpuid) /* * Set the exception base. */ - mips_wr_prid1(0x80000000 | cpuid); + mips_wr_ebase(0x80000000 | cpuid); /* * Set up interrupts, clear IPIs and unmask the IPI interrupt. diff --git a/sys/mips/include/cpufunc.h b/sys/mips/include/cpufunc.h index 9c34e3152d8..6520671137a 100644 --- a/sys/mips/include/cpufunc.h +++ b/sys/mips/include/cpufunc.h @@ -166,7 +166,7 @@ mips_wr_ ## n (uint32_t a0) \ #define MIPS_RDRW32_COP0_SEL(n,r,s) \ static __inline uint32_t \ -mips_rd_ ## n ## s(void) \ +mips_rd_ ## n(void) \ { \ int v0; \ __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ @@ -175,7 +175,7 @@ mips_rd_ ## n ## s(void) \ return (v0); \ } \ static __inline void \ -mips_wr_ ## n ## s(uint32_t a0) \ +mips_wr_ ## n(uint32_t a0) \ { \ __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ __XSTRING(COP0_SYNC)";" \ @@ -201,9 +201,9 @@ static __inline void mips_sync_icache (void) MIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE); MIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG); -MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 1); -MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 2); -MIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 3); +MIPS_RDRW32_COP0_SEL(config1, MIPS_COP_0_CONFIG, 1); +MIPS_RDRW32_COP0_SEL(config2, MIPS_COP_0_CONFIG, 2); +MIPS_RDRW32_COP0_SEL(config3, MIPS_COP_0_CONFIG, 3); MIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT); MIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX); MIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED); @@ -219,20 +219,20 @@ MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); #endif MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); /* XXX 64-bit? */ -MIPS_RDRW32_COP0_SEL(prid, MIPS_COP_0_PRID, 1); +MIPS_RDRW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1); MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); -MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1); -MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2); -MIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 3); +MIPS_RDRW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1); +MIPS_RDRW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2); +MIPS_RDRW32_COP0_SEL(watchlo3, MIPS_COP_0_WATCH_LO, 3); MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); -MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 1); -MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 2); -MIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 3); +MIPS_RDRW32_COP0_SEL(watchhi1, MIPS_COP_0_WATCH_HI, 1); +MIPS_RDRW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2); +MIPS_RDRW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3); -MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 0); -MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 1); -MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 2); -MIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 3); +MIPS_RDRW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0); +MIPS_RDRW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1); +MIPS_RDRW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2); +MIPS_RDRW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3); #undef MIPS_RDRW32_COP0 diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index 74e789c1416..3f4ffd208ba 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -78,21 +78,36 @@ * Caching of mapped addresses is controlled by bits in the TLB entry. */ -#define MIPS_KUSEG_START 0x0 -#define MIPS_KSEG0_START 0x80000000 -#define MIPS_KSEG0_END 0x9fffffff -#define MIPS_KSEG1_START 0xa0000000 -#define MIPS_KSEG1_END 0xbfffffff -#define MIPS_KSSEG_START 0xc0000000 -#define MIPS_KSSEG_END 0xdfffffff +#if !defined(_LOCORE) +#define MIPS_KUSEG_START 0x00000000 +#define MIPS_KSEG0_START ((intptr_t)(int32_t)0x80000000) +#define MIPS_KSEG0_END ((intptr_t)(int32_t)0x9fffffff) +#define MIPS_KSEG1_START ((intptr_t)(int32_t)0xa0000000) +#define MIPS_KSEG1_END ((intptr_t)(int32_t)0xbfffffff) +#define MIPS_KSSEG_START ((intptr_t)(int32_t)0xc0000000) +#define MIPS_KSSEG_END ((intptr_t)(int32_t)0xdfffffff) +#define MIPS_KSEG3_START ((intptr_t)(int32_t)0xe0000000) +#define MIPS_KSEG3_END ((intptr_t)(int32_t)0xffffffff) + #define MIPS_KSEG2_START MIPS_KSSEG_START #define MIPS_KSEG2_END MIPS_KSSEG_END -#define MIPS_KSEG3_START 0xe0000000 -#define MIPS_KSEG3_END 0xffffffff +#endif + +#define MIPS_XKPHYS_START 0x8000000000000000 +#define MIPS_XKPHYS_END 0xbfffffffffffffff + +#define MIPS_XKPHYS_CCA_UC 0x02 /* Uncached. */ +#define MIPS_XKPHYS_CCA_CNC 0x03 /* Cacheable non-coherent. */ #define MIPS_PHYS_TO_XKPHYS(cca,x) \ ((0x2ULL << 62) | ((unsigned long long)(cca) << 59) | (x)) -#define MIPS_XKPHYS_TO_PHYS(x) ((x) & 0x0effffffffffffffULL) +#define MIPS_XKPHYS_TO_PHYS(x) ((x) & 0x07ffffffffffffffULL) + +#define MIPS_XUSEG_START 0x0000000000000000 +#define MIPS_XUSEG_END 0x0000010000000000 + +#define MIPS_XKSEG_START 0xc000000000000000 +#define MIPS_XKSEG_END 0xc00000ff80000000 /* CPU dependent mtc0 hazard hook */ #ifdef TARGET_OCTEON @@ -471,7 +486,6 @@ * (3=32bit, 6=64bit, i=impl dep) * 0 MIPS_COP_0_TLB_INDEX 3333 TLB Index. * 1 MIPS_COP_0_TLB_RANDOM 3333 TLB Random. - * 2 MIPS_COP_0_TLB_LOW 3... r3k TLB entry low. * 2 MIPS_COP_0_TLB_LO0 .636 r4k TLB entry low. * 3 MIPS_COP_0_TLB_LO1 .636 r4k TLB entry low, extended. * 4 MIPS_COP_0_TLB_CONTEXT 3636 TLB Context. @@ -531,10 +545,6 @@ #define MIPS_COP_0_EXC_PC _(14) #define MIPS_COP_0_PRID _(15) - -/* MIPS-I */ -#define MIPS_COP_0_TLB_LOW _(2) - /* MIPS-III */ #define MIPS_COP_0_TLB_LO0 _(2) #define MIPS_COP_0_TLB_LO1 _(3) diff --git a/sys/mips/mips/genassym.c b/sys/mips/mips/genassym.c index b10a5e2327b..53f962b69f3 100644 --- a/sys/mips/mips/genassym.c +++ b/sys/mips/mips/genassym.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -91,9 +92,14 @@ ASSYM(SIGF_UC, offsetof(struct sigframe, sf_uc)); ASSYM(SIGFPE, SIGFPE); ASSYM(PAGE_SHIFT, PAGE_SHIFT); ASSYM(PAGE_SIZE, PAGE_SIZE); +ASSYM(PAGE_MASK, PAGE_MASK); ASSYM(SEGSHIFT, SEGSHIFT); ASSYM(NPTEPG, NPTEPG); ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED); ASSYM(TDF_ASTPENDING, TDF_ASTPENDING); ASSYM(PCPU_SIZE, sizeof(struct pcpu)); ASSYM(MAXCOMLEN, MAXCOMLEN); + +ASSYM(MIPS_KSEG0_START, MIPS_KSEG0_START); +ASSYM(MIPS_KSEG1_START, MIPS_KSEG1_START); +ASSYM(MIPS_KSEG2_START, MIPS_KSEG2_START); From 745bba1ab0e26d708f044f6f3fdce5364e8ab4f9 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Mon, 19 Apr 2010 07:34:26 +0000 Subject: [PATCH 133/532] o) Eliminate the "stand" frame and its use. Use CALLFRAME_* everywhere. o) Use macros for register-width, etc., rather than doing it by hand in a few more assembly files. o) Reduce diffs between various bits of TLB refill code in exception.S and between interrupt processing code. o) Use PTR_* to operate on registers that are pointers (e.g. sp). o) Add and use a macro, CLEAR_PTE_SWBITS rather than using the mysteriously-named WIRED_SHIFT to select bits to truncate when loading PTEs. o) Don't doubly disable interrupts by moving zero to the status register, especially since that has the nasty side-effect of taking us out of 64-bit mode. o) Use CLEAR_STATUS to disable interrupts the first time. o) Keep SR_PX set as well as SR_[KSU]X when doing exception processing. This is the bit that determines whether 64-bit operations are allowed. o) Don't enable interrupts until configure_final(), like most other ports. --- sys/mips/include/regnum.h | 4 - sys/mips/mips/autoconf.c | 1 + sys/mips/mips/exception.S | 431 ++++++++++++++++--------------------- sys/mips/mips/fp.S | 10 +- sys/mips/mips/machdep.c | 1 - sys/mips/mips/swtch.S | 131 ++++------- sys/mips/mips/vm_machdep.c | 6 +- 7 files changed, 236 insertions(+), 348 deletions(-) diff --git a/sys/mips/include/regnum.h b/sys/mips/include/regnum.h index baa60bd8b86..1c22bb96961 100644 --- a/sys/mips/include/regnum.h +++ b/sys/mips/include/regnum.h @@ -42,10 +42,6 @@ #ifndef _MACHINE_REGNUM_H_ #define _MACHINE_REGNUM_H_ -#define STAND_ARG_SIZE 16 -#define STAND_FRAME_SIZE 24 -#define STAND_RA_OFFSET 20 - /* This must match the numbers * in pcb.h and is used by * swtch.S diff --git a/sys/mips/mips/autoconf.c b/sys/mips/mips/autoconf.c index 99fd541927f..e16c05c147d 100644 --- a/sys/mips/mips/autoconf.c +++ b/sys/mips/mips/autoconf.c @@ -102,6 +102,7 @@ static void configure_final(dummy) void *dummy; { + intr_enable(); cninit_finish(); diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index aa775ea5d83..aa2a0a6b5e9 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -66,37 +66,14 @@ #include "assym.s" -#if defined(ISA_MIPS32) -#undef WITH_64BIT_CP0 -#elif defined(ISA_MIPS64) -#define WITH_64BIT_CP0 -#elif defined(ISA_MIPS3) -#define WITH_64BIT_CP0 -#else -#error "Please write the code for this ISA" -#endif +/* + * Clear the software-managed bits in a PTE in register pr. + */ +#define CLEAR_PTE_SWBITS(pr) \ + sll pr, 2 ; \ + srl pr, 2 # keep bottom 30 bits -#ifdef WITH_64BIT_CP0 -#define _SLL dsll -#define _SRL dsrl -#define _MFC0 dmfc0 -#define _MTC0 dmtc0 -#define WIRED_SHIFT 34 -#else -#define _SLL sll -#define _SRL srl -#define _MFC0 mfc0 -#define _MTC0 mtc0 -#define WIRED_SHIFT 2 -#endif .set noreorder # Noreorder is default style! -#if defined(ISA_MIPS32) - .set mips32 -#elif defined(ISA_MIPS64) - .set mips64 -#elif defined(ISA_MIPS3) - .set mips3 -#endif /* * Reasonable limit @@ -125,12 +102,12 @@ * * */ - - .set noat VECTOR(MipsTLBMiss, unknown) - j _C_LABEL(MipsDoTLBMiss) - mfc0 k0, COP_0_BAD_VADDR # get the fault address - nop + .set push + .set noat + j MipsDoTLBMiss + MFC0 k0, COP_0_BAD_VADDR # get the fault address + .set pop VECTOR_END(MipsTLBMiss) /* @@ -145,42 +122,40 @@ VECTOR_END(MipsTLBMiss) * let the processor trap to load the correct value after service. *---------------------------------------------------------------------------- */ + .set push + .set noat MipsDoTLBMiss: - #k0 already has BadVA - bltz k0, 1f #02: k0<0 -> 1f (kernel fault) - srl k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost) + bltz k0, 1f #02: k0<0 -> 1f (kernel fault) + PTR_SRL k0, k0, SEGSHIFT - 2 #03: k0=seg offset (almost) + GET_CPU_PCPU(k1) - lw k1, PC_SEGBASE(k1) - beqz k1, 2f #05: make sure segbase is not null - andi k0, k0, 0x7fc #06: k0=seg offset (mask 0x3) -#xxx mips64 unsafe? - addu k1, k0, k1 #07: k1=seg entry address - lw k1, 0(k1) #08: k1=seg entry - mfc0 k0, COP_0_BAD_VADDR #09: k0=bad address (again) - beq k1, zero, 2f #0a: ==0 -- no page table - srl k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10) + PTR_L k1, PC_SEGBASE(k1) + beqz k1, 2f #05: make sure segbase is not null + andi k0, k0, 0xffc #06: k0=seg offset (mask 0x3) + PTR_ADDU k1, k0, k1 #07: k1=seg entry address - andi k0, k0, ((NPTEPG/2) - 1) << 3 #0c: k0=page tab offset -#xxx mips64 unsafe? - addu k1, k1, k0 #0d: k1=pte address - lw k0, 0(k1) #0e: k0=lo0 pte - lw k1, 4(k1) #0f: k1=lo1 pte - _SLL k0, k0, WIRED_SHIFT #10: keep bottom 30 bits - _SRL k0, k0, WIRED_SHIFT #11: keep bottom 30 bits - _MTC0 k0, COP_0_TLB_LO0 #12: lo0 is loaded - _SLL k1, k1, WIRED_SHIFT #13: keep bottom 30 bits - _SRL k1, k1, WIRED_SHIFT #14: keep bottom 30 bits - _MTC0 k1, COP_0_TLB_LO1 #15: lo1 is loaded + PTR_L k1, 0(k1) #08: k1=seg entry + MFC0 k0, COP_0_BAD_VADDR #09: k0=bad address (again) + beq k1, zero, 2f #0a: ==0 -- no page table + srl k0, PAGE_SHIFT - 2 #0b: k0=VPN (aka va>>10) + andi k0, k0, 0xff8 #0c: k0=page tab offset + PTR_ADDU k1, k1, k0 #0d: k1=pte address + lw k0, 0(k1) #0e: k0=lo0 pte + lw k1, 4(k1) #0f: k1=lo0 pte + CLEAR_PTE_SWBITS(k0) + MTC0 k0, COP_0_TLB_LO0 #12: lo0 is loaded + COP0_SYNC + CLEAR_PTE_SWBITS(k1) + MTC0 k1, COP_0_TLB_LO1 #15: lo1 is loaded + COP0_SYNC + tlbwr #1a: write to tlb HAZARD_DELAY - tlbwr #1a: write to tlb - HAZARD_DELAY - eret #1f: retUrn from exception -1: j _C_LABEL(MipsTLBMissException) #20: kernel exception - nop #21: branch delay slot -2: j SlowFault #22: no page table present - nop #23: branch delay slot - - .set at + eret #1f: retUrn from exception +1: j MipsTLBMissException #20: kernel exception + nop #21: branch delay slot +2: j SlowFault #22: no page table present + nop #23: branch delay slot + .set pop /* * This code is copied to the general exception vector address to @@ -207,7 +182,7 @@ VECTOR(MipsException, unknown) # the cause is already # shifted left by 2 bits so # we dont have to shift. - lw k0, 0(k0) # Get the function address + PTR_L k0, 0(k0) # Get the function address nop j k0 # Jump to the function. nop @@ -244,20 +219,9 @@ SlowFault: * *---------------------------------------------------------------------------- */ -#if defined(ISA_MIPS32) -#define STORE sw /* 32 bit mode regsave instruction */ -#define LOAD lw /* 32 bit mode regload instruction */ -#define RSIZE 4 /* 32 bit mode register size */ -#elif defined(ISA_MIPS64) -#define STORE sd /* 64 bit mode regsave instruction */ -#define LOAD ld /* 64 bit mode regload instruction */ -#define RSIZE 8 /* 64 bit mode register size */ -#else -#error "Please write code for this isa." -#endif #define SAVE_REG(reg, offs, base) \ - STORE reg, STAND_ARG_SIZE + (RSIZE * offs) (base) + REG_S reg, CALLFRAME_SIZ + (SZREG * offs) (base) #ifdef TARGET_OCTEON #define CLEAR_STATUS \ @@ -274,7 +238,7 @@ SlowFault: and a0, a0, a2 ; \ mtc0 a0, COP_0_STATUS_REG #endif - + /* * Save CPU and CP0 register state. * @@ -317,8 +281,8 @@ SlowFault: mfhi v1 ;\ mfc0 a0, COP_0_STATUS_REG ;\ mfc0 a1, COP_0_CAUSE_REG ;\ - mfc0 a2, COP_0_BAD_VADDR ;\ - mfc0 a3, COP_0_EXC_PC ;\ + MFC0 a2, COP_0_BAD_VADDR ;\ + MFC0 a3, COP_0_EXC_PC ;\ SAVE_REG(v0, MULLO, sp) ;\ SAVE_REG(v1, MULHI, sp) ;\ SAVE_REG(a0, SR, sp) ;\ @@ -332,20 +296,20 @@ SlowFault: PTR_ADDU v0, sp, KERN_EXC_FRAME_SIZE ;\ SAVE_REG(v0, SP, sp) ;\ CLEAR_STATUS ;\ - PTR_ADDU a0, sp, STAND_ARG_SIZE ;\ + PTR_ADDU a0, sp, CALLFRAME_SIZ ;\ ITLBNOPFIX #define RESTORE_REG(reg, offs, base) \ - LOAD reg, STAND_ARG_SIZE + (RSIZE * offs) (base) + REG_L reg, CALLFRAME_SIZ + (SZREG * offs) (base) #define RESTORE_CPU \ - mtc0 zero,COP_0_STATUS_REG ;\ + CLEAR_STATUS ;\ RESTORE_REG(k0, SR, sp) ;\ RESTORE_REG(t0, MULLO, sp) ;\ RESTORE_REG(t1, MULHI, sp) ;\ mtlo t0 ;\ mthi t1 ;\ - _MTC0 v0, COP_0_EXC_PC ;\ + MTC0 v0, COP_0_EXC_PC ;\ .set noat ;\ RESTORE_REG(AT, AST, sp) ;\ RESTORE_REG(v0, V0, sp) ;\ @@ -384,13 +348,13 @@ SlowFault: * the status register and the multiply lo and high registers. * In addition, we set this up for linkage conventions. */ -#define KERN_REG_SIZE (NUMSAVEREGS * RSIZE) -#define KERN_EXC_FRAME_SIZE (STAND_FRAME_SIZE + KERN_REG_SIZE + 16) +#define KERN_REG_SIZE (NUMSAVEREGS * SZREG) +#define KERN_EXC_FRAME_SIZE (CALLFRAME_SIZ + KERN_REG_SIZE + 16) NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra) .set noat - subu sp, sp, KERN_EXC_FRAME_SIZE - .mask 0x80000000, (STAND_RA_OFFSET - KERN_EXC_FRAME_SIZE) + PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE + .mask 0x80000000, (CALLFRAME_RA - KERN_EXC_FRAME_SIZE) /* * Save CPU state, building 'frame'. */ @@ -401,7 +365,7 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra) PTR_LA gp, _C_LABEL(_gp) PTR_LA k0, _C_LABEL(trap) jalr k0 - sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) # for debugging + REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging /* * Update interrupt mask in saved status register @@ -410,7 +374,6 @@ NNON_LEAF(MipsKernGenException, KERN_EXC_FRAME_SIZE, ra) * in trap handler */ mfc0 a0, COP_0_STATUS_REG - mtc0 zero, COP_0_STATUS_REG and a0, a0, SR_INT_MASK RESTORE_REG(a1, SR, sp) and a1, a1, ~SR_INT_MASK @@ -424,10 +387,10 @@ END(MipsKernGenException) #define SAVE_U_PCB_REG(reg, offs, base) \ - STORE reg, U_PCB_REGS + (RSIZE * offs) (base) + REG_S reg, U_PCB_REGS + (SZREG * offs) (base) #define RESTORE_U_PCB_REG(reg, offs, base) \ - LOAD reg, U_PCB_REGS + (RSIZE * offs) (base) + REG_L reg, U_PCB_REGS + (SZREG * offs) (base) /*---------------------------------------------------------------------------- * @@ -443,14 +406,14 @@ END(MipsKernGenException) * *---------------------------------------------------------------------------- */ -NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) +NNON_LEAF(MipsUserGenException, CALLFRAME_SIZ, ra) .set noat - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) /* * Save all of the registers except for the kernel temporaries in u.u_pcb. */ GET_CPU_PCPU(k1) - lw k1, PC_CURPCB(k1) + PTR_L k1, PC_CURPCB(k1) SAVE_U_PCB_REG(AT, AST, k1) .set at SAVE_U_PCB_REG(v0, V0, k1) @@ -476,17 +439,17 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) SAVE_U_PCB_REG(s2, S2, k1) SAVE_U_PCB_REG(s3, S3, k1) SAVE_U_PCB_REG(s4, S4, k1) - mfc0 a2, COP_0_BAD_VADDR # Third arg is the fault addr + MFC0 a2, COP_0_BAD_VADDR # Third arg is the fault addr SAVE_U_PCB_REG(s5, S5, k1) SAVE_U_PCB_REG(s6, S6, k1) SAVE_U_PCB_REG(s7, S7, k1) SAVE_U_PCB_REG(t8, T8, k1) - mfc0 a3, COP_0_EXC_PC # Fourth arg is the pc. + MFC0 a3, COP_0_EXC_PC # Fourth arg is the pc. SAVE_U_PCB_REG(t9, T9, k1) SAVE_U_PCB_REG(gp, GP, k1) SAVE_U_PCB_REG(sp, SP, k1) SAVE_U_PCB_REG(s8, S8, k1) - subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP + PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP SAVE_U_PCB_REG(ra, RA, k1) SAVE_U_PCB_REG(v0, MULLO, k1) SAVE_U_PCB_REG(v1, MULHI, k1) @@ -494,12 +457,12 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) SAVE_U_PCB_REG(a1, CAUSE, k1) SAVE_U_PCB_REG(a2, BADVADDR, k1) SAVE_U_PCB_REG(a3, PC, k1) - sw a3, STAND_RA_OFFSET(sp) # for debugging + REG_S a3, CALLFRAME_RA(sp) # for debugging PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP # Turn off fpu and enter kernel mode and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_KSU_MASK | SR_INT_ENAB) #ifdef TARGET_OCTEON - or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) + or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS32_SR_PX) #endif mtc0 t0, COP_0_STATUS_REG PTR_ADDU a0, k1, U_PCB_REGS @@ -518,10 +481,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) */ DO_AST - mfc0 t0, COP_0_STATUS_REG # disable int - and t0, t0, ~(MIPS_SR_INT_IE) - mtc0 t0, COP_0_STATUS_REG - ITLBNOPFIX + CLEAR_STATUS /* * The use of k1 for storing the PCB pointer must be done only @@ -529,7 +489,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) * by the interrupt code. */ GET_CPU_PCPU(k1) - lw k1, PC_CURPCB(k1) + PTR_L k1, PC_CURPCB(k1) /* * Update interrupt mask in saved status register @@ -549,7 +509,7 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) mthi t1 RESTORE_U_PCB_REG(a0, PC, k1) RESTORE_U_PCB_REG(v0, V0, k1) - _MTC0 a0, COP_0_EXC_PC # set return address + MTC0 a0, COP_0_EXC_PC # set return address RESTORE_U_PCB_REG(v1, V1, k1) RESTORE_U_PCB_REG(a0, A0, k1) RESTORE_U_PCB_REG(a1, A1, k1) @@ -578,9 +538,6 @@ NNON_LEAF(MipsUserGenException, STAND_FRAME_SIZE, ra) RESTORE_U_PCB_REG(k0, SR, k1) RESTORE_U_PCB_REG(s8, S8, k1) RESTORE_U_PCB_REG(ra, RA, k1) -#ifdef TARGET_OCTEON - and k0, k0, ~(MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) -#endif .set noat RESTORE_U_PCB_REG(AT, AST, k1) @@ -610,27 +567,25 @@ END(MipsUserGenException) NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra) .set noat - subu sp, sp, KERN_EXC_FRAME_SIZE - .mask 0x80000000, (STAND_RA_OFFSET - KERN_EXC_FRAME_SIZE) + PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE + .mask 0x80000000, (CALLFRAME_RA - KERN_EXC_FRAME_SIZE) /* - * Save the relevant kernel registers onto the stack. + * Save CPU state, building 'frame'. */ SAVE_CPU - /* - * Call the interrupt handler. + * Call the interrupt handler. a0 points at the saved frame. */ PTR_LA gp, _C_LABEL(_gp) - PTR_ADDU a0, sp, STAND_ARG_SIZE PTR_LA k0, _C_LABEL(cpu_intr) jalr k0 - sw a3, STAND_RA_OFFSET + KERN_REG_SIZE(sp) - /* Why no AST processing here? */ + REG_S a3, CALLFRAME_RA + KERN_REG_SIZE(sp) # for debugging /* * Update interrupt mask in saved status register * Some of interrupts could be disabled by - * intr filters + * intr filters if interrupts are enabled later + * in trap handler */ mfc0 a0, COP_0_STATUS_REG and a0, a0, SR_INT_MASK @@ -638,12 +593,8 @@ NNON_LEAF(MipsKernIntr, KERN_EXC_FRAME_SIZE, ra) and a1, a1, ~SR_INT_MASK or a1, a1, a0 SAVE_REG(a1, SR, sp) - -/* - * Restore registers and return from the interrupt. - */ - lw v0, STAND_RA_OFFSET + KERN_REG_SIZE(sp) - RESTORE_CPU + REG_L v0, CALLFRAME_RA + KERN_REG_SIZE(sp) + RESTORE_CPU # v0 contains the return address. sync eret .set at @@ -668,15 +619,15 @@ END(MipsKernIntr) * *---------------------------------------------------------------------------- */ -NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) +NNON_LEAF(MipsUserIntr, CALLFRAME_SIZ, ra) .set noat - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) /* * Save the relevant user registers into the u.u_pcb struct. * We don't need to save s0 - s8 because the compiler does it for us. */ GET_CPU_PCPU(k1) - lw k1, PC_CURPCB(k1) + PTR_L k1, PC_CURPCB(k1) SAVE_U_PCB_REG(AT, AST, k1) .set at SAVE_U_PCB_REG(v0, V0, k1) @@ -715,19 +666,19 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) mfhi v1 mfc0 a0, COP_0_STATUS_REG mfc0 a1, COP_0_CAUSE_REG - mfc0 a3, COP_0_EXC_PC + MFC0 a3, COP_0_EXC_PC SAVE_U_PCB_REG(v0, MULLO, k1) SAVE_U_PCB_REG(v1, MULHI, k1) SAVE_U_PCB_REG(a0, SR, k1) SAVE_U_PCB_REG(a1, CAUSE, k1) SAVE_U_PCB_REG(a3, PC, k1) # PC in a3, note used later! - subu sp, k1, STAND_FRAME_SIZE # switch to kernel SP + PTR_SUBU sp, k1, CALLFRAME_SIZ # switch to kernel SP PTR_LA gp, _C_LABEL(_gp) # switch to kernel GP # Turn off fpu, disable interrupts, set kernel mode kernel mode, clear exception level. and t0, a0, ~(SR_COP_1_BIT | SR_EXL | SR_INT_ENAB | SR_KSU_MASK) #ifdef TARGET_OCTEON - or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) + or t0, t0, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS32_SR_PX) #endif mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX @@ -737,7 +688,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) */ PTR_LA k0, _C_LABEL(cpu_intr) jalr k0 - sw a3, STAND_RA_OFFSET(sp) # for debugging + REG_S a3, CALLFRAME_RA(sp) # for debugging /* * Enable interrupts before doing ast(). @@ -759,13 +710,10 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) /* * Restore user registers and return. */ - mfc0 t0, COP_0_STATUS_REG # disable int - and t0, t0, ~(MIPS_SR_INT_IE) - mtc0 t0, COP_0_STATUS_REG - ITLBNOPFIX + CLEAR_STATUS GET_CPU_PCPU(k1) - lw k1, PC_CURPCB(k1) + PTR_L k1, PC_CURPCB(k1) /* * Update interrupt mask in saved status register @@ -793,7 +741,7 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) RESTORE_U_PCB_REG(t2, PC, k1) mtlo t0 mthi t1 - _MTC0 t2, COP_0_EXC_PC # set return address + MTC0 t2, COP_0_EXC_PC # set return address RESTORE_U_PCB_REG(v0, V0, k1) RESTORE_U_PCB_REG(v1, V1, k1) RESTORE_U_PCB_REG(a0, A0, k1) @@ -814,9 +762,6 @@ NNON_LEAF(MipsUserIntr, STAND_FRAME_SIZE, ra) RESTORE_U_PCB_REG(k0, SR, k1) RESTORE_U_PCB_REG(sp, SP, k1) RESTORE_U_PCB_REG(ra, RA, k1) -#ifdef TARGET_OCTEON - and k0, k0, ~(MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) -#endif .set noat RESTORE_U_PCB_REG(AT, AST, k1) @@ -832,78 +777,78 @@ NLEAF(MipsTLBInvalidException) .set noat .set noreorder - mfc0 k0, COP_0_BAD_VADDR - li k1, VM_MAXUSER_ADDRESS - sltu k1, k0, k1 - bnez k1, 1f + MFC0 k0, COP_0_BAD_VADDR + PTR_LI k1, VM_MAXUSER_ADDRESS + sltu k1, k0, k1 + bnez k1, 1f nop - /* badvaddr = kernel address */ - lui k1, %hi(_C_LABEL(kernel_segmap)) - b 2f - lw k1, %lo(_C_LABEL(kernel_segmap))(k1) + /* Kernel address. */ + lui k1, %hi(kernel_segmap) # k1=hi of segbase + b 2f + PTR_L k1, %lo(kernel_segmap)(k1) # k1=segment tab base -1: - /* badvaddr = user address */ +1: /* User address. */ GET_CPU_PCPU(k1) - lw k1, PC_SEGBASE(k1) + PTR_L k1, PC_SEGBASE(k1) -2: - beqz k1, 3f /* invalid page directory pointer */ +2: /* Validate page directory pointer. */ + beqz k1, 3f nop - srl k0, SEGSHIFT - 2 - andi k0, 0xffc - addu k1, k1, k0 - lw k1, 0(k1) - beqz k1, 3f /* invalid page table page pointer */ + PTR_SRL k0, SEGSHIFT - 2 # k0=seg offset (almost) + beq k1, zero, MipsKernGenException # ==0 -- no seg tab + andi k0, k0, 0xffc # k0=seg offset (mask 0x3) + PTR_ADDU k1, k0, k1 # k1=seg entry address + PTR_L k1, 0(k1) # k1=seg entry + + /* Validate page table pointer. */ + beqz k1, 3f nop - mfc0 k0, COP_0_BAD_VADDR - srl k0, PAGE_SHIFT - 2 - andi k0, 0xffc - addu k1, k1, k0 + MFC0 k0, COP_0_BAD_VADDR # k0=bad address (again) + PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN + andi k0, k0, 0xffc # k0=page tab offset + PTR_ADDU k1, k1, k0 # k1=pte address + lw k0, 0(k1) # k0=this PTE - lw k0, 0(k1) - andi k0, PTE_V - beqz k0, 3f /* invalid page table entry */ + /* Validate page table entry. */ + andi k0, PTE_V + beqz k0, 3f nop - andi k0, k1, 4 - bnez k0, odd_page + /* Check whether this is an even or odd entry. */ + andi k0, k1, 4 + bnez k0, odd_page nop -even_page: - lw k0, 0(k1) - _SLL k0, k0, WIRED_SHIFT - _SRL k0, k0, WIRED_SHIFT - _MTC0 k0, COP_0_TLB_LO0 + lw k0, 0(k1) + lw k1, 4(k1) + CLEAR_PTE_SWBITS(k0) + MTC0 k0, COP_0_TLB_LO0 + COP0_SYNC + CLEAR_PTE_SWBITS(k1) + MTC0 k1, COP_0_TLB_LO1 + COP0_SYNC - lw k0, 4(k1) - _SLL k0, k0, WIRED_SHIFT - _SRL k0, k0, WIRED_SHIFT - _MTC0 k0, COP_0_TLB_LO1 - - b tlb_insert_entry + b tlb_insert_entry nop odd_page: - lw k0, 0(k1) - _SLL k0, k0, WIRED_SHIFT - _SRL k0, k0, WIRED_SHIFT - _MTC0 k0, COP_0_TLB_LO1 - - lw k0, -4(k1) - _SLL k0, k0, WIRED_SHIFT - _SRL k0, k0, WIRED_SHIFT - _MTC0 k0, COP_0_TLB_LO0 + lw k0, -4(k1) + lw k1, 0(k1) + CLEAR_PTE_SWBITS(k0) + MTC0 k0, COP_0_TLB_LO0 + COP0_SYNC + CLEAR_PTE_SWBITS(k1) + MTC0 k1, COP_0_TLB_LO1 + COP0_SYNC tlb_insert_entry: tlbp HAZARD_DELAY - mfc0 k0, COP_0_TLB_INDEX - HAZARD_DELAY - bltz k0, tlb_insert_random + mfc0 k0, COP_0_TLB_INDEX + bltz k0, tlb_insert_random nop tlbwi eret @@ -927,8 +872,8 @@ tlb_insert_random: * Check for kernel stack overflow. */ GET_CPU_PCPU(k1) - lw k0, PC_CURTHREAD(k1) - lw k0, TD_KSTACK(k0) + PTR_L k0, PC_CURTHREAD(k1) + PTR_L k0, TD_KSTACK(k0) sltu k0, k0, sp bnez k0, _C_LABEL(MipsKernGenException) nop @@ -944,8 +889,8 @@ tlb_insert_random: sll k1, k1, PAGE_SHIFT + 1 PTR_LA k0, _C_LABEL(pcpu_space) - addiu k0, (PAGE_SIZE * 2) - addu k0, k0, k1 + PTR_ADDU k0, PAGE_SIZE * 2 + PTR_ADDU k0, k0, k1 /* * Stash the original value of 'sp' so we can update trapframe later. @@ -954,12 +899,12 @@ tlb_insert_random: move k1, sp move sp, k0 - subu sp, sp, KERN_EXC_FRAME_SIZE + PTR_SUBU sp, sp, KERN_EXC_FRAME_SIZE move k0, ra move ra, zero - sw ra, CALLFRAME_RA(sp) /* stop the ddb backtrace right here */ - sw zero, CALLFRAME_SP(sp) + REG_S ra, CALLFRAME_RA(sp) /* stop the ddb backtrace right here */ + REG_S zero, CALLFRAME_SP(sp) move ra, k0 SAVE_CPU @@ -974,8 +919,8 @@ tlb_insert_random: * Squelch any more overflow checks by setting the stack base to 0. */ GET_CPU_PCPU(k1) - lw k0, PC_CURTHREAD(k1) - sw zero, TD_KSTACK(k0) + PTR_L k0, PC_CURTHREAD(k1) + PTR_S zero, TD_KSTACK(k0) move a1, a0 PANIC("kernel stack overflow - trapframe at %p") @@ -1008,34 +953,30 @@ END(MipsTLBInvalidException) */ NLEAF(MipsTLBMissException) .set noat - mfc0 k0, COP_0_BAD_VADDR # k0=bad address - li k1, (VM_MAX_KERNEL_ADDRESS) # check fault address against - sltu k1, k1, k0 # upper bound of kernel_segmap - bnez k1, _C_LABEL(MipsKernGenException) # out of bound - lui k1, %hi(_C_LABEL(kernel_segmap)) # k1=hi of segbase - srl k0, 20 # k0=seg offset (almost) - lw k1, %lo(_C_LABEL(kernel_segmap))(k1) # k1=segment tab base - beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no seg tab - andi k0, k0, 0xffc # k0=seg offset (mask 0x3) -#xxx mips64 unsafe - addu k1, k0, k1 # k1=seg entry address - lw k1, 0(k1) # k1=seg entry - mfc0 k0, COP_0_BAD_VADDR # k0=bad address (again) - beq k1, zero, _C_LABEL(MipsKernGenException) # ==0 -- no page table - srl k0, 10 # k0=VPN (aka va>>10) - andi k0, k0, 0xff8 # k0=page tab offset -#xxx mips64 unsafe - addu k1, k1, k0 # k1=pte address - lw k0, 0(k1) # k0=lo0 pte - lw k1, 4(k1) # k1=lo1 pte - _SLL k0, WIRED_SHIFT # chop bits [31..30] - _SRL k0, WIRED_SHIFT # chop bits [31..30] - _MTC0 k0, COP_0_TLB_LO0 # lo0 is loaded - _SLL k1, WIRED_SHIFT # chop bits [31..30] - _SRL k1, WIRED_SHIFT # chop bits [31..30] - _MTC0 k1, COP_0_TLB_LO1 # lo1 is loaded - - HAZARD_DELAY + MFC0 k0, COP_0_BAD_VADDR # k0=bad address + PTR_LI k1, VM_MAX_KERNEL_ADDRESS # check fault address against + sltu k1, k1, k0 # upper bound of kernel_segmap + bnez k1, MipsKernGenException # out of bound + lui k1, %hi(kernel_segmap) # k1=hi of segbase + PTR_SRL k0, SEGSHIFT - 2 # k0=seg offset (almost) + PTR_L k1, %lo(kernel_segmap)(k1) # k1=segment tab base + beq k1, zero, MipsKernGenException # ==0 -- no seg tab + andi k0, k0, 0xffc # k0=seg offset (mask 0x3) + PTR_ADDU k1, k0, k1 # k1=seg entry address + PTR_L k1, 0(k1) # k1=seg entry + MFC0 k0, COP_0_BAD_VADDR # k0=bad address (again) + beq k1, zero, MipsKernGenException # ==0 -- no page table + PTR_SRL k0, PAGE_SHIFT - 2 # k0=VPN + andi k0, k0, 0xff8 # k0=page tab offset + PTR_ADDU k1, k1, k0 # k1=pte address + lw k0, 0(k1) # k0=lo0 pte + lw k1, 4(k1) # k1=lo1 pte + CLEAR_PTE_SWBITS(k0) + MTC0 k0, COP_0_TLB_LO0 # lo0 is loaded + COP0_SYNC + CLEAR_PTE_SWBITS(k1) + MTC0 k1, COP_0_TLB_LO1 # lo1 is loaded + COP0_SYNC tlbwr # write to tlb HAZARD_DELAY eret # return from exception @@ -1061,11 +1002,11 @@ END(MipsTLBMissException) * *---------------------------------------------------------------------------- */ -NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) - subu sp, sp, STAND_FRAME_SIZE +NON_LEAF(MipsFPTrap, CALLFRAME_SIZ, ra) + PTR_SUBU sp, sp, CALLFRAME_SIZ mfc0 t0, COP_0_STATUS_REG - sw ra, STAND_RA_OFFSET(sp) - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) + REG_S ra, CALLFRAME_RA(sp) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) or t1, t0, SR_COP_1_BIT mtc0 t1, COP_0_STATUS_REG @@ -1086,10 +1027,10 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) * The instruction is in the branch delay slot so the branch will have to * be emulated to get the resulting PC. */ - sw a2, STAND_FRAME_SIZE + 8(sp) + PTR_S a2, CALLFRAME_SIZ + 8(sp) GET_CPU_PCPU(a0) #mips64 unsafe? - lw a0, PC_CURPCB(a0) + PTR_L a0, PC_CURPCB(a0) PTR_ADDU a0, a0, U_PCB_REGS # first arg is ptr to CPU registers move a1, a2 # second arg is instruction PC move a2, t1 # third arg is floating point CSR @@ -1100,7 +1041,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) * Now load the floating-point instruction in the branch delay slot * to be emulated. */ - lw a2, STAND_FRAME_SIZE + 8(sp) # restore EXC pc + PTR_L a2, CALLFRAME_SIZ + 8(sp) # restore EXC pc b 2f lw a0, 4(a2) # a0 = coproc instruction /* @@ -1110,10 +1051,10 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) 1: lw a0, 0(a2) # a0 = coproc instruction #xxx mips64 unsafe? - addu v0, a2, 4 # v0 = next pc + PTR_ADDU v0, a2, 4 # v0 = next pc 2: GET_CPU_PCPU(t2) - lw t2, PC_CURPCB(t2) + PTR_L t2, PC_CURPCB(t2) SAVE_U_PCB_REG(v0, PC, t2) # save new pc /* * Check to see if the instruction to be emulated is a floating-point @@ -1127,7 +1068,7 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) */ 3: GET_CPU_PCPU(a0) - lw a0, PC_CURTHREAD(a0) # get current thread + PTR_L a0, PC_CURTHREAD(a0) # get current thread cfc1 a2, FPC_CSR # code = FP execptions ctc1 zero, FPC_CSR # Clear exceptions PTR_LA t3, _C_LABEL(trapsignal) @@ -1149,12 +1090,12 @@ NON_LEAF(MipsFPTrap, STAND_FRAME_SIZE, ra) */ FPReturn: mfc0 t0, COP_0_STATUS_REG - lw ra, STAND_RA_OFFSET(sp) + PTR_L ra, CALLFRAME_RA(sp) and t0, t0, ~SR_COP_1_BIT mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX j ra - PTR_ADDU sp, sp, STAND_FRAME_SIZE + PTR_ADDU sp, sp, CALLFRAME_SIZ END(MipsFPTrap) /* @@ -1182,7 +1123,7 @@ VECTOR(MipsCache, unknown) PTR_LA k0, _C_LABEL(MipsCacheException) li k1, MIPS_PHYS_MASK and k0, k1 - li k1, MIPS_KSEG1_START + PTR_LI k1, MIPS_KSEG1_START or k0, k1 j k0 nop @@ -1200,16 +1141,16 @@ NESTED_NOPROFILE(MipsCacheException, KERN_EXC_FRAME_SIZE, ra) .mask 0x80000000, -4 PTR_LA k0, _C_LABEL(panic) # return to panic PTR_LA a0, 9f # panicstr - _MFC0 a1, COP_0_ERROR_PC + MFC0 a1, COP_0_ERROR_PC mfc0 a2, COP_0_CACHE_ERR # 3rd arg cache error - _MTC0 k0, COP_0_ERROR_PC # set return address + MTC0 k0, COP_0_ERROR_PC # set return address mfc0 k0, COP_0_STATUS_REG # restore status li k1, SR_DIAG_DE # ignore further errors or k0, k1 mtc0 k0, COP_0_STATUS_REG # restore status - HAZARD_DELAY + COP0_SYNC eret diff --git a/sys/mips/mips/fp.S b/sys/mips/mips/fp.S index afe9f03d1e0..ce1702eb225 100644 --- a/sys/mips/mips/fp.S +++ b/sys/mips/mips/fp.S @@ -94,9 +94,9 @@ * *---------------------------------------------------------------------------- */ -NON_LEAF(MipsEmulateFP, STAND_FRAME_SIZE, ra) - subu sp, sp, STAND_FRAME_SIZE - sw ra, STAND_RA_OFFSET(sp) +NON_LEAF(MipsEmulateFP, CALLFRAME_SIZ, ra) + subu sp, sp, CALLFRAME_SIZ + sw ra, CALLFRAME_RA(sp) /* * Decode the FMT field (bits 24-21) and FUNCTION field (bits 5-0). */ @@ -2247,8 +2247,8 @@ result_fs_d: # result is FS jal set_fd_d # save result (in t0,t1,t2,t3) done: - lw ra, STAND_RA_OFFSET(sp) - addu sp, sp, STAND_FRAME_SIZE + lw ra, CALLFRAME_RA(sp) + addu sp, sp, CALLFRAME_SIZ j ra END(MipsEmulateFP) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index b3f36e53fe6..a9c484c806e 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -369,7 +369,6 @@ mips_vector_init(void) * when handler is installed for it */ set_intr_mask(ALL_INT_MASK); - intr_enable(); /* Clear BEV in SR so we start handling our own exceptions */ mips_wr_status(mips_rd_status() & ~SR_BOOT_EXC_VEC); diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index 2919d21e5f3..f287476a3b3 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -65,53 +65,7 @@ #include "assym.s" -#if defined(ISA_MIPS32) -#undef WITH_64BIT_CP0 -#elif defined(ISA_MIPS64) -#define WITH_64BIT_CP0 -#elif defined(ISA_MIPS3) -#define WITH_64BIT_CP0 -#else -#error "Please write the code for this ISA" -#endif - -#ifdef WITH_64BIT_CP0 -#define _SLL dsll -#define _SRL dsrl -#define _MFC0 dmfc0 -#define _MTC0 dmtc0 -#define WIRED_SHIFT 34 -#else -#define _SLL sll -#define _SRL srl -#define _MFC0 mfc0 -#define _MTC0 mtc0 -#define WIRED_SHIFT 2 -#endif .set noreorder # Noreorder is default style! -#if defined(ISA_MIPS32) - .set mips32 -#elif defined(ISA_MIPS64) - .set mips64 -#elif defined(ISA_MIPS3) - .set mips3 -#endif - -#if defined(ISA_MIPS32) -#define STORE sw /* 32 bit mode regsave instruction */ -#define LOAD lw /* 32 bit mode regload instruction */ -#define RSIZE 4 /* 32 bit mode register size */ -#define STORE_FP swc1 /* 32 bit mode fp regsave instruction */ -#define LOAD_FP lwc1 /* 32 bit mode fp regload instruction */ -#define FP_RSIZE 4 /* 32 bit mode fp register size */ -#else -#define STORE sd /* 64 bit mode regsave instruction */ -#define LOAD ld /* 64 bit mode regload instruction */ -#define RSIZE 8 /* 64 bit mode register size */ -#define STORE_FP sdc1 /* 64 bit mode fp regsave instruction */ -#define LOAD_FP ldc1 /* 64 bit mode fp regload instruction */ -#define FP_RSIZE 8 /* 64 bit mode fp register size */ -#endif /* * FREEBSD_DEVELOPERS_FIXME @@ -125,28 +79,28 @@ #endif #define SAVE_U_PCB_REG(reg, offs, base) \ - STORE reg, U_PCB_REGS + (RSIZE * offs) (base) + REG_S reg, U_PCB_REGS + (SZREG * offs) (base) #define RESTORE_U_PCB_REG(reg, offs, base) \ - LOAD reg, U_PCB_REGS + (RSIZE * offs) (base) + REG_L reg, U_PCB_REGS + (SZREG * offs) (base) #define SAVE_U_PCB_FPREG(reg, offs, base) \ - STORE_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base) + FP_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base) #define RESTORE_U_PCB_FPREG(reg, offs, base) \ - LOAD_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base) + FP_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base) #define SAVE_U_PCB_FPSR(reg, offs, base) \ - STORE reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base) + REG_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base) #define RESTORE_U_PCB_FPSR(reg, offs, base) \ - LOAD reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base) + REG_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base) #define SAVE_U_PCB_CONTEXT(reg, offs, base) \ - STORE reg, U_PCB_CONTEXT + (RSIZE * offs) (base) + REG_S reg, U_PCB_CONTEXT + (SZREG * offs) (base) #define RESTORE_U_PCB_CONTEXT(reg, offs, base) \ - LOAD reg, U_PCB_CONTEXT + (RSIZE * offs) (base) + REG_L reg, U_PCB_CONTEXT + (SZREG * offs) (base) #define ITLBNOPFIX nop;nop;nop;nop;nop;nop;nop;nop;nop;nop; @@ -172,7 +126,7 @@ LEAF(fork_trampoline) */ .set noat GET_CPU_PCPU(k1) - lw k1, PC_CURPCB(k1) + PTR_L k1, PC_CURPCB(k1) RESTORE_U_PCB_REG(t0, MULLO, k1) RESTORE_U_PCB_REG(t1, MULHI, k1) @@ -181,7 +135,7 @@ LEAF(fork_trampoline) RESTORE_U_PCB_REG(a0, PC, k1) RESTORE_U_PCB_REG(AT, AST, k1) RESTORE_U_PCB_REG(v0, V0, k1) - _MTC0 a0, COP_0_EXC_PC # set return address + MTC0 a0, COP_0_EXC_PC # set return address RESTORE_U_PCB_REG(v1, V1, k1) RESTORE_U_PCB_REG(a0, A0, k1) @@ -265,7 +219,7 @@ END(savectx) KSEG0TEXT_START; -NON_LEAF(mips_cpu_throw, STAND_FRAME_SIZE, ra) +NON_LEAF(mips_cpu_throw, CALLFRAME_SIZ, ra) mfc0 t0, COP_0_STATUS_REG # t0 = saved status register nop nop @@ -285,7 +239,7 @@ END(mips_cpu_throw) * a2 - mtx * Find the highest priority process and resume it. */ -NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra) +NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra) mfc0 t0, COP_0_STATUS_REG # t0 = saved status register nop nop @@ -294,11 +248,11 @@ NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra) ITLBNOPFIX beqz a0, mips_sw1 move a3, a0 - lw a0, TD_PCB(a0) # load PCB addr of curproc + PTR_L a0, TD_PCB(a0) # load PCB addr of curproc SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0) # save old sp - subu sp, sp, STAND_FRAME_SIZE - sw ra, STAND_RA_OFFSET(sp) - .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) + PTR_SUBU sp, sp, CALLFRAME_SIZ + REG_S ra, CALLFRAME_RA(sp) + .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0) # do a 'savectx()' SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0) SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0) @@ -321,13 +275,13 @@ getpc: * to be saved with the other registers do so here. */ - sw a2, TD_LOCK(a3) # Switchout td_lock + PTR_S a2, TD_LOCK(a3) # Switchout td_lock mips_sw1: #if defined(SMP) && defined(SCHED_ULE) PTR_LA t0, _C_LABEL(blocked_lock) blocked_loop: - lw t1, TD_LOCK(a1) + PTR_L t1, TD_LOCK(a1) beq t0, t1, blocked_loop nop #endif @@ -336,20 +290,16 @@ blocked_loop: * Switch to new context. */ GET_CPU_PCPU(a3) - sw a1, PC_CURTHREAD(a3) - lw a2, TD_PCB(a1) - sw a2, PC_CURPCB(a3) - lw v0, TD_KSTACK(a1) - li s0, MIPS_KSEG2_START # If Uarea addr is below kseg2, + PTR_S a1, PC_CURTHREAD(a3) + PTR_L a2, TD_PCB(a1) + PTR_S a2, PC_CURPCB(a3) + PTR_L v0, TD_KSTACK(a1) +#if !defined(__mips_n64) + PTR_LI s0, MIPS_KSEG2_START # If Uarea addr is below kseg2, bltu v0, s0, sw2 # no need to insert in TLB. - lw a1, TD_UPTE+0(s7) # t0 = first u. pte - lw a2, TD_UPTE+4(s7) # t1 = 2nd u. pte - and s0, v0, PTE_ODDPG - beq s0, zero, entry0 - nop - - PANIC_KSEG0("USPACE sat on odd page boundary", t1) - +#endif + lw a1, TD_UPTE + 0(s7) # a1 = u. pte #0 + lw a2, TD_UPTE + 4(s7) # a2 = u. pte #1 /* * Wiredown the USPACE of newproc in TLB entry#0. Check whether target * USPACE is already in another place of TLB before that, and if so @@ -357,31 +307,32 @@ blocked_loop: * NOTE: This is hard coded to UPAGES == 2. * Also, there should be no TLB faults at this point. */ -entry0: - mtc0 v0, COP_0_TLB_HI # VPN = va + MTC0 v0, COP_0_TLB_HI # VPN = va HAZARD_DELAY tlbp # probe VPN HAZARD_DELAY mfc0 s0, COP_0_TLB_INDEX - nop -pgm: + HAZARD_DELAY + + PTR_LI t1, MIPS_KSEG0_START # invalidate tlb entry bltz s0, entry0set - li t1, MIPS_KSEG0_START # invalidate tlb entry + nop sll s0, PAGE_SHIFT + 1 addu t1, s0 - mtc0 t1, COP_0_TLB_HI + MTC0 t1, COP_0_TLB_HI mtc0 zero, COP_0_TLB_LO0 mtc0 zero, COP_0_TLB_LO1 HAZARD_DELAY tlbwi HAZARD_DELAY - mtc0 v0, COP_0_TLB_HI # set VPN again + MTC0 v0, COP_0_TLB_HI # set VPN again + entry0set: /* SMP!! - Works only for unshared TLB case - i.e. no v-cpus */ mtc0 zero, COP_0_TLB_INDEX # TLB entry #0 -# or a1, PG_G + HAZARD_DELAY mtc0 a1, COP_0_TLB_LO0 # upte[0] -# or a2, PG_G + HAZARD_DELAY mtc0 a2, COP_0_TLB_LO1 # upte[1] HAZARD_DELAY tlbwi # set TLB entry #0 @@ -396,7 +347,7 @@ sw2: /* * Restore registers and return. */ - lw a0, TD_PCB(s7) + PTR_L a0, TD_PCB(s7) RESTORE_U_PCB_CONTEXT(gp, PREG_GP, a0) RESTORE_U_PCB_CONTEXT(v0, PREG_SR, a0) # restore kernel context RESTORE_U_PCB_CONTEXT(ra, PREG_RA, a0) @@ -457,7 +408,7 @@ LEAF(MipsSwitchFPState) * First read out the status register to make sure that all FP operations * have completed. */ - lw a0, TD_PCB(a0) # get pointer to pcb for proc + PTR_L a0, TD_PCB(a0) # get pointer to pcb for proc cfc1 t0, FPC_CSR # stall til FP done cfc1 t0, FPC_CSR # now get status li t3, ~SR_COP_1_BIT @@ -567,13 +518,13 @@ END(MipsSwitchFPState) *---------------------------------------------------------------------------- */ LEAF(MipsSaveCurFPState) - lw a0, TD_PCB(a0) # get pointer to pcb for thread + PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread mfc0 t1, COP_0_STATUS_REG # Disable interrupts and li t0, SR_COP_1_BIT # enable the coprocessor mtc0 t0, COP_0_STATUS_REG ITLBNOPFIX GET_CPU_PCPU(a1) - sw zero, PC_FPCURTHREAD(a1) # indicate state has been saved + PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved /* * First read out the status register to make sure that all FP operations * have completed. diff --git a/sys/mips/mips/vm_machdep.c b/sys/mips/mips/vm_machdep.c index d385fddd9c4..20243038d2b 100644 --- a/sys/mips/mips/vm_machdep.c +++ b/sys/mips/mips/vm_machdep.c @@ -144,7 +144,7 @@ cpu_fork(register struct thread *td1,register struct proc *p2, pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline; /* Make sp 64-bit aligned */ pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td2->td_pcb & - ~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE); + ~(sizeof(__int64_t) - 1)) - CALLFRAME_SIZ); pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return; pcb2->pcb_context[PCB_REG_S1] = (register_t)td2; pcb2->pcb_context[PCB_REG_S2] = (register_t)td2->td_frame; @@ -339,7 +339,7 @@ cpu_set_upcall(struct thread *td, struct thread *td0) pcb2->pcb_context[PCB_REG_RA] = (register_t)fork_trampoline; /* Make sp 64-bit aligned */ pcb2->pcb_context[PCB_REG_SP] = (register_t)(((vm_offset_t)td->td_pcb & - ~(sizeof(__int64_t) - 1)) - STAND_FRAME_SIZE); + ~(sizeof(__int64_t) - 1)) - CALLFRAME_SIZ); pcb2->pcb_context[PCB_REG_S0] = (register_t)fork_return; pcb2->pcb_context[PCB_REG_S1] = (register_t)td; pcb2->pcb_context[PCB_REG_S2] = (register_t)td->td_frame; @@ -386,7 +386,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, * in ``See MIPS Run'' by D. Sweetman, p. 269 * align stack */ sp = ((register_t)(stack->ss_sp + stack->ss_size) & ~0x7) - - STAND_FRAME_SIZE; + CALLFRAME_SIZ; /* * Set the trap frame to point at the beginning of the uts From 540247e8c1f94ae64703b57e86022df5d63f3ded Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Mon, 19 Apr 2010 07:51:57 +0000 Subject: [PATCH 134/532] Remove unused file. --- sys/conf/files.mips | 1 - sys/mips/mips/copystr.S | 171 ---------------------------------------- 2 files changed, 172 deletions(-) delete mode 100644 sys/mips/mips/copystr.S diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 60ab0c2102d..f88949ce9d8 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -50,7 +50,6 @@ mips/mips/bus_space_generic.c standard mips/mips/busdma_machdep.c standard mips/mips/cache.c standard mips/mips/cache_mipsNN.c standard -#mips/mips/copystr.S standard mips/mips/db_disasm.c optional ddb mips/mips/db_interface.c optional ddb mips/mips/db_trace.c optional ddb diff --git a/sys/mips/mips/copystr.S b/sys/mips/mips/copystr.S deleted file mode 100644 index 35e79057a53..00000000000 --- a/sys/mips/mips/copystr.S +++ /dev/null @@ -1,171 +0,0 @@ -/* $NetBSD: copy.S,v 1.5 2007/10/17 19:55:37 garbled Exp $ */ - -/*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Digital Equipment Corporation and Ralph Campbell. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Copyright (C) 1989 Digital Equipment Corporation. - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby granted, - * provided that the above copyright notice appears in all copies. - * Digital Equipment Corporation makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s, - * v 1.1 89/07/11 17:55:04 nelson Exp SPRITE (DECWRL) - * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s, - * v 9.2 90/01/29 18:00:39 shirriff Exp SPRITE (DECWRL) - * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s, - * v 1.1 89/07/10 14:27:41 nelson Exp SPRITE (DECWRL) - * - * @(#)locore.s 8.5 (Berkeley) 1/4/94 - */ - -#include "assym.s" -#include -#include -__FBSDID("$FreeBSD$"); - -#include - -/* - * copystr(9) - * int copystr(const void *src, void *dst, size_t len, - * size_t *done) - */ -ENTRY(copystr) - .set noreorder - .set noat - move v0, zero - beqz a2, 2f - move t1, zero -1: subu a2, 1 /*XXX mips64 unsafe -- long */ - lbu t0, 0(a0) - PTR_ADDU a0, 1 - sb t0, 0(a1) - PTR_ADDU a1, 1 - beqz t0, 3f /* NULL - end of string*/ - addu t1, 1 /*XXX mips64 unsafe -- long */ - bnez a2, 1b - nop -2: /* ENAMETOOLONG */ - li v0, ENAMETOOLONG -3: /* done != NULL -> how many bytes were copied */ - beqz a3, 4f - nop - sw t1, 0(a3) /*XXX mips64 unsafe -- long */ -4: jr ra - nop - .set reorder - .set at -END(copystr) - -/* - * int copyinstr(void *uaddr, void *kaddr, size_t maxlen, size_t *lencopied) - * Copy a NIL-terminated string, at most maxlen characters long, from the - * user's address space. Return the number of characters copied (including - * the NIL) in *lencopied. If the string is too long, return ENAMETOOLONG; - * else return 0 or EFAULT. - */ -LEAF(copyinstr) - .set noreorder - .set noat - lw t2, pcpup - lw v1, PC_CURPCB(t2) - PTR_LA v0, _C_LABEL(copystrerr) - blt a0, zero, _C_LABEL(copystrerr) - sw v0, PCB_ONFAULT(v1) - move t0, a2 - beq a2, zero, 4f -1: - lbu v0, 0(a0) - subu a2, a2, 1 /*xxx mips64 unsafe -- long */ - beq v0, zero, 2f - sb v0, 0(a1) - PTR_ADDU a0, a0, 1 - bne a2, zero, 1b - PTR_ADDU a1, a1, 1 -4: - li v0, ENAMETOOLONG -2: - beq a3, zero, 3f - subu a2, t0, a2 /*xxx mips64 unsafe -- long */ - sw a2, 0(a3) /*xxx mips64 unsafe -- long */ -3: - j ra # v0 is 0 or ENAMETOOLONG - sw zero, PCB_ONFAULT(v1) - .set reorder - .set at -END(copyinstr) - -/* - * int copyoutstr(void *uaddr, void *kaddr, size_t maxlen, size_t *lencopied); - * Copy a NIL-terminated string, at most maxlen characters long, into the - * user's address space. Return the number of characters copied (including - * the NIL) in *lencopied. If the string is too long, return ENAMETOOLONG; - * else return 0 or EFAULT. - */ -LEAF(copyoutstr) - .set noreorder - .set noat - lw t2, pcpup - lw v1, PC_CURPCB(t2) - PTR_LA v0, _C_LABEL(copystrerr) - blt a1, zero, _C_LABEL(copystrerr) - sw v0, PCB_ONFAULT(v1) - move t0, a2 - beq a2, zero, 4f -1: - lbu v0, 0(a0) - subu a2, a2, 1 /*xxx mips64 unsafe -- long */ - beq v0, zero, 2f - sb v0, 0(a1) - PTR_ADDU a0, a0, 1 - bne a2, zero, 1b - PTR_ADDU a1, a1, 1 -4: - li v0, ENAMETOOLONG -2: - beq a3, zero, 3f - subu a2, t0, a2 /*xxx mips64 unsafe -- long */ - sw a2, 0(a3) /*xxx mips64 unsafe -- long */ -3: - j ra # v0 is 0 or ENAMETOOLONG - sw zero, PCB_ONFAULT(v1) - .set reorder - .set at -END(copyoutstr) - -LEAF(copystrerr) - sw zero, PCB_ONFAULT(v1) - j ra - li v0, EFAULT # return EFAULT -END(copystrerr) From fe7d6b6e6936d303fc397ddf187c083c46007bf7 Mon Sep 17 00:00:00 2001 From: Juli Mallett Date: Mon, 19 Apr 2010 09:03:34 +0000 Subject: [PATCH 135/532] Fix MALTA64 build. --- sys/mips/malta/gt_pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/malta/gt_pci.c b/sys/mips/malta/gt_pci.c index 2f0eadaba4e..237e74227e0 100644 --- a/sys/mips/malta/gt_pci.c +++ b/sys/mips/malta/gt_pci.c @@ -109,8 +109,8 @@ struct gt_pci_softc { struct rman sc_mem_rman; struct rman sc_io_rman; struct rman sc_irq_rman; - uint32_t sc_mem; - uint32_t sc_io; + unsigned long sc_mem; + bus_space_handle_t sc_io; struct resource *sc_irq; struct intr_event *sc_eventstab[ICU_LEN]; From 0e568ab25c4d3bae23b3452fffe9e4263fac9a8d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 19 Apr 2010 09:03:36 +0000 Subject: [PATCH 136/532] Partially MFp4 #176265 by pjd@: - Properly initialize and destroy system_taskq. - Add a dummy implementation of taskq_create_proc(). Note: We do not currently use system_taskq in ZFS so this is mostly a no-op at this time. Proper system_taskq initialization is required by newer ZFS code. Ok'ed by: pjd MFC after: 2 weeks --- .../compat/opensolaris/kern/opensolaris_taskq.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c index 584be24100e..1e3b1eff391 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c @@ -52,9 +52,9 @@ static void system_taskq_init(void *arg) { - system_taskq = (taskq_t *)taskqueue_thread; taskq_zone = uma_zcreate("taskq_zone", sizeof(struct ostask), NULL, NULL, NULL, NULL, 0, 0); + system_taskq = taskq_create("system_taskq", mp_ncpus, 0, 0, 0, 0); } SYSINIT(system_taskq_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_init, NULL); @@ -62,6 +62,7 @@ static void system_taskq_fini(void *arg) { + taskq_destroy(system_taskq); uma_zdestroy(taskq_zone); } SYSUNINIT(system_taskq_fini, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_fini, NULL); @@ -72,10 +73,8 @@ taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused, { taskq_t *tq; - if ((flags & TASKQ_THREADS_CPU_PCT) != 0) { - /* TODO: Calculate number od threads. */ - printf("%s: TASKQ_THREADS_CPU_PCT\n", __func__); - } + if ((flags & TASKQ_THREADS_CPU_PCT) != 0) + nthreads = MAX((mp_ncpus * nthreads) / 100, 1); tq = kmem_alloc(sizeof(*tq), KM_SLEEP); tq->tq_queue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue, @@ -85,6 +84,14 @@ taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused, return ((taskq_t *)tq); } +taskq_t * +taskq_create_proc(const char *name, int nthreads, pri_t pri, int minalloc, + int maxalloc, proc_t *proc __unused, uint_t flags) +{ + + return (taskq_create(name, nthreads, pri, minalloc, maxalloc, flags)); +} + void taskq_destroy(taskq_t *tq) { From 0ff2943ecb402e2acaaec69ebf3707f4f8d0cee0 Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 19 Apr 2010 14:07:33 +0000 Subject: [PATCH 137/532] Revert r206755. It causes some laptops to stop booting. --- sys/dev/ahci/ahci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c index a35fbacdab6..5d399683945 100644 --- a/sys/dev/ahci/ahci.c +++ b/sys/dev/ahci/ahci.c @@ -126,7 +126,6 @@ static struct { {0x26838086, 0x00, "Intel ESB2", 0}, {0x27c18086, 0x00, "Intel ICH7", 0}, {0x27c38086, 0x00, "Intel ICH7", 0}, - {0x27c48086, 0x00, "Intel ICH7M", 0}, {0x27c58086, 0x00, "Intel ICH7M", 0}, {0x27c68086, 0x00, "Intel ICH7M", 0}, {0x28218086, 0x00, "Intel ICH8", 0}, From 307b49efefe0161f8b128f1786ea2169a66aac71 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 19 Apr 2010 14:15:58 +0000 Subject: [PATCH 138/532] Get delayed SACK working again. MFC after: 3 days. --- sys/netinet/sctp_indata.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index a7e6c087fb4..97a9733ab84 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -2123,6 +2123,10 @@ failed_pdapi_express_del: } } finish_express_del: + if (tsn == (asoc->cumulative_tsn + 1)) { + /* Update cum-ack */ + asoc->cumulative_tsn = tsn; + } if (last_chunk) { *m = NULL; } From 3560b8af1fdb83b0b6c864144eaf0343077bf0cc Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Mon, 19 Apr 2010 14:34:44 +0000 Subject: [PATCH 139/532] Fix brokenness in top on big-endian 32-bit systems introduced when changing format_k2 to take a long long. Because itoa is defined as a K&R C function, without prototyping its arguments, format_k2 passed a 64-bit value, but itoa() received only the first word, showing '0' in all memory fields. --- contrib/top/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/top/utils.c b/contrib/top/utils.c index a38b2178fcc..43072b1eccb 100644 --- a/contrib/top/utils.c +++ b/contrib/top/utils.c @@ -499,7 +499,7 @@ unsigned long long amt; } } - p = strecpy(p, itoa(amt)); + p = strecpy(p, itoa((int)amt)); *p++ = tag; *p = '\0'; From 37133ba7027d430eccfe8b95c22c55c60ad8e4a1 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Mon, 19 Apr 2010 15:11:45 +0000 Subject: [PATCH 140/532] Slightly different handling of printf/snprintf for unaligned uint64_t, which should improve readability, and also to ease the port to platforms that do not support %llu MFC after: 3 days --- sbin/ipfw/dummynet.c | 8 +++--- sbin/ipfw/ipfw2.c | 66 +++++++++++++++++++++++--------------------- sbin/ipfw/ipfw2.h | 2 +- 3 files changed, 40 insertions(+), 36 deletions(-) diff --git a/sbin/ipfw/dummynet.c b/sbin/ipfw/dummynet.c index eb6547a046c..19d52a44b14 100644 --- a/sbin/ipfw/dummynet.c +++ b/sbin/ipfw/dummynet.c @@ -203,9 +203,9 @@ list_flow(struct dn_flow *ni) inet_ntop(AF_INET6, &(id->dst_ip6), buff, sizeof(buff)), id->dst_port); } - printf("%4llu %8llu %2u %4u %3u\n", - align_uint64(&ni->tot_pkts), - align_uint64(&ni->tot_bytes), + pr_u64(&ni->tot_pkts, 4); + pr_u64(&ni->tot_bytes, 8); + printf("%2u %4u %3u\n", ni->length, ni->len_bytes, ni->drops); } @@ -290,8 +290,8 @@ static void list_pipes(struct dn_id *oid, struct dn_id *end) { char buf[160]; /* pending buffer */ - buf[0] = '\0'; + buf[0] = '\0'; for (; oid != end; oid = O_NEXT(oid, oid->len)) { if (oid->len < sizeof(*oid)) errx(1, "invalid oid len %d\n", oid->len); diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 41f6e3ab3e8..b0f76830c40 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -314,22 +314,27 @@ static struct _s_x rule_options[] = { { NULL, 0 } /* terminator */ }; -/* - * The following is used to generate a printable argument for - * 64-bit numbers, irrespective of platform alignment and bit size. - * Because all the printf in this program use %llu as a format, - * we just return an unsigned long long, which is larger than - * we need in certain cases, but saves the hassle of using - * PRIu64 as a format specifier. - * We don't care about inlining, this is not performance critical code. +/* + * Helper routine to print a possibly unaligned uint64_t on + * various platform. If width > 0, print the value with + * the desired width, followed by a space; + * otherwise, return the required width. */ -unsigned long long -align_uint64(const uint64_t *pll) +int +pr_u64(uint64_t *pd, int width) { - uint64_t ret; +#ifdef TCC +#define U64_FMT "I64" +#else +#define U64_FMT "llu" +#endif + uint64_t d; - bcopy (pll, &ret, sizeof(ret)); - return ret; + bcopy (pd, &d, sizeof(d)); + return (width > 0) ? + printf("%*" U64_FMT " ", width, d) : + snprintf(NULL, 0, "%" U64_FMT, d) ; +#undef U64_FMT } void * @@ -973,9 +978,10 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth) } printf("%05u ", rule->rulenum); - if (pcwidth>0 || bcwidth>0) - printf("%*llu %*llu ", pcwidth, align_uint64(&rule->pcnt), - bcwidth, align_uint64(&rule->bcnt)); + if (pcwidth > 0 || bcwidth > 0) { + pr_u64(&rule->pcnt, pcwidth); + pr_u64(&rule->bcnt, bcwidth); + } if (co.do_time == 2) printf("%10u ", rule->timestamp); @@ -1577,10 +1583,12 @@ show_dyn_ipfw(ipfw_dyn_rule *d, int pcwidth, int bcwidth) } bcopy(&d->rule, &rulenum, sizeof(rulenum)); printf("%05d", rulenum); - if (pcwidth>0 || bcwidth>0) - printf(" %*llu %*llu (%ds)", pcwidth, - align_uint64(&d->pcnt), bcwidth, - align_uint64(&d->bcnt), d->expire); + if (pcwidth > 0 || bcwidth > 0) { + printf(" "); + pr_u64(&d->pcnt, pcwidth); + pr_u64(&d->bcnt, bcwidth); + printf("(%ds)", d->expire); + } switch (d->dyn_type) { case O_LIMIT_PARENT: printf(" PARENT %d", d->count); @@ -1645,9 +1653,9 @@ ipfw_sets_handler(char *av[]) free(data); nalloc = nalloc * 2 + 200; nbytes = nalloc; - data = safe_calloc(1, nbytes); - if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0) - err(EX_OSERR, "getsockopt(IP_FW_GET)"); + 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, @@ -1837,14 +1845,12 @@ ipfw_list(int ac, char *av[], int show_counters) continue; /* packet counter */ - width = snprintf(NULL, 0, "%llu", - align_uint64(&r->pcnt)); + width = pr_u64(&r->pcnt, 0); if (width > pcwidth) pcwidth = width; /* byte counter */ - width = snprintf(NULL, 0, "%llu", - align_uint64(&r->bcnt)); + width = pr_u64(&r->bcnt, 0); if (width > bcwidth) bcwidth = width; } @@ -1858,13 +1864,11 @@ ipfw_list(int ac, char *av[], int show_counters) if (set != co.use_set - 1) continue; } - width = snprintf(NULL, 0, "%llu", - align_uint64(&d->pcnt)); + width = pr_u64(&d->pcnt, 0); if (width > pcwidth) pcwidth = width; - width = snprintf(NULL, 0, "%llu", - align_uint64(&d->bcnt)); + width = pr_u64(&d->bcnt, 0); if (width > bcwidth) bcwidth = width; } diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h index d1729841e97..8566cdef021 100644 --- a/sbin/ipfw/ipfw2.h +++ b/sbin/ipfw/ipfw2.h @@ -207,7 +207,7 @@ enum tokens { #define NEED(_p, msg) {if (!_p) errx(EX_USAGE, msg);} #define NEED1(msg) {if (!(*av)) errx(EX_USAGE, msg);} -unsigned long long align_uint64(const uint64_t *pll); +int pr_u64(uint64_t *pd, int width); /* memory allocation support */ void *safe_calloc(size_t number, size_t size); From 3579cf4c4f96448eccadce9da9431aa253c60da5 Mon Sep 17 00:00:00 2001 From: "Kenneth D. Merry" Date: Mon, 19 Apr 2010 15:15:36 +0000 Subject: [PATCH 141/532] Don't clear other flags (e.g. CSUM_TCP) when setting CSUM_TSO. This was causing TSO to break for the Xen netfront driver. Reviewed by: gibbs, rwatson MFC after: 7 days --- sys/netinet/tcp_output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index ebe5e36ee3f..f9d1b6371e8 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1048,7 +1048,7 @@ send: * XXX: Fixme: This is currently not the case for IPv6. */ if (tso) { - m->m_pkthdr.csum_flags = CSUM_TSO; + m->m_pkthdr.csum_flags |= CSUM_TSO; m->m_pkthdr.tso_segsz = tp->t_maxopd - optlen; } From 6ba1ccc0f29eb64b529034ca224ce2c1e8f74fd8 Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Mon, 19 Apr 2010 16:17:30 +0000 Subject: [PATCH 142/532] whitespace fixes (trailing whitespace, bad indentation after a merge, etc.) --- sys/netinet/ip_dummynet.h | 54 ++++++++++++++++---------------- sys/netinet/ipfw/dn_sched.h | 4 +-- sys/netinet/ipfw/dn_sched_rr.c | 6 ++-- sys/netinet/ipfw/dn_sched_wf2q.c | 8 ++--- sys/netinet/ipfw/ip_dn_private.h | 2 +- sys/netinet/ipfw/ip_dummynet.c | 36 +++++++++++---------- sys/netinet/ipfw/ip_fw_pfil.c | 8 ++--- sys/netinet/ipfw/ip_fw_private.h | 2 +- 8 files changed, 61 insertions(+), 59 deletions(-) diff --git a/sys/netinet/ip_dummynet.h b/sys/netinet/ip_dummynet.h index 0bbc32638c9..dc2c3412a08 100644 --- a/sys/netinet/ip_dummynet.h +++ b/sys/netinet/ip_dummynet.h @@ -87,14 +87,14 @@ enum { DN_SYSCTL_SET, DN_LAST, -} ; +}; enum { /* subtype for schedulers, flowset and the like */ DN_SCHED_UNKNOWN = 0, DN_SCHED_FIFO = 1, DN_SCHED_WF2QP = 2, /* others are in individual modules */ -} ; +}; enum { /* user flags */ DN_HAVE_MASK = 0x0001, /* fs or sched has a mask */ @@ -113,16 +113,16 @@ enum { /* user flags */ struct dn_link { struct dn_id oid; - /* + /* * Userland sets bw and delay in bits/s and milliseconds. * The kernel converts this back and forth to bits/tick and ticks. * XXX what about burst ? - */ + */ int32_t link_nr; int bandwidth; /* bit/s or bits/tick. */ int delay; /* ms and ticks */ uint64_t burst; /* scaled. bits*Hz XXX */ -} ; +}; /* * A flowset, which is a template for flows. Contains parameters @@ -132,13 +132,13 @@ struct dn_link { */ struct dn_fs { struct dn_id oid; - uint32_t fs_nr; /* the flowset number */ - uint32_t flags; /* userland flags */ - int qsize ; /* queue size in slots or bytes */ - int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ + uint32_t fs_nr; /* the flowset number */ + uint32_t flags; /* userland flags */ + int qsize; /* queue size in slots or bytes */ + int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ uint32_t buckets; /* buckets used for the queue hash table */ - struct ipfw_flow_id flow_mask ; + struct ipfw_flow_id flow_mask; uint32_t sched_nr; /* the scheduler we attach to */ /* generic scheduler parameters. Leave them at -1 if unset. * Now we use 0: weight, 1: lmax, 2: priority @@ -149,14 +149,14 @@ struct dn_fs { * weight and probabilities are in the range 0..1 represented * in fixed point arithmetic with SCALE_RED decimal bits. */ -#define SCALE_RED 16 -#define SCALE(x) ( (x) << SCALE_RED ) -#define SCALE_VAL(x) ( (x) >> SCALE_RED ) -#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) - int w_q ; /* queue weight (scaled) */ - int max_th ; /* maximum threshold for queue (scaled) */ - int min_th ; /* minimum threshold for queue (scaled) */ - int max_p ; /* maximum value for p_b (scaled) */ +#define SCALE_RED 16 +#define SCALE(x) ( (x) << SCALE_RED ) +#define SCALE_VAL(x) ( (x) >> SCALE_RED ) +#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) + int w_q ; /* queue weight (scaled) */ + int max_th ; /* maximum threshold for queue (scaled) */ + int min_th ; /* minimum threshold for queue (scaled) */ + int max_p ; /* maximum value for p_b (scaled) */ }; @@ -177,10 +177,10 @@ struct dn_flow { }; - /* +/* * Scheduler template, mostly indicating the name, number, * sched_mask and buckets. - */ + */ struct dn_sch { struct dn_id oid; uint32_t sched_nr; /* N, scheduler number */ @@ -199,14 +199,14 @@ struct dn_sch { #define ED_MAX_SAMPLES_NO 1024 struct dn_profile { struct dn_id oid; - /* fields to simulate a delay profile */ + /* fields to simulate a delay profile */ #define ED_MAX_NAME_LEN 32 - char name[ED_MAX_NAME_LEN]; - int link_nr; - int loss_level; - int bandwidth; // XXX use link bandwidth? - int samples_no; /* actual length of samples[] */ - int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */ + char name[ED_MAX_NAME_LEN]; + int link_nr; + int loss_level; + int bandwidth; // XXX use link bandwidth? + int samples_no; /* actual len of samples[] */ + int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */ }; diff --git a/sys/netinet/ipfw/dn_sched.h b/sys/netinet/ipfw/dn_sched.h index fe54b0205cf..b6bf24e466a 100644 --- a/sys/netinet/ipfw/dn_sched.h +++ b/sys/netinet/ipfw/dn_sched.h @@ -140,9 +140,9 @@ struct dn_alg { /* MSVC does not support initializers so we need this ugly macro */ #ifdef _WIN32 -#define _SI(fld) +#define _SI(fld) #else -#define _SI(fld) fld +#define _SI(fld) fld #endif /* diff --git a/sys/netinet/ipfw/dn_sched_rr.c b/sys/netinet/ipfw/dn_sched_rr.c index fc7be001b30..1bbd80057c3 100644 --- a/sys/netinet/ipfw/dn_sched_rr.c +++ b/sys/netinet/ipfw/dn_sched_rr.c @@ -94,7 +94,7 @@ rr_remove_head(struct rr_si *si) if (si->head == NULL) return; /* empty queue */ si->head->status = 0; - + if (si->head == si->tail) { si->head = si->tail = NULL; return; @@ -141,7 +141,7 @@ next_pointer(struct rr_si *si) si->tail = si->tail->qnext; } -static int +static int rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m) { struct rr_si *si; @@ -154,7 +154,7 @@ rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m) return 0; } - /* If reach this point, queue q was idle */ + /* If reach this point, queue q was idle */ si = (struct rr_si *)(_si + 1); rrq = (struct rr_queue *)q; diff --git a/sys/netinet/ipfw/dn_sched_wf2q.c b/sys/netinet/ipfw/dn_sched_wf2q.c index 1fbc1202e40..55a49550b7f 100644 --- a/sys/netinet/ipfw/dn_sched_wf2q.c +++ b/sys/netinet/ipfw/dn_sched_wf2q.c @@ -125,7 +125,7 @@ idle_check(struct wf2qp_si *si, int n, int force) } } -static int +static int wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m) { struct dn_fsk *fs = q->fs; @@ -140,7 +140,7 @@ wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m) return 0; } - /* If reach this point, queue q was idle */ + /* If reach this point, queue q was idle */ alg_fq = (struct wf2qp_queue *)q; if (DN_KEY_LT(alg_fq->F, alg_fq->S)) { @@ -318,7 +318,7 @@ wf2qp_free_queue(struct dn_queue *q) { struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q; struct wf2qp_si *si = (struct wf2qp_si *)(q->_si + 1); - + if (alg_fq->S >= alg_fq->F + 1) return 0; /* nothing to do, not in any heap */ si->wsum -= q->fs->fs.par[0]; @@ -361,7 +361,7 @@ static struct dn_alg wf2qp_desc = { _SI( .destroy = ) NULL, _SI( .new_sched = ) wf2qp_new_sched, _SI( .free_sched = ) wf2qp_free_sched, - + _SI( .new_fsk = ) wf2qp_new_fsk, _SI( .free_fsk = ) NULL, diff --git a/sys/netinet/ipfw/ip_dn_private.h b/sys/netinet/ipfw/ip_dn_private.h index f1a7f3fa509..03b43dba55d 100644 --- a/sys/netinet/ipfw/ip_dn_private.h +++ b/sys/netinet/ipfw/ip_dn_private.h @@ -149,7 +149,7 @@ struct dn_parms { int drain_sch; uint32_t expire; uint32_t expire_cycle; /* tick count */ - + int init_done; /* if the upper half is busy doing something long, diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c index 0a6d16dc018..01714aa6634 100644 --- a/sys/netinet/ipfw/ip_dummynet.c +++ b/sys/netinet/ipfw/ip_dummynet.c @@ -1547,28 +1547,28 @@ config_profile(struct dn_profile *pf, struct dn_id *arg) /* XXX other sanity checks */ DN_BH_WLOCK(); for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) { - s = locate_scheduler(i); + s = locate_scheduler(i); - if (s == NULL) { + if (s == NULL) { err = EINVAL; break; - } - dn_cfg.id++; - /* - * If we had a profile and the new one does not fit, - * or it is deleted, then we need to free memory. - */ - if (s->profile && (pf->samples_no == 0 || - s->profile->oid.len < pf->oid.len)) { - free(s->profile, M_DUMMYNET); - s->profile = NULL; - } + } + dn_cfg.id++; + /* + * If we had a profile and the new one does not fit, + * or it is deleted, then we need to free memory. + */ + if (s->profile && (pf->samples_no == 0 || + s->profile->oid.len < pf->oid.len)) { + free(s->profile, M_DUMMYNET); + s->profile = NULL; + } if (pf->samples_no == 0) continue; - /* + /* * new profile, possibly allocate memory - * and copy data. - */ + * and copy data. + */ if (s->profile == NULL) s->profile = malloc(pf->oid.len, M_DUMMYNET, M_NOWAIT | M_ZERO); @@ -1642,7 +1642,8 @@ do_config(void *p, int l) default: D("cmd %d not implemented", o->type); break; -#ifdef EMULATE_SYSCTL + +#ifdef EMULATE_SYSCTL /* sysctl emulation. * if we recognize the command, jump to the correct * handler and return @@ -1651,6 +1652,7 @@ do_config(void *p, int l) err = kesysctl_emu_set(p, l); return err; #endif + case DN_CMD_CONFIG: /* simply a header */ break; diff --git a/sys/netinet/ipfw/ip_fw_pfil.c b/sys/netinet/ipfw/ip_fw_pfil.c index b4e31d4c8c8..e87a4c973fe 100644 --- a/sys/netinet/ipfw/ip_fw_pfil.c +++ b/sys/netinet/ipfw/ip_fw_pfil.c @@ -147,8 +147,8 @@ again: switch (ipfw) { case IP_FW_PASS: /* next_hop may be set by ipfw_chk */ - if (args.next_hop == NULL) - break; /* pass */ + if (args.next_hop == NULL) + break; /* pass */ #ifndef IPFIREWALL_FORWARD ret = EACCES; #else @@ -347,14 +347,14 @@ ipfw_attach_hooks(int arg) if (arg == 0) /* detach */ ipfw_hook(0, AF_INET); - else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) { + else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) { error = ENOENT; /* see ip_fw_pfil.c::ipfw_hook() */ printf("ipfw_hook() error\n"); } #ifdef INET6 if (arg == 0) /* detach */ ipfw_hook(0, AF_INET6); - else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) { + else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) { error = ENOENT; printf("ipfw6_hook() error\n"); } diff --git a/sys/netinet/ipfw/ip_fw_private.h b/sys/netinet/ipfw/ip_fw_private.h index c29ae0ad90b..ac55433750a 100644 --- a/sys/netinet/ipfw/ip_fw_private.h +++ b/sys/netinet/ipfw/ip_fw_private.h @@ -214,7 +214,7 @@ struct ip_fw_chain { struct ip_fw *default_rule; int n_rules; /* number of static rules */ int static_len; /* total len of static rules */ - struct ip_fw **map; /* array of rule ptrs to ease lookup */ + struct ip_fw **map; /* array of rule ptrs to ease lookup */ LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */ struct radix_node_head *tables[IPFW_TABLES_MAX]; #if defined( __linux__ ) || defined( _WIN32 ) From d55ebfbd4e1ccc00cad998a5e9d24de4b98b448e Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Mon, 19 Apr 2010 16:35:47 +0000 Subject: [PATCH 143/532] fix 64-bit build Reported by: Robert Noland --- sbin/ipfw/ipfw2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index b0f76830c40..f313b51b968 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -328,9 +328,11 @@ pr_u64(uint64_t *pd, int width) #else #define U64_FMT "llu" #endif - uint64_t d; + uint64_t u; + unsigned long long d; - bcopy (pd, &d, sizeof(d)); + bcopy (pd, &u, sizeof(u)); + d = u; return (width > 0) ? printf("%*" U64_FMT " ", width, d) : snprintf(NULL, 0, "%" U64_FMT, d) ; From 4ad53b2511c4a4421c361c2fe6622e4865d4695e Mon Sep 17 00:00:00 2001 From: Rui Paulo Date: Mon, 19 Apr 2010 17:16:23 +0000 Subject: [PATCH 144/532] Dump the AR_PHY_TURBO register on the AR5416. This register holds 11n configurations. Sponsored by: iXsystems, inc. --- tools/tools/ath/common/dumpregs_5416.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tools/ath/common/dumpregs_5416.c b/tools/tools/ath/common/dumpregs_5416.c index a074ff7feae..0bc66f35471 100644 --- a/tools/tools/ath/common/dumpregs_5416.c +++ b/tools/tools/ath/common/dumpregs_5416.c @@ -394,6 +394,7 @@ static struct dumpreg ar5416regs[] = { DEFBASIC(AR_SLP_CNT, "SLPCNT"), DEFBASIC(AR_SLP_MIB_CTRL, "SLPMIB"), DEFBASIC(AR_EXTRCCNT, "EXTRCCNT"), + DEFBASIC(AR_PHY_TURBO, "PHYTURBO"), DEFVOID(AR_PHY_ADC_SERIAL_CTL, "PHY_ADC_SERIAL_CTL"), From 002d1d1c385f0c9316948f2ed64973fbf496e270 Mon Sep 17 00:00:00 2001 From: Jaakko Heinonen Date: Mon, 19 Apr 2010 20:07:35 +0000 Subject: [PATCH 145/532] Fix ddb(4) "show geom addr" command when INVARIANTS is enabled. Don't assert that the topology lock is held when g_valid_obj() is called from debugger. MFC after: 1 week --- sys/geom/geom_subr.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index 9bef0e3638f..772277e02a7 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -59,6 +59,10 @@ __FBSDID("$FreeBSD$"); #include #endif +#ifdef KDB +#include +#endif + struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes); static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms); char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim; @@ -1011,12 +1015,11 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len) #if defined(DIAGNOSTIC) || defined(DDB) /* - * This function walks (topologically unsafely) the mesh and return a - * non-zero integer if it finds the argument pointer is an object. - * The return value indicates which type of object it is belived to be. - * If topology is not locked, this function is potentially dangerous, - * but since it is for debugging purposes and can be useful for instance - * from DDB, we do not assert topology lock is held. + * This function walks the mesh and returns a non-zero integer if it + * finds the argument pointer is an object. The return value indicates + * which type of object it is believed to be. If topology is not locked, + * this function is potentially dangerous, but we don't assert that the + * topology lock is held when called from debugger. */ int g_valid_obj(void const *ptr) @@ -1026,7 +1029,10 @@ g_valid_obj(void const *ptr) struct g_consumer *cp; struct g_provider *pp; - g_topology_assert(); +#ifdef KDB + if (kdb_active == 0) +#endif + g_topology_assert(); LIST_FOREACH(mp, &g_classes, class) { if (ptr == mp) From 206727f1fa03d968343c3cd1cb49ba1618ae620e Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Mon, 19 Apr 2010 20:54:00 +0000 Subject: [PATCH 146/532] Vendor import of tzdata2010i: - Marocca will have DST this year between May and August - Historical data for Taiwan - No more DST for the Argentinian province/state San Luis this year. Obtained from: ftp://elsie.nci.nih.gov/pub/ --- africa | 40 +++++++++++++++++++++++++++++++++++--- asia | 55 +++++++++++++++++++++++++++++++++++++++++++++++----- southamerica | 27 +++++++++++++++++++++++--- 3 files changed, 111 insertions(+), 11 deletions(-) diff --git a/africa b/africa index ad89bb743c1..8cae7a682b0 100644 --- a/africa +++ b/africa @@ -1,5 +1,5 @@ #
-# @(#)africa	8.23
+# @(#)africa	8.26
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -680,6 +680,21 @@ Zone	Indian/Mayotte	3:00:56 -	LMT	1911 Jul	# Mamoutzou
 # http://www.worldtimezone.com/dst_news/dst_news_morocco03.html
 # 
 
+# From Steffen Thorsen (2010-04-13):
+# Several news media in Morocco report that the Ministry of Modernization
+# of Public Sectors has announced that Morocco will have DST from
+# 2010-05-02 to 2010-08-08.
+#
+# Example:
+# 
+# http://www.lavieeco.com/actualites/4099-le-maroc-passera-a-l-heure-d-ete-gmt1-le-2-mai.html
+# 
+# (French)
+# Our page:
+# 
+# http://www.timeanddate.com/news/time/morocco-starts-dst-2010.html
+# 
+
 # RULE	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 
 Rule	Morocco	1939	only	-	Sep	12	 0:00	1:00	S
@@ -701,6 +716,8 @@ Rule	Morocco	2008	only	-	Jun	 1	 0:00	1:00	S
 Rule	Morocco	2008	only	-	Sep	 1	 0:00	0	-
 Rule	Morocco	2009	only	-	Jun	 1	 0:00	1:00	S
 Rule	Morocco	2009	only	-	Aug	 21	 0:00	0	-
+Rule	Morocco	2010	only	-	May	 2	 0:00	1:00	S
+Rule	Morocco	2010	only	-	Aug	 8	 0:00	0	-
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone Africa/Casablanca	-0:30:20 -	LMT	1913 Oct 26
 			 0:00	Morocco	WE%sT	1984 Mar 16
@@ -942,6 +959,24 @@ Zone	Africa/Lome	0:04:52 -	LMT	1893
 # Therefore, the standard time will be kept unchanged the whole year long."
 # So foregoing DST seems to be an exception (albeit one that may be repeated in the  future).
 
+# From Alexander Krivenyshev (2010-03-27):
+# According to some news reports Tunis confirmed not to use DST in 2010
+#
+# (translation):
+# "The Tunisian government has decided to abandon DST, which was scheduled on
+# Sunday...
+# Tunisian authorities had suspended the DST for the first time last year also
+# coincided with the month of Ramadan..."
+#
+# (in Arabic)
+# 
+# http://www.moheet.com/show_news.aspx?nid=358861&pg=1
+# 
+# http://www.almadenahnews.com/newss/news.php?c=118&id=38036
+# or
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_tunis02.html
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Tunisia	1939	only	-	Apr	15	23:00s	1:00	S
 Rule	Tunisia	1939	only	-	Nov	18	23:00s	0	-
@@ -968,8 +1003,7 @@ Rule	Tunisia	2005	only	-	May	 1	 0:00s	1:00	S
 Rule	Tunisia	2005	only	-	Sep	30	 1:00s	0	-
 Rule	Tunisia	2006	2008	-	Mar	lastSun	 2:00s	1:00	S
 Rule	Tunisia	2006	2008	-	Oct	lastSun	 2:00s	0	-
-Rule	Tunisia	2010	max	-	Mar	lastSun	 2:00s	1:00	S
-Rule	Tunisia	2010	max	-	Oct	lastSun	 2:00s	0	-
+
 # Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
 # more precise 0:09:21.
 # Shanks & Pottenger say the 1911 switch was on Mar 9; go with Howse's Mar 11.
diff --git a/asia b/asia
index 8cafc5973e2..78ff2ffedcf 100644
--- a/asia
+++ b/asia
@@ -1,4 +1,4 @@
-# @(#)asia	8.58
+# @(#)asia	8.60
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -566,6 +566,28 @@ Zone	Asia/Hong_Kong	7:36:36 -	LMT	1904 Oct 30
 # was still controlled by Japan.  This is hard to believe, but we don't
 # have any other information.
 
+# From smallufo (2010-04-03):
+# According to Taiwan's CWB,
+# 
+# http://www.cwb.gov.tw/V6/astronomy/cdata/summert.htm
+# 
+# Taipei has DST in 1979 between July 1st and Sep 30.
+
+# From Arthur David Olson (2010-04-07):
+# Here's Google's translation of the table at the bottom of the "summert.htm" page:
+# Decade 	                                                    Name                      Start and end date
+# Republic of China 34 years to 40 years (AD 1945-1951 years) Summer Time               May 1 to September 30 
+# 41 years of the Republic of China (AD 1952)                 Daylight Saving Time      March 1 to October 31 
+# Republic of China 42 years to 43 years (AD 1953-1954 years) Daylight Saving Time      April 1 to October 31 
+# In the 44 years to 45 years (AD 1955-1956 years)            Daylight Saving Time      April 1 to September 30 
+# Republic of China 46 years to 48 years (AD 1957-1959)       Summer Time               April 1 to September 30 
+# Republic of China 49 years to 50 years (AD 1960-1961)       Summer Time               June 1 to September 30 
+# Republic of China 51 years to 62 years (AD 1962-1973 years) Stop Summer Time 
+# Republic of China 63 years to 64 years (1974-1975 AD)       Daylight Saving Time      April 1 to September 30 
+# Republic of China 65 years to 67 years (1976-1978 AD)       Stop Daylight Saving Time 
+# Republic of China 68 years (AD 1979)                        Daylight Saving Time      July 1 to September 30 
+# Republic of China since 69 years (AD 1980)                  Stop Daylight Saving Time
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule	Taiwan	1945	1951	-	May	1	0:00	1:00	D
 Rule	Taiwan	1945	1951	-	Oct	1	0:00	0	S
@@ -576,8 +598,9 @@ Rule	Taiwan	1955	1961	-	Oct	1	0:00	0	S
 Rule	Taiwan	1960	1961	-	Jun	1	0:00	1:00	D
 Rule	Taiwan	1974	1975	-	Apr	1	0:00	1:00	D
 Rule	Taiwan	1974	1975	-	Oct	1	0:00	0	S
-Rule	Taiwan	1980	only	-	Jun	30	0:00	1:00	D
-Rule	Taiwan	1980	only	-	Sep	30	0:00	0	S
+Rule	Taiwan	1979	only	-	Jun	30	0:00	1:00	D
+Rule	Taiwan	1979	only	-	Sep	30	0:00	0	S
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Taipei	8:06:00 -	LMT	1896 # or Taibei or T'ai-pei
 			8:00	Taiwan	C%sT
@@ -1912,13 +1935,35 @@ Zone	Asia/Muscat	3:54:20 -	LMT	1920
 # [T]he German Consulate General in Karachi reported me today that Pakistan
 # will go back to standard time on 1st of November.
 
+# From Steffen Thorsen (2010-03-26):
+# Steffen Thorsen wrote:
+# > On Thursday (2010-03-25) it was announced that DST would start in
+# > Pakistan on 2010-04-01.
+# >
+# > Then today, the president said that they might have to revert the
+# > decision if it is not supported by the parliament. So at the time
+# > being, it seems unclear if DST will be actually observed or not - but
+# > April 1 could be a more likely date than April 15.
+# Now, it seems that the decision to not observe DST in final:
+#
+# "Govt Withdraws Plan To Advance Clocks"
+# 
+# http://www.apakistannews.com/govt-withdraws-plan-to-advance-clocks-172041
+# 
+#
+# "People laud PM's announcement to end DST"
+# 
+# http://www.app.com.pk/en_/index.php?option=com_content&task=view&id=99374&Itemid=2
+# 
+
 # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
 Rule Pakistan	2002	only	-	Apr	Sun>=2	0:01	1:00	S
 Rule Pakistan	2002	only	-	Oct	Sun>=2	0:01	0	-
 Rule Pakistan	2008	only	-	Jun	1	0:00	1:00	S
 Rule Pakistan	2008	only	-	Nov	1	0:00	0	-
-Rule Pakistan	2009	max	-	Apr	15	0:00	1:00	S
-Rule Pakistan	2009	max	-	Nov	1	0:00	0	-
+Rule Pakistan	2009	only	-	Apr	15	0:00	1:00	S
+Rule Pakistan	2009	only	-	Nov	1	0:00	0	-
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Karachi	4:28:12 -	LMT	1907
 			5:30	-	IST	1942 Sep
diff --git a/southamerica b/southamerica
index 8db45ccda9a..7355022929d 100644
--- a/southamerica
+++ b/southamerica
@@ -1,5 +1,5 @@
 # 
-# @(#)southamerica	8.43
+# @(#)southamerica	8.44
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
@@ -437,6 +437,27 @@ Rule	Arg	2008	only	-	Oct	Sun>=15	0:00	1:00	S
 # of the country calls it "ART".
 # ...
 
+# From Alexander Krivenyshev (2010-04-09):
+# According to news reports from El Diario de la Republica Province San
+# Luis, Argentina (standard time UTC-04) will keep Daylight Saving Time
+# after April 11, 2010--will continue to have same time as rest of
+# Argentina (UTC-3) (no DST).
+#
+# Confirmaron la prórroga del huso horario de verano (Spanish)
+# 
+# http://www.eldiariodelarepublica.com/index.php?option=com_content&task=view&id=29383&Itemid=9
+# 
+# or (some English translation):
+# 
+# http://www.worldtimezone.com/dst_news/dst_news_argentina08.html
+# 
+
+# From Mariano Absatz (2010-04-12):
+# yes...I can confirm this...and given that San Luis keeps calling
+# UTC-03:00 "summer time", we should't just let San Luis go back to "Arg"
+# rules...San Luis is still using "Western ARgentina Time" and it got
+# stuck on Summer daylight savings time even though the summer is over.
+
 # Zone	NAME		GMTOFF	RULES	FORMAT	[UNTIL]
 #
 # Buenos Aires (BA), Capital Federal (CF),
@@ -570,8 +591,8 @@ Zone America/Argentina/Mendoza -4:35:16 - LMT	1894 Oct 31
 #
 # San Luis (SL)
 
-Rule	SanLuis	2008	max	-	Mar	Sun>=8	0:00	0	-
-Rule	SanLuis	2007	max	-	Oct	Sun>=8	0:00	1:00	S
+Rule	SanLuis	2008	2009	-	Mar	Sun>=8	0:00	0	-
+Rule	SanLuis	2007	2009	-	Oct	Sun>=8	0:00	1:00	S
 
 Zone America/Argentina/San_Luis -4:25:24 - LMT	1894 Oct 31
 			-4:16:48 -	CMT	1920 May

From 6da6d0a9e3f608feb5ca67cf633670359157549b Mon Sep 17 00:00:00 2001
From: Pyun YongHyeon 
Date: Mon, 19 Apr 2010 22:10:40 +0000
Subject: [PATCH 147/532] With r206844, CSUM_TCP is also set for CSUM_TSO case.
 Modify drivers to take into account for the change. Basically CSUM_TSO should
 be checked before checking CSUM_TCP.

---
 sys/dev/age/if_age.c |  28 ++++++------
 sys/dev/alc/if_alc.c |  44 +++++++++---------
 sys/dev/ale/if_ale.c |  19 ++++----
 sys/dev/fxp/if_fxp.c | 106 +++++++++++++++++++++----------------------
 sys/dev/msk/if_msk.c |  48 ++++++++++----------
 sys/dev/nfe/if_nfe.c |  13 +++---
 6 files changed, 125 insertions(+), 133 deletions(-)

diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c
index 3c5a1079774..15ce0eff851 100644
--- a/sys/dev/age/if_age.c
+++ b/sys/dev/age/if_age.c
@@ -1629,22 +1629,8 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
 	}
 
 	m = *m_head;
-	/* Configure Tx IP/TCP/UDP checksum offload. */
-	if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
-		cflags |= AGE_TD_CSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
-			cflags |= AGE_TD_TCPCSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
-			cflags |= AGE_TD_UDPCSUM;
-		/* Set checksum start offset. */
-		cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
-		/* Set checksum insertion position of TCP/UDP. */
-		cflags |= ((poff + m->m_pkthdr.csum_data) <<
-		    AGE_TD_CSUM_XSUMOFFSET_SHIFT);
-	}
-
-	/* Configure TSO. */
 	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		/* Configure TSO. */
 		if (poff + (tcp->th_off << 2) == m->m_pkthdr.len) {
 			/* Not TSO but IP/TCP checksum offload. */
 			cflags |= AGE_TD_IPCSUM | AGE_TD_TCPCSUM;
@@ -1660,6 +1646,18 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
 		/* Set IP/TCP header size. */
 		cflags |= ip->ip_hl << AGE_TD_IPHDR_LEN_SHIFT;
 		cflags |= tcp->th_off << AGE_TD_TSO_TCPHDR_LEN_SHIFT;
+	} else if ((m->m_pkthdr.csum_flags & AGE_CSUM_FEATURES) != 0) {
+		/* Configure Tx IP/TCP/UDP checksum offload. */
+		cflags |= AGE_TD_CSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+			cflags |= AGE_TD_TCPCSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+			cflags |= AGE_TD_UDPCSUM;
+		/* Set checksum start offset. */
+		cflags |= (poff << AGE_TD_CSUM_PLOADOFFSET_SHIFT);
+		/* Set checksum insertion position of TCP/UDP. */
+		cflags |= ((poff + m->m_pkthdr.csum_data) <<
+		    AGE_TD_CSUM_XSUMOFFSET_SHIFT);
 	}
 
 	/* Configure VLAN hardware tag insertion. */
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index e95b04453cd..c685b84e863 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -1908,28 +1908,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
 		vtag = (vtag << TD_VLAN_SHIFT) & TD_VLAN_MASK;
 		cflags |= TD_INS_VLAN_TAG;
 	}
-	/* Configure Tx checksum offload. */
-	if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
-#ifdef ALC_USE_CUSTOM_CSUM
-		cflags |= TD_CUSTOM_CSUM;
-		/* Set checksum start offset. */
-		cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
-		    TD_PLOAD_OFFSET_MASK;
-		/* Set checksum insertion position of TCP/UDP. */
-		cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
-		    TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
-#else
-		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
-			cflags |= TD_IPCSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
-			cflags |= TD_TCPCSUM;
-		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
-			cflags |= TD_UDPCSUM;
-		/* Set TCP/UDP header offset. */
-		cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
-		    TD_L4HDR_OFFSET_MASK;
-#endif
-	} else if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
 		/* Request TSO and set MSS. */
 		cflags |= TD_TSO | TD_TSO_DESCV1;
 		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << TD_MSS_SHIFT) &
@@ -1961,6 +1940,27 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
 		}
 		/* Handle remaining fragments. */
 		idx = 1;
+	} else if ((m->m_pkthdr.csum_flags & ALC_CSUM_FEATURES) != 0) {
+		/* Configure Tx checksum offload. */
+#ifdef ALC_USE_CUSTOM_CSUM
+		cflags |= TD_CUSTOM_CSUM;
+		/* Set checksum start offset. */
+		cflags |= ((poff >> 1) << TD_PLOAD_OFFSET_SHIFT) &
+		    TD_PLOAD_OFFSET_MASK;
+		/* Set checksum insertion position of TCP/UDP. */
+		cflags |= (((poff + m->m_pkthdr.csum_data) >> 1) <<
+		    TD_CUSTOM_CSUM_OFFSET_SHIFT) & TD_CUSTOM_CSUM_OFFSET_MASK;
+#else
+		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
+			cflags |= TD_IPCSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
+			cflags |= TD_TCPCSUM;
+		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
+			cflags |= TD_UDPCSUM;
+		/* Set TCP/UDP header offset. */
+		cflags |= (poff << TD_L4HDR_OFFSET_SHIFT) &
+		    TD_L4HDR_OFFSET_MASK;
+#endif
 	}
 	for (; idx < nsegs; idx++) {
 		desc = &sc->alc_rdata.alc_tx_ring[prod];
diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c
index 76f1b74f2af..b3e71872d5b 100644
--- a/sys/dev/ale/if_ale.c
+++ b/sys/dev/ale/if_ale.c
@@ -1737,8 +1737,14 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
 	bus_dmamap_sync(sc->ale_cdata.ale_tx_tag, map, BUS_DMASYNC_PREWRITE);
 
 	m = *m_head;
-	/* Configure Tx checksum offload. */
-	if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		/* Request TSO and set MSS. */
+		cflags |= ALE_TD_TSO;
+		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
+		/* Set IP/TCP header size. */
+		cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
+		cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
+	} else if ((m->m_pkthdr.csum_flags & ALE_CSUM_FEATURES) != 0) {
 		/*
 		 * AR81xx supports Tx custom checksum offload feature
 		 * that offloads single 16bit checksum computation.
@@ -1769,15 +1775,6 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
 		    ALE_TD_CSUM_XSUMOFFSET_SHIFT);
 	}
 
-	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
-		/* Request TSO and set MSS. */
-		cflags |= ALE_TD_TSO;
-		cflags |= ((uint32_t)m->m_pkthdr.tso_segsz << ALE_TD_MSS_SHIFT);
-		/* Set IP/TCP header size. */
-		cflags |= ip->ip_hl << ALE_TD_IPHDR_LEN_SHIFT;
-		cflags |= tcp->th_off << ALE_TD_TCPHDR_LEN_SHIFT;
-	}
-
 	/* Configure VLAN hardware tag insertion. */
 	if ((m->m_flags & M_VLANTAG) != 0) {
 		vtag = ALE_TX_VLAN_TAG(m->m_pkthdr.ether_vtag);
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index a8d961eb0fb..a480e7cc6a4 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -1417,60 +1417,6 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
 		    FXP_IPCB_HARDWAREPARSING_ENABLE;
 
 	m = *m_head;
-	/*
-	 * Deal with TCP/IP checksum offload. Note that
-	 * in order for TCP checksum offload to work,
-	 * the pseudo header checksum must have already
-	 * been computed and stored in the checksum field
-	 * in the TCP header. The stack should have
-	 * already done this for us.
-	 */
-	if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
-		txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
-		if (m->m_pkthdr.csum_flags & CSUM_TCP)
-			txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
-
-#ifdef FXP_IP_CSUM_WAR
-		/*
-		 * XXX The 82550 chip appears to have trouble
-		 * dealing with IP header checksums in very small
-		 * datagrams, namely fragments from 1 to 3 bytes
-		 * in size. For example, say you want to transmit
-		 * a UDP packet of 1473 bytes. The packet will be
-		 * fragmented over two IP datagrams, the latter
-		 * containing only one byte of data. The 82550 will
-		 * botch the header checksum on the 1-byte fragment.
-		 * As long as the datagram contains 4 or more bytes
-		 * of data, you're ok.
-		 *
-                 * The following code attempts to work around this
-		 * problem: if the datagram is less than 38 bytes
-		 * in size (14 bytes ether header, 20 bytes IP header,
-		 * plus 4 bytes of data), we punt and compute the IP
-		 * header checksum by hand. This workaround doesn't
-		 * work very well, however, since it can be fooled
-		 * by things like VLAN tags and IP options that make
-		 * the header sizes/offsets vary.
-		 */
-
-		if (m->m_pkthdr.csum_flags & CSUM_IP) {
-			if (m->m_pkthdr.len < 38) {
-				struct ip *ip;
-				m->m_data += ETHER_HDR_LEN;
-				ip = mtod(m, struct ip *);
-				ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
-				m->m_data -= ETHER_HDR_LEN;
-				m->m_pkthdr.csum_flags &= ~CSUM_IP;
-			} else {
-				txp->tx_cb->ipcb_ip_activation_high =
-				    FXP_IPCB_HARDWAREPARSING_ENABLE;
-				txp->tx_cb->ipcb_ip_schedule |=
-				    FXP_IPCB_IP_CHECKSUM_ENABLE;
-			}
-		}
-#endif
-	}
-
 	if (m->m_pkthdr.csum_flags & CSUM_TSO) {
 		/*
 		 * 82550/82551 requires ethernet/IP/TCP headers must be
@@ -1539,6 +1485,58 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
 		tcp_payload = m->m_pkthdr.len - ip_off - (ip->ip_hl << 2);
 		tcp_payload -= tcp->th_off << 2;
 		*m_head = m;
+	} else if (m->m_pkthdr.csum_flags & FXP_CSUM_FEATURES) {
+		/*
+		 * Deal with TCP/IP checksum offload. Note that
+		 * in order for TCP checksum offload to work,
+		 * the pseudo header checksum must have already
+		 * been computed and stored in the checksum field
+		 * in the TCP header. The stack should have
+		 * already done this for us.
+		 */
+		txp->tx_cb->ipcb_ip_schedule = FXP_IPCB_TCPUDP_CHECKSUM_ENABLE;
+		if (m->m_pkthdr.csum_flags & CSUM_TCP)
+			txp->tx_cb->ipcb_ip_schedule |= FXP_IPCB_TCP_PACKET;
+
+#ifdef FXP_IP_CSUM_WAR
+		/*
+		 * XXX The 82550 chip appears to have trouble
+		 * dealing with IP header checksums in very small
+		 * datagrams, namely fragments from 1 to 3 bytes
+		 * in size. For example, say you want to transmit
+		 * a UDP packet of 1473 bytes. The packet will be
+		 * fragmented over two IP datagrams, the latter
+		 * containing only one byte of data. The 82550 will
+		 * botch the header checksum on the 1-byte fragment.
+		 * As long as the datagram contains 4 or more bytes
+		 * of data, you're ok.
+		 *
+                 * The following code attempts to work around this
+		 * problem: if the datagram is less than 38 bytes
+		 * in size (14 bytes ether header, 20 bytes IP header,
+		 * plus 4 bytes of data), we punt and compute the IP
+		 * header checksum by hand. This workaround doesn't
+		 * work very well, however, since it can be fooled
+		 * by things like VLAN tags and IP options that make
+		 * the header sizes/offsets vary.
+		 */
+
+		if (m->m_pkthdr.csum_flags & CSUM_IP) {
+			if (m->m_pkthdr.len < 38) {
+				struct ip *ip;
+				m->m_data += ETHER_HDR_LEN;
+				ip = mtod(m, struct ip *);
+				ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
+				m->m_data -= ETHER_HDR_LEN;
+				m->m_pkthdr.csum_flags &= ~CSUM_IP;
+			} else {
+				txp->tx_cb->ipcb_ip_activation_high =
+				    FXP_IPCB_HARDWAREPARSING_ENABLE;
+				txp->tx_cb->ipcb_ip_schedule |=
+				    FXP_IPCB_IP_CHECKSUM_ENABLE;
+			}
+		}
+#endif
 	}
 
 	error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map, *m_head,
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index 61b131bf451..c083e1e10f6 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -2605,23 +2605,32 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
 		ip = (struct ip *)(mtod(m, char *) + offset);
 		offset += (ip->ip_hl << 2);
 		tcp_offset = offset;
-		/*
-		 * It seems that Yukon II has Tx checksum offload bug for
-		 * small TCP packets that's less than 60 bytes in size
-		 * (e.g. TCP window probe packet, pure ACK packet).
-		 * Common work around like padding with zeros to make the
-		 * frame minimum ethernet frame size didn't work at all.
-		 * Instead of disabling checksum offload completely we
-		 * resort to S/W checksum routine when we encounter short
-		 * TCP frames.
-		 * Short UDP packets appear to be handled correctly by
-		 * Yukon II. Also I assume this bug does not happen on
-		 * controllers that use newer descriptor format or
-		 * automatic Tx checksum calaulcation.
-		 */
-		if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
+		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+			m = m_pullup(m, offset + sizeof(struct tcphdr));
+			if (m == NULL) {
+				*m_head = NULL;
+				return (ENOBUFS);
+			}
+			tcp = (struct tcphdr *)(mtod(m, char *) + offset);
+			offset += (tcp->th_off << 2);
+		} else if ((sc_if->msk_flags & MSK_FLAG_AUTOTX_CSUM) == 0 &&
 		    (m->m_pkthdr.len < MSK_MIN_FRAMELEN) &&
 		    (m->m_pkthdr.csum_flags & CSUM_TCP) != 0) {
+			/*
+			 * It seems that Yukon II has Tx checksum offload bug
+			 * for small TCP packets that's less than 60 bytes in
+			 * size (e.g. TCP window probe packet, pure ACK packet).
+			 * Common work around like padding with zeros to make
+			 * the frame minimum ethernet frame size didn't work at
+			 * all.
+			 * Instead of disabling checksum offload completely we
+			 * resort to S/W checksum routine when we encounter
+			 * short TCP frames.
+			 * Short UDP packets appear to be handled correctly by
+			 * Yukon II. Also I assume this bug does not happen on
+			 * controllers that use newer descriptor format or
+			 * automatic Tx checksum calaulcation.
+			 */
 			m = m_pullup(m, offset + sizeof(struct tcphdr));
 			if (m == NULL) {
 				*m_head = NULL;
@@ -2632,15 +2641,6 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
 			    m->m_pkthdr.len, offset);
 			m->m_pkthdr.csum_flags &= ~CSUM_TCP;
 		}
-		if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
-			m = m_pullup(m, offset + sizeof(struct tcphdr));
-			if (m == NULL) {
-				*m_head = NULL;
-				return (ENOBUFS);
-			}
-			tcp = (struct tcphdr *)(mtod(m, char *) + offset);
-			offset += (tcp->th_off << 2);
-		}
 		*m_head = m;
 	}
 
diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c
index 5d0bfd268f6..7d77754b90c 100644
--- a/sys/dev/nfe/if_nfe.c
+++ b/sys/dev/nfe/if_nfe.c
@@ -2366,7 +2366,12 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
 	m = *m_head;
 	cflags = flags = 0;
 	tso_segsz = 0;
-	if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
+	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
+		tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
+		    NFE_TX_TSO_SHIFT;
+		cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
+		cflags |= NFE_TX_TSO;
+	} else if ((m->m_pkthdr.csum_flags & NFE_CSUM_FEATURES) != 0) {
 		if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0)
 			cflags |= NFE_TX_IP_CSUM;
 		if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0)
@@ -2374,12 +2379,6 @@ nfe_encap(struct nfe_softc *sc, struct mbuf **m_head)
 		if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0)
 			cflags |= NFE_TX_TCP_UDP_CSUM;
 	}
-	if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
-		tso_segsz = (uint32_t)m->m_pkthdr.tso_segsz <<
-		    NFE_TX_TSO_SHIFT;
-		cflags &= ~(NFE_TX_IP_CSUM | NFE_TX_TCP_UDP_CSUM);
-		cflags |= NFE_TX_TSO;
-	}
 
 	for (i = 0; i < nsegs; i++) {
 		if (sc->nfe_flags & NFE_40BIT_ADDR) {

From 248bb9379fd3db5e637005b70c851d2bf08ca042 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 19 Apr 2010 23:27:54 +0000
Subject: [PATCH 148/532] Fix a deadlock in the shutdown code: When performing
 a smp_rendezvous() or more likely, on amd64 and i386, a smp_tlb_shootdown()
 the caller will end up with the smp_ipi_mtx spinlock held, busy-waiting for
 other CPUs to acknowledge the operation. As long as CPUs are suspended (via
 cpu_reset()) between the active mask read and IPI sending there can be a
 deadlock where the caller will wait forever for a dead CPU to acknowledge the
 operation. Please note that on CPU0 that is going to be someway heavier
 because of the spinlocks being disabled earlier than quitting the machine.

Fix this bug by calling cpu_reset() with the smp_ipi_mtx held.
Note that it is very likely that a saner offline/online CPUs mechanism
will help heavilly in fixing similar cases as it is likely more bugs
of this type may arise in the future.

Reported by:	rwatson
Discussed with:	jhb
Tested by:	rnoland, Giovanni Trematerra
		
MFC:		2 weeks

Special deciation to:	anyone who made possible to have 16-ways machines
			in Netperf
---
 sys/kern/kern_shutdown.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 9b28af40c28..4b27d45f6c0 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -62,7 +62,7 @@ __FBSDID("$FreeBSD$");
 #include 
 #include 
 #include 
-#include 		/* smp_active */
+#include 
 #include 
 #include 
 
@@ -485,15 +485,20 @@ static void
 shutdown_reset(void *junk, int howto)
 {
 
-	/*
-	 * Disable interrupts on CPU0 in order to avoid fast handlers
-	 * to preempt the stopping process and to deadlock against other
-	 * CPUs.
-	 */
-	spinlock_enter();
-
 	printf("Rebooting...\n");
 	DELAY(1000000);	/* wait 1 sec for printf's to complete and be read */
+
+	/*
+	 * Acquiring smp_ipi_mtx here has a double effect:
+	 * - it disables interrupts avoiding CPU0 preemption
+	 *   by fast handlers (thus deadlocking  against other CPUs)
+	 * - it avoids deadlocks against smp_rendezvous() or, more 
+	 *   generally, threads busy-waiting, with this spinlock held,
+	 *   and waiting for responses by threads on other CPUs
+	 *   (ie. smp_tlb_shootdown()).
+	 */
+	mtx_lock_spin(&smp_ipi_mtx);
+
 	/* cpu_boot(howto); */ /* doesn't do anything at the moment */
 	cpu_reset();
 	/* NOTREACHED */ /* assuming reset worked */

From 95335fd84431aace91d15fe4a5b8aa9c94afa1b5 Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Mon, 19 Apr 2010 23:40:46 +0000
Subject: [PATCH 149/532] getblk lockmgr is mostly used as a msleep() and may
 lead too easilly to false positives. Whitelist it.

Reported by:	Erik Cederstrand 
---
 sys/kern/kern_clock.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c
index 98e276bb34a..da05cc16356 100644
--- a/sys/kern/kern_clock.c
+++ b/sys/kern/kern_clock.c
@@ -163,6 +163,7 @@ SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE,
 
 #ifdef DEADLKRES
 static const char *blessed[] = {
+	"getblk",
 	"so_snd_sx",
 	"so_rcv_sx",
 	NULL

From a318bc273dca5d2fe11b487a42c8a116e12bbc04 Mon Sep 17 00:00:00 2001
From: Rick Macklem 
Date: Tue, 20 Apr 2010 01:02:39 +0000
Subject: [PATCH 150/532] For the experimental NFS client doing an NFSv4 mount,
 set the NFSCLFLAGS_RECVRINPROG while doing recovery from an expired lease in
 a manner similar to r206818 for server reboot recovery. This will prevent the
 function that acquires stateids for I/O operations from acquiring out of date
 stateids during recovery. Also, fix up mutex locking on the nfsc_flags field.

MFC after:	1 week
---
 sys/fs/nfsclient/nfs_clstate.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c
index 6a189635ff7..78b596640cf 100644
--- a/sys/fs/nfsclient/nfs_clstate.c
+++ b/sys/fs/nfsclient/nfs_clstate.c
@@ -2111,6 +2111,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
 		NFSUNLOCKCLSTATE();
 		return (0);
 	}
+	clp->nfsc_flags |= NFSCLFLAGS_RECVRINPROG;
 	NFSUNLOCKCLSTATE();
 
 	nmp = clp->nfsc_nmp;
@@ -2127,6 +2128,7 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
 		 * Clear out any state.
 		 */
 		nfscl_cleanclient(clp);
+		NFSLOCKCLSTATE();
 		clp->nfsc_flags &= ~(NFSCLFLAGS_HASCLIENTID |
 		    NFSCLFLAGS_RECOVER);
 	} else {
@@ -2140,14 +2142,15 @@ nfscl_hasexpired(struct nfsclclient *clp, u_int32_t clidrev, NFSPROC_T *p)
 		 * Expire the state for the client.
 		 */
 		nfscl_expireclient(clp, nmp, cred, p);
+		NFSLOCKCLSTATE();
 		clp->nfsc_flags |= NFSCLFLAGS_HASCLIENTID;
 		clp->nfsc_flags &= ~NFSCLFLAGS_RECOVER;
 	}
-	NFSFREECRED(cred);
-	clp->nfsc_flags &= ~NFSCLFLAGS_EXPIREIT;
-	NFSLOCKCLSTATE();
+	clp->nfsc_flags &= ~(NFSCLFLAGS_EXPIREIT | NFSCLFLAGS_RECVRINPROG);
+	wakeup(&clp->nfsc_flags);
 	nfsv4_unlock(&clp->nfsc_lock, 0);
 	NFSUNLOCKCLSTATE();
+	NFSFREECRED(cred);
 	return (error);
 }
 

From 0d526fa82972822897b544107dcd0d56a50f8d3c Mon Sep 17 00:00:00 2001
From: Nathan Whitehorn 
Date: Tue, 20 Apr 2010 01:12:23 +0000
Subject: [PATCH 151/532] Add gpart and glabel to the release CD mfsroot. Even
 if sysinstall cannot partition disks on powerpc, this will allow the user to.

PR:		powerpc/93203
Obtained from:	ia64
MFC after:	1 week
---
 release/powerpc/boot_crunch.conf | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/release/powerpc/boot_crunch.conf b/release/powerpc/boot_crunch.conf
index 9f7a3010b11..4868519c34e 100644
--- a/release/powerpc/boot_crunch.conf
+++ b/release/powerpc/boot_crunch.conf
@@ -15,6 +15,7 @@ srcdirs /usr/src/sbin
 progs camcontrol
 progs dhclient
 progs fsck_ffs
+progs geom
 progs ifconfig
 progs mount_msdosfs
 progs mount_nfs
@@ -25,6 +26,8 @@ progs rtsol
 progs tunefs
 ln fsck_ffs fsck_4.2bsd
 ln fsck_ffs fsck_ufs
+ln geom glabel
+ln geom gpart
 
 srcdirs /usr/src/usr.bin
 progs cpio
@@ -43,4 +46,4 @@ progs usbconfig
 
 libs -ll -ledit -lutil -lmd -lcrypt -lftpio -lz -lnetgraph
 libs -ldialog -lncurses -ldisk -lcam -lkiconv -lsbuf -lufs
-libs -lbsdxml -larchive -lbz2 -lusb -ljail
+libs -lgeom -lbsdxml -larchive -lbz2 -lusb -ljail

From 5d4a7b794595092d7946546d8fee39cf63b4e393 Mon Sep 17 00:00:00 2001
From: Alan Cox 
Date: Tue, 20 Apr 2010 04:16:39 +0000
Subject: [PATCH 152/532] Eliminate an unnecessary call to pmap_remove_all(). 
 If a page belongs to an object whose reference count is zero, then that page
 cannot possibly be mapped.

---
 sys/vm/vm_pageout.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index d5ede5a7503..735beee4b8b 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1122,7 +1122,8 @@ unlock_and_continue:
 			    m->act_count == 0) {
 				page_shortage--;
 				if (object->ref_count == 0) {
-					pmap_remove_all(m);
+					KASSERT(!pmap_page_is_mapped(m),
+				    ("vm_pageout_scan: page %p is mapped", m));
 					if (m->dirty == 0)
 						vm_page_cache(m);
 					else

From a8734ffdb3cb5e4e2a29628843cb9a8f4b76991a Mon Sep 17 00:00:00 2001
From: Maxim Konovalov 
Date: Tue, 20 Apr 2010 06:10:05 +0000
Subject: [PATCH 153/532] o Add do-not-fragment option support to ping6(8).

PR:		bin/145759
Submitted by:	pluknet
MFC after:	1 month
---
 sbin/ping6/ping6.8 |  8 +++++---
 sbin/ping6/ping6.c | 14 +++++++++++---
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/sbin/ping6/ping6.8 b/sbin/ping6/ping6.8
index 3897a90c473..3298deaa5a2 100644
--- a/sbin/ping6/ping6.8
+++ b/sbin/ping6/ping6.8
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd August 27, 2008
+.Dd April 20, 2010
 .Dt PING6 8
 .Os
 .Sh NAME
@@ -40,9 +40,9 @@ packets to network hosts
 .Sh SYNOPSIS
 .Nm
 .\" without ipsec, or new ipsec
-.Op Fl dfHmnNoqrRtvwW
+.Op Fl DdfHmnNoqrRtvwW
 .\" old ipsec
-.\" .Op Fl AdEfmnNqRtvwW
+.\" .Op Fl ADdEfmnNqRtvwW
 .Bk -words
 .Op Fl a Ar addrtype
 .Ek
@@ -141,6 +141,8 @@ Stop after sending
 .Ar count
 .Tn ECHO_RESPONSE
 packets.
+.It Fl D
+Disable IPv6 fragmentation.
 .It Fl d
 Set the
 .Dv SO_DEBUG
diff --git a/sbin/ping6/ping6.c b/sbin/ping6/ping6.c
index f7dba273650..69a98b23500 100644
--- a/sbin/ping6/ping6.c
+++ b/sbin/ping6/ping6.c
@@ -191,6 +191,7 @@ struct tv32 {
 #define F_ONCE		0x200000
 #define F_AUDIBLE	0x400000
 #define F_MISSED	0x800000
+#define F_DONTFRAG	0x1000000
 #define F_NOUSERDATA	(F_NODEADDR | F_FQDN | F_FQDNOLD | F_SUPTYPES)
 u_int options;
 
@@ -349,7 +350,7 @@ main(argc, argv)
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
 	while ((ch = getopt(argc, argv,
-	    "a:b:c:dfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
+	    "a:b:c:DdfHg:h:I:i:l:mnNop:qrRS:s:tvwW" ADDOPTS)) != -1) {
 #undef ADDOPTS
 		switch (ch) {
 		case 'a':
@@ -415,6 +416,9 @@ main(argc, argv)
 				errx(1,
 				    "illegal number of packets -- %s", optarg);
 			break;
+		case 'D':
+			options |= F_DONTFRAG;
+			break;
 		case 'd':
 			options |= F_SO_DEBUG;
 			break;
@@ -742,7 +746,11 @@ main(argc, argv)
 	for (i = 0; i < sizeof(nonce); i += sizeof(u_int32_t))
 		*((u_int32_t *)&nonce[i]) = arc4random();
 #endif
-
+	optval = 1;
+	if (options & F_DONTFRAG)
+		if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
+		    &optval, sizeof(optval)) == -1)
+			err(1, "IPV6_DONTFRAG");
 	hold = 1;
 
 	if (options & F_SO_DEBUG)
@@ -2780,7 +2788,7 @@ usage()
 	    "A"
 #endif
 	    "usage: ping6 [-"
-	    "d"
+	    "Dd"
 #if defined(IPSEC) && !defined(IPSEC_POLICY_IPSEC)
 	    "E"
 #endif

From 553aff12d462be96f31ded5685c391c9c402d66a Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Tue, 20 Apr 2010 08:50:19 +0000
Subject: [PATCH 154/532] Really print the nr_mapping array when it should be
 printed.`

MFC after: 3 days.
---
 sys/netinet/sctputil.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 0f2805fb613..26122ce4abf 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1215,7 +1215,7 @@ sctp_print_mapping_array(struct sctp_association *asoc)
 	}
 	printf("Non renegable mapping array (last %d entries are zero):\n", asoc->mapping_array_size - limit);
 	for (i = 0; i < limit; i++) {
-		printf("%2.2x%c", asoc->mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
+		printf("%2.2x%c", asoc->nr_mapping_array[i], ((i + 1) % 16) ? ' ' : '\n');
 	}
 	if (limit % 16)
 		printf("\n");

From ee94f0a272922e3e5a9fa907e5e73497991b6fcf Mon Sep 17 00:00:00 2001
From: Michael Tuexen 
Date: Tue, 20 Apr 2010 08:51:21 +0000
Subject: [PATCH 155/532] Update highest_tsn variables when sliding mapping
 arrays.

---
 sys/netinet/sctp_indata.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 97a9733ab84..c1430a53f40 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -2390,6 +2390,12 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
 				asoc->mapping_array[ii] = 0;
 				asoc->nr_mapping_array[ii] = 0;
 			}
+			if (asoc->highest_tsn_inside_map + 1 == asoc->mapping_array_base_tsn) {
+				asoc->highest_tsn_inside_map += (slide_from << 3);
+			}
+			if (asoc->highest_tsn_inside_nr_map + 1 == asoc->mapping_array_base_tsn) {
+				asoc->highest_tsn_inside_nr_map += (slide_from << 3);
+			}
 			asoc->mapping_array_base_tsn += (slide_from << 3);
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MAP_LOGGING_ENABLE) {
 				sctp_log_map(asoc->mapping_array_base_tsn,

From 9d79ec20fb18158492642c73fb8a17b531308a7d Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Apr 2010 10:16:44 +0000
Subject: [PATCH 156/532] Slightly modernize realpath(3).

SUSv4 requires that implementation returns EINVAL if supplied path is NULL,
and ENOENT if path is empty string [1].
Bring prototype in conformance with SUSv4, adding restrict keywords.
Allow the resolved path buffer pointer be NULL, in which case realpath(3)
allocates storage with malloc().

PR:	kern/121897 [1]
MFC after:	2 weeks
---
 include/stdlib.h           |  2 +-
 lib/libc/stdlib/realpath.3 | 19 +++++++++++---
 lib/libc/stdlib/realpath.c | 54 ++++++++++++++++++++++++++++++++++----
 3 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/include/stdlib.h b/include/stdlib.h
index b8cd1a389f8..b833203c65b 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -201,7 +201,7 @@ int	 posix_openpt(int);
 char	*ptsname(int);
 int	 putenv(char *);
 long	 random(void);
-char	*realpath(const char *, char resolved_path[]);
+char	*realpath(const char * __restrict, char * __restrict);
 unsigned short
 	*seed48(unsigned short[3]);
 #ifndef _SETKEY_DECLARED
diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3
index 4205a3d6bbc..371ee3b2804 100644
--- a/lib/libc/stdlib/realpath.3
+++ b/lib/libc/stdlib/realpath.3
@@ -31,7 +31,7 @@
 .\"     @(#)realpath.3	8.2 (Berkeley) 2/16/94
 .\" $FreeBSD$
 .\"
-.Dd February 16, 1994
+.Dd April 19, 2010
 .Dt REALPATH 3
 .Os
 .Sh NAME
@@ -43,7 +43,7 @@
 .In sys/param.h
 .In stdlib.h
 .Ft "char *"
-.Fn realpath "const char *pathname" "char resolved_path[PATH_MAX]"
+.Fn realpath "const char *pathname" "char *resolved_path"
 .Sh DESCRIPTION
 The
 .Fn realpath
@@ -64,7 +64,8 @@ argument
 .Em must
 refer to a buffer capable of storing at least
 .Dv PATH_MAX
-characters.
+characters, or be
+.Dv NULL .
 .Pp
 The
 .Fn realpath
@@ -82,6 +83,13 @@ The
 function returns
 .Fa resolved_path
 on success.
+If the function was supplied
+.Dv NULL
+as
+.Fa resolved_path ,
+and operation did not cause errors, the returned value is
+a null-terminated string in a buffer allocated by a call to
+.Fn malloc 3 .
 If an error occurs,
 .Fn realpath
 returns
@@ -89,6 +97,11 @@ returns
 and
 .Fa resolved_path
 contains the pathname which caused the problem.
+If
+.Fa resolved_path
+was
+.Dv NULL ,
+then information of the failed pathname component is lost.
 .Sh ERRORS
 The function
 .Fn realpath
diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c
index 3082f5f4b95..31c93e67741 100644
--- a/lib/libc/stdlib/realpath.c
+++ b/lib/libc/stdlib/realpath.c
@@ -43,23 +43,37 @@ __FBSDID("$FreeBSD$");
 #include "un-namespace.h"
 
 /*
- * char *realpath(const char *path, char resolved[PATH_MAX]);
- *
  * Find the real name of path, by removing all ".", ".." and symlink
  * components.  Returns (resolved) on success, or (NULL) on failure,
  * in which case the path which caused trouble is left in (resolved).
  */
 char *
-realpath(const char *path, char resolved[PATH_MAX])
+realpath(const char * __restrict path, char * __restrict resolved)
 {
 	struct stat sb;
 	char *p, *q, *s;
 	size_t left_len, resolved_len;
 	unsigned symlinks;
-	int serrno, slen;
+	int serrno, slen, m;
 	char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
 
+	if (path == NULL) {
+		errno = EINVAL;
+		return (NULL);
+	}
+	if (path[0] == '\0') {
+		errno = ENOENT;
+		return (NULL);
+	}
 	serrno = errno;
+	if (resolved == NULL) {
+		resolved = malloc(PATH_MAX);
+		if (resolved == NULL)
+			return (NULL);
+		m = 1;
+	} else
+		m = 0;
+
 	symlinks = 0;
 	if (path[0] == '/') {
 		resolved[0] = '/';
@@ -71,12 +85,19 @@ realpath(const char *path, char resolved[PATH_MAX])
 	} else {
 		if (getcwd(resolved, PATH_MAX) == NULL) {
 			strlcpy(resolved, ".", PATH_MAX);
+			if (m) {
+				serrno = errno;
+				free(resolved);
+				errno = serrno;
+			}
 			return (NULL);
 		}
 		resolved_len = strlen(resolved);
 		left_len = strlcpy(left, path, sizeof(left));
 	}
 	if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+		if (m)
+			free(resolved);
 		errno = ENAMETOOLONG;
 		return (NULL);
 	}
@@ -92,6 +113,8 @@ realpath(const char *path, char resolved[PATH_MAX])
 		p = strchr(left, '/');
 		s = p ? p : left + left_len;
 		if (s - left >= sizeof(next_token)) {
+			if (m)
+				free(resolved);
 			errno = ENAMETOOLONG;
 			return (NULL);
 		}
@@ -102,6 +125,8 @@ realpath(const char *path, char resolved[PATH_MAX])
 			memmove(left, s + 1, left_len + 1);
 		if (resolved[resolved_len - 1] != '/') {
 			if (resolved_len + 1 >= PATH_MAX) {
+				if (m)
+					free(resolved);
 				errno = ENAMETOOLONG;
 				return (NULL);
 			}
@@ -133,6 +158,8 @@ realpath(const char *path, char resolved[PATH_MAX])
 		 */
 		resolved_len = strlcat(resolved, next_token, PATH_MAX);
 		if (resolved_len >= PATH_MAX) {
+			if (m)
+				free(resolved);
 			errno = ENAMETOOLONG;
 			return (NULL);
 		}
@@ -141,16 +168,29 @@ realpath(const char *path, char resolved[PATH_MAX])
 				errno = serrno;
 				return (resolved);
 			}
+			if (m) {
+				serrno = errno;
+				free(resolved);
+				errno = serrno;
+			}
 			return (NULL);
 		}
 		if (S_ISLNK(sb.st_mode)) {
 			if (symlinks++ > MAXSYMLINKS) {
+				if (m)
+					free(resolved);
 				errno = ELOOP;
 				return (NULL);
 			}
 			slen = readlink(resolved, symlink, sizeof(symlink) - 1);
-			if (slen < 0)
+			if (slen < 0) {
+				if (m) {
+					serrno = errno;
+					free(resolved);
+					errno = serrno;
+				}
 				return (NULL);
+			}
 			symlink[slen] = '\0';
 			if (symlink[0] == '/') {
 				resolved[1] = 0;
@@ -171,6 +211,8 @@ realpath(const char *path, char resolved[PATH_MAX])
 			if (p != NULL) {
 				if (symlink[slen - 1] != '/') {
 					if (slen + 1 >= sizeof(symlink)) {
+						if (m)
+							free(resolved);
 						errno = ENAMETOOLONG;
 						return (NULL);
 					}
@@ -179,6 +221,8 @@ realpath(const char *path, char resolved[PATH_MAX])
 				}
 				left_len = strlcat(symlink, left, sizeof(left));
 				if (left_len >= sizeof(left)) {
+					if (m)
+						free(resolved);
 					errno = ENAMETOOLONG;
 					return (NULL);
 				}

From 5673e3cb08f0b3d813ce50e658fbc822e200904a Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Apr 2010 10:19:27 +0000
Subject: [PATCH 157/532] The cache_enter(9) function shall not be called for
 doomed dvp. Assert this.

In the reported panic, vdestroy() fired the assertion "vp has namecache
for ..", because pseudofs may end up doing cache_enter() with reclaimed
dvp, after dotdot lookup temporary unlocked dvp.
Similar problem exists in ufs_lookup() for "." lookup, when vnode
lock needs to be upgraded.

Verify that dvp is not reclaimed before calling cache_enter().

Reported and tested by:	pho
Reviewed by:	kan
MFC after:	2 weeks
---
 sys/fs/pseudofs/pseudofs_vnops.c | 2 +-
 sys/kern/vfs_cache.c             | 2 ++
 sys/ufs/ufs/ufs_lookup.c         | 8 ++++++++
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/sys/fs/pseudofs/pseudofs_vnops.c b/sys/fs/pseudofs/pseudofs_vnops.c
index 5854378336c..f8343a97401 100644
--- a/sys/fs/pseudofs/pseudofs_vnops.c
+++ b/sys/fs/pseudofs/pseudofs_vnops.c
@@ -542,7 +542,7 @@ pfs_lookup(struct vop_cachedlookup_args *va)
 
 	if (cnp->cn_flags & ISDOTDOT)
 		vn_lock(vn, LK_EXCLUSIVE|LK_RETRY);
-	if (cnp->cn_flags & MAKEENTRY)
+	if (cnp->cn_flags & MAKEENTRY && !(vn->v_iflag & VI_DOOMED))
 		cache_enter(vn, *vpp, cnp);
 	PFS_RETURN (0);
  failed:
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
index 533ec97875d..a13a721850d 100644
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -611,6 +611,8 @@ cache_enter(dvp, vp, cnp)
 	CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr);
 	VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp,
 	    ("cache_enter: Adding a doomed vnode"));
+	VNASSERT(dvp == NULL || (dvp->v_iflag & VI_DOOMED) == 0, dvp,
+	    ("cache_enter: Doomed vnode used as src"));
 
 	if (!doingcache)
 		return;
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c
index b0247e77d0d..ab71cf6df55 100644
--- a/sys/ufs/ufs/ufs_lookup.c
+++ b/sys/ufs/ufs/ufs_lookup.c
@@ -704,6 +704,14 @@ found:
 				vn_lock(vdp, LK_UPGRADE | LK_RETRY);
 			else /* if (ltype == LK_SHARED) */
 				vn_lock(vdp, LK_DOWNGRADE | LK_RETRY);
+			/*
+			 * Relock for the "." case may left us with
+			 * reclaimed vnode.
+			 */
+			if (vdp->v_iflag & VI_DOOMED) {
+				vrele(vdp);
+				return (ENOENT);
+			}
 		}
 		*vpp = vdp;
 	} else {

From 153bfab76a878d55c9fe0958d331cf98f9b8a055 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 20 Apr 2010 10:42:08 +0000
Subject: [PATCH 158/532] Remove svn:executable prop.

---
 sys/mips/rmi/debug.h                  | 0
 sys/mips/rmi/msgring.h                | 0
 sys/mips/rmi/shared_structs.h         | 0
 sys/mips/rmi/shared_structs_func.h    | 0
 sys/mips/rmi/shared_structs_offsets.h | 0
 5 files changed, 0 insertions(+), 0 deletions(-)
 mode change 100755 => 100644 sys/mips/rmi/debug.h
 mode change 100755 => 100644 sys/mips/rmi/msgring.h
 mode change 100755 => 100644 sys/mips/rmi/shared_structs.h
 mode change 100755 => 100644 sys/mips/rmi/shared_structs_func.h
 mode change 100755 => 100644 sys/mips/rmi/shared_structs_offsets.h

diff --git a/sys/mips/rmi/debug.h b/sys/mips/rmi/debug.h
old mode 100755
new mode 100644
diff --git a/sys/mips/rmi/msgring.h b/sys/mips/rmi/msgring.h
old mode 100755
new mode 100644
diff --git a/sys/mips/rmi/shared_structs.h b/sys/mips/rmi/shared_structs.h
old mode 100755
new mode 100644
diff --git a/sys/mips/rmi/shared_structs_func.h b/sys/mips/rmi/shared_structs_func.h
old mode 100755
new mode 100644
diff --git a/sys/mips/rmi/shared_structs_offsets.h b/sys/mips/rmi/shared_structs_offsets.h
old mode 100755
new mode 100644

From 0a2d5fea5921acbf8945307784cf6e4b7924a95a Mon Sep 17 00:00:00 2001
From: Attilio Rao 
Date: Tue, 20 Apr 2010 12:22:06 +0000
Subject: [PATCH 159/532] Fix compilation in the !SMP case. Keep the interrupts
 disabled in order to avoid preemption problems.

Reported by:	tinderbox, b.f. 
MFC:		2 weeks
X-MFC:		r206878
---
 sys/kern/kern_shutdown.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 4b27d45f6c0..bd3c7aa478c 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -496,8 +496,14 @@ shutdown_reset(void *junk, int howto)
 	 *   generally, threads busy-waiting, with this spinlock held,
 	 *   and waiting for responses by threads on other CPUs
 	 *   (ie. smp_tlb_shootdown()).
+	 *
+	 * For the !SMP case it just needs to handle the former problem.
 	 */
+#ifdef SMP
 	mtx_lock_spin(&smp_ipi_mtx);
+#else
+	spinlock_enter();
+#endif
 
 	/* cpu_boot(howto); */ /* doesn't do anything at the moment */
 	cpu_reset();

From 655c8a600bb02846e05f137609abb62134a13a26 Mon Sep 17 00:00:00 2001
From: Konstantin Belousov 
Date: Tue, 20 Apr 2010 14:22:29 +0000
Subject: [PATCH 160/532] Free() is not allowed to modify errno, remove safety
 brackets around it [1]. Add small optimization, do not copy a string to the
 buffer that is to be freed immediately after.

Noted by:	jh [1]
Reviewed by:	jh
MFC after:	2 weeks
---
 lib/libc/stdlib/realpath.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c
index 31c93e67741..e75ee4ac823 100644
--- a/lib/libc/stdlib/realpath.c
+++ b/lib/libc/stdlib/realpath.c
@@ -84,12 +84,10 @@ realpath(const char * __restrict path, char * __restrict resolved)
 		left_len = strlcpy(left, path + 1, sizeof(left));
 	} else {
 		if (getcwd(resolved, PATH_MAX) == NULL) {
-			strlcpy(resolved, ".", PATH_MAX);
-			if (m) {
-				serrno = errno;
+			if (m)
 				free(resolved);
-				errno = serrno;
-			}
+			else
+				strlcpy(resolved, ".", PATH_MAX);
 			return (NULL);
 		}
 		resolved_len = strlen(resolved);
@@ -168,11 +166,8 @@ realpath(const char * __restrict path, char * __restrict resolved)
 				errno = serrno;
 				return (resolved);
 			}
-			if (m) {
-				serrno = errno;
+			if (m)
 				free(resolved);
-				errno = serrno;
-			}
 			return (NULL);
 		}
 		if (S_ISLNK(sb.st_mode)) {
@@ -184,11 +179,8 @@ realpath(const char * __restrict path, char * __restrict resolved)
 			}
 			slen = readlink(resolved, symlink, sizeof(symlink) - 1);
 			if (slen < 0) {
-				if (m) {
-					serrno = errno;
+				if (m)
 					free(resolved);
-					errno = serrno;
-				}
 				return (NULL);
 			}
 			symlink[slen] = '\0';

From b527a2a4dc2a83b4da9a2b2fa6cdc6db4733da12 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 20 Apr 2010 16:30:17 +0000
Subject: [PATCH 161/532] The amd64 version of the cyclic dtrace module is a
 verbatim copy of the i386 version, so instead having a copy of the same file,
 use Makefile foo to include the i386 version on amd64.

---
 sys/cddl/dev/cyclic/amd64/cyclic_machdep.c | 133 ---------------------
 sys/modules/cyclic/Makefile                |   2 +-
 2 files changed, 1 insertion(+), 134 deletions(-)
 delete mode 100644 sys/cddl/dev/cyclic/amd64/cyclic_machdep.c

diff --git a/sys/cddl/dev/cyclic/amd64/cyclic_machdep.c b/sys/cddl/dev/cyclic/amd64/cyclic_machdep.c
deleted file mode 100644
index 9a15b2cdad0..00000000000
--- a/sys/cddl/dev/cyclic/amd64/cyclic_machdep.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*-
- * Copyright 2007 John Birrell 
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-static void enable(cyb_arg_t);
-static void disable(cyb_arg_t);
-static void reprogram(cyb_arg_t, hrtime_t);
-static void xcall(cyb_arg_t, cpu_t *, cyc_func_t, void *);
-
-static cyc_backend_t	be	= {
-	NULL,		/* cyb_configure */
-	NULL,		/* cyb_unconfigure */
-	enable,
-	disable,
-	reprogram,
-	xcall,
-	NULL		/* cyb_arg_t cyb_arg */
-};
-
-static void
-cyclic_ap_start(void *dummy)
-{
-	/* Initialise the rest of the CPUs. */
-	cyclic_mp_init();
-}
-
-SYSINIT(cyclic_ap_start, SI_SUB_SMP, SI_ORDER_ANY, cyclic_ap_start, NULL);
-
-/*
- *  Machine dependent cyclic subsystem initialisation.
- */
-static void
-cyclic_machdep_init(void)
-{
-	/* Register the cyclic backend. */
-	cyclic_init(&be);
-}
-
-static void
-cyclic_machdep_uninit(void)
-{
-	int i;
-
-	for (i = 0; i <= mp_maxid; i++)
-		/* Reset the cyclic clock callback hook. */
-		lapic_cyclic_clock_func[i] = NULL;
-
-	/* De-register the cyclic backend. */
-	cyclic_uninit();
-}
-
-static hrtime_t exp_due[MAXCPU];
-
-/*
- * This function is the one registered by the machine dependent
- * initialiser as the callback for high speed timer events.
- */
-static void
-cyclic_clock(struct trapframe *frame)
-{
-	cpu_t *c = &solaris_cpu[curcpu];
-
-	if (c->cpu_cyclic != NULL && gethrtime() >= exp_due[curcpu]) {
-		if (TRAPF_USERMODE(frame)) {
-			c->cpu_profile_pc = 0;
-			c->cpu_profile_upc = TRAPF_PC(frame);
-		} else {
-			c->cpu_profile_pc = TRAPF_PC(frame);
-			c->cpu_profile_upc = 0;
-		}
-
-		c->cpu_intr_actv = 1;
-
-		/* Fire any timers that are due. */
-		cyclic_fire(c);
-
-		c->cpu_intr_actv = 0;
-	}
-}
-
-static void enable(cyb_arg_t arg)
-{
-	/* Register the cyclic clock callback function. */
-	lapic_cyclic_clock_func[curcpu] = cyclic_clock;
-}
-
-static void disable(cyb_arg_t arg)
-{
-	/* Reset the cyclic clock callback function. */
-	lapic_cyclic_clock_func[curcpu] = NULL;
-}
-
-static void reprogram(cyb_arg_t arg, hrtime_t exp)
-{
-	exp_due[curcpu] = exp;
-}
-
-static void xcall(cyb_arg_t arg, cpu_t *c, cyc_func_t func, void *param)
-{
-	/*
-	 * If the target CPU is the current one, just call the
-	 * function. This covers the non-SMP case.
-	 */
-	if (c == &solaris_cpu[curcpu])
-		(*func)(param);
-	else
-		smp_rendezvous_cpus((cpumask_t) (1 << c->cpuid), NULL,
-		    func, smp_no_rendevous_barrier, param);
-}
diff --git a/sys/modules/cyclic/Makefile b/sys/modules/cyclic/Makefile
index db99488e138..371dac68054 100644
--- a/sys/modules/cyclic/Makefile
+++ b/sys/modules/cyclic/Makefile
@@ -10,7 +10,7 @@ SRCS+=		vnode_if.h
 CFLAGS+=	-I${.CURDIR}/../../cddl/compat/opensolaris		\
 		-I${.CURDIR}/../../cddl/contrib/opensolaris/uts/common	\
 		-I${.CURDIR}/../..					\
-		-I${.CURDIR}/../../cddl/dev/cyclic/${MACHINE_ARCH}
+		-I${.CURDIR}/../../cddl/dev/cyclic/${MACHINE_ARCH:S/amd64/i386/}
 
 CFLAGS+=	-DDEBUG=1
 

From ff569d8436052b01c102a791ff60caf4a05b0319 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 20 Apr 2010 17:03:30 +0000
Subject: [PATCH 162/532] Rename the cyclic global variable
 lapic_cyclic_clock_func to just cyclic_clock_func. This will make more sense
 when we start developing non x86 cyclic version.

---
 sys/amd64/amd64/local_apic.c              | 6 +++---
 sys/cddl/dev/cyclic/i386/cyclic_machdep.c | 6 +++---
 sys/i386/i386/local_apic.c                | 6 +++---
 sys/sys/dtrace_bsd.h                      | 2 +-
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/sys/amd64/amd64/local_apic.c b/sys/amd64/amd64/local_apic.c
index 8edc971c95c..c8f60f06675 100644
--- a/sys/amd64/amd64/local_apic.c
+++ b/sys/amd64/amd64/local_apic.c
@@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
 
 #ifdef KDTRACE_HOOKS
 #include 
-cyclic_clock_func_t	lapic_cyclic_clock_func[MAXCPU];
+cyclic_clock_func_t	cyclic_clock_func[MAXCPU];
 #endif
 
 /* Sanity checks on IDT vectors. */
@@ -778,8 +778,8 @@ lapic_handle_timer(struct trapframe *frame)
 	 * timers.
 	 */
 	int cpu = PCPU_GET(cpuid);
-	if (lapic_cyclic_clock_func[cpu] != NULL)
-		(*lapic_cyclic_clock_func[cpu])(frame);
+	if (cyclic_clock_func[cpu] != NULL)
+		(*cyclic_clock_func[cpu])(frame);
 #endif
 
 	/* Fire hardclock at hz. */
diff --git a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
index fa40db9329c..0b6ab5936e2 100644
--- a/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
+++ b/sys/cddl/dev/cyclic/i386/cyclic_machdep.c
@@ -67,7 +67,7 @@ cyclic_machdep_uninit(void)
 
 	for (i = 0; i <= mp_maxid; i++)
 		/* Reset the cyclic clock callback hook. */
-		lapic_cyclic_clock_func[i] = NULL;
+		cyclic_clock_func[i] = NULL;
 
 	/* De-register the cyclic backend. */
 	cyclic_uninit();
@@ -105,13 +105,13 @@ cyclic_clock(struct trapframe *frame)
 static void enable(cyb_arg_t arg)
 {
 	/* Register the cyclic clock callback function. */
-	lapic_cyclic_clock_func[curcpu] = cyclic_clock;
+	cyclic_clock_func[curcpu] = cyclic_clock;
 }
 
 static void disable(cyb_arg_t arg)
 {
 	/* Reset the cyclic clock callback function. */
-	lapic_cyclic_clock_func[curcpu] = NULL;
+	cyclic_clock_func[curcpu] = NULL;
 }
 
 static void reprogram(cyb_arg_t arg, hrtime_t exp)
diff --git a/sys/i386/i386/local_apic.c b/sys/i386/i386/local_apic.c
index 302535f27f9..d894d3271d0 100644
--- a/sys/i386/i386/local_apic.c
+++ b/sys/i386/i386/local_apic.c
@@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$");
 
 #ifdef KDTRACE_HOOKS
 #include 
-cyclic_clock_func_t	lapic_cyclic_clock_func[MAXCPU];
+cyclic_clock_func_t	cyclic_clock_func[MAXCPU];
 #endif
 
 /* Sanity checks on IDT vectors. */
@@ -779,8 +779,8 @@ lapic_handle_timer(struct trapframe *frame)
 	 * timers.
 	 */
 	int cpu = PCPU_GET(cpuid);
-	if (lapic_cyclic_clock_func[cpu] != NULL)
-		(*lapic_cyclic_clock_func[cpu])(frame);
+	if (cyclic_clock_func[cpu] != NULL)
+		(*cyclic_clock_func[cpu])(frame);
 #endif
 
 	/* Fire hardclock at hz. */
diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h
index f3232841fa0..a14a1a160f3 100644
--- a/sys/sys/dtrace_bsd.h
+++ b/sys/sys/dtrace_bsd.h
@@ -50,7 +50,7 @@ typedef	void (*cyclic_clock_func_t)(struct trapframe *);
  *
  * Defining them here avoids a proliferation of header files.
  */
-extern cyclic_clock_func_t     lapic_cyclic_clock_func[];
+extern cyclic_clock_func_t     cyclic_clock_func[];
 
 /*
  * The dtrace module handles traps that occur during a DTrace probe.

From 0017771c681d770dcec4aec1efb48438b82fd814 Mon Sep 17 00:00:00 2001
From: Rui Paulo 
Date: Tue, 20 Apr 2010 17:22:20 +0000
Subject: [PATCH 163/532] Add the necessary hooks for dtrace cyclic module.

---
 sys/mips/mips/tick.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c
index d2678b1f637..9a9108c0b83 100644
--- a/sys/mips/mips/tick.c
+++ b/sys/mips/mips/tick.c
@@ -295,7 +295,16 @@ clock_intr(void *arg)
 	 */
 	if (delta > cycles_per_hz)
 		delta = cycles_per_hz;
-
+#if KDTRACE_HOOKS
+	/*
+	 * If the DTrace hooks are configured and a callback function
+	 * has been registered, then call it to process the high speed
+	 * timers.
+	 */
+	int cpu = PCPU_GET(cpuid);
+	if (cyclic_clock_func[cpu] != NULL)
+		(*cyclic_clock_func[cpu])(tf);
+#endif
 	/* Fire hardclock at hz. */
 	cpu_ticks->hard_ticks += delta;
 	if (cpu_ticks->hard_ticks >= cycles_per_hz) {

From 0e954830e516457c9d94b6a20ca4e54d3055e8d3 Mon Sep 17 00:00:00 2001
From: Warner Losh 
Date: Tue, 20 Apr 2010 17:57:43 +0000
Subject: [PATCH 164/532] Make this file more C++ friendly.

---
 sys/sys/thr.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/sys/sys/thr.h b/sys/sys/thr.h
index ae4a65d368f..7ccc8724ffb 100644
--- a/sys/sys/thr.h
+++ b/sys/sys/thr.h
@@ -30,6 +30,7 @@
 #ifndef _SYS_THR_H_
 #define	_SYS_THR_H_
 
+#include 
 #include 
 #include 
 
@@ -68,6 +69,7 @@ typedef __pid_t		pid_t;
 #define _PID_T_DECLARED
 #endif
 
+__BEGIN_DECLS
 int thr_create(ucontext_t *ctx, long *id, int flags);
 int thr_new(struct thr_param *param, int param_size);
 int thr_self(long *id);
@@ -77,7 +79,7 @@ int thr_kill2(pid_t pid, long id, int sig);
 int thr_suspend(const struct timespec *timeout);
 int thr_wake(long id);
 int thr_set_name(long id, const char *name);
-
+__END_DECLS
 #endif /* !_KERNEL */
 
 #endif /* ! _SYS_THR_H_ */

From 60e3ce611c7b983ce0d18862cfc112beb4bc74b7 Mon Sep 17 00:00:00 2001
From: Ana Kukec 
Date: Tue, 20 Apr 2010 18:16:56 +0000
Subject: [PATCH 165/532] Add myself and list bz@ as my mentor.

Approved by:	bz (mentor)
---
 share/misc/committers-src.dot | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot
index a52aa272a54..f7e4a326e66 100644
--- a/share/misc/committers-src.dot
+++ b/share/misc/committers-src.dot
@@ -55,6 +55,7 @@ node [color=lightblue2, style=filled, bgcolor=black];
 ache [label="Andrey Chernov\nache@FreeBSD.org\n1993/10/31"]
 akiyama [label="Shunsuke Akiyama\nakiyama@FreeBSD.org\n2000/06/19"]
 ambrisko [label="Doug Ambrisko\nambrisko@FreeBSD.org\n2001/12/19"]
+anchie [label="Ana Kukec\anchie@FreeBSD.org\n2010/04/14"]
 andre [label="Andre Oppermann\nandre@FreeBSD.org\n2003/11/12"]
 anholt [label="Eric Anholt\nanholt@FreeBSD.org\n2002/04/22"]
 antoine [label="Antoine Brodin\nantoine@FreeBSD.org\n2008/02/03"]
@@ -238,6 +239,7 @@ brian -> joe
 brooks -> bushman
 brooks -> jamie
 
+bz -> anchie
 bz -> jamie
 bz -> syrinx
 

From 20c14533dda078fcc83f6ad7f1221933f1fdd87b Mon Sep 17 00:00:00 2001
From: Xin LI 
Date: Tue, 20 Apr 2010 18:42:51 +0000
Subject: [PATCH 166/532] Vendor import of zlib 1.2.5.

---
 ChangeLog  | 28 +++++++++++++++++++++++++++-
 README     |  4 ++--
 crc32.c    |  2 +-
 deflate.c  |  2 +-
 deflate.h  | 24 ++++++++++++------------
 gzguts.h   | 12 ++++++++----
 gzlib.c    |  6 +++---
 inffast.c  |  4 ++--
 inffast.h  |  4 ++--
 inftrees.c |  6 +++---
 inftrees.h |  4 ++--
 trees.c    | 17 +++++++++--------
 trees.h    |  4 ++--
 zconf.h    | 14 ++++++++++----
 zlib.3     |  4 ++--
 zlib.h     | 10 +++++-----
 zutil.c    | 24 ++++++++++++------------
 zutil.h    | 22 ++++++++++++++--------
 18 files changed, 117 insertions(+), 74 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 898c197f0cf..f310bb0fcdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,32 @@
 
                 ChangeLog file for zlib
 
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
 Changes in 1.2.4.3 (10 Apr 2010)
 - Only use CROSS_PREFIX in configure for ar and ranlib if they exist
 - Use CROSS_PREFIX for nm [Bar-Lev]
@@ -151,7 +177,7 @@ Changes in 1.2.3.6 (17 Jan 2010)
 - Correct email address in configure for system options
 - Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
 - Update zlib.map [Brown]
-- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Tšršk]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
 - Apply various fixes to CMakeLists.txt [Lowman]
 - Add checks on len in gzread() and gzwrite()
 - Add error message for no more room for gzungetc()
diff --git a/README b/README
index 68ff992369c..d4219bf889f 100644
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 ZLIB DATA COMPRESSION LIBRARY
 
-zlib 1.2.4.3 is a general purpose data compression library.  All the code is
+zlib 1.2.5 is a general purpose data compression library.  All the code is
 thread safe.  The data format used by the zlib library is described by RFCs
 (Request for Comments) 1950 to 1952 in the files
 http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
@@ -31,7 +31,7 @@ Mark Nelson  wrote an article about zlib for the Jan.  1997
 issue of Dr.  Dobb's Journal; a copy of the article is available at
 http://marknelson.us/1997/01/01/zlib-engine/ .
 
-The changes made in version 1.2.4.3 are documented in the file ChangeLog.
+The changes made in version 1.2.5 are documented in the file ChangeLog.
 
 Unsupported third party contributions are provided in directory contrib/ .
 
diff --git a/crc32.c b/crc32.c
index 6b81fb4a1ca..91be372d224 100644
--- a/crc32.c
+++ b/crc32.c
@@ -1,5 +1,5 @@
 /* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2006 Mark Adler
+ * Copyright (C) 1995-2006, 2010 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  *
  * Thanks to Rodney Brown  for his contribution of faster
diff --git a/deflate.c b/deflate.c
index efb26bf5d91..5c4022f3d47 100644
--- a/deflate.c
+++ b/deflate.c
@@ -52,7 +52,7 @@
 #include "deflate.h"
 
 const char deflate_copyright[] =
-   " deflate 1.2.4.3 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
+   " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
diff --git a/deflate.h b/deflate.h
index f53deba852b..cbf0d1ea5d9 100644
--- a/deflate.h
+++ b/deflate.h
@@ -1,5 +1,5 @@
 /* deflate.h -- internal compression state
- * Copyright (C) 1995-2009 Jean-loup Gailly
+ * Copyright (C) 1995-2010 Jean-loup Gailly
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -290,13 +290,13 @@ typedef struct internal_state {
    memory checker errors from longest match routines */
 
         /* in trees.c */
-void _tr_init         OF((deflate_state *s));
-int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
-void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
-                          int last));
-void _tr_align        OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-                          int last));
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
 
 #define d_code(dist) \
    ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
@@ -309,11 +309,11 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
 /* Inline versions of _tr_tally for speed: */
 
 #if defined(GEN_TREES_H) || !defined(STDC)
-  extern uch _length_code[];
-  extern uch _dist_code[];
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
 #else
-  extern const uch _length_code[];
-  extern const uch _dist_code[];
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
 #endif
 
 # define _tr_tally_lit(s, c, flush) \
diff --git a/gzguts.h b/gzguts.h
index b0a4cbdc336..0f8fb79f87d 100644
--- a/gzguts.h
+++ b/gzguts.h
@@ -12,7 +12,11 @@
 #  endif
 #endif
 
-#define ZLIB_INTERNAL
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
 
 #include 
 #include "zlib.h"
@@ -112,9 +116,9 @@ typedef struct {
 typedef gz_state FAR *gz_statep;
 
 /* shared functions */
-ZEXTERN void ZEXPORT gz_error OF((gz_statep, int, const char *));
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
 #if defined UNDER_CE
-ZEXTERN char ZEXPORT *gz_strwinerror OF((DWORD error));
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
 #endif
 
 /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
@@ -123,6 +127,6 @@ ZEXTERN char ZEXPORT *gz_strwinerror OF((DWORD error));
 #ifdef INT_MAX
 #  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
 #else
-ZEXTERN unsigned ZEXPORT gz_intmax OF((void));
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
 #  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
 #endif
diff --git a/gzlib.c b/gzlib.c
index 18390026905..603e60ed544 100644
--- a/gzlib.c
+++ b/gzlib.c
@@ -26,7 +26,7 @@ local gzFile gz_open OF((const char *, int, const char *));
 
    The gz_strwinerror function does not change the current setting of
    GetLastError. */
-char ZEXPORT *gz_strwinerror (error)
+char ZLIB_INTERNAL *gz_strwinerror (error)
      DWORD error;
 {
     static char buf[1024];
@@ -482,7 +482,7 @@ void ZEXPORT gzclearerr(file)
    memory).  Simply save the error message as a static string.  If there is an
    allocation failure constructing the error message, then convert the error to
    out of memory. */
-void ZEXPORT gz_error(state, err, msg)
+void ZLIB_INTERNAL gz_error(state, err, msg)
     gz_statep state;
     int err;
     const char *msg;
@@ -522,7 +522,7 @@ void ZEXPORT gz_error(state, err, msg)
    available) -- we need to do this to cover cases where 2's complement not
    used, since C standard permits 1's complement and sign-bit representations,
    otherwise we could just use ((unsigned)-1) >> 1 */
-unsigned ZEXPORT gz_intmax()
+unsigned ZLIB_INTERNAL gz_intmax()
 {
     unsigned p, q;
 
diff --git a/inffast.c b/inffast.c
index 0a0761f3de0..2f1d60b43b8 100644
--- a/inffast.c
+++ b/inffast.c
@@ -1,5 +1,5 @@
 /* inffast.c -- fast decoding
- * Copyright (C) 1995-2008 Mark Adler
+ * Copyright (C) 1995-2008, 2010 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -64,7 +64,7 @@
       requires strm->avail_out >= 258 for each loop to avoid checking for
       output space.
  */
-void inflate_fast(strm, start)
+void ZLIB_INTERNAL inflate_fast(strm, start)
 z_streamp strm;
 unsigned start;         /* inflate()'s starting value for strm->avail_out */
 {
diff --git a/inffast.h b/inffast.h
index 1e88d2d97b5..e5c1aa4ca8c 100644
--- a/inffast.h
+++ b/inffast.h
@@ -1,5 +1,5 @@
 /* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
+ * Copyright (C) 1995-2003, 2010 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -8,4 +8,4 @@
    subject to change. Applications should only use zlib.h.
  */
 
-void inflate_fast OF((z_streamp strm, unsigned start));
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/inftrees.c b/inftrees.c
index 430b1741585..11e9c52accb 100644
--- a/inftrees.c
+++ b/inftrees.c
@@ -9,7 +9,7 @@
 #define MAXBITS 15
 
 const char inflate_copyright[] =
-   " inflate 1.2.4.3 Copyright 1995-2010 Mark Adler ";
+   " inflate 1.2.5 Copyright 1995-2010 Mark Adler ";
 /*
   If you use the zlib library in a product, an acknowledgment is welcome
   in the documentation of your product. If for some reason you cannot
@@ -29,7 +29,7 @@ const char inflate_copyright[] =
    table index bits.  It will differ if the request is greater than the
    longest code or if it is less than the shortest code.
  */
-int inflate_table(type, lens, codes, table, bits, work)
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
 codetype type;
 unsigned short FAR *lens;
 unsigned codes;
@@ -62,7 +62,7 @@ unsigned short FAR *work;
         35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
     static const unsigned short lext[31] = { /* Length codes 257..285 extra */
         16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 195, 66};
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195};
     static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
         1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
         257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
diff --git a/inftrees.h b/inftrees.h
index 67461da0348..baa53a0b1a1 100644
--- a/inftrees.h
+++ b/inftrees.h
@@ -1,5 +1,5 @@
 /* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
+ * Copyright (C) 1995-2005, 2010 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -57,6 +57,6 @@ typedef enum {
     DISTS
 } codetype;
 
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
                              unsigned codes, code FAR * FAR *table,
                              unsigned FAR *bits, unsigned short FAR *work));
diff --git a/trees.c b/trees.c
index 1a6e997ac0a..56e9bb1c115 100644
--- a/trees.c
+++ b/trees.c
@@ -1,5 +1,5 @@
 /* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-2009 Jean-loup Gailly
+ * Copyright (C) 1995-2010 Jean-loup Gailly
  * detect_data_type() function provided freely by Cosmin Truta, 2006
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
@@ -351,13 +351,14 @@ void gen_trees_header()
                 static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
     }
 
-    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
     for (i = 0; i < DIST_CODE_LEN; i++) {
         fprintf(header, "%2u%s", _dist_code[i],
                 SEPARATOR(i, DIST_CODE_LEN-1, 20));
     }
 
-    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
     for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
         fprintf(header, "%2u%s", _length_code[i],
                 SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
@@ -382,7 +383,7 @@ void gen_trees_header()
 /* ===========================================================================
  * Initialize the tree data structures for a new zlib stream.
  */
-void _tr_init(s)
+void ZLIB_INTERNAL _tr_init(s)
     deflate_state *s;
 {
     tr_static_init();
@@ -867,7 +868,7 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
 /* ===========================================================================
  * Send a stored block
  */
-void _tr_stored_block(s, buf, stored_len, last)
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
     deflate_state *s;
     charf *buf;       /* input block */
     ulg stored_len;   /* length of input block */
@@ -892,7 +893,7 @@ void _tr_stored_block(s, buf, stored_len, last)
  * To simplify the code, we assume the worst case of last real code encoded
  * on one bit only.
  */
-void _tr_align(s)
+void ZLIB_INTERNAL _tr_align(s)
     deflate_state *s;
 {
     send_bits(s, STATIC_TREES<<1, 3);
@@ -921,7 +922,7 @@ void _tr_align(s)
  * Determine the best encoding for the current block: dynamic trees, static
  * trees or store, and output the encoded block to the zip file.
  */
-void _tr_flush_block(s, buf, stored_len, last)
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
     deflate_state *s;
     charf *buf;       /* input block, or NULL if too old */
     ulg stored_len;   /* length of input block */
@@ -1022,7 +1023,7 @@ void _tr_flush_block(s, buf, stored_len, last)
  * Save the match info and tally the frequency counts. Return true if
  * the current block must be flushed.
  */
-int _tr_tally (s, dist, lc)
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
     deflate_state *s;
     unsigned dist;  /* distance of matched string */
     unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
diff --git a/trees.h b/trees.h
index 72facf900f7..d35639d82a2 100644
--- a/trees.h
+++ b/trees.h
@@ -70,7 +70,7 @@ local const ct_data static_dtree[D_CODES] = {
 {{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
 };
 
-const uch _dist_code[DIST_CODE_LEN] = {
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
  0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
@@ -99,7 +99,7 @@ const uch _dist_code[DIST_CODE_LEN] = {
 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
 };
 
-const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
  0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
diff --git a/zconf.h b/zconf.h
index 1988920109f..02ce56c4313 100644
--- a/zconf.h
+++ b/zconf.h
@@ -315,10 +315,6 @@
 #  endif
 #endif
 
-#ifdef HAVE_VISIBILITY_PRAGMA
-#  define ZEXTERN __attribute__((visibility ("default"))) extern
-#endif
-
 #ifndef ZEXTERN
 #  define ZEXTERN extern
 #endif
@@ -368,6 +364,16 @@ typedef uLong FAR uLongf;
 #  include     /* for off_t */
 #endif
 
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
 #if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
 #  include        /* for SEEK_* and off_t */
 #  ifdef VMS
diff --git a/zlib.3 b/zlib.3
index b5346168d0e..27adc4cd10a 100644
--- a/zlib.3
+++ b/zlib.3
@@ -1,4 +1,4 @@
-.TH ZLIB 3 "10 Apr 2010"
+.TH ZLIB 3 "19 Apr 2010"
 .SH NAME
 zlib \- compression/decompression library
 .SH SYNOPSIS
@@ -125,7 +125,7 @@ before asking for help.
 Send questions and/or comments to zlib@gzip.org,
 or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
 .SH AUTHORS
-Version 1.2.4.3
+Version 1.2.5
 Copyright (C) 1995-2010 Jean-loup Gailly (jloup@gzip.org)
 and Mark Adler (madler@alumni.caltech.edu).
 .LP
diff --git a/zlib.h b/zlib.h
index 699630c1ddc..bfbba83e8ee 100644
--- a/zlib.h
+++ b/zlib.h
@@ -1,5 +1,5 @@
 /* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.2.4.3, April 10th, 2010
+  version 1.2.5, April 19th, 2010
 
   Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
 
@@ -37,12 +37,12 @@
 extern "C" {
 #endif
 
-#define ZLIB_VERSION "1.2.4.3"
-#define ZLIB_VERNUM 0x1243
+#define ZLIB_VERSION "1.2.5"
+#define ZLIB_VERNUM 0x1250
 #define ZLIB_VER_MAJOR 1
 #define ZLIB_VER_MINOR 2
-#define ZLIB_VER_REVISION 4
-#define ZLIB_VER_SUBREVISION 3
+#define ZLIB_VER_REVISION 5
+#define ZLIB_VER_SUBREVISION 0
 
 /*
     The 'zlib' compression library provides in-memory compression and
diff --git a/zutil.c b/zutil.c
index 6ba16f68c23..898ed345b0e 100644
--- a/zutil.c
+++ b/zutil.c
@@ -1,5 +1,5 @@
 /* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * Copyright (C) 1995-2005, 2010 Jean-loup Gailly.
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
@@ -117,9 +117,9 @@ uLong ZEXPORT zlibCompileFlags()
 #  ifndef verbose
 #    define verbose 0
 #  endif
-int z_verbose = verbose;
+int ZLIB_INTERNAL z_verbose = verbose;
 
-void z_error (m)
+void ZLIB_INTERNAL z_error (m)
     char *m;
 {
     fprintf(stderr, "%s\n", m);
@@ -146,7 +146,7 @@ const char * ZEXPORT zError(err)
 
 #ifndef HAVE_MEMCPY
 
-void zmemcpy(dest, source, len)
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
     Bytef* dest;
     const Bytef* source;
     uInt  len;
@@ -157,7 +157,7 @@ void zmemcpy(dest, source, len)
     } while (--len != 0);
 }
 
-int zmemcmp(s1, s2, len)
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
     const Bytef* s1;
     const Bytef* s2;
     uInt  len;
@@ -170,7 +170,7 @@ int zmemcmp(s1, s2, len)
     return 0;
 }
 
-void zmemzero(dest, len)
+void ZLIB_INTERNAL zmemzero(dest, len)
     Bytef* dest;
     uInt  len;
 {
@@ -213,7 +213,7 @@ local ptr_table table[MAX_PTR];
  * a protected system like OS/2. Use Microsoft C instead.
  */
 
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
 {
     voidpf buf = opaque; /* just to make some compilers happy */
     ulg bsize = (ulg)items*size;
@@ -237,7 +237,7 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
     return buf;
 }
 
-void  zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
 {
     int n;
     if (*(ush*)&ptr != 0) { /* object < 64K */
@@ -272,13 +272,13 @@ void  zcfree (voidpf opaque, voidpf ptr)
 #  define _hfree   hfree
 #endif
 
-voidpf zcalloc (voidpf opaque, uInt items, uInt size)
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
 {
     if (opaque) opaque = 0; /* to make compiler happy */
     return _halloc((long)items, size);
 }
 
-void  zcfree (voidpf opaque, voidpf ptr)
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
 {
     if (opaque) opaque = 0; /* to make compiler happy */
     _hfree(ptr);
@@ -297,7 +297,7 @@ extern voidp  calloc OF((uInt items, uInt size));
 extern void   free   OF((voidpf ptr));
 #endif
 
-voidpf zcalloc (opaque, items, size)
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
     voidpf opaque;
     unsigned items;
     unsigned size;
@@ -307,7 +307,7 @@ voidpf zcalloc (opaque, items, size)
                               (voidpf)calloc(items, size);
 }
 
-void  zcfree (opaque, ptr)
+void ZLIB_INTERNAL zcfree (opaque, ptr)
     voidpf opaque;
     voidpf ptr;
 {
diff --git a/zutil.h b/zutil.h
index a250088640a..258fa88799a 100644
--- a/zutil.h
+++ b/zutil.h
@@ -13,7 +13,12 @@
 #ifndef ZUTIL_H
 #define ZUTIL_H
 
-#define ZLIB_INTERNAL
+#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ)
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
 #include "zlib.h"
 
 #ifdef STDC
@@ -231,16 +236,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #    define zmemzero(dest, len) memset(dest, 0, len)
 #  endif
 #else
-   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
-   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
-   extern void zmemzero OF((Bytef* dest, uInt len));
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
 #endif
 
 /* Diagnostic functions */
 #ifdef DEBUG
 #  include 
-   extern int z_verbose;
-   extern void z_error    OF((char *m));
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
 #  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
 #  define Trace(x) {if (z_verbose>=0) fprintf x ;}
 #  define Tracev(x) {if (z_verbose>0) fprintf x ;}
@@ -257,8 +262,9 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
 #endif
 
 
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void   zcfree  OF((voidpf opaque, voidpf ptr));
+voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                        unsigned size));
+void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
 
 #define ZALLOC(strm, items, size) \
            (*((strm)->zalloc))((strm)->opaque, (items), (size))

From 62592d917310c364b915d2c4be86bc1e0da1c1a1 Mon Sep 17 00:00:00 2001
From: Rebecca Cran 
Date: Tue, 20 Apr 2010 19:30:12 +0000
Subject: [PATCH 167/532] It's not necessary to reset the chip every time an
 input overflow event occurs. In addition, the delay when programming the
 short cable fix should be 100us, not 100ms.

PR:	kern/64556
Submitted by:	Thomas Hurst 
Approved by:	rrs (mentor)
MFC after:	1 week
---
 sys/dev/sis/if_sis.c | 15 +++------------
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/sys/dev/sis/if_sis.c b/sys/dev/sis/if_sis.c
index aac46f7bda0..19833423c82 100644
--- a/sys/dev/sis/if_sis.c
+++ b/sys/dev/sis/if_sis.c
@@ -1483,15 +1483,6 @@ sis_rxeof(struct sis_softc *sc)
 	return (rx_npkts);
 }
 
-static void
-sis_rxeoc(struct sis_softc *sc)
-{
-
-	SIS_LOCK_ASSERT(sc);
-	sis_rxeof(sc);
-	sis_initl(sc);
-}
-
 /*
  * A frame was downloaded to the chip. It's safe for us to clean up
  * the list buffers.
@@ -1614,7 +1605,7 @@ sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 		status = CSR_READ_4(sc, SIS_ISR);
 
 		if (status & (SIS_ISR_RX_ERR|SIS_ISR_RX_OFLOW))
-			sis_rxeoc(sc);
+			ifp->if_ierrors++;
 
 		if (status & (SIS_ISR_RX_IDLE))
 			SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
@@ -1672,7 +1663,7 @@ sis_intr(void *arg)
 			sis_rxeof(sc);
 
 		if (status & SIS_ISR_RX_OFLOW)
-			sis_rxeoc(sc);
+			ifp->if_ierrors++;
 
 		if (status & (SIS_ISR_RX_IDLE))
 			SIS_SETBIT(sc, SIS_CSR, SIS_CSR_RX_ENABLE);
@@ -2017,7 +2008,7 @@ sis_initl(struct sis_softc *sc)
 		CSR_WRITE_4(sc, NS_PHY_PAGE, 0x0001);
 		reg = CSR_READ_4(sc, NS_PHY_DSPCFG) & 0xfff;
 		CSR_WRITE_4(sc, NS_PHY_DSPCFG, reg | 0x1000);
-		DELAY(100000);
+		DELAY(100);
 		reg = CSR_READ_4(sc, NS_PHY_TDATA) & 0xff;
 		if ((reg & 0x0080) == 0 || (reg > 0xd8 && reg <= 0xff)) {
 			device_printf(sc->sis_dev,

From bd34cda61a6e3ac2aaa9a18f4853498a41e65018 Mon Sep 17 00:00:00 2001
From: Warner Losh 
Date: Tue, 20 Apr 2010 20:36:38 +0000
Subject: [PATCH 168/532] Bump minor version of config to reflect the new
 option remapping feature.  The kernel makefiles have specifically not been
 bumped because nothing uses this new feature and doing so forces everybody to
 recompile for no good reason.  This chnage will be MFC'd where the kernel
 version numbers for amd64 and ia64 will be bumped, since those are the only
 two that have use the option remapping feature.  Once merged, this will give
 a better error message to folks that are using buildkernel without buildworld
 or kernel-toolchain to update their kernels.

MFC after:	3 days
---
 usr.sbin/config/configvers.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/usr.sbin/config/configvers.h b/usr.sbin/config/configvers.h
index 28451585ec2..73310bd6f41 100644
--- a/usr.sbin/config/configvers.h
+++ b/usr.sbin/config/configvers.h
@@ -49,5 +49,5 @@
  *
  * $FreeBSD$
  */
-#define	CONFIGVERS	600007
+#define	CONFIGVERS	600008
 #define	MAJOR_VERS(x)	((x) / 100000)

From e8b93e425769587779f6ee962c61dc095ea8cdc0 Mon Sep 17 00:00:00 2001
From: Warner Losh 
Date: Tue, 20 Apr 2010 20:39:42 +0000
Subject: [PATCH 169/532] Make sure that we free the passed in data message if
 we don't actually insert it onto the queue.  Also, fix a mtx leak if someone
 turns off devctl while we're processing a messages.

MFC after:	5 days
---
 sys/kern/subr_bus.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 6e939c0ed77..9d3292aac45 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -545,15 +545,16 @@ devctl_queue_data(char *data)
 	struct proc *p;
 
 	if (strlen(data) == 0)
-		return;
+		goto out;
 	if (devctl_queue_length == 0)
-		return;
+		goto out;
 	n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
 	if (n1 == NULL)
-		return;
+		goto out;
 	n1->dei_data = data;
 	mtx_lock(&devsoftc.mtx);
 	if (devctl_queue_length == 0) {
+		mtx_unlock(&devsoftc.mtx);
 		free(n1->dei_data, M_BUS);
 		free(n1, M_BUS);
 		return;
@@ -577,6 +578,14 @@ devctl_queue_data(char *data)
 		psignal(p, SIGIO);
 		PROC_UNLOCK(p);
 	}
+	return;
+out:
+	/*
+	 * We have to free data on all error paths since the caller
+	 * assumes it will be free'd when this item is dequeued.
+	 */
+	free(data, M_BUS);
+	return;
 }
 
 /**

From 2669f95457b9136a7c9fa78e879cc53f68799078 Mon Sep 17 00:00:00 2001
From: Marius Strobl 
Date: Tue, 20 Apr 2010 20:47:58 +0000
Subject: [PATCH 170/532] Initial import of TestFloat 2a.

Obtained from:	http://www.jhauser.us/arithmetic/TestFloat.html
---
 processors/386-gcc.h                    |   80 +
 processors/SPARC-gcc.h                  |   80 +
 testfloat/386-Win32-gcc/Makefile        |   64 +
 testfloat/386-Win32-gcc/milieu.h        |   51 +
 testfloat/386-Win32-gcc/systflags.S     |   41 +
 testfloat/386-Win32-gcc/systfloat.S     |  332 ++
 testfloat/386-Win32-gcc/systfloat.h     |  181 ++
 testfloat/386-Win32-gcc/systmodes.S     |   82 +
 testfloat/README.txt                    |   50 +
 testfloat/SPARC-Solaris-gcc/Makefile    |   64 +
 testfloat/SPARC-Solaris-gcc/milieu.h    |   51 +
 testfloat/SPARC-Solaris-gcc/systflags.c |   42 +
 testfloat/SPARC-Solaris-gcc/systfloat.S |  941 ++++++
 testfloat/SPARC-Solaris-gcc/systfloat.h |  205 ++
 testfloat/SPARC-Solaris-gcc/systmodes.c |   51 +
 testfloat/fail.c                        |   46 +
 testfloat/fail.h                        |   29 +
 testfloat/random.c                      |   65 +
 testfloat/random.h                      |   32 +
 testfloat/slowfloat-32.c                | 1183 ++++++++
 testfloat/slowfloat-64.c                | 2109 +++++++++++++
 testfloat/slowfloat.c                   |   35 +
 testfloat/slowfloat.h                   |  167 +
 testfloat/systemBugs.txt                |  323 ++
 testfloat/systflags.h                   |   33 +
 testfloat/systfloat.c                   |  553 ++++
 testfloat/systfloat.h                   |  233 ++
 testfloat/systmodes.h                   |   42 +
 testfloat/templates/Makefile            |   67 +
 testfloat/templates/milieu.h            |   62 +
 testfloat/templates/systflags.c         |   41 +
 testfloat/templates/systmodes.c         |   58 +
 testfloat/testCases.c                   | 3679 +++++++++++++++++++++++
 testfloat/testCases.h                   |   69 +
 testfloat/testFunction.c                | 1149 +++++++
 testfloat/testFunction.h                |  135 +
 testfloat/testLoops.c                   | 2713 +++++++++++++++++
 testfloat/testLoops.h                   |  143 +
 testfloat/testfloat-history.txt         |   57 +
 testfloat/testfloat-source.txt          |  444 +++
 testfloat/testfloat.c                   |  295 ++
 testfloat/testfloat.txt                 |  771 +++++
 testfloat/testsoftfloat.c               | 1040 +++++++
 testfloat/writeHex.c                    |  183 ++
 testfloat/writeHex.h                    |   42 +
 45 files changed, 18113 insertions(+)
 create mode 100644 processors/386-gcc.h
 create mode 100644 processors/SPARC-gcc.h
 create mode 100644 testfloat/386-Win32-gcc/Makefile
 create mode 100644 testfloat/386-Win32-gcc/milieu.h
 create mode 100644 testfloat/386-Win32-gcc/systflags.S
 create mode 100644 testfloat/386-Win32-gcc/systfloat.S
 create mode 100644 testfloat/386-Win32-gcc/systfloat.h
 create mode 100644 testfloat/386-Win32-gcc/systmodes.S
 create mode 100644 testfloat/README.txt
 create mode 100644 testfloat/SPARC-Solaris-gcc/Makefile
 create mode 100644 testfloat/SPARC-Solaris-gcc/milieu.h
 create mode 100644 testfloat/SPARC-Solaris-gcc/systflags.c
 create mode 100644 testfloat/SPARC-Solaris-gcc/systfloat.S
 create mode 100644 testfloat/SPARC-Solaris-gcc/systfloat.h
 create mode 100644 testfloat/SPARC-Solaris-gcc/systmodes.c
 create mode 100644 testfloat/fail.c
 create mode 100644 testfloat/fail.h
 create mode 100644 testfloat/random.c
 create mode 100644 testfloat/random.h
 create mode 100644 testfloat/slowfloat-32.c
 create mode 100644 testfloat/slowfloat-64.c
 create mode 100644 testfloat/slowfloat.c
 create mode 100644 testfloat/slowfloat.h
 create mode 100644 testfloat/systemBugs.txt
 create mode 100644 testfloat/systflags.h
 create mode 100644 testfloat/systfloat.c
 create mode 100644 testfloat/systfloat.h
 create mode 100644 testfloat/systmodes.h
 create mode 100644 testfloat/templates/Makefile
 create mode 100644 testfloat/templates/milieu.h
 create mode 100644 testfloat/templates/systflags.c
 create mode 100644 testfloat/templates/systmodes.c
 create mode 100644 testfloat/testCases.c
 create mode 100644 testfloat/testCases.h
 create mode 100644 testfloat/testFunction.c
 create mode 100644 testfloat/testFunction.h
 create mode 100644 testfloat/testLoops.c
 create mode 100644 testfloat/testLoops.h
 create mode 100644 testfloat/testfloat-history.txt
 create mode 100644 testfloat/testfloat-source.txt
 create mode 100644 testfloat/testfloat.c
 create mode 100644 testfloat/testfloat.txt
 create mode 100644 testfloat/testsoftfloat.c
 create mode 100644 testfloat/writeHex.c
 create mode 100644 testfloat/writeHex.h

diff --git a/processors/386-gcc.h b/processors/386-gcc.h
new file mode 100644
index 00000000000..1fe8bb9ca03
--- /dev/null
+++ b/processors/386-gcc.h
@@ -0,0 +1,80 @@
+
+/*
+-------------------------------------------------------------------------------
+One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+-------------------------------------------------------------------------------
+*/
+#define LITTLEENDIAN
+
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified.  For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef char flag;
+typedef unsigned char uint8;
+typedef signed char int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified.  For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and
+if necessary ``marks'' the literal as having a 64-bit integer type.
+For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
+defined as the identity macro:  `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined.  If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE extern inline
+
diff --git a/processors/SPARC-gcc.h b/processors/SPARC-gcc.h
new file mode 100644
index 00000000000..f926615f99e
--- /dev/null
+++ b/processors/SPARC-gcc.h
@@ -0,0 +1,80 @@
+
+/*
+-------------------------------------------------------------------------------
+One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+-------------------------------------------------------------------------------
+*/
+#define BIGENDIAN
+
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified.  For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef int flag;
+typedef int uint8;
+typedef int int8;
+typedef int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified.  For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and
+if necessary ``marks'' the literal as having a 64-bit integer type.
+For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type.  Some compilers may allow `LIT64' to be
+defined as the identity macro:  `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined.  If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE extern inline
+
diff --git a/testfloat/386-Win32-gcc/Makefile b/testfloat/386-Win32-gcc/Makefile
new file mode 100644
index 00000000000..bba8b9e5b1e
--- /dev/null
+++ b/testfloat/386-Win32-gcc/Makefile
@@ -0,0 +1,64 @@
+
+PROCESSOR_H = ../../processors/386-gcc.h
+SOFTFLOAT_VERSION = bits64
+TARGET = 386-Win32-gcc
+SOFTFLOAT_DIR = ../../softfloat/$(SOFTFLOAT_VERSION)/$(TARGET)
+
+OBJ = .o
+EXE = .exe
+INCLUDES = -I. -I.. -I$(SOFTFLOAT_DIR)
+COMPILE_ASM = gcc -c -o $@
+COMPILE_C = gcc -c -o $@ $(INCLUDES) -I- -O2
+COMPILE_SLOWFLOAT_C = gcc -c -o $@ $(INCLUDES) -I- -O3
+LINK = gcc -o $@
+
+SOFTFLOAT_H = $(SOFTFLOAT_DIR)/softfloat.h
+SOFTFLOAT_OBJ = $(SOFTFLOAT_DIR)/softfloat$(OBJ)
+
+ALL: testsoftfloat$(EXE) testfloat$(EXE)
+
+milieu.h: $(PROCESSOR_H)
+	touch milieu.h
+
+fail$(OBJ): milieu.h ../fail.h
+	$(COMPILE_C) ../fail.c
+
+random$(OBJ): milieu.h ../random.h
+	$(COMPILE_C) ../random.c
+
+testCases$(OBJ): milieu.h ../fail.h ../random.h $(SOFTFLOAT_H) ../testCases.h ../testCases.c
+	$(COMPILE_C) ../testCases.c
+
+writeHex$(OBJ): milieu.h $(SOFTFLOAT_H) ../writeHex.h ../writeHex.c
+	$(COMPILE_C) ../writeHex.c
+
+testLoops$(OBJ): milieu.h $(SOFTFLOAT_H) ../testCases.h ../writeHex.h ../testLoops.h ../testLoops.c
+	$(COMPILE_C) ../testLoops.c
+
+slowfloat$(OBJ): milieu.h $(SOFTFLOAT_H) ../slowfloat.h ../slowfloat-32.c ../slowfloat-64.c ../slowfloat.c
+	$(COMPILE_SLOWFLOAT_C) ../slowfloat.c
+
+testsoftfloat$(OBJ): milieu.h ../fail.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../slowfloat.h ../testsoftfloat.c
+	$(COMPILE_C) ../testsoftfloat.c
+
+testsoftfloat$(EXE): fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) slowfloat$(OBJ) testsoftfloat$(OBJ)
+	$(LINK) fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) slowfloat$(OBJ) testsoftfloat$(OBJ)
+
+systmodes$(OBJ): systmodes.S
+	$(COMPILE_ASM) systmodes.S
+
+systflags$(OBJ): systflags.S
+	$(COMPILE_ASM) systflags.S
+
+systfloat$(OBJ): systfloat.S
+	$(COMPILE_ASM) systfloat.S
+
+testFunction$(OBJ): milieu.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../systmodes.h ../systflags.h systfloat.h ../testFunction.h ../testFunction.c
+	$(COMPILE_C) ../testFunction.c
+
+testfloat$(OBJ): milieu.h ../fail.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../systflags.h ../testFunction.h ../testfloat.c
+	$(COMPILE_C) ../testfloat.c
+
+testfloat$(EXE): fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) systmodes$(OBJ) systflags$(OBJ) systfloat$(OBJ) testFunction$(OBJ) testfloat$(OBJ)
+	$(LINK) fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) systmodes$(OBJ) systflags$(OBJ) systfloat$(OBJ) testFunction$(OBJ) testfloat$(OBJ)
+
diff --git a/testfloat/386-Win32-gcc/milieu.h b/testfloat/386-Win32-gcc/milieu.h
new file mode 100644
index 00000000000..7f795dd9396
--- /dev/null
+++ b/testfloat/386-Win32-gcc/milieu.h
@@ -0,0 +1,51 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "../../processors/386-gcc.h"
+
+/*
+-------------------------------------------------------------------------------
+If the `BITS64' macro is defined by the processor header file but the
+version of SoftFloat being tested is the 32-bit one (`bits32'), the `BITS64'
+macro must be undefined here.
+-------------------------------------------------------------------------------
+#undef BITS64
+*/
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+    FALSE = 0,
+    TRUE  = 1
+};
+
diff --git a/testfloat/386-Win32-gcc/systflags.S b/testfloat/386-Win32-gcc/systflags.S
new file mode 100644
index 00000000000..b338e54be82
--- /dev/null
+++ b/testfloat/386-Win32-gcc/systflags.S
@@ -0,0 +1,41 @@
+
+/*
+===============================================================================
+
+This GNU assembler source file is part of TestFloat, Release 2a, a package
+of programs for testing the correctness of floating-point arithmetic
+complying to the IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+	.text
+
+/*
+-------------------------------------------------------------------------------
+Clears the system's IEC/IEEE floating-point exception flags.  Returns the
+previous value of the flags.
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_float_flags_clear
+_syst_float_flags_clear:
+	fnstsw %ax
+	fnclex
+	andl $61,%eax
+	ret
+
diff --git a/testfloat/386-Win32-gcc/systfloat.S b/testfloat/386-Win32-gcc/systfloat.S
new file mode 100644
index 00000000000..01e8983e494
--- /dev/null
+++ b/testfloat/386-Win32-gcc/systfloat.S
@@ -0,0 +1,332 @@
+
+/*
+===============================================================================
+
+This GNU assembler source file is part of TestFloat, Release 2a, a package
+of programs for testing the correctness of floating-point arithmetic
+complying to the IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+	.text
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_int32_to_floatx80
+_syst_int32_to_floatx80:
+	fildl 8(%esp)
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_int64_to_floatx80
+_syst_int64_to_floatx80:
+	fildq 8(%esp)
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_float32_to_floatx80
+_syst_float32_to_floatx80:
+	flds 8(%esp)
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_float64_to_floatx80
+_syst_float64_to_floatx80:
+	fldl 8(%esp)
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_to_int32
+_syst_floatx80_to_int32:
+	fldt 4(%esp)
+	subl $4,%esp
+	fistpl (%esp)
+	movl (%esp),%eax
+	addl $4,%esp
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_to_int64
+_syst_floatx80_to_int64:
+	fldt 4(%esp)
+	subl $8,%esp
+	fistpq (%esp)
+	movl (%esp),%eax
+	movl 4(%esp),%edx
+	addl $8,%esp
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_to_float32
+_syst_floatx80_to_float32:
+	fldt 4(%esp)
+	subl $4,%esp
+	fstps (%esp)
+	movl (%esp),%eax
+	addl $4,%esp
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_to_float64
+_syst_floatx80_to_float64:
+	fldt 4(%esp)
+	subl $8,%esp
+	fstpl (%esp)
+	movl 4(%esp),%edx
+	movl (%esp),%eax
+	addl $8,%esp
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_round_to_int
+_syst_floatx80_round_to_int:
+	fldt 8(%esp)
+	frndint
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_add
+_syst_floatx80_add:
+	fldt 8(%esp)
+	fldt 20(%esp)
+	faddp
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_sub
+_syst_floatx80_sub:
+	fldt 8(%esp)
+	fldt 20(%esp)
+	fsubrp
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_mul
+_syst_floatx80_mul:
+	fldt 8(%esp)
+	fldt 20(%esp)
+	fmulp
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_div
+_syst_floatx80_div:
+	fldt 8(%esp)
+	fldt 20(%esp)
+	fdivrp
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_rem
+_syst_floatx80_rem:
+	fldt 20(%esp)
+	fldt 8(%esp)
+floatx80_rem_loop:
+	fprem1
+	fnstsw %ax
+	btw $10,%ax
+	jc floatx80_rem_loop
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	fstp %st(0)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_sqrt
+_syst_floatx80_sqrt:
+	fldt 8(%esp)
+	fsqrt
+	movl 4(%esp),%eax
+	fstpt (%eax)
+	ret $4
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_eq
+_syst_floatx80_eq:
+	fldt 16(%esp)
+	fldt 4(%esp)
+	fucompp
+	fnstsw %ax
+	andw $17664,%ax
+	cmpw $16384,%ax
+	seteb %al
+	movzb %al,%eax
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_le
+_syst_floatx80_le:
+	fldt 4(%esp)
+	fldt 16(%esp)
+	fcompp
+	fnstsw %ax
+	notl %eax
+	shrl $8,%eax
+	andl $1,%eax
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_lt
+_syst_floatx80_lt:
+	fldt 4(%esp)
+	fldt 16(%esp)
+	fcompp
+	fnstsw %ax
+	andw $17664,%ax
+	setzb %al
+	movzb %al,%eax
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_eq_signaling
+_syst_floatx80_eq_signaling:
+	fldt 16(%esp)
+	fldt 4(%esp)
+	fcompp
+	fnstsw %ax
+	andw $17664,%ax
+	cmpw $16384,%ax
+	seteb %al
+	movzb %al,%eax
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_le_quiet
+_syst_floatx80_le_quiet:
+	fldt 4(%esp)
+	fldt 16(%esp)
+	fucompp
+	fnstsw %ax
+	notl %eax
+	shrl $8,%eax
+	andl $1,%eax
+	ret
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 2
+.globl _syst_floatx80_lt_quiet
+_syst_floatx80_lt_quiet:
+	fldt 4(%esp)
+	fldt 16(%esp)
+	fucompp
+	fnstsw %ax
+	andw $17664,%ax
+	setzb %al
+	movzb %al,%eax
+	ret
+
diff --git a/testfloat/386-Win32-gcc/systfloat.h b/testfloat/386-Win32-gcc/systfloat.h
new file mode 100644
index 00000000000..167b9160203
--- /dev/null
+++ b/testfloat/386-Win32-gcc/systfloat.h
@@ -0,0 +1,181 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+The following macros are defined to indicate that the corresponding
+functions exist.
+-------------------------------------------------------------------------------
+*/
+#define SYST_INT32_TO_FLOATX80
+#define SYST_INT64_TO_FLOATX80
+#define SYST_FLOAT32_TO_FLOATX80
+#define SYST_FLOAT64_TO_FLOATX80
+#define SYST_FLOATX80_TO_INT32
+#define SYST_FLOATX80_TO_INT64
+#define SYST_FLOATX80_TO_FLOAT32
+#define SYST_FLOATX80_TO_FLOAT64
+#define SYST_FLOATX80_ROUND_TO_INT
+#define SYST_FLOATX80_ADD
+#define SYST_FLOATX80_SUB
+#define SYST_FLOATX80_MUL
+#define SYST_FLOATX80_DIV
+#define SYST_FLOATX80_REM
+#define SYST_FLOATX80_SQRT
+#define SYST_FLOATX80_EQ
+#define SYST_FLOATX80_LE
+#define SYST_FLOATX80_LT
+#define SYST_FLOATX80_EQ_SIGNALING
+#define SYST_FLOATX80_LE_QUIET
+#define SYST_FLOATX80_LT_QUIET
+
+/*
+-------------------------------------------------------------------------------
+System function declarations.  (Some of these functions may not exist.)
+-------------------------------------------------------------------------------
+*/
+float32 syst_int32_to_float32( int32 );
+float64 syst_int32_to_float64( int32 );
+#ifdef FLOATX80
+floatx80 syst_int32_to_floatx80( int32 );
+#endif
+#ifdef FLOAT128
+float128 syst_int32_to_float128( int32 );
+#endif
+#ifdef BITS64
+float32 syst_int64_to_float32( int64 );
+float64 syst_int64_to_float64( int64 );
+#ifdef FLOATX80
+floatx80 syst_int64_to_floatx80( int64 );
+#endif
+#ifdef FLOAT128
+float128 syst_int64_to_float128( int64 );
+#endif
+#endif
+int32 syst_float32_to_int32( float32 );
+int32 syst_float32_to_int32_round_to_zero( float32 );
+#ifdef BITS64
+int64 syst_float32_to_int64( float32 );
+int64 syst_float32_to_int64_round_to_zero( float32 );
+#endif
+float64 syst_float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 syst_float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 syst_float32_to_float128( float32 );
+#endif
+float32 syst_float32_round_to_int( float32 );
+float32 syst_float32_add( float32, float32 );
+float32 syst_float32_sub( float32, float32 );
+float32 syst_float32_mul( float32, float32 );
+float32 syst_float32_div( float32, float32 );
+float32 syst_float32_rem( float32, float32 );
+float32 syst_float32_sqrt( float32 );
+flag syst_float32_eq( float32, float32 );
+flag syst_float32_le( float32, float32 );
+flag syst_float32_lt( float32, float32 );
+flag syst_float32_eq_signaling( float32, float32 );
+flag syst_float32_le_quiet( float32, float32 );
+flag syst_float32_lt_quiet( float32, float32 );
+int32 syst_float64_to_int32( float64 );
+int32 syst_float64_to_int32_round_to_zero( float64 );
+#ifdef BITS64
+int64 syst_float64_to_int64( float64 );
+int64 syst_float64_to_int64_round_to_zero( float64 );
+#endif
+float32 syst_float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 syst_float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 syst_float64_to_float128( float64 );
+#endif
+float64 syst_float64_round_to_int( float64 );
+float64 syst_float64_add( float64, float64 );
+float64 syst_float64_sub( float64, float64 );
+float64 syst_float64_mul( float64, float64 );
+float64 syst_float64_div( float64, float64 );
+float64 syst_float64_rem( float64, float64 );
+float64 syst_float64_sqrt( float64 );
+flag syst_float64_eq( float64, float64 );
+flag syst_float64_le( float64, float64 );
+flag syst_float64_lt( float64, float64 );
+flag syst_float64_eq_signaling( float64, float64 );
+flag syst_float64_le_quiet( float64, float64 );
+flag syst_float64_lt_quiet( float64, float64 );
+#ifdef FLOATX80
+int32 syst_floatx80_to_int32( floatx80 );
+int32 syst_floatx80_to_int32_round_to_zero( floatx80 );
+#ifdef BITS64
+int64 syst_floatx80_to_int64( floatx80 );
+int64 syst_floatx80_to_int64_round_to_zero( floatx80 );
+#endif
+float32 syst_floatx80_to_float32( floatx80 );
+float64 syst_floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 syst_floatx80_to_float128( floatx80 );
+#endif
+floatx80 syst_floatx80_round_to_int( floatx80 );
+floatx80 syst_floatx80_add( floatx80, floatx80 );
+floatx80 syst_floatx80_sub( floatx80, floatx80 );
+floatx80 syst_floatx80_mul( floatx80, floatx80 );
+floatx80 syst_floatx80_div( floatx80, floatx80 );
+floatx80 syst_floatx80_rem( floatx80, floatx80 );
+floatx80 syst_floatx80_sqrt( floatx80 );
+flag syst_floatx80_eq( floatx80, floatx80 );
+flag syst_floatx80_le( floatx80, floatx80 );
+flag syst_floatx80_lt( floatx80, floatx80 );
+flag syst_floatx80_eq_signaling( floatx80, floatx80 );
+flag syst_floatx80_le_quiet( floatx80, floatx80 );
+flag syst_floatx80_lt_quiet( floatx80, floatx80 );
+#endif
+#ifdef FLOAT128
+int32 syst_float128_to_int32( float128 );
+int32 syst_float128_to_int32_round_to_zero( float128 );
+#ifdef BITS64
+int64 syst_float128_to_int64( float128 );
+int64 syst_float128_to_int64_round_to_zero( float128 );
+#endif
+float32 syst_float128_to_float32( float128 );
+float64 syst_float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 syst_float128_to_floatx80( float128 );
+#endif
+float128 syst_float128_round_to_int( float128 );
+float128 syst_float128_add( float128, float128 );
+float128 syst_float128_sub( float128, float128 );
+float128 syst_float128_mul( float128, float128 );
+float128 syst_float128_div( float128, float128 );
+float128 syst_float128_rem( float128, float128 );
+float128 syst_float128_sqrt( float128 );
+flag syst_float128_eq( float128, float128 );
+flag syst_float128_le( float128, float128 );
+flag syst_float128_lt( float128, float128 );
+flag syst_float128_eq_signaling( float128, float128 );
+flag syst_float128_le_quiet( float128, float128 );
+flag syst_float128_lt_quiet( float128, float128 );
+#endif
+
diff --git a/testfloat/386-Win32-gcc/systmodes.S b/testfloat/386-Win32-gcc/systmodes.S
new file mode 100644
index 00000000000..a8f3c8bc889
--- /dev/null
+++ b/testfloat/386-Win32-gcc/systmodes.S
@@ -0,0 +1,82 @@
+
+/*
+===============================================================================
+
+This GNU assembler source file is part of TestFloat, Release 2a, a package
+of programs for testing the correctness of floating-point arithmetic
+complying to the IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+	.text
+
+/*
+-------------------------------------------------------------------------------
+Sets the system's IEC/IEEE floating-point rounding mode.  Also disables all
+system exception traps.
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global _syst_float_set_rounding_mode
+_syst_float_set_rounding_mode:
+	movb 4(%esp),%al
+	andb $3,%al
+	shlw $10,%ax
+	orw $63,%ax
+	subl $2,%esp
+	fnstcw 0(%esp)
+	andw $768,0(%esp)
+	orw %ax,0(%esp)
+	fldcw 0(%esp)
+	addl $2,%esp
+	ret
+
+/*
+-------------------------------------------------------------------------------
+Sets the rounding precision of subsequent extended double-precision
+operations.  The `precision' argument should be one of 0, 32, 64, or 80.
+If `precision' is 32, the rounding precision is set equivalent to single
+precision; else if `precision' is 64, the rounding precision is set
+equivalent to double precision; else the rounding precision is set to full
+extended double precision.
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global _syst_float_set_rounding_precision
+_syst_float_set_rounding_precision:
+	movb 4(%esp),%al
+	movb $0,%ah
+	cmpb $32,%al
+	je setRoundingPrecision
+	movb $2,%ah
+	cmpb $64,%al
+	je setRoundingPrecision
+	movb $3,%ah
+	cmpb $80,%al
+	je setRoundingPrecision
+	movb $0,%ah
+setRoundingPrecision:
+	movb $0,%al
+	subl $2,%esp
+	fnstcw 0(%esp)
+	andw $64767,0(%esp)
+	orw %ax,0(%esp)
+	fldcw 0(%esp)
+	addl $2,%esp
+	ret
+
diff --git a/testfloat/README.txt b/testfloat/README.txt
new file mode 100644
index 00000000000..fe99fd95d64
--- /dev/null
+++ b/testfloat/README.txt
@@ -0,0 +1,50 @@
+
+Package Overview for TestFloat Release 2a
+
+John R. Hauser
+1998 December 16
+
+
+TestFloat is a program for testing that a floating-point implementation
+conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+TestFloat is distributed in the form of C source code.  The TestFloat
+package actually provides two related programs:
+
+-- The `testfloat' program tests a system's floating-point for conformance
+   to the IEC/IEEE Standard.  This program uses the SoftFloat software
+   floating-point implementation as a basis for comparison.
+
+-- The `testsoftfloat' program tests SoftFloat itself for conformance to
+   the IEC/IEEE Standard.  These tests are performed by comparing against a
+   separate, slower software floating-point that is included in the TestFloat
+   package.
+
+TestFloat depends on SoftFloat, but SoftFloat is not included in the
+TestFloat package.  SoftFloat can be obtained through the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
+
+TestFloat is documented in three text files:
+
+   testfloat.txt          Documentation for using the TestFloat programs
+                              (both `testfloat' and `testsoftfloat').
+   testfloat-source.txt   Documentation for porting and compiling TestFloat.
+   testfloat-history.txt  History of major changes to TestFloat.
+
+The following file is also provided:
+
+   systemBugs.txt         Information about processor bugs found using
+                              TestFloat.
+
+Other files in the package comprise the source code for TestFloat.
+
+Please be aware that some work is involved in porting this software to other
+targets.  It is not just a matter of getting `make' to complete without
+error messages.  I would have written the code that way if I could, but
+there are fundamental differences between systems that I can't make go away.
+You should not attempt to compile the TestFloat sources without first
+reading `testfloat-source.txt'.
+
+At the time of this writing, the most up-to-date information about
+TestFloat and the latest release can be found at the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
diff --git a/testfloat/SPARC-Solaris-gcc/Makefile b/testfloat/SPARC-Solaris-gcc/Makefile
new file mode 100644
index 00000000000..ee53aa19d33
--- /dev/null
+++ b/testfloat/SPARC-Solaris-gcc/Makefile
@@ -0,0 +1,64 @@
+
+PROCESSOR_H = ../../processors/SPARC-gcc.h
+SOFTFLOAT_VERSION = bits64
+TARGET = SPARC-Solaris-gcc
+SOFTFLOAT_DIR = ../../softfloat/$(SOFTFLOAT_VERSION)/$(TARGET)
+
+OBJ = .o
+EXE =
+INCLUDES = -I. -I.. -I$(SOFTFLOAT_DIR)
+COMPILE_ASM = gcc -c -o $@
+COMPILE_C = gcc -c -o $@ $(INCLUDES) -I- -O2
+COMPILE_SLOWFLOAT_C = gcc -c -o $@ $(INCLUDES) -I- -O3
+LINK = gcc -o $@
+
+SOFTFLOAT_H = $(SOFTFLOAT_DIR)/softfloat.h
+SOFTFLOAT_OBJ = $(SOFTFLOAT_DIR)/softfloat$(OBJ)
+
+ALL: testsoftfloat$(EXE) testfloat$(EXE)
+
+milieu.h: $(PROCESSOR_H)
+	touch milieu.h
+
+fail$(OBJ): milieu.h ../fail.h
+	$(COMPILE_C) ../fail.c
+
+random$(OBJ): milieu.h ../random.h
+	$(COMPILE_C) ../random.c
+
+testCases$(OBJ): milieu.h ../fail.h ../random.h $(SOFTFLOAT_H) ../testCases.h ../testCases.c
+	$(COMPILE_C) ../testCases.c
+
+writeHex$(OBJ): milieu.h $(SOFTFLOAT_H) ../writeHex.h ../writeHex.c
+	$(COMPILE_C) ../writeHex.c
+
+testLoops$(OBJ): milieu.h $(SOFTFLOAT_H) ../testCases.h ../writeHex.h ../testLoops.h ../testLoops.c
+	$(COMPILE_C) ../testLoops.c
+
+slowfloat$(OBJ): milieu.h $(SOFTFLOAT_H) ../slowfloat.h ../slowfloat-32.c ../slowfloat-64.c ../slowfloat.c
+	$(COMPILE_SLOWFLOAT_C) ../slowfloat.c
+
+testsoftfloat$(OBJ): milieu.h ../fail.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../slowfloat.h ../testsoftfloat.c
+	$(COMPILE_C) ../testsoftfloat.c
+
+testsoftfloat$(EXE): fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) slowfloat$(OBJ) testsoftfloat$(OBJ)
+	$(LINK) fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) slowfloat$(OBJ) testsoftfloat$(OBJ)
+
+systmodes$(OBJ): milieu.h ../systmodes.h systmodes.c
+	$(COMPILE_C) systmodes.c
+
+systflags$(OBJ): milieu.h ../systflags.h systflags.c
+	$(COMPILE_C) systflags.c
+
+systfloat$(OBJ): systfloat.S
+	$(COMPILE_ASM) systfloat.S
+
+testFunction$(OBJ): milieu.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../systmodes.h ../systflags.h systfloat.h ../testFunction.h ../testFunction.c
+	$(COMPILE_C) ../testFunction.c
+
+testfloat$(OBJ): milieu.h ../fail.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../systflags.h ../testFunction.h ../testfloat.c
+	$(COMPILE_C) ../testfloat.c
+
+testfloat$(EXE): fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) systmodes$(OBJ) systflags$(OBJ) systfloat$(OBJ) testFunction$(OBJ) testfloat$(OBJ)
+	$(LINK) fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) systmodes$(OBJ) systflags$(OBJ) systfloat$(OBJ) testFunction$(OBJ) testfloat$(OBJ)
+
diff --git a/testfloat/SPARC-Solaris-gcc/milieu.h b/testfloat/SPARC-Solaris-gcc/milieu.h
new file mode 100644
index 00000000000..4aa7b13f0ea
--- /dev/null
+++ b/testfloat/SPARC-Solaris-gcc/milieu.h
@@ -0,0 +1,51 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "../../processors/SPARC-gcc.h"
+
+/*
+-------------------------------------------------------------------------------
+If the `BITS64' macro is defined by the processor header file but the
+version of SoftFloat being used/tested is the 32-bit one (`bits32'), the
+`BITS64' macro must be undefined here.
+-------------------------------------------------------------------------------
+#undef BITS64
+*/
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+    FALSE = 0,
+    TRUE  = 1
+};
+
diff --git a/testfloat/SPARC-Solaris-gcc/systflags.c b/testfloat/SPARC-Solaris-gcc/systflags.c
new file mode 100644
index 00000000000..d0e29a1a4b2
--- /dev/null
+++ b/testfloat/SPARC-Solaris-gcc/systflags.c
@@ -0,0 +1,42 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include "milieu.h"
+#include "systflags.h"
+
+/*
+-------------------------------------------------------------------------------
+Clears the system's IEC/IEEE floating-point exception flags.  Returns the
+previous value of the flags.
+-------------------------------------------------------------------------------
+*/
+int8 syst_float_flags_clear( void )
+{
+
+    return fpsetsticky( 0 );
+
+}
+
diff --git a/testfloat/SPARC-Solaris-gcc/systfloat.S b/testfloat/SPARC-Solaris-gcc/systfloat.S
new file mode 100644
index 00000000000..1c0264d5bf6
--- /dev/null
+++ b/testfloat/SPARC-Solaris-gcc/systfloat.S
@@ -0,0 +1,941 @@
+
+/*
+===============================================================================
+
+This GNU assembler source file is part of TestFloat, Release 2a, a package
+of programs for testing the correctness of floating-point arithmetic
+complying to the IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+	.text
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_int32_to_float32
+syst_int32_to_float32:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fitos %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_int32_to_float64
+syst_int32_to_float64:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fitod %f0,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_int32_to_float128
+syst_int32_to_float128:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fitoq %f0,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_to_int32_round_to_zero
+syst_float32_to_int32_round_to_zero:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fstoi %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_to_float64
+syst_float32_to_float64:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fstod %f0,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_to_float128
+syst_float32_to_float128:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fstoq %f0,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_add
+syst_float32_add:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fadds %f0,%f1,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_sub
+syst_float32_sub:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fsubs %f0,%f1,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_mul
+syst_float32_mul:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fmuls %f0,%f1,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_div
+syst_float32_div:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fdivs %f0,%f1,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_sqrt
+syst_float32_sqrt:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	ld [%sp+96],%f0
+	fsqrts %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_eq
+syst_float32_eq:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fcmps %f0,%f1
+	mov 0,%i0
+	fbe,a float32EqExit
+	mov 1,%i0
+float32EqExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_le
+syst_float32_le:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fcmpes %f0,%f1
+	mov 0,%i0
+	fble,a float32LeExit
+	mov 1,%i0
+float32LeExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_lt
+syst_float32_lt:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fcmpes %f0,%f1
+	mov 0,%i0
+	fbl,a float32LtExit
+	mov 1,%i0
+float32LtExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_eq_signaling
+syst_float32_eq_signaling:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fcmpes %f0,%f1
+	mov 0,%i0
+	fbe,a float32EqSignalingExit
+	mov 1,%i0
+float32EqSignalingExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_le_quiet
+syst_float32_le_quiet:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fcmps %f0,%f1
+	mov 0,%i0
+	fble,a float32LeQuietExit
+	mov 1,%i0
+float32LeQuietExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float32_lt_quiet
+syst_float32_lt_quiet:
+	save %sp,-128,%sp
+
+	st %i0,[%sp+96]
+	st %i1,[%sp+100]
+	ld [%sp+96],%f0
+	ld [%sp+100],%f1
+	fcmps %f0,%f1
+	mov 0,%i0
+	fbl,a float32LtQuietExit
+	mov 1,%i0
+float32LtQuietExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_to_int32_round_to_zero
+syst_float64_to_int32_round_to_zero:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	ldd [%sp+96],%f0
+	fdtoi %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_to_float32
+syst_float64_to_float32:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	ldd [%sp+96],%f0
+	fdtos %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_to_float128
+syst_float64_to_float128:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	ldd [%sp+96],%f0
+	fdtoq %f0,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_add
+syst_float64_add:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	faddd %f0,%f2,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_sub
+syst_float64_sub:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fsubd %f0,%f2,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_mul
+syst_float64_mul:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fmuld %f0,%f2,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_div
+syst_float64_div:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fdivd %f0,%f2,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_sqrt
+syst_float64_sqrt:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	ldd [%sp+96],%f0
+	fsqrtd %f0,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_eq
+syst_float64_eq:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fcmpd %f0,%f2
+	mov 0,%i0
+	fbe,a float64EqExit
+	mov 1,%i0
+float64EqExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_le
+syst_float64_le:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fcmped %f0,%f2
+	mov 0,%i0
+	fble,a float64LeExit
+	mov 1,%i0
+float64LeExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_lt
+syst_float64_lt:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fcmped %f0,%f2
+	mov 0,%i0
+	fbl,a float64LtExit
+	mov 1,%i0
+float64LtExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_eq_signaling
+syst_float64_eq_signaling:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fcmped %f0,%f2
+	mov 0,%i0
+	fbe,a float64EqSignalingExit
+	mov 1,%i0
+float64EqSignalingExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_le_quiet
+syst_float64_le_quiet:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fcmpd %f0,%f2
+	mov 0,%i0
+	fble,a float64LeQuietExit
+	mov 1,%i0
+float64LeQuietExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float64_lt_quiet
+syst_float64_lt_quiet:
+	save %sp,-128,%sp
+
+	std %i0,[%sp+96]
+	std %i2,[%sp+104]
+	ldd [%sp+96],%f0
+	ldd [%sp+104],%f2
+	fcmpd %f0,%f2
+	mov 0,%i0
+	fbl,a float64LtQuietExit
+	mov 1,%i0
+float64LtQuietExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_to_int32_round_to_zero
+syst_float128_to_int32_round_to_zero:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	fqtoi %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_to_float32
+syst_float128_to_float32:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	fqtos %f0,%f0
+	st %f0,[%sp+96]
+	ld [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_to_float64
+syst_float128_to_float64:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	fqtod %f0,%f0
+	std %f0,[%sp+96]
+	ldd [%sp+96],%i0
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_add
+syst_float128_add:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	faddq %f0,%f4,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_sub
+syst_float128_sub:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fsubq %f0,%f4,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_mul
+syst_float128_mul:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fmulq %f0,%f4,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_div
+syst_float128_div:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fdivq %f0,%f4,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_sqrt
+syst_float128_sqrt:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	fsqrtq %f0,%f0
+	ld [%sp+192],%o0
+	std %f0,[%o0]
+	std %f2,[%o0+8]
+
+	jmp %i7+12
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_eq
+syst_float128_eq:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fcmpq %f0,%f4
+	mov 0,%i0
+	fbe,a float128EqExit
+	mov 1,%i0
+float128EqExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_le
+syst_float128_le:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fcmpeq %f0,%f4
+	mov 0,%i0
+	fble,a float128Le
+	mov 1,%i0
+float128Le:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_lt
+syst_float128_lt:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fcmpeq %f0,%f4
+	mov 0,%i0
+	fbl,a float128Lt
+	mov 1,%i0
+float128Lt:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_eq_signaling
+syst_float128_eq_signaling:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fcmpeq %f0,%f4
+	mov 0,%i0
+	fbe,a float128EqSignalingExit
+	mov 1,%i0
+float128EqSignalingExit:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_le_quiet
+syst_float128_le_quiet:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fcmpq %f0,%f4
+	mov 0,%i0
+	fble,a float128LeQuiet
+	mov 1,%i0
+float128LeQuiet:
+
+	ret
+	restore
+
+/*
+-------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
+*/
+	.align 4
+	.global syst_float128_lt_quiet
+syst_float128_lt_quiet:
+	save %sp,-128,%sp
+
+	ldd [%i0],%f0
+	ldd [%i0+8],%f2
+	ldd [%i1],%f4
+	ldd [%i1+8],%f6
+	fcmpq %f0,%f4
+	mov 0,%i0
+	fbl,a float128LtQuiet
+	mov 1,%i0
+float128LtQuiet:
+
+	ret
+	restore
+
diff --git a/testfloat/SPARC-Solaris-gcc/systfloat.h b/testfloat/SPARC-Solaris-gcc/systfloat.h
new file mode 100644
index 00000000000..956e470f4fb
--- /dev/null
+++ b/testfloat/SPARC-Solaris-gcc/systfloat.h
@@ -0,0 +1,205 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+The following macros are defined to indicate that the corresponding
+functions exist.
+-------------------------------------------------------------------------------
+*/
+#define SYST_INT32_TO_FLOAT32
+#define SYST_INT32_TO_FLOAT64
+#define SYST_INT32_TO_FLOAT128
+#define SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+#define SYST_FLOAT32_TO_FLOAT64
+#define SYST_FLOAT32_TO_FLOAT128
+#define SYST_FLOAT32_ADD
+#define SYST_FLOAT32_SUB
+#define SYST_FLOAT32_MUL
+#define SYST_FLOAT32_DIV
+#define SYST_FLOAT32_SQRT
+#define SYST_FLOAT32_EQ
+#define SYST_FLOAT32_LE
+#define SYST_FLOAT32_LT
+#define SYST_FLOAT32_EQ_SIGNALING
+#define SYST_FLOAT32_LE_QUIET
+#define SYST_FLOAT32_LT_QUIET
+#define SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+#define SYST_FLOAT64_TO_FLOAT32
+#define SYST_FLOAT64_TO_FLOAT128
+#define SYST_FLOAT64_ADD
+#define SYST_FLOAT64_SUB
+#define SYST_FLOAT64_MUL
+#define SYST_FLOAT64_DIV
+#define SYST_FLOAT64_SQRT
+#define SYST_FLOAT64_EQ
+#define SYST_FLOAT64_LE
+#define SYST_FLOAT64_LT
+#define SYST_FLOAT64_EQ_SIGNALING
+#define SYST_FLOAT64_LE_QUIET
+#define SYST_FLOAT64_LT_QUIET
+#define SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+#define SYST_FLOAT128_TO_FLOAT32
+#define SYST_FLOAT128_TO_FLOAT64
+#define SYST_FLOAT128_ADD
+#define SYST_FLOAT128_SUB
+#define SYST_FLOAT128_MUL
+#define SYST_FLOAT128_DIV
+#define SYST_FLOAT128_SQRT
+#define SYST_FLOAT128_EQ
+#define SYST_FLOAT128_LE
+#define SYST_FLOAT128_LT
+#define SYST_FLOAT128_EQ_SIGNALING
+#define SYST_FLOAT128_LE_QUIET
+#define SYST_FLOAT128_LT_QUIET
+
+/*
+-------------------------------------------------------------------------------
+System function declarations.  (Some of these functions may not exist.)
+-------------------------------------------------------------------------------
+*/
+float32 syst_int32_to_float32( int32 );
+float64 syst_int32_to_float64( int32 );
+#ifdef FLOATX80
+floatx80 syst_int32_to_floatx80( int32 );
+#endif
+#ifdef FLOAT128
+float128 syst_int32_to_float128( int32 );
+#endif
+#ifdef BITS64
+float32 syst_int64_to_float32( int64 );
+float64 syst_int64_to_float64( int64 );
+#ifdef FLOATX80
+floatx80 syst_int64_to_floatx80( int64 );
+#endif
+#ifdef FLOAT128
+float128 syst_int64_to_float128( int64 );
+#endif
+#endif
+int32 syst_float32_to_int32( float32 );
+int32 syst_float32_to_int32_round_to_zero( float32 );
+#ifdef BITS64
+int64 syst_float32_to_int64( float32 );
+int64 syst_float32_to_int64_round_to_zero( float32 );
+#endif
+float64 syst_float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 syst_float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 syst_float32_to_float128( float32 );
+#endif
+float32 syst_float32_round_to_int( float32 );
+float32 syst_float32_add( float32, float32 );
+float32 syst_float32_sub( float32, float32 );
+float32 syst_float32_mul( float32, float32 );
+float32 syst_float32_div( float32, float32 );
+float32 syst_float32_rem( float32, float32 );
+float32 syst_float32_sqrt( float32 );
+flag syst_float32_eq( float32, float32 );
+flag syst_float32_le( float32, float32 );
+flag syst_float32_lt( float32, float32 );
+flag syst_float32_eq_signaling( float32, float32 );
+flag syst_float32_le_quiet( float32, float32 );
+flag syst_float32_lt_quiet( float32, float32 );
+int32 syst_float64_to_int32( float64 );
+int32 syst_float64_to_int32_round_to_zero( float64 );
+#ifdef BITS64
+int64 syst_float64_to_int64( float64 );
+int64 syst_float64_to_int64_round_to_zero( float64 );
+#endif
+float32 syst_float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 syst_float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 syst_float64_to_float128( float64 );
+#endif
+float64 syst_float64_round_to_int( float64 );
+float64 syst_float64_add( float64, float64 );
+float64 syst_float64_sub( float64, float64 );
+float64 syst_float64_mul( float64, float64 );
+float64 syst_float64_div( float64, float64 );
+float64 syst_float64_rem( float64, float64 );
+float64 syst_float64_sqrt( float64 );
+flag syst_float64_eq( float64, float64 );
+flag syst_float64_le( float64, float64 );
+flag syst_float64_lt( float64, float64 );
+flag syst_float64_eq_signaling( float64, float64 );
+flag syst_float64_le_quiet( float64, float64 );
+flag syst_float64_lt_quiet( float64, float64 );
+#ifdef FLOATX80
+int32 syst_floatx80_to_int32( floatx80 );
+int32 syst_floatx80_to_int32_round_to_zero( floatx80 );
+#ifdef BITS64
+int64 syst_floatx80_to_int64( floatx80 );
+int64 syst_floatx80_to_int64_round_to_zero( floatx80 );
+#endif
+float32 syst_floatx80_to_float32( floatx80 );
+float64 syst_floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 syst_floatx80_to_float128( floatx80 );
+#endif
+floatx80 syst_floatx80_round_to_int( floatx80 );
+floatx80 syst_floatx80_add( floatx80, floatx80 );
+floatx80 syst_floatx80_sub( floatx80, floatx80 );
+floatx80 syst_floatx80_mul( floatx80, floatx80 );
+floatx80 syst_floatx80_div( floatx80, floatx80 );
+floatx80 syst_floatx80_rem( floatx80, floatx80 );
+floatx80 syst_floatx80_sqrt( floatx80 );
+flag syst_floatx80_eq( floatx80, floatx80 );
+flag syst_floatx80_le( floatx80, floatx80 );
+flag syst_floatx80_lt( floatx80, floatx80 );
+flag syst_floatx80_eq_signaling( floatx80, floatx80 );
+flag syst_floatx80_le_quiet( floatx80, floatx80 );
+flag syst_floatx80_lt_quiet( floatx80, floatx80 );
+#endif
+#ifdef FLOAT128
+int32 syst_float128_to_int32( float128 );
+int32 syst_float128_to_int32_round_to_zero( float128 );
+#ifdef BITS64
+int64 syst_float128_to_int64( float128 );
+int64 syst_float128_to_int64_round_to_zero( float128 );
+#endif
+float32 syst_float128_to_float32( float128 );
+float64 syst_float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 syst_float128_to_floatx80( float128 );
+#endif
+float128 syst_float128_round_to_int( float128 );
+float128 syst_float128_add( float128, float128 );
+float128 syst_float128_sub( float128, float128 );
+float128 syst_float128_mul( float128, float128 );
+float128 syst_float128_div( float128, float128 );
+float128 syst_float128_rem( float128, float128 );
+float128 syst_float128_sqrt( float128 );
+flag syst_float128_eq( float128, float128 );
+flag syst_float128_le( float128, float128 );
+flag syst_float128_lt( float128, float128 );
+flag syst_float128_eq_signaling( float128, float128 );
+flag syst_float128_le_quiet( float128, float128 );
+flag syst_float128_lt_quiet( float128, float128 );
+#endif
+
diff --git a/testfloat/SPARC-Solaris-gcc/systmodes.c b/testfloat/SPARC-Solaris-gcc/systmodes.c
new file mode 100644
index 00000000000..3981cd79a6a
--- /dev/null
+++ b/testfloat/SPARC-Solaris-gcc/systmodes.c
@@ -0,0 +1,51 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include "milieu.h"
+#include "systmodes.h"
+
+/*
+-------------------------------------------------------------------------------
+Sets the system's IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_mode( int8 roundingMode )
+{
+
+    (void) fpsetround( roundingMode );
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Does nothing.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_precision( int8 precision )
+{
+
+}
+
diff --git a/testfloat/fail.c b/testfloat/fail.c
new file mode 100644
index 00000000000..30bbea6bd7d
--- /dev/null
+++ b/testfloat/fail.c
@@ -0,0 +1,46 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include 
+#include 
+#include "milieu.h"
+#include "fail.h"
+
+char *fail_programName = "";
+
+void fail( const char *message, ... )
+{
+    va_list varArgs;
+
+    fprintf( stderr, "%s: ", fail_programName );
+    va_start( varArgs, message );
+    vfprintf( stderr, message, varArgs );
+    va_end( varArgs );
+    fputs( ".\n", stderr );
+    exit( EXIT_FAILURE );
+
+}
+
diff --git a/testfloat/fail.h b/testfloat/fail.h
new file mode 100644
index 00000000000..9c338da260a
--- /dev/null
+++ b/testfloat/fail.h
@@ -0,0 +1,29 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+extern char *fail_programName;
+
+void fail( const char *, ... );
+
diff --git a/testfloat/random.c b/testfloat/random.c
new file mode 100644
index 00000000000..53453665760
--- /dev/null
+++ b/testfloat/random.c
@@ -0,0 +1,65 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include "milieu.h"
+#include "random.h"
+
+uint8 randomUint8( void )
+{
+
+    return (bits8) ( rand()>>4 );
+
+}
+
+uint16 randomUint16( void )
+{
+
+    return ( ( rand() & 0x0FF0 )<<4 ) | ( ( rand()>>4 ) & 0xFF );
+
+}
+
+uint32 randomUint32( void )
+{
+
+    return
+          ( ( (uint32) ( rand() & 0x0FF0 ) )<<20 )
+        | ( ( (uint32) ( rand() & 0x0FF0 ) )<<12 )
+        | ( ( rand() & 0x0FF0 )<<4 )
+        | ( ( rand()>>4 ) & 0xFF );
+
+}
+
+#ifdef BITS64
+
+uint64 randomUint64( void )
+{
+
+    return ( ( (uint64) randomUint32() )<<32 ) | randomUint32();
+
+}
+
+#endif
+
diff --git a/testfloat/random.h b/testfloat/random.h
new file mode 100644
index 00000000000..7375499ea96
--- /dev/null
+++ b/testfloat/random.h
@@ -0,0 +1,32 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+uint8 randomUint8( void );
+uint16 randomUint16( void );
+uint32 randomUint32( void );
+#ifdef BITS64
+uint64 randomUint64( void );
+#endif
+
diff --git a/testfloat/slowfloat-32.c b/testfloat/slowfloat-32.c
new file mode 100644
index 00000000000..549654b05e6
--- /dev/null
+++ b/testfloat/slowfloat-32.c
@@ -0,0 +1,1183 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+int8 slow_float_rounding_mode;
+int8 slow_float_exception_flags;
+int8 slow_float_detect_tininess;
+
+typedef struct {
+    bits32 a0, a1;
+} bits64X;
+
+typedef struct {
+    flag isNaN;
+    flag isInf;
+    flag isZero;
+    flag sign;
+    int16 exp;
+    bits64X sig;
+} floatX;
+
+static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
+static const floatX floatXPositiveZero =
+    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
+static const floatX floatXNegativeZero =
+    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
+
+static bits64X shortShift64Left( bits64X a, int8 shiftCount )
+{
+    int8 negShiftCount;
+
+    negShiftCount = ( - shiftCount & 31 );
+    a.a0 = ( a.a0<>negShiftCount );
+    a.a1 <<= shiftCount;
+    return a;
+
+}
+
+static bits64X shortShift64RightJamming( bits64X a, int8 shiftCount )
+{
+    int8 negShiftCount;
+    bits32 extra;
+
+    negShiftCount = ( - shiftCount & 31 );
+    extra = a.a1<>shiftCount ) | ( extra != 0 );
+    a.a0 >>= shiftCount;
+    return a;
+
+}
+
+static bits64X neg64( bits64X a )
+{
+
+    if ( a.a1 == 0 ) {
+        a.a0 = - a.a0;
+    }
+    else {
+        a.a1 = - a.a1;
+        a.a0 = ~ a.a0;
+    }
+    return a;
+
+}
+
+static bits64X add64( bits64X a, bits64X b )
+{
+
+    a.a1 += b.a1;
+    a.a0 += b.a0 + ( a.a1 < b.a1 );
+    return a;
+
+}
+
+static flag eq64( bits64X a, bits64X b )
+{
+
+    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
+
+}
+
+static flag le64( bits64X a, bits64X b )
+{
+
+    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
+
+}
+
+static flag lt64( bits64X a, bits64X b )
+{
+
+    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
+
+}
+
+static floatX roundFloatXTo24( flag isTiny, floatX zx )
+{
+
+    if ( zx.sig.a1 ) {
+        slow_float_exception_flags |= float_flag_inexact;
+        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+        switch ( slow_float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( zx.sig.a1 < 0x80000000 ) goto noIncrement;
+            if ( ( zx.sig.a1 == 0x80000000 ) && ! ( zx.sig.a0 & 1 ) ) {
+                goto noIncrement;
+            }
+            break;
+         case float_round_to_zero:
+            goto noIncrement;
+         case float_round_down:
+            if ( ! zx.sign ) goto noIncrement;
+            break;
+         case float_round_up:
+            if ( zx.sign ) goto noIncrement;
+            break;
+        }
+        ++zx.sig.a0;
+        if ( zx.sig.a0 == 0x01000000 ) {
+            zx.sig.a0 = 0x00800000;
+            ++zx.exp;
+        }
+    }
+ noIncrement:
+    zx.sig.a1 = 0;
+    return zx;
+
+}
+
+static floatX roundFloatXTo53( flag isTiny, floatX zx )
+{
+    int8 roundBits;
+
+    roundBits = zx.sig.a1 & 7;
+    zx.sig.a1 -= roundBits;
+    if ( roundBits ) {
+        slow_float_exception_flags |= float_flag_inexact;
+        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+        switch ( slow_float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( roundBits < 4 ) goto noIncrement;
+            if ( ( roundBits == 4 ) && ! ( zx.sig.a1 & 8 ) ) goto noIncrement;
+            break;
+         case float_round_to_zero:
+            goto noIncrement;
+         case float_round_down:
+            if ( ! zx.sign ) goto noIncrement;
+            break;
+         case float_round_up:
+            if ( zx.sign ) goto noIncrement;
+            break;
+        }
+        zx.sig.a1 += 8;
+        zx.sig.a0 += ( zx.sig.a1 == 0 );
+        if ( zx.sig.a0 == 0x01000000 ) {
+            zx.sig.a0 = 0x00800000;
+            ++zx.exp;
+        }
+    }
+ noIncrement:
+    return zx;
+
+}
+
+static floatX int32ToFloatX( int32 a )
+{
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.sign = ( a < 0 );
+    ax.sig.a1 = ax.sign ? - a : a;
+    ax.sig.a0 = 0;
+    if ( a == 0 ) {
+        ax.isZero = TRUE;
+        return ax;
+    }
+    ax.isZero = FALSE;
+    ax.sig = shortShift64Left( ax.sig, 23 );
+    ax.exp = 32;
+    while ( ax.sig.a0 < 0x00800000 ) {
+        ax.sig = shortShift64Left( ax.sig, 1 );
+        --ax.exp;
+    }
+    return ax;
+
+}
+
+static int32 floatXToInt32( floatX ax )
+{
+    int8 savedExceptionFlags;
+    int16 shiftCount;
+    int32 z;
+
+    if ( ax.isInf || ax.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+        return ( ax.isInf & ax.sign ) ? 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( ax.isZero ) return 0;
+    savedExceptionFlags = slow_float_exception_flags;
+    shiftCount = 52 - ax.exp;
+    if ( 56 < shiftCount ) {
+        ax.sig.a1 = 1;
+        ax.sig.a0 = 0;
+    }
+    else {
+        while ( 0 < shiftCount ) {
+            ax.sig = shortShift64RightJamming( ax.sig, 1 );
+            --shiftCount;
+        }
+    }
+    ax = roundFloatXTo53( FALSE, ax );
+    ax.sig = shortShift64RightJamming( ax.sig, 3 );
+    z = ax.sig.a1;
+    if ( ax.sign ) z = - z;
+    if (    ( shiftCount < 0 )
+         || ax.sig.a0
+         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
+       ) {
+        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
+        return ax.sign ? 0x80000000 : 0x7FFFFFFF;
+    }
+    return z;
+
+}
+
+static floatX float32ToFloatX( float32 a )
+{
+    int16 expField;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.isZero = FALSE;
+    ax.sign = ( ( a & 0x80000000 ) != 0 );
+    expField = ( a>>23 ) & 0xFF;
+    ax.sig.a1 = 0;
+    ax.sig.a0 = a & 0x007FFFFF;
+    if ( expField == 0 ) {
+        if ( ax.sig.a0 == 0 ) {
+            ax.isZero = TRUE;
+        }
+        else {
+            expField = 1 - 0x7F;
+            do {
+                ax.sig.a0 <<= 1;
+                --expField;
+            } while ( ax.sig.a0 < 0x00800000 );
+            ax.exp = expField;
+        }
+    }
+    else if ( expField == 0xFF ) {
+        if ( ax.sig.a0 == 0 ) {
+            ax.isInf = TRUE;
+        }
+        else {
+            ax.isNaN = TRUE;
+        }
+    }
+    else {
+        ax.sig.a0 |= 0x00800000;
+        ax.exp = expField - 0x7F;
+    }
+    return ax;
+
+}
+
+static float32 floatXToFloat32( floatX zx )
+{
+    floatX savedZ;
+    flag isTiny;
+    int16 expField;
+    float32 z;
+
+    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
+    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
+    if ( zx.isNaN ) return 0xFFFFFFFF;
+    while ( 0x01000000 <= zx.sig.a0 ) {
+        zx.sig = shortShift64RightJamming( zx.sig, 1 );
+        ++zx.exp;
+    }
+    while ( zx.sig.a0 < 0x00800000 ) {
+        zx.sig = shortShift64Left( zx.sig, 1 );
+        --zx.exp;
+    }
+    savedZ = zx;
+    isTiny =
+           ( slow_float_detect_tininess == float_tininess_before_rounding )
+        && ( zx.exp + 0x7F <= 0 );
+    zx = roundFloatXTo24( isTiny, zx );
+    expField = zx.exp + 0x7F;
+    if ( 0xFF <= expField ) {
+        slow_float_exception_flags |=
+            float_flag_overflow | float_flag_inexact;
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z = 0xFF800000;
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                z = 0xFF7FFFFF;
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z = 0x7F800000;
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                z = 0x7F7FFFFF;
+                break;
+            }
+        }
+        return z;
+    }
+    if ( expField <= 0 ) {
+        isTiny = TRUE;
+        zx = savedZ;
+        expField = zx.exp + 0x7F;
+        if ( expField < -27 ) {
+            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expField <= 0 ) {
+                zx.sig = shortShift64RightJamming( zx.sig, 1 );
+                ++expField;
+            }
+        }
+        zx = roundFloatXTo24( isTiny, zx );
+        expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
+    }
+    z = expField;
+    z <<= 23;
+    if ( zx.sign ) z |= 0x80000000;
+    z |= zx.sig.a0 & 0x007FFFFF;
+    return z;
+
+}
+
+static floatX float64ToFloatX( float64 a )
+{
+    int16 expField;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.isZero = FALSE;
+#ifdef BITS64
+    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
+    expField = ( a>>52 ) & 0x7FF;
+    ax.sig.a1 = a;
+    ax.sig.a0 = ( a>>32 ) & 0x000FFFFF;
+#else
+    ax.sign = ( ( a.high & 0x80000000 ) != 0 );
+    expField = ( a.high>>( 52 - 32 ) ) & 0x7FF;
+    ax.sig.a1 = a.low;
+    ax.sig.a0 = a.high & 0x000FFFFF;
+#endif
+    if ( expField == 0 ) {
+        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+            ax.isZero = TRUE;
+        }
+        else {
+            expField = 1 - 0x3FF;
+            do {
+                ax.sig = shortShift64Left( ax.sig, 1 );
+                --expField;
+            } while ( ax.sig.a0 < 0x00100000 );
+            ax.exp = expField;
+        }
+    }
+    else if ( expField == 0x7FF ) {
+        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+            ax.isInf = TRUE;
+        }
+        else {
+            ax.isNaN = TRUE;
+        }
+    }
+    else {
+        ax.exp = expField - 0x3FF;
+        ax.sig.a0 |= 0x00100000;
+    }
+    ax.sig = shortShift64Left( ax.sig, 3 );
+    return ax;
+
+}
+
+static float64 floatXToFloat64( floatX zx )
+{
+    floatX savedZ;
+    flag isTiny;
+    int16 expField;
+    float64 z;
+
+#ifdef BITS64
+    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
+    if ( zx.isInf ) {
+        return
+              zx.sign ? LIT64( 0xFFF0000000000000 )
+            : LIT64( 0x7FF0000000000000 );
+    }
+    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+#else
+    if ( zx.isZero ) {
+        z.low = 0;
+        z.high = zx.sign ? 0x80000000 : 0;
+        return z;
+    }
+    if ( zx.isInf ) {
+        z.low = 0;
+        z.high = zx.sign ? 0xFFF00000 : 0x7FF00000;
+        return z;
+    }
+    if ( zx.isNaN ) {
+        z.high = z.low = 0xFFFFFFFF;
+        return z;
+    }
+#endif
+    while ( 0x01000000 <= zx.sig.a0 ) {
+        zx.sig = shortShift64RightJamming( zx.sig, 1 );
+        ++zx.exp;
+    }
+    while ( zx.sig.a0 < 0x00800000 ) {
+        zx.sig = shortShift64Left( zx.sig, 1 );
+        --zx.exp;
+    }
+    savedZ = zx;
+    isTiny =
+           ( slow_float_detect_tininess == float_tininess_before_rounding )
+        && ( zx.exp + 0x3FF <= 0 );
+    zx = roundFloatXTo53( isTiny, zx );
+    expField = zx.exp + 0x3FF;
+    if ( 0x7FF <= expField ) {
+        slow_float_exception_flags |=
+            float_flag_overflow | float_flag_inexact;
+#ifdef BITS64
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z = LIT64( 0xFFF0000000000000 );
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                z = LIT64( 0xFFEFFFFFFFFFFFFF );
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z = LIT64( 0x7FF0000000000000 );
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                z = LIT64( 0x7FEFFFFFFFFFFFFF );
+                break;
+            }
+        }
+#else
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z.low = 0;
+                z.high = 0xFFF00000;
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                z.low = 0xFFFFFFFF;
+                z.high = 0xFFEFFFFF;
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z.low = 0;
+                z.high = 0x7FF00000;
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                z.low = 0xFFFFFFFF;
+                z.high = 0x7FEFFFFF;
+                break;
+            }
+        }
+#endif
+        return z;
+    }
+    if ( expField <= 0 ) {
+        isTiny = TRUE;
+        zx = savedZ;
+        expField = zx.exp + 0x3FF;
+        if ( expField < -56 ) {
+            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expField <= 0 ) {
+                zx.sig = shortShift64RightJamming( zx.sig, 1 );
+                ++expField;
+            }
+        }
+        zx = roundFloatXTo53( isTiny, zx );
+        expField = ( 0x00800000 <= zx.sig.a0 ) ? 1 : 0;
+    }
+    zx.sig = shortShift64RightJamming( zx.sig, 3 );
+#ifdef BITS64
+    z = expField;
+    z <<= 52;
+    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
+    z |= ( ( (bits64) ( zx.sig.a0 & 0x000FFFFF ) )<<32 ) | zx.sig.a1;
+#else
+    z.low = zx.sig.a1;
+    z.high = expField;
+    z.high <<= 52 - 32;
+    if ( zx.sign ) z.high |= 0x80000000;
+    z.high |= zx.sig.a0 & 0x000FFFFF;
+#endif
+    return z;
+
+}
+
+static floatX floatXInvalid( void )
+{
+
+    slow_float_exception_flags |= float_flag_invalid;
+    return floatXNaN;
+
+}
+
+static floatX floatXRoundToInt( floatX ax )
+{
+    int16 shiftCount, i;
+
+    if ( ax.isNaN || ax.isInf ) return ax;
+    shiftCount = 52 - ax.exp;
+    if ( shiftCount <= 0 ) return ax;
+    if ( 55 < shiftCount ) {
+        ax.exp = 52;
+        ax.sig.a1 = ! ax.isZero;
+        ax.sig.a0 = 0;
+    }
+    else {
+        while ( 0 < shiftCount ) {
+            ax.sig = shortShift64RightJamming( ax.sig, 1 );
+            ++ax.exp;
+            --shiftCount;
+        }
+    }
+    ax = roundFloatXTo53( FALSE, ax );
+    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+    return ax;
+
+}
+
+static floatX floatXAdd( floatX ax, floatX bx )
+{
+    int16 expDiff;
+    floatX zx;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf && bx.isInf ) {
+        if ( ax.sign == bx.sign ) return ax;
+        return floatXInvalid();
+    }
+    if ( ax.isInf ) return ax;
+    if ( bx.isInf ) return bx;
+    if ( ax.isZero && bx.isZero ) {
+        if ( ax.sign == bx.sign ) return ax;
+        goto completeCancellation;
+    }
+    if (    ( ax.sign != bx.sign )
+         && ( ax.exp == bx.exp )
+         && eq64( ax.sig, bx.sig )
+       ) {
+ completeCancellation:
+        return
+              ( slow_float_rounding_mode == float_round_down ) ?
+                  floatXNegativeZero
+            : floatXPositiveZero;
+    }
+    if ( ax.isZero ) return bx;
+    if ( bx.isZero ) return ax;
+    expDiff = ax.exp - bx.exp;
+    if ( expDiff < 0 ) {
+        zx = ax;
+        zx.exp = bx.exp;
+        if ( expDiff < -56 ) {
+            zx.sig.a1 = 1;
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expDiff < 0 ) {
+                zx.sig = shortShift64RightJamming( zx.sig, 1 );
+                ++expDiff;
+            }
+        }
+        if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
+        zx.sign = bx.sign;
+        zx.sig = add64( zx.sig, bx.sig );
+    }
+    else {
+        zx = bx;
+        zx.exp = ax.exp;
+        if ( 56 < expDiff ) {
+            zx.sig.a1 = 1;
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( 0 < expDiff ) {
+                zx.sig = shortShift64RightJamming( zx.sig, 1 );
+                --expDiff;
+            }
+        }
+        if ( ax.sign != bx.sign ) zx.sig = neg64( zx.sig );
+        zx.sign = ax.sign;
+        zx.sig = add64( zx.sig, ax.sig );
+    }
+    if ( zx.sig.a0 & 0x80000000 ) {
+        zx.sig = neg64( zx.sig );
+        zx.sign = ! zx.sign;
+    }
+    return zx;
+
+}
+
+static floatX floatXMul( floatX ax, floatX bx )
+{
+    int8 bitNum;
+    floatX zx;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf ) {
+        if ( bx.isZero ) return floatXInvalid();
+        if ( bx.sign ) ax.sign = ! ax.sign;
+        return ax;
+    }
+    if ( bx.isInf ) {
+        if ( ax.isZero ) return floatXInvalid();
+        if ( ax.sign ) bx.sign = ! bx.sign;
+        return bx;
+    }
+    zx = ax;
+    zx.sign ^= bx.sign;
+    if ( ax.isZero || bx.isZero ) {
+        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+    }
+    zx.exp += bx.exp + 1;
+    zx.sig.a1 = 0;
+    zx.sig.a0 = 0;
+    for ( bitNum = 0; bitNum < 55; ++bitNum ) {
+        if ( bx.sig.a1 & 2 ) zx.sig = add64( zx.sig, ax.sig );
+        bx.sig = shortShift64RightJamming( bx.sig, 1 );
+        zx.sig = shortShift64RightJamming( zx.sig, 1 );
+    }
+    return zx;
+
+}
+
+static floatX floatXDiv( floatX ax, floatX bx )
+{
+    bits64X negBSig;
+    int8 bitNum;
+    floatX zx;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf ) {
+        if ( bx.isInf ) return floatXInvalid();
+        if ( bx.sign ) ax.sign = ! ax.sign;
+        return ax;
+    }
+    if ( bx.isZero ) {
+        if ( ax.isZero ) return floatXInvalid();
+        slow_float_exception_flags |= float_flag_divbyzero;
+        if ( ax.sign ) bx.sign = ! bx.sign;
+        bx.isZero = FALSE;
+        bx.isInf = TRUE;
+        return bx;
+    }
+    zx = ax;
+    zx.sign ^= bx.sign;
+    if ( ax.isZero || bx.isInf ) {
+        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+    }
+    zx.exp -= bx.exp + 1;
+    zx.sig.a1 = 0;
+    zx.sig.a0 = 0;
+    negBSig = neg64( bx.sig );
+    for ( bitNum = 0; bitNum < 56; ++bitNum ) {
+        if ( le64( bx.sig, ax.sig ) ) {
+            zx.sig.a1 |= 1;
+            ax.sig = add64( ax.sig, negBSig );
+        }
+        ax.sig = shortShift64Left( ax.sig, 1 );
+        zx.sig = shortShift64Left( zx.sig, 1 );
+    }
+    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+    return zx;
+
+}
+
+static floatX floatXRem( floatX ax, floatX bx )
+{
+    bits64X negBSig;
+    flag lastQuotientBit;
+    bits64X savedASig;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf || bx.isZero ) return floatXInvalid();
+    if ( ax.isZero || bx.isInf ) return ax;
+    --bx.exp;
+    if ( ax.exp < bx.exp ) return ax;
+    bx.sig = shortShift64Left( bx.sig, 1 );
+    negBSig = neg64( bx.sig );
+    while ( bx.exp < ax.exp ) {
+        if ( le64( bx.sig, ax.sig ) ) ax.sig = add64( ax.sig, negBSig );
+        ax.sig = shortShift64Left( ax.sig, 1 );
+        --ax.exp;
+    }
+    lastQuotientBit = le64( bx.sig, ax.sig );
+    if ( lastQuotientBit ) ax.sig = add64( ax.sig, negBSig );
+    savedASig = ax.sig;
+    ax.sig = neg64( add64( ax.sig, negBSig ) );
+    if ( lt64( ax.sig, savedASig ) ) {
+        ax.sign = ! ax.sign;
+    }
+    else if ( lt64( savedASig, ax.sig ) ) {
+        ax.sig = savedASig;
+    }
+    else {
+        if ( lastQuotientBit ) {
+            ax.sign = ! ax.sign;
+        }
+        else {
+            ax.sig = savedASig;
+        }
+    }
+    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+    return ax;
+
+}
+
+static floatX floatXSqrt( floatX ax )
+{
+    int8 bitNum;
+    bits64X bitSig, savedASig;
+    floatX zx;
+
+    if ( ax.isNaN || ax.isZero ) return ax;
+    if ( ax.sign ) return floatXInvalid();
+    if ( ax.isInf ) return ax;
+    zx = ax;
+    zx.exp >>= 1;
+    if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift64RightJamming( ax.sig, 1 );
+    zx.sig.a1 = 0;
+    zx.sig.a0 = 0;
+    bitSig.a1 = 0;
+    bitSig.a0 = 0x00800000;
+    for ( bitNum = 0; bitNum < 56; ++bitNum ) {
+        savedASig = ax.sig;
+        ax.sig = add64( ax.sig, neg64( zx.sig ) );
+        ax.sig = shortShift64Left( ax.sig, 1 );
+        ax.sig = add64( ax.sig, neg64( bitSig ) );
+        if ( ax.sig.a0 & 0x80000000 ) {
+            ax.sig = shortShift64Left( savedASig, 1 );
+        }
+        else {
+            zx.sig.a1 |= bitSig.a1;
+            zx.sig.a0 |= bitSig.a0;
+        }
+        bitSig = shortShift64RightJamming( bitSig, 1 );
+    }
+    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+    return zx;
+
+}
+
+static flag floatXEq( floatX ax, floatX bx )
+{
+
+    if ( ax.isNaN || bx.isNaN ) return FALSE;
+    if ( ax.isZero && bx.isZero ) return TRUE;
+    if ( ax.sign != bx.sign ) return FALSE;
+    if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
+    return ( ax.exp == bx.exp ) && eq64( ax.sig, bx.sig );
+
+}
+
+static flag floatXLe( floatX ax, floatX bx )
+{
+
+    if ( ax.isNaN || bx.isNaN ) return FALSE;
+    if ( ax.isZero && bx.isZero ) return TRUE;
+    if ( ax.sign != bx.sign ) return ax.sign;
+    if ( ax.sign ) {
+        if ( ax.isInf || bx.isZero ) return TRUE;
+        if ( bx.isInf || ax.isZero ) return FALSE;
+        if ( bx.exp < ax.exp ) return TRUE;
+        if ( ax.exp < bx.exp ) return FALSE;
+        return le64( bx.sig, ax.sig );
+    }
+    else {
+        if ( bx.isInf || ax.isZero ) return TRUE;
+        if ( ax.isInf || bx.isZero ) return FALSE;
+        if ( ax.exp < bx.exp ) return TRUE;
+        if ( bx.exp < ax.exp ) return FALSE;
+        return le64( ax.sig, bx.sig );
+    }
+
+}
+
+static flag floatXLt( floatX ax, floatX bx )
+{
+
+    if ( ax.isNaN || bx.isNaN ) return FALSE;
+    if ( ax.isZero && bx.isZero ) return FALSE;
+    if ( ax.sign != bx.sign ) return ax.sign;
+    if ( ax.isInf && bx.isInf ) return FALSE;
+    if ( ax.sign ) {
+        if ( ax.isInf || bx.isZero ) return TRUE;
+        if ( bx.isInf || ax.isZero ) return FALSE;
+        if ( bx.exp < ax.exp ) return TRUE;
+        if ( ax.exp < bx.exp ) return FALSE;
+        return lt64( bx.sig, ax.sig );
+    }
+    else {
+        if ( bx.isInf || ax.isZero ) return TRUE;
+        if ( ax.isInf || bx.isZero ) return FALSE;
+        if ( ax.exp < bx.exp ) return TRUE;
+        if ( bx.exp < ax.exp ) return FALSE;
+        return lt64( ax.sig, bx.sig );
+    }
+
+}
+
+float32 slow_int32_to_float32( int32 a )
+{
+
+    return floatXToFloat32( int32ToFloatX( a ) );
+
+}
+
+float64 slow_int32_to_float64( int32 a )
+{
+
+    return floatXToFloat64( int32ToFloatX( a ) );
+
+}
+
+int32 slow_float32_to_int32( float32 a )
+{
+
+    return floatXToInt32( float32ToFloatX( a ) );
+
+}
+
+int32 slow_float32_to_int32_round_to_zero( float32 a )
+{
+    int8 savedRoundingMode;
+    int32 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt32( float32ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+float64 slow_float32_to_float64( float32 a )
+{
+
+    return floatXToFloat64( float32ToFloatX( a ) );
+
+}
+
+float32 slow_float32_round_to_int( float32 a )
+{
+
+    return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
+
+}
+
+float32 slow_float32_add( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sub( float32 a, float32 b )
+{
+
+    b ^= 0x80000000;
+    return
+        floatXToFloat32(
+            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_mul( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_div( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_rem( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sqrt( float32 a )
+{
+
+    return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
+
+}
+
+flag slow_float32_eq( float32 a, float32 b )
+{
+
+    return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_le( float32 a, float32 b )
+{
+    floatX ax, bx;
+
+    ax = float32ToFloatX( a );
+    bx = float32ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLe( ax, bx );
+
+}
+
+flag slow_float32_lt( float32 a, float32 b )
+{
+    floatX ax, bx;
+
+    ax = float32ToFloatX( a );
+    bx = float32ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLt( ax, bx );
+
+}
+
+flag slow_float32_eq_signaling( float32 a, float32 b )
+{
+    floatX ax, bx;
+
+    ax = float32ToFloatX( a );
+    bx = float32ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXEq( ax, bx );
+
+}
+
+flag slow_float32_le_quiet( float32 a, float32 b )
+{
+
+    return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_lt_quiet( float32 a, float32 b )
+{
+
+    return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+int32 slow_float64_to_int32( float64 a )
+{
+
+    return floatXToInt32( float64ToFloatX( a ) );
+
+}
+
+int32 slow_float64_to_int32_round_to_zero( float64 a )
+{
+    int8 savedRoundingMode;
+    int32 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt32( float64ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+float32 slow_float64_to_float32( float64 a )
+{
+
+    return floatXToFloat32( float64ToFloatX( a ) );
+
+}
+
+float64 slow_float64_round_to_int( float64 a )
+{
+
+    return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
+
+}
+
+float64 slow_float64_add( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sub( float64 a, float64 b )
+{
+
+#ifdef BITS64
+    b ^= LIT64( 0x8000000000000000 );
+#else
+    b.high ^= 0x80000000;
+#endif
+    return
+        floatXToFloat64(
+            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_mul( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_div( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_rem( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sqrt( float64 a )
+{
+
+    return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
+
+}
+
+flag slow_float64_eq( float64 a, float64 b )
+{
+
+    return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_le( float64 a, float64 b )
+{
+    floatX ax, bx;
+
+    ax = float64ToFloatX( a );
+    bx = float64ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLe( ax, bx );
+
+}
+
+flag slow_float64_lt( float64 a, float64 b )
+{
+    floatX ax, bx;
+
+    ax = float64ToFloatX( a );
+    bx = float64ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLt( ax, bx );
+
+}
+
+flag slow_float64_eq_signaling( float64 a, float64 b )
+{
+    floatX ax, bx;
+
+    ax = float64ToFloatX( a );
+    bx = float64ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXEq( ax, bx );
+
+}
+
+flag slow_float64_le_quiet( float64 a, float64 b )
+{
+
+    return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_lt_quiet( float64 a, float64 b )
+{
+
+    return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
diff --git a/testfloat/slowfloat-64.c b/testfloat/slowfloat-64.c
new file mode 100644
index 00000000000..27e56e1152a
--- /dev/null
+++ b/testfloat/slowfloat-64.c
@@ -0,0 +1,2109 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+int8 slow_float_rounding_mode;
+int8 slow_float_exception_flags;
+int8 slow_float_detect_tininess;
+#ifdef FLOATX80
+int8 slow_floatx80_rounding_precision;
+#endif
+
+typedef struct {
+    bits64 a0, a1;
+} bits128X;
+
+typedef struct {
+    flag isNaN;
+    flag isInf;
+    flag isZero;
+    flag sign;
+    int32 exp;
+    bits128X sig;
+} floatX;
+
+static const floatX floatXNaN = { TRUE, FALSE, FALSE, FALSE, 0, { 0, 0 } };
+static const floatX floatXPositiveZero =
+    { FALSE, FALSE, TRUE, FALSE, 0, { 0, 0 } };
+static const floatX floatXNegativeZero =
+    { FALSE, FALSE, TRUE, TRUE, 0, { 0, 0 } };
+
+static bits128X shortShift128Left( bits128X a, int8 shiftCount )
+{
+    int8 negShiftCount;
+
+    negShiftCount = ( - shiftCount & 63 );
+    a.a0 = ( a.a0<>negShiftCount );
+    a.a1 <<= shiftCount;
+    return a;
+
+}
+
+static bits128X shortShift128RightJamming( bits128X a, int8 shiftCount )
+{
+    int8 negShiftCount;
+    bits64 extra;
+
+    negShiftCount = ( - shiftCount & 63 );
+    extra = a.a1<>shiftCount ) | ( extra != 0 );
+    a.a0 >>= shiftCount;
+    return a;
+
+}
+
+static bits128X neg128( bits128X a )
+{
+
+    if ( a.a1 == 0 ) {
+        a.a0 = - a.a0;
+    }
+    else {
+        a.a1 = - a.a1;
+        a.a0 = ~ a.a0;
+    }
+    return a;
+
+}
+
+static bits128X add128( bits128X a, bits128X b )
+{
+
+    a.a1 += b.a1;
+    a.a0 += b.a0 + ( a.a1 < b.a1 );
+    return a;
+
+}
+
+static flag eq128( bits128X a, bits128X b )
+{
+
+    return ( a.a0 == b.a0 ) && ( a.a1 == b.a1 );
+
+}
+
+static flag le128( bits128X a, bits128X b )
+{
+
+    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 <= b.a1 ) );
+
+}
+
+static flag lt128( bits128X a, bits128X b )
+{
+
+    return ( a.a0 < b.a0 ) || ( ( a.a0 == b.a0 ) && ( a.a1 < b.a1 ) );
+
+}
+
+static floatX roundFloatXTo24( flag isTiny, floatX zx )
+{
+    bits32 roundBits;
+
+    zx.sig.a0 |= ( zx.sig.a1 != 0 );
+    zx.sig.a1 = 0;
+    roundBits = zx.sig.a0 & 0xFFFFFFFF;
+    zx.sig.a0 -= roundBits;
+    if ( roundBits ) {
+        slow_float_exception_flags |= float_flag_inexact;
+        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+        switch ( slow_float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( roundBits < 0x80000000 ) goto noIncrement;
+            if (    ( roundBits == 0x80000000 )
+                 && ! ( zx.sig.a0 & LIT64( 0x100000000 ) ) ) {
+                goto noIncrement;
+            }
+            break;
+         case float_round_to_zero:
+            goto noIncrement;
+         case float_round_down:
+            if ( ! zx.sign ) goto noIncrement;
+            break;
+         case float_round_up:
+            if ( zx.sign ) goto noIncrement;
+            break;
+        }
+        zx.sig.a0 += LIT64( 0x100000000 );
+        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+            zx.sig.a0 = LIT64( 0x0080000000000000 );
+            ++zx.exp;
+        }
+    }
+ noIncrement:
+    return zx;
+
+}
+
+static floatX roundFloatXTo53( flag isTiny, floatX zx )
+{
+    int8 roundBits;
+
+    zx.sig.a0 |= ( zx.sig.a1 != 0 );
+    zx.sig.a1 = 0;
+    roundBits = zx.sig.a0 & 7;
+    zx.sig.a0 -= roundBits;
+    if ( roundBits ) {
+        slow_float_exception_flags |= float_flag_inexact;
+        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+        switch ( slow_float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( roundBits < 4 ) goto noIncrement;
+            if ( ( roundBits == 4 ) && ! ( zx.sig.a0 & 8 ) ) goto noIncrement;
+            break;
+         case float_round_to_zero:
+            goto noIncrement;
+         case float_round_down:
+            if ( ! zx.sign ) goto noIncrement;
+            break;
+         case float_round_up:
+            if ( zx.sign ) goto noIncrement;
+            break;
+        }
+        zx.sig.a0 += 8;
+        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+            zx.sig.a0 = LIT64( 0x0080000000000000 );
+            ++zx.exp;
+        }
+    }
+ noIncrement:
+    return zx;
+
+}
+
+static floatX roundFloatXTo64( flag isTiny, floatX zx )
+{
+    int64 roundBits;
+
+    roundBits = zx.sig.a1 & LIT64( 0x00FFFFFFFFFFFFFF );
+    zx.sig.a1 -= roundBits;
+    if ( roundBits ) {
+        slow_float_exception_flags |= float_flag_inexact;
+        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+        switch ( slow_float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( roundBits < LIT64( 0x0080000000000000 ) ) goto noIncrement;
+            if (    ( roundBits == LIT64( 0x0080000000000000 ) )
+                 && ! ( zx.sig.a1 & LIT64( 0x0100000000000000 ) ) ) {
+                goto noIncrement;
+            }
+            break;
+         case float_round_to_zero:
+            goto noIncrement;
+         case float_round_down:
+            if ( ! zx.sign ) goto noIncrement;
+            break;
+         case float_round_up:
+            if ( zx.sign ) goto noIncrement;
+            break;
+        }
+        zx.sig.a1 += LIT64( 0x0100000000000000 );
+        zx.sig.a0 += ( zx.sig.a1 == 0 );
+        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+            zx.sig.a0 = LIT64( 0x0080000000000000 );
+            ++zx.exp;
+        }
+    }
+ noIncrement:
+    return zx;
+
+}
+
+static floatX roundFloatXTo113( flag isTiny, floatX zx )
+{
+    int8 roundBits;
+
+    roundBits = zx.sig.a1 & 0x7F;
+    zx.sig.a1 -= roundBits;
+    if ( roundBits ) {
+        slow_float_exception_flags |= float_flag_inexact;
+        if ( isTiny ) slow_float_exception_flags |= float_flag_underflow;
+        switch ( slow_float_rounding_mode ) {
+         case float_round_nearest_even:
+            if ( roundBits < 0x40 ) goto noIncrement;
+            if (    ( roundBits == 0x40 )
+                 && ! ( zx.sig.a1 & 0x80 ) ) goto noIncrement;
+            break;
+         case float_round_to_zero:
+            goto noIncrement;
+         case float_round_down:
+            if ( ! zx.sign ) goto noIncrement;
+            break;
+         case float_round_up:
+            if ( zx.sign ) goto noIncrement;
+            break;
+        }
+        zx.sig.a1 += 0x80;
+        zx.sig.a0 += ( zx.sig.a1 == 0 );
+        if ( zx.sig.a0 == LIT64( 0x0100000000000000 ) ) {
+            zx.sig.a0 = LIT64( 0x0080000000000000 );
+            ++zx.exp;
+        }
+    }
+ noIncrement:
+    return zx;
+
+}
+
+static floatX int32ToFloatX( int32 a )
+{
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.sign = ( a < 0 );
+    ax.sig.a1 = 0;
+    ax.sig.a0 = ax.sign ? - (bits64) a : a;
+    if ( a == 0 ) {
+        ax.isZero = TRUE;
+        return ax;
+    }
+    ax.isZero = FALSE;
+    ax.sig.a0 <<= 24;
+    ax.exp = 31;
+    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+        ax.sig.a0 <<= 1;
+        --ax.exp;
+    }
+    return ax;
+
+}
+
+static int32 floatXToInt32( floatX ax )
+{
+    int8 savedExceptionFlags;
+    int32 shiftCount;
+    int32 z;
+
+    if ( ax.isInf || ax.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+        return ( ax.isInf & ax.sign ) ? (sbits32) 0x80000000 : 0x7FFFFFFF;
+    }
+    if ( ax.isZero ) return 0;
+    savedExceptionFlags = slow_float_exception_flags;
+    shiftCount = 52 - ax.exp;
+    if ( 56 < shiftCount ) {
+        ax.sig.a1 = 1;
+        ax.sig.a0 = 0;
+    }
+    else {
+        while ( 0 < shiftCount ) {
+            ax.sig = shortShift128RightJamming( ax.sig, 1 );
+            --shiftCount;
+        }
+    }
+    ax = roundFloatXTo53( FALSE, ax );
+    ax.sig = shortShift128RightJamming( ax.sig, 3 );
+    z = ax.sig.a0;
+    if ( ax.sign ) z = - z;
+    if (    ( shiftCount < 0 )
+         || ( ax.sig.a0>>32 )
+         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
+       ) {
+        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
+        return ax.sign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
+    }
+    return z;
+
+}
+
+static floatX int64ToFloatX( int64 a )
+{
+    uint64 absA;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.sign = ( a < 0 );
+    ax.sig.a1 = ax.sign ? - a : a;
+    ax.sig.a0 = 0;
+    if ( a == 0 ) {
+        ax.isZero = TRUE;
+        return ax;
+    }
+    ax.isZero = FALSE;
+    ax.sig = shortShift128Left( ax.sig, 56 );
+    ax.exp = 63;
+    while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+        ax.sig = shortShift128Left( ax.sig, 1 );
+        --ax.exp;
+    }
+    return ax;
+
+}
+
+static int64 floatXToInt64( floatX ax )
+{
+    int8 savedExceptionFlags;
+    int32 shiftCount;
+    int64 z;
+
+    if ( ax.isInf || ax.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+        return
+              ( ax.isInf & ax.sign ) ? (sbits64) LIT64( 0x8000000000000000 )
+            : LIT64( 0x7FFFFFFFFFFFFFFF );
+    }
+    if ( ax.isZero ) return 0;
+    savedExceptionFlags = slow_float_exception_flags;
+    shiftCount = 112 - ax.exp;
+    if ( 116 < shiftCount ) {
+        ax.sig.a1 = 1;
+        ax.sig.a0 = 0;
+    }
+    else {
+        while ( 0 < shiftCount ) {
+            ax.sig = shortShift128RightJamming( ax.sig, 1 );
+            --shiftCount;
+        }
+    }
+    ax = roundFloatXTo113( FALSE, ax );
+    ax.sig = shortShift128RightJamming( ax.sig, 7 );
+    z = ax.sig.a1;
+    if ( ax.sign ) z = - z;
+    if (    ( shiftCount < 0 )
+         || ax.sig.a0
+         || ( ( z != 0 ) && ( ( ax.sign ^ ( z < 0 ) ) != 0 ) )
+       ) {
+        slow_float_exception_flags = savedExceptionFlags | float_flag_invalid;
+        return
+              ax.sign ? (sbits64) LIT64( 0x8000000000000000 )
+            : LIT64( 0x7FFFFFFFFFFFFFFF );
+    }
+    return z;
+
+}
+
+static floatX float32ToFloatX( float32 a )
+{
+    int16 expField;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.isZero = FALSE;
+    ax.sign = ( ( a & 0x80000000 ) != 0 );
+    expField = ( a>>23 ) & 0xFF;
+    ax.sig.a1 = 0;
+    ax.sig.a0 = a & 0x007FFFFF;
+    ax.sig.a0 <<= 32;
+    if ( expField == 0 ) {
+        if ( ax.sig.a0 == 0 ) {
+            ax.isZero = TRUE;
+        }
+        else {
+            expField = 1 - 0x7F;
+            do {
+                ax.sig.a0 <<= 1;
+                --expField;
+            } while ( ax.sig.a0 < LIT64( 0x0080000000000000 ) );
+            ax.exp = expField;
+        }
+    }
+    else if ( expField == 0xFF ) {
+        if ( ax.sig.a0 == 0 ) {
+            ax.isInf = TRUE;
+        }
+        else {
+            ax.isNaN = TRUE;
+        }
+    }
+    else {
+        ax.sig.a0 |= LIT64( 0x0080000000000000 );
+        ax.exp = expField - 0x7F;
+    }
+    return ax;
+
+}
+
+static float32 floatXToFloat32( floatX zx )
+{
+    floatX savedZ;
+    flag isTiny;
+    int32 expField;
+    float32 z;
+
+    if ( zx.isZero ) return zx.sign ? 0x80000000 : 0;
+    if ( zx.isInf ) return zx.sign ? 0xFF800000 : 0x7F800000;
+    if ( zx.isNaN ) return 0xFFFFFFFF;
+    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+        zx.sig = shortShift128RightJamming( zx.sig, 1 );
+        ++zx.exp;
+    }
+    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+        zx.sig = shortShift128Left( zx.sig, 1 );
+        --zx.exp;
+    }
+    savedZ = zx;
+    isTiny =
+           ( slow_float_detect_tininess == float_tininess_before_rounding )
+        && ( zx.exp + 0x7F <= 0 );
+    zx = roundFloatXTo24( isTiny, zx );
+    expField = zx.exp + 0x7F;
+    if ( 0xFF <= expField ) {
+        slow_float_exception_flags |=
+            float_flag_overflow | float_flag_inexact;
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z = 0xFF800000;
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                z = 0xFF7FFFFF;
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z = 0x7F800000;
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                z = 0x7F7FFFFF;
+                break;
+            }
+        }
+        return z;
+    }
+    if ( expField <= 0 ) {
+        isTiny = TRUE;
+        zx = savedZ;
+        expField = zx.exp + 0x7F;
+        if ( expField < -27 ) {
+            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expField <= 0 ) {
+                zx.sig = shortShift128RightJamming( zx.sig, 1 );
+                ++expField;
+            }
+        }
+        zx = roundFloatXTo24( isTiny, zx );
+        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+    }
+    z = expField;
+    z <<= 23;
+    if ( zx.sign ) z |= 0x80000000;
+    z |= ( zx.sig.a0>>32 ) & 0x007FFFFF;
+    return z;
+
+}
+
+static floatX float64ToFloatX( float64 a )
+{
+    int16 expField;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.isZero = FALSE;
+    ax.sign = ( ( a & LIT64( 0x8000000000000000 ) ) != 0 );
+    expField = ( a>>52 ) & 0x7FF;
+    ax.sig.a1 = 0;
+    ax.sig.a0 = a & LIT64( 0x000FFFFFFFFFFFFF );
+    if ( expField == 0 ) {
+        if ( ax.sig.a0 == 0 ) {
+            ax.isZero = TRUE;
+        }
+        else {
+            expField = 1 - 0x3FF;
+            do {
+                ax.sig.a0 <<= 1;
+                --expField;
+            } while ( ax.sig.a0 < LIT64( 0x0010000000000000 ) );
+            ax.exp = expField;
+        }
+    }
+    else if ( expField == 0x7FF ) {
+        if ( ax.sig.a0 == 0 ) {
+            ax.isInf = TRUE;
+        }
+        else {
+            ax.isNaN = TRUE;
+        }
+    }
+    else {
+        ax.exp = expField - 0x3FF;
+        ax.sig.a0 |= LIT64( 0x0010000000000000 );
+    }
+    ax.sig.a0 <<= 3;
+    return ax;
+
+}
+
+static float64 floatXToFloat64( floatX zx )
+{
+    floatX savedZ;
+    flag isTiny;
+    int32 expField;
+    float64 z;
+
+    if ( zx.isZero ) return zx.sign ? LIT64( 0x8000000000000000 ) : 0;
+    if ( zx.isInf ) {
+        return
+              zx.sign ? LIT64( 0xFFF0000000000000 )
+            : LIT64( 0x7FF0000000000000 );
+    }
+    if ( zx.isNaN ) return LIT64( 0xFFFFFFFFFFFFFFFF );
+    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+        zx.sig = shortShift128RightJamming( zx.sig, 1 );
+        ++zx.exp;
+    }
+    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+        zx.sig = shortShift128Left( zx.sig, 1 );
+        --zx.exp;
+    }
+    savedZ = zx;
+    isTiny =
+           ( slow_float_detect_tininess == float_tininess_before_rounding )
+        && ( zx.exp + 0x3FF <= 0 );
+    zx = roundFloatXTo53( isTiny, zx );
+    expField = zx.exp + 0x3FF;
+    if ( 0x7FF <= expField ) {
+        slow_float_exception_flags |=
+            float_flag_overflow | float_flag_inexact;
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z = LIT64( 0xFFF0000000000000 );
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                z = LIT64( 0xFFEFFFFFFFFFFFFF );
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z = LIT64( 0x7FF0000000000000 );
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                z = LIT64( 0x7FEFFFFFFFFFFFFF );
+                break;
+            }
+        }
+        return z;
+    }
+    if ( expField <= 0 ) {
+        isTiny = TRUE;
+        zx = savedZ;
+        expField = zx.exp + 0x3FF;
+        if ( expField < -56 ) {
+            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expField <= 0 ) {
+                zx.sig = shortShift128RightJamming( zx.sig, 1 );
+                ++expField;
+            }
+        }
+        zx = roundFloatXTo53( isTiny, zx );
+        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+    }
+    zx.sig.a0 >>= 3;
+    z = expField;
+    z <<= 52;
+    if ( zx.sign ) z |= LIT64( 0x8000000000000000 );
+    z |= zx.sig.a0 & LIT64( 0x000FFFFFFFFFFFFF );
+    return z;
+
+}
+
+#ifdef FLOATX80
+
+static floatX floatx80ToFloatX( floatx80 a )
+{
+    int32 expField;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.isZero = FALSE;
+    ax.sign = ( ( a.high & 0x8000 ) != 0 );
+    expField = a.high & 0x7FFF;
+    ax.sig.a1 = a.low;
+    ax.sig.a0 = 0;
+    if ( expField == 0 ) {
+        if ( ax.sig.a1 == 0 ) {
+            ax.isZero = TRUE;
+        }
+        else {
+            expField = 1 - 0x3FFF;
+            while ( ax.sig.a1 < LIT64( 0x8000000000000000 ) ) {
+                ax.sig.a1 <<= 1;
+                --expField;
+            }
+            ax.exp = expField;
+        }
+    }
+    else if ( expField == 0x7FFF ) {
+        if ( ( ax.sig.a1 & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 ) {
+            ax.isInf = TRUE;
+        }
+        else {
+            ax.isNaN = TRUE;
+        }
+    }
+    else {
+        ax.exp = expField - 0x3FFF;
+    }
+    ax.sig = shortShift128Left( ax.sig, 56 );
+    return ax;
+
+}
+
+static floatx80 floatXToFloatx80( floatX zx )
+{
+    floatX savedZ;
+    flag isTiny;
+    int32 expField;
+    floatx80 z;
+
+    if ( zx.isZero ) {
+        z.low = 0;
+        z.high = zx.sign ? 0x8000 : 0;
+        return z;
+    }
+    if ( zx.isInf ) {
+        z.low = LIT64( 0x8000000000000000 );
+        z.high = zx.sign ? 0xFFFF : 0x7FFF;
+        return z;
+    }
+    if ( zx.isNaN ) {
+        z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+        z.high = 0xFFFF;
+        return z;
+    }
+    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+        zx.sig = shortShift128RightJamming( zx.sig, 1 );
+        ++zx.exp;
+    }
+    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+        zx.sig = shortShift128Left( zx.sig, 1 );
+        --zx.exp;
+    }
+    savedZ = zx;
+    isTiny =
+           ( slow_float_detect_tininess == float_tininess_before_rounding )
+        && ( zx.exp + 0x3FFF <= 0 );
+    switch ( slow_floatx80_rounding_precision ) {
+     case 32:
+        zx = roundFloatXTo24( isTiny, zx );
+        break;
+     case 64:
+        zx = roundFloatXTo53( isTiny, zx );
+        break;
+     default:
+        zx = roundFloatXTo64( isTiny, zx );
+        break;
+    }
+    expField = zx.exp + 0x3FFF;
+    if ( 0x7FFF <= expField ) {
+        slow_float_exception_flags |=
+            float_flag_overflow | float_flag_inexact;
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z.low = LIT64( 0x8000000000000000 );
+                z.high = 0xFFFF;
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                switch ( slow_floatx80_rounding_precision ) {
+                 case 32:
+                    z.low = LIT64( 0xFFFFFF0000000000 );
+                    break;
+                 case 64:
+                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
+                    break;
+                 default:
+                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+                    break;
+                }
+                z.high = 0xFFFE;
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z.low = LIT64( 0x8000000000000000 );
+                z.high = 0x7FFF;
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                switch ( slow_floatx80_rounding_precision ) {
+                 case 32:
+                    z.low = LIT64( 0xFFFFFF0000000000 );
+                    break;
+                 case 64:
+                    z.low = LIT64( 0xFFFFFFFFFFFFF800 );
+                    break;
+                 default:
+                    z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+                    break;
+                }
+                z.high = 0x7FFE;
+                break;
+            }
+        }
+        return z;
+    }
+    if ( expField <= 0 ) {
+        isTiny = TRUE;
+        zx = savedZ;
+        expField = zx.exp + 0x3FFF;
+        if ( expField < -70 ) {
+            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expField <= 0 ) {
+                zx.sig = shortShift128RightJamming( zx.sig, 1 );
+                ++expField;
+            }
+        }
+        switch ( slow_floatx80_rounding_precision ) {
+         case 32:
+            zx = roundFloatXTo24( isTiny, zx );
+            break;
+         case 64:
+            zx = roundFloatXTo53( isTiny, zx );
+            break;
+         default:
+            zx = roundFloatXTo64( isTiny, zx );
+            break;
+        }
+        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+    }
+    zx.sig = shortShift128RightJamming( zx.sig, 56 );
+    z.low = zx.sig.a1;
+    z.high = expField;
+    if ( zx.sign ) z.high |= 0x8000;
+    return z;
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+static floatX float128ToFloatX( float128 a )
+{
+    int32 expField;
+    floatX ax;
+
+    ax.isNaN = FALSE;
+    ax.isInf = FALSE;
+    ax.isZero = FALSE;
+    ax.sign = ( ( a.high & LIT64( 0x8000000000000000 ) ) != 0 );
+    expField = ( a.high>>48 ) & 0x7FFF;
+    ax.sig.a1 = a.low;
+    ax.sig.a0 = a.high & LIT64( 0x0000FFFFFFFFFFFF );
+    if ( expField == 0 ) {
+        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+            ax.isZero = TRUE;
+        }
+        else {
+            expField = 1 - 0x3FFF;
+            do {
+                ax.sig = shortShift128Left( ax.sig, 1 );
+                --expField;
+            } while ( ax.sig.a0 < LIT64( 0x0001000000000000 ) );
+            ax.exp = expField;
+        }
+    }
+    else if ( expField == 0x7FFF ) {
+        if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) {
+            ax.isInf = TRUE;
+        }
+        else {
+            ax.isNaN = TRUE;
+        }
+    }
+    else {
+        ax.exp = expField - 0x3FFF;
+        ax.sig.a0 |= LIT64( 0x0001000000000000 );
+    }
+    ax.sig = shortShift128Left( ax.sig, 7 );
+    return ax;
+
+}
+
+static float128 floatXToFloat128( floatX zx )
+{
+    floatX savedZ;
+    flag isTiny;
+    int32 expField;
+    float128 z;
+
+    if ( zx.isZero ) {
+        z.low = 0;
+        z.high = zx.sign ? LIT64( 0x8000000000000000 ) : 0;
+        return z;
+    }
+    if ( zx.isInf ) {
+        z.low = 0;
+        z.high =
+              zx.sign ? LIT64( 0xFFFF000000000000 )
+            : LIT64( 0x7FFF000000000000 );
+        return z;
+    }
+    if ( zx.isNaN ) {
+        z.high = z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+        return z;
+    }
+    while ( LIT64( 0x0100000000000000 ) <= zx.sig.a0 ) {
+        zx.sig = shortShift128RightJamming( zx.sig, 1 );
+        ++zx.exp;
+    }
+    while ( zx.sig.a0 < LIT64( 0x0080000000000000 ) ) {
+        zx.sig = shortShift128Left( zx.sig, 1 );
+        --zx.exp;
+    }
+    savedZ = zx;
+    isTiny =
+           ( slow_float_detect_tininess == float_tininess_before_rounding )
+        && ( zx.exp + 0x3FFF <= 0 );
+    zx = roundFloatXTo113( isTiny, zx );
+    expField = zx.exp + 0x3FFF;
+    if ( 0x7FFF <= expField ) {
+        slow_float_exception_flags |=
+            float_flag_overflow | float_flag_inexact;
+        if ( zx.sign ) {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_down:
+                z.low = 0;
+                z.high = LIT64( 0xFFFF000000000000 );
+                break;
+             case float_round_to_zero:
+             case float_round_up:
+                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+                z.high = LIT64( 0xFFFEFFFFFFFFFFFF );
+                break;
+            }
+        }
+        else {
+            switch ( slow_float_rounding_mode ) {
+             case float_round_nearest_even:
+             case float_round_up:
+                z.low = 0;
+                z.high = LIT64( 0x7FFF000000000000 );
+                break;
+             case float_round_to_zero:
+             case float_round_down:
+                z.low = LIT64( 0xFFFFFFFFFFFFFFFF );
+                z.high = LIT64( 0x7FFEFFFFFFFFFFFF );
+                break;
+            }
+        }
+        return z;
+    }
+    if ( expField <= 0 ) {
+        isTiny = TRUE;
+        zx = savedZ;
+        expField = zx.exp + 0x3FFF;
+        if ( expField < -120 ) {
+            zx.sig.a1 = ( zx.sig.a0 != 0 ) || ( zx.sig.a1 != 0 );
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expField <= 0 ) {
+                zx.sig = shortShift128RightJamming( zx.sig, 1 );
+                ++expField;
+            }
+        }
+        zx = roundFloatXTo113( isTiny, zx );
+        expField = ( LIT64( 0x0080000000000000 ) <= zx.sig.a0 ) ? 1 : 0;
+    }
+    zx.sig = shortShift128RightJamming( zx.sig, 7 );
+    z.low = zx.sig.a1;
+    z.high = expField;
+    z.high <<= 48;
+    if ( zx.sign ) z.high |= LIT64( 0x8000000000000000 );
+    z.high |= zx.sig.a0 & LIT64( 0x0000FFFFFFFFFFFF );
+    return z;
+
+}
+
+#endif
+
+static floatX floatXInvalid( void )
+{
+
+    slow_float_exception_flags |= float_flag_invalid;
+    return floatXNaN;
+
+}
+
+static floatX floatXRoundToInt( floatX ax )
+{
+    int32 shiftCount, i;
+
+    if ( ax.isNaN || ax.isInf ) return ax;
+    shiftCount = 112 - ax.exp;
+    if ( shiftCount <= 0 ) return ax;
+    if ( 119 < shiftCount ) {
+        ax.exp = 112;
+        ax.sig.a1 = ! ax.isZero;
+        ax.sig.a0 = 0;
+    }
+    else {
+        while ( 0 < shiftCount ) {
+            ax.sig = shortShift128RightJamming( ax.sig, 1 );
+            ++ax.exp;
+            --shiftCount;
+        }
+    }
+    ax = roundFloatXTo113( FALSE, ax );
+    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+    return ax;
+
+}
+
+static floatX floatXAdd( floatX ax, floatX bx )
+{
+    int32 expDiff;
+    floatX zx;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf && bx.isInf ) {
+        if ( ax.sign == bx.sign ) return ax;
+        return floatXInvalid();
+    }
+    if ( ax.isInf ) return ax;
+    if ( bx.isInf ) return bx;
+    if ( ax.isZero && bx.isZero ) {
+        if ( ax.sign == bx.sign ) return ax;
+        goto completeCancellation;
+    }
+    if (    ( ax.sign != bx.sign )
+         && ( ax.exp == bx.exp )
+         && eq128( ax.sig, bx.sig )
+       ) {
+ completeCancellation:
+        return
+              ( slow_float_rounding_mode == float_round_down ) ?
+                  floatXNegativeZero
+            : floatXPositiveZero;
+    }
+    if ( ax.isZero ) return bx;
+    if ( bx.isZero ) return ax;
+    expDiff = ax.exp - bx.exp;
+    if ( expDiff < 0 ) {
+        zx = ax;
+        zx.exp = bx.exp;
+        if ( expDiff < -120 ) {
+            zx.sig.a1 = 1;
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( expDiff < 0 ) {
+                zx.sig = shortShift128RightJamming( zx.sig, 1 );
+                ++expDiff;
+            }
+        }
+        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
+        zx.sign = bx.sign;
+        zx.sig = add128( zx.sig, bx.sig );
+    }
+    else {
+        zx = bx;
+        zx.exp = ax.exp;
+        if ( 120 < expDiff ) {
+            zx.sig.a1 = 1;
+            zx.sig.a0 = 0;
+        }
+        else {
+            while ( 0 < expDiff ) {
+                zx.sig = shortShift128RightJamming( zx.sig, 1 );
+                --expDiff;
+            }
+        }
+        if ( ax.sign != bx.sign ) zx.sig = neg128( zx.sig );
+        zx.sign = ax.sign;
+        zx.sig = add128( zx.sig, ax.sig );
+    }
+    if ( zx.sig.a0 & LIT64( 0x8000000000000000 ) ) {
+        zx.sig = neg128( zx.sig );
+        zx.sign = ! zx.sign;
+    }
+    return zx;
+
+}
+
+static floatX floatXMul( floatX ax, floatX bx )
+{
+    int8 bitNum;
+    floatX zx;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf ) {
+        if ( bx.isZero ) return floatXInvalid();
+        if ( bx.sign ) ax.sign = ! ax.sign;
+        return ax;
+    }
+    if ( bx.isInf ) {
+        if ( ax.isZero ) return floatXInvalid();
+        if ( ax.sign ) bx.sign = ! bx.sign;
+        return bx;
+    }
+    zx = ax;
+    zx.sign ^= bx.sign;
+    if ( ax.isZero || bx.isZero ) {
+        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+    }
+    zx.exp += bx.exp + 1;
+    zx.sig.a1 = 0;
+    zx.sig.a0 = 0;
+    for ( bitNum = 0; bitNum < 119; ++bitNum ) {
+        if ( bx.sig.a1 & 2 ) zx.sig = add128( zx.sig, ax.sig );
+        bx.sig = shortShift128RightJamming( bx.sig, 1 );
+        zx.sig = shortShift128RightJamming( zx.sig, 1 );
+    }
+    return zx;
+
+}
+
+static floatX floatXDiv( floatX ax, floatX bx )
+{
+    bits128X negBSig;
+    int8 bitNum;
+    floatX zx;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf ) {
+        if ( bx.isInf ) return floatXInvalid();
+        if ( bx.sign ) ax.sign = ! ax.sign;
+        return ax;
+    }
+    if ( bx.isZero ) {
+        if ( ax.isZero ) return floatXInvalid();
+        slow_float_exception_flags |= float_flag_divbyzero;
+        if ( ax.sign ) bx.sign = ! bx.sign;
+        bx.isZero = FALSE;
+        bx.isInf = TRUE;
+        return bx;
+    }
+    zx = ax;
+    zx.sign ^= bx.sign;
+    if ( ax.isZero || bx.isInf ) {
+        return zx.sign ? floatXNegativeZero : floatXPositiveZero;
+    }
+    zx.exp -= bx.exp + 1;
+    zx.sig.a1 = 0;
+    zx.sig.a0 = 0;
+    negBSig = neg128( bx.sig );
+    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
+        if ( le128( bx.sig, ax.sig ) ) {
+            zx.sig.a1 |= 1;
+            ax.sig = add128( ax.sig, negBSig );
+        }
+        ax.sig = shortShift128Left( ax.sig, 1 );
+        zx.sig = shortShift128Left( zx.sig, 1 );
+    }
+    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+    return zx;
+
+}
+
+static floatX floatXRem( floatX ax, floatX bx )
+{
+    bits128X negBSig;
+    flag lastQuotientBit;
+    bits128X savedASig;
+
+    if ( ax.isNaN ) return ax;
+    if ( bx.isNaN ) return bx;
+    if ( ax.isInf || bx.isZero ) return floatXInvalid();
+    if ( ax.isZero || bx.isInf ) return ax;
+    --bx.exp;
+    if ( ax.exp < bx.exp ) return ax;
+    bx.sig = shortShift128Left( bx.sig, 1 );
+    negBSig = neg128( bx.sig );
+    while ( bx.exp < ax.exp ) {
+        if ( le128( bx.sig, ax.sig ) ) ax.sig = add128( ax.sig, negBSig );
+        ax.sig = shortShift128Left( ax.sig, 1 );
+        --ax.exp;
+    }
+    lastQuotientBit = le128( bx.sig, ax.sig );
+    if ( lastQuotientBit ) ax.sig = add128( ax.sig, negBSig );
+    savedASig = ax.sig;
+    ax.sig = neg128( add128( ax.sig, negBSig ) );
+    if ( lt128( ax.sig, savedASig ) ) {
+        ax.sign = ! ax.sign;
+    }
+    else if ( lt128( savedASig, ax.sig ) ) {
+        ax.sig = savedASig;
+    }
+    else {
+        if ( lastQuotientBit ) {
+            ax.sign = ! ax.sign;
+        }
+        else {
+            ax.sig = savedASig;
+        }
+    }
+    if ( ( ax.sig.a0 == 0 ) && ( ax.sig.a1 == 0 ) ) ax.isZero = TRUE;
+    return ax;
+
+}
+
+static floatX floatXSqrt( floatX ax )
+{
+    int8 bitNum;
+    bits128X bitSig, savedASig;
+    floatX zx;
+
+    if ( ax.isNaN || ax.isZero ) return ax;
+    if ( ax.sign ) return floatXInvalid();
+    if ( ax.isInf ) return ax;
+    zx = ax;
+    zx.exp >>= 1;
+    if ( ( ax.exp & 1 ) == 0 ) ax.sig = shortShift128RightJamming( ax.sig, 1 );
+    zx.sig.a1 = 0;
+    zx.sig.a0 = 0;
+    bitSig.a1 = 0;
+    bitSig.a0 = LIT64( 0x0080000000000000 );
+    for ( bitNum = 0; bitNum < 120; ++bitNum ) {
+        savedASig = ax.sig;
+        ax.sig = add128( ax.sig, neg128( zx.sig ) );
+        ax.sig = shortShift128Left( ax.sig, 1 );
+        ax.sig = add128( ax.sig, neg128( bitSig ) );
+        if ( ax.sig.a0 & LIT64( 0x8000000000000000 ) ) {
+            ax.sig = shortShift128Left( savedASig, 1 );
+        }
+        else {
+            zx.sig.a1 |= bitSig.a1;
+            zx.sig.a0 |= bitSig.a0;
+        }
+        bitSig = shortShift128RightJamming( bitSig, 1 );
+    }
+    if ( ax.sig.a0 || ax.sig.a1 ) zx.sig.a1 |= 1;
+    return zx;
+
+}
+
+static flag floatXEq( floatX ax, floatX bx )
+{
+
+    if ( ax.isNaN || bx.isNaN ) return FALSE;
+    if ( ax.isZero && bx.isZero ) return TRUE;
+    if ( ax.sign != bx.sign ) return FALSE;
+    if ( ax.isInf || bx.isInf ) return ax.isInf && bx.isInf;
+    return ( ax.exp == bx.exp ) && eq128( ax.sig, bx.sig );
+
+}
+
+static flag floatXLe( floatX ax, floatX bx )
+{
+
+    if ( ax.isNaN || bx.isNaN ) return FALSE;
+    if ( ax.isZero && bx.isZero ) return TRUE;
+    if ( ax.sign != bx.sign ) return ax.sign;
+    if ( ax.sign ) {
+        if ( ax.isInf || bx.isZero ) return TRUE;
+        if ( bx.isInf || ax.isZero ) return FALSE;
+        if ( bx.exp < ax.exp ) return TRUE;
+        if ( ax.exp < bx.exp ) return FALSE;
+        return le128( bx.sig, ax.sig );
+    }
+    else {
+        if ( bx.isInf || ax.isZero ) return TRUE;
+        if ( ax.isInf || bx.isZero ) return FALSE;
+        if ( ax.exp < bx.exp ) return TRUE;
+        if ( bx.exp < ax.exp ) return FALSE;
+        return le128( ax.sig, bx.sig );
+    }
+
+}
+
+static flag floatXLt( floatX ax, floatX bx )
+{
+
+    if ( ax.isNaN || bx.isNaN ) return FALSE;
+    if ( ax.isZero && bx.isZero ) return FALSE;
+    if ( ax.sign != bx.sign ) return ax.sign;
+    if ( ax.isInf && bx.isInf ) return FALSE;
+    if ( ax.sign ) {
+        if ( ax.isInf || bx.isZero ) return TRUE;
+        if ( bx.isInf || ax.isZero ) return FALSE;
+        if ( bx.exp < ax.exp ) return TRUE;
+        if ( ax.exp < bx.exp ) return FALSE;
+        return lt128( bx.sig, ax.sig );
+    }
+    else {
+        if ( bx.isInf || ax.isZero ) return TRUE;
+        if ( ax.isInf || bx.isZero ) return FALSE;
+        if ( ax.exp < bx.exp ) return TRUE;
+        if ( bx.exp < ax.exp ) return FALSE;
+        return lt128( ax.sig, bx.sig );
+    }
+
+}
+
+float32 slow_int32_to_float32( int32 a )
+{
+
+    return floatXToFloat32( int32ToFloatX( a ) );
+
+}
+
+float64 slow_int32_to_float64( int32 a )
+{
+
+    return floatXToFloat64( int32ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_int32_to_floatx80( int32 a )
+{
+
+    return floatXToFloatx80( int32ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_int32_to_float128( int32 a )
+{
+
+    return floatXToFloat128( int32ToFloatX( a ) );
+
+}
+
+#endif
+
+float32 slow_int64_to_float32( int64 a )
+{
+
+    return floatXToFloat32( int64ToFloatX( a ) );
+
+}
+
+float64 slow_int64_to_float64( int64 a )
+{
+
+    return floatXToFloat64( int64ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_int64_to_floatx80( int64 a )
+{
+
+    return floatXToFloatx80( int64ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_int64_to_float128( int64 a )
+{
+
+    return floatXToFloat128( int64ToFloatX( a ) );
+
+}
+
+#endif
+
+int32 slow_float32_to_int32( float32 a )
+{
+
+    return floatXToInt32( float32ToFloatX( a ) );
+
+}
+
+int32 slow_float32_to_int32_round_to_zero( float32 a )
+{
+    int8 savedRoundingMode;
+    int32 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt32( float32ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+int64 slow_float32_to_int64( float32 a )
+{
+
+    return floatXToInt64( float32ToFloatX( a ) );
+
+}
+
+int64 slow_float32_to_int64_round_to_zero( float32 a )
+{
+    int8 savedRoundingMode;
+    int64 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt64( float32ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+float64 slow_float32_to_float64( float32 a )
+{
+
+    return floatXToFloat64( float32ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_float32_to_floatx80( float32 a )
+{
+
+    return floatXToFloatx80( float32ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_float32_to_float128( float32 a )
+{
+
+    return floatXToFloat128( float32ToFloatX( a ) );
+
+}
+
+#endif
+
+float32 slow_float32_round_to_int( float32 a )
+{
+
+    return floatXToFloat32( floatXRoundToInt( float32ToFloatX( a ) ) );
+
+}
+
+float32 slow_float32_add( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sub( float32 a, float32 b )
+{
+
+    b ^= 0x80000000;
+    return
+        floatXToFloat32(
+            floatXAdd( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_mul( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXMul( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_div( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXDiv( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_rem( float32 a, float32 b )
+{
+
+    return
+        floatXToFloat32(
+            floatXRem( float32ToFloatX( a ), float32ToFloatX( b ) ) );
+
+}
+
+float32 slow_float32_sqrt( float32 a )
+{
+
+    return floatXToFloat32( floatXSqrt( float32ToFloatX( a ) ) );
+
+}
+
+flag slow_float32_eq( float32 a, float32 b )
+{
+
+    return floatXEq( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_le( float32 a, float32 b )
+{
+    floatX ax, bx;
+
+    ax = float32ToFloatX( a );
+    bx = float32ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLe( ax, bx );
+
+}
+
+flag slow_float32_lt( float32 a, float32 b )
+{
+    floatX ax, bx;
+
+    ax = float32ToFloatX( a );
+    bx = float32ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLt( ax, bx );
+
+}
+
+flag slow_float32_eq_signaling( float32 a, float32 b )
+{
+    floatX ax, bx;
+
+    ax = float32ToFloatX( a );
+    bx = float32ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXEq( ax, bx );
+
+}
+
+flag slow_float32_le_quiet( float32 a, float32 b )
+{
+
+    return floatXLe( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+flag slow_float32_lt_quiet( float32 a, float32 b )
+{
+
+    return floatXLt( float32ToFloatX( a ), float32ToFloatX( b ) );
+
+}
+
+int32 slow_float64_to_int32( float64 a )
+{
+
+    return floatXToInt32( float64ToFloatX( a ) );
+
+}
+
+int32 slow_float64_to_int32_round_to_zero( float64 a )
+{
+    int8 savedRoundingMode;
+    int32 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt32( float64ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+int64 slow_float64_to_int64( float64 a )
+{
+
+    return floatXToInt64( float64ToFloatX( a ) );
+
+}
+
+int64 slow_float64_to_int64_round_to_zero( float64 a )
+{
+    int8 savedRoundingMode;
+    int64 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt64( float64ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+float32 slow_float64_to_float32( float64 a )
+{
+
+    return floatXToFloat32( float64ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_float64_to_floatx80( float64 a )
+{
+
+    return floatXToFloatx80( float64ToFloatX( a ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+float128 slow_float64_to_float128( float64 a )
+{
+
+    return floatXToFloat128( float64ToFloatX( a ) );
+
+}
+
+#endif
+
+float64 slow_float64_round_to_int( float64 a )
+{
+
+    return floatXToFloat64( floatXRoundToInt( float64ToFloatX( a ) ) );
+
+}
+
+float64 slow_float64_add( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sub( float64 a, float64 b )
+{
+
+    b ^= LIT64( 0x8000000000000000 );
+    return
+        floatXToFloat64(
+            floatXAdd( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_mul( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXMul( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_div( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXDiv( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_rem( float64 a, float64 b )
+{
+
+    return
+        floatXToFloat64(
+            floatXRem( float64ToFloatX( a ), float64ToFloatX( b ) ) );
+
+}
+
+float64 slow_float64_sqrt( float64 a )
+{
+
+    return floatXToFloat64( floatXSqrt( float64ToFloatX( a ) ) );
+
+}
+
+flag slow_float64_eq( float64 a, float64 b )
+{
+
+    return floatXEq( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_le( float64 a, float64 b )
+{
+    floatX ax, bx;
+
+    ax = float64ToFloatX( a );
+    bx = float64ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLe( ax, bx );
+
+}
+
+flag slow_float64_lt( float64 a, float64 b )
+{
+    floatX ax, bx;
+
+    ax = float64ToFloatX( a );
+    bx = float64ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLt( ax, bx );
+
+}
+
+flag slow_float64_eq_signaling( float64 a, float64 b )
+{
+    floatX ax, bx;
+
+    ax = float64ToFloatX( a );
+    bx = float64ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXEq( ax, bx );
+
+}
+
+flag slow_float64_le_quiet( float64 a, float64 b )
+{
+
+    return floatXLe( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+flag slow_float64_lt_quiet( float64 a, float64 b )
+{
+
+    return floatXLt( float64ToFloatX( a ), float64ToFloatX( b ) );
+
+}
+
+#ifdef FLOATX80
+
+int32 slow_floatx80_to_int32( floatx80 a )
+{
+
+    return floatXToInt32( floatx80ToFloatX( a ) );
+
+}
+
+int32 slow_floatx80_to_int32_round_to_zero( floatx80 a )
+{
+    int8 savedRoundingMode;
+    int32 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt32( floatx80ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+int64 slow_floatx80_to_int64( floatx80 a )
+{
+
+    return floatXToInt64( floatx80ToFloatX( a ) );
+
+}
+
+int64 slow_floatx80_to_int64_round_to_zero( floatx80 a )
+{
+    int8 savedRoundingMode;
+    int64 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt64( floatx80ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+float32 slow_floatx80_to_float32( floatx80 a )
+{
+
+    return floatXToFloat32( floatx80ToFloatX( a ) );
+
+}
+
+float64 slow_floatx80_to_float64( floatx80 a )
+{
+
+    return floatXToFloat64( floatx80ToFloatX( a ) );
+
+}
+
+#ifdef FLOAT128
+
+float128 slow_floatx80_to_float128( floatx80 a )
+{
+
+    return floatXToFloat128( floatx80ToFloatX( a ) );
+
+}
+
+#endif
+
+floatx80 slow_floatx80_round_to_int( floatx80 a )
+{
+
+    return floatXToFloatx80( floatXRoundToInt( floatx80ToFloatX( a ) ) );
+
+}
+
+floatx80 slow_floatx80_add( floatx80 a, floatx80 b )
+{
+
+    return
+        floatXToFloatx80(
+            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_sub( floatx80 a, floatx80 b )
+{
+
+    b.high ^= 0x8000;
+    return
+        floatXToFloatx80(
+            floatXAdd( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_mul( floatx80 a, floatx80 b )
+{
+
+    return
+        floatXToFloatx80(
+            floatXMul( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_div( floatx80 a, floatx80 b )
+{
+
+    return
+        floatXToFloatx80(
+            floatXDiv( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_rem( floatx80 a, floatx80 b )
+{
+
+    return
+        floatXToFloatx80(
+            floatXRem( floatx80ToFloatX( a ), floatx80ToFloatX( b ) ) );
+
+}
+
+floatx80 slow_floatx80_sqrt( floatx80 a )
+{
+
+    return floatXToFloatx80( floatXSqrt( floatx80ToFloatX( a ) ) );
+
+}
+
+flag slow_floatx80_eq( floatx80 a, floatx80 b )
+{
+
+    return floatXEq( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
+
+}
+
+flag slow_floatx80_le( floatx80 a, floatx80 b )
+{
+    floatX ax, bx;
+
+    ax = floatx80ToFloatX( a );
+    bx = floatx80ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLe( ax, bx );
+
+}
+
+flag slow_floatx80_lt( floatx80 a, floatx80 b )
+{
+    floatX ax, bx;
+
+    ax = floatx80ToFloatX( a );
+    bx = floatx80ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLt( ax, bx );
+
+}
+
+flag slow_floatx80_eq_signaling( floatx80 a, floatx80 b )
+{
+    floatX ax, bx;
+
+    ax = floatx80ToFloatX( a );
+    bx = floatx80ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXEq( ax, bx );
+
+}
+
+flag slow_floatx80_le_quiet( floatx80 a, floatx80 b )
+{
+
+    return floatXLe( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
+
+}
+
+flag slow_floatx80_lt_quiet( floatx80 a, floatx80 b )
+{
+
+    return floatXLt( floatx80ToFloatX( a ), floatx80ToFloatX( b ) );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+int32 slow_float128_to_int32( float128 a )
+{
+
+    return floatXToInt32( float128ToFloatX( a ) );
+
+}
+
+int32 slow_float128_to_int32_round_to_zero( float128 a )
+{
+    int8 savedRoundingMode;
+    int32 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt32( float128ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+int64 slow_float128_to_int64( float128 a )
+{
+
+    return floatXToInt64( float128ToFloatX( a ) );
+
+}
+
+int64 slow_float128_to_int64_round_to_zero( float128 a )
+{
+    int8 savedRoundingMode;
+    int64 z;
+
+    savedRoundingMode = slow_float_rounding_mode;
+    slow_float_rounding_mode = float_round_to_zero;
+    z = floatXToInt64( float128ToFloatX( a ) );
+    slow_float_rounding_mode = savedRoundingMode;
+    return z;
+
+}
+
+float32 slow_float128_to_float32( float128 a )
+{
+
+    return floatXToFloat32( float128ToFloatX( a ) );
+
+}
+
+float64 slow_float128_to_float64( float128 a )
+{
+
+    return floatXToFloat64( float128ToFloatX( a ) );
+
+}
+
+#ifdef FLOATX80
+
+floatx80 slow_float128_to_floatx80( float128 a )
+{
+
+    return floatXToFloatx80( float128ToFloatX( a ) );
+
+}
+
+#endif
+
+float128 slow_float128_round_to_int( float128 a )
+{
+
+    return floatXToFloat128( floatXRoundToInt( float128ToFloatX( a ) ) );
+
+}
+
+float128 slow_float128_add( float128 a, float128 b )
+{
+
+    return
+        floatXToFloat128(
+            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_sub( float128 a, float128 b )
+{
+
+    b.high ^= LIT64( 0x8000000000000000 );
+    return
+        floatXToFloat128(
+            floatXAdd( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_mul( float128 a, float128 b )
+{
+
+    return
+        floatXToFloat128(
+            floatXMul( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_div( float128 a, float128 b )
+{
+
+    return
+        floatXToFloat128(
+            floatXDiv( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_rem( float128 a, float128 b )
+{
+
+    return
+        floatXToFloat128(
+            floatXRem( float128ToFloatX( a ), float128ToFloatX( b ) ) );
+
+}
+
+float128 slow_float128_sqrt( float128 a )
+{
+
+    return floatXToFloat128( floatXSqrt( float128ToFloatX( a ) ) );
+
+}
+
+flag slow_float128_eq( float128 a, float128 b )
+{
+
+    return floatXEq( float128ToFloatX( a ), float128ToFloatX( b ) );
+
+}
+
+flag slow_float128_le( float128 a, float128 b )
+{
+    floatX ax, bx;
+
+    ax = float128ToFloatX( a );
+    bx = float128ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLe( ax, bx );
+
+}
+
+flag slow_float128_lt( float128 a, float128 b )
+{
+    floatX ax, bx;
+
+    ax = float128ToFloatX( a );
+    bx = float128ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXLt( ax, bx );
+
+}
+
+flag slow_float128_eq_signaling( float128 a, float128 b )
+{
+    floatX ax, bx;
+
+    ax = float128ToFloatX( a );
+    bx = float128ToFloatX( b );
+    if ( ax.isNaN || bx.isNaN ) {
+        slow_float_exception_flags |= float_flag_invalid;
+    }
+    return floatXEq( ax, bx );
+
+}
+
+flag slow_float128_le_quiet( float128 a, float128 b )
+{
+
+    return floatXLe( float128ToFloatX( a ), float128ToFloatX( b ) );
+
+}
+
+flag slow_float128_lt_quiet( float128 a, float128 b )
+{
+
+    return floatXLt( float128ToFloatX( a ), float128ToFloatX( b ) );
+
+}
+
+#endif
+
diff --git a/testfloat/slowfloat.c b/testfloat/slowfloat.c
new file mode 100644
index 00000000000..ea69f82908e
--- /dev/null
+++ b/testfloat/slowfloat.c
@@ -0,0 +1,35 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+#include "slowfloat.h"
+
+#ifdef BITS64
+#include "slowfloat-64.c"
+#else
+#include "slowfloat-32.c"
+#endif
+
diff --git a/testfloat/slowfloat.h b/testfloat/slowfloat.h
new file mode 100644
index 00000000000..45c6c6be00a
--- /dev/null
+++ b/testfloat/slowfloat.h
@@ -0,0 +1,167 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+extern int8 slow_float_rounding_mode;
+extern int8 slow_float_exception_flags;
+extern int8 slow_float_detect_tininess;
+#ifdef FLOATX80
+extern int8 slow_floatx80_rounding_precision;
+#endif
+
+float32 slow_int32_to_float32( int32 );
+float64 slow_int32_to_float64( int32 );
+#ifdef FLOATX80
+floatx80 slow_int32_to_floatx80( int32 );
+#endif
+#ifdef FLOAT128
+float128 slow_int32_to_float128( int32 );
+#endif
+#ifdef BITS64
+float32 slow_int64_to_float32( int64 );
+float64 slow_int64_to_float64( int64 );
+#ifdef FLOATX80
+floatx80 slow_int64_to_floatx80( int64 );
+#endif
+#ifdef FLOAT128
+float128 slow_int64_to_float128( int64 );
+#endif
+#endif
+
+int32 slow_float32_to_int32( float32 );
+int32 slow_float32_to_int32_round_to_zero( float32 );
+#ifdef BITS64
+int64 slow_float32_to_int64( float32 );
+int64 slow_float32_to_int64_round_to_zero( float32 );
+#endif
+float64 slow_float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 slow_float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 slow_float32_to_float128( float32 );
+#endif
+
+float32 slow_float32_round_to_int( float32 );
+float32 slow_float32_add( float32, float32 );
+float32 slow_float32_sub( float32, float32 );
+float32 slow_float32_mul( float32, float32 );
+float32 slow_float32_div( float32, float32 );
+float32 slow_float32_rem( float32, float32 );
+float32 slow_float32_sqrt( float32 );
+flag slow_float32_eq( float32, float32 );
+flag slow_float32_le( float32, float32 );
+flag slow_float32_lt( float32, float32 );
+flag slow_float32_eq_signaling( float32, float32 );
+flag slow_float32_le_quiet( float32, float32 );
+flag slow_float32_lt_quiet( float32, float32 );
+
+int32 slow_float64_to_int32( float64 );
+int32 slow_float64_to_int32_round_to_zero( float64 );
+#ifdef BITS64
+int64 slow_float64_to_int64( float64 );
+int64 slow_float64_to_int64_round_to_zero( float64 );
+#endif
+float32 slow_float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 slow_float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 slow_float64_to_float128( float64 );
+#endif
+
+float64 slow_float64_round_to_int( float64 );
+float64 slow_float64_add( float64, float64 );
+float64 slow_float64_sub( float64, float64 );
+float64 slow_float64_mul( float64, float64 );
+float64 slow_float64_div( float64, float64 );
+float64 slow_float64_rem( float64, float64 );
+float64 slow_float64_sqrt( float64 );
+flag slow_float64_eq( float64, float64 );
+flag slow_float64_le( float64, float64 );
+flag slow_float64_lt( float64, float64 );
+flag slow_float64_eq_signaling( float64, float64 );
+flag slow_float64_le_quiet( float64, float64 );
+flag slow_float64_lt_quiet( float64, float64 );
+
+#ifdef FLOATX80
+
+int32 slow_floatx80_to_int32( floatx80 );
+int32 slow_floatx80_to_int32_round_to_zero( floatx80 );
+#ifdef BITS64
+int64 slow_floatx80_to_int64( floatx80 );
+int64 slow_floatx80_to_int64_round_to_zero( floatx80 );
+#endif
+float32 slow_floatx80_to_float32( floatx80 );
+float64 slow_floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 slow_floatx80_to_float128( floatx80 );
+#endif
+
+floatx80 slow_floatx80_round_to_int( floatx80 );
+floatx80 slow_floatx80_add( floatx80, floatx80 );
+floatx80 slow_floatx80_sub( floatx80, floatx80 );
+floatx80 slow_floatx80_mul( floatx80, floatx80 );
+floatx80 slow_floatx80_div( floatx80, floatx80 );
+floatx80 slow_floatx80_rem( floatx80, floatx80 );
+floatx80 slow_floatx80_sqrt( floatx80 );
+flag slow_floatx80_eq( floatx80, floatx80 );
+flag slow_floatx80_le( floatx80, floatx80 );
+flag slow_floatx80_lt( floatx80, floatx80 );
+flag slow_floatx80_eq_signaling( floatx80, floatx80 );
+flag slow_floatx80_le_quiet( floatx80, floatx80 );
+flag slow_floatx80_lt_quiet( floatx80, floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+int32 slow_float128_to_int32( float128 );
+int32 slow_float128_to_int32_round_to_zero( float128 );
+#ifdef BITS64
+int64 slow_float128_to_int64( float128 );
+int64 slow_float128_to_int64_round_to_zero( float128 );
+#endif
+float32 slow_float128_to_float32( float128 );
+float64 slow_float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 slow_float128_to_floatx80( float128 );
+#endif
+
+float128 slow_float128_round_to_int( float128 );
+float128 slow_float128_add( float128, float128 );
+float128 slow_float128_sub( float128, float128 );
+float128 slow_float128_mul( float128, float128 );
+float128 slow_float128_div( float128, float128 );
+float128 slow_float128_rem( float128, float128 );
+float128 slow_float128_sqrt( float128 );
+flag slow_float128_eq( float128, float128 );
+flag slow_float128_le( float128, float128 );
+flag slow_float128_lt( float128, float128 );
+flag slow_float128_eq_signaling( float128, float128 );
+flag slow_float128_le_quiet( float128, float128 );
+flag slow_float128_lt_quiet( float128, float128 );
+
+#endif
+
diff --git a/testfloat/systemBugs.txt b/testfloat/systemBugs.txt
new file mode 100644
index 00000000000..a0d171a31bb
--- /dev/null
+++ b/testfloat/systemBugs.txt
@@ -0,0 +1,323 @@
+
+Known Floating-point Bugs Detected by TestFloat
+
+John R. Hauser
+1997 December 15
+
+
+-------------------------------------------------------------------------------
+Introduction
+
+Several popular systems have bugs that TestFloat is very likely to run
+across.  The ones I know of are documented here.  First off, TestFloat finds
+no errors in the following processors/machines:
+
+    AMD 486 DX4's
+    Sun UltraSPARC 1's and 2's
+
+On the other hand, bugs are found in these processors/machines:
+
+    Older Intel Pentiums (with the divide bug)
+    Intel Pentium Pros
+    Sun SPARCstation 1's and IPX's
+    Sun SPARCstation 10's
+    HP Precision Architecture processors, with HP-UX prior to version 10.10
+
+For some reason, most of the bugs found involve conversions from floating-
+point to integer formats.
+
+The bugs are shown as actual TestFloat error lines, along with a brief
+explanation.  The error lines given are not necesarily exhaustive and were
+not necessarily output in the order shown.
+
+This document does not pretend to be an authoritative bug listing for all
+commercial processors.  The vast majority of processors are absent from this
+list because I have never run TestFloat on such machines and I thus have no
+knowledge of what bugs TestFloat might find in them.
+
+The latest version of this file can be found at the Web page `http://
+http.cs.berkeley.edu/~jhauser/arithmetic/testfloat.html'.
+
+
+-------------------------------------------------------------------------------
+Older Intel Pentiums (with the divide bug)
+
+The following conversion problems are found on Pentiums that also suffer
+from the infamous floating-point divide bug.  These bugs have been fixed on
+newer Pentiums.  (TestFloat does not find the divide bug.)
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+floatx80_to_int32
+
+-- A few small fractions are treated as though they were zero.
+
+	Errors found in floatx80_to_int32, rounding nearest_even:
+	3FFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	3FFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	3FFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	Errors found in floatx80_to_int32, rounding to_zero:
+	3FFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	3FFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	3FFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	Errors found in floatx80_to_int32, rounding down:
+	3FFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	3FFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	3FFC.C000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFB.8000000000000000  soft: FFFFFFFF ....x  syst: 00000000 .....
+	BFFC.8000000000000000  soft: FFFFFFFF ....x  syst: 00000000 .....
+	BFFC.C000000000000000  soft: FFFFFFFF ....x  syst: 00000000 .....
+	Errors found in floatx80_to_int32, rounding up:
+	3FFB.8000000000000000  soft: 00000001 ....x  syst: 00000000 .....
+	3FFC.8000000000000000  soft: 00000001 ....x  syst: 00000000 .....
+	3FFC.C000000000000000  soft: 00000001 ....x  syst: 00000000 .....
+	BFFB.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+	BFFC.8000000000000000  soft: 00000000 ....x  syst: 00000000 .....
+
+   3FFB.8000000000000000 is the fraction 1/16; 3FFC.8000000000000000 is 1/8;
+   and 3FFC.C000000000000000 is 3/16.  Both positive and negative inputs are
+   affected.
+
+-- Some (all?) positive floating-point values between 2^32 - 1/2
+   (401E.FFFFFFFF00000000) and 2^32 (401F.0000000000000000) are rounded to
+   zero when the rounding mode is nearest/even or up.
+
+	Errors found in floatx80_to_int32, rounding nearest_even:
+	401E.FFFFFFFF80000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFC00001FE  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFF8000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFEC00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFF002000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFC00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFE00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFD7FFE  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFFFFFE  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFFFFFF  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	Errors found in floatx80_to_int32, rounding up:
+	401E.FFFFFFFF00800000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFF80000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFEFFFC000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFC000000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFE7FFFFF  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFF00000  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFE0800  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFF7FFB  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFFFFFE  soft: 7FFFFFFF v....  syst: 00000000 ....x
+	401E.FFFFFFFFFFFFFFFF  soft: 7FFFFFFF v....  syst: 00000000 ....x
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Intel Pentium Pros
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+floatx80_to_int32
+
+-- The inexact flag is sometimes raised instead of the invalid flag for
+   floating-point inputs under -(2^32) (C01F.0000000000000000).  This bug is
+   sporadic.  It appears to be deterministic but dependent on the sequence
+   of operations executed.
+
+	Errors found in floatx80_to_int32, rounding nearest_even:
+	C01F.C000000000000002  soft: 80000000 v....  syst: 80000000 ....x
+	C021.F00000000000003F  soft: 80000000 v....  syst: 80000000 ....x
+	Errors found in floatx80_to_int32, rounding to_zero:
+	C021.F00000000000003F  soft: 80000000 v....  syst: 80000000 ....x
+	Errors found in floatx80_to_int32, rounding up:
+	C01F.C000000000000007  soft: 80000000 v....  syst: 80000000 ....x
+	C01F.C000000000001000  soft: 80000000 v....  syst: 80000000 ....x
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Sun SPARCstation 1's and IPX's
+
+Some older SPARCstations appear confused about whether underflow tininess is
+detected before or after rounding.  For conversions from double precision
+to single precision, tininess is detected after rounding, while for all
+quadruple-precision operations it is detected before rounding.  Single- and
+double-precision multipies go both ways:
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float32_mul, float64_mul
+
+-- For multiplies, underflow tininess is detected _before_ rounding if one
+   of the inputs is subnormal, and _after_ rounding otherwise.  If tininess
+   is assumed to be detected before rounding, the following errors are
+   generated:
+
+	Errors found in float32_mul, rounding nearest_even:
+	001.000001  07E.7FFFFE  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	001.000001  87E.7FFFFE  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	001.000002  07E.7FFFFC  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	001.000002  87E.7FFFFC  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	001.000004  07E.7FFFF8  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	Errors found in float32_mul, rounding down:
+	001.000001  87E.7FFFFE  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	001.000002  87E.7FFFFC  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	001.000004  87E.7FFFF8  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	001.000008  87E.7FFFF0  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	001.000010  87E.7FFFE0  soft: 801.000000 ...ux  syst: 801.000000 ....x
+	Errors found in float32_mul, rounding up:
+	001.000001  07E.7FFFFE  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	001.000002  07E.7FFFFC  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	001.000004  07E.7FFFF8  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	001.000008  07E.7FFFF0  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	001.000010  07E.7FFFE0  soft: 001.000000 ...ux  syst: 001.000000 ....x
+	Errors found in float64_mul, rounding nearest_even:
+	001.0000000000001  3FE.FFFFFFFFFFFFE
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	001.0000000000001  BFE.FFFFFFFFFFFFE
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	001.0000000000002  3FE.FFFFFFFFFFFFC
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	001.0000000000002  BFE.FFFFFFFFFFFFC
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	001.0000000000004  3FE.FFFFFFFFFFFF8
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	Errors found in float64_mul, rounding down:
+	001.0000000000001  BFE.FFFFFFFFFFFFE
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	001.0000000000002  BFE.FFFFFFFFFFFFC
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	001.0000000000004  BFE.FFFFFFFFFFFF8
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	001.0000000000008  BFE.FFFFFFFFFFFF0
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	001.0000000000010  BFE.FFFFFFFFFFFE0
+		soft: 801.0000000000000 ...ux  syst: 801.0000000000000 ....x
+	Errors found in float64_mul, rounding up:
+	001.0000000000001  3FE.FFFFFFFFFFFFE
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	001.0000000000002  3FE.FFFFFFFFFFFFC
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	001.0000000000004  3FE.FFFFFFFFFFFF8
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	001.0000000000008  3FE.FFFFFFFFFFFF0
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+	001.0000000000010  3FE.FFFFFFFFFFFE0
+		soft: 001.0000000000000 ...ux  syst: 001.0000000000000 ....x
+
+   If we assume tininess should be detected after rounding, we get the
+   following errors:
+
+	Errors found in float32_mul, rounding nearest_even:
+	000.7FFC00  07F.000400  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	000.7FFC00  87F.000400  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	000.7FFE00  07F.000200  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	000.7FFE00  87F.000200  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	000.7FFF00  07F.000100  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	Errors found in float32_mul, rounding down:
+	000.7FFC00  87F.000400  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	000.7FFE00  87F.000200  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	000.7FFF00  87F.000100  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	000.7FFF80  87F.000080  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	000.7FFFC0  87F.000040  soft: 801.000000 ....x  syst: 801.000000 ...ux
+	Errors found in float32_mul, rounding up:
+	000.7FFC00  07F.000400  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	000.7FFE00  07F.000200  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	000.7FFF00  07F.000100  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	000.7FFF80  07F.000080  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	000.7FFFC0  07F.000040  soft: 001.000000 ....x  syst: 001.000000 ...ux
+	Errors found in float64_mul, rounding nearest_even:
+	000.FFFFFFE000000  3FF.0000002000000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	000.FFFFFFE000000  BFF.0000002000000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	000.FFFFFFF000000  3FF.0000001000000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	000.FFFFFFF000000  BFF.0000001000000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	000.FFFFFFF800000  3FF.0000000800000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	Errors found in float64_mul, rounding down:
+	000.FFFFFFE000000  BFF.0000002000000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	000.FFFFFFF000000  BFF.0000001000000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	000.FFFFFFF800000  BFF.0000000800000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	000.FFFFFFFC00000  BFF.0000000400000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	000.FFFFFFFE00000  BFF.0000000200000
+		soft: 801.0000000000000 ....x  syst: 801.0000000000000 ...ux
+	Errors found in float64_mul, rounding up:
+	000.FFFFFFE000000  3FF.0000002000000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	000.FFFFFFF000000  3FF.0000001000000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	000.FFFFFFF800000  3FF.0000000800000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	000.FFFFFFFC00000  3FF.0000000400000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+	000.FFFFFFFE00000  3FF.0000000200000
+		soft: 001.0000000000000 ....x  syst: 001.0000000000000 ...ux
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Sun SPARCstation 10's
+
+Like other SPARCstations, some SPARCstation 10's are inconsistent regarding
+underflow tininess, detecting it after rounding for single- and double-
+precision operations and before rounding for quadruple-precision operations.
+The following bug has also been observed.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float32_to_int32_round_to_zero, float64_to_int32_round_to_zero
+
+-- Single- and double-precision NaNs are converted to the integer zero.
+   (The invalid exception flag is raised correctly.)
+
+	Errors found in float32_to_int32_round_to_zero:
+	8FF.5D36AC  soft: 7FFFFFFF v....  syst: 00000000 v....
+	0FF.7FFFC0  soft: 7FFFFFFF v....  syst: 00000000 v....
+	8FF.7C0000  soft: 7FFFFFFF v....  syst: 00000000 v....
+	0FF.2AB7ED  soft: 7FFFFFFF v....  syst: 00000000 v....
+	0FF.03FFFF  soft: 7FFFFFFF v....  syst: 00000000 v....
+	Errors found in float64_to_int32_round_to_zero:
+	7FF.45AD84DB2524A  soft: 7FFFFFFF v....  syst: 00000000 v....
+	7FF.CFEE063EE0512  soft: 7FFFFFFF v....  syst: 00000000 v....
+	7FF.89FF03AB7DBA2  soft: 7FFFFFFF v....  syst: 00000000 v....
+	7FF.FFFFFFFFFF800  soft: 7FFFFFFF v....  syst: 00000000 v....
+	FFF.68A6410E91BF6  soft: 7FFFFFFF v....  syst: 00000000 v....
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+HP Precision Architecture processors, with HP-UX prior to version 10.10
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+float32_to_int32_round_to_zero, float64_to_int32_round_to_zero
+
+-- When the floating-point value is too large, the overflow and inexact
+   exception flags are raised instead of the invalid flag.
+
+	Errors found in float32_to_int32_round_to_zero:
+	89E.000007  soft: 80000000 v....  syst: 80000000 ..o.x
+	0A2.000020  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
+	8FA.7C0000  soft: 80000000 v....  syst: 80000000 ..o.x
+	Errors found in float64_to_int32_round_to_zero:
+	7FD.0448700002F1C  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
+	DAA.F000000000000  soft: 80000000 v....  syst: 80000000 ..o.x
+	41E.063DA00005E65  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
+	47E.FFFF800000000  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
+	51F.0000000000004  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
+	DDA.0000001FFFFFF  soft: 80000000 v....  syst: 80000000 ..o.x
+	D70.00000000003FF  soft: 80000000 v....  syst: 80000000 ..o.x
+	C7E.0000100000000  soft: 80000000 v....  syst: 80000000 ..o.x
+	47E.000000000007F  soft: 7FFFFFFF v....  syst: 7FFFFFFF ..o.x
+	D57.000000000FFFF  soft: 80000000 v....  syst: 80000000 ..o.x
+
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
diff --git a/testfloat/systflags.h b/testfloat/systflags.h
new file mode 100644
index 00000000000..23e6b236472
--- /dev/null
+++ b/testfloat/systflags.h
@@ -0,0 +1,33 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Target-specific function for clearing the system's IEC/IEEE floating-point
+exception flags.  The previous value of the flags is returned.
+-------------------------------------------------------------------------------
+*/
+int8 syst_float_flags_clear( void );
+
diff --git a/testfloat/systfloat.c b/testfloat/systfloat.c
new file mode 100644
index 00000000000..08548c4981e
--- /dev/null
+++ b/testfloat/systfloat.c
@@ -0,0 +1,553 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include "milieu.h"
+#include "softfloat.h"
+#include "systfloat.h"
+
+float32 syst_int32_to_float32( int32 a )
+{
+    float32 z;
+
+    *( (float *) &z ) = a;
+    return z;
+
+}
+
+float64 syst_int32_to_float64( int32 a )
+{
+    float64 z;
+
+    *( (double *) &z ) = a;
+    return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_int32_to_floatx80( int32 a )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) = a;
+    return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_int32_to_float128( int32 a )
+{
+    float128 z;
+
+    *( (long double *) &z ) = a;
+    return z;
+
+}
+
+#endif
+
+#ifdef BITS64
+
+float32 syst_int64_to_float32( int64 a )
+{
+    float32 z;
+
+    *( (float *) &z ) = a;
+    return z;
+
+}
+
+float64 syst_int64_to_float64( int64 a )
+{
+    float64 z;
+
+    *( (double *) &z ) = a;
+    return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_int64_to_floatx80( int64 a )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) = a;
+    return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_int64_to_float128( int64 a )
+{
+    float128 z;
+
+    *( (long double *) &z ) = a;
+    return z;
+
+}
+
+#endif
+
+#endif
+
+int32 syst_float32_to_int32_round_to_zero( float32 a )
+{
+
+    return *( (float *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_float32_to_int64_round_to_zero( float32 a )
+{
+
+    return *( (float *) &a );
+
+}
+
+#endif
+
+float64 syst_float32_to_float64( float32 a )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (float *) &a );
+    return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_float32_to_floatx80( float32 a )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) = *( (float *) &a );
+    return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_float32_to_float128( float32 a )
+{
+    float128 z;
+
+    *( (long double *) &z ) = *( (float *) &a );
+    return z;
+
+}
+
+#endif
+
+float32 syst_float32_add( float32 a, float32 b )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (float *) &a ) + *( (float *) &b );
+    return z;
+
+}
+
+float32 syst_float32_sub( float32 a, float32 b )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (float *) &a ) - *( (float *) &b );
+    return z;
+
+}
+
+float32 syst_float32_mul( float32 a, float32 b )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (float *) &a ) * *( (float *) &b );
+    return z;
+
+}
+
+float32 syst_float32_div( float32 a, float32 b )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (float *) &a ) / *( (float *) &b );
+    return z;
+
+}
+
+flag syst_float32_eq( float32 a, float32 b )
+{
+
+    return ( *( (float *) &a ) == *( (float *) &b ) );
+
+}
+
+flag syst_float32_le( float32 a, float32 b )
+{
+
+    return ( *( (float *) &a ) <= *( (float *) &b ) );
+
+}
+
+flag syst_float32_lt( float32 a, float32 b )
+{
+
+    return ( *( (float *) &a ) < *( (float *) &b ) );
+
+}
+
+int32 syst_float64_to_int32_round_to_zero( float64 a )
+{
+
+    return *( (double *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_float64_to_int64_round_to_zero( float64 a )
+{
+
+    return *( (double *) &a );
+
+}
+
+#endif
+
+float32 syst_float64_to_float32( float64 a )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (double *) &a );
+    return z;
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+floatx80 syst_float64_to_floatx80( float64 a )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) = *( (double *) &a );
+    return z;
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+float128 syst_float64_to_float128( float64 a )
+{
+    float128 z;
+
+    *( (long double *) &z ) = *( (double *) &a );
+    return z;
+
+}
+
+#endif
+
+float64 syst_float64_add( float64 a, float64 b )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (double *) &a ) + *( (double *) &b );
+    return z;
+
+}
+
+float64 syst_float64_sub( float64 a, float64 b )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (double *) &a ) - *( (double *) &b );
+    return z;
+
+}
+
+float64 syst_float64_mul( float64 a, float64 b )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (double *) &a ) * *( (double *) &b );
+    return z;
+
+}
+
+float64 syst_float64_div( float64 a, float64 b )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (double *) &a ) / *( (double *) &b );
+    return z;
+
+}
+
+float64 syst_float64_sqrt( float64 a )
+{
+    float64 z;
+
+    *( (double *) &z ) = sqrt( *( (double *) &a ) );
+    return z;
+
+}
+
+flag syst_float64_eq( float64 a, float64 b )
+{
+
+    return ( *( (double *) &a ) == *( (double *) &b ) );
+
+}
+
+flag syst_float64_le( float64 a, float64 b )
+{
+
+    return ( *( (double *) &a ) <= *( (double *) &b ) );
+
+}
+
+flag syst_float64_lt( float64 a, float64 b )
+{
+
+    return ( *( (double *) &a ) < *( (double *) &b ) );
+
+}
+
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+
+int32 syst_floatx80_to_int32_round_to_zero( floatx80 a )
+{
+
+    return *( (long double *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_floatx80_to_int64_round_to_zero( floatx80 a )
+{
+
+    return *( (long double *) &a );
+
+}
+
+#endif
+
+float32 syst_floatx80_to_float32( floatx80 a )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (long double *) &a );
+    return z;
+
+}
+
+float64 syst_floatx80_to_float64( floatx80 a )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (long double *) &a );
+    return z;
+
+}
+
+floatx80 syst_floatx80_add( floatx80 a, floatx80 b )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) + *( (long double *) &b );
+    return z;
+
+}
+
+floatx80 syst_floatx80_sub( floatx80 a, floatx80 b )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) - *( (long double *) &b );
+    return z;
+
+}
+
+floatx80 syst_floatx80_mul( floatx80 a, floatx80 b )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) * *( (long double *) &b );
+    return z;
+
+}
+
+floatx80 syst_floatx80_div( floatx80 a, floatx80 b )
+{
+    floatx80 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) / *( (long double *) &b );
+    return z;
+
+}
+
+flag syst_floatx80_eq( floatx80 a, floatx80 b )
+{
+
+    return ( *( (long double *) &a ) == *( (long double *) &b ) );
+
+}
+
+flag syst_floatx80_le( floatx80 a, floatx80 b )
+{
+
+    return ( *( (long double *) &a ) <= *( (long double *) &b ) );
+
+}
+
+flag syst_floatx80_lt( floatx80 a, floatx80 b )
+{
+
+    return ( *( (long double *) &a ) < *( (long double *) &b ) );
+
+}
+
+#endif
+
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+
+int32 syst_float128_to_int32_round_to_zero( float128 a )
+{
+
+    return *( (long double *) &a );
+
+}
+
+#ifdef BITS64
+
+int64 syst_float128_to_int64_round_to_zero( float128 a )
+{
+
+    return *( (long double *) &a );
+
+}
+
+#endif
+
+float32 syst_float128_to_float32( float128 a )
+{
+    float32 z;
+
+    *( (float *) &z ) = *( (long double *) &a );
+    return z;
+
+}
+
+float64 syst_float128_to_float64( float128 a )
+{
+    float64 z;
+
+    *( (double *) &z ) = *( (long double *) &a );
+    return z;
+
+}
+
+float128 syst_float128_add( float128 a, float128 b )
+{
+    float128 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) + *( (long double *) &b );
+    return z;
+
+}
+
+float128 syst_float128_sub( float128 a, float128 b )
+{
+    float128 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) - *( (long double *) &b );
+    return z;
+
+}
+
+float128 syst_float128_mul( float128 a, float128 b )
+{
+    float128 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) * *( (long double *) &b );
+    return z;
+
+}
+
+float128 syst_float128_div( float128 a, float128 b )
+{
+    float128 z;
+
+    *( (long double *) &z ) =
+        *( (long double *) &a ) / *( (long double *) &b );
+    return z;
+
+}
+
+flag syst_float128_eq( float128 a, float128 b )
+{
+
+    return ( *( (long double *) &a ) == *( (long double *) &b ) );
+
+}
+
+flag syst_float128_le( float128 a, float128 b )
+{
+
+    return ( *( (long double *) &a ) <= *( (long double *) &b ) );
+
+}
+
+flag syst_float128_lt( float128 a, float128 b )
+{
+
+    return ( *( (long double *) &a ) < *( (long double *) &b ) );
+
+}
+
+#endif
+
diff --git a/testfloat/systfloat.h b/testfloat/systfloat.h
new file mode 100644
index 00000000000..88f0dc40498
--- /dev/null
+++ b/testfloat/systfloat.h
@@ -0,0 +1,233 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+The following macros are defined to indicate that the corresponding
+functions exist.
+-------------------------------------------------------------------------------
+*/
+#define SYST_INT32_TO_FLOAT32
+#define SYST_INT32_TO_FLOAT64
+#ifdef BITS64
+#define SYST_INT64_TO_FLOAT32
+#define SYST_INT64_TO_FLOAT64
+#endif
+#define SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+#ifdef BITS64
+#define SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
+#endif
+#define SYST_FLOAT32_TO_FLOAT64
+#define SYST_FLOAT32_ADD
+#define SYST_FLOAT32_SUB
+#define SYST_FLOAT32_MUL
+#define SYST_FLOAT32_DIV
+#define SYST_FLOAT32_EQ
+#define SYST_FLOAT32_LE
+#define SYST_FLOAT32_LT
+#define SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+#ifdef BITS64
+#define SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
+#endif
+#define SYST_FLOAT64_TO_FLOAT32
+#define SYST_FLOAT64_ADD
+#define SYST_FLOAT64_SUB
+#define SYST_FLOAT64_MUL
+#define SYST_FLOAT64_DIV
+#define SYST_FLOAT64_SQRT
+#define SYST_FLOAT64_EQ
+#define SYST_FLOAT64_LE
+#define SYST_FLOAT64_LT
+#if defined( FLOATX80 ) && defined( LONG_DOUBLE_IS_FLOATX80 )
+#define SYST_INT32_TO_FLOATX80
+#ifdef BITS64
+#define SYST_INT64_TO_FLOATX80
+#endif
+#define SYST_FLOAT32_TO_FLOATX80
+#define SYST_FLOAT64_TO_FLOATX80
+#define SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
+#ifdef BITS64
+#define SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
+#endif
+#define SYST_FLOATX80_TO_FLOAT32
+#define SYST_FLOATX80_TO_FLOAT64
+#define SYST_FLOATX80_ADD
+#define SYST_FLOATX80_SUB
+#define SYST_FLOATX80_MUL
+#define SYST_FLOATX80_DIV
+#define SYST_FLOATX80_EQ
+#define SYST_FLOATX80_LE
+#define SYST_FLOATX80_LT
+#endif
+#if defined( FLOAT128 ) && defined( LONG_DOUBLE_IS_FLOAT128 )
+#define SYST_INT32_TO_FLOAT128
+#ifdef BITS64
+#define SYST_INT64_TO_FLOAT128
+#endif
+#define SYST_FLOAT32_TO_FLOAT128
+#define SYST_FLOAT64_TO_FLOAT128
+#define SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+#ifdef BITS64
+#define SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
+#endif
+#define SYST_FLOAT128_TO_FLOAT32
+#define SYST_FLOAT128_TO_FLOAT64
+#define SYST_FLOAT128_ADD
+#define SYST_FLOAT128_SUB
+#define SYST_FLOAT128_MUL
+#define SYST_FLOAT128_DIV
+#define SYST_FLOAT128_EQ
+#define SYST_FLOAT128_LE
+#define SYST_FLOAT128_LT
+#endif
+
+/*
+-------------------------------------------------------------------------------
+System function declarations.  (Some of these functions may not exist.)
+-------------------------------------------------------------------------------
+*/
+float32 syst_int32_to_float32( int32 );
+float64 syst_int32_to_float64( int32 );
+#ifdef FLOATX80
+floatx80 syst_int32_to_floatx80( int32 );
+#endif
+#ifdef FLOAT128
+float128 syst_int32_to_float128( int32 );
+#endif
+#ifdef BITS64
+float32 syst_int64_to_float32( int64 );
+float64 syst_int64_to_float64( int64 );
+#ifdef FLOATX80
+floatx80 syst_int64_to_floatx80( int64 );
+#endif
+#ifdef FLOAT128
+float128 syst_int64_to_float128( int64 );
+#endif
+#endif
+int32 syst_float32_to_int32( float32 );
+int32 syst_float32_to_int32_round_to_zero( float32 );
+#ifdef BITS64
+int64 syst_float32_to_int64( float32 );
+int64 syst_float32_to_int64_round_to_zero( float32 );
+#endif
+float64 syst_float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 syst_float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 syst_float32_to_float128( float32 );
+#endif
+float32 syst_float32_round_to_int( float32 );
+float32 syst_float32_add( float32, float32 );
+float32 syst_float32_sub( float32, float32 );
+float32 syst_float32_mul( float32, float32 );
+float32 syst_float32_div( float32, float32 );
+float32 syst_float32_rem( float32, float32 );
+float32 syst_float32_sqrt( float32 );
+flag syst_float32_eq( float32, float32 );
+flag syst_float32_le( float32, float32 );
+flag syst_float32_lt( float32, float32 );
+flag syst_float32_eq_signaling( float32, float32 );
+flag syst_float32_le_quiet( float32, float32 );
+flag syst_float32_lt_quiet( float32, float32 );
+int32 syst_float64_to_int32( float64 );
+int32 syst_float64_to_int32_round_to_zero( float64 );
+#ifdef BITS64
+int64 syst_float64_to_int64( float64 );
+int64 syst_float64_to_int64_round_to_zero( float64 );
+#endif
+float32 syst_float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 syst_float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 syst_float64_to_float128( float64 );
+#endif
+float64 syst_float64_round_to_int( float64 );
+float64 syst_float64_add( float64, float64 );
+float64 syst_float64_sub( float64, float64 );
+float64 syst_float64_mul( float64, float64 );
+float64 syst_float64_div( float64, float64 );
+float64 syst_float64_rem( float64, float64 );
+float64 syst_float64_sqrt( float64 );
+flag syst_float64_eq( float64, float64 );
+flag syst_float64_le( float64, float64 );
+flag syst_float64_lt( float64, float64 );
+flag syst_float64_eq_signaling( float64, float64 );
+flag syst_float64_le_quiet( float64, float64 );
+flag syst_float64_lt_quiet( float64, float64 );
+#ifdef FLOATX80
+int32 syst_floatx80_to_int32( floatx80 );
+int32 syst_floatx80_to_int32_round_to_zero( floatx80 );
+#ifdef BITS64
+int64 syst_floatx80_to_int64( floatx80 );
+int64 syst_floatx80_to_int64_round_to_zero( floatx80 );
+#endif
+float32 syst_floatx80_to_float32( floatx80 );
+float64 syst_floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 syst_floatx80_to_float128( floatx80 );
+#endif
+floatx80 syst_floatx80_round_to_int( floatx80 );
+floatx80 syst_floatx80_add( floatx80, floatx80 );
+floatx80 syst_floatx80_sub( floatx80, floatx80 );
+floatx80 syst_floatx80_mul( floatx80, floatx80 );
+floatx80 syst_floatx80_div( floatx80, floatx80 );
+floatx80 syst_floatx80_rem( floatx80, floatx80 );
+floatx80 syst_floatx80_sqrt( floatx80 );
+flag syst_floatx80_eq( floatx80, floatx80 );
+flag syst_floatx80_le( floatx80, floatx80 );
+flag syst_floatx80_lt( floatx80, floatx80 );
+flag syst_floatx80_eq_signaling( floatx80, floatx80 );
+flag syst_floatx80_le_quiet( floatx80, floatx80 );
+flag syst_floatx80_lt_quiet( floatx80, floatx80 );
+#endif
+#ifdef FLOAT128
+int32 syst_float128_to_int32( float128 );
+int32 syst_float128_to_int32_round_to_zero( float128 );
+#ifdef BITS64
+int64 syst_float128_to_int64( float128 );
+int64 syst_float128_to_int64_round_to_zero( float128 );
+#endif
+float32 syst_float128_to_float32( float128 );
+float64 syst_float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 syst_float128_to_floatx80( float128 );
+#endif
+float128 syst_float128_round_to_int( float128 );
+float128 syst_float128_add( float128, float128 );
+float128 syst_float128_sub( float128, float128 );
+float128 syst_float128_mul( float128, float128 );
+float128 syst_float128_div( float128, float128 );
+float128 syst_float128_rem( float128, float128 );
+float128 syst_float128_sqrt( float128 );
+flag syst_float128_eq( float128, float128 );
+flag syst_float128_le( float128, float128 );
+flag syst_float128_lt( float128, float128 );
+flag syst_float128_eq_signaling( float128, float128 );
+flag syst_float128_le_quiet( float128, float128 );
+flag syst_float128_lt_quiet( float128, float128 );
+#endif
+
diff --git a/testfloat/systmodes.h b/testfloat/systmodes.h
new file mode 100644
index 00000000000..b2befa4ad59
--- /dev/null
+++ b/testfloat/systmodes.h
@@ -0,0 +1,42 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Target-specific function for setting the system's IEC/IEEE floating-point
+rounding mode.  Other system modes are also initialized as necessary (for
+example, exception trapping may be disabled).
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_mode( int8 );
+
+/*
+-------------------------------------------------------------------------------
+Target-specific function for setting the IEC/IEEE rounding precision of
+subsequent extended double-precision operations performed by the system.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_precision( int8 );
+
diff --git a/testfloat/templates/Makefile b/testfloat/templates/Makefile
new file mode 100644
index 00000000000..f5f3cde713c
--- /dev/null
+++ b/testfloat/templates/Makefile
@@ -0,0 +1,67 @@
+
+PROCESSOR_H = ../../processors/!!!processor.h
+SOFTFLOAT_VERSION = bits64
+TARGET = !!!target
+SOFTFLOAT_DIR = ../../softfloat/$(SOFTFLOAT_VERSION)/$(TARGET)
+
+OBJ = .o
+EXE =
+INCLUDES = -I. -I.. -I$(SOFTFLOAT_DIR)
+COMPILE_C = gcc -c -o $@ $(INCLUDES) -I- -O2
+COMPILE_SLOWFLOAT_C = gcc -c -o $@ $(INCLUDES) -I- -O3
+LINK = gcc -o $@
+
+SOFTFLOAT_H = $(SOFTFLOAT_DIR)/softfloat.h
+SOFTFLOAT_OBJ = $(SOFTFLOAT_DIR)/softfloat$(OBJ)
+
+ALL: testsoftfloat$(EXE) testfloat$(EXE)
+
+systmodes$(OBJ): milieu.h ../systmodes.h systmodes.c
+	$(COMPILE_C) systmodes.c
+
+systflags$(OBJ): milieu.h ../systflags.h systflags.c
+	$(COMPILE_C) systflags.c
+
+systfloat$(OBJ): milieu.h $(SOFTFLOAT_H) ../systfloat.h ../systfloat.c
+	$(COMPILE_C) ../systfloat.c
+
+#------------------------------------------------------------------------------
+# Probably O.K. below here.
+#------------------------------------------------------------------------------
+
+milieu.h: $(PROCESSOR_H)
+	touch milieu.h
+
+fail$(OBJ): milieu.h ../fail.h
+	$(COMPILE_C) ../fail.c
+
+random$(OBJ): milieu.h ../random.h
+	$(COMPILE_C) ../random.c
+
+testCases$(OBJ): milieu.h ../fail.h ../random.h $(SOFTFLOAT_H) ../testCases.h ../testCases.c
+	$(COMPILE_C) ../testCases.c
+
+writeHex$(OBJ): milieu.h $(SOFTFLOAT_H) ../writeHex.h ../writeHex.c
+	$(COMPILE_C) ../writeHex.c
+
+testLoops$(OBJ): milieu.h $(SOFTFLOAT_H) ../testCases.h ../writeHex.h ../testLoops.h ../testLoops.c
+	$(COMPILE_C) ../testLoops.c
+
+slowfloat$(OBJ): milieu.h $(SOFTFLOAT_H) ../slowfloat.h ../slowfloat-32.c ../slowfloat-64.c ../slowfloat.c
+	$(COMPILE_SLOWFLOAT_C) ../slowfloat.c
+
+testsoftfloat$(OBJ): milieu.h ../fail.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../slowfloat.h ../testsoftfloat.c
+	$(COMPILE_C) ../testsoftfloat.c
+
+testsoftfloat$(EXE): fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) slowfloat$(OBJ) testsoftfloat$(OBJ)
+	$(LINK) fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) slowfloat$(OBJ) testsoftfloat$(OBJ)
+
+testFunction$(OBJ): milieu.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../systmodes.h ../systflags.h systfloat.h ../testFunction.h ../testFunction.c
+	$(COMPILE_C) ../testFunction.c
+
+testfloat$(OBJ): milieu.h ../fail.h $(SOFTFLOAT_H) ../testCases.h ../testLoops.h ../systflags.h ../testFunction.h testfloat.c
+	$(COMPILE_C) testfloat.c
+
+testfloat$(EXE): fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) systmodes$(OBJ) systflags$(OBJ) systfloat$(OBJ) testFunction$(OBJ) testfloat$(OBJ)
+	$(LINK) fail$(OBJ) random$(OBJ) $(SOFTFLOAT_OBJ) testCases$(OBJ) writeHex$(OBJ) testLoops$(OBJ) systmodes$(OBJ) systflags$(OBJ) systfloat$(OBJ) testFunction$(OBJ) testfloat$(OBJ)
+
diff --git a/testfloat/templates/milieu.h b/testfloat/templates/milieu.h
new file mode 100644
index 00000000000..56d3ac49a9a
--- /dev/null
+++ b/testfloat/templates/milieu.h
@@ -0,0 +1,62 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "../../processors/!!!processor.h"
+
+/*
+-------------------------------------------------------------------------------
+If the `BITS64' macro is defined by the processor header file but the
+version of SoftFloat being used/tested is the 32-bit one (`bits32'), the
+`BITS64' macro must be undefined here.
+-------------------------------------------------------------------------------
+#undef BITS64
+*/
+
+/*
+-------------------------------------------------------------------------------
+The macro `LONG_DOUBLE_IS_FLOATX80' can be defined to indicate that the
+C compiler supports the type `long double' as an extended double-precision
+format.  Alternatively, the macro `LONG_DOUBLE_IS_FLOAT128' can be defined
+to indicate that `long double' is a quadruple-precision format.  If neither
+of these macros is defined, `long double' will be ignored.
+-------------------------------------------------------------------------------
+#define LONG_DOUBLE_IS_FLOATX80
+*/
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+    FALSE = 0,
+    TRUE  = 1
+};
+
diff --git a/testfloat/templates/systflags.c b/testfloat/templates/systflags.c
new file mode 100644
index 00000000000..3eb86c1ade8
--- /dev/null
+++ b/testfloat/templates/systflags.c
@@ -0,0 +1,41 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "systflags.h"
+
+/*
+-------------------------------------------------------------------------------
+Clears the system's IEC/IEEE floating-point exception flags.  Returns the
+previous value of the flags.
+-------------------------------------------------------------------------------
+*/
+int8 syst_float_flags_clear( void )
+{
+
+    !!!code
+
+}
+
diff --git a/testfloat/templates/systmodes.c b/testfloat/templates/systmodes.c
new file mode 100644
index 00000000000..49450ab258b
--- /dev/null
+++ b/testfloat/templates/systmodes.c
@@ -0,0 +1,58 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "systmodes.h"
+
+/*
+-------------------------------------------------------------------------------
+Sets the system's IEC/IEEE floating-point rounding mode.  Also disables all
+system exception traps.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_mode( int8 roundingMode )
+{
+
+    !!!code
+
+}
+
+/*
+-------------------------------------------------------------------------------
+Sets the rounding precision of subsequent extended double-precision
+operations.  The `precision' argument should be one of 0, 32, 64, or 80.
+If `precision' is 32, the rounding precision is set equivalent to single
+precision; else if `precision' is 64, the rounding precision is set
+equivalent to double precision; else the rounding precision is set to full
+extended double precision.
+-------------------------------------------------------------------------------
+*/
+void syst_float_set_rounding_precision( int8 precision )
+{
+
+    !!!code (possibly empty)
+
+}
+
diff --git a/testfloat/testCases.c b/testfloat/testCases.c
new file mode 100644
index 00000000000..44676306af3
--- /dev/null
+++ b/testfloat/testCases.c
@@ -0,0 +1,3679 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "fail.h"
+#include "random.h"
+#include "softfloat.h"
+#include "testCases.h"
+
+typedef struct {
+    int16 expNum, term1Num, term2Num;
+    flag done;
+} sequenceT;
+
+enum {
+    int32NumP1 = 124
+};
+
+static const uint32 int32P1[ int32NumP1 ] = {
+    0x00000000,
+    0x00000001,
+    0x00000002,
+    0x00000004,
+    0x00000008,
+    0x00000010,
+    0x00000020,
+    0x00000040,
+    0x00000080,
+    0x00000100,
+    0x00000200,
+    0x00000400,
+    0x00000800,
+    0x00001000,
+    0x00002000,
+    0x00004000,
+    0x00008000,
+    0x00010000,
+    0x00020000,
+    0x00040000,
+    0x00080000,
+    0x00100000,
+    0x00200000,
+    0x00400000,
+    0x00800000,
+    0x01000000,
+    0x02000000,
+    0x04000000,
+    0x08000000,
+    0x10000000,
+    0x20000000,
+    0x40000000,
+    0x80000000,
+    0xC0000000,
+    0xE0000000,
+    0xF0000000,
+    0xF8000000,
+    0xFC000000,
+    0xFE000000,
+    0xFF000000,
+    0xFF800000,
+    0xFFC00000,
+    0xFFE00000,
+    0xFFF00000,
+    0xFFF80000,
+    0xFFFC0000,
+    0xFFFE0000,
+    0xFFFF0000,
+    0xFFFF8000,
+    0xFFFFC000,
+    0xFFFFE000,
+    0xFFFFF000,
+    0xFFFFF800,
+    0xFFFFFC00,
+    0xFFFFFE00,
+    0xFFFFFF00,
+    0xFFFFFF80,
+    0xFFFFFFC0,
+    0xFFFFFFE0,
+    0xFFFFFFF0,
+    0xFFFFFFF8,
+    0xFFFFFFFC,
+    0xFFFFFFFE,
+    0xFFFFFFFF,
+    0xFFFFFFFD,
+    0xFFFFFFFB,
+    0xFFFFFFF7,
+    0xFFFFFFEF,
+    0xFFFFFFDF,
+    0xFFFFFFBF,
+    0xFFFFFF7F,
+    0xFFFFFEFF,
+    0xFFFFFDFF,
+    0xFFFFFBFF,
+    0xFFFFF7FF,
+    0xFFFFEFFF,
+    0xFFFFDFFF,
+    0xFFFFBFFF,
+    0xFFFF7FFF,
+    0xFFFEFFFF,
+    0xFFFDFFFF,
+    0xFFFBFFFF,
+    0xFFF7FFFF,
+    0xFFEFFFFF,
+    0xFFDFFFFF,
+    0xFFBFFFFF,
+    0xFF7FFFFF,
+    0xFEFFFFFF,
+    0xFDFFFFFF,
+    0xFBFFFFFF,
+    0xF7FFFFFF,
+    0xEFFFFFFF,
+    0xDFFFFFFF,
+    0xBFFFFFFF,
+    0x7FFFFFFF,
+    0x3FFFFFFF,
+    0x1FFFFFFF,
+    0x0FFFFFFF,
+    0x07FFFFFF,
+    0x03FFFFFF,
+    0x01FFFFFF,
+    0x00FFFFFF,
+    0x007FFFFF,
+    0x003FFFFF,
+    0x001FFFFF,
+    0x000FFFFF,
+    0x0007FFFF,
+    0x0003FFFF,
+    0x0001FFFF,
+    0x0000FFFF,
+    0x00007FFF,
+    0x00003FFF,
+    0x00001FFF,
+    0x00000FFF,
+    0x000007FF,
+    0x000003FF,
+    0x000001FF,
+    0x000000FF,
+    0x0000007F,
+    0x0000003F,
+    0x0000001F,
+    0x0000000F,
+    0x00000007,
+    0x00000003
+};
+
+static int32 int32NextP1( sequenceT *sequencePtr )
+{
+    uint8 termNum;
+    int32 z;
+
+    termNum = sequencePtr->term1Num;
+    z = int32P1[ termNum ];
+    ++termNum;
+    if ( int32NumP1 <= termNum ) {
+        termNum = 0;
+        sequencePtr->done = TRUE;
+    }
+    sequencePtr->term1Num = termNum;
+    return (sbits32) z;
+
+}
+
+static const int32 int32NumP2 = ( int32NumP1 * int32NumP1 + int32NumP1 ) / 2;
+
+static int32 int32NextP2( sequenceT *sequencePtr )
+{
+    uint8 term1Num, term2Num;
+    int32 z;
+
+    term2Num = sequencePtr->term2Num;
+    term1Num = sequencePtr->term1Num;
+    z = int32P1[ term1Num ] + int32P1[ term2Num ];
+    ++term2Num;
+    if ( int32NumP1 <= term2Num ) {
+        ++term1Num;
+        if ( int32NumP1 <= term1Num ) {
+            term1Num = 0;
+            sequencePtr->done = TRUE;
+        }
+        term2Num = term1Num;
+        sequencePtr->term1Num = term1Num;
+    }
+    sequencePtr->term2Num = term2Num;
+    return (sbits32) z;
+
+}
+
+static int32 int32RandomP3( void )
+{
+
+    return
+        (sbits32) (
+              int32P1[ randomUint8() % int32NumP1 ]
+            + int32P1[ randomUint8() % int32NumP1 ]
+            + int32P1[ randomUint8() % int32NumP1 ]
+        );
+
+}
+
+enum {
+    int32NumPInfWeightMasks = 29
+};
+
+static const uint32 int32PInfWeightMasks[ int32NumPInfWeightMasks ] = {
+    0xFFFFFFFF,
+    0x7FFFFFFF,
+    0x3FFFFFFF,
+    0x1FFFFFFF,
+    0x0FFFFFFF,
+    0x07FFFFFF,
+    0x03FFFFFF,
+    0x01FFFFFF,
+    0x00FFFFFF,
+    0x007FFFFF,
+    0x003FFFFF,
+    0x001FFFFF,
+    0x000FFFFF,
+    0x0007FFFF,
+    0x0003FFFF,
+    0x0001FFFF,
+    0x0000FFFF,
+    0x00007FFF,
+    0x00003FFF,
+    0x00001FFF,
+    0x00000FFF,
+    0x000007FF,
+    0x000003FF,
+    0x000001FF,
+    0x000000FF,
+    0x0000007F,
+    0x0000003F,
+    0x0000001F,
+    0x0000000F
+};
+
+static const uint32 int32PInfWeightOffsets[ int32NumPInfWeightMasks ] = {
+    0x00000000,
+    0xC0000000,
+    0xE0000000,
+    0xF0000000,
+    0xF8000000,
+    0xFC000000,
+    0xFE000000,
+    0xFF000000,
+    0xFF800000,
+    0xFFC00000,
+    0xFFE00000,
+    0xFFF00000,
+    0xFFF80000,
+    0xFFFC0000,
+    0xFFFE0000,
+    0xFFFF0000,
+    0xFFFF8000,
+    0xFFFFC000,
+    0xFFFFE000,
+    0xFFFFF000,
+    0xFFFFF800,
+    0xFFFFFC00,
+    0xFFFFFE00,
+    0xFFFFFF00,
+    0xFFFFFF80,
+    0xFFFFFFC0,
+    0xFFFFFFE0,
+    0xFFFFFFF0,
+    0xFFFFFFF8
+};
+
+static int32 int32RandomPInf( void )
+{
+    int8 weightMaskNum;
+
+    weightMaskNum = randomUint8() % int32NumPInfWeightMasks;
+    return
+        (sbits32) (
+              ( randomUint32() & int32PInfWeightMasks[ weightMaskNum ] )
+            + int32PInfWeightOffsets[ weightMaskNum ]
+        );
+
+}
+
+#ifdef BITS64
+
+enum {
+    int64NumP1 = 252
+};
+
+static const uint64 int64P1[ int64NumP1 ] = {
+    LIT64( 0x0000000000000000 ),
+    LIT64( 0x0000000000000001 ),
+    LIT64( 0x0000000000000002 ),
+    LIT64( 0x0000000000000004 ),
+    LIT64( 0x0000000000000008 ),
+    LIT64( 0x0000000000000010 ),
+    LIT64( 0x0000000000000020 ),
+    LIT64( 0x0000000000000040 ),
+    LIT64( 0x0000000000000080 ),
+    LIT64( 0x0000000000000100 ),
+    LIT64( 0x0000000000000200 ),
+    LIT64( 0x0000000000000400 ),
+    LIT64( 0x0000000000000800 ),
+    LIT64( 0x0000000000001000 ),
+    LIT64( 0x0000000000002000 ),
+    LIT64( 0x0000000000004000 ),
+    LIT64( 0x0000000000008000 ),
+    LIT64( 0x0000000000010000 ),
+    LIT64( 0x0000000000020000 ),
+    LIT64( 0x0000000000040000 ),
+    LIT64( 0x0000000000080000 ),
+    LIT64( 0x0000000000100000 ),
+    LIT64( 0x0000000000200000 ),
+    LIT64( 0x0000000000400000 ),
+    LIT64( 0x0000000000800000 ),
+    LIT64( 0x0000000001000000 ),
+    LIT64( 0x0000000002000000 ),
+    LIT64( 0x0000000004000000 ),
+    LIT64( 0x0000000008000000 ),
+    LIT64( 0x0000000010000000 ),
+    LIT64( 0x0000000020000000 ),
+    LIT64( 0x0000000040000000 ),
+    LIT64( 0x0000000080000000 ),
+    LIT64( 0x0000000100000000 ),
+    LIT64( 0x0000000200000000 ),
+    LIT64( 0x0000000400000000 ),
+    LIT64( 0x0000000800000000 ),
+    LIT64( 0x0000001000000000 ),
+    LIT64( 0x0000002000000000 ),
+    LIT64( 0x0000004000000000 ),
+    LIT64( 0x0000008000000000 ),
+    LIT64( 0x0000010000000000 ),
+    LIT64( 0x0000020000000000 ),
+    LIT64( 0x0000040000000000 ),
+    LIT64( 0x0000080000000000 ),
+    LIT64( 0x0000100000000000 ),
+    LIT64( 0x0000200000000000 ),
+    LIT64( 0x0000400000000000 ),
+    LIT64( 0x0000800000000000 ),
+    LIT64( 0x0001000000000000 ),
+    LIT64( 0x0002000000000000 ),
+    LIT64( 0x0004000000000000 ),
+    LIT64( 0x0008000000000000 ),
+    LIT64( 0x0010000000000000 ),
+    LIT64( 0x0020000000000000 ),
+    LIT64( 0x0040000000000000 ),
+    LIT64( 0x0080000000000000 ),
+    LIT64( 0x0100000000000000 ),
+    LIT64( 0x0200000000000000 ),
+    LIT64( 0x0400000000000000 ),
+    LIT64( 0x0800000000000000 ),
+    LIT64( 0x1000000000000000 ),
+    LIT64( 0x2000000000000000 ),
+    LIT64( 0x4000000000000000 ),
+    LIT64( 0x8000000000000000 ),
+    LIT64( 0xC000000000000000 ),
+    LIT64( 0xE000000000000000 ),
+    LIT64( 0xF000000000000000 ),
+    LIT64( 0xF800000000000000 ),
+    LIT64( 0xFC00000000000000 ),
+    LIT64( 0xFE00000000000000 ),
+    LIT64( 0xFF00000000000000 ),
+    LIT64( 0xFF80000000000000 ),
+    LIT64( 0xFFC0000000000000 ),
+    LIT64( 0xFFE0000000000000 ),
+    LIT64( 0xFFF0000000000000 ),
+    LIT64( 0xFFF8000000000000 ),
+    LIT64( 0xFFFC000000000000 ),
+    LIT64( 0xFFFE000000000000 ),
+    LIT64( 0xFFFF000000000000 ),
+    LIT64( 0xFFFF800000000000 ),
+    LIT64( 0xFFFFC00000000000 ),
+    LIT64( 0xFFFFE00000000000 ),
+    LIT64( 0xFFFFF00000000000 ),
+    LIT64( 0xFFFFF80000000000 ),
+    LIT64( 0xFFFFFC0000000000 ),
+    LIT64( 0xFFFFFE0000000000 ),
+    LIT64( 0xFFFFFF0000000000 ),
+    LIT64( 0xFFFFFF8000000000 ),
+    LIT64( 0xFFFFFFC000000000 ),
+    LIT64( 0xFFFFFFE000000000 ),
+    LIT64( 0xFFFFFFF000000000 ),
+    LIT64( 0xFFFFFFF800000000 ),
+    LIT64( 0xFFFFFFFC00000000 ),
+    LIT64( 0xFFFFFFFE00000000 ),
+    LIT64( 0xFFFFFFFF00000000 ),
+    LIT64( 0xFFFFFFFF80000000 ),
+    LIT64( 0xFFFFFFFFC0000000 ),
+    LIT64( 0xFFFFFFFFE0000000 ),
+    LIT64( 0xFFFFFFFFF0000000 ),
+    LIT64( 0xFFFFFFFFF8000000 ),
+    LIT64( 0xFFFFFFFFFC000000 ),
+    LIT64( 0xFFFFFFFFFE000000 ),
+    LIT64( 0xFFFFFFFFFF000000 ),
+    LIT64( 0xFFFFFFFFFF800000 ),
+    LIT64( 0xFFFFFFFFFFC00000 ),
+    LIT64( 0xFFFFFFFFFFE00000 ),
+    LIT64( 0xFFFFFFFFFFF00000 ),
+    LIT64( 0xFFFFFFFFFFF80000 ),
+    LIT64( 0xFFFFFFFFFFFC0000 ),
+    LIT64( 0xFFFFFFFFFFFE0000 ),
+    LIT64( 0xFFFFFFFFFFFF0000 ),
+    LIT64( 0xFFFFFFFFFFFF8000 ),
+    LIT64( 0xFFFFFFFFFFFFC000 ),
+    LIT64( 0xFFFFFFFFFFFFE000 ),
+    LIT64( 0xFFFFFFFFFFFFF000 ),
+    LIT64( 0xFFFFFFFFFFFFF800 ),
+    LIT64( 0xFFFFFFFFFFFFFC00 ),
+    LIT64( 0xFFFFFFFFFFFFFE00 ),
+    LIT64( 0xFFFFFFFFFFFFFF00 ),
+    LIT64( 0xFFFFFFFFFFFFFF80 ),
+    LIT64( 0xFFFFFFFFFFFFFFC0 ),
+    LIT64( 0xFFFFFFFFFFFFFFE0 ),
+    LIT64( 0xFFFFFFFFFFFFFFF0 ),
+    LIT64( 0xFFFFFFFFFFFFFFF8 ),
+    LIT64( 0xFFFFFFFFFFFFFFFC ),
+    LIT64( 0xFFFFFFFFFFFFFFFE ),
+    LIT64( 0xFFFFFFFFFFFFFFFF ),
+    LIT64( 0xFFFFFFFFFFFFFFFD ),
+    LIT64( 0xFFFFFFFFFFFFFFFB ),
+    LIT64( 0xFFFFFFFFFFFFFFF7 ),
+    LIT64( 0xFFFFFFFFFFFFFFEF ),
+    LIT64( 0xFFFFFFFFFFFFFFDF ),
+    LIT64( 0xFFFFFFFFFFFFFFBF ),
+    LIT64( 0xFFFFFFFFFFFFFF7F ),
+    LIT64( 0xFFFFFFFFFFFFFEFF ),
+    LIT64( 0xFFFFFFFFFFFFFDFF ),
+    LIT64( 0xFFFFFFFFFFFFFBFF ),
+    LIT64( 0xFFFFFFFFFFFFF7FF ),
+    LIT64( 0xFFFFFFFFFFFFEFFF ),
+    LIT64( 0xFFFFFFFFFFFFDFFF ),
+    LIT64( 0xFFFFFFFFFFFFBFFF ),
+    LIT64( 0xFFFFFFFFFFFF7FFF ),
+    LIT64( 0xFFFFFFFFFFFEFFFF ),
+    LIT64( 0xFFFFFFFFFFFDFFFF ),
+    LIT64( 0xFFFFFFFFFFFBFFFF ),
+    LIT64( 0xFFFFFFFFFFF7FFFF ),
+    LIT64( 0xFFFFFFFFFFEFFFFF ),
+    LIT64( 0xFFFFFFFFFFDFFFFF ),
+    LIT64( 0xFFFFFFFFFFBFFFFF ),
+    LIT64( 0xFFFFFFFFFF7FFFFF ),
+    LIT64( 0xFFFFFFFFFEFFFFFF ),
+    LIT64( 0xFFFFFFFFFDFFFFFF ),
+    LIT64( 0xFFFFFFFFFBFFFFFF ),
+    LIT64( 0xFFFFFFFFF7FFFFFF ),
+    LIT64( 0xFFFFFFFFEFFFFFFF ),
+    LIT64( 0xFFFFFFFFDFFFFFFF ),
+    LIT64( 0xFFFFFFFFBFFFFFFF ),
+    LIT64( 0xFFFFFFFF7FFFFFFF ),
+    LIT64( 0xFFFFFFFEFFFFFFFF ),
+    LIT64( 0xFFFFFFFDFFFFFFFF ),
+    LIT64( 0xFFFFFFFBFFFFFFFF ),
+    LIT64( 0xFFFFFFF7FFFFFFFF ),
+    LIT64( 0xFFFFFFEFFFFFFFFF ),
+    LIT64( 0xFFFFFFDFFFFFFFFF ),
+    LIT64( 0xFFFFFFBFFFFFFFFF ),
+    LIT64( 0xFFFFFF7FFFFFFFFF ),
+    LIT64( 0xFFFFFEFFFFFFFFFF ),
+    LIT64( 0xFFFFFDFFFFFFFFFF ),
+    LIT64( 0xFFFFFBFFFFFFFFFF ),
+    LIT64( 0xFFFFF7FFFFFFFFFF ),
+    LIT64( 0xFFFFEFFFFFFFFFFF ),
+    LIT64( 0xFFFFDFFFFFFFFFFF ),
+    LIT64( 0xFFFFBFFFFFFFFFFF ),
+    LIT64( 0xFFFF7FFFFFFFFFFF ),
+    LIT64( 0xFFFEFFFFFFFFFFFF ),
+    LIT64( 0xFFFDFFFFFFFFFFFF ),
+    LIT64( 0xFFFBFFFFFFFFFFFF ),
+    LIT64( 0xFFF7FFFFFFFFFFFF ),
+    LIT64( 0xFFEFFFFFFFFFFFFF ),
+    LIT64( 0xFFDFFFFFFFFFFFFF ),
+    LIT64( 0xFFBFFFFFFFFFFFFF ),
+    LIT64( 0xFF7FFFFFFFFFFFFF ),
+    LIT64( 0xFEFFFFFFFFFFFFFF ),
+    LIT64( 0xFDFFFFFFFFFFFFFF ),
+    LIT64( 0xFBFFFFFFFFFFFFFF ),
+    LIT64( 0xF7FFFFFFFFFFFFFF ),
+    LIT64( 0xEFFFFFFFFFFFFFFF ),
+    LIT64( 0xDFFFFFFFFFFFFFFF ),
+    LIT64( 0xBFFFFFFFFFFFFFFF ),
+    LIT64( 0x7FFFFFFFFFFFFFFF ),
+    LIT64( 0x3FFFFFFFFFFFFFFF ),
+    LIT64( 0x1FFFFFFFFFFFFFFF ),
+    LIT64( 0x0FFFFFFFFFFFFFFF ),
+    LIT64( 0x07FFFFFFFFFFFFFF ),
+    LIT64( 0x03FFFFFFFFFFFFFF ),
+    LIT64( 0x01FFFFFFFFFFFFFF ),
+    LIT64( 0x00FFFFFFFFFFFFFF ),
+    LIT64( 0x007FFFFFFFFFFFFF ),
+    LIT64( 0x003FFFFFFFFFFFFF ),
+    LIT64( 0x001FFFFFFFFFFFFF ),
+    LIT64( 0x000FFFFFFFFFFFFF ),
+    LIT64( 0x0007FFFFFFFFFFFF ),
+    LIT64( 0x0003FFFFFFFFFFFF ),
+    LIT64( 0x0001FFFFFFFFFFFF ),
+    LIT64( 0x0000FFFFFFFFFFFF ),
+    LIT64( 0x00007FFFFFFFFFFF ),
+    LIT64( 0x00003FFFFFFFFFFF ),
+    LIT64( 0x00001FFFFFFFFFFF ),
+    LIT64( 0x00000FFFFFFFFFFF ),
+    LIT64( 0x000007FFFFFFFFFF ),
+    LIT64( 0x000003FFFFFFFFFF ),
+    LIT64( 0x000001FFFFFFFFFF ),
+    LIT64( 0x000000FFFFFFFFFF ),
+    LIT64( 0x0000007FFFFFFFFF ),
+    LIT64( 0x0000003FFFFFFFFF ),
+    LIT64( 0x0000001FFFFFFFFF ),
+    LIT64( 0x0000000FFFFFFFFF ),
+    LIT64( 0x00000007FFFFFFFF ),
+    LIT64( 0x00000003FFFFFFFF ),
+    LIT64( 0x00000001FFFFFFFF ),
+    LIT64( 0x00000000FFFFFFFF ),
+    LIT64( 0x000000007FFFFFFF ),
+    LIT64( 0x000000003FFFFFFF ),
+    LIT64( 0x000000001FFFFFFF ),
+    LIT64( 0x000000000FFFFFFF ),
+    LIT64( 0x0000000007FFFFFF ),
+    LIT64( 0x0000000003FFFFFF ),
+    LIT64( 0x0000000001FFFFFF ),
+    LIT64( 0x0000000000FFFFFF ),
+    LIT64( 0x00000000007FFFFF ),
+    LIT64( 0x00000000003FFFFF ),
+    LIT64( 0x00000000001FFFFF ),
+    LIT64( 0x00000000000FFFFF ),
+    LIT64( 0x000000000007FFFF ),
+    LIT64( 0x000000000003FFFF ),
+    LIT64( 0x000000000001FFFF ),
+    LIT64( 0x000000000000FFFF ),
+    LIT64( 0x0000000000007FFF ),
+    LIT64( 0x0000000000003FFF ),
+    LIT64( 0x0000000000001FFF ),
+    LIT64( 0x0000000000000FFF ),
+    LIT64( 0x00000000000007FF ),
+    LIT64( 0x00000000000003FF ),
+    LIT64( 0x00000000000001FF ),
+    LIT64( 0x00000000000000FF ),
+    LIT64( 0x000000000000007F ),
+    LIT64( 0x000000000000003F ),
+    LIT64( 0x000000000000001F ),
+    LIT64( 0x000000000000000F ),
+    LIT64( 0x0000000000000007 ),
+    LIT64( 0x0000000000000003 )
+};
+
+static int64 int64NextP1( sequenceT *sequencePtr )
+{
+    uint8 termNum;
+    int64 z;
+
+    termNum = sequencePtr->term1Num;
+    z = int64P1[ termNum ];
+    ++termNum;
+    if ( int64NumP1 <= termNum ) {
+        termNum = 0;
+        sequencePtr->done = TRUE;
+    }
+    sequencePtr->term1Num = termNum;
+    return (sbits64) z;
+
+}
+
+static const int64 int64NumP2 = ( int64NumP1 * int64NumP1 + int64NumP1 ) / 2;
+
+static int64 int64NextP2( sequenceT *sequencePtr )
+{
+    uint8 term1Num, term2Num;
+    int64 z;
+
+    term2Num = sequencePtr->term2Num;
+    term1Num = sequencePtr->term1Num;
+    z = int64P1[ term1Num ] + int64P1[ term2Num ];
+    ++term2Num;
+    if ( int64NumP1 <= term2Num ) {
+        ++term1Num;
+        if ( int64NumP1 <= term1Num ) {
+            term1Num = 0;
+            sequencePtr->done = TRUE;
+        }
+        term2Num = term1Num;
+        sequencePtr->term1Num = term1Num;
+    }
+    sequencePtr->term2Num = term2Num;
+    return (sbits64) z;
+
+}
+
+static int64 int64RandomP3( void )
+{
+
+    return
+        (sbits64) (
+              int64P1[ randomUint8() % int64NumP1 ]
+            + int64P1[ randomUint8() % int64NumP1 ]
+            + int64P1[ randomUint8() % int64NumP1 ]
+        );
+
+}
+
+enum {
+    int64NumPInfWeightMasks = 61
+};
+
+static const uint64 int64PInfWeightMasks[ int64NumPInfWeightMasks ] = {
+    LIT64( 0xFFFFFFFFFFFFFFFF ),
+    LIT64( 0x7FFFFFFFFFFFFFFF ),
+    LIT64( 0x3FFFFFFFFFFFFFFF ),
+    LIT64( 0x1FFFFFFFFFFFFFFF ),
+    LIT64( 0x0FFFFFFFFFFFFFFF ),
+    LIT64( 0x07FFFFFFFFFFFFFF ),
+    LIT64( 0x03FFFFFFFFFFFFFF ),
+    LIT64( 0x01FFFFFFFFFFFFFF ),
+    LIT64( 0x00FFFFFFFFFFFFFF ),
+    LIT64( 0x007FFFFFFFFFFFFF ),
+    LIT64( 0x003FFFFFFFFFFFFF ),
+    LIT64( 0x001FFFFFFFFFFFFF ),
+    LIT64( 0x000FFFFFFFFFFFFF ),
+    LIT64( 0x0007FFFFFFFFFFFF ),
+    LIT64( 0x0003FFFFFFFFFFFF ),
+    LIT64( 0x0001FFFFFFFFFFFF ),
+    LIT64( 0x0000FFFFFFFFFFFF ),
+    LIT64( 0x00007FFFFFFFFFFF ),
+    LIT64( 0x00003FFFFFFFFFFF ),
+    LIT64( 0x00001FFFFFFFFFFF ),
+    LIT64( 0x00000FFFFFFFFFFF ),
+    LIT64( 0x000007FFFFFFFFFF ),
+    LIT64( 0x000003FFFFFFFFFF ),
+    LIT64( 0x000001FFFFFFFFFF ),
+    LIT64( 0x000000FFFFFFFFFF ),
+    LIT64( 0x0000007FFFFFFFFF ),
+    LIT64( 0x0000003FFFFFFFFF ),
+    LIT64( 0x0000001FFFFFFFFF ),
+    LIT64( 0x0000000FFFFFFFFF ),
+    LIT64( 0x00000007FFFFFFFF ),
+    LIT64( 0x00000003FFFFFFFF ),
+    LIT64( 0x00000001FFFFFFFF ),
+    LIT64( 0x00000000FFFFFFFF ),
+    LIT64( 0x000000007FFFFFFF ),
+    LIT64( 0x000000003FFFFFFF ),
+    LIT64( 0x000000001FFFFFFF ),
+    LIT64( 0x000000000FFFFFFF ),
+    LIT64( 0x0000000007FFFFFF ),
+    LIT64( 0x0000000003FFFFFF ),
+    LIT64( 0x0000000001FFFFFF ),
+    LIT64( 0x0000000000FFFFFF ),
+    LIT64( 0x00000000007FFFFF ),
+    LIT64( 0x00000000003FFFFF ),
+    LIT64( 0x00000000001FFFFF ),
+    LIT64( 0x00000000000FFFFF ),
+    LIT64( 0x000000000007FFFF ),
+    LIT64( 0x000000000003FFFF ),
+    LIT64( 0x000000000001FFFF ),
+    LIT64( 0x000000000000FFFF ),
+    LIT64( 0x0000000000007FFF ),
+    LIT64( 0x0000000000003FFF ),
+    LIT64( 0x0000000000001FFF ),
+    LIT64( 0x0000000000000FFF ),
+    LIT64( 0x00000000000007FF ),
+    LIT64( 0x00000000000003FF ),
+    LIT64( 0x00000000000001FF ),
+    LIT64( 0x00000000000000FF ),
+    LIT64( 0x000000000000007F ),
+    LIT64( 0x000000000000003F ),
+    LIT64( 0x000000000000001F ),
+    LIT64( 0x000000000000000F )
+};
+
+static const uint64 int64PInfWeightOffsets[ int64NumPInfWeightMasks ] = {
+    LIT64( 0x0000000000000000 ),
+    LIT64( 0xC000000000000000 ),
+    LIT64( 0xE000000000000000 ),
+    LIT64( 0xF000000000000000 ),
+    LIT64( 0xF800000000000000 ),
+    LIT64( 0xFC00000000000000 ),
+    LIT64( 0xFE00000000000000 ),
+    LIT64( 0xFF00000000000000 ),
+    LIT64( 0xFF80000000000000 ),
+    LIT64( 0xFFC0000000000000 ),
+    LIT64( 0xFFE0000000000000 ),
+    LIT64( 0xFFF0000000000000 ),
+    LIT64( 0xFFF8000000000000 ),
+    LIT64( 0xFFFC000000000000 ),
+    LIT64( 0xFFFE000000000000 ),
+    LIT64( 0xFFFF000000000000 ),
+    LIT64( 0xFFFF800000000000 ),
+    LIT64( 0xFFFFC00000000000 ),
+    LIT64( 0xFFFFE00000000000 ),
+    LIT64( 0xFFFFF00000000000 ),
+    LIT64( 0xFFFFF80000000000 ),
+    LIT64( 0xFFFFFC0000000000 ),
+    LIT64( 0xFFFFFE0000000000 ),
+    LIT64( 0xFFFFFF0000000000 ),
+    LIT64( 0xFFFFFF8000000000 ),
+    LIT64( 0xFFFFFFC000000000 ),
+    LIT64( 0xFFFFFFE000000000 ),
+    LIT64( 0xFFFFFFF000000000 ),
+    LIT64( 0xFFFFFFF800000000 ),
+    LIT64( 0xFFFFFFFC00000000 ),
+    LIT64( 0xFFFFFFFE00000000 ),
+    LIT64( 0xFFFFFFFF00000000 ),
+    LIT64( 0xFFFFFFFF80000000 ),
+    LIT64( 0xFFFFFFFFC0000000 ),
+    LIT64( 0xFFFFFFFFE0000000 ),
+    LIT64( 0xFFFFFFFFF0000000 ),
+    LIT64( 0xFFFFFFFFF8000000 ),
+    LIT64( 0xFFFFFFFFFC000000 ),
+    LIT64( 0xFFFFFFFFFE000000 ),
+    LIT64( 0xFFFFFFFFFF000000 ),
+    LIT64( 0xFFFFFFFFFF800000 ),
+    LIT64( 0xFFFFFFFFFFC00000 ),
+    LIT64( 0xFFFFFFFFFFE00000 ),
+    LIT64( 0xFFFFFFFFFFF00000 ),
+    LIT64( 0xFFFFFFFFFFF80000 ),
+    LIT64( 0xFFFFFFFFFFFC0000 ),
+    LIT64( 0xFFFFFFFFFFFE0000 ),
+    LIT64( 0xFFFFFFFFFFFF0000 ),
+    LIT64( 0xFFFFFFFFFFFF8000 ),
+    LIT64( 0xFFFFFFFFFFFFC000 ),
+    LIT64( 0xFFFFFFFFFFFFE000 ),
+    LIT64( 0xFFFFFFFFFFFFF000 ),
+    LIT64( 0xFFFFFFFFFFFFF800 ),
+    LIT64( 0xFFFFFFFFFFFFFC00 ),
+    LIT64( 0xFFFFFFFFFFFFFE00 ),
+    LIT64( 0xFFFFFFFFFFFFFF00 ),
+    LIT64( 0xFFFFFFFFFFFFFF80 ),
+    LIT64( 0xFFFFFFFFFFFFFFC0 ),
+    LIT64( 0xFFFFFFFFFFFFFFE0 ),
+    LIT64( 0xFFFFFFFFFFFFFFF0 ),
+    LIT64( 0xFFFFFFFFFFFFFFF8 )
+};
+
+static int64 int64RandomPInf( void )
+{
+    int8 weightMaskNum;
+
+    weightMaskNum = randomUint8() % int64NumPInfWeightMasks;
+    return
+        (sbits64) (
+              ( randomUint64() & int64PInfWeightMasks[ weightMaskNum ] )
+            + int64PInfWeightOffsets[ weightMaskNum ]
+        );
+
+}
+
+#endif
+
+enum {
+    float32NumQIn  = 22,
+    float32NumQOut = 50,
+    float32NumP1   =  4,
+    float32NumP2   = 88
+};
+
+static const uint32 float32QIn[ float32NumQIn ] = {
+    0x00000000,		/* positive, subnormal		*/
+    0x00800000,		/* positive, -126		*/
+    0x33800000,		/* positive,  -24		*/
+    0x3E800000,		/* positive,   -2		*/
+    0x3F000000,		/* positive,   -1		*/
+    0x3F800000,		/* positive,    0		*/
+    0x40000000,		/* positive,    1		*/
+    0x40800000,		/* positive,    2		*/
+    0x4B800000,		/* positive,   24		*/
+    0x7F000000,		/* positive,  127		*/
+    0x7F800000,		/* positive, infinity or NaN	*/
+    0x80000000,		/* negative, subnormal		*/
+    0x80800000,		/* negative, -126		*/
+    0xB3800000,		/* negative,  -24		*/
+    0xBE800000,		/* negative,   -2		*/
+    0xBF000000,		/* negative,   -1		*/
+    0xBF800000,		/* negative,    0		*/
+    0xC0000000,		/* negative,    1		*/
+    0xC0800000,		/* negative,    2		*/
+    0xCB800000,		/* negative,   24		*/
+    0xFE800000,		/* negative,  126		*/
+    0xFF800000		/* negative, infinity or NaN	*/
+};
+
+static const uint32 float32QOut[ float32NumQOut ] = {
+    0x00000000,		/* positive, subnormal		*/
+    0x00800000,		/* positive, -126		*/
+    0x01000000,		/* positive, -125		*/
+    0x33800000,		/* positive,  -24		*/
+    0x3D800000,		/* positive,   -4		*/
+    0x3E000000,		/* positive,   -3		*/
+    0x3E800000,		/* positive,   -2		*/
+    0x3F000000,		/* positive,   -1		*/
+    0x3F800000,		/* positive,    0		*/
+    0x40000000,		/* positive,    1		*/
+    0x40800000,		/* positive,    2		*/
+    0x41000000,		/* positive,    3		*/
+    0x41800000,		/* positive,    4		*/
+    0x4B800000,		/* positive,   24		*/
+    0x4E000000,		/* positive,   29		*/
+    0x4E800000,		/* positive,   30		*/
+    0x4F000000,		/* positive,   31		*/
+    0x4F800000,		/* positive,   32		*/
+    0x5E000000,		/* positive,   61		*/
+    0x5E800000,		/* positive,   62		*/
+    0x5F000000,		/* positive,   63		*/
+    0x5F800000,		/* positive,   64		*/
+    0x7E800000,		/* positive,  126		*/
+    0x7F000000,		/* positive,  127		*/
+    0x7F800000,		/* positive, infinity or NaN	*/
+    0x80000000,		/* negative, subnormal		*/
+    0x80800000,		/* negative, -126		*/
+    0x81000000,		/* negative, -125		*/
+    0xB3800000,		/* negative,  -24		*/
+    0xBD800000,		/* negative,   -4		*/
+    0xBE000000,		/* negative,   -3		*/
+    0xBE800000,		/* negative,   -2		*/
+    0xBF000000,		/* negative,   -1		*/
+    0xBF800000,		/* negative,    0		*/
+    0xC0000000,		/* negative,    1		*/
+    0xC0800000,		/* negative,    2		*/
+    0xC1000000,		/* negative,    3		*/
+    0xC1800000,		/* negative,    4		*/
+    0xCB800000,		/* negative,   24		*/
+    0xCE000000,		/* negative,   29		*/
+    0xCE800000,		/* negative,   30		*/
+    0xCF000000,		/* negative,   31		*/
+    0xCF800000,		/* negative,   32		*/
+    0xDE000000,		/* negative,   61		*/
+    0xDE800000,		/* negative,   62		*/
+    0xDF000000,		/* negative,   63		*/
+    0xDF800000,		/* negative,   64		*/
+    0xFE800000,		/* negative,  126		*/
+    0xFF000000,		/* negative,  127		*/
+    0xFF800000		/* negative, infinity or NaN	*/
+};
+
+static const uint32 float32P1[ float32NumP1 ] = {
+    0x00000000,
+    0x00000001,
+    0x007FFFFF,
+    0x007FFFFE
+};
+
+static const uint32 float32P2[ float32NumP2 ] = {
+    0x00000000,
+    0x00000001,
+    0x00000002,
+    0x00000004,
+    0x00000008,
+    0x00000010,
+    0x00000020,
+    0x00000040,
+    0x00000080,
+    0x00000100,
+    0x00000200,
+    0x00000400,
+    0x00000800,
+    0x00001000,
+    0x00002000,
+    0x00004000,
+    0x00008000,
+    0x00010000,
+    0x00020000,
+    0x00040000,
+    0x00080000,
+    0x00100000,
+    0x00200000,
+    0x00400000,
+    0x00600000,
+    0x00700000,
+    0x00780000,
+    0x007C0000,
+    0x007E0000,
+    0x007F0000,
+    0x007F8000,
+    0x007FC000,
+    0x007FE000,
+    0x007FF000,
+    0x007FF800,
+    0x007FFC00,
+    0x007FFE00,
+    0x007FFF00,
+    0x007FFF80,
+    0x007FFFC0,
+    0x007FFFE0,
+    0x007FFFF0,
+    0x007FFFF8,
+    0x007FFFFC,
+    0x007FFFFE,
+    0x007FFFFF,
+    0x007FFFFD,
+    0x007FFFFB,
+    0x007FFFF7,
+    0x007FFFEF,
+    0x007FFFDF,
+    0x007FFFBF,
+    0x007FFF7F,
+    0x007FFEFF,
+    0x007FFDFF,
+    0x007FFBFF,
+    0x007FF7FF,
+    0x007FEFFF,
+    0x007FDFFF,
+    0x007FBFFF,
+    0x007F7FFF,
+    0x007EFFFF,
+    0x007DFFFF,
+    0x007BFFFF,
+    0x0077FFFF,
+    0x006FFFFF,
+    0x005FFFFF,
+    0x003FFFFF,
+    0x001FFFFF,
+    0x000FFFFF,
+    0x0007FFFF,
+    0x0003FFFF,
+    0x0001FFFF,
+    0x0000FFFF,
+    0x00007FFF,
+    0x00003FFF,
+    0x00001FFF,
+    0x00000FFF,
+    0x000007FF,
+    0x000003FF,
+    0x000001FF,
+    0x000000FF,
+    0x0000007F,
+    0x0000003F,
+    0x0000001F,
+    0x0000000F,
+    0x00000007,
+    0x00000003
+};
+
+static const uint32 float32NumQInP1 = float32NumQIn * float32NumP1;
+static const uint32 float32NumQOutP1 = float32NumQOut * float32NumP1;
+
+static float32 float32NextQInP1( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float32 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z = float32QIn[ expNum ] | float32P1[ sigNum ];
+    ++sigNum;
+    if ( float32NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float32NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float32 float32NextQOutP1( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float32 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z = float32QOut[ expNum ] | float32P1[ sigNum ];
+    ++sigNum;
+    if ( float32NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float32NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static const uint32 float32NumQInP2 = float32NumQIn * float32NumP2;
+static const uint32 float32NumQOutP2 = float32NumQOut * float32NumP2;
+
+static float32 float32NextQInP2( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float32 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z = float32QIn[ expNum ] | float32P2[ sigNum ];
+    ++sigNum;
+    if ( float32NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float32NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float32 float32NextQOutP2( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float32 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z = float32QOut[ expNum ] | float32P2[ sigNum ];
+    ++sigNum;
+    if ( float32NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float32NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float32 float32RandomQOutP3( void )
+{
+
+    return
+          float32QOut[ randomUint8() % float32NumQOut ]
+        | (   (   float32P2[ randomUint8() % float32NumP2 ]
+                + float32P2[ randomUint8() % float32NumP2 ] )
+            & 0x007FFFFF );
+
+}
+
+static float32 float32RandomQOutPInf( void )
+{
+
+    return
+          float32QOut[ randomUint8() % float32NumQOut ]
+        | ( randomUint32() & 0x007FFFFF );
+
+}
+
+enum {
+    float32NumQInfWeightMasks = 7
+};
+
+static const uint32 float32QInfWeightMasks[ float32NumQInfWeightMasks ] = {
+    0x7F800000,
+    0x7F800000,
+    0x3F800000,
+    0x1F800000,
+    0x0F800000,
+    0x07800000,
+    0x03800000
+};
+
+static const uint32 float32QInfWeightOffsets[ float32NumQInfWeightMasks ] = {
+    0x00000000,
+    0x00000000,
+    0x20000000,
+    0x30000000,
+    0x38000000,
+    0x3C000000,
+    0x3E000000
+};
+
+static float32 float32RandomQInfP3( void )
+{
+    int8 weightMaskNum;
+
+    weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
+    return
+          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+        | (   (   ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
+                & float32QInfWeightMasks[ weightMaskNum ] )
+            + float32QInfWeightOffsets[ weightMaskNum ]
+          )
+        | (   (   float32P2[ randomUint8() % float32NumP2 ]
+                + float32P2[ randomUint8() % float32NumP2 ] )
+            & 0x007FFFFF );
+
+}
+
+static float32 float32RandomQInfPInf( void )
+{
+    int8 weightMaskNum;
+
+    weightMaskNum = randomUint8() % float32NumQInfWeightMasks;
+    return
+          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+        | (   (   ( ( (uint32) ( randomUint16() & 0x1FF ) )<<23 )
+                & float32QInfWeightMasks[ weightMaskNum ] )
+            + float32QInfWeightOffsets[ weightMaskNum ]
+          )
+        | ( randomUint32() & 0x007FFFFF );
+
+}
+
+static float32 float32Random( void )
+{
+
+    switch ( randomUint8() & 7 ) {
+     case 0:
+     case 1:
+     case 2:
+        return float32RandomQOutP3();
+     case 3:
+        return float32RandomQOutPInf();
+     case 4:
+     case 5:
+     case 6:
+        return float32RandomQInfP3();
+     case 7:
+        return float32RandomQInfPInf();
+    }
+
+}
+
+#ifdef BITS64
+#define SETFLOAT64( z, zHigh, zLow ) z = ( ( (float64) zHigh )<<32 ) | zLow
+#else
+#define SETFLOAT64( z, zHigh, zLow ) z.low = zLow; z.high = zHigh
+#endif
+
+enum {
+    float64NumQIn  =  22,
+    float64NumQOut =  64,
+    float64NumP1   =   4,
+    float64NumP2   = 204
+};
+
+static const uint32 float64QIn[ float64NumQIn ] = {
+    0x00000000,		/* positive, subnormal		*/
+    0x00100000,		/* positive, -1022		*/
+    0x3CA00000,		/* positive,   -53		*/
+    0x3FD00000,		/* positive,    -2		*/
+    0x3FE00000,		/* positive,    -1		*/
+    0x3FF00000,		/* positive,     0		*/
+    0x40000000,		/* positive,     1		*/
+    0x40100000,		/* positive,     2		*/
+    0x43400000,		/* positive,    53		*/
+    0x7FE00000,		/* positive,  1023		*/
+    0x7FF00000,		/* positive, infinity or NaN	*/
+    0x80000000,		/* negative, subnormal		*/
+    0x80100000,		/* negative, -1022		*/
+    0xBCA00000,		/* negative,   -53		*/
+    0xBFD00000,		/* negative,    -2		*/
+    0xBFE00000,		/* negative,    -1		*/
+    0xBFF00000,		/* negative,     0		*/
+    0xC0000000,		/* negative,     1		*/
+    0xC0100000,		/* negative,     2		*/
+    0xC3400000,		/* negative,    53		*/
+    0xFFE00000,		/* negative,  1023		*/
+    0xFFF00000		/* negative, infinity or NaN	*/
+};
+
+static const uint32 float64QOut[ float64NumQOut ] = {
+    0x00000000,		/* positive, subnormal		*/
+    0x00100000,		/* positive, -1022		*/
+    0x00200000,		/* positive, -1021		*/
+    0x37E00000,		/* positive,  -129		*/
+    0x37F00000,		/* positive,  -128		*/
+    0x38000000,		/* positive,  -127		*/
+    0x38100000,		/* positive,  -126		*/
+    0x3CA00000,		/* positive,   -53		*/
+    0x3FB00000,		/* positive,    -4		*/
+    0x3FC00000,		/* positive,    -3		*/
+    0x3FD00000,		/* positive,    -2		*/
+    0x3FE00000,		/* positive,    -1		*/
+    0x3FF00000,		/* positive,     0		*/
+    0x40000000,		/* positive,     1		*/
+    0x40100000,		/* positive,     2		*/
+    0x40200000,		/* positive,     3		*/
+    0x40300000,		/* positive,     4		*/
+    0x41C00000,		/* positive,    29		*/
+    0x41D00000,		/* positive,    30		*/
+    0x41E00000,		/* positive,    31		*/
+    0x41F00000,		/* positive,    32		*/
+    0x43400000,		/* positive,    53		*/
+    0x43C00000,		/* positive,    61		*/
+    0x43D00000,		/* positive,    62		*/
+    0x43E00000,		/* positive,    63		*/
+    0x43F00000,		/* positive,    64		*/
+    0x47E00000,		/* positive,   127		*/
+    0x47F00000,		/* positive,   128		*/
+    0x48000000,		/* positive,   129		*/
+    0x7FD00000,		/* positive,  1022		*/
+    0x7FE00000,		/* positive,  1023		*/
+    0x7FF00000,		/* positive, infinity or NaN	*/
+    0x80000000,		/* negative, subnormal		*/
+    0x80100000,		/* negative, -1022		*/
+    0x80200000,		/* negative, -1021		*/
+    0xB7E00000,		/* negative,  -129		*/
+    0xB7F00000,		/* negative,  -128		*/
+    0xB8000000,		/* negative,  -127		*/
+    0xB8100000,		/* negative,  -126		*/
+    0xBCA00000,		/* negative,   -53		*/
+    0xBFB00000,		/* negative,    -4		*/
+    0xBFC00000,		/* negative,    -3		*/
+    0xBFD00000,		/* negative,    -2		*/
+    0xBFE00000,		/* negative,    -1		*/
+    0xBFF00000,		/* negative,     0		*/
+    0xC0000000,		/* negative,     1		*/
+    0xC0100000,		/* negative,     2		*/
+    0xC0200000,		/* negative,     3		*/
+    0xC0300000,		/* negative,     4		*/
+    0xC1C00000,		/* negative,    29		*/
+    0xC1D00000,		/* negative,    30		*/
+    0xC1E00000,		/* negative,    31		*/
+    0xC1F00000,		/* negative,    32		*/
+    0xC3400000,		/* negative,    53		*/
+    0xC3C00000,		/* negative,    61		*/
+    0xC3D00000,		/* negative,    62		*/
+    0xC3E00000,		/* negative,    63		*/
+    0xC3F00000,		/* negative,    64		*/
+    0xC7E00000,		/* negative,   127		*/
+    0xC7F00000,		/* negative,   128		*/
+    0xC8000000,		/* negative,   129		*/
+    0xFFD00000,		/* negative,  1022		*/
+    0xFFE00000,		/* negative,  1023		*/
+    0xFFF00000		/* negative, infinity or NaN	*/
+};
+
+static const struct { bits32 high, low; } float64P1[ float64NumP1 ] = {
+    { 0x00000000, 0x00000000 },
+    { 0x00000000, 0x00000001 },
+    { 0x000FFFFF, 0xFFFFFFFF },
+    { 0x000FFFFF, 0xFFFFFFFE }
+};
+
+static const struct { bits32 high, low; } float64P2[ float64NumP2 ] = {
+    { 0x00000000, 0x00000000 },
+    { 0x00000000, 0x00000001 },
+    { 0x00000000, 0x00000002 },
+    { 0x00000000, 0x00000004 },
+    { 0x00000000, 0x00000008 },
+    { 0x00000000, 0x00000010 },
+    { 0x00000000, 0x00000020 },
+    { 0x00000000, 0x00000040 },
+    { 0x00000000, 0x00000080 },
+    { 0x00000000, 0x00000100 },
+    { 0x00000000, 0x00000200 },
+    { 0x00000000, 0x00000400 },
+    { 0x00000000, 0x00000800 },
+    { 0x00000000, 0x00001000 },
+    { 0x00000000, 0x00002000 },
+    { 0x00000000, 0x00004000 },
+    { 0x00000000, 0x00008000 },
+    { 0x00000000, 0x00010000 },
+    { 0x00000000, 0x00020000 },
+    { 0x00000000, 0x00040000 },
+    { 0x00000000, 0x00080000 },
+    { 0x00000000, 0x00100000 },
+    { 0x00000000, 0x00200000 },
+    { 0x00000000, 0x00400000 },
+    { 0x00000000, 0x00800000 },
+    { 0x00000000, 0x01000000 },
+    { 0x00000000, 0x02000000 },
+    { 0x00000000, 0x04000000 },
+    { 0x00000000, 0x08000000 },
+    { 0x00000000, 0x10000000 },
+    { 0x00000000, 0x20000000 },
+    { 0x00000000, 0x40000000 },
+    { 0x00000000, 0x80000000 },
+    { 0x00000001, 0x00000000 },
+    { 0x00000002, 0x00000000 },
+    { 0x00000004, 0x00000000 },
+    { 0x00000008, 0x00000000 },
+    { 0x00000010, 0x00000000 },
+    { 0x00000020, 0x00000000 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000080, 0x00000000 },
+    { 0x00000100, 0x00000000 },
+    { 0x00000200, 0x00000000 },
+    { 0x00000400, 0x00000000 },
+    { 0x00000800, 0x00000000 },
+    { 0x00001000, 0x00000000 },
+    { 0x00002000, 0x00000000 },
+    { 0x00004000, 0x00000000 },
+    { 0x00008000, 0x00000000 },
+    { 0x00010000, 0x00000000 },
+    { 0x00020000, 0x00000000 },
+    { 0x00040000, 0x00000000 },
+    { 0x00080000, 0x00000000 },
+    { 0x000C0000, 0x00000000 },
+    { 0x000E0000, 0x00000000 },
+    { 0x000F0000, 0x00000000 },
+    { 0x000F8000, 0x00000000 },
+    { 0x000FC000, 0x00000000 },
+    { 0x000FE000, 0x00000000 },
+    { 0x000FF000, 0x00000000 },
+    { 0x000FF800, 0x00000000 },
+    { 0x000FFC00, 0x00000000 },
+    { 0x000FFE00, 0x00000000 },
+    { 0x000FFF00, 0x00000000 },
+    { 0x000FFF80, 0x00000000 },
+    { 0x000FFFC0, 0x00000000 },
+    { 0x000FFFE0, 0x00000000 },
+    { 0x000FFFF0, 0x00000000 },
+    { 0x000FFFF8, 0x00000000 },
+    { 0x000FFFFC, 0x00000000 },
+    { 0x000FFFFE, 0x00000000 },
+    { 0x000FFFFF, 0x00000000 },
+    { 0x000FFFFF, 0x80000000 },
+    { 0x000FFFFF, 0xC0000000 },
+    { 0x000FFFFF, 0xE0000000 },
+    { 0x000FFFFF, 0xF0000000 },
+    { 0x000FFFFF, 0xF8000000 },
+    { 0x000FFFFF, 0xFC000000 },
+    { 0x000FFFFF, 0xFE000000 },
+    { 0x000FFFFF, 0xFF000000 },
+    { 0x000FFFFF, 0xFF800000 },
+    { 0x000FFFFF, 0xFFC00000 },
+    { 0x000FFFFF, 0xFFE00000 },
+    { 0x000FFFFF, 0xFFF00000 },
+    { 0x000FFFFF, 0xFFF80000 },
+    { 0x000FFFFF, 0xFFFC0000 },
+    { 0x000FFFFF, 0xFFFE0000 },
+    { 0x000FFFFF, 0xFFFF0000 },
+    { 0x000FFFFF, 0xFFFF8000 },
+    { 0x000FFFFF, 0xFFFFC000 },
+    { 0x000FFFFF, 0xFFFFE000 },
+    { 0x000FFFFF, 0xFFFFF000 },
+    { 0x000FFFFF, 0xFFFFF800 },
+    { 0x000FFFFF, 0xFFFFFC00 },
+    { 0x000FFFFF, 0xFFFFFE00 },
+    { 0x000FFFFF, 0xFFFFFF00 },
+    { 0x000FFFFF, 0xFFFFFF80 },
+    { 0x000FFFFF, 0xFFFFFFC0 },
+    { 0x000FFFFF, 0xFFFFFFE0 },
+    { 0x000FFFFF, 0xFFFFFFF0 },
+    { 0x000FFFFF, 0xFFFFFFF8 },
+    { 0x000FFFFF, 0xFFFFFFFC },
+    { 0x000FFFFF, 0xFFFFFFFE },
+    { 0x000FFFFF, 0xFFFFFFFF },
+    { 0x000FFFFF, 0xFFFFFFFD },
+    { 0x000FFFFF, 0xFFFFFFFB },
+    { 0x000FFFFF, 0xFFFFFFF7 },
+    { 0x000FFFFF, 0xFFFFFFEF },
+    { 0x000FFFFF, 0xFFFFFFDF },
+    { 0x000FFFFF, 0xFFFFFFBF },
+    { 0x000FFFFF, 0xFFFFFF7F },
+    { 0x000FFFFF, 0xFFFFFEFF },
+    { 0x000FFFFF, 0xFFFFFDFF },
+    { 0x000FFFFF, 0xFFFFFBFF },
+    { 0x000FFFFF, 0xFFFFF7FF },
+    { 0x000FFFFF, 0xFFFFEFFF },
+    { 0x000FFFFF, 0xFFFFDFFF },
+    { 0x000FFFFF, 0xFFFFBFFF },
+    { 0x000FFFFF, 0xFFFF7FFF },
+    { 0x000FFFFF, 0xFFFEFFFF },
+    { 0x000FFFFF, 0xFFFDFFFF },
+    { 0x000FFFFF, 0xFFFBFFFF },
+    { 0x000FFFFF, 0xFFF7FFFF },
+    { 0x000FFFFF, 0xFFEFFFFF },
+    { 0x000FFFFF, 0xFFDFFFFF },
+    { 0x000FFFFF, 0xFFBFFFFF },
+    { 0x000FFFFF, 0xFF7FFFFF },
+    { 0x000FFFFF, 0xFEFFFFFF },
+    { 0x000FFFFF, 0xFDFFFFFF },
+    { 0x000FFFFF, 0xFBFFFFFF },
+    { 0x000FFFFF, 0xF7FFFFFF },
+    { 0x000FFFFF, 0xEFFFFFFF },
+    { 0x000FFFFF, 0xDFFFFFFF },
+    { 0x000FFFFF, 0xBFFFFFFF },
+    { 0x000FFFFF, 0x7FFFFFFF },
+    { 0x000FFFFE, 0xFFFFFFFF },
+    { 0x000FFFFD, 0xFFFFFFFF },
+    { 0x000FFFFB, 0xFFFFFFFF },
+    { 0x000FFFF7, 0xFFFFFFFF },
+    { 0x000FFFEF, 0xFFFFFFFF },
+    { 0x000FFFDF, 0xFFFFFFFF },
+    { 0x000FFFBF, 0xFFFFFFFF },
+    { 0x000FFF7F, 0xFFFFFFFF },
+    { 0x000FFEFF, 0xFFFFFFFF },
+    { 0x000FFDFF, 0xFFFFFFFF },
+    { 0x000FFBFF, 0xFFFFFFFF },
+    { 0x000FF7FF, 0xFFFFFFFF },
+    { 0x000FEFFF, 0xFFFFFFFF },
+    { 0x000FDFFF, 0xFFFFFFFF },
+    { 0x000FBFFF, 0xFFFFFFFF },
+    { 0x000F7FFF, 0xFFFFFFFF },
+    { 0x000EFFFF, 0xFFFFFFFF },
+    { 0x000DFFFF, 0xFFFFFFFF },
+    { 0x000BFFFF, 0xFFFFFFFF },
+    { 0x0007FFFF, 0xFFFFFFFF },
+    { 0x0003FFFF, 0xFFFFFFFF },
+    { 0x0001FFFF, 0xFFFFFFFF },
+    { 0x0000FFFF, 0xFFFFFFFF },
+    { 0x00007FFF, 0xFFFFFFFF },
+    { 0x00003FFF, 0xFFFFFFFF },
+    { 0x00001FFF, 0xFFFFFFFF },
+    { 0x00000FFF, 0xFFFFFFFF },
+    { 0x000007FF, 0xFFFFFFFF },
+    { 0x000003FF, 0xFFFFFFFF },
+    { 0x000001FF, 0xFFFFFFFF },
+    { 0x000000FF, 0xFFFFFFFF },
+    { 0x0000007F, 0xFFFFFFFF },
+    { 0x0000003F, 0xFFFFFFFF },
+    { 0x0000001F, 0xFFFFFFFF },
+    { 0x0000000F, 0xFFFFFFFF },
+    { 0x00000007, 0xFFFFFFFF },
+    { 0x00000003, 0xFFFFFFFF },
+    { 0x00000001, 0xFFFFFFFF },
+    { 0x00000000, 0xFFFFFFFF },
+    { 0x00000000, 0x7FFFFFFF },
+    { 0x00000000, 0x3FFFFFFF },
+    { 0x00000000, 0x1FFFFFFF },
+    { 0x00000000, 0x0FFFFFFF },
+    { 0x00000000, 0x07FFFFFF },
+    { 0x00000000, 0x03FFFFFF },
+    { 0x00000000, 0x01FFFFFF },
+    { 0x00000000, 0x00FFFFFF },
+    { 0x00000000, 0x007FFFFF },
+    { 0x00000000, 0x003FFFFF },
+    { 0x00000000, 0x001FFFFF },
+    { 0x00000000, 0x000FFFFF },
+    { 0x00000000, 0x0007FFFF },
+    { 0x00000000, 0x0003FFFF },
+    { 0x00000000, 0x0001FFFF },
+    { 0x00000000, 0x0000FFFF },
+    { 0x00000000, 0x00007FFF },
+    { 0x00000000, 0x00003FFF },
+    { 0x00000000, 0x00001FFF },
+    { 0x00000000, 0x00000FFF },
+    { 0x00000000, 0x000007FF },
+    { 0x00000000, 0x000003FF },
+    { 0x00000000, 0x000001FF },
+    { 0x00000000, 0x000000FF },
+    { 0x00000000, 0x0000007F },
+    { 0x00000000, 0x0000003F },
+    { 0x00000000, 0x0000001F },
+    { 0x00000000, 0x0000000F },
+    { 0x00000000, 0x00000007 },
+    { 0x00000000, 0x00000003 }
+};
+
+static const uint32 float64NumQInP1 = float64NumQIn * float64NumP1;
+static const uint32 float64NumQOutP1 = float64NumQOut * float64NumP1;
+
+static float64 float64NextQInP1( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float64 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    SETFLOAT64(
+        z,
+        float64QIn[ expNum ] | float64P1[ sigNum ].high,
+        float64P1[ sigNum ].low
+    );
+    ++sigNum;
+    if ( float64NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float64NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float64 float64NextQOutP1( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float64 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    SETFLOAT64(
+        z,
+        float64QOut[ expNum ] | float64P1[ sigNum ].high,
+        float64P1[ sigNum ].low
+    );
+    ++sigNum;
+    if ( float64NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float64NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static const uint32 float64NumQInP2 = float64NumQIn * float64NumP2;
+static const uint32 float64NumQOutP2 = float64NumQOut * float64NumP2;
+
+static float64 float64NextQInP2( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float64 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    SETFLOAT64(
+        z,
+        float64QIn[ expNum ] | float64P2[ sigNum ].high,
+        float64P2[ sigNum ].low
+    );
+    ++sigNum;
+    if ( float64NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float64NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float64 float64NextQOutP2( sequenceT *sequencePtr )
+{
+    uint8 expNum, sigNum;
+    float64 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    SETFLOAT64(
+        z,
+        float64QOut[ expNum ] | float64P2[ sigNum ].high,
+        float64P2[ sigNum ].low
+    );
+    ++sigNum;
+    if ( float64NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float64NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float64 float64RandomQOutP3( void )
+{
+    int8 sigNum1, sigNum2;
+    uint32 sig1Low, sig2Low, zLow;
+    float64 z;
+
+    sigNum1 = randomUint8() % float64NumP2;
+    sigNum2 = randomUint8() % float64NumP2;
+    sig1Low = float64P2[ sigNum1 ].low;
+    sig2Low = float64P2[ sigNum2 ].low;
+    zLow = sig1Low + sig2Low;
+    SETFLOAT64(
+        z,
+          float64QOut[ randomUint8() % float64NumQOut ]
+        | (   (   float64P2[ sigNum1 ].high
+                + float64P2[ sigNum2 ].high
+                + ( zLow < sig1Low )
+              )
+            & 0x000FFFFF
+          ),
+        zLow
+    );
+    return z;
+
+}
+
+static float64 float64RandomQOutPInf( void )
+{
+    float64 z;
+
+    SETFLOAT64(
+        z,
+          float64QOut[ randomUint8() % float64NumQOut ]
+        | ( randomUint32() & 0x000FFFFF ),
+        randomUint32()
+    );
+    return z;
+
+}
+
+enum {
+    float64NumQInfWeightMasks = 10
+};
+
+static const uint32 float64QInfWeightMasks[ float64NumQInfWeightMasks ] = {
+    0x7FF00000,
+    0x7FF00000,
+    0x3FF00000,
+    0x1FF00000,
+    0x0FF00000,
+    0x07F00000,
+    0x03F00000,
+    0x01F00000,
+    0x00F00000,
+    0x00700000
+};
+
+static const uint32 float64QInfWeightOffsets[ float64NumQInfWeightMasks ] = {
+    0x00000000,
+    0x00000000,
+    0x20000000,
+    0x30000000,
+    0x38000000,
+    0x3C000000,
+    0x3E000000,
+    0x3F000000,
+    0x3F800000,
+    0x3FC00000
+};
+
+static float64 float64RandomQInfP3( void )
+{
+    int8 sigNum1, sigNum2;
+    uint32 sig1Low, sig2Low, zLow;
+    int8 weightMaskNum;
+    float64 z;
+
+    sigNum1 = randomUint8() % float64NumP2;
+    sigNum2 = randomUint8() % float64NumP2;
+    sig1Low = float64P2[ sigNum1 ].low;
+    sig2Low = float64P2[ sigNum2 ].low;
+    zLow = sig1Low + sig2Low;
+    weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
+    SETFLOAT64(
+        z,
+          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+        | (   (   ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
+                & float64QInfWeightMasks[ weightMaskNum ] )
+            + float64QInfWeightOffsets[ weightMaskNum ]
+          )
+        | (   (   float64P2[ sigNum1 ].high
+                + float64P2[ sigNum2 ].high
+                + ( zLow < sig1Low )
+              )
+            & 0x000FFFFF
+          ),
+        zLow
+    );
+    return z;
+
+}
+
+static float64 float64RandomQInfPInf( void )
+{
+    int8 weightMaskNum;
+    float64 z;
+
+    weightMaskNum = randomUint8() % float64NumQInfWeightMasks;
+    SETFLOAT64(
+        z,
+          ( ( (uint32) ( randomUint8() & 1 ) )<<31 )
+        | (   (   ( ( (uint32) ( randomUint16() & 0xFFF ) )<<20 )
+                & float64QInfWeightMasks[ weightMaskNum ] )
+            + float64QInfWeightOffsets[ weightMaskNum ]
+          )
+        | ( randomUint32() & 0x000FFFFF ),
+        randomUint32()
+    );
+    return z;
+
+}
+
+static float64 float64Random( void )
+{
+
+    switch ( randomUint8() & 7 ) {
+     case 0:
+     case 1:
+     case 2:
+        return float64RandomQOutP3();
+     case 3:
+        return float64RandomQOutPInf();
+     case 4:
+     case 5:
+     case 6:
+        return float64RandomQInfP3();
+     case 7:
+        return float64RandomQInfPInf();
+    }
+
+}
+
+#ifdef FLOATX80
+
+enum {
+    floatx80NumQIn  =  22,
+    floatx80NumQOut =  76,
+    floatx80NumP1   =   4,
+    floatx80NumP2   = 248
+};
+
+static const uint16 floatx80QIn[ floatx80NumQIn ] = {
+    0x0000,		/* positive, subnormal		*/
+    0x0001,		/* positive, -16382		*/
+    0x3FBF,		/* positive,    -64		*/
+    0x3FFD,		/* positive,     -2		*/
+    0x3FFE,		/* positive,     -1		*/
+    0x3FFF,		/* positive,      0		*/
+    0x4000,		/* positive,      1		*/
+    0x4001,		/* positive,      2		*/
+    0x403F,		/* positive,     64		*/
+    0x7FFE,		/* positive,  16383		*/
+    0x7FFF,		/* positive, infinity or NaN	*/
+    0x8000,		/* negative, subnormal		*/
+    0x8001,		/* negative, -16382		*/
+    0xBFBF,		/* negative,    -64		*/
+    0xBFFD,		/* negative,     -2		*/
+    0xBFFE,		/* negative,     -1		*/
+    0xBFFF,		/* negative,      0		*/
+    0xC000,		/* negative,      1		*/
+    0xC001,		/* negative,      2		*/
+    0xC03F,		/* negative,     64		*/
+    0xFFFE,		/* negative,  16383		*/
+    0xFFFF		/* negative, infinity or NaN	*/
+};
+
+static const uint16 floatx80QOut[ floatx80NumQOut ] = {
+    0x0000,		/* positive, subnormal		*/
+    0x0001,		/* positive, -16382		*/
+    0x0002,		/* positive, -16381		*/
+    0x3BFE,		/* positive,  -1025		*/
+    0x3BFF,		/* positive,  -1024		*/
+    0x3C00,		/* positive,  -1023		*/
+    0x3C01,		/* positive,  -1022		*/
+    0x3F7E,		/* positive,   -129		*/
+    0x3F7F,		/* positive,   -128		*/
+    0x3F80,		/* positive,   -127		*/
+    0x3F81,		/* positive,   -126		*/
+    0x3FBF,		/* positive,    -64		*/
+    0x3FFB,		/* positive,     -4		*/
+    0x3FFC,		/* positive,     -3		*/
+    0x3FFD,		/* positive,     -2		*/
+    0x3FFE,		/* positive,     -1		*/
+    0x3FFF,		/* positive,      0		*/
+    0x4000,		/* positive,      1		*/
+    0x4001,		/* positive,      2		*/
+    0x4002,		/* positive,      3		*/
+    0x4003,		/* positive,      4		*/
+    0x401C,		/* positive,     29		*/
+    0x401D,		/* positive,     30		*/
+    0x401E,		/* positive,     31		*/
+    0x401F,		/* positive,     32		*/
+    0x403C,		/* positive,     61		*/
+    0x403D,		/* positive,     62		*/
+    0x403E,		/* positive,     63		*/
+    0x403F,		/* positive,     64		*/
+    0x407E,		/* positive,    127		*/
+    0x407F,		/* positive,    128		*/
+    0x4080,		/* positive,    129		*/
+    0x43FE,		/* positive,   1023		*/
+    0x43FF,		/* positive,   1024		*/
+    0x4400,		/* positive,   1025		*/
+    0x7FFD,		/* positive,  16382		*/
+    0x7FFE,		/* positive,  16383		*/
+    0x7FFF,		/* positive, infinity or NaN	*/
+    0x8000,		/* negative, subnormal		*/
+    0x8001,		/* negative, -16382		*/
+    0x8002,		/* negative, -16381		*/
+    0xBBFE,		/* negative,  -1025		*/
+    0xBBFF,		/* negative,  -1024		*/
+    0xBC00,		/* negative,  -1023		*/
+    0xBC01,		/* negative,  -1022		*/
+    0xBF7E,		/* negative,   -129		*/
+    0xBF7F,		/* negative,   -128		*/
+    0xBF80,		/* negative,   -127		*/
+    0xBF81,		/* negative,   -126		*/
+    0xBFBF,		/* negative,    -64		*/
+    0xBFFB,		/* negative,     -4		*/
+    0xBFFC,		/* negative,     -3		*/
+    0xBFFD,		/* negative,     -2		*/
+    0xBFFE,		/* negative,     -1		*/
+    0xBFFF,		/* negative,      0		*/
+    0xC000,		/* negative,      1		*/
+    0xC001,		/* negative,      2		*/
+    0xC002,		/* negative,      3		*/
+    0xC003,		/* negative,      4		*/
+    0xC01C,		/* negative,     29		*/
+    0xC01D,		/* negative,     30		*/
+    0xC01E,		/* negative,     31		*/
+    0xC01F,		/* negative,     32		*/
+    0xC03C,		/* negative,     61		*/
+    0xC03D,		/* negative,     62		*/
+    0xC03E,		/* negative,     63		*/
+    0xC03F,		/* negative,     64		*/
+    0xC07E,		/* negative,    127		*/
+    0xC07F,		/* negative,    128		*/
+    0xC080,		/* negative,    129		*/
+    0xC3FE,		/* negative,   1023		*/
+    0xC3FF,		/* negative,   1024		*/
+    0xC400,		/* negative,   1025		*/
+    0xFFFD,		/* negative,  16382		*/
+    0xFFFE,		/* negative,  16383		*/
+    0xFFFF		/* negative, infinity or NaN	*/
+};
+
+static const bits64 floatx80P1[ floatx80NumP1 ] = {
+    LIT64( 0x0000000000000000 ),
+    LIT64( 0x0000000000000001 ),
+    LIT64( 0x7FFFFFFFFFFFFFFF ),
+    LIT64( 0x7FFFFFFFFFFFFFFE )
+};
+
+static const bits64 floatx80P2[ floatx80NumP2 ] = {
+    LIT64( 0x0000000000000000 ),
+    LIT64( 0x0000000000000001 ),
+    LIT64( 0x0000000000000002 ),
+    LIT64( 0x0000000000000004 ),
+    LIT64( 0x0000000000000008 ),
+    LIT64( 0x0000000000000010 ),
+    LIT64( 0x0000000000000020 ),
+    LIT64( 0x0000000000000040 ),
+    LIT64( 0x0000000000000080 ),
+    LIT64( 0x0000000000000100 ),
+    LIT64( 0x0000000000000200 ),
+    LIT64( 0x0000000000000400 ),
+    LIT64( 0x0000000000000800 ),
+    LIT64( 0x0000000000001000 ),
+    LIT64( 0x0000000000002000 ),
+    LIT64( 0x0000000000004000 ),
+    LIT64( 0x0000000000008000 ),
+    LIT64( 0x0000000000010000 ),
+    LIT64( 0x0000000000020000 ),
+    LIT64( 0x0000000000040000 ),
+    LIT64( 0x0000000000080000 ),
+    LIT64( 0x0000000000100000 ),
+    LIT64( 0x0000000000200000 ),
+    LIT64( 0x0000000000400000 ),
+    LIT64( 0x0000000000800000 ),
+    LIT64( 0x0000000001000000 ),
+    LIT64( 0x0000000002000000 ),
+    LIT64( 0x0000000004000000 ),
+    LIT64( 0x0000000008000000 ),
+    LIT64( 0x0000000010000000 ),
+    LIT64( 0x0000000020000000 ),
+    LIT64( 0x0000000040000000 ),
+    LIT64( 0x0000000080000000 ),
+    LIT64( 0x0000000100000000 ),
+    LIT64( 0x0000000200000000 ),
+    LIT64( 0x0000000400000000 ),
+    LIT64( 0x0000000800000000 ),
+    LIT64( 0x0000001000000000 ),
+    LIT64( 0x0000002000000000 ),
+    LIT64( 0x0000004000000000 ),
+    LIT64( 0x0000008000000000 ),
+    LIT64( 0x0000010000000000 ),
+    LIT64( 0x0000020000000000 ),
+    LIT64( 0x0000040000000000 ),
+    LIT64( 0x0000080000000000 ),
+    LIT64( 0x0000100000000000 ),
+    LIT64( 0x0000200000000000 ),
+    LIT64( 0x0000400000000000 ),
+    LIT64( 0x0000800000000000 ),
+    LIT64( 0x0001000000000000 ),
+    LIT64( 0x0002000000000000 ),
+    LIT64( 0x0004000000000000 ),
+    LIT64( 0x0008000000000000 ),
+    LIT64( 0x0010000000000000 ),
+    LIT64( 0x0020000000000000 ),
+    LIT64( 0x0040000000000000 ),
+    LIT64( 0x0080000000000000 ),
+    LIT64( 0x0100000000000000 ),
+    LIT64( 0x0200000000000000 ),
+    LIT64( 0x0400000000000000 ),
+    LIT64( 0x0800000000000000 ),
+    LIT64( 0x1000000000000000 ),
+    LIT64( 0x2000000000000000 ),
+    LIT64( 0x4000000000000000 ),
+    LIT64( 0x6000000000000000 ),
+    LIT64( 0x7000000000000000 ),
+    LIT64( 0x7800000000000000 ),
+    LIT64( 0x7C00000000000000 ),
+    LIT64( 0x7E00000000000000 ),
+    LIT64( 0x7F00000000000000 ),
+    LIT64( 0x7F80000000000000 ),
+    LIT64( 0x7FC0000000000000 ),
+    LIT64( 0x7FE0000000000000 ),
+    LIT64( 0x7FF0000000000000 ),
+    LIT64( 0x7FF8000000000000 ),
+    LIT64( 0x7FFC000000000000 ),
+    LIT64( 0x7FFE000000000000 ),
+    LIT64( 0x7FFF000000000000 ),
+    LIT64( 0x7FFF800000000000 ),
+    LIT64( 0x7FFFC00000000000 ),
+    LIT64( 0x7FFFE00000000000 ),
+    LIT64( 0x7FFFF00000000000 ),
+    LIT64( 0x7FFFF80000000000 ),
+    LIT64( 0x7FFFFC0000000000 ),
+    LIT64( 0x7FFFFE0000000000 ),
+    LIT64( 0x7FFFFF0000000000 ),
+    LIT64( 0x7FFFFF8000000000 ),
+    LIT64( 0x7FFFFFC000000000 ),
+    LIT64( 0x7FFFFFE000000000 ),
+    LIT64( 0x7FFFFFF000000000 ),
+    LIT64( 0x7FFFFFF800000000 ),
+    LIT64( 0x7FFFFFFC00000000 ),
+    LIT64( 0x7FFFFFFE00000000 ),
+    LIT64( 0x7FFFFFFF00000000 ),
+    LIT64( 0x7FFFFFFF80000000 ),
+    LIT64( 0x7FFFFFFFC0000000 ),
+    LIT64( 0x7FFFFFFFE0000000 ),
+    LIT64( 0x7FFFFFFFF0000000 ),
+    LIT64( 0x7FFFFFFFF8000000 ),
+    LIT64( 0x7FFFFFFFFC000000 ),
+    LIT64( 0x7FFFFFFFFE000000 ),
+    LIT64( 0x7FFFFFFFFF000000 ),
+    LIT64( 0x7FFFFFFFFF800000 ),
+    LIT64( 0x7FFFFFFFFFC00000 ),
+    LIT64( 0x7FFFFFFFFFE00000 ),
+    LIT64( 0x7FFFFFFFFFF00000 ),
+    LIT64( 0x7FFFFFFFFFF80000 ),
+    LIT64( 0x7FFFFFFFFFFC0000 ),
+    LIT64( 0x7FFFFFFFFFFE0000 ),
+    LIT64( 0x7FFFFFFFFFFF0000 ),
+    LIT64( 0x7FFFFFFFFFFF8000 ),
+    LIT64( 0x7FFFFFFFFFFFC000 ),
+    LIT64( 0x7FFFFFFFFFFFE000 ),
+    LIT64( 0x7FFFFFFFFFFFF000 ),
+    LIT64( 0x7FFFFFFFFFFFF800 ),
+    LIT64( 0x7FFFFFFFFFFFFC00 ),
+    LIT64( 0x7FFFFFFFFFFFFE00 ),
+    LIT64( 0x7FFFFFFFFFFFFF00 ),
+    LIT64( 0x7FFFFFFFFFFFFF80 ),
+    LIT64( 0x7FFFFFFFFFFFFFC0 ),
+    LIT64( 0x7FFFFFFFFFFFFFE0 ),
+    LIT64( 0x7FFFFFFFFFFFFFF0 ),
+    LIT64( 0x7FFFFFFFFFFFFFF8 ),
+    LIT64( 0x7FFFFFFFFFFFFFFC ),
+    LIT64( 0x7FFFFFFFFFFFFFFE ),
+    LIT64( 0x7FFFFFFFFFFFFFFF ),
+    LIT64( 0x7FFFFFFFFFFFFFFD ),
+    LIT64( 0x7FFFFFFFFFFFFFFB ),
+    LIT64( 0x7FFFFFFFFFFFFFF7 ),
+    LIT64( 0x7FFFFFFFFFFFFFEF ),
+    LIT64( 0x7FFFFFFFFFFFFFDF ),
+    LIT64( 0x7FFFFFFFFFFFFFBF ),
+    LIT64( 0x7FFFFFFFFFFFFF7F ),
+    LIT64( 0x7FFFFFFFFFFFFEFF ),
+    LIT64( 0x7FFFFFFFFFFFFDFF ),
+    LIT64( 0x7FFFFFFFFFFFFBFF ),
+    LIT64( 0x7FFFFFFFFFFFF7FF ),
+    LIT64( 0x7FFFFFFFFFFFEFFF ),
+    LIT64( 0x7FFFFFFFFFFFDFFF ),
+    LIT64( 0x7FFFFFFFFFFFBFFF ),
+    LIT64( 0x7FFFFFFFFFFF7FFF ),
+    LIT64( 0x7FFFFFFFFFFEFFFF ),
+    LIT64( 0x7FFFFFFFFFFDFFFF ),
+    LIT64( 0x7FFFFFFFFFFBFFFF ),
+    LIT64( 0x7FFFFFFFFFF7FFFF ),
+    LIT64( 0x7FFFFFFFFFEFFFFF ),
+    LIT64( 0x7FFFFFFFFFDFFFFF ),
+    LIT64( 0x7FFFFFFFFFBFFFFF ),
+    LIT64( 0x7FFFFFFFFF7FFFFF ),
+    LIT64( 0x7FFFFFFFFEFFFFFF ),
+    LIT64( 0x7FFFFFFFFDFFFFFF ),
+    LIT64( 0x7FFFFFFFFBFFFFFF ),
+    LIT64( 0x7FFFFFFFF7FFFFFF ),
+    LIT64( 0x7FFFFFFFEFFFFFFF ),
+    LIT64( 0x7FFFFFFFDFFFFFFF ),
+    LIT64( 0x7FFFFFFFBFFFFFFF ),
+    LIT64( 0x7FFFFFFF7FFFFFFF ),
+    LIT64( 0x7FFFFFFEFFFFFFFF ),
+    LIT64( 0x7FFFFFFDFFFFFFFF ),
+    LIT64( 0x7FFFFFFBFFFFFFFF ),
+    LIT64( 0x7FFFFFF7FFFFFFFF ),
+    LIT64( 0x7FFFFFEFFFFFFFFF ),
+    LIT64( 0x7FFFFFDFFFFFFFFF ),
+    LIT64( 0x7FFFFFBFFFFFFFFF ),
+    LIT64( 0x7FFFFF7FFFFFFFFF ),
+    LIT64( 0x7FFFFEFFFFFFFFFF ),
+    LIT64( 0x7FFFFDFFFFFFFFFF ),
+    LIT64( 0x7FFFFBFFFFFFFFFF ),
+    LIT64( 0x7FFFF7FFFFFFFFFF ),
+    LIT64( 0x7FFFEFFFFFFFFFFF ),
+    LIT64( 0x7FFFDFFFFFFFFFFF ),
+    LIT64( 0x7FFFBFFFFFFFFFFF ),
+    LIT64( 0x7FFF7FFFFFFFFFFF ),
+    LIT64( 0x7FFEFFFFFFFFFFFF ),
+    LIT64( 0x7FFDFFFFFFFFFFFF ),
+    LIT64( 0x7FFBFFFFFFFFFFFF ),
+    LIT64( 0x7FF7FFFFFFFFFFFF ),
+    LIT64( 0x7FEFFFFFFFFFFFFF ),
+    LIT64( 0x7FDFFFFFFFFFFFFF ),
+    LIT64( 0x7FBFFFFFFFFFFFFF ),
+    LIT64( 0x7F7FFFFFFFFFFFFF ),
+    LIT64( 0x7EFFFFFFFFFFFFFF ),
+    LIT64( 0x7DFFFFFFFFFFFFFF ),
+    LIT64( 0x7BFFFFFFFFFFFFFF ),
+    LIT64( 0x77FFFFFFFFFFFFFF ),
+    LIT64( 0x6FFFFFFFFFFFFFFF ),
+    LIT64( 0x5FFFFFFFFFFFFFFF ),
+    LIT64( 0x3FFFFFFFFFFFFFFF ),
+    LIT64( 0x1FFFFFFFFFFFFFFF ),
+    LIT64( 0x0FFFFFFFFFFFFFFF ),
+    LIT64( 0x07FFFFFFFFFFFFFF ),
+    LIT64( 0x03FFFFFFFFFFFFFF ),
+    LIT64( 0x01FFFFFFFFFFFFFF ),
+    LIT64( 0x00FFFFFFFFFFFFFF ),
+    LIT64( 0x007FFFFFFFFFFFFF ),
+    LIT64( 0x003FFFFFFFFFFFFF ),
+    LIT64( 0x001FFFFFFFFFFFFF ),
+    LIT64( 0x000FFFFFFFFFFFFF ),
+    LIT64( 0x0007FFFFFFFFFFFF ),
+    LIT64( 0x0003FFFFFFFFFFFF ),
+    LIT64( 0x0001FFFFFFFFFFFF ),
+    LIT64( 0x0000FFFFFFFFFFFF ),
+    LIT64( 0x00007FFFFFFFFFFF ),
+    LIT64( 0x00003FFFFFFFFFFF ),
+    LIT64( 0x00001FFFFFFFFFFF ),
+    LIT64( 0x00000FFFFFFFFFFF ),
+    LIT64( 0x000007FFFFFFFFFF ),
+    LIT64( 0x000003FFFFFFFFFF ),
+    LIT64( 0x000001FFFFFFFFFF ),
+    LIT64( 0x000000FFFFFFFFFF ),
+    LIT64( 0x0000007FFFFFFFFF ),
+    LIT64( 0x0000003FFFFFFFFF ),
+    LIT64( 0x0000001FFFFFFFFF ),
+    LIT64( 0x0000000FFFFFFFFF ),
+    LIT64( 0x00000007FFFFFFFF ),
+    LIT64( 0x00000003FFFFFFFF ),
+    LIT64( 0x00000001FFFFFFFF ),
+    LIT64( 0x00000000FFFFFFFF ),
+    LIT64( 0x000000007FFFFFFF ),
+    LIT64( 0x000000003FFFFFFF ),
+    LIT64( 0x000000001FFFFFFF ),
+    LIT64( 0x000000000FFFFFFF ),
+    LIT64( 0x0000000007FFFFFF ),
+    LIT64( 0x0000000003FFFFFF ),
+    LIT64( 0x0000000001FFFFFF ),
+    LIT64( 0x0000000000FFFFFF ),
+    LIT64( 0x00000000007FFFFF ),
+    LIT64( 0x00000000003FFFFF ),
+    LIT64( 0x00000000001FFFFF ),
+    LIT64( 0x00000000000FFFFF ),
+    LIT64( 0x000000000007FFFF ),
+    LIT64( 0x000000000003FFFF ),
+    LIT64( 0x000000000001FFFF ),
+    LIT64( 0x000000000000FFFF ),
+    LIT64( 0x0000000000007FFF ),
+    LIT64( 0x0000000000003FFF ),
+    LIT64( 0x0000000000001FFF ),
+    LIT64( 0x0000000000000FFF ),
+    LIT64( 0x00000000000007FF ),
+    LIT64( 0x00000000000003FF ),
+    LIT64( 0x00000000000001FF ),
+    LIT64( 0x00000000000000FF ),
+    LIT64( 0x000000000000007F ),
+    LIT64( 0x000000000000003F ),
+    LIT64( 0x000000000000001F ),
+    LIT64( 0x000000000000000F ),
+    LIT64( 0x0000000000000007 ),
+    LIT64( 0x0000000000000003 )
+};
+
+static const uint32 floatx80NumQInP1 = floatx80NumQIn * floatx80NumP1;
+static const uint32 floatx80NumQOutP1 = floatx80NumQOut * floatx80NumP1;
+
+static floatx80 floatx80NextQInP1( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    floatx80 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = floatx80P1[ sigNum ];
+    z.high = floatx80QIn[ expNum ];
+    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+    ++sigNum;
+    if ( floatx80NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( floatx80NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static floatx80 floatx80NextQOutP1( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    floatx80 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = floatx80P1[ sigNum ];
+    z.high = floatx80QOut[ expNum ];
+    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+    ++sigNum;
+    if ( floatx80NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( floatx80NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static const uint32 floatx80NumQInP2 = floatx80NumQIn * floatx80NumP2;
+static const uint32 floatx80NumQOutP2 = floatx80NumQOut * floatx80NumP2;
+
+static floatx80 floatx80NextQInP2( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    floatx80 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = floatx80P2[ sigNum ];
+    z.high = floatx80QIn[ expNum ];
+    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+    ++sigNum;
+    if ( floatx80NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( floatx80NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static floatx80 floatx80NextQOutP2( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    floatx80 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = floatx80P2[ sigNum ];
+    z.high = floatx80QOut[ expNum ];
+    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+    ++sigNum;
+    if ( floatx80NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( floatx80NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static floatx80 floatx80RandomQOutP3( void )
+{
+    floatx80 z;
+
+    z.low =
+          (   floatx80P2[ randomUint8() % floatx80NumP2 ]
+            + floatx80P2[ randomUint8() % floatx80NumP2 ] )
+        & LIT64( 0x7FFFFFFFFFFFFFFF );
+    z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
+    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+    return z;
+
+}
+
+static floatx80 floatx80RandomQOutPInf( void )
+{
+    floatx80 z;
+
+    z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
+    z.high = floatx80QOut[ randomUint8() % floatx80NumQOut ];
+    if ( z.high & 0x7FFF ) z.low |= LIT64( 0x8000000000000000 );
+    return z;
+
+}
+
+enum {
+    floatx80NumQInfWeightMasks = 14
+};
+
+static const uint16 floatx80QInfWeightMasks[ floatx80NumQInfWeightMasks ] = {
+    0x7FFF,
+    0x7FFF,
+    0x3FFF,
+    0x1FFF,
+    0x07FF,
+    0x07FF,
+    0x03FF,
+    0x01FF,
+    0x00FF,
+    0x007F,
+    0x003F,
+    0x001F,
+    0x000F,
+    0x0007
+};
+
+static const uint16 floatx80QInfWeightOffsets[ floatx80NumQInfWeightMasks ] = {
+    0x0000,
+    0x0000,
+    0x2000,
+    0x3000,
+    0x3800,
+    0x3C00,
+    0x3E00,
+    0x3F00,
+    0x3F80,
+    0x3FC0,
+    0x3FE0,
+    0x3FF0,
+    0x3FF8,
+    0x3FFC
+};
+
+static floatx80 floatx80RandomQInfP3( void )
+{
+    int8 weightMaskNum;
+    floatx80 z;
+
+    z.low =
+          (   floatx80P2[ randomUint8() % floatx80NumP2 ]
+            + floatx80P2[ randomUint8() % floatx80NumP2 ] )
+        & LIT64( 0x7FFFFFFFFFFFFFFF );
+    weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
+    z.high =
+          randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ]
+        + floatx80QInfWeightOffsets[ weightMaskNum ];
+    if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
+    z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
+    return z;
+
+}
+
+static floatx80 floatx80RandomQInfPInf( void )
+{
+    int8 weightMaskNum;
+    floatx80 z;
+
+    z.low = randomUint64() & LIT64( 0x7FFFFFFFFFFFFFFF );
+    weightMaskNum = randomUint8() % floatx80NumQInfWeightMasks;
+    z.high =
+          randomUint16() & floatx80QInfWeightMasks[ weightMaskNum ]
+        + floatx80QInfWeightOffsets[ weightMaskNum ];
+    if ( z.high ) z.low |= LIT64( 0x8000000000000000 );
+    z.high |= ( (uint16) ( randomUint8() & 1 ) )<<15;
+    return z;
+
+}
+
+static floatx80 floatx80Random( void )
+{
+
+    switch ( randomUint8() & 7 ) {
+     case 0:
+     case 1:
+     case 2:
+        return floatx80RandomQOutP3();
+     case 3:
+        return floatx80RandomQOutPInf();
+     case 4:
+     case 5:
+     case 6:
+        return floatx80RandomQInfP3();
+     case 7:
+        return floatx80RandomQInfPInf();
+    }
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+enum {
+    float128NumQIn  =  22,
+    float128NumQOut =  78,
+    float128NumP1   =   4,
+    float128NumP2   = 443
+};
+
+static const uint64 float128QIn[ float128NumQIn ] = {
+    LIT64( 0x0000000000000000 ),	/* positive, subnormal		*/
+    LIT64( 0x0001000000000000 ),	/* positive, -16382		*/
+    LIT64( 0x3F8E000000000000 ),	/* positive,   -113		*/
+    LIT64( 0x3FFD000000000000 ),	/* positive,     -2		*/
+    LIT64( 0x3FFE000000000000 ),	/* positive,     -1		*/
+    LIT64( 0x3FFF000000000000 ),	/* positive,      0		*/
+    LIT64( 0x4000000000000000 ),	/* positive,      1		*/
+    LIT64( 0x4001000000000000 ),	/* positive,      2		*/
+    LIT64( 0x4070000000000000 ),	/* positive,    113		*/
+    LIT64( 0x7FFE000000000000 ),	/* positive,  16383		*/
+    LIT64( 0x7FFF000000000000 ),	/* positive, infinity or NaN	*/
+    LIT64( 0x8000000000000000 ),	/* negative, subnormal		*/
+    LIT64( 0x8001000000000000 ),	/* negative, -16382		*/
+    LIT64( 0xBF8E000000000000 ),	/* negative,   -113		*/
+    LIT64( 0xBFFD000000000000 ),	/* negative,     -2		*/
+    LIT64( 0xBFFE000000000000 ),	/* negative,     -1		*/
+    LIT64( 0xBFFF000000000000 ),	/* negative,      0		*/
+    LIT64( 0xC000000000000000 ),	/* negative,      1		*/
+    LIT64( 0xC001000000000000 ),	/* negative,      2		*/
+    LIT64( 0xC070000000000000 ),	/* negative,    113		*/
+    LIT64( 0xFFFE000000000000 ),	/* negative,  16383		*/
+    LIT64( 0xFFFF000000000000 )		/* negative, infinity or NaN	*/
+};
+
+static const uint64 float128QOut[ float128NumQOut ] = {
+    LIT64( 0x0000000000000000 ),	/* positive, subnormal		*/
+    LIT64( 0x0001000000000000 ),	/* positive, -16382		*/
+    LIT64( 0x0002000000000000 ),	/* positive, -16381		*/
+    LIT64( 0x3BFE000000000000 ),	/* positive,  -1025		*/
+    LIT64( 0x3BFF000000000000 ),	/* positive,  -1024		*/
+    LIT64( 0x3C00000000000000 ),	/* positive,  -1023		*/
+    LIT64( 0x3C01000000000000 ),	/* positive,  -1022		*/
+    LIT64( 0x3F7E000000000000 ),	/* positive,   -129		*/
+    LIT64( 0x3F7F000000000000 ),	/* positive,   -128		*/
+    LIT64( 0x3F80000000000000 ),	/* positive,   -127		*/
+    LIT64( 0x3F81000000000000 ),	/* positive,   -126		*/
+    LIT64( 0x3F8E000000000000 ),	/* positive,   -113		*/
+    LIT64( 0x3FFB000000000000 ),	/* positive,     -4		*/
+    LIT64( 0x3FFC000000000000 ),	/* positive,     -3		*/
+    LIT64( 0x3FFD000000000000 ),	/* positive,     -2		*/
+    LIT64( 0x3FFE000000000000 ),	/* positive,     -1		*/
+    LIT64( 0x3FFF000000000000 ),	/* positive,      0		*/
+    LIT64( 0x4000000000000000 ),	/* positive,      1		*/
+    LIT64( 0x4001000000000000 ),	/* positive,      2		*/
+    LIT64( 0x4002000000000000 ),	/* positive,      3		*/
+    LIT64( 0x4003000000000000 ),	/* positive,      4		*/
+    LIT64( 0x401C000000000000 ),	/* positive,     29		*/
+    LIT64( 0x401D000000000000 ),	/* positive,     30		*/
+    LIT64( 0x401E000000000000 ),	/* positive,     31		*/
+    LIT64( 0x401F000000000000 ),	/* positive,     32		*/
+    LIT64( 0x403C000000000000 ),	/* positive,     61		*/
+    LIT64( 0x403D000000000000 ),	/* positive,     62		*/
+    LIT64( 0x403E000000000000 ),	/* positive,     63		*/
+    LIT64( 0x403F000000000000 ),	/* positive,     64		*/
+    LIT64( 0x4070000000000000 ),	/* positive,    113		*/
+    LIT64( 0x407E000000000000 ),	/* positive,    127		*/
+    LIT64( 0x407F000000000000 ),	/* positive,    128		*/
+    LIT64( 0x4080000000000000 ),	/* positive,    129		*/
+    LIT64( 0x43FE000000000000 ),	/* positive,   1023		*/
+    LIT64( 0x43FF000000000000 ),	/* positive,   1024		*/
+    LIT64( 0x4400000000000000 ),	/* positive,   1025		*/
+    LIT64( 0x7FFD000000000000 ),	/* positive,  16382		*/
+    LIT64( 0x7FFE000000000000 ),	/* positive,  16383		*/
+    LIT64( 0x7FFF000000000000 ),	/* positive, infinity or NaN	*/
+    LIT64( 0x8000000000000000 ),	/* negative, subnormal		*/
+    LIT64( 0x8001000000000000 ),	/* negative, -16382		*/
+    LIT64( 0x8002000000000000 ),	/* negative, -16381		*/
+    LIT64( 0xBBFE000000000000 ),	/* negative,  -1025		*/
+    LIT64( 0xBBFF000000000000 ),	/* negative,  -1024		*/
+    LIT64( 0xBC00000000000000 ),	/* negative,  -1023		*/
+    LIT64( 0xBC01000000000000 ),	/* negative,  -1022		*/
+    LIT64( 0xBF7E000000000000 ),	/* negative,   -129		*/
+    LIT64( 0xBF7F000000000000 ),	/* negative,   -128		*/
+    LIT64( 0xBF80000000000000 ),	/* negative,   -127		*/
+    LIT64( 0xBF81000000000000 ),	/* negative,   -126		*/
+    LIT64( 0xBF8E000000000000 ),	/* negative,   -113		*/
+    LIT64( 0xBFFB000000000000 ),	/* negative,     -4		*/
+    LIT64( 0xBFFC000000000000 ),	/* negative,     -3		*/
+    LIT64( 0xBFFD000000000000 ),	/* negative,     -2		*/
+    LIT64( 0xBFFE000000000000 ),	/* negative,     -1		*/
+    LIT64( 0xBFFF000000000000 ),	/* negative,      0		*/
+    LIT64( 0xC000000000000000 ),	/* negative,      1		*/
+    LIT64( 0xC001000000000000 ),	/* negative,      2		*/
+    LIT64( 0xC002000000000000 ),	/* negative,      3		*/
+    LIT64( 0xC003000000000000 ),	/* negative,      4		*/
+    LIT64( 0xC01C000000000000 ),	/* negative,     29		*/
+    LIT64( 0xC01D000000000000 ),	/* negative,     30		*/
+    LIT64( 0xC01E000000000000 ),	/* negative,     31		*/
+    LIT64( 0xC01F000000000000 ),	/* negative,     32		*/
+    LIT64( 0xC03C000000000000 ),	/* negative,     61		*/
+    LIT64( 0xC03D000000000000 ),	/* negative,     62		*/
+    LIT64( 0xC03E000000000000 ),	/* negative,     63		*/
+    LIT64( 0xC03F000000000000 ),	/* negative,     64		*/
+    LIT64( 0xC070000000000000 ),	/* negative,    113		*/
+    LIT64( 0xC07E000000000000 ),	/* negative,    127		*/
+    LIT64( 0xC07F000000000000 ),	/* negative,    128		*/
+    LIT64( 0xC080000000000000 ),	/* negative,    129		*/
+    LIT64( 0xC3FE000000000000 ),	/* negative,   1023		*/
+    LIT64( 0xC3FF000000000000 ),	/* negative,   1024		*/
+    LIT64( 0xC400000000000000 ),	/* negative,   1025		*/
+    LIT64( 0xFFFD000000000000 ),	/* negative,  16382		*/
+    LIT64( 0xFFFE000000000000 ),	/* negative,  16383		*/
+    LIT64( 0xFFFF000000000000 )		/* negative, infinity or NaN	*/
+};
+
+static const struct { bits64 high, low; } float128P1[ float128NumP1 ] = {
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) }
+};
+
+static const struct { bits64 high, low; } float128P2[ float128NumP2 ] = {
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000001 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000002 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000004 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000008 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000010 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000020 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000040 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000080 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000100 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000200 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000400 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000800 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000002000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000004000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000008000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000010000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000020000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000040000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000080000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000100000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000200000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000400000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000800000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000001000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000002000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000004000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000008000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000010000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000020000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000040000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000080000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000100000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000200000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000400000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000800000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000001000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000002000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000004000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000008000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000010000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000020000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000040000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000080000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000100000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000200000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000400000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000800000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0001000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0002000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0004000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0008000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0010000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0020000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0040000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0080000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0100000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0200000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0400000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0800000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x1000000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x2000000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x4000000000000000 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x8000000000000000 ) },
+    { LIT64( 0x0000000000000001 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000002 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000004 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000008 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000010 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000020 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000040 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000080 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000100 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000200 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000400 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000000800 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000001000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000002000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000004000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000008000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000010000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000020000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000040000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000080000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000100000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000200000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000400000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000000800000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000001000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000002000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000004000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000008000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000010000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000020000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000040000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000080000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000100000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000200000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000400000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000000800000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000001000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000002000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000004000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000008000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000010000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000020000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000040000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000080000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000100000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000200000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000400000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000800000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000C00000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000E00000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000F00000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000F80000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FC0000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FE0000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FF0000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FF8000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFC000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFE000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFF000000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFF800000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFC00000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFE00000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFF00000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFF80000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFC0000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFE0000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFF0000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFF8000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFC000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFE000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFF000000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFF800000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFC00000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFE00000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFF00000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFF80000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFC0000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFE0000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFF0000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFF8000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFC000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFE000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFF000 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFF800 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFC00 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFE00 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFF00 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFF80 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFC0 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFE0 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFF0 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFF8 ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFC ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFE ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x0000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x8000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xC000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xE000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF000000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF800000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFC00000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFE00000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF00000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF80000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFC0000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFE0000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF0000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF8000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFC000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFE000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF000000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF800000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFC00000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFE00000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF00000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF80000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFC0000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFE0000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF0000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF8000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFC000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFE000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF000000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF800000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFC00000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFE00000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF00000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF80000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFC0000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFE0000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF0000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF8000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFC000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFE000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF000000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF800000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFC00000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFE00000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF00000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF80000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFC0000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFE0000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF0000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF8000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFC000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFE000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF000 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF800 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFC00 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFE00 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF00 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF80 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFC0 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFE0 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF0 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF8 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFC ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFE ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFD ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFB ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFF7 ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFEF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFDF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFBF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFF7F ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFEFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFDFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFBFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFF7FF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFEFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFDFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFBFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFF7FFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFEFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFDFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFBFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFF7FFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFEFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFDFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFBFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFF7FFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFEFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFDFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFBFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFF7FFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFEFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFDFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFFBFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFF7FFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFEFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFDFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFFBFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFF7FFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFEFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFDFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFFBFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFF7FFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFEFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFDFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFFBFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFF7FFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFEFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFDFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFFBFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFF7FFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFEFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFDFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFFBFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFF7FFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFEFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFDFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFFBFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFF7FFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFEFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFDFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xFBFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xF7FFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xEFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xDFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0xBFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFF ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFD ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFFB ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFF7 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFEF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFDF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFFBF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFF7F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFEFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFDFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFFBFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFF7FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFEFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFDFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFFBFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFF7FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFEFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFDFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFFBFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFF7FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFEFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFDFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFFBFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFF7FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFEFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFDFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFFBFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFF7FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFEFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFDFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFFBFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFF7FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFEFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFDFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFFBFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFF7FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFEFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFDFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FFBFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FF7FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FEFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FDFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000FBFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000F7FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000EFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000DFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000BFFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00007FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00003FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00001FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000FFFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000007FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000003FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000001FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000FFFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000007FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000003FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000001FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000FFFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000007FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000003FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000001FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000FFFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000007FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000003FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000001FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000FFFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000007FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000003FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000001FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000FFFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000007FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000003FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000001FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000000FFFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000007FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000003FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000001FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000000FFFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000007FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000003FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000001FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000FFF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000000007FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000000003FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000000001FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x00000000000000FF ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000000007F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000000003F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000000001F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x000000000000000F ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000007 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000003 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000001 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0xFFFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x7FFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x3FFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x1FFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0FFFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x07FFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x03FFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x01FFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00FFFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x007FFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x003FFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x001FFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000FFFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0007FFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0003FFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0001FFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000FFFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00007FFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00003FFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00001FFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000FFFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000007FFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000003FFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000001FFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000FFFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000007FFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000003FFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000001FFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000FFFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000007FFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000003FFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000001FFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000FFFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000007FFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000003FFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000001FFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000FFFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000007FFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000003FFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000001FFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000FFFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000007FFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000003FFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000001FFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000FFFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000007FFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000003FFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000001FFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000FFFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000007FFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000003FFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000001FFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000FFF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000007FF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000003FF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000001FF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x00000000000000FF ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000007F ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000003F ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000001F ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x000000000000000F ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000007 ) },
+    { LIT64( 0x0000000000000000 ), LIT64( 0x0000000000000003 ) }
+};
+
+static const uint32 float128NumQInP1 = float128NumQIn * float128NumP1;
+static const uint32 float128NumQOutP1 = float128NumQOut * float128NumP1;
+
+static float128 float128NextQInP1( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    float128 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = float128P1[ sigNum ].low;
+    z.high = float128QIn[ expNum ] | float128P1[ sigNum ].high;
+    ++sigNum;
+    if ( float128NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float128NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float128 float128NextQOutP1( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    float128 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = float128P1[ sigNum ].low;
+    z.high = float128QOut[ expNum ] | float128P1[ sigNum ].high;
+    ++sigNum;
+    if ( float128NumP1 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float128NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static const uint32 float128NumQInP2 = float128NumQIn * float128NumP2;
+static const uint32 float128NumQOutP2 = float128NumQOut * float128NumP2;
+
+static float128 float128NextQInP2( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    float128 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = float128P2[ sigNum ].low;
+    z.high = float128QIn[ expNum ] | float128P2[ sigNum ].high;
+    ++sigNum;
+    if ( float128NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float128NumQIn <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float128 float128NextQOutP2( sequenceT *sequencePtr )
+{
+    int16 expNum, sigNum;
+    float128 z;
+
+    sigNum = sequencePtr->term1Num;
+    expNum = sequencePtr->expNum;
+    z.low = float128P2[ sigNum ].low;
+    z.high = float128QOut[ expNum ] | float128P2[ sigNum ].high;
+    ++sigNum;
+    if ( float128NumP2 <= sigNum ) {
+        sigNum = 0;
+        ++expNum;
+        if ( float128NumQOut <= expNum ) {
+            expNum = 0;
+            sequencePtr->done = TRUE;
+        }
+        sequencePtr->expNum = expNum;
+    }
+    sequencePtr->term1Num = sigNum;
+    return z;
+
+}
+
+static float128 float128RandomQOutP3( void )
+{
+    int16 sigNum1, sigNum2;
+    uint64 sig1Low, sig2Low;
+    float128 z;
+
+    sigNum1 = randomUint8() % float128NumP2;
+    sigNum2 = randomUint8() % float128NumP2;
+    sig1Low = float128P2[ sigNum1 ].low;
+    sig2Low = float128P2[ sigNum2 ].low;
+    z.low = sig1Low + sig2Low;
+    z.high =
+          float128QOut[ randomUint8() % float128NumQOut ]
+        | (   (   float128P2[ sigNum1 ].high
+                + float128P2[ sigNum2 ].high
+                + ( z.low < sig1Low )
+              )
+            & LIT64( 0x0000FFFFFFFFFFFF )
+          );
+    return z;
+
+}
+
+static float128 float128RandomQOutPInf( void )
+{
+    float128 z;
+
+    z.low = randomUint64();
+    z.high =
+          float128QOut[ randomUint8() % float128NumQOut ]
+        | ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
+    return z;
+
+}
+
+enum {
+    float128NumQInfWeightMasks = 14
+};
+
+static const uint64 float128QInfWeightMasks[ float128NumQInfWeightMasks ] = {
+    LIT64( 0x7FFF000000000000 ),
+    LIT64( 0x7FFF000000000000 ),
+    LIT64( 0x3FFF000000000000 ),
+    LIT64( 0x1FFF000000000000 ),
+    LIT64( 0x07FF000000000000 ),
+    LIT64( 0x07FF000000000000 ),
+    LIT64( 0x03FF000000000000 ),
+    LIT64( 0x01FF000000000000 ),
+    LIT64( 0x00FF000000000000 ),
+    LIT64( 0x007F000000000000 ),
+    LIT64( 0x003F000000000000 ),
+    LIT64( 0x001F000000000000 ),
+    LIT64( 0x000F000000000000 ),
+    LIT64( 0x0007000000000000 )
+};
+
+static const uint64 float128QInfWeightOffsets[ float128NumQInfWeightMasks ] = {
+    LIT64( 0x0000000000000000 ),
+    LIT64( 0x0000000000000000 ),
+    LIT64( 0x2000000000000000 ),
+    LIT64( 0x3000000000000000 ),
+    LIT64( 0x3800000000000000 ),
+    LIT64( 0x3C00000000000000 ),
+    LIT64( 0x3E00000000000000 ),
+    LIT64( 0x3F00000000000000 ),
+    LIT64( 0x3F80000000000000 ),
+    LIT64( 0x3FC0000000000000 ),
+    LIT64( 0x3FE0000000000000 ),
+    LIT64( 0x3FF0000000000000 ),
+    LIT64( 0x3FF8000000000000 ),
+    LIT64( 0x3FFC000000000000 )
+};
+
+static float128 float128RandomQInfP3( void )
+{
+    int16 sigNum1, sigNum2;
+    uint64 sig1Low, sig2Low;
+    int8 weightMaskNum;
+    float128 z;
+
+    sigNum1 = randomUint8() % float128NumP2;
+    sigNum2 = randomUint8() % float128NumP2;
+    sig1Low = float128P2[ sigNum1 ].low;
+    sig2Low = float128P2[ sigNum2 ].low;
+    z.low = sig1Low + sig2Low;
+    weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
+    z.high =
+          ( ( (uint64) ( randomUint8() & 1 ) )<<63 )
+        | (   (   ( ( (uint64) randomUint16() )<<48 )
+                & float128QInfWeightMasks[ weightMaskNum ] )
+            + float128QInfWeightOffsets[ weightMaskNum ]
+          )
+        | (   (   float128P2[ sigNum1 ].high
+                + float128P2[ sigNum2 ].high
+                + ( z.low < sig1Low )
+              )
+            & LIT64( 0x0000FFFFFFFFFFFF )
+          );
+    return z;
+
+}
+
+static float128 float128RandomQInfPInf( void )
+{
+    int8 weightMaskNum;
+    float128 z;
+
+    weightMaskNum = randomUint8() % float128NumQInfWeightMasks;
+    z.low = randomUint64();
+    z.high =
+          ( ( (uint64) ( randomUint8() & 1 ) )<<63 )
+        | (   (   ( ( (uint64) randomUint16() )<<48 )
+                & float128QInfWeightMasks[ weightMaskNum ] )
+            + float128QInfWeightOffsets[ weightMaskNum ]
+          )
+        | ( randomUint64() & LIT64( 0x0000FFFFFFFFFFFF ) );
+    return z;
+
+}
+
+static float128 float128Random( void )
+{
+
+    switch ( randomUint8() & 7 ) {
+     case 0:
+     case 1:
+     case 2:
+        return float128RandomQOutP3();
+     case 3:
+        return float128RandomQOutPInf();
+     case 4:
+     case 5:
+     case 6:
+        return float128RandomQInfP3();
+     case 7:
+        return float128RandomQInfPInf();
+    }
+
+}
+
+#endif
+
+static int8 level = 0;
+
+void testCases_setLevel( int8 levelIn )
+{
+
+    if ( ( levelIn < 1 ) || ( 2 < levelIn ) ) {
+        fail( "Invalid testing level: %d", levelIn );
+    }
+    level = levelIn;
+
+}
+
+static int8 sequenceType;
+static sequenceT sequenceA, sequenceB;
+static int8 subcase;
+
+uint32 testCases_total;
+flag testCases_done;
+
+static float32 current_a_float32;
+static float32 current_b_float32;
+static float64 current_a_float64;
+static float64 current_b_float64;
+#ifdef FLOATX80
+static floatx80 current_a_floatx80;
+static floatx80 current_b_floatx80;
+#endif
+#ifdef FLOAT128
+static float128 current_a_float128;
+static float128 current_b_float128;
+#endif
+
+void testCases_initSequence( int8 sequenceTypeIn )
+{
+
+    sequenceType = sequenceTypeIn;
+    sequenceA.term2Num = 0;
+    sequenceA.term1Num = 0;
+    sequenceA.expNum = 0;
+    sequenceA.done = FALSE;
+    sequenceB.term2Num = 0;
+    sequenceB.term1Num = 0;
+    sequenceB.expNum = 0;
+    sequenceB.done = FALSE;
+    subcase = 0;
+    switch ( level ) {
+     case 1:
+        switch ( sequenceTypeIn ) {
+         case testCases_sequence_a_int32:
+            testCases_total = 3 * int32NumP1;
+            break;
+#ifdef BITS64
+         case testCases_sequence_a_int64:
+            testCases_total = 3 * int64NumP1;
+            break;
+#endif
+         case testCases_sequence_a_float32:
+            testCases_total = 3 * float32NumQOutP1;
+            break;
+         case testCases_sequence_ab_float32:
+            testCases_total = 6 * float32NumQInP1 * float32NumQInP1;
+            current_a_float32 = float32NextQInP1( &sequenceA );
+            break;
+         case testCases_sequence_a_float64:
+            testCases_total = 3 * float64NumQOutP1;
+            break;
+         case testCases_sequence_ab_float64:
+            testCases_total = 6 * float64NumQInP1 * float64NumQInP1;
+            current_a_float64 = float64NextQInP1( &sequenceA );
+            break;
+#ifdef FLOATX80
+         case testCases_sequence_a_floatx80:
+            testCases_total = 3 * floatx80NumQOutP1;
+            break;
+         case testCases_sequence_ab_floatx80:
+            testCases_total = 6 * floatx80NumQInP1 * floatx80NumQInP1;
+            current_a_floatx80 = floatx80NextQInP1( &sequenceA );
+            break;
+#endif
+#ifdef FLOAT128
+         case testCases_sequence_a_float128:
+            testCases_total = 3 * float128NumQOutP1;
+            break;
+         case testCases_sequence_ab_float128:
+            testCases_total = 6 * float128NumQInP1 * float128NumQInP1;
+            current_a_float128 = float128NextQInP1( &sequenceA );
+            break;
+#endif
+        }
+        break;
+     case 2:
+        switch ( sequenceTypeIn ) {
+         case testCases_sequence_a_int32:
+            testCases_total = 2 * int32NumP2;
+            break;
+#ifdef BITS64
+         case testCases_sequence_a_int64:
+            testCases_total = 2 * int64NumP2;
+            break;
+#endif
+         case testCases_sequence_a_float32:
+            testCases_total = 2 * float32NumQOutP2;
+            break;
+         case testCases_sequence_ab_float32:
+            testCases_total = 2 * float32NumQInP2 * float32NumQInP2;
+            current_a_float32 = float32NextQInP2( &sequenceA );
+            break;
+         case testCases_sequence_a_float64:
+            testCases_total = 2 * float64NumQOutP2;
+            break;
+         case testCases_sequence_ab_float64:
+            testCases_total = 2 * float64NumQInP2 * float64NumQInP2;
+            current_a_float64 = float64NextQInP2( &sequenceA );
+            break;
+#ifdef FLOATX80
+         case testCases_sequence_a_floatx80:
+            testCases_total = 2 * floatx80NumQOutP2;
+            break;
+         case testCases_sequence_ab_floatx80:
+            testCases_total = 2 * floatx80NumQInP2 * floatx80NumQInP2;
+            current_a_floatx80 = floatx80NextQInP2( &sequenceA );
+            break;
+#endif
+#ifdef FLOAT128
+         case testCases_sequence_a_float128:
+            testCases_total = 2 * float128NumQOutP2;
+            break;
+         case testCases_sequence_ab_float128:
+            testCases_total = 2 * float128NumQInP2 * float128NumQInP2;
+            current_a_float128 = float128NextQInP2( &sequenceA );
+            break;
+#endif
+        }
+        break;
+    }
+    testCases_done = FALSE;
+
+}
+
+int32 testCases_a_int32;
+#ifdef BITS64
+int64 testCases_a_int64;
+#endif
+float32 testCases_a_float32;
+float32 testCases_b_float32;
+float64 testCases_a_float64;
+float64 testCases_b_float64;
+#ifdef FLOATX80
+floatx80 testCases_a_floatx80;
+floatx80 testCases_b_floatx80;
+#endif
+#ifdef FLOAT128
+float128 testCases_a_float128;
+float128 testCases_b_float128;
+#endif
+
+void testCases_next( void )
+{
+
+    switch ( level ) {
+     case 1:
+        switch ( sequenceType ) {
+         case testCases_sequence_a_int32:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_int32 = int32RandomP3();
+                break;
+             case 1:
+                testCases_a_int32 = int32RandomPInf();
+                break;
+             case 2:
+                testCases_a_int32 = int32NextP1( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#ifdef BITS64
+         case testCases_sequence_a_int64:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_int64 = int64RandomP3();
+                break;
+             case 1:
+                testCases_a_int64 = int64RandomPInf();
+                break;
+             case 2:
+                testCases_a_int64 = int64NextP1( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#endif
+         case testCases_sequence_a_float32:
+            switch ( subcase ) {
+             case 0:
+             case 1:
+                testCases_a_float32 = float32Random();
+                break;
+             case 2:
+                testCases_a_float32 = float32NextQOutP1( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_float32:
+            switch ( subcase ) {
+             case 0:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_float32 = float32NextQInP1( &sequenceA );
+                }
+                current_b_float32 = float32NextQInP1( &sequenceB );
+             case 2:
+             case 4:
+                testCases_a_float32 = float32Random();
+                testCases_b_float32 = float32Random();
+                break;
+             case 1:
+                testCases_a_float32 = current_a_float32;
+                testCases_b_float32 = float32Random();
+                break;
+             case 3:
+                testCases_a_float32 = float32Random();
+                testCases_b_float32 = current_b_float32;
+                break;
+             case 5:
+                testCases_a_float32 = current_a_float32;
+                testCases_b_float32 = current_b_float32;
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_a_float64:
+            switch ( subcase ) {
+             case 0:
+             case 1:
+                testCases_a_float64 = float64Random();
+                break;
+             case 2:
+                testCases_a_float64 = float64NextQOutP1( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_float64:
+            switch ( subcase ) {
+             case 0:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_float64 = float64NextQInP1( &sequenceA );
+                }
+                current_b_float64 = float64NextQInP1( &sequenceB );
+             case 2:
+             case 4:
+                testCases_a_float64 = float64Random();
+                testCases_b_float64 = float64Random();
+                break;
+             case 1:
+                testCases_a_float64 = current_a_float64;
+                testCases_b_float64 = float64Random();
+                break;
+             case 3:
+                testCases_a_float64 = float64Random();
+                testCases_b_float64 = current_b_float64;
+                break;
+             case 5:
+                testCases_a_float64 = current_a_float64;
+                testCases_b_float64 = current_b_float64;
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#ifdef FLOATX80
+         case testCases_sequence_a_floatx80:
+            switch ( subcase ) {
+             case 0:
+             case 1:
+                testCases_a_floatx80 = floatx80Random();
+                break;
+             case 2:
+                testCases_a_floatx80 = floatx80NextQOutP1( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_floatx80:
+            switch ( subcase ) {
+             case 0:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_floatx80 = floatx80NextQInP1( &sequenceA );
+                }
+                current_b_floatx80 = floatx80NextQInP1( &sequenceB );
+             case 2:
+             case 4:
+                testCases_a_floatx80 = floatx80Random();
+                testCases_b_floatx80 = floatx80Random();
+                break;
+             case 1:
+                testCases_a_floatx80 = current_a_floatx80;
+                testCases_b_floatx80 = floatx80Random();
+                break;
+             case 3:
+                testCases_a_floatx80 = floatx80Random();
+                testCases_b_floatx80 = current_b_floatx80;
+                break;
+             case 5:
+                testCases_a_floatx80 = current_a_floatx80;
+                testCases_b_floatx80 = current_b_floatx80;
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#endif
+#ifdef FLOAT128
+         case testCases_sequence_a_float128:
+            switch ( subcase ) {
+             case 0:
+             case 1:
+                testCases_a_float128 = float128Random();
+                break;
+             case 2:
+                testCases_a_float128 = float128NextQOutP1( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_float128:
+            switch ( subcase ) {
+             case 0:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_float128 = float128NextQInP1( &sequenceA );
+                }
+                current_b_float128 = float128NextQInP1( &sequenceB );
+             case 2:
+             case 4:
+                testCases_a_float128 = float128Random();
+                testCases_b_float128 = float128Random();
+                break;
+             case 1:
+                testCases_a_float128 = current_a_float128;
+                testCases_b_float128 = float128Random();
+                break;
+             case 3:
+                testCases_a_float128 = float128Random();
+                testCases_b_float128 = current_b_float128;
+                break;
+             case 5:
+                testCases_a_float128 = current_a_float128;
+                testCases_b_float128 = current_b_float128;
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#endif
+        }
+        break;
+     case 2:
+        switch ( sequenceType ) {
+         case testCases_sequence_a_int32:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_int32 = int32RandomP3();
+                break;
+             case 2:
+                testCases_a_int32 = int32RandomPInf();
+                break;
+             case 3:
+                subcase = -1;
+             case 1:
+                testCases_a_int32 = int32NextP2( &sequenceA );
+                testCases_done = sequenceA.done;
+                break;
+            }
+            ++subcase;
+            break;
+#ifdef BITS64
+         case testCases_sequence_a_int64:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_int64 = int64RandomP3();
+                break;
+             case 2:
+                testCases_a_int64 = int64RandomPInf();
+                break;
+             case 3:
+                subcase = -1;
+             case 1:
+                testCases_a_int64 = int64NextP2( &sequenceA );
+                testCases_done = sequenceA.done;
+                break;
+            }
+            ++subcase;
+            break;
+#endif
+         case testCases_sequence_a_float32:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_float32 = float32Random();
+                break;
+             case 1:
+                testCases_a_float32 = float32NextQOutP2( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_float32:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_float32 = float32Random();
+                testCases_b_float32 = float32Random();
+                break;
+             case 1:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_float32 = float32NextQInP2( &sequenceA );
+                }
+                testCases_a_float32 = current_a_float32;
+                testCases_b_float32 = float32NextQInP2( &sequenceB );
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_a_float64:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_float64 = float64Random();
+                break;
+             case 1:
+                testCases_a_float64 = float64NextQOutP2( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_float64:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_float64 = float64Random();
+                testCases_b_float64 = float64Random();
+                break;
+             case 1:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_float64 = float64NextQInP2( &sequenceA );
+                }
+                testCases_a_float64 = current_a_float64;
+                testCases_b_float64 = float64NextQInP2( &sequenceB );
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#ifdef FLOATX80
+         case testCases_sequence_a_floatx80:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_floatx80 = floatx80Random();
+                break;
+             case 1:
+                testCases_a_floatx80 = floatx80NextQOutP2( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_floatx80:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_floatx80 = floatx80Random();
+                testCases_b_floatx80 = floatx80Random();
+                break;
+             case 1:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_floatx80 = floatx80NextQInP2( &sequenceA );
+                }
+                testCases_a_floatx80 = current_a_floatx80;
+                testCases_b_floatx80 = floatx80NextQInP2( &sequenceB );
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#endif
+#ifdef FLOAT128
+         case testCases_sequence_a_float128:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_float128 = float128Random();
+                break;
+             case 1:
+                testCases_a_float128 = float128NextQOutP2( &sequenceA );
+                testCases_done = sequenceA.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+         case testCases_sequence_ab_float128:
+            switch ( subcase ) {
+             case 0:
+                testCases_a_float128 = float128Random();
+                testCases_b_float128 = float128Random();
+                break;
+             case 1:
+                if ( sequenceB.done ) {
+                    sequenceB.done = FALSE;
+                    current_a_float128 = float128NextQInP2( &sequenceA );
+                }
+                testCases_a_float128 = current_a_float128;
+                testCases_b_float128 = float128NextQInP2( &sequenceB );
+                testCases_done = sequenceA.done & sequenceB.done;
+                subcase = -1;
+                break;
+            }
+            ++subcase;
+            break;
+#endif
+        }
+        break;
+    }
+
+}
+
diff --git a/testfloat/testCases.h b/testfloat/testCases.h
new file mode 100644
index 00000000000..ed6ea2be46b
--- /dev/null
+++ b/testfloat/testCases.h
@@ -0,0 +1,69 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+void testCases_setLevel( int8 );
+
+void testCases_initSequence( int8 );
+enum {
+    testCases_sequence_a_int32,
+#ifdef BITS64
+    testCases_sequence_a_int64,
+#endif
+    testCases_sequence_a_float32,
+    testCases_sequence_ab_float32,
+    testCases_sequence_a_float64,
+    testCases_sequence_ab_float64,
+#ifdef FLOATX80
+    testCases_sequence_a_floatx80,
+    testCases_sequence_ab_floatx80,
+#endif
+#ifdef FLOAT128
+    testCases_sequence_a_float128,
+    testCases_sequence_ab_float128,
+#endif
+};
+
+extern uint32 testCases_total;
+extern flag testCases_done;
+
+void testCases_next( void );
+
+extern int32 testCases_a_int32;
+#ifdef BITS64
+extern int64 testCases_a_int64;
+#endif
+extern float32 testCases_a_float32;
+extern float32 testCases_b_float32;
+extern float64 testCases_a_float64;
+extern float64 testCases_b_float64;
+#ifdef FLOATX80
+extern floatx80 testCases_a_floatx80;
+extern floatx80 testCases_b_floatx80;
+#endif
+#ifdef FLOAT128
+extern float128 testCases_a_float128;
+extern float128 testCases_b_float128;
+#endif
+
diff --git a/testfloat/testFunction.c b/testfloat/testFunction.c
new file mode 100644
index 00000000000..687563b0d75
--- /dev/null
+++ b/testfloat/testFunction.c
@@ -0,0 +1,1149 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include "milieu.h"
+#include "softfloat.h"
+#include "testCases.h"
+#include "testLoops.h"
+#include "systmodes.h"
+#include "systflags.h"
+#include "systfloat.h"
+#include "testFunction.h"
+
+const functionT functions[ NUM_FUNCTIONS ] = {
+    { 0, 0, 0, 0 },
+    { "int32_to_float32",                1, FALSE, TRUE  },
+    { "int32_to_float64",                1, FALSE, FALSE },
+    { "int32_to_floatx80",               1, FALSE, FALSE },
+    { "int32_to_float128",               1, FALSE, FALSE },
+    { "int64_to_float32",                1, FALSE, TRUE  },
+    { "int64_to_float64",                1, FALSE, TRUE  },
+    { "int64_to_floatx80",               1, FALSE, FALSE },
+    { "int64_to_float128",               1, FALSE, FALSE },
+    { "float32_to_int32",                1, FALSE, TRUE  },
+    { "float32_to_int32_round_to_zero",  1, FALSE, FALSE },
+    { "float32_to_int64",                1, FALSE, TRUE  },
+    { "float32_to_int64_round_to_zero",  1, FALSE, FALSE },
+    { "float32_to_float64",              1, FALSE, FALSE },
+    { "float32_to_floatx80",             1, FALSE, FALSE },
+    { "float32_to_float128",             1, FALSE, FALSE },
+    { "float32_round_to_int",            1, FALSE, TRUE  },
+    { "float32_add",                     2, FALSE, TRUE  },
+    { "float32_sub",                     2, FALSE, TRUE  },
+    { "float32_mul",                     2, FALSE, TRUE  },
+    { "float32_div",                     2, FALSE, TRUE  },
+    { "float32_rem",                     2, FALSE, FALSE },
+    { "float32_sqrt",                    1, FALSE, TRUE  },
+    { "float32_eq",                      2, FALSE, FALSE },
+    { "float32_le",                      2, FALSE, FALSE },
+    { "float32_lt",                      2, FALSE, FALSE },
+    { "float32_eq_signaling",            2, FALSE, FALSE },
+    { "float32_le_quiet",                2, FALSE, FALSE },
+    { "float32_lt_quiet",                2, FALSE, FALSE },
+    { "float64_to_int32",                1, FALSE, TRUE  },
+    { "float64_to_int32_round_to_zero",  1, FALSE, FALSE },
+    { "float64_to_int64",                1, FALSE, TRUE  },
+    { "float64_to_int64_round_to_zero",  1, FALSE, FALSE },
+    { "float64_to_float32",              1, FALSE, TRUE  },
+    { "float64_to_floatx80",             1, FALSE, FALSE },
+    { "float64_to_float128",             1, FALSE, FALSE },
+    { "float64_round_to_int",            1, FALSE, TRUE  },
+    { "float64_add",                     2, FALSE, TRUE  },
+    { "float64_sub",                     2, FALSE, TRUE  },
+    { "float64_mul",                     2, FALSE, TRUE  },
+    { "float64_div",                     2, FALSE, TRUE  },
+    { "float64_rem",                     2, FALSE, FALSE },
+    { "float64_sqrt",                    1, FALSE, TRUE  },
+    { "float64_eq",                      2, FALSE, FALSE },
+    { "float64_le",                      2, FALSE, FALSE },
+    { "float64_lt",                      2, FALSE, FALSE },
+    { "float64_eq_signaling",            2, FALSE, FALSE },
+    { "float64_le_quiet",                2, FALSE, FALSE },
+    { "float64_lt_quiet",                2, FALSE, FALSE },
+    { "floatx80_to_int32",               1, FALSE, TRUE  },
+    { "floatx80_to_int32_round_to_zero", 1, FALSE, FALSE },
+    { "floatx80_to_int64",               1, FALSE, TRUE  },
+    { "floatx80_to_int64_round_to_zero", 1, FALSE, FALSE },
+    { "floatx80_to_float32",             1, FALSE, TRUE  },
+    { "floatx80_to_float64",             1, FALSE, TRUE  },
+    { "floatx80_to_float128",            1, FALSE, FALSE },
+    { "floatx80_round_to_int",           1, FALSE, TRUE  },
+    { "floatx80_add",                    2, TRUE,  TRUE  },
+    { "floatx80_sub",                    2, TRUE,  TRUE  },
+    { "floatx80_mul",                    2, TRUE,  TRUE  },
+    { "floatx80_div",                    2, TRUE,  TRUE  },
+    { "floatx80_rem",                    2, FALSE, FALSE },
+    { "floatx80_sqrt",                   1, TRUE,  TRUE  },
+    { "floatx80_eq",                     2, FALSE, FALSE },
+    { "floatx80_le",                     2, FALSE, FALSE },
+    { "floatx80_lt",                     2, FALSE, FALSE },
+    { "floatx80_eq_signaling",           2, FALSE, FALSE },
+    { "floatx80_le_quiet",               2, FALSE, FALSE },
+    { "floatx80_lt_quiet",               2, FALSE, FALSE },
+    { "float128_to_int32",               1, FALSE, TRUE  },
+    { "float128_to_int32_round_to_zero", 1, FALSE, FALSE },
+    { "float128_to_int64",               1, FALSE, TRUE  },
+    { "float128_to_int64_round_to_zero", 1, FALSE, FALSE },
+    { "float128_to_float32",             1, FALSE, TRUE  },
+    { "float128_to_float64",             1, FALSE, TRUE  },
+    { "float128_to_floatx80",            1, FALSE, TRUE  },
+    { "float128_round_to_int",           1, FALSE, TRUE  },
+    { "float128_add",                    2, FALSE, TRUE  },
+    { "float128_sub",                    2, FALSE, TRUE  },
+    { "float128_mul",                    2, FALSE, TRUE  },
+    { "float128_div",                    2, FALSE, TRUE  },
+    { "float128_rem",                    2, FALSE, FALSE },
+    { "float128_sqrt",                   1, FALSE, TRUE  },
+    { "float128_eq",                     2, FALSE, FALSE },
+    { "float128_le",                     2, FALSE, FALSE },
+    { "float128_lt",                     2, FALSE, FALSE },
+    { "float128_eq_signaling",           2, FALSE, FALSE },
+    { "float128_le_quiet",               2, FALSE, FALSE },
+    { "float128_lt_quiet",               2, FALSE, FALSE },
+};
+
+const flag functionExists[ NUM_FUNCTIONS ] = {
+    0,
+#ifdef SYST_INT32_TO_FLOAT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT32_TO_FLOAT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT32_TO_FLOATX80
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT32_TO_FLOAT128
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT64_TO_FLOAT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT64_TO_FLOAT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT64_TO_FLOATX80
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_INT64_TO_FLOAT128
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_FLOATX80
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT128
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_ROUND_TO_INT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_ADD
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_SUB
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_MUL
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_DIV
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_REM
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_SQRT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_EQ
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_LE
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_LT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_EQ_SIGNALING
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_LE_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT32_LT_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_FLOATX80
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT128
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_ROUND_TO_INT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_ADD
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_SUB
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_MUL
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_DIV
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_REM
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_SQRT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_EQ
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_LE
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_LT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_EQ_SIGNALING
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_LE_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT64_LT_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT128
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_ROUND_TO_INT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_ADD
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_SUB
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_MUL
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_DIV
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_REM
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_SQRT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_EQ
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_LE
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_LT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_EQ_SIGNALING
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_LE_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOATX80_LT_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT32
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT64
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_TO_FLOATX80
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_ROUND_TO_INT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_ADD
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_SUB
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_MUL
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_DIV
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_REM
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_SQRT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_EQ
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_LE
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_LT
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_EQ_SIGNALING
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_LE_QUIET
+    1,
+#else
+    0,
+#endif
+#ifdef SYST_FLOAT128_LT_QUIET
+    1,
+#else
+    0,
+#endif
+};
+
+static void
+ testFunctionVariety(
+     uint8 functionCode, int8 roundingPrecision, int8 roundingMode )
+{
+    uint8 roundingCode;
+
+    functionName = functions[ functionCode ].name;
+#ifdef FLOATX80
+    if ( roundingPrecision == 32 ) {
+        roundingPrecisionName = "32";
+    }
+    else if ( roundingPrecision == 64 ) {
+        roundingPrecisionName = "64";
+    }
+    else if ( roundingPrecision == 80 ) {
+        roundingPrecisionName = "80";
+    }
+    else {
+        roundingPrecision = 80;
+        roundingPrecisionName = 0;
+    }
+    floatx80_rounding_precision = roundingPrecision;
+    syst_float_set_rounding_precision( roundingPrecision );
+#endif
+    switch ( roundingMode ) {
+     case 0:
+        roundingModeName = 0;
+        roundingCode = float_round_nearest_even;
+        break;
+     case ROUND_NEAREST_EVEN:
+        roundingModeName = "nearest_even";
+        roundingCode = float_round_nearest_even;
+        break;
+     case ROUND_TO_ZERO:
+        roundingModeName = "to_zero";
+        roundingCode = float_round_to_zero;
+        break;
+     case ROUND_DOWN:
+        roundingModeName = "down";
+        roundingCode = float_round_down;
+        break;
+     case ROUND_UP:
+        roundingModeName = "up";
+        roundingCode = float_round_up;
+        break;
+    }
+    float_rounding_mode = roundingCode;
+    syst_float_set_rounding_mode( roundingCode );
+    fputs( "Testing ", stderr );
+    writeFunctionName( stderr );
+    fputs( ".\n", stderr );
+    switch ( functionCode ) {
+#ifdef SYST_INT32_TO_FLOAT32
+     case INT32_TO_FLOAT32:
+        test_a_int32_z_float32( int32_to_float32, syst_int32_to_float32 );
+        break;
+#endif
+#ifdef SYST_INT32_TO_FLOAT64
+     case INT32_TO_FLOAT64:
+        test_a_int32_z_float64( int32_to_float64, syst_int32_to_float64 );
+        break;
+#endif
+#ifdef SYST_INT32_TO_FLOATX80
+     case INT32_TO_FLOATX80:
+        test_a_int32_z_floatx80( int32_to_floatx80, syst_int32_to_floatx80 );
+        break;
+#endif
+#ifdef SYST_INT32_TO_FLOAT128
+     case INT32_TO_FLOAT128:
+        test_a_int32_z_float128( int32_to_float128, syst_int32_to_float128 );
+        break;
+#endif
+#ifdef SYST_INT64_TO_FLOAT32
+     case INT64_TO_FLOAT32:
+        test_a_int64_z_float32( int64_to_float32, syst_int64_to_float32 );
+        break;
+#endif
+#ifdef SYST_INT64_TO_FLOAT64
+     case INT64_TO_FLOAT64:
+        test_a_int64_z_float64( int64_to_float64, syst_int64_to_float64 );
+        break;
+#endif
+#ifdef SYST_INT64_TO_FLOATX80
+     case INT64_TO_FLOATX80:
+        test_a_int64_z_floatx80( int64_to_floatx80, syst_int64_to_floatx80 );
+        break;
+#endif
+#ifdef SYST_INT64_TO_FLOAT128
+     case INT64_TO_FLOAT128:
+        test_a_int64_z_float128( int64_to_float128, syst_int64_to_float128 );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT32
+     case FLOAT32_TO_INT32:
+        test_a_float32_z_int32( float32_to_int32, syst_float32_to_int32 );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT32_ROUND_TO_ZERO
+     case FLOAT32_TO_INT32_ROUND_TO_ZERO:
+        test_a_float32_z_int32(
+            float32_to_int32_round_to_zero,
+            syst_float32_to_int32_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT64
+     case FLOAT32_TO_INT64:
+        test_a_float32_z_int64( float32_to_int64, syst_float32_to_int64 );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_INT64_ROUND_TO_ZERO
+     case FLOAT32_TO_INT64_ROUND_TO_ZERO:
+        test_a_float32_z_int64(
+            float32_to_int64_round_to_zero,
+            syst_float32_to_int64_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT64
+     case FLOAT32_TO_FLOAT64:
+        test_a_float32_z_float64(
+            float32_to_float64, syst_float32_to_float64 );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_FLOATX80
+     case FLOAT32_TO_FLOATX80:
+        test_a_float32_z_floatx80(
+            float32_to_floatx80, syst_float32_to_floatx80 );
+        break;
+#endif
+#ifdef SYST_FLOAT32_TO_FLOAT128
+     case FLOAT32_TO_FLOAT128:
+        test_a_float32_z_float128(
+            float32_to_float128, syst_float32_to_float128 );
+        break;
+#endif
+#ifdef SYST_FLOAT32_ROUND_TO_INT
+     case FLOAT32_ROUND_TO_INT:
+        test_az_float32( float32_round_to_int, syst_float32_round_to_int );
+        break;
+#endif
+#ifdef SYST_FLOAT32_ADD
+     case FLOAT32_ADD:
+        test_abz_float32( float32_add, syst_float32_add );
+        break;
+#endif
+#ifdef SYST_FLOAT32_SUB
+     case FLOAT32_SUB:
+        test_abz_float32( float32_sub, syst_float32_sub );
+        break;
+#endif
+#ifdef SYST_FLOAT32_MUL
+     case FLOAT32_MUL:
+        test_abz_float32( float32_mul, syst_float32_mul );
+        break;
+#endif
+#ifdef SYST_FLOAT32_DIV
+     case FLOAT32_DIV:
+        test_abz_float32( float32_div, syst_float32_div );
+        break;
+#endif
+#ifdef SYST_FLOAT32_REM
+     case FLOAT32_REM:
+        test_abz_float32( float32_rem, syst_float32_rem );
+        break;
+#endif
+#ifdef SYST_FLOAT32_SQRT
+     case FLOAT32_SQRT:
+        test_az_float32( float32_sqrt, syst_float32_sqrt );
+        break;
+#endif
+#ifdef SYST_FLOAT32_EQ
+     case FLOAT32_EQ:
+        test_ab_float32_z_flag( float32_eq, syst_float32_eq );
+        break;
+#endif
+#ifdef SYST_FLOAT32_LE
+     case FLOAT32_LE:
+        test_ab_float32_z_flag( float32_le, syst_float32_le );
+        break;
+#endif
+#ifdef SYST_FLOAT32_LT
+     case FLOAT32_LT:
+        test_ab_float32_z_flag( float32_lt, syst_float32_lt );
+        break;
+#endif
+#ifdef SYST_FLOAT32_EQ_SIGNALING
+     case FLOAT32_EQ_SIGNALING:
+        test_ab_float32_z_flag(
+            float32_eq_signaling, syst_float32_eq_signaling );
+        break;
+#endif
+#ifdef SYST_FLOAT32_LE_QUIET
+     case FLOAT32_LE_QUIET:
+        test_ab_float32_z_flag( float32_le_quiet, syst_float32_le_quiet );
+        break;
+#endif
+#ifdef SYST_FLOAT32_LT_QUIET
+     case FLOAT32_LT_QUIET:
+        test_ab_float32_z_flag( float32_lt_quiet, syst_float32_lt_quiet );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT32
+     case FLOAT64_TO_INT32:
+        test_a_float64_z_int32( float64_to_int32, syst_float64_to_int32 );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT32_ROUND_TO_ZERO
+     case FLOAT64_TO_INT32_ROUND_TO_ZERO:
+        test_a_float64_z_int32(
+            float64_to_int32_round_to_zero,
+            syst_float64_to_int32_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT64
+     case FLOAT64_TO_INT64:
+        test_a_float64_z_int64( float64_to_int64, syst_float64_to_int64 );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_INT64_ROUND_TO_ZERO
+     case FLOAT64_TO_INT64_ROUND_TO_ZERO:
+        test_a_float64_z_int64(
+            float64_to_int64_round_to_zero,
+            syst_float64_to_int64_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT32
+     case FLOAT64_TO_FLOAT32:
+        test_a_float64_z_float32(
+            float64_to_float32, syst_float64_to_float32 );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_FLOATX80
+     case FLOAT64_TO_FLOATX80:
+        test_a_float64_z_floatx80(
+            float64_to_floatx80, syst_float64_to_floatx80 );
+        break;
+#endif
+#ifdef SYST_FLOAT64_TO_FLOAT128
+     case FLOAT64_TO_FLOAT128:
+        test_a_float64_z_float128(
+            float64_to_float128, syst_float64_to_float128 );
+        break;
+#endif
+#ifdef SYST_FLOAT64_ROUND_TO_INT
+     case FLOAT64_ROUND_TO_INT:
+        test_az_float64( float64_round_to_int, syst_float64_round_to_int );
+        break;
+#endif
+#ifdef SYST_FLOAT64_ADD
+     case FLOAT64_ADD:
+        test_abz_float64( float64_add, syst_float64_add );
+        break;
+#endif
+#ifdef SYST_FLOAT64_SUB
+     case FLOAT64_SUB:
+        test_abz_float64( float64_sub, syst_float64_sub );
+        break;
+#endif
+#ifdef SYST_FLOAT64_MUL
+     case FLOAT64_MUL:
+        test_abz_float64( float64_mul, syst_float64_mul );
+        break;
+#endif
+#ifdef SYST_FLOAT64_DIV
+     case FLOAT64_DIV:
+        test_abz_float64( float64_div, syst_float64_div );
+        break;
+#endif
+#ifdef SYST_FLOAT64_REM
+     case FLOAT64_REM:
+        test_abz_float64( float64_rem, syst_float64_rem );
+        break;
+#endif
+#ifdef SYST_FLOAT64_SQRT
+     case FLOAT64_SQRT:
+        test_az_float64( float64_sqrt, syst_float64_sqrt );
+        break;
+#endif
+#ifdef SYST_FLOAT64_EQ
+     case FLOAT64_EQ:
+        test_ab_float64_z_flag( float64_eq, syst_float64_eq );
+        break;
+#endif
+#ifdef SYST_FLOAT64_LE
+     case FLOAT64_LE:
+        test_ab_float64_z_flag( float64_le, syst_float64_le );
+        break;
+#endif
+#ifdef SYST_FLOAT64_LT
+     case FLOAT64_LT:
+        test_ab_float64_z_flag( float64_lt, syst_float64_lt );
+        break;
+#endif
+#ifdef SYST_FLOAT64_EQ_SIGNALING
+     case FLOAT64_EQ_SIGNALING:
+        test_ab_float64_z_flag(
+            float64_eq_signaling, syst_float64_eq_signaling );
+        break;
+#endif
+#ifdef SYST_FLOAT64_LE_QUIET
+     case FLOAT64_LE_QUIET:
+        test_ab_float64_z_flag( float64_le_quiet, syst_float64_le_quiet );
+        break;
+#endif
+#ifdef SYST_FLOAT64_LT_QUIET
+     case FLOAT64_LT_QUIET:
+        test_ab_float64_z_flag( float64_lt_quiet, syst_float64_lt_quiet );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT32
+     case FLOATX80_TO_INT32:
+        test_a_floatx80_z_int32( floatx80_to_int32, syst_floatx80_to_int32 );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT32_ROUND_TO_ZERO
+     case FLOATX80_TO_INT32_ROUND_TO_ZERO:
+        test_a_floatx80_z_int32(
+            floatx80_to_int32_round_to_zero,
+            syst_floatx80_to_int32_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT64
+     case FLOATX80_TO_INT64:
+        test_a_floatx80_z_int64( floatx80_to_int64, syst_floatx80_to_int64 );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_INT64_ROUND_TO_ZERO
+     case FLOATX80_TO_INT64_ROUND_TO_ZERO:
+        test_a_floatx80_z_int64(
+            floatx80_to_int64_round_to_zero,
+            syst_floatx80_to_int64_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT32
+     case FLOATX80_TO_FLOAT32:
+        test_a_floatx80_z_float32(
+            floatx80_to_float32, syst_floatx80_to_float32 );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT64
+     case FLOATX80_TO_FLOAT64:
+        test_a_floatx80_z_float64(
+            floatx80_to_float64, syst_floatx80_to_float64 );
+        break;
+#endif
+#ifdef SYST_FLOATX80_TO_FLOAT128
+     case FLOATX80_TO_FLOAT128:
+        test_a_floatx80_z_float128(
+            floatx80_to_float128, syst_floatx80_to_float128 );
+        break;
+#endif
+#ifdef SYST_FLOATX80_ROUND_TO_INT
+     case FLOATX80_ROUND_TO_INT:
+        test_az_floatx80( floatx80_round_to_int, syst_floatx80_round_to_int );
+        break;
+#endif
+#ifdef SYST_FLOATX80_ADD
+     case FLOATX80_ADD:
+        test_abz_floatx80( floatx80_add, syst_floatx80_add );
+        break;
+#endif
+#ifdef SYST_FLOATX80_SUB
+     case FLOATX80_SUB:
+        test_abz_floatx80( floatx80_sub, syst_floatx80_sub );
+        break;
+#endif
+#ifdef SYST_FLOATX80_MUL
+     case FLOATX80_MUL:
+        test_abz_floatx80( floatx80_mul, syst_floatx80_mul );
+        break;
+#endif
+#ifdef SYST_FLOATX80_DIV
+     case FLOATX80_DIV:
+        test_abz_floatx80( floatx80_div, syst_floatx80_div );
+        break;
+#endif
+#ifdef SYST_FLOATX80_REM
+     case FLOATX80_REM:
+        test_abz_floatx80( floatx80_rem, syst_floatx80_rem );
+        break;
+#endif
+#ifdef SYST_FLOATX80_SQRT
+     case FLOATX80_SQRT:
+        test_az_floatx80( floatx80_sqrt, syst_floatx80_sqrt );
+        break;
+#endif
+#ifdef SYST_FLOATX80_EQ
+     case FLOATX80_EQ:
+        test_ab_floatx80_z_flag( floatx80_eq, syst_floatx80_eq );
+        break;
+#endif
+#ifdef SYST_FLOATX80_LE
+     case FLOATX80_LE:
+        test_ab_floatx80_z_flag( floatx80_le, syst_floatx80_le );
+        break;
+#endif
+#ifdef SYST_FLOATX80_LT
+     case FLOATX80_LT:
+        test_ab_floatx80_z_flag( floatx80_lt, syst_floatx80_lt );
+        break;
+#endif
+#ifdef SYST_FLOATX80_EQ_SIGNALING
+     case FLOATX80_EQ_SIGNALING:
+        test_ab_floatx80_z_flag(
+            floatx80_eq_signaling, syst_floatx80_eq_signaling );
+        break;
+#endif
+#ifdef SYST_FLOATX80_LE_QUIET
+     case FLOATX80_LE_QUIET:
+        test_ab_floatx80_z_flag( floatx80_le_quiet, syst_floatx80_le_quiet );
+        break;
+#endif
+#ifdef SYST_FLOATX80_LT_QUIET
+     case FLOATX80_LT_QUIET:
+        test_ab_floatx80_z_flag( floatx80_lt_quiet, syst_floatx80_lt_quiet );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT32
+     case FLOAT128_TO_INT32:
+        test_a_float128_z_int32( float128_to_int32, syst_float128_to_int32 );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT32_ROUND_TO_ZERO
+     case FLOAT128_TO_INT32_ROUND_TO_ZERO:
+        test_a_float128_z_int32(
+            float128_to_int32_round_to_zero,
+            syst_float128_to_int32_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT64
+     case FLOAT128_TO_INT64:
+        test_a_float128_z_int64( float128_to_int64, syst_float128_to_int64 );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_INT64_ROUND_TO_ZERO
+     case FLOAT128_TO_INT64_ROUND_TO_ZERO:
+        test_a_float128_z_int64(
+            float128_to_int64_round_to_zero,
+            syst_float128_to_int64_round_to_zero
+        );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT32
+     case FLOAT128_TO_FLOAT32:
+        test_a_float128_z_float32(
+            float128_to_float32, syst_float128_to_float32 );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_FLOAT64
+     case FLOAT128_TO_FLOAT64:
+        test_a_float128_z_float64(
+            float128_to_float64, syst_float128_to_float64 );
+        break;
+#endif
+#ifdef SYST_FLOAT128_TO_FLOATX80
+     case FLOAT128_TO_FLOATX80:
+        test_a_float128_z_floatx80(
+            float128_to_floatx80, syst_float128_to_floatx80 );
+        break;
+#endif
+#ifdef SYST_FLOAT128_ROUND_TO_INT
+     case FLOAT128_ROUND_TO_INT:
+        test_az_float128( float128_round_to_int, syst_float128_round_to_int );
+        break;
+#endif
+#ifdef SYST_FLOAT128_ADD
+     case FLOAT128_ADD:
+        test_abz_float128( float128_add, syst_float128_add );
+        break;
+#endif
+#ifdef SYST_FLOAT128_SUB
+     case FLOAT128_SUB:
+        test_abz_float128( float128_sub, syst_float128_sub );
+        break;
+#endif
+#ifdef SYST_FLOAT128_MUL
+     case FLOAT128_MUL:
+        test_abz_float128( float128_mul, syst_float128_mul );
+        break;
+#endif
+#ifdef SYST_FLOAT128_DIV
+     case FLOAT128_DIV:
+        test_abz_float128( float128_div, syst_float128_div );
+        break;
+#endif
+#ifdef SYST_FLOAT128_REM
+     case FLOAT128_REM:
+        test_abz_float128( float128_rem, syst_float128_rem );
+        break;
+#endif
+#ifdef SYST_FLOAT128_SQRT
+     case FLOAT128_SQRT:
+        test_az_float128( float128_sqrt, syst_float128_sqrt );
+        break;
+#endif
+#ifdef SYST_FLOAT128_EQ
+     case FLOAT128_EQ:
+        test_ab_float128_z_flag( float128_eq, syst_float128_eq );
+        break;
+#endif
+#ifdef SYST_FLOAT128_LE
+     case FLOAT128_LE:
+        test_ab_float128_z_flag( float128_le, syst_float128_le );
+        break;
+#endif
+#ifdef SYST_FLOAT128_LT
+     case FLOAT128_LT:
+        test_ab_float128_z_flag( float128_lt, syst_float128_lt );
+        break;
+#endif
+#ifdef SYST_FLOAT128_EQ_SIGNALING
+     case FLOAT128_EQ_SIGNALING:
+        test_ab_float128_z_flag(
+            float128_eq_signaling, syst_float128_eq_signaling );
+        break;
+#endif
+#ifdef SYST_FLOAT128_LE_QUIET
+     case FLOAT128_LE_QUIET:
+        test_ab_float128_z_flag( float128_le_quiet, syst_float128_le_quiet );
+        break;
+#endif
+#ifdef SYST_FLOAT128_LT_QUIET
+     case FLOAT128_LT_QUIET:
+        test_ab_float128_z_flag( float128_lt_quiet, syst_float128_lt_quiet );
+        break;
+#endif
+    }
+    if ( ( errorStop && anyErrors ) || stop ) exitWithStatus();
+
+}
+
+void
+ testFunction(
+     uint8 functionCode, int8 roundingPrecisionIn, int8 roundingModeIn )
+{
+    int8 roundingPrecision, roundingMode;
+
+    roundingPrecision = 32;
+    for (;;) {
+        if ( ! functions[ functionCode ].roundingPrecision ) {
+            roundingPrecision = 0;
+        }
+        else if ( roundingPrecisionIn ) {
+            roundingPrecision = roundingPrecisionIn;
+        }
+        for ( roundingMode = 1;
+              roundingMode < NUM_ROUNDINGMODES;
+              ++roundingMode
+            ) {
+            if ( ! functions[ functionCode ].roundingMode ) {
+                roundingMode = 0;
+            }
+            else if ( roundingModeIn ) {
+                roundingMode = roundingModeIn;
+            }
+            testFunctionVariety(
+                functionCode, roundingPrecision, roundingMode );
+            if ( roundingModeIn || ! roundingMode ) break;
+        }
+        if ( roundingPrecisionIn || ! roundingPrecision ) break;
+        if ( roundingPrecision == 80 ) {
+            break;
+        }
+        else if ( roundingPrecision == 64 ) {
+            roundingPrecision = 80;
+        }
+        else if ( roundingPrecision == 32 ) {
+            roundingPrecision = 64;
+        }
+    }
+
+}
+
diff --git a/testfloat/testFunction.h b/testfloat/testFunction.h
new file mode 100644
index 00000000000..04bf856046d
--- /dev/null
+++ b/testfloat/testFunction.h
@@ -0,0 +1,135 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+enum {
+    INT32_TO_FLOAT32 = 1,
+    INT32_TO_FLOAT64,
+    INT32_TO_FLOATX80,
+    INT32_TO_FLOAT128,
+    INT64_TO_FLOAT32,
+    INT64_TO_FLOAT64,
+    INT64_TO_FLOATX80,
+    INT64_TO_FLOAT128,
+    FLOAT32_TO_INT32,
+    FLOAT32_TO_INT32_ROUND_TO_ZERO,
+    FLOAT32_TO_INT64,
+    FLOAT32_TO_INT64_ROUND_TO_ZERO,
+    FLOAT32_TO_FLOAT64,
+    FLOAT32_TO_FLOATX80,
+    FLOAT32_TO_FLOAT128,
+    FLOAT32_ROUND_TO_INT,
+    FLOAT32_ADD,
+    FLOAT32_SUB,
+    FLOAT32_MUL,
+    FLOAT32_DIV,
+    FLOAT32_REM,
+    FLOAT32_SQRT,
+    FLOAT32_EQ,
+    FLOAT32_LE,
+    FLOAT32_LT,
+    FLOAT32_EQ_SIGNALING,
+    FLOAT32_LE_QUIET,
+    FLOAT32_LT_QUIET,
+    FLOAT64_TO_INT32,
+    FLOAT64_TO_INT32_ROUND_TO_ZERO,
+    FLOAT64_TO_INT64,
+    FLOAT64_TO_INT64_ROUND_TO_ZERO,
+    FLOAT64_TO_FLOAT32,
+    FLOAT64_TO_FLOATX80,
+    FLOAT64_TO_FLOAT128,
+    FLOAT64_ROUND_TO_INT,
+    FLOAT64_ADD,
+    FLOAT64_SUB,
+    FLOAT64_MUL,
+    FLOAT64_DIV,
+    FLOAT64_REM,
+    FLOAT64_SQRT,
+    FLOAT64_EQ,
+    FLOAT64_LE,
+    FLOAT64_LT,
+    FLOAT64_EQ_SIGNALING,
+    FLOAT64_LE_QUIET,
+    FLOAT64_LT_QUIET,
+    FLOATX80_TO_INT32,
+    FLOATX80_TO_INT32_ROUND_TO_ZERO,
+    FLOATX80_TO_INT64,
+    FLOATX80_TO_INT64_ROUND_TO_ZERO,
+    FLOATX80_TO_FLOAT32,
+    FLOATX80_TO_FLOAT64,
+    FLOATX80_TO_FLOAT128,
+    FLOATX80_ROUND_TO_INT,
+    FLOATX80_ADD,
+    FLOATX80_SUB,
+    FLOATX80_MUL,
+    FLOATX80_DIV,
+    FLOATX80_REM,
+    FLOATX80_SQRT,
+    FLOATX80_EQ,
+    FLOATX80_LE,
+    FLOATX80_LT,
+    FLOATX80_EQ_SIGNALING,
+    FLOATX80_LE_QUIET,
+    FLOATX80_LT_QUIET,
+    FLOAT128_TO_INT32,
+    FLOAT128_TO_INT32_ROUND_TO_ZERO,
+    FLOAT128_TO_INT64,
+    FLOAT128_TO_INT64_ROUND_TO_ZERO,
+    FLOAT128_TO_FLOAT32,
+    FLOAT128_TO_FLOAT64,
+    FLOAT128_TO_FLOATX80,
+    FLOAT128_ROUND_TO_INT,
+    FLOAT128_ADD,
+    FLOAT128_SUB,
+    FLOAT128_MUL,
+    FLOAT128_DIV,
+    FLOAT128_REM,
+    FLOAT128_SQRT,
+    FLOAT128_EQ,
+    FLOAT128_LE,
+    FLOAT128_LT,
+    FLOAT128_EQ_SIGNALING,
+    FLOAT128_LE_QUIET,
+    FLOAT128_LT_QUIET,
+    NUM_FUNCTIONS
+};
+
+typedef struct {
+    char *name;
+    int8 numInputs;
+    flag roundingPrecision, roundingMode;
+} functionT;
+extern const functionT functions[ NUM_FUNCTIONS ];
+extern const flag functionExists[ NUM_FUNCTIONS ];
+
+enum {
+    ROUND_NEAREST_EVEN = 1,
+    ROUND_TO_ZERO,
+    ROUND_DOWN,
+    ROUND_UP,
+    NUM_ROUNDINGMODES
+};
+
+void testFunction( uint8, int8, int8 );
+
diff --git a/testfloat/testLoops.c b/testfloat/testLoops.c
new file mode 100644
index 00000000000..8ba92f313a4
--- /dev/null
+++ b/testfloat/testLoops.c
@@ -0,0 +1,2713 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include 
+#include "milieu.h"
+#include "softfloat.h"
+#include "testCases.h"
+#include "writeHex.h"
+#include "testLoops.h"
+
+volatile flag stop = FALSE;
+
+char *trueName, *testName;
+flag forever, errorStop;
+uint32 maxErrorCount = 0;
+flag checkNaNs = FALSE;
+int8 *trueFlagsPtr;
+int8 ( *testFlagsFunctionPtr )( void );
+char *functionName;
+char *roundingPrecisionName, *roundingModeName, *tininessModeName;
+flag anyErrors = FALSE;
+
+void writeFunctionName( FILE *stream )
+{
+
+    fputs( functionName, stream );
+    if ( roundingModeName ) {
+        if ( roundingPrecisionName ) {
+            fputs( ", precision ", stream );
+            fputs( roundingPrecisionName, stream );
+        }
+        fputs( ", rounding ", stream );
+        fputs( roundingModeName, stream );
+        if ( tininessModeName ) {
+            fputs( ", tininess ", stream );
+            fputs( tininessModeName, stream );
+            fputs( " rounding", stream );
+        }
+    }
+
+}
+
+void exitWithStatus( void )
+{
+
+    exit( anyErrors ? EXIT_FAILURE : EXIT_SUCCESS );
+
+}
+
+static uint32 tenthousandsCount, errorCount = 0;
+
+static void writeTestsTotal( void )
+{
+
+    if ( forever ) {
+        fputs( "Unbounded tests.\n", stderr );
+    }
+    else {
+        fprintf( stderr, "\r%d tests total.\n", testCases_total );
+    }
+
+}
+
+static void writeTestsPerformed( int16 count )
+{
+
+    if ( tenthousandsCount ) {
+        fprintf(
+            stderr, "\r%d%04d tests performed", tenthousandsCount, count );
+    }
+    else {
+        fprintf( stderr, "\r%d tests performed", count );
+    }
+    if ( errorCount ) {
+        fprintf(
+            stderr,
+            "; %d error%s found.\n",
+            errorCount,
+            ( errorCount == 1 ) ? "" : "s"
+        );
+    }
+    else {
+        fputs( ".\n", stderr );
+        fputs( "No errors found in ", stdout );
+        writeFunctionName( stdout );
+        fputs( ".\n", stdout );
+        fflush( stdout );
+    }
+
+}
+
+static void checkEarlyExit( void )
+{
+
+    ++tenthousandsCount;
+    if ( stop ) {
+        writeTestsPerformed( 0 );
+        exitWithStatus();
+    }
+    fprintf( stderr, "\r%3d0000", tenthousandsCount );
+
+}
+
+static void writeErrorFound( int16 count )
+{
+
+    fputc( '\r', stderr );
+    if ( errorCount == 1 ) {
+        fputs( "Errors found in ", stdout );
+        writeFunctionName( stdout );
+        fputs( ":\n", stdout );
+    }
+    if ( stop ) {
+        writeTestsPerformed( count );
+        exitWithStatus();
+    }
+    anyErrors = TRUE;
+
+}
+
+INLINE void writeInput_a_int32( void )
+{
+
+    writeHex_bits32( testCases_a_int32, stdout );
+
+}
+
+#ifdef BITS64
+
+INLINE void writeInput_a_int64( void )
+{
+
+    writeHex_bits64( testCases_a_int64, stdout );
+
+}
+
+#endif
+
+INLINE void writeInput_a_float32( void )
+{
+
+    writeHex_float32( testCases_a_float32, stdout );
+
+}
+
+static void writeInputs_ab_float32( void )
+{
+
+    writeHex_float32( testCases_a_float32, stdout );
+    fputs( "  ", stdout );
+    writeHex_float32( testCases_b_float32, stdout );
+
+}
+
+INLINE void writeInput_a_float64( void )
+{
+
+    writeHex_float64( testCases_a_float64, stdout );
+
+}
+
+static void writeInputs_ab_float64( void )
+{
+
+    writeHex_float64( testCases_a_float64, stdout );
+    fputs( "  ", stdout );
+    writeHex_float64( testCases_b_float64, stdout );
+
+}
+
+#ifdef FLOATX80
+
+INLINE void writeInput_a_floatx80( void )
+{
+
+    writeHex_floatx80( testCases_a_floatx80, stdout );
+
+}
+
+static void writeInputs_ab_floatx80( void )
+{
+
+    writeHex_floatx80( testCases_a_floatx80, stdout );
+    fputs( "  ", stdout );
+    writeHex_floatx80( testCases_b_floatx80, stdout );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+INLINE void writeInput_a_float128( void )
+{
+
+    writeHex_float128( testCases_a_float128, stdout );
+
+}
+
+static void writeInputs_ab_float128( void )
+{
+
+    writeHex_float128( testCases_a_float128, stdout );
+    fputs( "  ", stdout );
+    writeHex_float128( testCases_b_float128, stdout );
+
+}
+
+#endif
+
+static void
+ writeOutputs_z_flag(
+     flag trueZ, uint8 trueFlags, flag testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_flag( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "  ", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_flag( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+static void
+ writeOutputs_z_int32(
+     int32 trueZ, uint8 trueFlags, int32 testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_bits32( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "  ", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_bits32( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+#ifdef BITS64
+
+static void
+ writeOutputs_z_int64(
+     int64 trueZ, uint8 trueFlags, int64 testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_bits64( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "  ", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_bits64( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+#endif
+
+static void
+ writeOutputs_z_float32(
+     float32 trueZ, uint8 trueFlags, float32 testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_float32( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "  ", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_float32( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+static void
+ writeOutputs_z_float64(
+     float64 trueZ, uint8 trueFlags, float64 testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_float64( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "  ", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_float64( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+#ifdef FLOATX80
+
+static void
+ writeOutputs_z_floatx80(
+     floatx80 trueZ, uint8 trueFlags, floatx80 testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_floatx80( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "  ", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_floatx80( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+static void
+ writeOutputs_z_float128(
+     float128 trueZ, uint8 trueFlags, float128 testZ, uint8 testFlags )
+{
+
+    fputs( trueName, stdout );
+    fputs( ": ", stdout );
+    writeHex_float128( trueZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( trueFlags, stdout );
+    fputs( "\n\t", stdout );
+    fputs( testName, stdout );
+    fputs( ": ", stdout );
+    writeHex_float128( testZ, stdout );
+    fputc( ' ', stdout );
+    writeHex_float_flags( testFlags, stdout );
+    fputc( '\n', stdout );
+
+}
+
+#endif
+
+INLINE flag float32_isNaN( float32 a )
+{
+
+    return 0x7F800000 < ( a & 0x7FFFFFFF );
+
+}
+
+#ifdef BITS64
+
+INLINE flag float64_same( float64 a, float64 b )
+{
+
+    return a == b;
+
+}
+
+INLINE flag float64_isNaN( float64 a )
+{
+
+    return LIT64( 0x7FF0000000000000 ) < ( a & LIT64( 0x7FFFFFFFFFFFFFFF ) );
+
+}
+
+#else
+
+INLINE flag float64_same( float64 a, float64 b )
+{
+
+    return ( a.high == b.high ) && ( a.low == b.low );
+
+}
+
+INLINE flag float64_isNaN( float64 a )
+{
+    bits32 absAHigh;
+
+    absAHigh = a.high & 0x7FFFFFFF;
+    return
+        ( 0x7FF00000 < absAHigh ) || ( ( absAHigh == 0x7FF00000 ) && a.low );
+
+}
+
+#endif
+
+#ifdef FLOATX80
+
+INLINE flag floatx80_same( floatx80 a, floatx80 b )
+{
+
+    return ( a.high == b.high ) && ( a.low == b.low );
+
+}
+
+INLINE flag floatx80_isNaN( floatx80 a )
+{
+
+    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && a.low;
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+INLINE flag float128_same( float128 a, float128 b )
+{
+
+    return ( a.high == b.high ) && ( a.low == b.low );
+
+}
+
+INLINE flag float128_isNaN( float128 a )
+{
+    bits64 absAHigh;
+
+    absAHigh = a.high & LIT64( 0x7FFFFFFFFFFFFFFF );
+    return
+           ( LIT64( 0x7FFF000000000000 ) < absAHigh )
+        || ( ( absAHigh == LIT64( 0x7FFF000000000000 ) ) && a.low );
+
+}
+
+#endif
+
+void
+ test_a_int32_z_float32(
+     float32 trueFunction( int32 ), float32 testFunction( int32 ) )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int32();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_int32_z_float64(
+     float64 trueFunction( int32 ), float64 testFunction( int32 ) )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int32();
+                fputs( "  ", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_int32_z_floatx80(
+     floatx80 trueFunction( int32 ), floatx80 testFunction( int32 ) )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int32();
+                fputs( "  ", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_int32_z_float128(
+     float128 trueFunction( int32 ), float128 testFunction( int32 ) )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int32();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef BITS64
+
+void
+ test_a_int64_z_float32(
+     float32 trueFunction( int64 ), float32 testFunction( int64 ) )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int64();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_int64_z_float64(
+     float64 trueFunction( int64 ), float64 testFunction( int64 ) )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int64();
+                fputs( "  ", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_int64_z_floatx80(
+     floatx80 trueFunction( int64 ), floatx80 testFunction( int64 ) )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int64();
+                fputs( "  ", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_int64_z_float128(
+     float128 trueFunction( int64 ), float128 testFunction( int64 ) )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_int64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_int64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_int64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_int64();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#endif
+
+void
+ test_a_float32_z_int32(
+     int32 trueFunction( float32 ), int32 testFunction( float32 ) )
+{
+    int16 count;
+    int32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == 0x7FFFFFFF )
+                 && (    ( testZ == 0x7FFFFFFF )
+                      || ( testZ == (sbits32) 0x80000000 ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float32();
+                fputs( "  ", stdout );
+                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_float32_z_int64(
+     int64 trueFunction( float32 ), int64 testFunction( float32 ) )
+{
+    int16 count;
+    int64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float32();
+                fputs( "  ", stdout );
+                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_float32_z_float64(
+     float64 trueFunction( float32 ), float64 testFunction( float32 ) )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float32();
+                fputs( "  ", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_float32_z_floatx80(
+     floatx80 trueFunction( float32 ), floatx80 testFunction( float32 ) )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float32();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_float32_z_float128(
+     float128 trueFunction( float32 ), float128 testFunction( float32 ) )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float32();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_float32(
+     float32 trueFunction( float32 ), float32 testFunction( float32 ) )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float32_is_signaling_nan( testCases_a_float32 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float32();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_float32_z_flag(
+     flag trueFunction( float32, float32 ),
+     flag testFunction( float32, float32 )
+ )
+{
+    int16 count;
+    flag trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32, testCases_b_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    float32_is_signaling_nan( testCases_a_float32 )
+                      || float32_is_signaling_nan( testCases_b_float32 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_float32();
+                fputs( "  ", stdout );
+                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+void
+ test_abz_float32(
+     float32 trueFunction( float32, float32 ),
+     float32 testFunction( float32, float32 )
+ )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_float32 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float32, testCases_b_float32 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float32, testCases_b_float32 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    float32_is_signaling_nan( testCases_a_float32 )
+                      || float32_is_signaling_nan( testCases_b_float32 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_float32();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+void
+ test_a_float64_z_int32(
+     int32 trueFunction( float64 ), int32 testFunction( float64 ) )
+{
+    int16 count;
+    int32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == 0x7FFFFFFF )
+                 && (    ( testZ == 0x7FFFFFFF )
+                      || ( testZ == (sbits32) 0x80000000 ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float64();
+                fputs( "  ", stdout );
+                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_float64_z_int64(
+     int64 trueFunction( float64 ), int64 testFunction( float64 ) )
+{
+    int16 count;
+    int64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float64();
+                fputs( "  ", stdout );
+                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_float64_z_float32(
+     float32 trueFunction( float64 ), float32 testFunction( float64 ) )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float64();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_float64_z_floatx80(
+     floatx80 trueFunction( float64 ), floatx80 testFunction( float64 ) )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float64();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_float64_z_float128(
+     float128 trueFunction( float64 ), float128 testFunction( float64 ) )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float64();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_float64(
+     float64 trueFunction( float64 ), float64 testFunction( float64 ) )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float64_is_signaling_nan( testCases_a_float64 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float64();
+                fputs( "  ", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_float64_z_flag(
+     flag trueFunction( float64, float64 ),
+     flag testFunction( float64, float64 )
+ )
+{
+    int16 count;
+    flag trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64, testCases_b_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    float64_is_signaling_nan( testCases_a_float64 )
+                      || float64_is_signaling_nan( testCases_b_float64 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_float64();
+                fputs( "  ", stdout );
+                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+void
+ test_abz_float64(
+     float64 trueFunction( float64, float64 ),
+     float64 testFunction( float64, float64 )
+ )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_float64 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float64, testCases_b_float64 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float64, testCases_b_float64 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    float64_is_signaling_nan( testCases_a_float64 )
+                      || float64_is_signaling_nan( testCases_b_float64 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_float64();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_floatx80_z_int32(
+     int32 trueFunction( floatx80 ), int32 testFunction( floatx80 ) )
+{
+    int16 count;
+    int32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == 0x7FFFFFFF )
+                 && (    ( testZ == 0x7FFFFFFF )
+                      || ( testZ == (sbits32) 0x80000000 ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_floatx80();
+                fputs( "  ", stdout );
+                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_floatx80_z_int64(
+     int64 trueFunction( floatx80 ), int64 testFunction( floatx80 ) )
+{
+    int16 count;
+    int64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_floatx80();
+                fputs( "  ", stdout );
+                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_floatx80_z_float32(
+     float32 trueFunction( floatx80 ), float32 testFunction( floatx80 ) )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_floatx80();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_floatx80_z_float64(
+     float64 trueFunction( floatx80 ), float64 testFunction( floatx80 ) )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_floatx80();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOAT128
+
+void
+ test_a_floatx80_z_float128(
+     float128 trueFunction( floatx80 ), float128 testFunction( floatx80 ) )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_floatx80();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_floatx80(
+     floatx80 trueFunction( floatx80 ), floatx80 testFunction( floatx80 ) )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && floatx80_is_signaling_nan( testCases_a_floatx80 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_floatx80();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_floatx80_z_flag(
+     flag trueFunction( floatx80, floatx80 ),
+     flag testFunction( floatx80, floatx80 )
+ )
+{
+    int16 count;
+    flag trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    floatx80_is_signaling_nan( testCases_a_floatx80 )
+                      || floatx80_is_signaling_nan( testCases_b_floatx80 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_floatx80();
+                fputs( "  ", stdout );
+                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+void
+ test_abz_floatx80(
+     floatx80 trueFunction( floatx80, floatx80 ),
+     floatx80 testFunction( floatx80, floatx80 )
+ )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_floatx80 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_floatx80, testCases_b_floatx80 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_floatx80, testCases_b_floatx80 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    floatx80_is_signaling_nan( testCases_a_floatx80 )
+                      || floatx80_is_signaling_nan( testCases_b_floatx80 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_floatx80();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+#endif
+
+#ifdef FLOAT128
+
+void
+ test_a_float128_z_int32(
+     int32 trueFunction( float128 ), int32 testFunction( float128 ) )
+{
+    int16 count;
+    int32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == 0x7FFFFFFF )
+                 && (    ( testZ == 0x7FFFFFFF )
+                      || ( testZ == (sbits32) 0x80000000 ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float128();
+                fputs( "  ", stdout );
+                writeOutputs_z_int32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef BITS64
+
+void
+ test_a_float128_z_int64(
+     int64 trueFunction( float128 ), int64 testFunction( float128 ) )
+{
+    int16 count;
+    int64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ( trueZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                 && (    ( testZ == LIT64( 0x7FFFFFFFFFFFFFFF ) )
+                      || ( testZ == (sbits64) LIT64( 0x8000000000000000 ) ) )
+                 && ( trueFlags == float_flag_invalid )
+                 && ( testFlags == float_flag_invalid )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float128();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_int64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_a_float128_z_float32(
+     float32 trueFunction( float128 ), float32 testFunction( float128 ) )
+{
+    int16 count;
+    float32 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float32_isNaN( trueZ )
+                 && float32_isNaN( testZ )
+                 && ! float32_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float128();
+                fputs( "  ", stdout );
+                writeOutputs_z_float32( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_a_float128_z_float64(
+     float64 trueFunction( float128 ), float64 testFunction( float128 ) )
+{
+    int16 count;
+    float64 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float64_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float64_isNaN( trueZ )
+                 && float64_isNaN( testZ )
+                 && ! float64_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float128();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float64( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#ifdef FLOATX80
+
+void
+ test_a_float128_z_floatx80(
+     floatx80 trueFunction( float128 ), floatx80 testFunction( float128 ) )
+{
+    int16 count;
+    floatx80 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! floatx80_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && floatx80_isNaN( trueZ )
+                 && floatx80_isNaN( testZ )
+                 && ! floatx80_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float128();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_floatx80( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+#endif
+
+void
+ test_az_float128(
+     float128 trueFunction( float128 ), float128 testFunction( float128 ) )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_a_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && float128_is_signaling_nan( testCases_a_float128 ) ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInput_a_float128();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+
+}
+
+void
+ test_ab_float128_z_flag(
+     flag trueFunction( float128, float128 ),
+     flag testFunction( float128, float128 )
+ )
+{
+    int16 count;
+    flag trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128, testCases_b_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    float128_is_signaling_nan( testCases_a_float128 )
+                      || float128_is_signaling_nan( testCases_b_float128 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if ( ( trueZ != testZ ) || ( trueFlags != testFlags ) ) {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_float128();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_flag( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+void
+ test_abz_float128(
+     float128 trueFunction( float128, float128 ),
+     float128 testFunction( float128, float128 )
+ )
+{
+    int16 count;
+    float128 trueZ, testZ;
+    uint8 trueFlags, testFlags;
+
+    errorCount = 0;
+    tenthousandsCount = 0;
+    count = 10000;
+    testCases_initSequence( testCases_sequence_ab_float128 );
+    writeTestsTotal();
+    while ( ! testCases_done || forever ) {
+        testCases_next();
+        *trueFlagsPtr = 0;
+        trueZ = trueFunction( testCases_a_float128, testCases_b_float128 );
+        trueFlags = *trueFlagsPtr;
+        (void) testFlagsFunctionPtr();
+        testZ = testFunction( testCases_a_float128, testCases_b_float128 );
+        testFlags = testFlagsFunctionPtr();
+        --count;
+        if ( count == 0 ) {
+            checkEarlyExit();
+            count = 10000;
+        }
+        if ( ! float128_same( trueZ, testZ ) || ( trueFlags != testFlags ) ) {
+            if (    ! checkNaNs
+                 && (    float128_is_signaling_nan( testCases_a_float128 )
+                      || float128_is_signaling_nan( testCases_b_float128 ) )
+               ) {
+                trueFlags |= float_flag_invalid;
+            }
+            if (    ! checkNaNs
+                 && float128_isNaN( trueZ )
+                 && float128_isNaN( testZ )
+                 && ! float128_is_signaling_nan( testZ )
+                 && ( trueFlags == testFlags )
+               ) {
+                /* no problem */
+            }
+            else {
+                ++errorCount;
+                writeErrorFound( 10000 - count );
+                writeInputs_ab_float128();
+                fputs( "\n\t", stdout );
+                writeOutputs_z_float128( trueZ, trueFlags, testZ, testFlags );
+                fflush( stdout );
+                if ( errorCount == maxErrorCount ) goto exit;
+            }
+        }
+    }
+ exit:
+    writeTestsPerformed( 10000 - count );
+    return;
+
+}
+
+#endif
+
diff --git a/testfloat/testLoops.h b/testfloat/testLoops.h
new file mode 100644
index 00000000000..c3b08477f0e
--- /dev/null
+++ b/testfloat/testLoops.h
@@ -0,0 +1,143 @@
+
+/*
+===============================================================================
+
+This C header file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+
+extern volatile flag stop;
+
+extern char *trueName, *testName;
+extern flag forever, errorStop;
+extern uint32 maxErrorCount;
+extern flag checkNaNs;
+extern int8 *trueFlagsPtr;
+extern int8 ( *testFlagsFunctionPtr )( void );
+extern char *functionName;
+extern char *roundingPrecisionName, *roundingModeName, *tininessModeName;
+extern flag anyErrors;
+
+void writeFunctionName( FILE * );
+void exitWithStatus( void );
+
+void test_a_int32_z_float32( float32 ( int32 ), float32 ( int32 ) );
+void test_a_int32_z_float64( float64 ( int32 ), float64 ( int32 ) );
+#ifdef FLOATX80
+void test_a_int32_z_floatx80( floatx80 ( int32 ), floatx80 ( int32 ) );
+#endif
+#ifdef FLOAT128
+void test_a_int32_z_float128( float128 ( int32 ), float128 ( int32 ) );
+#endif
+#ifdef BITS64
+void test_a_int64_z_float32( float32 ( int64 ), float32 ( int64 ) );
+void test_a_int64_z_float64( float64 ( int64 ), float64 ( int64 ) );
+#ifdef FLOATX80
+void test_a_int64_z_floatx80( floatx80 ( int64 ), floatx80 ( int64 ) );
+#endif
+#ifdef FLOAT128
+void test_a_int64_z_float128( float128 ( int64 ), float128 ( int64 ) );
+#endif
+#endif
+
+void test_a_float32_z_int32( int32 ( float32 ), int32 ( float32 ) );
+#ifdef BITS64
+void test_a_float32_z_int64( int64 ( float32 ), int64 ( float32 ) );
+#endif
+void test_a_float32_z_float64( float64 ( float32 ), float64 ( float32 ) );
+#ifdef FLOATX80
+void test_a_float32_z_floatx80( floatx80 ( float32 ), floatx80 ( float32 ) );
+#endif
+#ifdef FLOAT128
+void test_a_float32_z_float128( float128 ( float32 ), float128 ( float32 ) );
+#endif
+void test_az_float32( float32 ( float32 ), float32 ( float32 ) );
+void
+ test_ab_float32_z_flag(
+     flag ( float32, float32 ), flag ( float32, float32 ) );
+void
+ test_abz_float32(
+     float32 ( float32, float32 ), float32 ( float32, float32 ) );
+
+void test_a_float64_z_int32( int32 ( float64 ), int32 ( float64 ) );
+#ifdef BITS64
+void test_a_float64_z_int64( int64 ( float64 ), int64 ( float64 ) );
+#endif
+void test_a_float64_z_float32( float32 ( float64 ), float32 ( float64 ) );
+#ifdef FLOATX80
+void test_a_float64_z_floatx80( floatx80 ( float64 ), floatx80 ( float64 ) );
+#endif
+#ifdef FLOAT128
+void test_a_float64_z_float128( float128 ( float64 ), float128 ( float64 ) );
+#endif
+void test_az_float64( float64 ( float64 ), float64 ( float64 ) );
+void
+ test_ab_float64_z_flag(
+     flag ( float64, float64 ), flag ( float64, float64 ) );
+void
+ test_abz_float64(
+     float64 ( float64, float64 ), float64 ( float64, float64 ) );
+
+#ifdef FLOATX80
+
+void test_a_floatx80_z_int32( int32 ( floatx80 ), int32 ( floatx80 ) );
+#ifdef BITS64
+void test_a_floatx80_z_int64( int64 ( floatx80 ), int64 ( floatx80 ) );
+#endif
+void test_a_floatx80_z_float32( float32 ( floatx80 ), float32 ( floatx80 ) );
+void test_a_floatx80_z_float64( float64 ( floatx80 ), float64 ( floatx80 ) );
+#ifdef FLOAT128
+void
+ test_a_floatx80_z_float128( float128 ( floatx80 ), float128 ( floatx80 ) );
+#endif
+void test_az_floatx80( floatx80 ( floatx80 ), floatx80 ( floatx80 ) );
+void
+ test_ab_floatx80_z_flag(
+     flag ( floatx80, floatx80 ), flag ( floatx80, floatx80 ) );
+void
+ test_abz_floatx80(
+     floatx80 ( floatx80, floatx80 ), floatx80 ( floatx80, floatx80 ) );
+
+#endif
+
+#ifdef FLOAT128
+
+void test_a_float128_z_int32( int32 ( float128 ), int32 ( float128 ) );
+#ifdef BITS64
+void test_a_float128_z_int64( int64 ( float128 ), int64 ( float128 ) );
+#endif
+void test_a_float128_z_float32( float32 ( float128 ), float32 ( float128 ) );
+void test_a_float128_z_float64( float64 ( float128 ), float64 ( float128 ) );
+#ifdef FLOATX80
+void
+ test_a_float128_z_floatx80( floatx80 ( float128 ), floatx80 ( float128 ) );
+#endif
+void test_az_float128( float128 ( float128 ), float128 ( float128 ) );
+void
+ test_ab_float128_z_flag(
+     flag ( float128, float128 ), flag ( float128, float128 ) );
+void
+ test_abz_float128(
+     float128 ( float128, float128 ), float128 ( float128, float128 ) );
+
+#endif
+
diff --git a/testfloat/testfloat-history.txt b/testfloat/testfloat-history.txt
new file mode 100644
index 00000000000..61520b3b678
--- /dev/null
+++ b/testfloat/testfloat-history.txt
@@ -0,0 +1,57 @@
+
+History of Major Changes to TestFloat, up to Release 2a
+
+John R. Hauser
+1998 December 17
+
+
+The TestFloat releases parallel those of SoftFloat, on which TestFloat is
+based.  Each TestFloat release also incorporates all bug fixes from the
+corresponding release of SoftFloat.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 2a (1998 December)
+
+-- Added support for testing conversions between floating-point and 64-bit
+   integers.
+
+-- Improved the makefiles.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 2 (1997 June)
+
+-- Integrated the generation of test cases and the checking of system
+   results into a single program.  (Before they were separate programs,
+   normally joined by explicit command-line pipes.)
+
+-- Improved the sequence of test cases.
+
+-- Added support for testing extended double precision and quadruple
+   precision.
+
+-- Made program output more readable, and added new command arguments.
+
+-- Reduced dependence on the quality of the standard `random' function for
+   generating test cases.  (Previously naively expected `random' to be able
+   to generate good random bits for the entire machine word width.)
+
+-- Created `testsoftfloat', with its own simpler complete software floating-
+   point (``slowfloat'') for comparison purposes.
+
+-- Made some changes to the source file structure, including renaming
+   `environment.h' to `milieu.h' (to avoid confusion with environment
+   variables).
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 1a (1996 July)
+
+-- Added the `-tininessbefore' and `-tininessafter' options to control
+   whether tininess should be detected before or after rounding.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Release 1 (1996 July)
+
+-- Original release.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
diff --git a/testfloat/testfloat-source.txt b/testfloat/testfloat-source.txt
new file mode 100644
index 00000000000..b8f7e9bb3ed
--- /dev/null
+++ b/testfloat/testfloat-source.txt
@@ -0,0 +1,444 @@
+
+TestFloat Release 2a Source Documentation
+
+John R. Hauser
+1998 December 16
+
+
+-------------------------------------------------------------------------------
+Introduction
+
+TestFloat is a program for testing that a floating-point implementation
+conforms to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
+All standard operations supported by the system can be tested, except for
+conversions to and from decimal.  Any of the following machine formats can
+be tested:  single precision, double precision, extended double precision,
+and/or quadruple precision.  Testing extended double-precision or quadruple-
+precision formats requires a C compiler that supports 64-bit integer
+arithmetic.
+
+This document gives information needed for compiling and/or porting
+TestFloat.
+
+The source code for TestFloat is intended to be relatively machine-
+independent.  TestFloat is written in C, and should be compilable using
+any ISO/ANSI C compiler.  At the time of this writing, the program has
+been successfully compiled using the GNU C Compiler (`gcc') for several
+platforms.  Because ISO/ANSI C does not provide access to some features
+of IEC/IEEE floating-point such as the exception flags, porting TestFloat
+unfortunately involves some machine-dependent coding.
+
+TestFloat depends on SoftFloat, which is a software implementation of
+floating-point that conforms to the IEC/IEEE Standard.  SoftFloat is not
+included with the TestFloat sources.  It can be obtained from the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/SoftFloat.html'.
+
+In addition to a program for testing a machine's floating-point, the
+TestFloat package includes a variant for testing SoftFloat called
+`testsoftfloat'.  The sources for both programs are intermixed, and both are
+described here.
+
+The first release of TestFloat (Release 1) was called _FloatTest_.  The old
+name has been obsolete for some time.
+
+
+-------------------------------------------------------------------------------
+Limitations
+
+TestFloat as written requires an ISO/ANSI-style C compiler.  No attempt has
+been made to accomodate compilers that are not ISO-conformant.  Older ``K&R-
+style'' compilers are not adequate for compiling TestFloat.  All testing I
+have done so far has been with the GNU C Compiler.  Compilation with other
+compilers should be possible but has not been tested.
+
+The TestFloat sources assume that source code file names can be longer than
+8 characters.  In order to compile under an MS-DOS-style system, many of the
+source files will need to be renamed, and the source and makefiles edited
+appropriately.  Once compiled, the TestFloat program does not depend on the
+existence of long file names.
+
+The underlying machine is assumed to be binary with a word size that is a
+power of 2.  Bytes are 8 bits.  Testing of extended double-precision and
+quadruple-precision formats depends on the C compiler implementing a 64-bit
+integer type.  If the largest integer type supported by the C compiler is
+32 bits, only single- and double-precision operations can be tested.
+
+
+-------------------------------------------------------------------------------
+Contents
+
+    Introduction
+    Limitations
+    Contents
+    Legal Notice
+    TestFloat Source Directory Structure
+    Target-Independent Modules
+    Target-Specific Modules
+    Target-Specific Header Files
+        processors/*.h
+        testfloat/*/milieu.h
+    Target-Specific Floating-Point Subroutines
+    Steps to Creating the TestFloat Executables
+    Improving the Random Number Generator
+    Contact Information
+
+
+
+-------------------------------------------------------------------------------
+Legal Notice
+
+TestFloat was written by John R. Hauser.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+
+-------------------------------------------------------------------------------
+TestFloat Source Directory Structure
+
+Because TestFloat is targeted to multiple platforms, its source code
+is slightly scattered between target-specific and target-independent
+directories and files.  The directory structure is as follows:
+
+    processors
+    testfloat
+        templates
+        386-Win32-gcc
+        SPARC-Solaris-gcc
+
+The two topmost directories and their contents are:
+
+    testfloat    - Most of the source code needed for TestFloat.
+    processors   - Target-specific header files that are not specific to
+                       TestFloat.
+
+Within the `testfloat' directory are subdirectories for each of the
+targeted platforms.  The TestFloat source code is distributed with targets
+`386-Win32-gcc' and `SPARC-Solaris-gcc' (and perhaps others) already
+prepared.  These can be used as examples for porting to new targets.  Source
+files that are not within these target-specific subdirectories are intended
+to be target-independent.
+
+The naming convention used for the target-specific directories is
+`--'.  The names of the supplied
+target directories should be interpreted as follows:
+
+  :
+    386          - Intel 386-compatible processor.
+    SPARC        - SPARC processor (as used by Sun machines).
+  :
+    Win32        - Microsoft Win32 executable.
+    Solaris      - Sun Solaris executable.
+  :
+    gcc          - GNU C Compiler.
+
+You do not need to maintain this convention if you do not want to.
+
+Alongside the supplied target-specific directories there is a `templates'
+directory containing a set of ``generic'' target-specific source files.
+A new target directory can be created by copying the `templates' directory
+and editing the files inside.  (Complete instructions for porting TestFloat
+to a new target are in the section _Steps_to_Creating_the_TestFloat_
+_Executables_.)  Note that the `templates' directory will not work as a
+target directory without some editing.  To avoid confusion, it would be wise
+to refrain from editing the files inside `templates' directly.
+
+In addition to the distributed sources, TestFloat depends on the existence
+of an appropriately-compiled SoftFloat binary and the corresponding header
+file `softfloat.h'.  SoftFloat is not included with the TestFloat sources.
+It can be obtained from the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/SoftFloat.html'.
+
+As distributed, the makefiles for TestFloat assume the existence of three
+sibling directories:
+
+    processors
+    softfloat
+    testfloat
+
+Only the `processors' and `testfloat' directories are included in the
+TestFloat package.  The `softfloat' directory is assumed to contain a
+target-specific subdirectory within which the SoftFloat header file and
+compiled binary can be found.  (See the source documentation accompanying
+SoftFloat.)  The `processors' directory distributed with TestFloat is
+intended to be identical to that included with the SoftFloat source.
+
+These are the defaults, but other organizations of the sources are possible.
+The TestFloat makefiles and `milieu.h' files (see below) are easily edited
+to accomodate other arrangements.
+
+
+-------------------------------------------------------------------------------
+Target-Independent Modules
+
+The TestFloat program is composed of a number of modules, some target-
+specific and some target-independent.  The target-independent modules are as
+follows:
+
+-- The `fail' module provides a common routine for writing an error message
+   and aborting.
+
+-- The `random' module generates random integer values.
+
+-- The `writeHex' module defines routines for writing the various types in
+   the hexadecimal form used by TestFloat.
+
+-- The `testCases' module generates test cases for the various types.
+
+-- The `testLoops' module contains various routines for exercising two
+   implementations of a function and reporting any differences observed.
+
+-- The `slowfloat' module provides the simple floating-point implementation
+   used by `testsoftfloat' for comparing against SoftFloat.  The heart
+   of `slowfloat' is found in either `slowfloat-32' or `slowfloat-64',
+   depending on whether the `BITS64' macro is defined.
+
+-- The `systfloat' module gives a SoftFloat-like interface to the machine's
+   floating-point.
+
+-- The `testFunction' module implements `testfloat's main loop for testing a
+   function for all of the relevant rounding modes and rounding precisions.
+   (The `testsoftfloat' program contains its own version of this code.)
+
+-- The `testfloat' and `testsoftfloat' modules are the main modules for the
+   `testfloat' and `testsoftfloat' programs.
+
+Except possibly for `systfloat', these modules should not need to be
+modified.
+
+The `systfloat' module uses the floating-point operations of the C language
+to access a machine's floating-point.  Unfortunately, some IEC/IEEE
+floating-point operations are not accessible within ISO/ANSI C.  The
+following machine functions cannot be tested unless an alternate `systfloat'
+module is provided:
+
+    _to_int32 (rounded according to rounding mode)
+    _to_int64 (rounded according to rounding mode)
+    _round_to_int
+    _rem
+    _sqrt, except float64_sqrt
+    _eq_signaling
+    _le_quiet
+    _lt_quiet
+
+The `-list' option to `testfloat' will show the operations the program is
+prepared to test.  The section _Target-Specific_Floating-Point_Subroutines_
+later in this document explains how to create a target-specific `systfloat'
+module to change the set of testable functions.
+
+
+-------------------------------------------------------------------------------
+Target-Specific Modules
+
+No target-specific modules are needed for `testsoftfloat'.
+
+The `testfloat' program uses two target-specific modules:
+
+-- The `systmodes' module defines functions for setting the modes
+   controlling the system's floating-point, including the rounding mode and
+   the rounding precision for extended double precision.
+
+-- The `systflags' module provides a function for clearing and examining the
+   system's floating-point exception flags.
+
+These modules must be supplied for each target.  They can be implemented in
+any way desired, so long as all is reflected in the target's makefile.  For
+the targets that come with the distributed source, each of these modules is
+implemented as a single assembly language or C language source file.
+
+
+-------------------------------------------------------------------------------
+Target-Specific Header Files
+
+The purpose of the two target-specific header files is detailed below.
+In the following, the `*' symbol is used in place of the name of a specific
+target, such as `386-Win32-gcc' or `SPARC-Solaris-gcc', or in place of some
+other text as explained below.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+processors/*.h
+
+The target-specific `processors' header file defines integer types
+of various sizes, and also defines certain C preprocessor macros that
+characterize the target.  The two examples supplied are `386-gcc.h' and
+`SPARC-gcc.h'.  The naming convention used for processor header files is
+`-.h'.  The `processors' header file used to compile
+TestFloat should be the same as that used to compile SoftFloat.
+
+If 64-bit integers are supported by the compiler, the macro name `BITS64'
+should be defined here along with the corresponding 64-bit integer
+types.  In addition, the function-like macro `LIT64' must be defined for
+constructing 64-bit integer literals (constants).  The `LIT64' macro is used
+consistently in the TestFloat code to annotate 64-bit literals.
+
+If an inlining attribute (such as an `inline' keyword) is provided by the
+compiler, the macro `INLINE' should be defined to the appropriate keyword.
+If not, `INLINE' can be set to the keyword `static'.  The `INLINE' macro
+appears in the TestFloat source code before every function that should be
+inlined by the compiler.
+
+For maximum flexibility, the TestFloat source files do not include the
+`processors' header file directly; rather, this file is included by the
+target-specific `milieu.h' header, and `milieu.h' is included by the source
+files.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+testfloat/*/milieu.h
+
+The `milieu.h' header file provides declarations that are needed to
+compile TestFloat.  In particular, it is through this header file that
+the appropriate `processors' header is included to characterize the target
+processor.  In addition, deviations from ISO/ANSI C by the compiler (such as
+names not properly declared in system header files) are corrected in this
+header if possible.
+
+If the preprocessor macro `BITS64' is defined in the `processors' header
+file but only the 32-bit version of SoftFloat is actually used, the `BITS64'
+macro should be undefined here after the `processors' header has defined it.
+
+If the C compiler implements the `long double' floating-point type of C
+as extended double precision, then `LONG_DOUBLE_IS_FLOATX80' should be
+defined here.  Alternatively, if the C `long double' type is implemented as
+quadruple precision, `LONG_DOUBLE_IS_FLOAT128' should be defined.  At most
+one of these macros should be defined.  A C compiler is allowed to implement
+`long double' the same as `double', in which case neither of these macros
+should be defined.
+
+- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+-------------------------------------------------------------------------------
+Target-Specific Floating-Point Subroutines
+
+This section applies only to `testfloat' and not to `testsoftfloat'.
+
+By default, TestFloat tests a machine's floating-point by testing the
+floating-point operations of the C language.  Unfortunately, some IEC/IEEE
+floating-point operations are not defined within ISO/ANSI C.  If a machine
+implements such ``non-C'' operations, target-specific subroutines for
+the operations can be supplied to allow TestFloat to test these machine
+features.  Typically, such subroutines will need to be written in assembly
+language, although equivalent functions can sometimes be found among the
+system's software libraries.
+
+The following machine functions cannot be tested by TestFloat unless target-
+specific subroutines are supplied for them:
+
+    _to_int32 (rounded according to rounding mode)
+    _to_int64 (rounded according to rounding mode)
+    _round_to_int
+    _rem
+    _sqrt, except float64_sqrt
+    _eq_signaling
+    _le_quiet
+    _lt_quiet
+
+In addition to these, none of the `floatx80' functions can be tested by
+default if the C `long double' type is something other than extended double
+precision; and likewise, none of the `float128' functions can be tested by
+default if `long double' is not quadruple precision.  Since `long double'
+cannot be both extended double precision and quadruple precision at the
+same time, at least one of these types cannot be tested by TestFloat without
+appropriate subroutines being supplied for that type.  (On the other hand,
+few systems implement _both_ extended double-precision and quadruple-
+precision floating-point; and unless a system does implement both, it does
+not need both tested.)
+
+Note that the `-list' option to `testfloat' will show the operations
+TestFloat is prepared to test.
+
+TestFloat's `systfloat' module supplies the system version of the functions
+to be tested.  The names of the `systfloat' subroutines are the same as the
+function names used as arguments to the `testfloat' command but with `syst_'
+prefixed--thus, for example, `syst_float32_add' and `syst_int32_to_float32'.
+The default `systfloat' module maps these system functions to the standard
+C operations; so `syst_float32_add', for example, is implemented using the
+C `+' operation for the single-precision `float' type.  For each system
+function supplied by `systfloat', a corresponding `SYST_'
+preprocessor macro is defined in `systfloat.h' to indicate that the function
+exists to be tested (e.g., `SYST_FLOAT32_ADD').  The `systfloat.h' header
+file also declares function prototypes for the `systfloat' functions.
+
+(The `systfloat.h' file that comes with the TestFloat package declares
+prototypes for all of the possible `systfloat' functions, whether defined in
+`systfloat' or not.  There is no penalty for declaring a function prototype
+that is never used.)
+
+A target-specific version of the `systfloat' module can easily be created to
+replace the generic one.  This in fact has been done for the example targets
+`386-Win32-gcc' and `SPARC-Solaris-gcc'.  For each target, an assembly
+language `systfloat.S' has been created in the target directory along with
+a corresponding `systfloat.h' header file defining the `SYST_'
+macros for the functions implemented.  The makefiles of the targets have
+been edited to use these target-specific versions of `systfloat' rather than
+the generic one.
+
+The `systfloat' modules of the example targets have been written entirely
+in assembly language in order to bypass any peculiarities of the C compiler.
+Although this is probably a good idea, it is certainly not required.
+
+
+-------------------------------------------------------------------------------
+Steps to Creating the TestFloat Executables
+
+Porting and/or compiling TestFloat involves the following steps:
+
+1. Port SoftFloat and create a SoftFloat binary.  (Refer to the
+   documentation accompanying SoftFloat.)
+
+2. If one does not already exist, create an appropriate target-specific
+   subdirectory under `testfloat' by copying the given `templates'
+   directory.  The remaining steps occur within the target-specific
+   subdirectory.
+
+3. Edit the files `milieu.h' and `Makefile' to reflect the current
+   environment.
+
+4. Make `testsoftfloat' by executing `make testsoftfloat' (or `make
+   testsoftfloat.exe', or whatever the `testsoftfloat' executable is
+   called).  Verify that SoftFloat is working correctly by testing it with
+   `testsoftfloat'.
+
+If you only wanted `testsoftfloat', you are done.  The steps for `testfloat'
+continue:
+
+5. In the target-specific subdirectory, implement the `systmodes' and
+   `systflags' modules.  (The `syst_float_set_rounding_precision' function
+   need not do anything if the system does not support extended double
+   precision.)
+
+6. If the target machine supports standard floating-point functions that are
+   not accessible within ISO/ANSI C, or if the C compiler cannot be trusted
+   to use the machine's floating-point directly, create a target-specific
+   `systfloat' module.
+
+7. In the target-specific subdirectory, execute `make'.
+
+
+-------------------------------------------------------------------------------
+Improving the Random Number Generator
+
+If you are serious about using TestFloat for testing floating-point, you
+should consider replacing the supplied `random.c' with a better target-
+specific one.  The standard C `rand' function is rather poor on some
+systems, and consequently `random.c' has been written to assume very little
+about the quality of `rand'.  As a result, the `rand' function is called
+more frequently than it might need to be, shortening the time before
+the random number generator repeats, and possibly wasting time as well.
+If `rand' is better on your system, or if another better random number
+generator is available (such as `rand48' on most Unix systems), TestFloat
+can be improved by overriding the given `random.c' with a target-specific
+one.
+
+
+-------------------------------------------------------------------------------
+Contact Information
+
+At the time of this writing, the most up-to-date information about
+TestFloat and the latest release can be found at the Web page `http://
+HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+
diff --git a/testfloat/testfloat.c b/testfloat/testfloat.c
new file mode 100644
index 00000000000..ea9e8f4c09d
--- /dev/null
+++ b/testfloat/testfloat.c
@@ -0,0 +1,295 @@
+
+/*
+===============================================================================
+
+This C source file is part of TestFloat, Release 2a, a package of programs
+for testing the correctness of floating-point arithmetic complying to the
+IEC/IEEE Standard for Floating-Point.
+
+Written by John R. Hauser.  More information is available through the Web
+page `http://HTTP.CS.Berkeley.EDU/~jhauser/arithmetic/TestFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+#include 
+#include 
+#include 
+#include "milieu.h"
+#include "fail.h"
+#include "softfloat.h"
+#include "testCases.h"
+#include "testLoops.h"
+#include "systflags.h"
+#include "testFunction.h"
+
+static void catchSIGINT( int signalCode )
+{
+
+    if ( stop ) exit( EXIT_FAILURE );
+    stop = TRUE;
+
+}
+
+main( int argc, char **argv )
+{
+    char *argPtr;
+    flag functionArgument;
+    uint8 functionCode;
+    int8 operands, roundingPrecision, roundingMode;
+
+    fail_programName = "testfloat";
+    if ( argc <= 1 ) goto writeHelpMessage;
+    testCases_setLevel( 1 );
+    trueName = "soft";
+    testName = "syst";
+    errorStop = FALSE;
+    forever = FALSE;
+    maxErrorCount = 20;
+    trueFlagsPtr = &float_exception_flags;
+    testFlagsFunctionPtr = syst_float_flags_clear;
+    tininessModeName = 0;
+    functionArgument = FALSE;
+    functionCode = 0;
+    operands = 0;
+    roundingPrecision = 0;
+    roundingMode = 0;
+    --argc;
+    ++argv;
+    while ( argc && ( argPtr = argv[ 0 ] ) ) {
+        if ( argPtr[ 0 ] == '-' ) ++argPtr;
+        if ( strcmp( argPtr, "help" ) == 0 ) {
+ writeHelpMessage:
+            fputs(
+"testfloat [