IFC @ r245178

This commit is contained in:
Neel Natu 2013-01-09 02:26:50 +00:00
commit 1b54fbe69d
133 changed files with 1819 additions and 1769 deletions

View File

@ -184,7 +184,10 @@ prn_octal(const char *s)
for (i = 0; i < (int)clen; i++)
putchar((unsigned char)s[i]);
len += wcwidth(wc);
} else if (goodchar && f_octal_escape && wc >= 0 &&
} else if (goodchar && f_octal_escape &&
#if WCHAR_MIN < 0
wc >= 0 &&
#endif
wc <= (wchar_t)UCHAR_MAX &&
(p = strchr(esc, (char)wc)) != NULL) {
putchar('\\');

View File

@ -25,6 +25,22 @@ THIS SOFTWARE.
This file lists all bug fixes, changes, etc., made since the AWK book
was sent to the printers in August, 1987.
Dec 20, 2012:
fiddled makefile to get correct yacc and bison flags. pick yacc
(linux) or bison (mac) as necessary.
added __attribute__((__noreturn__)) to a couple of lines in
proto.h, to silence someone's enthusiastic checker.
fixed obscure call by value bug in split(a[1],a) reported on
9fans. the management of temporary values is just a mess; i
took a shortcut by making an extra string copy. thanks
to paul patience and arnold robbins for passing it on and for
proposed patches.
tiny fiddle in setfval to eliminate -0 results in T.expr, which
has irritated me for 20+ years.
Aug 10, 2011:
another fix to avoid core dump with delete(ARGV); again, many thanks
to ruslan ermilov.

View File

@ -25,7 +25,7 @@ THIS SOFTWARE.
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
const char *version = "version 20110810 (FreeBSD)";
const char *version = "version 20121220 (FreeBSD)";
#define DEBUG
#include <stdio.h>

View File

@ -26,15 +26,15 @@ CFLAGS = -g
CFLAGS = -O2
CFLAGS =
CC = gcc -Wall -g
CC = cc
CC = gcc -Wall -g -Wwrite-strings
CC = gcc -fprofile-arcs -ftest-coverage # then gcov f1.c; cat f1.c.gcov
CC = gcc -g -Wall -pedantic
CC = gcc -O4 -Wall -pedantic -fno-strict-aliasing
YACC = bison -y
YACC = yacc
YFLAGS = -d
YACC = bison -d -y
YACC = yacc -d -S
#YFLAGS = -d -S
# -S uses sprintf in yacc parser instead of sprint
OFILES = b.o main.o parse.o proctab.o tran.o lib.o run.o lex.o

View File

@ -46,7 +46,7 @@ extern void freetr(Node *);
extern int hexstr(uschar **);
extern int quoted(uschar **);
extern char *cclenter(const char *);
extern void overflo(const char *);
extern void overflo(const char *) __attribute__((__noreturn__));
extern void cfoll(fa *, Node *);
extern int first(Node *);
extern void follow(Node *);
@ -132,7 +132,7 @@ extern void fpecatch(int);
extern void bracecheck(void);
extern void bcheck2(int, int, int);
extern void SYNTAX(const char *, ...);
extern void FATAL(const char *, ...);
extern void FATAL(const char *, ...) __attribute__((__noreturn__));
extern void WARNING(const char *, ...);
extern void error(void);
extern void eprint(void);

View File

@ -1213,13 +1213,13 @@ Cell *dopa2(Node **a, int n) /* a[0], a[1] { a[2] } */
Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
{
Cell *x = 0, *y, *ap;
char *s;
char *s, *origs;
int sep;
char *t, temp, num[50], *fs = 0;
int n, tempstat, arg3type;
y = execute(a[0]); /* source string */
s = getsval(y);
origs = s = strdup(getsval(y));
arg3type = ptoi(a[3]);
if (a[2] == 0) /* fs string */
fs = *FS;
@ -1339,6 +1339,7 @@ Cell *split(Node **a, int nnn) /* split(a[0], a[1], a[2]); a[3] is type */
}
tempfree(ap);
tempfree(y);
free(origs);
if (a[2] != 0 && arg3type == STRING) {
tempfree(x);
}

View File

@ -298,6 +298,8 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
xfree(vp->sval); /* free any previous string */
vp->tval &= ~STR; /* mark string invalid */
vp->tval |= NUM; /* mark number ok */
if (f == -0) /* who would have thought this possible? */
f = 0;
dprintf( ("setfval %p: %s = %g, t=%o\n", (void*)vp, NN(vp->nval), f, vp->tval) );
return vp->fval = f;
}

View File

@ -7,14 +7,14 @@
; (e.g. reference this file in the "cache . <file>"
; configuration file of BIND domain name servers).
;
; This file is made available by InterNIC
; This file is made available by InterNIC
; under anonymous FTP as
; file /domain/named.root
; file /domain/named.cache
; on server FTP.INTERNIC.NET
; -OR- RS.INTERNIC.NET
;
; last update: Jun 8, 2011
; related version of root zone: 2011060800
; last update: Jan 3, 2013
; related version of root zone: 2013010300
;
; formerly NS.INTERNIC.NET
;
@ -35,7 +35,7 @@ C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
; FORMERLY TERP.UMD.EDU
;
. 3600000 NS D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET. 3600000 A 128.8.10.90
D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13
D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2D::D
;
; FORMERLY NS.NASA.GOV

View File

@ -43,5 +43,5 @@ divert(0)dnl
VERSIONID(`$FreeBSD$')
OSTYPE(freebsd6)
FEATURE(nullclient, smarthost.ysv.$m)
FEATURE(nullclient, smarthost.ysv.freebsd.org)
MASQUERADE_AS(FreeBSD.org)

View File

@ -1,6 +1,7 @@
# $FreeBSD$
. ${srcdir}/emulparams/armelf.sh
. ${srcdir}/emulparams/elf_fbsd.sh
TARGET2_TYPE=got-rel
MAXPAGESIZE=0x8000
GENERATE_PIE_SCRIPT=yes

View File

@ -5,6 +5,7 @@
#OUTPUT_FORMAT="elf32-bigarm"
. ${srcdir}/emulparams/armelf.sh
. ${srcdir}/emulparams/elf_fbsd.sh
TARGET2_TYPE=got-rel
MAXPAGESIZE=0x8000
GENERATE_PIE_SCRIPT=yes

View File

@ -61,9 +61,7 @@ _start(char **ap, void (*cleanup)(void))
argc = *(long *)(void *)ap;
argv = ap + 1;
env = ap + 2 + argc;
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (&_DYNAMIC != NULL)
atexit(cleanup);

View File

@ -98,10 +98,7 @@ __start(int argc, char **argv, char **env, struct ps_strings *ps_strings,
const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void))
{
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (ps_strings != (struct ps_strings *)0)
__ps_strings = ps_strings;

View File

@ -87,14 +87,18 @@ handle_static_init(int argc, char **argv, char **env)
}
static inline void
handle_progname(const char *v)
handle_argv(int argc, char *argv[], char **env)
{
const char *s;
__progname = v;
for (s = __progname; *s != '\0'; s++) {
if (*s == '/')
__progname = s + 1;
if (environ == NULL)
environ = env;
if (argc > 0 && argv[0] != NULL) {
__progname = argv[0];
for (s = __progname; *s != '\0'; s++) {
if (*s == '/')
__progname = s + 1;
}
}
}

View File

@ -61,10 +61,7 @@ _start1(fptr cleanup, int argc, char *argv[])
char **env;
env = argv + argc + 1;
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (&_DYNAMIC != NULL)
atexit(cleanup);
else

View File

@ -71,9 +71,7 @@ __start(char **ap,
argc = * (long *) ap;
argv = ap + 1;
env = ap + 2 + argc;
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (&_DYNAMIC != NULL)
atexit(cleanup);

View File

@ -81,10 +81,8 @@ _start(int argc, char **argv, char **env,
struct ps_strings *ps_strings)
{
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (ps_strings != (struct ps_strings *)0)
__ps_strings = ps_strings;

View File

@ -81,10 +81,7 @@ _start(int argc, char **argv, char **env,
struct ps_strings *ps_strings)
{
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (ps_strings != (struct ps_strings *)0)
__ps_strings = ps_strings;

View File

@ -85,9 +85,7 @@ _start(char **ap, void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused,
argc = *(long *)(void *)ap;
argv = ap + 1;
env = ap + 2 + argc;
environ = env;
if (argc > 0 && argv[0] != NULL)
handle_progname(argv[0]);
handle_argv(argc, argv, env);
if (&_DYNAMIC != NULL)
atexit(cleanup);

View File

@ -95,7 +95,7 @@ what the endianness of the CPU. VFP is sane.
#define FLOAT64_DEMANGLE(a) (a)
#define FLOAT64_MANGLE(a) (a)
#else
#define FLOAT64_DEMANGLE(a) (((a) << 32) | ((a) >> 32))
#define FLOAT64_DEMANGLE(a) ((((a) & 0xfffffffful) << 32) | ((a) >> 32))
#define FLOAT64_MANGLE(a) FLOAT64_DEMANGLE(a)
#endif
#endif

View File

@ -36,9 +36,9 @@ if [ $# -lt 3 ]; then
exit 1
fi
LABEL=$1; shift
LABEL=`echo $1 | tr '[:lower:]' '[:upper:]'`; shift
NAME=$1; shift
echo "/dev/iso9660/`echo $LABEL | tr '[:lower:]' '[:upper:]'` / cd9660 ro 0 0" > $1/etc/fstab
echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > $1/etc/fstab
makefs -t cd9660 $bootable -o rockridge -o label=$LABEL $NAME $*
rm $1/etc/fstab

View File

@ -36,9 +36,9 @@ if [ $# -lt 3 ]; then
exit 1
fi
LABEL=$1; shift
LABEL=`echo $1 | tr '[:lower:]' '[:upper:]'`; shift
NAME=$1; shift
echo "/dev/iso9660/`echo $LABEL | tr '[:lower:]' '[:upper:]'` / cd9660 ro 0 0" > $1/etc/fstab
echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > $1/etc/fstab
makefs -t cd9660 $bootable -o rockridge -o label=$LABEL $NAME $*
rm $1/etc/fstab

View File

@ -37,7 +37,7 @@ if [ $# -lt 3 ]; then
exit 1
fi
LABEL=$1; shift
LABEL=`echo $1 | tr '[:lower:]' '[:upper:]'`; shift
NAME=$1; shift
BASE=$1; shift

View File

@ -36,9 +36,9 @@ if [ $# -lt 3 ]; then
exit 1
fi
LABEL=$1; shift
LABEL=`echo $1 | tr '[:lower:]' '[:upper:]'`; shift
NAME=$1; shift
echo "/dev/iso9660/`echo $LABEL | tr '[:lower:]' '[:upper:]'` / cd9660 ro 0 0" > $1/etc/fstab
echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > $1/etc/fstab
makefs -t cd9660 $bootable -o rockridge -o label=$LABEL $NAME $*
rm $1/etc/fstab

View File

@ -58,10 +58,10 @@ if [ $# -lt 3 ]; then
exit 1
fi
LABEL=$1; shift
LABEL=`echo $1 | tr '[:lower:]' '[:upper:]'`; shift
NAME=$1; shift
echo "/dev/iso9660/`echo $LABEL | tr '[:lower:]' '[:upper:]'` / cd9660 ro 0 0" > $1/etc/fstab
echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > $1/etc/fstab
makefs -t cd9660 $bootable -o rockridge -o label=$LABEL $NAME $*
rm $1/etc/fstab
rm /tmp/hfs-boot-block

View File

@ -63,7 +63,7 @@ if [ $? -ne 0 ]; then
fi
fi
LABEL=$1; shift
LABEL=`echo $1 | tr '[:lower:]' '[:upper:]'`; shift
NAME=$1; shift
echo "/dev/iso9660/$LABEL / cd9660 ro 0 0" > $1/etc/fstab

View File

@ -73,6 +73,6 @@ g_journal_ufs_using_last_sector(const char *prov)
/* Provider size in 512 bytes blocks. */
psize = g_get_mediasize(prov) / DEV_BSIZE;
/* File system size in 512 bytes blocks. */
fssize = fsbtodb(fs, dbtofsb(fs, psize));
return (psize == fssize);
fssize = fsbtodb(fs, fs->fs_size);
return (psize <= fssize);
}

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 19, 2012
.Dd January 3, 2013
.Dt GPART 8
.Os
.Sh NAME
@ -453,8 +453,14 @@ about its use.
.El
.\" ==== SHOW ====
.It Cm show
Show the current partition information of the specified geoms
or all geoms if none are specified.
Show current partition information for the specified geoms, or all
geoms if none are specified.
The default output includes the logical starting block of each
partition, the partition size in blocks, the partition index number,
the partition type, and a human readable partition size.
Block sizes and locations are based on the device's Sectorsize
as shown by
.Cm gpart list .
Additional options include:
.Bl -tag -width 10n
.It Fl l
@ -919,7 +925,7 @@ and
.Cm list
will report about corrupt tables.
.Pp
If the size of the device has changed (e.g.\& volume expansion) the
If the size of the device has changed (e.g.,\& volume expansion) the
secondary GPT header will no longer be located in the last sector.
This is not a metadata corruption, but it is dangerous because any
corruption of the primary GPT will lead to loss of the partition table.
@ -979,14 +985,14 @@ This may break a mirrored volume and lead to data damage.
Exit status is 0 on success, and 1 if the command fails.
.Sh EXAMPLES
Create a GPT scheme on
.Pa ad0 :
.Pa ada0 :
.Bd -literal -offset indent
/sbin/gpart create -s GPT ad0
/sbin/gpart create -s GPT ada0
.Ed
.Pp
Embed GPT bootstrap code into a protective MBR:
.Bd -literal -offset indent
/sbin/gpart bootcode -b /boot/pmbr ad0
/sbin/gpart bootcode -b /boot/pmbr ada0
.Ed
.Pp
Create a dedicated
@ -1011,15 +1017,15 @@ aligned on a 64 kB boundary without the need to specify an explicit
offset or alignment.
The boot partition itself is aligned on a 4 kB boundary.
.Bd -literal -offset indent
/sbin/gpart add -b 40 -s 88 -t freebsd-boot ad0
/sbin/gpart bootcode -p /boot/gptboot -i 1 ad0
/sbin/gpart add -b 40 -s 88 -t freebsd-boot ada0
/sbin/gpart bootcode -p /boot/gptboot -i 1 ada0
.Ed
.Pp
Create a 512MB-sized
.Cm freebsd-ufs
partition to contain a UFS filesystem from which the system can boot.
.Bd -literal -offset indent
/sbin/gpart add -s 512M -t freebsd-ufs ad0
/sbin/gpart add -s 512M -t freebsd-ufs ada0
.Ed
.Pp
Create an MBR scheme on

View File

@ -57,27 +57,35 @@ static const char rcsid[] =
#include "mntopts.h"
static struct mntopt mopts[] = {
MOPT_STDOPTS,
MOPT_END
};
int subdir(const char *, const char *);
static void usage(void) __dead2;
int
main(int argc, char *argv[])
{
struct iovec iov[6];
int ch, mntflags;
struct iovec *iov;
char *p, *val;
char source[MAXPATHLEN];
char target[MAXPATHLEN];
char errmsg[255];
int ch, mntflags, iovlen;
char nullfs[] = "nullfs";
iov = NULL;
iovlen = 0;
mntflags = 0;
errmsg[0] = '\0';
while ((ch = getopt(argc, argv, "o:")) != -1)
switch(ch) {
case 'o':
getmntopts(optarg, mopts, &mntflags, 0);
val = strdup("");
p = strchr(optarg, '=');
if (p != NULL) {
free(val);
*p = '\0';
val = p + 1;
}
build_iovec(&iov, &iovlen, optarg, val, (size_t)-1);
break;
case '?':
default:
@ -99,21 +107,16 @@ main(int argc, char *argv[])
errx(EX_USAGE, "%s (%s) and %s are not distinct paths",
argv[0], target, argv[1]);
iov[0].iov_base = strdup("fstype");
iov[0].iov_len = sizeof("fstype");
iov[1].iov_base = strdup("nullfs");
iov[1].iov_len = strlen(iov[1].iov_base) + 1;
iov[2].iov_base = strdup("fspath");
iov[2].iov_len = sizeof("fspath");
iov[3].iov_base = source;
iov[3].iov_len = strlen(source) + 1;
iov[4].iov_base = strdup("target");
iov[4].iov_len = sizeof("target");
iov[5].iov_base = target;
iov[5].iov_len = strlen(target) + 1;
if (nmount(iov, 6, mntflags))
err(1, NULL);
build_iovec(&iov, &iovlen, "fstype", nullfs, (size_t)-1);
build_iovec(&iov, &iovlen, "fspath", source, (size_t)-1);
build_iovec(&iov, &iovlen, "target", target, (size_t)-1);
build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
if (nmount(iov, iovlen, mntflags) < 0) {
if (errmsg[0] != 0)
err(1, "%s: %s", source, errmsg);
else
err(1, "%s", source);
}
exit(0);
}

View File

@ -94,7 +94,7 @@ typedef union sockunion *sup;
int pid, rtm_addrs;
int s;
int forcehost, forcenet, doflush, nflag, af, qflag, tflag;
int iflag, verbose, aflen = sizeof (struct sockaddr_in);
int verbose, aflen = sizeof (struct sockaddr_in);
int locking, lockrest, debugonly;
struct rt_metrics rt_metrics;
u_long rtm_inits;
@ -107,7 +107,7 @@ static char *atalk_ntoa(struct at_addr);
static void bprintf(FILE *, int, u_char *);
static void flushroutes(int argc, char *argv[]);
static int flushroutes_fib(int);
static int getaddr(int, char *, struct hostent **);
static int getaddr(int, char *, struct hostent **, int);
static int keyword(const char *);
static void inet_makenetandmask(u_long, struct sockaddr_in *, u_long);
#ifdef INET6
@ -833,34 +833,34 @@ newroute(int argc, char **argv)
case K_IFA:
if (!--argc)
usage(NULL);
(void) getaddr(RTA_IFA, *++argv, 0);
getaddr(RTA_IFA, *++argv, 0, nrflags);
break;
case K_IFP:
if (!--argc)
usage(NULL);
(void) getaddr(RTA_IFP, *++argv, 0);
getaddr(RTA_IFP, *++argv, 0, nrflags);
break;
case K_GENMASK:
if (!--argc)
usage(NULL);
(void) getaddr(RTA_GENMASK, *++argv, 0);
getaddr(RTA_GENMASK, *++argv, 0, nrflags);
break;
case K_GATEWAY:
if (!--argc)
usage(NULL);
(void) getaddr(RTA_GATEWAY, *++argv, 0);
getaddr(RTA_GATEWAY, *++argv, 0, nrflags);
break;
case K_DST:
if (!--argc)
usage(NULL);
if (getaddr(RTA_DST, *++argv, &hp))
if (getaddr(RTA_DST, *++argv, &hp, nrflags))
nrflags |= F_ISHOST;
dest = *argv;
break;
case K_NETMASK:
if (!--argc)
usage(NULL);
(void) getaddr(RTA_NETMASK, *++argv, 0);
getaddr(RTA_NETMASK, *++argv, 0, nrflags);
/* FALLTHROUGH */
case K_NET:
nrflags |= F_FORCENET;
@ -895,13 +895,13 @@ newroute(int argc, char **argv)
} else {
if ((rtm_addrs & RTA_DST) == 0) {
dest = *argv;
if (getaddr(RTA_DST, *argv, &hp))
if (getaddr(RTA_DST, *argv, &hp, nrflags))
nrflags |= F_ISHOST;
} else if ((rtm_addrs & RTA_GATEWAY) == 0) {
gateway = *argv;
(void) getaddr(RTA_GATEWAY, *argv, &hp);
getaddr(RTA_GATEWAY, *argv, &hp, nrflags);
} else {
(void) getaddr(RTA_NETMASK, *argv, 0);
getaddr(RTA_NETMASK, *argv, 0, nrflags);
nrflags |= F_FORCENET;
}
}
@ -1116,7 +1116,7 @@ inet6_makenetandmask(struct sockaddr_in6 *sin6, const char *plen)
* returning 1 if a host address, 0 if a network address.
*/
static int
getaddr(int which, char *str, struct hostent **hpp)
getaddr(int which, char *str, struct hostent **hpp, int nrflags)
{
sup su;
struct hostent *hp;
@ -1137,7 +1137,7 @@ getaddr(int which, char *str, struct hostent **hpp)
break;
case RTA_GATEWAY:
su = &so_gate;
if (iflag) {
if (nrflags & F_INTERFACE) {
struct ifaddrs *ifap, *ifa;
struct sockaddr_dl *sdl = NULL;
@ -1197,7 +1197,7 @@ getaddr(int which, char *str, struct hostent **hpp)
#if 0
bzero(su, sizeof(*su)); /* for readability */
#endif
getaddr(RTA_NETMASK, str, 0);
getaddr(RTA_NETMASK, str, 0, nrflags);
break;
#if 0
case RTA_NETMASK:

View File

@ -52,7 +52,6 @@ XFILES= BSD_daemon/FreeBSD.pfa \
csh/dot.cshrc \
cvsup/README \
cvsup/cvs-supfile \
cvsup/gnats-supfile \
cvsup/ports-supfile \
cvsup/refuse \
cvsup/refuse.README \

View File

@ -1,5 +1,15 @@
# $FreeBSD$
BEWARE, CVS is deprecated and no longer supported by the FreeBSD project.
The primary development work happens in Subversion and is temporarily
exported to the legacy CVS system with significant time delays.
You should NOT set up a new consumer of FreeBSD source code via CVS.
Please see:
http://www.freebsd.org/doc/handbook/svn.html
http://www.freebsd.org/doc/handbook/svn-mirrors.html
This directory contains sample "supfiles" for obtaining and updating
the FreeBSD sources via the Internet. These supfiles will work
with CVSup version 14.0 or later. For general information on CVSup
@ -20,10 +30,6 @@ FreeBSD, use:
cvs-supfile Main source tree and ports collection
To maintain a copy of the FreeBSD bug database, use the file:
gnats-supfile FreeBSD bug database
IMPORTANT: Before you use any of the supfiles in this directory,
you will need to edit in an appropriate "host" setting. See:

View File

@ -1,7 +1,14 @@
# $FreeBSD$
#
# This file contains all of the "CVSup collections" that make up the
# CVS development tree of the FreeBSD system.
# BEWARE, CVS is deprecated and no longer supported by the FreeBSD project.
#
# The primary development work happens in Subversion and is temporarily
# exported to the legacy CVS system with significant time delays.
#
# You should NOT set up a new consumer of FreeBSD source code via CVS.
# Please see:
# http://www.freebsd.org/doc/handbook/svn.html
# http://www.freebsd.org/doc/handbook/svn-mirrors.html
#
# csup (CVS Update Protocol) allows you to download the latest CVS
# tree (or any branch of development therefrom) to your system easily
@ -61,36 +68,6 @@
# mega-collection. It includes all of the individual "src-*" collections.
src-all
# These are the individual collections that make up "src-all". If you
# use these, be sure to comment out "src-all" above.
#src-base
#src-bin
#src-cddl
#src-contrib
#src-etc
#src-games
#src-gnu
#src-include
#src-kerberos5
#src-kerberosIV
#src-lib
#src-libexec
#src-release
#src-rescue
#src-sbin
#src-share
#src-sys
#src-tools
#src-usrbin
#src-usrsbin
# These are the individual collections that make up FreeBSD's crypto
# collection. They are no longer export-restricted and are a part of
# src-all
#src-crypto
#src-eBones
#src-secure
#src-sys-crypto
## Ports Collection.
#
# The easiest way to get the ports tree is to use the "ports-all"
@ -98,77 +75,6 @@ src-all
# collections,
ports-all
# These are the individual collections that make up "ports-all". If you
# use these, be sure to comment out "ports-all" above and always include
# "ports-base" if you use any of the other individual collections below.
# Your ports may not build correctly without an up-to-date "ports-base".
#
#ports-base
#
#ports-accessibility
#ports-arabic
#ports-archivers
#ports-astro
#ports-audio
#ports-benchmarks
#ports-biology
#ports-cad
#ports-chinese
#ports-comms
#ports-converters
#ports-databases
#ports-deskutils
#ports-devel
#ports-dns
#ports-editors
#ports-emulators
#ports-finance
#ports-french
#ports-ftp
#ports-games
#ports-german
#ports-graphics
#ports-hebrew
#ports-hungarian
#ports-irc
#ports-japanese
#ports-java
#ports-korean
#ports-lang
#ports-mail
#ports-math
#ports-misc
#ports-multimedia
#ports-net
#ports-net-im
#ports-net-mgmt
#ports-net-p2p
#ports-news
#ports-palm
#ports-picobsd
#ports-polish
#ports-ports-mgmt
#ports-portuguese
#ports-print
#ports-russian
#ports-science
#ports-security
#ports-shells
#ports-sysutils
#ports-textproc
#ports-ukrainian
#ports-vietnamese
#ports-www
#ports-x11
#ports-x11-clocks
#ports-x11-drivers
#ports-x11-fm
#ports-x11-fonts
#ports-x11-servers
#ports-x11-themes
#ports-x11-toolkits
#ports-x11-wm
## Projects
#
# This collection retrieves the projects tree of the FreeBSD
@ -179,11 +85,3 @@ projects-all
#
# This is to get the control files that cvs(1) needs and the commit logs.
cvsroot-all
# These are the individual collections that make up "cvsroot-all" If you
# use these, be sure to comment out "cvsroot-all" above. "cvsroot-common"
# is a synthetic CVSROOT that has all the modules from the other CVSROOT-*
# directories merged into one, and merged commitlogs via symlinks.
#cvsroot-common
#cvsroot-src
#cvsroot-ports

View File

@ -1,60 +0,0 @@
# $FreeBSD$
#
# This file contains all of the "CVSup collections" that make up the
# FreeBSD GNATS bug report database.
#
# csup (CVS Update Protocol) allows you to download the latest CVS
# tree (or any branch of development therefrom) to your system easily
# and efficiently
#
# To keep your CVS tree up-to-date run:
#
# csup gnats-supfile
#
# Note that this only updates the tree contents and does not
# update what is actually installed.
#
# You may wish to change some of the settings in this file to better
# suit your system:
#
# host=CHANGE_THIS.FreeBSD.org
# This specifies the server host which will supply the
# file updates. You must change it to one of the CVSup
# mirror sites listed in the FreeBSD Handbook at
# http://www.freebsd.org/doc/handbook/cvsup.html#CVSUP-MIRRORS.
# You can override this setting on the command line
# with cvsup's "-h host" option.
#
# base=/var/db
# This specifies the root where csup will store information
# about the collections you have transferred to your system.
# A setting of "/var/db" will generate this information in
# /var/db/sup. You can override the "base" setting on the
# command line with cvsup's "-b base" option. This directory
# must exist in order to run CVSup.
#
# prefix=/usr
# This specifies where to place the requested files. A
# setting of "/usr" will place all of the files requested
# in "/usr/gnats".
# The prefix directory must exist in order to run CVSup.
# Defaults that apply to all the collections
#
# IMPORTANT: Change the next line to use one of the CVSup mirror sites
# listed at http://www.freebsd.org/doc/handbook/cvsup.html#CVSUP-MIRRORS.
*default host=CHANGE_THIS.FreeBSD.org
*default base=/var/db
*default prefix=/usr
*default release=current
*default delete use-rel-suffix
# If you seem to be limited by CPU rather than network or disk bandwidth, try
# commenting out the following line. (Normally, today's CPUs are fast enough
# that you want to run compression.)
*default compress
## GNATS database
#
gnats

View File

@ -1,7 +1,14 @@
# $FreeBSD$
#
# This file contains all of the "CVSup collections" that make up the
# ports collection.
# BEWARE, CVS is deprecated and no longer supported by the FreeBSD project.
#
# The primary development work happens in Subversion and is temporarily
# exported to the legacy CVS system with significant time delays.
#
# You should NOT set up a new consumer of FreeBSD source code via CVS.
# Please see:
# http://www.freebsd.org/doc/handbook/svn.html
# http://www.freebsd.org/doc/handbook/svn-mirrors.html
#
# csup (CVS Update Protocol) allows you to download the latest CVS
# tree (or any branch of development therefrom) to your system easily
@ -65,76 +72,3 @@
# mega-collection. It includes all of the individual "ports-*"
# collections,
ports-all
# These are the individual collections that make up "ports-all". If you
# use these, be sure to comment out "ports-all" above.
# Be sure to ALWAYS cvsup the ports-base collection if you use any of the
# other individual collections below. ports-base is a mandatory collection
# for the ports collection, and your ports may not build correctly if it
# is not kept up to date.
#
# Use of individual collections is not a supported configuration.
#ports-base
#ports-accessibility
#ports-arabic
#ports-archivers
#ports-astro
#ports-audio
#ports-benchmarks
#ports-biology
#ports-cad
#ports-chinese
#ports-comms
#ports-converters
#ports-databases
#ports-deskutils
#ports-devel
#ports-dns
#ports-editors
#ports-emulators
#ports-finance
#ports-french
#ports-ftp
#ports-games
#ports-german
#ports-graphics
#ports-hebrew
#ports-hungarian
#ports-irc
#ports-japanese
#ports-java
#ports-korean
#ports-lang
#ports-mail
#ports-math
#ports-misc
#ports-multimedia
#ports-net
#ports-net-im
#ports-net-mgmt
#ports-net-p2p
#ports-news
#ports-palm
#ports-polish
#ports-ports-mgmt
#ports-portuguese
#ports-print
#ports-russian
#ports-science
#ports-security
#ports-shells
#ports-sysutils
#ports-textproc
#ports-ukrainian
#ports-vietnamese
#ports-www
#ports-x11
#ports-x11-clocks
#ports-x11-drivers
#ports-x11-fm
#ports-x11-fonts
#ports-x11-servers
#ports-x11-themes
#ports-x11-toolkits
#ports-x11-wm

View File

@ -1,7 +1,14 @@
# $FreeBSD$
#
# This file contains all of the "CVSup collections" that make up the
# FreeBSD-stable source tree.
# BEWARE, CVS is deprecated and no longer supported by the FreeBSD project.
#
# The primary development work happens in Subversion and is temporarily
# exported to the legacy CVS system with significant time delays.
#
# You should NOT set up a new consumer of FreeBSD source code via CVS.
# Please see:
# http://www.freebsd.org/doc/handbook/svn.html
# http://www.freebsd.org/doc/handbook/svn-mirrors.html
#
# csup (CVS Update Protocol) allows you to download the latest CVS
# tree (or any branch of development therefrom) to your system easily
@ -80,33 +87,3 @@
# mega-collection. It includes all of the individual "src-*" collections.
# Please note: If you want to track -STABLE, leave this uncommented.
src-all
# These are the individual collections that make up "src-all". If you
# use these, be sure to comment out "src-all" above.
#src-base
#src-bin
#src-cddl
#src-contrib
#src-etc
#src-games
#src-gnu
#src-include
#src-kerberos5
#src-kerberosIV
#src-lib
#src-libexec
#src-release
#src-rescue
#src-sbin
#src-share
#src-sys
#src-tools
#src-usrbin
#src-usrsbin
# These are the individual collections that make up FreeBSD's crypto
# collection. They are no longer export-restricted and are a part of
# src-all
#src-crypto
#src-eBones
#src-secure
#src-sys-crypto

View File

@ -1,7 +1,14 @@
# $FreeBSD$
#
# This file contains all of the "CVSup collections" that make up the
# FreeBSD-current source tree.
# BEWARE, CVS is deprecated and no longer supported by the FreeBSD project.
#
# The primary development work happens in Subversion and is temporarily
# exported to the legacy CVS system with significant time delays.
#
# You should NOT set up a new consumer of FreeBSD source code via CVS.
# Please see:
# http://www.freebsd.org/doc/handbook/svn.html
# http://www.freebsd.org/doc/handbook/svn-mirrors.html
#
# csup (CVS Update Protocol) allows you to download the latest CVS
# tree (or any branch of development therefrom) to your system easily
@ -59,33 +66,3 @@
# The easiest way to get the main source tree is to use the "src-all"
# mega-collection. It includes all of the individual "src-*" collections.
src-all
# These are the individual collections that make up "src-all". If you
# use these, be sure to comment out "src-all" above.
#src-base
#src-bin
#src-cddl
#src-contrib
#src-etc
#src-games
#src-gnu
#src-include
#src-kerberos5
#src-kerberosIV
#src-lib
#src-libexec
#src-release
#src-rescue
#src-sbin
#src-share
#src-sys
#src-tools
#src-usrbin
#src-usrsbin
# These are the individual collections that make up FreeBSD's crypto
# collection. They are no longer export-restricted and are a part of
# src-all
#src-crypto
#src-eBones
#src-secure
#src-sys-crypto

View File

@ -34,7 +34,7 @@
.\" $Id: //depot/SpectraBSD/head/share/man/man4/mps.4#6 $
.\" $FreeBSD$
.\"
.Dd June 30, 2012
.Dd January 3, 2013
.Dt MPS 4
.Os
.Sh NAME
@ -62,7 +62,7 @@ controllers and WarpDrive solid state storage cards.
.Sh HARDWARE
The
.Nm
driver supports the following controllers:
driver supports the following hardware:
.Pp
.Bl -bullet -compact
.It
@ -80,6 +80,19 @@ LSI Logic SAS2116 (16 Port
.It
LSI Logic SAS2208 (8 Port
.Tn SAS )
.It
LSI Logic SAS2308 (8 Port
.Tn SAS )
.It
LSI Logic SSS6200 Solid State Storage
.It
Intel Integrated RAID Module RMS25JB040
.It
Intel Integrated RAID Module RMS25JB080
.It
Intel Integrated RAID Module RMS25KB040
.It
Intel Integrated RAID Module RMS25KB080
.El
.Sh CONFIGURATION
To disable MSI interrupts for all

View File

@ -102,12 +102,11 @@ If
.Fa priority
includes the
.Dv PCATCH
flag, pending
signals are checked before and after sleeping, otherwise signals are
not checked.
flag, pending signals are allowed to interrupt the sleep, otherwise
pending signals are ignored during the sleep.
If
.Dv PCATCH
is set and a signal needs to be delivered,
is set and a signal becomes pending,
.Er ERESTART
is returned if the current system call should be restarted if
possible, and
@ -119,9 +118,10 @@ If the
.Dv PBDRY
flag is specified in addition to
.Dv PCATCH ,
then the sleeping thread is not stopped upon delivery of
then the sleeping thread is not stopped when
.Dv SIGSTOP
or other stop action while it is sleeping.
becomes pending
or some other stop action occurs while it is sleeping.
Instead, it is woken up, with the assumption
that the stop will occur on reaching a stop
point when returning to usermode.

View File

@ -140,6 +140,7 @@ maho [label="Maho Nakata\nmaho@FreeBSD.org\n2002/10/17"]
makc [label="Max Brazhnikov\nmakc@FreeBSD.org\n2008/08/25"]
mandree [label="Matthias Andree\nmandree@FreeBSD.org\n2009/11/18"]
marcus [label="Joe Marcus Clarke\nmarcus@FreeBSD.org\n2002/04/05"]
marius [label="Marius Strobl\nmarius@FreeBSD.org\n2012/12/29"]
markus [label="Markus Brueffer\nmarkus@FreeBSD.org\n2004/02/21"]
martymac [label="Ganael Laplanche\nmartymac@FreeBSD.org\n2010/09/24"]
mat [label="Mathieu Arnold\nmat@FreeBSD.org\n2003/08/15"]
@ -235,8 +236,10 @@ avilla -> rakuco
bapt -> bdrewery
bapt -> eadler
bapt -> jlaffaye
bapt -> marius
beat -> decke
beat -> marius
beat -> sperber
beat -> uqs

View File

@ -97,13 +97,13 @@ _CPUCFLAGS = -march=${CPUTYPE}
. if ${CPUTYPE} == "xscale"
#XXX: gcc doesn't seem to like -mcpu=xscale, and dies while rebuilding itself
#_CPUCFLAGS = -mcpu=xscale
_CPUCFLAGS = -march=armv5te -D__XSCALE__ -DARM_WANT_TP_ADDRESS
_CPUCFLAGS = -march=armv5te -D__XSCALE__
. elif ${CPUTYPE} == "armv6"
_CPUCFLAGS = -march=${CPUTYPE} -DARM_ARCH_6=1
. elif ${CPUTYPE} == "cortexa"
_CPUCFLAGS = -march=armv6 -DARM_ARCH_6=1 -mfpu=vfp
_CPUCFLAGS = -DARM_ARCH_6=1 -mfpu=vfp
. else
_CPUCFLAGS = -mcpu=${CPUTYPE} -DARM_WANT_TP_ADDRESS
_CPUCFLAGS = -mcpu=${CPUTYPE}
. endif
. elif ${MACHINE_ARCH} == "powerpc"
. if ${CPUTYPE} == "e500"

View File

@ -35,6 +35,7 @@ options SOFTUPDATES # Enable FFS soft updates support
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
options UFS_GJOURNAL # Enable gjournal-based UFS journaling
options QUOTA # Enable disk quotas for UFS
options MD_ROOT # MD is a potential root device
options NFSCL # New Network Filesystem Client
options NFSD # New Network Filesystem Server
@ -317,15 +318,6 @@ device usb # USB Bus (required)
device ukbd # Keyboard
device umass # Disks/Mass storage - Requires scbus and da
# FireWire support
device firewire # FireWire bus code
# sbp(4) works for some systems but causes boot failure on others
#device sbp # SCSI over FireWire (Requires scbus and da)
device fwe # Ethernet over FireWire (non-standard!)
device fwip # IP over FireWire (RFC 2734,3146)
device dcons # Dumb console driver
device dcons_crom # Configuration ROM for dcons
# Sound support
device sound # Generic sound driver (required)
device snd_cmi # CMedia CMI8338/CMI8738

View File

@ -72,6 +72,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ptrace.h>
#include <sys/signalvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/uio.h>
@ -162,8 +163,6 @@ const struct pmap_devmap *pmap_devmap_bootstrap_table;
uint32_t board_id;
struct arm_lbabi_tag *atag_list;
uint32_t revision;
uint64_t serial;
char linux_command_line[LBABI_MAX_COMMAND_LINE + 1];
char atags[LBABI_MAX_COMMAND_LINE * 2];
uint32_t memstart[LBABI_MAX_BANKS];
@ -171,6 +170,31 @@ uint32_t memsize[LBABI_MAX_BANKS];
uint32_t membanks;
#endif
static uint32_t board_revision;
/* hex representation of uint64_t */
static char board_serial[32];
SYSCTL_NODE(_hw, OID_AUTO, board, CTLFLAG_RD, 0, "Board attributes");
SYSCTL_UINT(_hw_board, OID_AUTO, revision, CTLFLAG_RD,
&board_revision, 0, "Board revision");
SYSCTL_STRING(_hw_board, OID_AUTO, serial, CTLFLAG_RD,
board_serial, 0, "Board serial");
void
board_set_serial(uint64_t serial)
{
snprintf(board_serial, sizeof(board_serial)-1,
"%016jx", serial);
}
void
board_set_revision(uint32_t revision)
{
board_revision = revision;
}
void
sendsig(catcher, ksi, mask)
sig_t catcher;
@ -849,6 +873,8 @@ vm_offset_t
linux_parse_boot_param(struct arm_boot_params *abp)
{
struct arm_lbabi_tag *walker;
uint32_t revision;
uint64_t serial;
/*
* Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2
@ -883,9 +909,11 @@ linux_parse_boot_param(struct arm_boot_params *abp)
case ATAG_SERIAL:
serial = walker->u.tag_sn.low |
((uint64_t)walker->u.tag_sn.high << 32);
board_set_serial(serial);
break;
case ATAG_REVISION:
revision = walker->u.tag_rev.rev;
board_set_revision(revision);
break;
case ATAG_CMDLINE:
/* XXX open question: Parse this for boothowto? */

View File

@ -135,11 +135,12 @@ pl310_cache_sync(void)
return;
#ifdef PL310_ERRATA_753970
/* Write uncached PL310 register */
pl310_write4(pl310_softc, 0x740, 0xffffffff);
#else
pl310_write4(pl310_softc, PL310_CACHE_SYNC, 0xffffffff);
if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
/* Write uncached PL310 register */
pl310_write4(pl310_softc, 0x740, 0xffffffff);
else
#endif
pl310_write4(pl310_softc, PL310_CACHE_SYNC, 0xffffffff);
}
@ -152,13 +153,17 @@ pl310_wbinv_all(void)
PL310_LOCK(pl310_softc);
#ifdef PL310_ERRATA_727915
platform_pl310_write_debug(pl310_softc, 3);
if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0 ||
pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
platform_pl310_write_debug(pl310_softc, 3);
#endif
pl310_write4(pl310_softc, PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
pl310_wait_background_op(PL310_CLEAN_INV_WAY, g_l2cache_way_mask);
pl310_cache_sync();
#ifdef PL310_ERRATA_727915
platform_pl310_write_debug(pl310_softc, 0);
if (pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r2p0 ||
pl310_softc->sc_rtl_revision == CACHE_ID_RELEASE_r3p0)
platform_pl310_write_debug(pl310_softc, 0);
#endif
PL310_UNLOCK(pl310_softc);
}
@ -186,18 +191,19 @@ pl310_wbinv_range(vm_paddr_t start, vm_size_t size)
#endif
while (size > 0) {
#ifdef PL310_ERRATA_588369
/*
* Errata 588369 says that clean + inv may keep the
* cache line if it was clean, the recommanded workaround
* is to clean then invalidate the cache line, with
* write-back and cache linefill disabled
*/
pl310_write4(pl310_softc, PL310_CLEAN_LINE_PA, start);
pl310_write4(pl310_softc, PL310_INV_LINE_PA, start);
#else
pl310_write4(pl310_softc, PL310_CLEAN_INV_LINE_PA, start);
if (pl310_softc->sc_rtl_revision <= CACHE_ID_RELEASE_r1p0) {
/*
* Errata 588369 says that clean + inv may keep the
* cache line if it was clean, the recommanded
* workaround is to clean then invalidate the cache
* line, with write-back and cache linefill disabled.
*/
pl310_write4(pl310_softc, PL310_CLEAN_LINE_PA, start);
pl310_write4(pl310_softc, PL310_INV_LINE_PA, start);
} else
#endif
pl310_write4(pl310_softc, PL310_CLEAN_INV_LINE_PA,
start);
start += g_l2cache_line_size;
size -= g_l2cache_line_size;
}
@ -307,6 +313,8 @@ pl310_attach(device_t dev)
pl310_filter, NULL, sc, &sc->sc_irq_h);
cache_id = pl310_read4(sc, PL310_CACHE_ID);
sc->sc_rtl_revision = (cache_id >> CACHE_ID_RELEASE_SHIFT) &
CACHE_ID_RELEASE_MASK;
device_printf(dev, "Part number: 0x%x, release: 0x%x\n",
(cache_id >> CACHE_ID_PARTNUM_SHIFT) & CACHE_ID_PARTNUM_MASK,
(cache_id >> CACHE_ID_RELEASE_SHIFT) & CACHE_ID_RELEASE_MASK);

View File

@ -193,6 +193,14 @@ int pmap_debug_level = 0;
#define PMAP_INLINE __inline
#endif /* PMAP_DEBUG */
#ifdef ARM_L2_PIPT
#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((pa), (size))
#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((pa), (size))
#else
#define pmap_l2cache_wbinv_range(va, pa, size) cpu_l2cache_wbinv_range((va), (size))
#define pmap_l2cache_inv_range(va, pa, size) cpu_l2cache_inv_range((va), (size))
#endif
extern struct pv_addr systempage;
/*
@ -786,11 +794,7 @@ pmap_l2ptp_ctor(void *mem, int size, void *arg, int flags)
pte = *ptep;
cpu_idcache_wbinv_range(va, PAGE_SIZE);
#ifdef ARM_L2_PIPT
cpu_l2cache_wbinv_range(pte & L2_S_FRAME, PAGE_SIZE);
#else
cpu_l2cache_wbinv_range(va, PAGE_SIZE);
#endif
pmap_l2cache_wbinv_range(va, pte & L2_S_FRAME, PAGE_SIZE);
if ((pte & L2_S_CACHE_MASK) != pte_l2_s_cache_mode_pt) {
/*
* Page tables must have the cache-mode set to
@ -2121,6 +2125,7 @@ pmap_kremove(vm_offset_t va)
cpu_tlb_flushD_SE(va);
cpu_cpwait();
*pte = 0;
PTE_SYNC(pte);
}
}
@ -2387,11 +2392,7 @@ pmap_change_attr(vm_offset_t sva, vm_size_t len, int mode)
pte = *ptep &~ L2_S_CACHE_MASK;
cpu_idcache_wbinv_range(tmpva, PAGE_SIZE);
#ifdef ARM_L2_PIPT
cpu_l2cache_wbinv_range(pte & L2_S_FRAME, PAGE_SIZE);
#else
cpu_l2cache_wbinv_range(tmpva, PAGE_SIZE);
#endif
pmap_l2cache_wbinv_range(tmpva, pte & L2_S_FRAME, PAGE_SIZE);
*ptep = pte;
cpu_tlb_flushID_SE(tmpva);
@ -2754,6 +2755,9 @@ do_l2b_alloc:
else if (PV_BEEN_REFD(oflags))
cpu_tlb_flushD_SE(va);
}
if ((pmap != pmap_kernel()) && (pmap == &curproc->p_vmspace->vm_pmap))
cpu_icache_sync_range(va, PAGE_SIZE);
}
/*
@ -3197,6 +3201,16 @@ pmap_zero_page_gen(vm_page_t pg, int off, int size)
else
bzero_page(cdstp);
/*
* Although aliasing is not possible if we use
* cdstp temporary mappings with memory that
* will be mapped later as non-cached or with write-through
* caches we might end up overwriting it when calling wbinv_all
* So make sure caches are clean after copy operation
*/
cpu_idcache_wbinv_range(cdstp, size);
pmap_l2cache_wbinv_range(cdstp, phys, size);
mtx_unlock(&cmtx);
}
@ -3276,12 +3290,23 @@ pmap_copy_page_generic(vm_paddr_t src, vm_paddr_t dst)
*cdst_pte = L2_S_PROTO | dst | pte_l2_s_cache_mode;
pmap_set_prot(cdst_pte, VM_PROT_READ | VM_PROT_WRITE, 0);
PTE_SYNC(cdst_pte);
cpu_tlb_flushD_SE(csrcp);
cpu_tlb_flushD_SE(cdstp);
cpu_cpwait();
/*
* Although aliasing is not possible if we use
* cdstp temporary mappings with memory that
* will be mapped later as non-cached or with write-through
* caches we might end up overwriting it when calling wbinv_all
* So make sure caches are clean after copy operation
*/
bcopy_page(csrcp, cdstp);
cpu_idcache_wbinv_range(cdstp, PAGE_SIZE);
pmap_l2cache_wbinv_range(cdstp, dst, PAGE_SIZE);
mtx_unlock(&cmtx);
}

View File

@ -891,7 +891,7 @@ bcmfb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+ (sc->depth/8) * (col + sc->xmargin);
fg = a & 0xf ;
bg = (a >> 8) & 0xf;
bg = (a >> 4) & 0xf;
for (i = 0; i < BCMFB_FONT_HEIGHT; i++) {
for (j = 0, k = 7; j < 8; j++, k--) {

View File

@ -78,6 +78,25 @@ initarm_gpio_init(void)
void
initarm_late_init(void)
{
phandle_t system;
pcell_t cells[2];
int len;
/*
* It seems there is no way to let syscons framework know
* that framebuffer resolution has changed. So just try
* to fetch data from FDT and go with defaults if failed
*/
system = OF_finddevice("/system");
if (system != 0) {
len = OF_getprop(system, "linux,serial", &cells, sizeof(cells));
if (len > 0)
board_set_serial(fdt64_to_cpu(*((uint64_t *)cells)));
len = OF_getprop(system, "linux,revision", &cells, sizeof(cells));
if (len > 0)
board_set_revision(fdt32_to_cpu(*((uint32_t *)cells)));
}
}
#define FDT_DEVMAP_MAX (2) // FIXME

View File

@ -62,11 +62,11 @@ options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed
# NFS support
#options NFSCL
#options NFSSERVER #Network Filesystem Server
#options NFSCLIENT #Network Filesystem Client
#options NFSD
#options NFSLOCKD
# Uncomment this for NFS root
#options NFS_ROOT #NFS usable as /, requires NFSCLIENT
#options NFS_ROOT #NFS usable as /, requires NFSCL
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
#options BOOTP

View File

@ -47,9 +47,25 @@
#include <machine/cpuconf.h>
#endif
#define mb()
#define wmb()
#define rmb()
#if defined (__ARM_ARCH_7__) || defined (__ARM_ARCH_7A__)
#define isb() __asm __volatile("isb" : : : "memory")
#define dsb() __asm __volatile("dsb" : : : "memory")
#define dmb() __asm __volatile("dmb" : : : "memory")
#elif defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__) || \
defined (__ARM_ARCH_6K__) || defined (__ARM_ARCH_6Z__) || \
defined (__ARM_ARCH_6ZK__)
#define isb() __asm __volatile("mcr p15, 0, %0, c7, c5, 4" : : "r" (0) : "memory")
#define dsb() __asm __volatile("mcr p15, 0, %0, c7, c10, 4" : : "r" (0) : "memory")
#define dmb() __asm __volatile("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory")
#else
#define isb()
#define dsb()
#define dmb()
#endif
#define mb() dmb()
#define wmb() dmb()
#define rmb() dmb()
#ifndef I32_bit
#define I32_bit (1 << 7) /* IRQ disable */

View File

@ -37,6 +37,10 @@ void initarm_gpio_init(void);
void initarm_late_init(void);
int platform_devmap_init(void);
/* Board-specific attributes */
void board_set_serial(uint64_t);
void board_set_revision(uint32_t);
/* Needs to be initialised by platform_devmap_init */
extern const struct pmap_devmap *pmap_devmap_bootstrap_table;

View File

@ -131,6 +131,7 @@ struct pl310_softc {
void* sc_irq_h;
int sc_enabled;
struct mtx sc_mtx;
u_int sc_rtl_revision;
};
/**

View File

@ -61,7 +61,7 @@
#else
#define PTE_NOCACHE 1
#endif
#define PTE_CACHE 4
#define PTE_CACHE 6
#define PTE_DEVICE 2
#define PTE_PAGETABLE 4
#else

View File

@ -98,7 +98,7 @@ static int cpsw_ioctl(struct ifnet *ifp, u_long command, caddr_t data);
static int cpsw_init_slot_lists(struct cpsw_softc *sc);
static void cpsw_free_slot(struct cpsw_softc *sc, struct cpsw_slot *slot);
static void cpsw_fill_rx_queue_locked(struct cpsw_softc *sc);
static void cpsw_watchdog(struct cpsw_softc *sc);
static void cpsw_tx_watchdog(struct cpsw_softc *sc);
static void cpsw_intr_rx_thresh(void *arg);
static void cpsw_intr_rx(void *arg);
@ -716,34 +716,24 @@ cpsw_start_locked(struct ifnet *ifp)
if (STAILQ_EMPTY(&newslots))
return;
/* Attach new segments to the hardware TX queue. */
/* Attach the list of new buffers to the hardware TX queue. */
prev_slot = STAILQ_LAST(&sc->tx_active, cpsw_slot, next);
first_new_slot = STAILQ_FIRST(&newslots);
STAILQ_CONCAT(&sc->tx_active, &newslots);
if (prev_slot == NULL) {
/* Start the TX queue fresh. */
cpsw_write_4(CPSW_CPDMA_TX_HDP(0),
cpsw_cpdma_txbd_paddr(first_new_slot->index));
cpsw_cpdma_txbd_paddr(first_new_slot->index));
} else {
/* Add packets to current queue. */
/* Race: The hardware might have sent the last packet
* on the queue and stopped the transmitter just
* before we got here. In that case, this is a no-op,
* but it also means there's a TX interrupt waiting
* to be processed as soon as we release the lock here.
* That TX interrupt can detect and recover from this
* situation; see cpsw_intr_tx_locked.
*/
/* Add buffers to end of current queue. */
cpsw_cpdma_write_txbd_next(prev_slot->index,
cpsw_cpdma_txbd_paddr(first_new_slot->index));
/* If underrun, restart queue. */
if (cpsw_cpdma_read_txbd_flags(prev_slot->index) & CPDMA_BD_EOQ)
cpsw_write_4(CPSW_CPDMA_TX_HDP(0),
cpsw_cpdma_txbd_paddr(first_new_slot->index));
}
/* If tx_retires hasn't changed, then we may have
lost a TX interrupt, so let the timer tick. */
sc->tx_enqueues += enqueued;
if (sc->tx_retires_at_wd_reset != sc->tx_retires) {
sc->tx_retires_at_wd_reset = sc->tx_retires;
sc->wd_timer = 5;
}
sc->tx_queued += enqueued;
if (sc->tx_queued > sc->tx_max_queued) {
sc->tx_max_queued = sc->tx_queued;
@ -771,7 +761,6 @@ cpsw_stop_locked(struct cpsw_softc *sc)
/* Stop tick engine */
callout_stop(&sc->wd_callout);
sc->wd_timer = 0;
/* Wait for hardware to clear pending ops. */
CPSW_GLOBAL_UNLOCK(sc);
@ -1098,14 +1087,10 @@ cpsw_fill_rx_queue_locked(struct cpsw_softc *sc)
cpsw_write_4(CPSW_CPDMA_RX_HDP(0),
cpsw_cpdma_rxbd_paddr(next_slot->index));
} else {
/* Extend an existing RX queue. */
/* Add buffers to end of current queue. */
cpsw_cpdma_write_rxbd_next(prev_slot->index,
cpsw_cpdma_rxbd_paddr(next_slot->index));
/* XXX Order matters: Previous write must complete
before next read begins in order to avoid an
end-of-queue race. I think bus_write and bus_read have
sufficient barriers built-in to ensure this. XXX */
/* If old RX queue was stopped, restart it. */
/* If underrun, restart queue. */
if (cpsw_cpdma_read_rxbd_flags(prev_slot->index) & CPDMA_BD_EOQ) {
cpsw_write_4(CPSW_CPDMA_RX_HDP(0),
cpsw_cpdma_rxbd_paddr(next_slot->index));
@ -1177,15 +1162,8 @@ cpsw_intr_tx_locked(void *arg)
/* Tell hardware the last item we dequeued. */
cpsw_write_4(CPSW_CPDMA_TX_CP(0),
cpsw_cpdma_txbd_paddr(last_slot->index));
/* If transmitter stopped and there's more, restart it. */
/* This resolves the race described in tx_start above. */
if ((last_flags & CPDMA_BD_EOQ) && (slot != NULL)) {
cpsw_write_4(CPSW_CPDMA_TX_HDP(0),
cpsw_cpdma_txbd_paddr(slot->index));
}
sc->tx_retires += retires;
sc->tx_queued -= retires;
sc->wd_timer = 0;
}
}
@ -1206,7 +1184,7 @@ cpsw_tick(void *msc)
struct cpsw_softc *sc = msc;
/* Check for TX timeout */
cpsw_watchdog(sc);
cpsw_tx_watchdog(sc);
mii_tick(sc->mii);
@ -1222,21 +1200,28 @@ cpsw_tick(void *msc)
}
static void
cpsw_watchdog(struct cpsw_softc *sc)
cpsw_tx_watchdog(struct cpsw_softc *sc)
{
struct ifnet *ifp;
struct ifnet *ifp = sc->ifp;
ifp = sc->ifp;
CPSW_GLOBAL_LOCK(sc);
if (sc->wd_timer == 0 || --sc->wd_timer) {
CPSW_GLOBAL_UNLOCK(sc);
return;
if (sc->tx_retires > sc->tx_retires_at_last_tick) {
sc->tx_wd_timer = 0; /* Stuff got sent. */
} else if (sc->tx_queued == 0) {
sc->tx_wd_timer = 0; /* Nothing to send. */
} else {
/* There was something to send but we didn't. */
++sc->tx_wd_timer;
if (sc->tx_wd_timer > 3) {
sc->tx_wd_timer = 0;
ifp->if_oerrors++;
if_printf(ifp, "watchdog timeout\n");
cpsw_stop_locked(sc);
cpsw_init_locked(sc);
CPSW_DEBUGF(("watchdog reset completed\n"));
}
}
ifp->if_oerrors++;
if_printf(ifp, "watchdog timeout\n");
cpsw_stop_locked(sc);
cpsw_init_locked(sc);
sc->tx_retires_at_last_tick = sc->tx_retires;
CPSW_GLOBAL_UNLOCK(sc);
}
@ -1381,7 +1366,7 @@ cpsw_init_locked(void *arg)
/* Activate network interface */
sc->rx_running = 1;
sc->tx_running = 1;
sc->wd_timer = 0;
sc->tx_wd_timer = 0;
callout_reset(&sc->wd_callout, hz, cpsw_tick, sc);
sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;

View File

@ -63,7 +63,7 @@ struct cpsw_softc {
int cpsw_media_status;
struct callout wd_callout;
int wd_timer;
int tx_wd_timer;
bus_dma_tag_t mbuf_dtag;
@ -82,7 +82,7 @@ struct cpsw_softc {
/* Statistics */
uint32_t tx_enqueues; /* total TX bufs added to queue */
uint32_t tx_retires; /* total TX bufs removed from queue */
uint32_t tx_retires_at_wd_reset; /* used for watchdog */
uint32_t tx_retires_at_last_tick; /* used for watchdog */
/* Note: tx_queued != tx_enqueues - tx_retires
At driver reset, packets can be discarded
from TX queue without being retired. */

View File

@ -129,27 +129,75 @@ omap4_get_revision(void)
switch (hawkeye) {
case 0xB852:
if (revision == 0)
switch (revision) {
case 0:
chip_revision = OMAP4430_REV_ES1_0;
else
chip_revision = OMAP4430_REV_ES2_0;
break;
case 0xB95C:
if (revision == 3)
break;
case 1:
chip_revision = OMAP4430_REV_ES2_1;
else if (revision == 4)
chip_revision = OMAP4430_REV_ES2_2;
else
chip_revision = OMAP4430_REV_ES2_3;
break;
default:
chip_revision = OMAP4430_REV_UNKNOWN;
break;
}
break;
case 0xB95C:
switch (revision) {
case 3:
chip_revision = OMAP4430_REV_ES2_1;
break;
case 4:
chip_revision = OMAP4430_REV_ES2_2;
break;
case 6:
chip_revision = OMAP4430_REV_ES2_3;
break;
default:
chip_revision = OMAP4430_REV_UNKNOWN;
break;
}
break;
case 0xB94E:
switch (revision) {
case 0:
chip_revision = OMAP4460_REV_ES1_0;
break;
case 2:
chip_revision = OMAP4460_REV_ES1_1;
break;
default:
chip_revision = OMAP4460_REV_UNKNOWN;
break;
}
break;
case 0xB975:
switch (revision) {
case 0:
chip_revision = OMAP4470_REV_ES1_0;
break;
default:
chip_revision = OMAP4470_REV_UNKNOWN;
break;
}
break;
default:
/* Default to the latest revision if we can't determine type */
chip_revision = OMAP4430_REV_ES2_3;
chip_revision = OMAP_UNKNOWN_DEV;
break;
}
printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision),
OMAP_REV_MINOR(chip_revision));
if (chip_revision != OMAP_UNKNOWN_DEV) {
printf("Texas Instruments OMAP%04x Processor, Revision ES%u.%u\n",
OMAP_REV_DEVICE(chip_revision), OMAP_REV_MAJOR(chip_revision),
OMAP_REV_MINOR(chip_revision));
}
else {
printf("Texas Instruments unknown OMAP chip: %04x, rev %d\n",
hawkeye, revision);
}
}
/**

View File

@ -30,34 +30,46 @@
#ifndef _TI_CPUID_H_
#define _TI_CPUID_H_
#define OMAP_MAKEREV(d, a, b, c) \
#define OMAP_MAKEREV(d, a, b, c) \
(uint32_t)(((d) << 16) | (((a) & 0xf) << 8) | (((b) & 0xf) << 4) | ((c) & 0xf))
#define OMAP_REV_DEVICE(x) (((x) >> 16) & 0xffff)
#define OMAP_REV_MAJOR(x) (((x) >> 8) & 0xf)
#define OMAP_REV_MINOR(x) (((x) >> 4) & 0xf)
#define OMAP_REV_MINOR_MINOR(x) (((x) >> 0) & 0xf)
#define OMAP_REV_DEVICE(x) (((x) >> 16) & 0xffff)
#define OMAP_REV_MAJOR(x) (((x) >> 8) & 0xf)
#define OMAP_REV_MINOR(x) (((x) >> 4) & 0xf)
#define OMAP_REV_MINOR_MINOR(x) (((x) >> 0) & 0xf)
#define OMAP3350_DEV 0x3530
#define OMAP3350_REV_ES1_0 OMAP_MAKEREV(OMAP3350_DEV, 1, 0, 0)
#define OMAP3530_REV_ES2_0 OMAP_MAKEREV(OMAP3350_DEV, 2, 0, 0)
#define OMAP3530_REV_ES2_1 OMAP_MAKEREV(OMAP3350_DEV, 2, 1, 0)
#define OMAP3530_REV_ES3_0 OMAP_MAKEREV(OMAP3350_DEV, 3, 0, 0)
#define OMAP3530_REV_ES3_1 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 0)
#define OMAP3530_REV_ES3_1_2 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 2)
#define OMAP3350_REV_ES1_0 OMAP_MAKEREV(OMAP3350_DEV, 1, 0, 0)
#define OMAP3530_REV_ES2_0 OMAP_MAKEREV(OMAP3350_DEV, 2, 0, 0)
#define OMAP3530_REV_ES2_1 OMAP_MAKEREV(OMAP3350_DEV, 2, 1, 0)
#define OMAP3530_REV_ES3_0 OMAP_MAKEREV(OMAP3350_DEV, 3, 0, 0)
#define OMAP3530_REV_ES3_1 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 0)
#define OMAP3530_REV_ES3_1_2 OMAP_MAKEREV(OMAP3350_DEV, 3, 1, 2)
#define OMAP4430_DEV 0x4430
#define OMAP4430_REV_ES1_0 OMAP_MAKEREV(OMAP4430_DEV, 1, 0, 0)
#define OMAP4430_REV_ES2_0 OMAP_MAKEREV(OMAP4430_DEV, 2, 0, 0)
#define OMAP4430_REV_ES2_1 OMAP_MAKEREV(OMAP4430_DEV, 2, 1, 0)
#define OMAP4430_REV_ES2_2 OMAP_MAKEREV(OMAP4430_DEV, 2, 2, 0)
#define OMAP4430_REV_ES2_3 OMAP_MAKEREV(OMAP4430_DEV, 2, 3, 0)
#define OMAP4430_REV_ES1_0 OMAP_MAKEREV(OMAP4430_DEV, 1, 0, 0)
#define OMAP4430_REV_ES2_0 OMAP_MAKEREV(OMAP4430_DEV, 2, 0, 0)
#define OMAP4430_REV_ES2_1 OMAP_MAKEREV(OMAP4430_DEV, 2, 1, 0)
#define OMAP4430_REV_ES2_2 OMAP_MAKEREV(OMAP4430_DEV, 2, 2, 0)
#define OMAP4430_REV_ES2_3 OMAP_MAKEREV(OMAP4430_DEV, 2, 3, 0)
#define OMAP4430_REV_UNKNOWN OMAP_MAKEREV(OMAP4430_DEV, 9, 9, 9)
#define AM335X_DEVREV(x) ((x) >> 28)
#define OMAP4460_DEV 0x4460
#define OMAP4460_REV_ES1_0 OMAP_MAKEREV(OMAP4460_DEV, 1, 0, 0)
#define OMAP4460_REV_ES1_1 OMAP_MAKEREV(OMAP4460_DEV, 1, 1, 0)
#define OMAP4460_REV_UNKNOWN OMAP_MAKEREV(OMAP4460_DEV, 9, 9, 9)
#define CHIP_OMAP_3 0
#define CHIP_OMAP_4 1
#define CHIP_AM335X 2
#define OMAP4470_DEV 0x4470
#define OMAP4470_REV_ES1_0 OMAP_MAKEREV(OMAP4470_DEV, 1, 0, 0)
#define OMAP4470_REV_UNKNOWN OMAP_MAKEREV(OMAP4470_DEV, 9, 9, 9)
#define OMAP_UNKNOWN_DEV OMAP_MAKEREV(0x9999, 9, 9, 9)
#define AM335X_DEVREV(x) ((x) >> 28)
#define CHIP_OMAP_3 0
#define CHIP_OMAP_4 1
#define CHIP_AM335X 2
static __inline int ti_chip(void)
{

View File

@ -892,7 +892,7 @@ versatilefb_putc(video_adapter_t *adp, vm_offset_t off, uint8_t c, uint8_t a)
+ (sc->depth/8) * (col + sc->xmargin);
fg = a & 0xf ;
bg = (a >> 8) & 0xf;
bg = (a >> 4) & 0xf;
for (i = 0; i < VERSATILE_FONT_HEIGHT; i++) {
for (j = 0, k = 7; j < 8; j++, k--) {

View File

@ -53,8 +53,8 @@ extern char bootprog_rev[];
/*
* FreeBSD loader default dictionary cells
*/
#ifndef BF_DICTSIZE
#define BF_DICTSIZE 10000
#ifndef BF_DICTSIZE
#define BF_DICTSIZE 10000
#endif
/*
@ -247,6 +247,7 @@ bf_init(void)
char create_buf[41]; /* 31 characters-long builtins */
int fd;
bf_sys = ficlInitSystem(BF_DICTSIZE);
bf_vm = ficlNewVM(bf_sys);

View File

@ -73,6 +73,7 @@ MAXMEM opt_global.h
#
OCTEON_MODEL opt_cvmx.h
OCTEON_VENDOR_LANNER opt_cvmx.h
OCTEON_VENDOR_UBIQUITI opt_cvmx.h
OCTEON_VENDOR_RADISYS opt_cvmx.h
OCTEON_BOARD_CAPK_0100ND opt_cvmx.h

View File

@ -299,6 +299,9 @@ enum cvmx_board_types_enum {
CVMX_BOARD_TYPE_CUST_LANNER_MR320= 20002,
CVMX_BOARD_TYPE_CUST_LANNER_MR321X=20007,
#endif
#if defined(OCTEON_VENDOR_UBIQUITI)
CVMX_BOARD_TYPE_CUST_UBIQUITI_E100=20002,
#endif
#if defined(OCTEON_VENDOR_RADISYS)
CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE=20002,
#endif
@ -426,6 +429,9 @@ static inline const char *cvmx_board_type_to_string(enum cvmx_board_types_enum t
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_LANNER_MR320)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_LANNER_MR321X)
#endif
#if defined(OCTEON_VENDOR_UBIQUITI)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_UBIQUITI_E100)
#endif
#if defined(OCTEON_VENDOR_RADISYS)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE)
#endif

View File

@ -592,6 +592,12 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
return -1;
}
#endif
#if defined(OCTEON_VENDOR_UBIQUITI)
case CVMX_BOARD_TYPE_CUST_UBIQUITI_E100:
if (ipd_port > 2)
return -1;
return (7 - ipd_port);
#endif
#if defined(OCTEON_VENDOR_RADISYS)
case CVMX_BOARD_TYPE_CUST_RADISYS_RSYS4GBE:
/* No MII. */
@ -1463,6 +1469,9 @@ cvmx_helper_board_usb_clock_types_t __cvmx_helper_board_usb_get_clock_type(void)
case CVMX_BOARD_TYPE_CUST_LANNER_MR320:
case CVMX_BOARD_TYPE_CUST_LANNER_MR321X:
#endif
#if defined(OCTEON_VENDOR_UBIQUITI)
case CVMX_BOARD_TYPE_CUST_UBIQUITI_E100:
#endif
#if defined(OCTEON_BOARD_CAPK_0100ND)
case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
#endif

View File

@ -423,7 +423,21 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
sc->sc_rx_th.wr_flags = sc->sc_hwmap[rix].rxflags;
#ifdef AH_SUPPORT_AR5416
sc->sc_rx_th.wr_chan_flags &= ~CHAN_HT;
if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */
if (rs->rs_status & HAL_RXERR_PHY) {
struct ieee80211com *ic = ifp->if_l2com;
/*
* PHY error - make sure the channel flags
* reflect the actual channel configuration,
* not the received frame.
*/
if (IEEE80211_IS_CHAN_HT40U(ic->ic_curchan))
sc->sc_rx_th.wr_chan_flags |= CHAN_HT40U;
else if (IEEE80211_IS_CHAN_HT40D(ic->ic_curchan))
sc->sc_rx_th.wr_chan_flags |= CHAN_HT40D;
else if (IEEE80211_IS_CHAN_HT20(ic->ic_curchan))
sc->sc_rx_th.wr_chan_flags |= CHAN_HT20;
} else if (sc->sc_rx_th.wr_rate & IEEE80211_RATE_MCS) { /* HT rate */
struct ieee80211com *ic = ifp->if_l2com;
if ((rs->rs_flags & HAL_RX_2040) == 0)
@ -435,6 +449,7 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m,
if ((rs->rs_flags & HAL_RX_GI) == 0)
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
}
#endif
sc->sc_rx_th.wr_tsf = htole64(ath_extend_tsf(sc, rs->rs_tstamp, tsf));
if (rs->rs_status & HAL_RXERR_CRC)

View File

@ -82,13 +82,20 @@ struct ath_spectral_state {
*/
/*
* Attach DFS to the given interface
* Attach spectral to the given interface
*/
int
ath_spectral_attach(struct ath_softc *sc)
{
struct ath_spectral_state *ss;
/*
* If spectral isn't supported, don't error - just
* quietly complete.
*/
if (! ath_hal_spectral_supported(sc->sc_ah))
return (0);
ss = malloc(sizeof(struct ath_spectral_state),
M_TEMP, M_WAITOK | M_ZERO);
@ -106,11 +113,15 @@ ath_spectral_attach(struct ath_softc *sc)
}
/*
* Detach DFS from the given interface
* Detach spectral from the given interface
*/
int
ath_spectral_detach(struct ath_softc *sc)
{
if (! ath_hal_spectral_supported(sc->sc_ah))
return (0);
if (sc->sc_spectral != NULL) {
free(sc->sc_spectral, M_TEMP);
}
@ -148,6 +159,9 @@ ath_ioctl_spectral(struct ath_softc *sc, struct ath_diag *ad)
HAL_SPECTRAL_PARAM *pe;
struct ath_spectral_state *ss = sc->sc_spectral;
if (! ath_hal_spectral_supported(sc->sc_ah))
return (EINVAL);
if (ad->ad_id & ATH_DIAG_IN) {
/*
* Copy in data.

View File

@ -1303,6 +1303,8 @@ void ath_intr(void *);
#define ath_hal_get_chan_ext_busy(_ah) \
((*(_ah)->ah_get11nExtBusy)((_ah)))
#define ath_hal_spectral_supported(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_SPECTRAL_SCAN, 0, NULL) == HAL_OK)
#define ath_hal_spectral_get_config(_ah, _p) \
((*(_ah)->ah_spectralGetConfig)((_ah), (_p)))
#define ath_hal_spectral_configure(_ah, _p) \

View File

@ -287,10 +287,10 @@ nvme_ns_test(struct nvme_namespace *ns, u_long cmd, caddr_t arg)
for (i = 0; i < io_test->num_threads; i++)
#if __FreeBSD_version >= 800004
kthread_add(fn, io_test_internal,
curproc, NULL, 0, 0, "nvme_io_test[%d]", i);
NULL, NULL, 0, 0, "nvme_io_test[%d]", i);
#else
kthread_create(fn, io_test_internal,
curproc, 0, 0, "nvme_io_test[%d]", i);
NULL, 0, 0, "nvme_io_test[%d]", i);
#endif
tsleep(io_test_internal, 0, "nvme_test", io_test->time * 2 * hz);

View File

@ -244,7 +244,7 @@ static const struct pci_quirk pci_quirks[] = {
* but support MSI just fine. QEMU uses the Intel 82440.
*/
{ 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 },
{ 0x12751275, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 }, /* BHyVe */
{ 0x12751275, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 }, /* bhyve */
/*
* HPET MMIO base address may appear in Bar1 for AMD SB600 SMBus

View File

@ -1440,26 +1440,37 @@ void
xhci_interrupt(struct xhci_softc *sc)
{
uint32_t status;
uint32_t temp;
uint32_t iman;
USB_BUS_LOCK(&sc->sc_bus);
status = XREAD4(sc, oper, XHCI_USBSTS);
if (status == 0)
goto done;
/* acknowledge interrupts */
XWRITE4(sc, oper, XHCI_USBSTS, status);
temp = XREAD4(sc, runt, XHCI_IMAN(0));
DPRINTFN(16, "real interrupt (status=0x%08x)\n", status);
if (status & XHCI_STS_EINT) {
/* acknowledge pending event */
/* acknowledge pending event */
iman = XREAD4(sc, runt, XHCI_IMAN(0));
XWRITE4(sc, runt, XHCI_IMAN(0), temp);
/* reset interrupt */
XWRITE4(sc, runt, XHCI_IMAN(0), iman);
DPRINTFN(16, "real interrupt (iman=0x%08x)\n", iman);
/* check for event(s) */
xhci_interrupt_poll(sc);
}
DPRINTFN(16, "real interrupt (sts=0x%08x, "
"iman=0x%08x)\n", status, temp);
if (status & (XHCI_STS_PCD | XHCI_STS_HCH |
XHCI_STS_HSE | XHCI_STS_HCE)) {
if (status != 0) {
if (status & XHCI_STS_PCD) {
xhci_root_intr(sc);
}
@ -1479,9 +1490,7 @@ xhci_interrupt(struct xhci_softc *sc)
__FUNCTION__);
}
}
xhci_interrupt_poll(sc);
done:
USB_BUS_UNLOCK(&sc->sc_bus);
}

View File

@ -2019,7 +2019,8 @@ run_key_set_cb(void *arg)
wcid = 0; /* NB: update WCID0 for group keys */
base = RT2860_SKEY(RUN_VAP(vap)->rvp_id, k->wk_keyix);
} else {
wcid = RUN_AID2WCID(associd);
wcid = (vap->iv_opmode == IEEE80211_M_STA) ?
1 : RUN_AID2WCID(associd);
base = RT2860_PKEY(wcid);
}
@ -2374,9 +2375,12 @@ run_newassoc(struct ieee80211_node *ni, int isnew)
struct run_softc *sc = ic->ic_ifp->if_softc;
uint8_t rate;
uint8_t ridx;
uint8_t wcid = RUN_AID2WCID(ni->ni_associd);
uint8_t wcid;
int i, j;
wcid = (vap->iv_opmode == IEEE80211_M_STA) ?
1 : RUN_AID2WCID(ni->ni_associd);
if (wcid > RT2870_WCID_MAX) {
device_printf(sc->sc_dev, "wcid=%d out of range\n", wcid);
return;
@ -3044,8 +3048,12 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni)
txd->flags = qflags;
txwi = (struct rt2860_txwi *)(txd + 1);
txwi->xflags = xflags;
txwi->wcid = IEEE80211_IS_MULTICAST(wh->i_addr1) ?
0 : RUN_AID2WCID(ni->ni_associd);
if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
txwi->wcid = 0;
} else {
txwi->wcid = (vap->iv_opmode == IEEE80211_M_STA) ?
1 : RUN_AID2WCID(ni->ni_associd);
}
/* clear leftover garbage bits */
txwi->flags = 0;
txwi->txop = 0;

View File

@ -125,7 +125,6 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#endif
#include <geom/geom.h>
#include <machine/_inttypes.h>
@ -145,8 +144,6 @@ __FBSDID("$FreeBSD$");
#include <xen/xenbus/xenbusvar.h>
#define NUM_ELEMENTS(x) (sizeof(x) / sizeof(*(x)))
/*--------------------------- Forward Declarations --------------------------*/
/** Function signature for shutdown event handlers. */
typedef void (xctrl_shutdown_handler_t)(void);
@ -165,7 +162,7 @@ struct xctrl_shutdown_reason {
};
/** Lookup table for shutdown event name to handler. */
static struct xctrl_shutdown_reason xctrl_shutdown_reasons[] = {
static const struct xctrl_shutdown_reason xctrl_shutdown_reasons[] = {
{ "poweroff", xctrl_poweroff },
{ "reboot", xctrl_reboot },
{ "suspend", xctrl_suspend },
@ -198,7 +195,6 @@ extern void xencons_resume(void);
static void
xctrl_suspend()
{
u_int cpuid;
int i, j, k, fpp;
unsigned long max_pfn, start_info_mfn;
@ -207,6 +203,8 @@ xctrl_suspend()
#ifdef SMP
struct thread *td;
cpuset_t map;
u_int cpuid;
/*
* Bind us to CPU 0 and stop any other VCPUs.
*/
@ -231,7 +229,7 @@ xctrl_suspend()
mtx_lock(&Giant);
if (DEVICE_SUSPEND(root_bus) != 0) {
mtx_unlock(&Giant);
printf("xen_suspend: device_suspend failed\n");
printf("%s: device_suspend failed\n", __func__);
#ifdef SMP
if (!CPU_EMPTY(&map))
restart_cpus(map);
@ -343,9 +341,9 @@ xctrl_suspend()
* drivers need this.
*/
mtx_lock(&Giant);
if (DEVICE_SUSPEND(root_bus)) {
if (DEVICE_SUSPEND(root_bus) != 0) {
mtx_unlock(&Giant);
printf("xen_suspend: device_suspend failed\n");
printf("%s: device_suspend failed\n", __func__);
return;
}
mtx_unlock(&Giant);
@ -396,8 +394,8 @@ xctrl_halt()
static void
xctrl_on_watch_event(struct xs_watch *watch, const char **vec, unsigned int len)
{
struct xctrl_shutdown_reason *reason;
struct xctrl_shutdown_reason *last_reason;
const struct xctrl_shutdown_reason *reason;
const struct xctrl_shutdown_reason *last_reason;
char *result;
int error;
int result_len;
@ -408,7 +406,7 @@ xctrl_on_watch_event(struct xs_watch *watch, const char **vec, unsigned int len)
return;
reason = xctrl_shutdown_reasons;
last_reason = reason + NUM_ELEMENTS(xctrl_shutdown_reasons);
last_reason = reason + nitems(xctrl_shutdown_reasons);
while (reason < last_reason) {
if (!strcmp(result, reason->name)) {
@ -511,10 +509,10 @@ static device_method_t xctrl_methods[] = {
DEVMETHOD(device_attach, xctrl_attach),
DEVMETHOD(device_detach, xctrl_detach),
{ 0, 0 }
DEVMETHOD_END
};
DEFINE_CLASS_0(xctrl, xctrl_driver, xctrl_methods, sizeof(struct xctrl_softc));
devclass_t xctrl_devclass;
DRIVER_MODULE(xctrl, xenstore, xctrl_driver, xctrl_devclass, 0, 0);
DRIVER_MODULE(xctrl, xenstore, xctrl_driver, xctrl_devclass, NULL, NULL);

View File

@ -1,394 +0,0 @@
/******************************************************************************
* evtchn.c
*
* Xenolinux driver for receiving and demuxing event-channel signals.
*
* Copyright (c) 2004, K A Fraser
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/uio.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/selinfo.h>
#include <sys/poll.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/ioccom.h>
#include <machine/cpufunc.h>
#include <machine/intr_machdep.h>
#include <machine/xen-os.h>
#include <xen/xen_intr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <machine/synch_bitops.h>
#include <xen/hypervisor.h>
typedef struct evtchn_sotfc {
struct selinfo ev_rsel;
} evtchn_softc_t;
#ifdef linuxcrap
/* NB. This must be shared amongst drivers if more things go in /dev/xen */
static devfs_handle_t xen_dev_dir;
#endif
/* Only one process may open /dev/xen/evtchn at any time. */
static unsigned long evtchn_dev_inuse;
/* Notification ring, accessed via /dev/xen/evtchn. */
#define EVTCHN_RING_SIZE 2048 /* 2048 16-bit entries */
#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
static uint16_t *ring;
static unsigned int ring_cons, ring_prod, ring_overflow;
/* Which ports is user-space bound to? */
static uint32_t bound_ports[32];
/* Unique address for processes to sleep on */
static void *evtchn_waddr = &ring;
static struct mtx lock, upcall_lock;
static d_read_t evtchn_read;
static d_write_t evtchn_write;
static d_ioctl_t evtchn_ioctl;
static d_poll_t evtchn_poll;
static d_open_t evtchn_open;
static d_close_t evtchn_close;
void
evtchn_device_upcall(int port)
{
mtx_lock(&upcall_lock);
mask_evtchn(port);
clear_evtchn(port);
if ( ring != NULL ) {
if ( (ring_prod - ring_cons) < EVTCHN_RING_SIZE ) {
ring[EVTCHN_RING_MASK(ring_prod)] = (uint16_t)port;
if ( ring_cons == ring_prod++ ) {
wakeup(evtchn_waddr);
}
}
else {
ring_overflow = 1;
}
}
mtx_unlock(&upcall_lock);
}
static void
__evtchn_reset_buffer_ring(void)
{
/* Initialise the ring to empty. Clear errors. */
ring_cons = ring_prod = ring_overflow = 0;
}
static int
evtchn_read(struct cdev *dev, struct uio *uio, int ioflag)
{
int rc;
unsigned int count, c, p, sst = 0, bytes1 = 0, bytes2 = 0;
count = uio->uio_resid;
count &= ~1; /* even number of bytes */
if ( count == 0 )
{
rc = 0;
goto out;
}
if ( count > PAGE_SIZE )
count = PAGE_SIZE;
for ( ; ; ) {
if ( (c = ring_cons) != (p = ring_prod) )
break;
if ( ring_overflow ) {
rc = EFBIG;
goto out;
}
if (sst != 0) {
rc = EINTR;
goto out;
}
/* PCATCH == check for signals before and after sleeping
* PWAIT == priority of waiting on resource
*/
sst = tsleep(evtchn_waddr, PWAIT|PCATCH, "evchwt", 10);
}
/* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
if ( ((c ^ p) & EVTCHN_RING_SIZE) != 0 ) {
bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) * sizeof(uint16_t);
bytes2 = EVTCHN_RING_MASK(p) * sizeof(uint16_t);
}
else {
bytes1 = (p - c) * sizeof(uint16_t);
bytes2 = 0;
}
/* Truncate chunks according to caller's maximum byte count. */
if ( bytes1 > count ) {
bytes1 = count;
bytes2 = 0;
}
else if ( (bytes1 + bytes2) > count ) {
bytes2 = count - bytes1;
}
if ( uiomove(&ring[EVTCHN_RING_MASK(c)], bytes1, uio) ||
((bytes2 != 0) && uiomove(&ring[0], bytes2, uio)))
/* keeping this around as its replacement is not equivalent
* copyout(&ring[0], &buf[bytes1], bytes2)
*/
{
rc = EFAULT;
goto out;
}
ring_cons += (bytes1 + bytes2) / sizeof(uint16_t);
rc = bytes1 + bytes2;
out:
return rc;
}
static int
evtchn_write(struct cdev *dev, struct uio *uio, int ioflag)
{
int rc, i, count;
count = uio->uio_resid;
uint16_t *kbuf = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK);
if ( kbuf == NULL )
return ENOMEM;
count &= ~1; /* even number of bytes */
if ( count == 0 ) {
rc = 0;
goto out;
}
if ( count > PAGE_SIZE )
count = PAGE_SIZE;
if ( uiomove(kbuf, count, uio) != 0 ) {
rc = EFAULT;
goto out;
}
mtx_lock_spin(&lock);
for ( i = 0; i < (count/2); i++ )
if ( test_bit(kbuf[i], &bound_ports[0]) )
unmask_evtchn(kbuf[i]);
mtx_unlock_spin(&lock);
rc = count;
out:
free(kbuf, M_DEVBUF);
return rc;
}
static int
evtchn_ioctl(struct cdev *dev, unsigned long cmd, caddr_t arg,
int mode, struct thread *td __unused)
{
int rc = 0;
mtx_lock_spin(&lock);
switch ( cmd )
{
case EVTCHN_RESET:
__evtchn_reset_buffer_ring();
break;
case EVTCHN_BIND:
if ( !synch_test_and_set_bit((int)arg, &bound_ports[0]) )
unmask_evtchn((int)arg);
else
rc = EINVAL;
break;
case EVTCHN_UNBIND:
if ( synch_test_and_clear_bit((int)arg, &bound_ports[0]) )
mask_evtchn((int)arg);
else
rc = EINVAL;
break;
default:
rc = ENOSYS;
break;
}
mtx_unlock_spin(&lock);
return rc;
}
static int
evtchn_poll(struct cdev *dev, int poll_events, struct thread *td)
{
evtchn_softc_t *sc;
unsigned int mask = POLLOUT | POLLWRNORM;
sc = dev->si_drv1;
if ( ring_cons != ring_prod )
mask |= POLLIN | POLLRDNORM;
else if ( ring_overflow )
mask = POLLERR;
else
selrecord(td, &sc->ev_rsel);
return mask;
}
static int
evtchn_open(struct cdev *dev, int flag, int otyp, struct thread *td)
{
uint16_t *_ring;
if (flag & O_NONBLOCK)
return EBUSY;
if ( synch_test_and_set_bit(0, &evtchn_dev_inuse) )
return EBUSY;
if ( (_ring = (uint16_t *)malloc(PAGE_SIZE, M_DEVBUF, M_WAITOK)) == NULL )
return ENOMEM;
mtx_lock_spin(&lock);
ring = _ring;
__evtchn_reset_buffer_ring();
mtx_unlock_spin(&lock);
return 0;
}
static int
evtchn_close(struct cdev *dev, int flag, int otyp, struct thread *td __unused)
{
int i;
mtx_lock_spin(&lock);
if (ring != NULL) {
free(ring, M_DEVBUF);
ring = NULL;
}
for ( i = 0; i < NR_EVENT_CHANNELS; i++ )
if ( synch_test_and_clear_bit(i, &bound_ports[0]) )
mask_evtchn(i);
mtx_unlock_spin(&lock);
evtchn_dev_inuse = 0;
return 0;
}
static struct cdevsw evtchn_devsw = {
d_version: D_VERSION,
d_open: evtchn_open,
d_close: evtchn_close,
d_read: evtchn_read,
d_write: evtchn_write,
d_ioctl: evtchn_ioctl,
d_poll: evtchn_poll,
d_name: "evtchn",
d_flags: 0,
};
/* XXX - if this device is ever supposed to support use by more than one process
* this global static will have to go away
*/
static struct cdev *evtchn_dev;
static int
evtchn_init(void *dummy __unused)
{
/* XXX I believe we don't need these leaving them here for now until we
* have some semblance of it working
*/
mtx_init(&upcall_lock, "evtchup", NULL, MTX_DEF);
/* (DEVFS) create '/dev/misc/evtchn'. */
evtchn_dev = make_dev(&evtchn_devsw, 0, UID_ROOT, GID_WHEEL, 0600, "xen/evtchn");
mtx_init(&lock, "evch", NULL, MTX_SPIN | MTX_NOWITNESS);
evtchn_dev->si_drv1 = malloc(sizeof(evtchn_softc_t), M_DEVBUF, M_WAITOK);
bzero(evtchn_dev->si_drv1, sizeof(evtchn_softc_t));
/* XXX I don't think we need any of this rubbish */
#if 0
if ( err != 0 )
{
printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
return err;
}
/* (DEVFS) create directory '/dev/xen'. */
xen_dev_dir = devfs_mk_dir(NULL, "xen", NULL);
/* (DEVFS) &link_dest[pos] == '../misc/evtchn'. */
pos = devfs_generate_path(evtchn_miscdev.devfs_handle,
&link_dest[3],
sizeof(link_dest) - 3);
if ( pos >= 0 )
strncpy(&link_dest[pos], "../", 3);
/* (DEVFS) symlink '/dev/xen/evtchn' -> '../misc/evtchn'. */
(void)devfs_mk_symlink(xen_dev_dir,
"evtchn",
DEVFS_FL_DEFAULT,
&link_dest[pos],
&symlink_handle,
NULL);
/* (DEVFS) automatically destroy the symlink with its destination. */
devfs_auto_unregister(evtchn_miscdev.devfs_handle, symlink_handle);
#endif
printk("Event-channel device installed.\n");
return 0;
}
SYSINIT(evtchn_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, evtchn_init, NULL);

View File

@ -24,7 +24,6 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -208,8 +207,6 @@ struct xn_chain_data {
struct mbuf *xn_rx_chain[NET_RX_RING_SIZE+1];
};
#define NUM_ELEMENTS(x) (sizeof(x)/sizeof(*x))
struct net_device_stats
{
u_long rx_packets; /* total packets received */
@ -244,7 +241,6 @@ struct net_device_stats
};
struct netfront_info {
struct ifnet *xn_ifp;
#if __FreeBSD_version >= 700000
struct lro_ctrl xn_lro;
@ -329,12 +325,6 @@ struct netfront_rx_info {
/* Access macros for acquiring freeing slots in xn_free_{tx,rx}_idxs[]. */
/*
* Access macros for acquiring freeing slots in tx_skbs[].
*/
static inline void
add_id_to_freelist(struct mbuf **list, uintptr_t id)
{
@ -517,7 +507,6 @@ netfront_resume(device_t dev)
return (0);
}
/* Common code used when first setting up, and when resuming. */
static int
talk_to_backend(device_t dev, struct netfront_info *info)
@ -605,7 +594,6 @@ talk_to_backend(device_t dev, struct netfront_info *info)
return err;
}
static int
setup_device(device_t dev, struct netfront_info *info)
{
@ -794,7 +782,7 @@ netif_release_tx_bufs(struct netfront_info *np)
add_id_to_freelist(np->tx_mbufs, i);
np->xn_cdata.xn_tx_chain_cnt--;
if (np->xn_cdata.xn_tx_chain_cnt < 0) {
panic("netif_release_tx_bufs: tx_chain_cnt must be >= 0");
panic("%s: tx_chain_cnt must be >= 0", __func__);
}
m_free(m);
}
@ -946,7 +934,6 @@ refill:
reservation.domid = DOMID_SELF;
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* After all PTEs have been zapped, flush the TLB. */
sc->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
UVMF_TLB_FLUSH|UVMF_ALL;
@ -958,15 +945,11 @@ refill:
/* Zap PTEs and give away pages in one big multicall. */
(void)HYPERVISOR_multicall(sc->rx_mcl, i+1);
/* Check return status of HYPERVISOR_dom_mem_op(). */
if (unlikely(sc->rx_mcl[i].result != i))
panic("Unable to reduce memory reservation\n");
} else {
if (HYPERVISOR_memory_op(
XENMEM_decrease_reservation, &reservation)
!= i)
panic("Unable to reduce memory "
"reservation\n");
if (unlikely(sc->rx_mcl[i].result != i ||
HYPERVISOR_memory_op(XENMEM_decrease_reservation,
&reservation) != i))
panic("%s: unable to reduce memory "
"reservation\n", __func__);
}
} else {
wmb();
@ -1169,8 +1152,8 @@ xn_txeof(struct netfront_info *np)
ifp->if_opackets++;
if (unlikely(gnttab_query_foreign_access(
np->grant_tx_ref[id]) != 0)) {
panic("grant id %u still in use by the backend",
id);
panic("%s: grant id %u still in use by the "
"backend", __func__, id);
}
gnttab_end_foreign_access_ref(
np->grant_tx_ref[id]);
@ -1210,7 +1193,6 @@ xn_txeof(struct netfront_info *np)
netif_wake_queue(dev);
#endif
}
}
static void
@ -1240,7 +1222,6 @@ xn_intr(void *xsc)
xn_start(ifp);
}
static void
xennet_move_rx_slot(struct netfront_info *np, struct mbuf *m,
grant_ref_t ref)
@ -1319,17 +1300,15 @@ xennet_get_responses(struct netfront_info *np,
m0 = m = m_prev = xennet_get_rx_mbuf(np, *cons);
if (rx->flags & NETRXF_extra_info) {
err = xennet_get_extras(np, extras, rp, cons);
}
if (m0 != NULL) {
m0->m_pkthdr.len = 0;
m0->m_next = NULL;
}
for (;;) {
u_long mfn;
@ -1468,10 +1447,8 @@ xn_tick_locked(struct netfront_info *sc)
callout_reset(&sc->xn_stat_ch, hz, xn_tick, sc);
/* XXX placeholder for printing debug information */
}
static void
xn_tick(void *xsc)
{
@ -1481,7 +1458,6 @@ xn_tick(void *xsc)
XN_RX_LOCK(sc);
xn_tick_locked(sc);
XN_RX_UNLOCK(sc);
}
/**
@ -1595,10 +1571,12 @@ xn_assemble_tx_request(struct netfront_info *sc, struct mbuf *m_head)
tx = RING_GET_REQUEST(&sc->tx, sc->tx.req_prod_pvt);
id = get_id_from_freelist(sc->tx_mbufs);
if (id == 0)
panic("xn_start_locked: was allocated the freelist head!\n");
panic("%s: was allocated the freelist head!\n",
__func__);
sc->xn_cdata.xn_tx_chain_cnt++;
if (sc->xn_cdata.xn_tx_chain_cnt > NET_TX_RING_SIZE)
panic("xn_start_locked: tx_chain_cnt must be <= NET_TX_RING_SIZE\n");
panic("%s: tx_chain_cnt must be <= NET_TX_RING_SIZE\n",
__func__);
sc->tx_mbufs[id] = m;
tx->id = id;
ref = gnttab_claim_grant_reference(&sc->gref_tx_head);
@ -1710,7 +1688,6 @@ xn_start_locked(struct ifnet *ifp)
}
}
static void
xn_start(struct ifnet *ifp)
{
@ -1744,10 +1721,8 @@ xn_ifinit_locked(struct netfront_info *sc)
if_link_state_change(ifp, LINK_STATE_UP);
callout_reset(&sc->xn_stat_ch, hz, xn_tick, sc);
}
static void
xn_ifinit(void *xsc)
{
@ -1756,10 +1731,8 @@ xn_ifinit(void *xsc)
XN_LOCK(sc);
xn_ifinit_locked(sc);
XN_UNLOCK(sc);
}
static int
xn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
@ -2261,7 +2234,7 @@ static device_method_t netfront_methods[] = {
/* Xenbus interface */
DEVMETHOD(xenbus_otherend_changed, netfront_backend_changed),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t netfront_driver = {
@ -2271,4 +2244,5 @@ static driver_t netfront_driver = {
};
devclass_t netfront_devclass;
DRIVER_MODULE(xe, xenbusb_front, netfront_driver, netfront_devclass, 0, 0);
DRIVER_MODULE(xe, xenbusb_front, netfront_driver, netfront_devclass, NULL,
NULL);

View File

@ -1,80 +0,0 @@
/*-
* Copyright (c) 2008 Citrix Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/interrupt.h>
#include <machine/atomic.h>
#include <machine/xen/xen-os.h>
#include <xen/hypervisor.h>
#include <xen/xen_intr.h>
#include <dev/xen/xenpci/xenpcivar.h>
void
xen_suspend()
{
int suspend_cancelled;
if (DEVICE_SUSPEND(root_bus)) {
printf("xen_suspend: device_suspend failed\n");
return;
}
/*
* Make sure we don't change cpus or switch to some other
* thread. for the duration.
*/
critical_enter();
/*
* Prevent any races with evtchn_interrupt() handler.
*/
irq_suspend();
disable_intr();
suspend_cancelled = HYPERVISOR_suspend(0);
if (!suspend_cancelled)
xenpci_resume();
/*
* Re-enable interrupts and put the scheduler back to normal.
*/
enable_intr();
critical_exit();
/*
* FreeBSD really needs to add DEVICE_SUSPEND_CANCEL or
* similar.
*/
if (!suspend_cancelled)
DEVICE_RESUME(root_bus);
}

View File

@ -29,8 +29,6 @@
#ifndef _FS_EXT2FS_EXT2_DINODE_H_
#define _FS_EXT2FS_EXT2_DINODE_H_
#define e2di_size_high e2di_dacl
/*
* Special inode numbers
* The root inode is the root of the file system. Inode 0 can't be used for
@ -87,11 +85,11 @@
struct ext2fs_dinode {
uint16_t e2di_mode; /* 0: IFMT, permissions; see below. */
uint16_t e2di_uid; /* 2: Owner UID */
uint32_t e2di_size; /* 4: Size (in bytes) */
uint32_t e2di_atime; /* 8: Access time */
uint32_t e2di_ctime; /* 12: Change time */
uint32_t e2di_mtime; /* 16: Modification time */
uint32_t e2di_dtime; /* 20: Deletion time */
uint32_t e2di_size; /* 4: Size (in bytes) */
uint32_t e2di_atime; /* 8: Access time */
uint32_t e2di_ctime; /* 12: Change time */
uint32_t e2di_mtime; /* 16: Modification time */
uint32_t e2di_dtime; /* 20: Deletion time */
uint16_t e2di_gid; /* 24: Owner GID */
uint16_t e2di_nlink; /* 26: File link count */
uint32_t e2di_nblock; /* 28: Blocks count */
@ -99,22 +97,23 @@ struct ext2fs_dinode {
uint32_t e2di_version; /* 36: Low 32 bits inode version */
uint32_t e2di_blocks[EXT2_N_BLOCKS]; /* 40: disk blocks */
uint32_t e2di_gen; /* 100: generation number */
uint32_t e2di_facl; /* 104: file ACL (not implemented) */
uint32_t e2di_dacl; /* 108: dir ACL (not implemented) */
uint32_t e2di_faddr; /* 112: fragment address */
uint32_t e2di_facl; /* 104: Low EA block */
uint32_t e2di_size_high; /* 108: Upper bits of file size */
uint32_t e2di_faddr; /* 112: Fragment address (obsolete) */
uint16_t e2di_nblock_high; /* 116: Blocks count bits 47:32 */
uint16_t e2di_facl_high; /* 118: file ACL bits 47:32 */
uint16_t e2di_facl_high; /* 118: File EA bits 47:32 */
uint16_t e2di_uid_high; /* 120: Owner UID top 16 bits */
uint16_t e2di_gid_high; /* 122: Owner GID top 16 bits */
uint32_t e2di_linux_reserved3; /* 124 */
uint16_t e2di_extra_isize;
uint16_t e2di_pad1;
uint32_t e2di_ctime_extra; /* Extra change time */
uint32_t e2di_mtime_extra; /* Extra modification time */
uint32_t e2di_atime_extra; /* Extra access time */
uint32_t e2di_crtime; /* Creation (birth)time */
uint32_t e2di_crtime_extra; /* Extra creation (birth)time */
uint32_t e2di_version_hi; /* High 30 bits of inode version */
uint16_t e2di_chksum_lo; /* 124: Lower inode checksum */
uint16_t e2di_lx_reserved; /* 126: Unused */
uint16_t e2di_extra_isize; /* 128: Size of this inode */
uint16_t e2di_chksum_hi; /* 130: High inode checksum */
uint32_t e2di_ctime_extra; /* 132: Extra change time */
uint32_t e2di_mtime_extra; /* 136: Extra modification time */
uint32_t e2di_atime_extra; /* 140: Extra access time */
uint32_t e2di_crtime; /* 144: Creation (birth)time */
uint32_t e2di_crtime_extra; /* 148: Extra creation (birth)time */
uint32_t e2di_version_hi; /* 152: High bits of inode version */
};
#endif /* !_FS_EXT2FS_EXT2_DINODE_H_ */

View File

@ -113,7 +113,7 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio,
struct ucred *cred, struct fuse_filehandle *fufh);
static int
fuse_write_biobackend(struct vnode *vp, struct uio *uio,
struct ucred *cred, struct fuse_filehandle *fufh);
struct ucred *cred, struct fuse_filehandle *fufh, int ioflag);
int
fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
@ -162,7 +162,7 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
} else {
FS_DEBUG("buffered write of vnode %ju\n",
(uintmax_t)VTOILLU(vp));
err = fuse_write_biobackend(vp, uio, cred, fufh);
err = fuse_write_biobackend(vp, uio, cred, fufh, ioflag);
}
break;
default:
@ -371,7 +371,7 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio,
static int
fuse_write_biobackend(struct vnode *vp, struct uio *uio,
struct ucred *cred, struct fuse_filehandle *fufh)
struct ucred *cred, struct fuse_filehandle *fufh, int ioflag)
{
struct fuse_vnode_data *fvdat = VTOFUD(vp);
struct buf *bp;
@ -390,6 +390,8 @@ fuse_write_biobackend(struct vnode *vp, struct uio *uio,
return (EINVAL);
if (uio->uio_resid == 0)
return (0);
if (ioflag & IO_APPEND)
uio_setoffset(uio, fvdat->filesize);
/*
* Find all of this file's B_NEEDCOMMIT buffers. If our writes

View File

@ -478,39 +478,19 @@ nandfs_iterate_dirty_vnodes(struct mount *mp, struct nandfs_seginfo *seginfo)
struct nandfs_node *nandfs_node;
struct vnode *vp, *mvp;
struct thread *td;
int error, lockreq, update;
int error, update;
td = curthread;
lockreq = LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY;
MNT_ILOCK(mp);
MNT_VNODE_FOREACH(vp, mp, mvp) {
MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) {
update = 0;
if (mp->mnt_syncer == vp)
continue;
if (VOP_ISLOCKED(vp))
continue;
VI_LOCK(vp);
MNT_IUNLOCK(mp);
if (vp->v_iflag & VI_DOOMED) {
if (mp->mnt_syncer == vp || VOP_ISLOCKED(vp)) {
VI_UNLOCK(vp);
MNT_ILOCK(mp);
continue;
}
if ((error = vget(vp, lockreq, td)) != 0) {
MNT_ILOCK(mp);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT, td) != 0)
continue;
}
if (vp->v_iflag & VI_DOOMED) {
vput(vp);
MNT_ILOCK(mp);
continue;
}
nandfs_node = VTON(vp);
if (nandfs_node->nn_flags & IN_MODIFIED) {
@ -532,12 +512,8 @@ nandfs_iterate_dirty_vnodes(struct mount *mp, struct nandfs_seginfo *seginfo)
if (update)
nandfs_node_update(nandfs_node);
MNT_ILOCK(mp);
}
MNT_IUNLOCK(mp);
return (0);
}

View File

@ -34,9 +34,15 @@
* $FreeBSD$
*/
#ifndef FS_NULL_H
#define FS_NULL_H
#define NULLM_CACHE 0x0001
struct null_mount {
struct mount *nullm_vfs;
struct vnode *nullm_rootvp; /* Reference to root null_node */
uint64_t nullm_flags;
};
#ifdef _KERNEL
@ -80,3 +86,5 @@ MALLOC_DECLARE(M_NULLFSNODE);
#endif /* NULLFS_DEBUG */
#endif /* _KERNEL */
#endif

View File

@ -224,6 +224,9 @@ null_nodeget(mp, lowervp, vpp)
* provide ready to use vnode.
*/
if (VOP_ISLOCKED(lowervp) != LK_EXCLUSIVE) {
KASSERT((MOUNTTONULLMOUNT(mp)->nullm_flags & NULLM_CACHE) != 0,
("lowervp %p is not excl locked and cache is disabled",
lowervp));
vn_lock(lowervp, LK_UPGRADE | LK_RETRY);
if ((lowervp->v_iflag & VI_DOOMED) != 0) {
vput(lowervp);

View File

@ -67,6 +67,15 @@ static vfs_vget_t nullfs_vget;
static vfs_extattrctl_t nullfs_extattrctl;
static vfs_reclaim_lowervp_t nullfs_reclaim_lowervp;
/* Mount options that we support. */
static const char *nullfs_opts[] = {
"cache",
"export",
"from",
"target",
NULL
};
/*
* Mount null layer
*/
@ -86,9 +95,11 @@ nullfs_mount(struct mount *mp)
if (!prison_allow(td->td_ucred, PR_ALLOW_MOUNT_NULLFS))
return (EPERM);
if (mp->mnt_flag & MNT_ROOTFS)
return (EOPNOTSUPP);
if (vfs_filteropt(mp->mnt_optnew, nullfs_opts))
return (EINVAL);
/*
* Update is a no-op
*/
@ -149,7 +160,7 @@ nullfs_mount(struct mount *mp)
}
xmp = (struct null_mount *) malloc(sizeof(struct null_mount),
M_NULLFSMNT, M_WAITOK);
M_NULLFSMNT, M_WAITOK | M_ZERO);
/*
* Save reference to underlying FS
@ -187,16 +198,27 @@ nullfs_mount(struct mount *mp)
mp->mnt_flag |= MNT_LOCAL;
MNT_IUNLOCK(mp);
}
xmp->nullm_flags |= NULLM_CACHE;
if (vfs_getopt(mp->mnt_optnew, "nocache", NULL, NULL) == 0)
xmp->nullm_flags &= ~NULLM_CACHE;
MNT_ILOCK(mp);
mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag &
(MNTK_SHARED_WRITES | MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED);
if ((xmp->nullm_flags & NULLM_CACHE) != 0) {
mp->mnt_kern_flag |= lowerrootvp->v_mount->mnt_kern_flag &
(MNTK_SHARED_WRITES | MNTK_LOOKUP_SHARED |
MNTK_EXTENDED_SHARED);
}
mp->mnt_kern_flag |= MNTK_LOOKUP_EXCL_DOTDOT;
MNT_IUNLOCK(mp);
mp->mnt_data = xmp;
vfs_getnewfsid(mp);
MNT_ILOCK(xmp->nullm_vfs);
TAILQ_INSERT_TAIL(&xmp->nullm_vfs->mnt_uppers, mp, mnt_upper_link);
MNT_IUNLOCK(xmp->nullm_vfs);
if ((xmp->nullm_flags & NULLM_CACHE) != 0) {
MNT_ILOCK(xmp->nullm_vfs);
TAILQ_INSERT_TAIL(&xmp->nullm_vfs->mnt_uppers, mp,
mnt_upper_link);
MNT_IUNLOCK(xmp->nullm_vfs);
}
vfs_mountedfrom(mp, target);
@ -234,13 +256,15 @@ nullfs_unmount(mp, mntflags)
*/
mntdata = mp->mnt_data;
ump = mntdata->nullm_vfs;
MNT_ILOCK(ump);
while ((ump->mnt_kern_flag & MNTK_VGONE_UPPER) != 0) {
ump->mnt_kern_flag |= MNTK_VGONE_WAITER;
msleep(&ump->mnt_uppers, &ump->mnt_mtx, 0, "vgnupw", 0);
if ((mntdata->nullm_flags & NULLM_CACHE) != 0) {
MNT_ILOCK(ump);
while ((ump->mnt_kern_flag & MNTK_VGONE_UPPER) != 0) {
ump->mnt_kern_flag |= MNTK_VGONE_WAITER;
msleep(&ump->mnt_uppers, &ump->mnt_mtx, 0, "vgnupw", 0);
}
TAILQ_REMOVE(&ump->mnt_uppers, mp, mnt_upper_link);
MNT_IUNLOCK(ump);
}
TAILQ_REMOVE(&ump->mnt_uppers, mp, mnt_upper_link);
MNT_IUNLOCK(ump);
mp->mnt_data = NULL;
free(mntdata, M_NULLFSMNT);
return (0);

View File

@ -692,7 +692,22 @@ null_unlock(struct vop_unlock_args *ap)
static int
null_inactive(struct vop_inactive_args *ap __unused)
{
struct vnode *vp;
struct mount *mp;
struct null_mount *xmp;
vp = ap->a_vp;
mp = vp->v_mount;
xmp = MOUNTTONULLMOUNT(mp);
if ((xmp->nullm_flags & NULLM_CACHE) == 0) {
/*
* If this is the last reference and caching of the
* nullfs vnodes is not enabled, then free up the
* vnode so as not to tie up the lower vnodes.
*/
vp->v_object = NULL;
vrecycle(vp);
}
return (0);
}

View File

@ -49,6 +49,7 @@
/* --------------------------------------------------------------------- */
#include <sys/malloc.h>
#include <sys/systm.h>
#include <sys/tree.h>
#include <sys/vmmeter.h>
#include <vm/swap_pager.h>
@ -60,104 +61,81 @@ MALLOC_DECLARE(M_TMPFSNAME);
/*
* Internal representation of a tmpfs directory entry.
*/
LIST_HEAD(tmpfs_dir_duphead, tmpfs_dirent);
struct tmpfs_dirent {
TAILQ_ENTRY(tmpfs_dirent) td_entries;
/*
* Depending on td_cookie flag entry can be of 3 types:
* - regular -- no hash collisions, stored in RB-Tree
* - duphead -- synthetic linked list head for dup entries
* - dup -- stored in linked list instead of RB-Tree
*/
union {
/* regular and duphead entry types */
RB_ENTRY(tmpfs_dirent) td_entries;
/* Length of the name stored in this directory entry. This avoids
* the need to recalculate it every time the name is used. */
uint16_t td_namelen;
/* dup entry type */
struct {
LIST_ENTRY(tmpfs_dirent) entries;
LIST_ENTRY(tmpfs_dirent) index_entries;
} td_dup;
} uh;
/* The name of the entry, allocated from a string pool. This
* string is not required to be zero-terminated; therefore, the
* td_namelen field must always be used when accessing its value. */
char * td_name;
uint32_t td_cookie;
uint32_t td_hash;
u_int td_namelen;
/* Pointer to the node this entry refers to. In case this field
* is NULL, the node is a whiteout. */
struct tmpfs_node * td_node;
union {
/*
* The name of the entry, allocated from a string pool. This
* string is not required to be zero-terminated.
*/
char * td_name; /* regular, dup */
struct tmpfs_dir_duphead td_duphead; /* duphead */
} ud;
};
/* A directory in tmpfs holds a sorted list of directory entries, which in
/* A directory in tmpfs holds a list of directory entries, which in
* turn point to other files (which can be directories themselves).
*
* In tmpfs, this list is managed by a tail queue, whose head is defined by
* In tmpfs, this list is managed by a RB-Tree, whose head is defined by
* the struct tmpfs_dir type.
*
* It is imporant to notice that directories do not have entries for . and
* It is important to notice that directories do not have entries for . and
* .. as other file systems do. These can be generated when requested
* based on information available by other means, such as the pointer to
* the node itself in the former case or the pointer to the parent directory
* in the latter case. This is done to simplify tmpfs's code and, more
* importantly, to remove redundancy. */
TAILQ_HEAD(tmpfs_dir, tmpfs_dirent);
RB_HEAD(tmpfs_dir, tmpfs_dirent);
/* Each entry in a directory has a cookie that identifies it. Cookies
* supersede offsets within directories because, given how tmpfs stores
* directories in memory, there is no such thing as an offset. (Emulating
* a real offset could be very difficult.)
*
* directories in memory, there is no such thing as an offset.
*
* The '.', '..' and the end of directory markers have fixed cookies which
* cannot collide with the cookies generated by other entries. The cookies
* fot the other entries are generated based on the memory address on which
* stores their information is stored.
* for the other entries are generated based on the file name hash value or
* unique number in case of name hash collision.
*
* Ideally, using the entry's memory pointer as the cookie would be enough
* to represent it and it wouldn't cause collisions in any system.
* Unfortunately, this results in "offsets" with very large values which
* later raise problems in the Linux compatibility layer (and maybe in other
* places) as described in PR kern/32034. Hence we need to workaround this
* with a rather ugly hack.
*
* Linux 32-bit binaries, unless built with _FILE_OFFSET_BITS=64, have off_t
* set to 'long', which is a 32-bit *signed* long integer. Regardless of
* the macro value, GLIBC (2.3 at least) always uses the getdents64
* system call (when calling readdir) which internally returns off64_t
* offsets. In order to make 32-bit binaries work, *GLIBC* converts the
* 64-bit values returned by the kernel to 32-bit ones and aborts with
* EOVERFLOW if the conversion results in values that won't fit in 32-bit
* integers (which it assumes is because the directory is extremely large).
* This wouldn't cause problems if we were dealing with unsigned integers,
* but as we have signed integers, this check fails due to sign expansion.
*
* For example, consider that the kernel returns the 0xc1234567 cookie to
* userspace in a off64_t integer. Later on, GLIBC casts this value to
* off_t (remember, signed) with code similar to:
* system call returns the offset in kernel_value;
* off_t casted_value = kernel_value;
* if (sizeof(off_t) != sizeof(off64_t) &&
* kernel_value != casted_value)
* error!
* In this case, casted_value still has 0xc1234567, but when it is compared
* for equality against kernel_value, it is promoted to a 64-bit integer and
* becomes 0xffffffffc1234567, which is different than 0x00000000c1234567.
* Then, GLIBC assumes this is because the directory is very large.
*
* Given that all the above happens in user-space, we have no control over
* it; therefore we must workaround the issue here. We do this by
* truncating the pointer value to a 32-bit integer and hope that there
* won't be collisions. In fact, this will not cause any problems in
* 32-bit platforms but some might arise in 64-bit machines (I'm not sure
* if they can happen at all in practice).
*
* XXX A nicer solution shall be attempted. */
#ifdef _KERNEL
#define TMPFS_DIRCOOKIE_DOT 0
#define TMPFS_DIRCOOKIE_DOTDOT 1
#define TMPFS_DIRCOOKIE_EOF 2
static __inline
off_t
tmpfs_dircookie(struct tmpfs_dirent *de)
{
off_t cookie;
* To preserve compatibility cookies are limited to 31 bits.
*/
cookie = ((off_t)(uintptr_t)de >> 1) & 0x7FFFFFFF;
MPASS(cookie != TMPFS_DIRCOOKIE_DOT);
MPASS(cookie != TMPFS_DIRCOOKIE_DOTDOT);
MPASS(cookie != TMPFS_DIRCOOKIE_EOF);
return cookie;
}
#endif
#define TMPFS_DIRCOOKIE_DOT 0
#define TMPFS_DIRCOOKIE_DOTDOT 1
#define TMPFS_DIRCOOKIE_EOF 2
#define TMPFS_DIRCOOKIE_MASK ((off_t)0x3fffffffU)
#define TMPFS_DIRCOOKIE_MIN ((off_t)0x00000004U)
#define TMPFS_DIRCOOKIE_DUP ((off_t)0x40000000U)
#define TMPFS_DIRCOOKIE_DUPHEAD ((off_t)0x80000000U)
#define TMPFS_DIRCOOKIE_DUP_MIN TMPFS_DIRCOOKIE_DUP
#define TMPFS_DIRCOOKIE_DUP_MAX \
(TMPFS_DIRCOOKIE_DUP | TMPFS_DIRCOOKIE_MASK)
/* --------------------------------------------------------------------- */
@ -243,29 +221,31 @@ struct tmpfs_node {
dev_t tn_rdev;
/* Valid when tn_type == VDIR. */
struct tn_dir{
struct tn_dir {
/* Pointer to the parent directory. The root
* directory has a pointer to itself in this field;
* this property identifies the root node. */
struct tmpfs_node * tn_parent;
/* Head of a tail-queue that links the contents of
* the directory together. See above for a
* description of its contents. */
/* Head of a tree that links the contents of
* the directory together. */
struct tmpfs_dir tn_dirhead;
/* Head of a list the contains fake directory entries
* heads, i.e. entries with TMPFS_DIRCOOKIE_DUPHEAD
* flag. */
struct tmpfs_dir_duphead tn_dupindex;
/* Number and pointer of the first directory entry
* returned by the readdir operation if it were
* called again to continue reading data from the
* same directory as before. This is used to speed
* up reads of long directories, assuming that no
* more than one read is in progress at a given time.
* Otherwise, these values are discarded and a linear
* scan is performed from the beginning up to the
* point where readdir starts returning values. */
* Otherwise, these values are discarded. */
off_t tn_readdir_lastn;
struct tmpfs_dirent * tn_readdir_lastp;
}tn_dir;
} tn_dir;
/* Valid when tn_type == VLNK. */
/* The link's target, allocated from a string pool. */
@ -419,9 +399,9 @@ int tmpfs_alloc_node(struct tmpfs_mount *, enum vtype,
char *, dev_t, struct tmpfs_node **);
void tmpfs_free_node(struct tmpfs_mount *, struct tmpfs_node *);
int tmpfs_alloc_dirent(struct tmpfs_mount *, struct tmpfs_node *,
const char *, uint16_t, struct tmpfs_dirent **);
void tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *,
boolean_t);
const char *, u_int, struct tmpfs_dirent **);
void tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *);
void tmpfs_dirent_init(struct tmpfs_dirent *, const char *, u_int);
int tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, int,
struct vnode **);
void tmpfs_free_vp(struct vnode *);
@ -429,13 +409,12 @@ int tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *,
struct componentname *, char *);
void tmpfs_dir_attach(struct vnode *, struct tmpfs_dirent *);
void tmpfs_dir_detach(struct vnode *, struct tmpfs_dirent *);
void tmpfs_dir_destroy(struct tmpfs_mount *, struct tmpfs_node *);
struct tmpfs_dirent * tmpfs_dir_lookup(struct tmpfs_node *node,
struct tmpfs_node *f,
struct componentname *cnp);
int tmpfs_dir_getdotdent(struct tmpfs_node *, struct uio *);
int tmpfs_dir_getdotdotdent(struct tmpfs_node *, struct uio *);
struct tmpfs_dirent * tmpfs_dir_lookupbycookie(struct tmpfs_node *, off_t);
int tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, off_t *);
int tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, int,
u_long *, int *);
int tmpfs_dir_whiteout_add(struct vnode *, struct componentname *);
void tmpfs_dir_whiteout_remove(struct vnode *, struct componentname *);
int tmpfs_reg_resize(struct vnode *, off_t, boolean_t);
@ -467,8 +446,8 @@ int tmpfs_truncate(struct vnode *, off_t);
* with a length of 'len'.
*/
#define TMPFS_DIRENT_MATCHES(de, name, len) \
(de->td_namelen == (uint16_t)len && \
bcmp((de)->td_name, (name), (de)->td_namelen) == 0)
(de->td_namelen == len && \
bcmp((de)->ud.td_name, (name), (de)->td_namelen) == 0)
/* --------------------------------------------------------------------- */
@ -476,11 +455,10 @@ int tmpfs_truncate(struct vnode *, off_t);
* Ensures that the node pointed by 'node' is a directory and that its
* contents are consistent with respect to directories.
*/
#define TMPFS_VALIDATE_DIR(node) \
MPASS((node)->tn_type == VDIR); \
MPASS((node)->tn_size % sizeof(struct tmpfs_dirent) == 0); \
MPASS((node)->tn_dir.tn_readdir_lastp == NULL || \
tmpfs_dircookie((node)->tn_dir.tn_readdir_lastp) == (node)->tn_dir.tn_readdir_lastn);
#define TMPFS_VALIDATE_DIR(node) do { \
MPASS((node)->tn_type == VDIR); \
MPASS((node)->tn_size % sizeof(struct tmpfs_dirent) == 0); \
} while (0)
/* --------------------------------------------------------------------- */

View File

@ -37,6 +37,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/fnv_hash.h>
#include <sys/namei.h>
#include <sys/priv.h>
#include <sys/proc.h>
@ -58,6 +59,11 @@ __FBSDID("$FreeBSD$");
#include <fs/tmpfs/tmpfs_fifoops.h>
#include <fs/tmpfs/tmpfs_vnops.h>
struct tmpfs_dir_cursor {
struct tmpfs_dirent *tdc_current;
struct tmpfs_dirent *tdc_tree;
};
SYSCTL_NODE(_vfs, OID_AUTO, tmpfs, CTLFLAG_RW, 0, "tmpfs file system");
static long tmpfs_pages_reserved = TMPFS_PAGES_MINRESERVED;
@ -87,6 +93,10 @@ SYSCTL_PROC(_vfs_tmpfs, OID_AUTO, memory_reserved, CTLTYPE_LONG|CTLFLAG_RW,
&tmpfs_pages_reserved, 0, sysctl_mem_reserved, "L",
"Amount of available memory and swap below which tmpfs growth stops");
static __inline int tmpfs_dirtree_cmp(struct tmpfs_dirent *a,
struct tmpfs_dirent *b);
RB_PROTOTYPE_STATIC(tmpfs_dir, tmpfs_dirent, uh.td_entries, tmpfs_dirtree_cmp);
size_t
tmpfs_mem_avail(void)
{
@ -188,7 +198,8 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type,
break;
case VDIR:
TAILQ_INIT(&nnode->tn_dir.tn_dirhead);
RB_INIT(&nnode->tn_dir.tn_dirhead);
LIST_INIT(&nnode->tn_dir.tn_dupindex);
MPASS(parent != nnode);
MPASS(IMPLIES(parent == NULL, tmp->tm_root == NULL));
nnode->tn_dir.tn_parent = (parent == NULL) ? nnode : parent;
@ -309,6 +320,49 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
/* --------------------------------------------------------------------- */
static __inline uint32_t
tmpfs_dirent_hash(const char *name, u_int len)
{
uint32_t hash;
hash = fnv_32_buf(name, len, FNV1_32_INIT + len) & TMPFS_DIRCOOKIE_MASK;
#ifdef TMPFS_DEBUG_DIRCOOKIE_DUP
hash &= 0xf;
#endif
if (hash < TMPFS_DIRCOOKIE_MIN)
hash += TMPFS_DIRCOOKIE_MIN;
return (hash);
}
static __inline off_t
tmpfs_dirent_cookie(struct tmpfs_dirent *de)
{
MPASS(de->td_cookie >= TMPFS_DIRCOOKIE_MIN);
return (de->td_cookie);
}
static __inline boolean_t
tmpfs_dirent_dup(struct tmpfs_dirent *de)
{
return ((de->td_cookie & TMPFS_DIRCOOKIE_DUP) != 0);
}
static __inline boolean_t
tmpfs_dirent_duphead(struct tmpfs_dirent *de)
{
return ((de->td_cookie & TMPFS_DIRCOOKIE_DUPHEAD) != 0);
}
void
tmpfs_dirent_init(struct tmpfs_dirent *de, const char *name, u_int namelen)
{
de->td_hash = de->td_cookie = tmpfs_dirent_hash(name, namelen);
memcpy(de->ud.td_name, name, namelen);
de->td_namelen = namelen;
}
/*
* Allocates a new directory entry for the node node with a name of name.
* The new directory entry is returned in *de.
@ -320,17 +374,17 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
*/
int
tmpfs_alloc_dirent(struct tmpfs_mount *tmp, struct tmpfs_node *node,
const char *name, uint16_t len, struct tmpfs_dirent **de)
const char *name, u_int len, struct tmpfs_dirent **de)
{
struct tmpfs_dirent *nde;
nde = (struct tmpfs_dirent *)uma_zalloc(
tmp->tm_dirent_pool, M_WAITOK);
nde->td_name = malloc(len, M_TMPFSNAME, M_WAITOK);
nde->td_namelen = len;
memcpy(nde->td_name, name, len);
nde = uma_zalloc(tmp->tm_dirent_pool, M_WAITOK);
nde->td_node = node;
if (name != NULL) {
nde->ud.td_name = malloc(len, M_TMPFSNAME, M_WAITOK);
tmpfs_dirent_init(nde, name, len);
} else
nde->td_namelen = 0;
if (node != NULL)
node->tn_links++;
@ -351,20 +405,17 @@ tmpfs_alloc_dirent(struct tmpfs_mount *tmp, struct tmpfs_node *node,
* directory entry, as it may already have been released from the outside.
*/
void
tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de,
boolean_t node_exists)
tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de)
{
if (node_exists) {
struct tmpfs_node *node;
struct tmpfs_node *node;
node = de->td_node;
if (node != NULL) {
MPASS(node->tn_links > 0);
node->tn_links--;
}
node = de->td_node;
if (node != NULL) {
MPASS(node->tn_links > 0);
node->tn_links--;
}
free(de->td_name, M_TMPFSNAME);
if (!tmpfs_dirent_duphead(de) && de->ud.td_name != NULL)
free(de->ud.td_name, M_TMPFSNAME);
uma_zfree(tmp->tm_dirent_pool, de);
}
@ -586,7 +637,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap,
/* Allocate a vnode for the new file. */
error = tmpfs_alloc_vp(dvp->v_mount, node, LK_EXCLUSIVE, vpp);
if (error != 0) {
tmpfs_free_dirent(tmp, de, TRUE);
tmpfs_free_dirent(tmp, de);
tmpfs_free_node(tmp, node);
goto out;
}
@ -605,6 +656,215 @@ out:
/* --------------------------------------------------------------------- */
static struct tmpfs_dirent *
tmpfs_dir_first(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
{
struct tmpfs_dirent *de;
de = RB_MIN(tmpfs_dir, &dnode->tn_dir.tn_dirhead);
dc->tdc_tree = de;
if (de != NULL && tmpfs_dirent_duphead(de))
de = LIST_FIRST(&de->ud.td_duphead);
dc->tdc_current = de;
return (dc->tdc_current);
}
static struct tmpfs_dirent *
tmpfs_dir_next(struct tmpfs_node *dnode, struct tmpfs_dir_cursor *dc)
{
struct tmpfs_dirent *de;
MPASS(dc->tdc_tree != NULL);
if (tmpfs_dirent_dup(dc->tdc_current)) {
dc->tdc_current = LIST_NEXT(dc->tdc_current, uh.td_dup.entries);
if (dc->tdc_current != NULL)
return (dc->tdc_current);
}
dc->tdc_tree = dc->tdc_current = RB_NEXT(tmpfs_dir,
&dnode->tn_dir.tn_dirhead, dc->tdc_tree);
if ((de = dc->tdc_current) != NULL && tmpfs_dirent_duphead(de)) {
dc->tdc_current = LIST_FIRST(&de->ud.td_duphead);
MPASS(dc->tdc_current != NULL);
}
return (dc->tdc_current);
}
/* Lookup directory entry in RB-Tree. Function may return duphead entry. */
static struct tmpfs_dirent *
tmpfs_dir_xlookup_hash(struct tmpfs_node *dnode, uint32_t hash)
{
struct tmpfs_dirent *de, dekey;
dekey.td_hash = hash;
de = RB_FIND(tmpfs_dir, &dnode->tn_dir.tn_dirhead, &dekey);
return (de);
}
/* Lookup directory entry by cookie, initialize directory cursor accordingly. */
static struct tmpfs_dirent *
tmpfs_dir_lookup_cookie(struct tmpfs_node *node, off_t cookie,
struct tmpfs_dir_cursor *dc)
{
struct tmpfs_dir *dirhead = &node->tn_dir.tn_dirhead;
struct tmpfs_dirent *de, dekey;
MPASS(cookie >= TMPFS_DIRCOOKIE_MIN);
if (cookie == node->tn_dir.tn_readdir_lastn &&
(de = node->tn_dir.tn_readdir_lastp) != NULL) {
/* Protect against possible race, tn_readdir_last[pn]
* may be updated with only shared vnode lock held. */
if (cookie == tmpfs_dirent_cookie(de))
goto out;
}
if ((cookie & TMPFS_DIRCOOKIE_DUP) != 0) {
LIST_FOREACH(de, &node->tn_dir.tn_dupindex,
uh.td_dup.index_entries) {
MPASS(tmpfs_dirent_dup(de));
if (de->td_cookie == cookie)
goto out;
/* dupindex list is sorted. */
if (de->td_cookie < cookie) {
de = NULL;
goto out;
}
}
MPASS(de == NULL);
goto out;
}
MPASS((cookie & TMPFS_DIRCOOKIE_MASK) == cookie);
dekey.td_hash = cookie;
/* Recover if direntry for cookie was removed */
de = RB_NFIND(tmpfs_dir, dirhead, &dekey);
dc->tdc_tree = de;
dc->tdc_current = de;
if (de != NULL && tmpfs_dirent_duphead(de)) {
dc->tdc_current = LIST_FIRST(&de->ud.td_duphead);
MPASS(dc->tdc_current != NULL);
}
return (dc->tdc_current);
out:
dc->tdc_tree = de;
dc->tdc_current = de;
if (de != NULL && tmpfs_dirent_dup(de))
dc->tdc_tree = tmpfs_dir_xlookup_hash(node,
de->td_hash);
return (dc->tdc_current);
}
/*
* Looks for a directory entry in the directory represented by node.
* 'cnp' describes the name of the entry to look for. Note that the .
* and .. components are not allowed as they do not physically exist
* within directories.
*
* Returns a pointer to the entry when found, otherwise NULL.
*/
struct tmpfs_dirent *
tmpfs_dir_lookup(struct tmpfs_node *node, struct tmpfs_node *f,
struct componentname *cnp)
{
struct tmpfs_dir_duphead *duphead;
struct tmpfs_dirent *de;
uint32_t hash;
MPASS(IMPLIES(cnp->cn_namelen == 1, cnp->cn_nameptr[0] != '.'));
MPASS(IMPLIES(cnp->cn_namelen == 2, !(cnp->cn_nameptr[0] == '.' &&
cnp->cn_nameptr[1] == '.')));
TMPFS_VALIDATE_DIR(node);
hash = tmpfs_dirent_hash(cnp->cn_nameptr, cnp->cn_namelen);
de = tmpfs_dir_xlookup_hash(node, hash);
if (de != NULL && tmpfs_dirent_duphead(de)) {
duphead = &de->ud.td_duphead;
LIST_FOREACH(de, duphead, uh.td_dup.entries) {
if (TMPFS_DIRENT_MATCHES(de, cnp->cn_nameptr,
cnp->cn_namelen))
break;
}
} else if (de != NULL) {
if (!TMPFS_DIRENT_MATCHES(de, cnp->cn_nameptr,
cnp->cn_namelen))
de = NULL;
}
if (de != NULL && f != NULL && de->td_node != f)
de = NULL;
return (de);
}
/*
* Attach duplicate-cookie directory entry nde to dnode and insert to dupindex
* list, allocate new cookie value.
*/
static void
tmpfs_dir_attach_dup(struct tmpfs_node *dnode,
struct tmpfs_dir_duphead *duphead, struct tmpfs_dirent *nde)
{
struct tmpfs_dir_duphead *dupindex;
struct tmpfs_dirent *de, *pde;
dupindex = &dnode->tn_dir.tn_dupindex;
de = LIST_FIRST(dupindex);
if (de == NULL || de->td_cookie < TMPFS_DIRCOOKIE_DUP_MAX) {
if (de == NULL)
nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MIN;
else
nde->td_cookie = de->td_cookie + 1;
MPASS(tmpfs_dirent_dup(nde));
LIST_INSERT_HEAD(dupindex, nde, uh.td_dup.index_entries);
LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
return;
}
/*
* Cookie numbers are near exhaustion. Scan dupindex list for unused
* numbers. dupindex list is sorted in descending order. Keep it so
* after inserting nde.
*/
while (1) {
pde = de;
de = LIST_NEXT(de, uh.td_dup.index_entries);
if (de == NULL && pde->td_cookie != TMPFS_DIRCOOKIE_DUP_MIN) {
/*
* Last element of the index doesn't have minimal cookie
* value, use it.
*/
nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MIN;
LIST_INSERT_AFTER(pde, nde, uh.td_dup.index_entries);
LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
return;
} else if (de == NULL) {
/*
* We are so lucky have 2^30 hash duplicates in single
* directory :) Return largest possible cookie value.
* It should be fine except possible issues with
* VOP_READDIR restart.
*/
nde->td_cookie = TMPFS_DIRCOOKIE_DUP_MAX;
LIST_INSERT_HEAD(dupindex, nde,
uh.td_dup.index_entries);
LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
return;
}
if (de->td_cookie + 1 == pde->td_cookie ||
de->td_cookie >= TMPFS_DIRCOOKIE_DUP_MAX)
continue; /* No hole or invalid cookie. */
nde->td_cookie = de->td_cookie + 1;
MPASS(tmpfs_dirent_dup(nde));
MPASS(pde->td_cookie > nde->td_cookie);
MPASS(nde->td_cookie > de->td_cookie);
LIST_INSERT_BEFORE(de, nde, uh.td_dup.index_entries);
LIST_INSERT_HEAD(duphead, nde, uh.td_dup.entries);
return;
};
}
/*
* Attaches the directory entry de to the directory represented by vp.
* Note that this does not change the link count of the node pointed by
@ -614,10 +874,38 @@ void
tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de)
{
struct tmpfs_node *dnode;
struct tmpfs_dirent *xde, *nde;
ASSERT_VOP_ELOCKED(vp, __func__);
MPASS(de->td_namelen > 0);
MPASS(de->td_hash >= TMPFS_DIRCOOKIE_MIN);
MPASS(de->td_cookie == de->td_hash);
dnode = VP_TO_TMPFS_DIR(vp);
TAILQ_INSERT_TAIL(&dnode->tn_dir.tn_dirhead, de, td_entries);
dnode->tn_dir.tn_readdir_lastn = 0;
dnode->tn_dir.tn_readdir_lastp = NULL;
MPASS(!tmpfs_dirent_dup(de));
xde = RB_INSERT(tmpfs_dir, &dnode->tn_dir.tn_dirhead, de);
if (xde != NULL && tmpfs_dirent_duphead(xde))
tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, de);
else if (xde != NULL) {
/*
* Allocate new duphead. Swap xde with duphead to avoid
* adding/removing elements with the same hash.
*/
MPASS(!tmpfs_dirent_dup(xde));
tmpfs_alloc_dirent(VFS_TO_TMPFS(vp->v_mount), NULL, NULL, 0,
&nde);
/* *nde = *xde; XXX gcc 4.2.1 may generate invalid code. */
memcpy(nde, xde, sizeof(*xde));
xde->td_cookie |= TMPFS_DIRCOOKIE_DUPHEAD;
LIST_INIT(&xde->ud.td_duphead);
xde->td_namelen = 0;
xde->td_node = NULL;
tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, nde);
tmpfs_dir_attach_dup(dnode, &xde->ud.td_duphead, de);
}
dnode->tn_size += sizeof(struct tmpfs_dirent);
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
TMPFS_NODE_MODIFIED;
@ -633,58 +921,61 @@ tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de)
void
tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de)
{
struct tmpfs_mount *tmp;
struct tmpfs_dir *head;
struct tmpfs_node *dnode;
struct tmpfs_dirent *xde;
ASSERT_VOP_ELOCKED(vp, __func__);
dnode = VP_TO_TMPFS_DIR(vp);
head = &dnode->tn_dir.tn_dirhead;
dnode->tn_dir.tn_readdir_lastn = 0;
dnode->tn_dir.tn_readdir_lastp = NULL;
if (dnode->tn_dir.tn_readdir_lastp == de) {
dnode->tn_dir.tn_readdir_lastn = 0;
dnode->tn_dir.tn_readdir_lastp = NULL;
}
if (tmpfs_dirent_dup(de)) {
/* Remove duphead if de was last entry. */
if (LIST_NEXT(de, uh.td_dup.entries) == NULL) {
xde = tmpfs_dir_xlookup_hash(dnode, de->td_hash);
MPASS(tmpfs_dirent_duphead(xde));
} else
xde = NULL;
LIST_REMOVE(de, uh.td_dup.entries);
LIST_REMOVE(de, uh.td_dup.index_entries);
if (xde != NULL) {
if (LIST_EMPTY(&xde->ud.td_duphead)) {
RB_REMOVE(tmpfs_dir, head, xde);
tmp = VFS_TO_TMPFS(vp->v_mount);
MPASS(xde->td_node == NULL);
tmpfs_free_dirent(tmp, xde);
}
}
} else
RB_REMOVE(tmpfs_dir, head, de);
TAILQ_REMOVE(&dnode->tn_dir.tn_dirhead, de, td_entries);
dnode->tn_size -= sizeof(struct tmpfs_dirent);
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
TMPFS_NODE_MODIFIED;
}
/* --------------------------------------------------------------------- */
/*
* Looks for a directory entry in the directory represented by node.
* 'cnp' describes the name of the entry to look for. Note that the .
* and .. components are not allowed as they do not physically exist
* within directories.
*
* Returns a pointer to the entry when found, otherwise NULL.
*/
struct tmpfs_dirent *
tmpfs_dir_lookup(struct tmpfs_node *node, struct tmpfs_node *f,
struct componentname *cnp)
void
tmpfs_dir_destroy(struct tmpfs_mount *tmp, struct tmpfs_node *dnode)
{
boolean_t found;
struct tmpfs_dirent *de;
struct tmpfs_dirent *de, *dde, *nde;
MPASS(IMPLIES(cnp->cn_namelen == 1, cnp->cn_nameptr[0] != '.'));
MPASS(IMPLIES(cnp->cn_namelen == 2, !(cnp->cn_nameptr[0] == '.' &&
cnp->cn_nameptr[1] == '.')));
TMPFS_VALIDATE_DIR(node);
found = 0;
TAILQ_FOREACH(de, &node->tn_dir.tn_dirhead, td_entries) {
if (f != NULL && de->td_node != f)
continue;
MPASS(cnp->cn_namelen < 0xffff);
if (de->td_namelen == (uint16_t)cnp->cn_namelen &&
bcmp(de->td_name, cnp->cn_nameptr, de->td_namelen) == 0) {
found = 1;
break;
RB_FOREACH_SAFE(de, tmpfs_dir, &dnode->tn_dir.tn_dirhead, nde) {
RB_REMOVE(tmpfs_dir, &dnode->tn_dir.tn_dirhead, de);
/* Node may already be destroyed. */
de->td_node = NULL;
if (tmpfs_dirent_duphead(de)) {
while ((dde = LIST_FIRST(&de->ud.td_duphead)) != NULL) {
LIST_REMOVE(dde, uh.td_dup.entries);
dde->td_node = NULL;
tmpfs_free_dirent(tmp, dde);
}
}
tmpfs_free_dirent(tmp, de);
}
node->tn_status |= TMPFS_NODE_ACCESSED;
return found ? de : NULL;
}
/* --------------------------------------------------------------------- */
@ -696,7 +987,7 @@ tmpfs_dir_lookup(struct tmpfs_node *node, struct tmpfs_node *f,
* hold the directory entry or an appropriate error code if another
* error happens.
*/
int
static int
tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
{
int error;
@ -713,12 +1004,9 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
dent.d_reclen = GENERIC_DIRSIZ(&dent);
if (dent.d_reclen > uio->uio_resid)
error = -1;
else {
error = EJUSTRETURN;
else
error = uiomove(&dent, dent.d_reclen, uio);
if (error == 0)
uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
}
node->tn_status |= TMPFS_NODE_ACCESSED;
@ -734,7 +1022,7 @@ tmpfs_dir_getdotdent(struct tmpfs_node *node, struct uio *uio)
* hold the directory entry or an appropriate error code if another
* error happens.
*/
int
static int
tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
{
int error;
@ -763,19 +1051,9 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
dent.d_reclen = GENERIC_DIRSIZ(&dent);
if (dent.d_reclen > uio->uio_resid)
error = -1;
else {
error = EJUSTRETURN;
else
error = uiomove(&dent, dent.d_reclen, uio);
if (error == 0) {
struct tmpfs_dirent *de;
de = TAILQ_FIRST(&node->tn_dir.tn_dirhead);
if (de == NULL)
uio->uio_offset = TMPFS_DIRCOOKIE_EOF;
else
uio->uio_offset = tmpfs_dircookie(de);
}
}
node->tn_status |= TMPFS_NODE_ACCESSED;
@ -784,30 +1062,6 @@ tmpfs_dir_getdotdotdent(struct tmpfs_node *node, struct uio *uio)
/* --------------------------------------------------------------------- */
/*
* Lookup a directory entry by its associated cookie.
*/
struct tmpfs_dirent *
tmpfs_dir_lookupbycookie(struct tmpfs_node *node, off_t cookie)
{
struct tmpfs_dirent *de;
if (cookie == node->tn_dir.tn_readdir_lastn &&
node->tn_dir.tn_readdir_lastp != NULL) {
return node->tn_dir.tn_readdir_lastp;
}
TAILQ_FOREACH(de, &node->tn_dir.tn_dirhead, td_entries) {
if (tmpfs_dircookie(de) == cookie) {
break;
}
}
return de;
}
/* --------------------------------------------------------------------- */
/*
* Helper function for tmpfs_readdir. Returns as much directory entries
* as can fit in the uio space. The read starts at uio->uio_offset.
@ -816,27 +1070,47 @@ tmpfs_dir_lookupbycookie(struct tmpfs_node *node, off_t cookie)
* error code if another error happens.
*/
int
tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, off_t *cntp)
tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, int cnt,
u_long *cookies, int *ncookies)
{
int error;
off_t startcookie;
struct tmpfs_dir_cursor dc;
struct tmpfs_dirent *de;
off_t off;
int error;
TMPFS_VALIDATE_DIR(node);
/* Locate the first directory entry we have to return. We have cached
* the last readdir in the node, so use those values if appropriate.
* Otherwise do a linear scan to find the requested entry. */
startcookie = uio->uio_offset;
MPASS(startcookie != TMPFS_DIRCOOKIE_DOT);
MPASS(startcookie != TMPFS_DIRCOOKIE_DOTDOT);
if (startcookie == TMPFS_DIRCOOKIE_EOF) {
return 0;
} else {
de = tmpfs_dir_lookupbycookie(node, startcookie);
}
if (de == NULL) {
return EINVAL;
off = 0;
switch (uio->uio_offset) {
case TMPFS_DIRCOOKIE_DOT:
error = tmpfs_dir_getdotdent(node, uio);
if (error != 0)
return (error);
uio->uio_offset = TMPFS_DIRCOOKIE_DOTDOT;
if (cnt != 0)
cookies[(*ncookies)++] = off = uio->uio_offset;
case TMPFS_DIRCOOKIE_DOTDOT:
error = tmpfs_dir_getdotdotdent(node, uio);
if (error != 0)
return (error);
de = tmpfs_dir_first(node, &dc);
if (de == NULL)
uio->uio_offset = TMPFS_DIRCOOKIE_EOF;
else
uio->uio_offset = tmpfs_dirent_cookie(de);
if (cnt != 0)
cookies[(*ncookies)++] = off = uio->uio_offset;
if (de == NULL)
return (0);
break;
case TMPFS_DIRCOOKIE_EOF:
return (0);
default:
de = tmpfs_dir_lookup_cookie(node, uio->uio_offset, &dc);
if (de == NULL)
return (EINVAL);
if (cnt != 0)
off = tmpfs_dirent_cookie(de);
}
/* Read as much entries as possible; i.e., until we reach the end of
@ -887,14 +1161,14 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, off_t *cntp)
}
d.d_namlen = de->td_namelen;
MPASS(de->td_namelen < sizeof(d.d_name));
(void)memcpy(d.d_name, de->td_name, de->td_namelen);
(void)memcpy(d.d_name, de->ud.td_name, de->td_namelen);
d.d_name[de->td_namelen] = '\0';
d.d_reclen = GENERIC_DIRSIZ(&d);
/* Stop reading if the directory entry we are treating is
* bigger than the amount of data that can be returned. */
if (d.d_reclen > uio->uio_resid) {
error = -1;
error = EJUSTRETURN;
break;
}
@ -902,21 +1176,30 @@ tmpfs_dir_getdents(struct tmpfs_node *node, struct uio *uio, off_t *cntp)
* advance pointers. */
error = uiomove(&d, d.d_reclen, uio);
if (error == 0) {
(*cntp)++;
de = TAILQ_NEXT(de, td_entries);
de = tmpfs_dir_next(node, &dc);
if (cnt != 0) {
if (de == NULL)
off = TMPFS_DIRCOOKIE_EOF;
else
off = tmpfs_dirent_cookie(de);
MPASS(*ncookies < cnt);
cookies[(*ncookies)++] = off;
}
}
} while (error == 0 && uio->uio_resid > 0 && de != NULL);
/* Update the offset and cache. */
if (de == NULL) {
uio->uio_offset = TMPFS_DIRCOOKIE_EOF;
node->tn_dir.tn_readdir_lastn = 0;
node->tn_dir.tn_readdir_lastp = NULL;
} else {
node->tn_dir.tn_readdir_lastn = uio->uio_offset = tmpfs_dircookie(de);
node->tn_dir.tn_readdir_lastp = de;
if (cnt == 0) {
if (de == NULL)
off = TMPFS_DIRCOOKIE_EOF;
else
off = tmpfs_dirent_cookie(de);
}
uio->uio_offset = off;
node->tn_dir.tn_readdir_lastn = off;
node->tn_dir.tn_readdir_lastp = de;
node->tn_status |= TMPFS_NODE_ACCESSED;
return error;
}
@ -943,7 +1226,7 @@ tmpfs_dir_whiteout_remove(struct vnode *dvp, struct componentname *cnp)
de = tmpfs_dir_lookup(VP_TO_TMPFS_DIR(dvp), NULL, cnp);
MPASS(de != NULL && de->td_node == NULL);
tmpfs_dir_detach(dvp, de);
tmpfs_free_dirent(VFS_TO_TMPFS(dvp->v_mount), de, TRUE);
tmpfs_free_dirent(VFS_TO_TMPFS(dvp->v_mount), de);
}
/* --------------------------------------------------------------------- */
@ -1436,3 +1719,15 @@ out:
return error;
}
static __inline int
tmpfs_dirtree_cmp(struct tmpfs_dirent *a, struct tmpfs_dirent *b)
{
if (a->td_hash > b->td_hash)
return (1);
else if (a->td_hash < b->td_hash)
return (-1);
return (0);
}
RB_GENERATE_STATIC(tmpfs_dir, tmpfs_dirent, uh.td_entries, tmpfs_dirtree_cmp);

View File

@ -294,19 +294,8 @@ tmpfs_unmount(struct mount *mp, int mntflags)
while (node != NULL) {
struct tmpfs_node *next;
if (node->tn_type == VDIR) {
struct tmpfs_dirent *de;
de = TAILQ_FIRST(&node->tn_dir.tn_dirhead);
while (de != NULL) {
struct tmpfs_dirent *nde;
nde = TAILQ_NEXT(de, td_entries);
tmpfs_free_dirent(tmp, de, FALSE);
de = nde;
node->tn_size -= sizeof(struct tmpfs_dirent);
}
}
if (node->tn_type == VDIR)
tmpfs_dir_destroy(tmp, node);
next = LIST_NEXT(node, tn_entries);
tmpfs_free_node(tmp, node);

View File

@ -847,7 +847,7 @@ tmpfs_remove(struct vop_remove_args *v)
/* Free the directory entry we just deleted. Note that the node
* referred by it will not be removed until the vnode is really
* reclaimed. */
tmpfs_free_dirent(tmp, de, TRUE);
tmpfs_free_dirent(tmp, de);
node->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED;
error = 0;
@ -1263,26 +1263,25 @@ tmpfs_rename(struct vop_rename_args *v)
fdnode->tn_links--;
TMPFS_NODE_UNLOCK(fdnode);
}
/* Do the move: just remove the entry from the source directory
* and insert it into the target one. */
tmpfs_dir_detach(fdvp, de);
if (fcnp->cn_flags & DOWHITEOUT)
tmpfs_dir_whiteout_add(fdvp, fcnp);
if (tcnp->cn_flags & ISWHITEOUT)
tmpfs_dir_whiteout_remove(tdvp, tcnp);
tmpfs_dir_attach(tdvp, de);
}
/* Do the move: just remove the entry from the source directory
* and insert it into the target one. */
tmpfs_dir_detach(fdvp, de);
if (fcnp->cn_flags & DOWHITEOUT)
tmpfs_dir_whiteout_add(fdvp, fcnp);
if (tcnp->cn_flags & ISWHITEOUT)
tmpfs_dir_whiteout_remove(tdvp, tcnp);
/* If the name has changed, we need to make it effective by changing
* it in the directory entry. */
if (newname != NULL) {
MPASS(tcnp->cn_namelen <= MAXNAMLEN);
free(de->td_name, M_TMPFSNAME);
de->td_namelen = (uint16_t)tcnp->cn_namelen;
memcpy(newname, tcnp->cn_nameptr, tcnp->cn_namelen);
de->td_name = newname;
free(de->ud.td_name, M_TMPFSNAME);
de->ud.td_name = newname;
tmpfs_dirent_init(de, tcnp->cn_nameptr, tcnp->cn_namelen);
fnode->tn_status |= TMPFS_NODE_CHANGED;
tdnode->tn_status |= TMPFS_NODE_MODIFIED;
@ -1291,15 +1290,20 @@ tmpfs_rename(struct vop_rename_args *v)
/* If we are overwriting an entry, we have to remove the old one
* from the target directory. */
if (tvp != NULL) {
struct tmpfs_dirent *tde;
/* Remove the old entry from the target directory. */
de = tmpfs_dir_lookup(tdnode, tnode, tcnp);
tmpfs_dir_detach(tdvp, de);
tde = tmpfs_dir_lookup(tdnode, tnode, tcnp);
tmpfs_dir_detach(tdvp, tde);
/* Free the directory entry we just deleted. Note that the
* node referred by it will not be removed until the vnode is
* really reclaimed. */
tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), de, TRUE);
tmpfs_free_dirent(VFS_TO_TMPFS(tvp->v_mount), tde);
}
tmpfs_dir_attach(tdvp, de);
cache_purge(fvp);
if (tvp != NULL)
cache_purge(tvp);
@ -1427,7 +1431,7 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
/* Free the directory entry we just deleted. Note that the node
* referred by it will not be removed until the vnode is really
* reclaimed. */
tmpfs_free_dirent(tmp, de, TRUE);
tmpfs_free_dirent(tmp, de);
/* Release the deleted vnode (will destroy the node, notify
* interested parties and clean it from the cache). */
@ -1473,8 +1477,8 @@ tmpfs_readdir(struct vop_readdir_args *v)
int *ncookies = v->a_ncookies;
int error;
off_t startoff;
off_t cnt = 0;
ssize_t startresid;
int cnt = 0;
struct tmpfs_node *node;
/* This operation only makes sense on directory nodes. */
@ -1483,69 +1487,29 @@ tmpfs_readdir(struct vop_readdir_args *v)
node = VP_TO_TMPFS_DIR(vp);
startoff = uio->uio_offset;
startresid = uio->uio_resid;
if (uio->uio_offset == TMPFS_DIRCOOKIE_DOT) {
error = tmpfs_dir_getdotdent(node, uio);
if (error != 0)
goto outok;
cnt++;
if (cookies != NULL && ncookies != NULL) {
cnt = howmany(node->tn_size, sizeof(struct tmpfs_dirent)) + 2;
*cookies = malloc(cnt * sizeof(**cookies), M_TEMP, M_WAITOK);
*ncookies = 0;
}
if (uio->uio_offset == TMPFS_DIRCOOKIE_DOTDOT) {
error = tmpfs_dir_getdotdotdent(node, uio);
if (error != 0)
goto outok;
cnt++;
}
if (cnt == 0)
error = tmpfs_dir_getdents(node, uio, 0, NULL, NULL);
else
error = tmpfs_dir_getdents(node, uio, cnt, *cookies, ncookies);
error = tmpfs_dir_getdents(node, uio, &cnt);
if (error == EJUSTRETURN)
error = (uio->uio_resid != startresid) ? 0 : EINVAL;
outok:
MPASS(error >= -1);
if (error == -1)
error = (cnt != 0) ? 0 : EINVAL;
if (error != 0 && cnt != 0)
free(*cookies, M_TEMP);
if (eofflag != NULL)
*eofflag =
(error == 0 && uio->uio_offset == TMPFS_DIRCOOKIE_EOF);
/* Update NFS-related variables. */
if (error == 0 && cookies != NULL && ncookies != NULL) {
off_t i;
off_t off = startoff;
struct tmpfs_dirent *de = NULL;
*ncookies = cnt;
*cookies = malloc(cnt * sizeof(off_t), M_TEMP, M_WAITOK);
for (i = 0; i < cnt; i++) {
MPASS(off != TMPFS_DIRCOOKIE_EOF);
if (off == TMPFS_DIRCOOKIE_DOT) {
off = TMPFS_DIRCOOKIE_DOTDOT;
} else {
if (off == TMPFS_DIRCOOKIE_DOTDOT) {
de = TAILQ_FIRST(&node->tn_dir.tn_dirhead);
} else if (de != NULL) {
de = TAILQ_NEXT(de, td_entries);
} else {
de = tmpfs_dir_lookupbycookie(node,
off);
MPASS(de != NULL);
de = TAILQ_NEXT(de, td_entries);
}
if (de == NULL)
off = TMPFS_DIRCOOKIE_EOF;
else
off = tmpfs_dircookie(de);
}
(*cookies)[i] = off;
}
MPASS(uio->uio_offset == off);
}
return error;
}

View File

@ -37,6 +37,7 @@ options SOFTUPDATES # Enable FFS soft updates support
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
options UFS_GJOURNAL # Enable gjournal-based UFS journaling
options QUOTA # Enable disk quotas for UFS
options MD_ROOT # MD is a potential root device
options NFSCL # New Network Filesystem Client
options NFSD # New Network Filesystem Server
@ -331,15 +332,6 @@ device usb # USB Bus (required)
device ukbd # Keyboard
device umass # Disks/Mass storage - Requires scbus and da
# FireWire support
device firewire # FireWire bus code
# sbp(4) works for some systems but causes boot failure on others
#device sbp # SCSI over FireWire (Requires scbus and da)
device fwe # Ethernet over FireWire (non-standard!)
device fwip # IP over FireWire (RFC 2734,3146)
device dcons # Dumb console driver
device dcons_crom # Configuration ROM for dcons
# Sound support
device sound # Generic sound driver (required)
device snd_cmi # CMedia CMI8338/CMI8738

View File

@ -216,7 +216,9 @@ static mmu_update_t xpq_queue[MAX_VIRT_CPUS][XPQUEUE_SIZE];
#else
static mmu_update_t xpq_queue[XPQUEUE_SIZE];
#ifdef INVARIANTS
static struct mmu_log xpq_queue_log[XPQUEUE_SIZE];
#endif
static int xpq_idx = 0;
#define XPQ_QUEUE_LOG xpq_queue_log

View File

@ -60,6 +60,7 @@ options SYSVSHM # SYSV-style shared memory
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Hash-based directory lookup scheme
options UFS_GJOURNAL # Enable gjournal-based UFS journaling
options QUOTA # Enable disk quotas for UFS
options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B RT extensions
# Debugging support. Always need this:
@ -77,7 +78,6 @@ options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
options MALLOC_DEBUG_MAXZONES=8 # Separate malloc(9) zones
# Various "busses"
device firewire # FireWire bus code
device miibus # MII bus support (Ethernet)
device pci # PCI bus support
device scbus # SCSI bus (required for ATA/SCSI)
@ -190,11 +190,6 @@ options IEEE80211_SUPPORT_MESH
# builds everything including AR5416 (and later 11n NIC) support.
options AH_SUPPORT_AR5416
# FireWire support
device fwip # IP over FireWire (RFC 2734,3146)
# sbp(4) works for some systems but causes boot failure on others
#device sbp # SCSI over FireWire (need scbus & da)
# Various (pseudo) devices
device ether # Ethernet support
device faith # IPv6-to-IPv4 relaying (translation)

View File

@ -1074,7 +1074,9 @@ kern_wait6(struct thread *td, idtype_t idtype, id_t id, int *status,
q = td->td_proc;
if ((pid_t)id == WAIT_MYPGRP && (idtype == P_PID || idtype == P_PGID)) {
PROC_LOCK(q);
id = (id_t)q->p_pgid;
PROC_UNLOCK(q);
idtype = P_PGID;
}

View File

@ -498,6 +498,8 @@ __lockmgr_args(struct lock *lk, u_int flags, struct lock_object *ilk,
case LK_DOWNGRADE:
_lockmgr_assert(lk, KA_XLOCKED | KA_NOTRECURSED,
file, line);
if (flags & LK_INTERLOCK)
class->lc_unlock(ilk);
return (0);
}
}

View File

@ -133,10 +133,10 @@ sleepinit(void)
* General sleep call. Suspends the current thread until a wakeup is
* performed on the specified identifier. The thread will then be made
* runnable with the specified priority. Sleeps at most timo/hz seconds
* (0 means no timeout). If pri includes PCATCH flag, signals are checked
* before and after sleeping, else signals are not checked. Returns 0 if
* (0 means no timeout). If pri includes the PCATCH flag, let signals
* interrupt the sleep, otherwise ignore them while sleeping. Returns 0 if
* awakened, EWOULDBLOCK if the timeout expires. If PCATCH is set and a
* signal needs to be delivered, ERESTART is returned if the current system
* signal becomes pending, ERESTART is returned if the current system
* call should be restarted if possible, and EINTR is returned if the system
* call should be interrupted by the signal (return EINTR).
*

View File

@ -160,7 +160,7 @@ static const char *const vm_bnames[] = {
"Plex86", /* Plex86 */
"Bochs", /* Bochs */
"Xen", /* Xen */
"BHYVE", /* BHyVe */
"BHYVE", /* bhyve */
NULL
};

View File

@ -559,7 +559,7 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions)
if (error || fstype[fstypelen - 1] != '\0') {
error = EINVAL;
if (errmsg != NULL)
strlcpy(errmsg, "Invalid fstype", errmsg_len);
strncpy(errmsg, "Invalid fstype", errmsg_len);
goto bail;
}
fspathlen = 0;
@ -567,7 +567,7 @@ vfs_donmount(struct thread *td, uint64_t fsflags, struct uio *fsoptions)
if (error || fspath[fspathlen - 1] != '\0') {
error = EINVAL;
if (errmsg != NULL)
strlcpy(errmsg, "Invalid fspath", errmsg_len);
strncpy(errmsg, "Invalid fspath", errmsg_len);
goto bail;
}
@ -1447,7 +1447,7 @@ vfs_filteropt(struct vfsoptlist *opts, const char **legal)
if (ret != 0) {
TAILQ_FOREACH(opt, opts, link) {
if (strcmp(opt->name, "errmsg") == 0) {
strlcpy((char *)opt->value, errmsg, opt->len);
strncpy((char *)opt->value, errmsg, opt->len);
break;
}
}
@ -1705,103 +1705,6 @@ vfs_copyopt(opts, name, dest, len)
return (ENOENT);
}
/*
* These are helper functions for filesystems to traverse all
* their vnodes. See MNT_VNODE_FOREACH() in sys/mount.h.
*
* This interface has been deprecated in favor of MNT_VNODE_FOREACH_ALL.
*/
MALLOC_DECLARE(M_VNODE_MARKER);
struct vnode *
__mnt_vnode_next(struct vnode **mvp, struct mount *mp)
{
struct vnode *vp;
mtx_assert(MNT_MTX(mp), MA_OWNED);
KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch"));
if (should_yield()) {
MNT_IUNLOCK(mp);
kern_yield(PRI_USER);
MNT_ILOCK(mp);
}
vp = TAILQ_NEXT(*mvp, v_nmntvnodes);
while (vp != NULL && vp->v_type == VMARKER)
vp = TAILQ_NEXT(vp, v_nmntvnodes);
/* Check if we are done */
if (vp == NULL) {
__mnt_vnode_markerfree(mvp, mp);
return (NULL);
}
TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes);
TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes);
return (vp);
}
struct vnode *
__mnt_vnode_first(struct vnode **mvp, struct mount *mp)
{
struct vnode *vp;
mtx_assert(MNT_MTX(mp), MA_OWNED);
vp = TAILQ_FIRST(&mp->mnt_nvnodelist);
while (vp != NULL && vp->v_type == VMARKER)
vp = TAILQ_NEXT(vp, v_nmntvnodes);
/* Check if we are done */
if (vp == NULL) {
*mvp = NULL;
return (NULL);
}
MNT_REF(mp);
MNT_IUNLOCK(mp);
*mvp = (struct vnode *) malloc(sizeof(struct vnode),
M_VNODE_MARKER,
M_WAITOK | M_ZERO);
MNT_ILOCK(mp);
(*mvp)->v_type = VMARKER;
vp = TAILQ_FIRST(&mp->mnt_nvnodelist);
while (vp != NULL && vp->v_type == VMARKER)
vp = TAILQ_NEXT(vp, v_nmntvnodes);
/* Check if we are done */
if (vp == NULL) {
MNT_IUNLOCK(mp);
free(*mvp, M_VNODE_MARKER);
MNT_ILOCK(mp);
*mvp = NULL;
MNT_REL(mp);
return (NULL);
}
(*mvp)->v_mount = mp;
TAILQ_INSERT_AFTER(&mp->mnt_nvnodelist, vp, *mvp, v_nmntvnodes);
return (vp);
}
void
__mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp)
{
if (*mvp == NULL)
return;
mtx_assert(MNT_MTX(mp), MA_OWNED);
KASSERT((*mvp)->v_mount == mp, ("marker vnode mount list mismatch"));
TAILQ_REMOVE(&mp->mnt_nvnodelist, *mvp, v_nmntvnodes);
MNT_IUNLOCK(mp);
free(*mvp, M_VNODE_MARKER);
MNT_ILOCK(mp);
*mvp = NULL;
MNT_REL(mp);
}
int
__vfs_statfs(struct mount *mp, struct statfs *sbp)
{

View File

@ -81,6 +81,7 @@ struct ar71xx_pci_softc {
device_t sc_dev;
int sc_busno;
int sc_baseslot;
struct rman sc_mem_rman;
struct rman sc_irq_rman;
@ -395,6 +396,16 @@ ar71xx_pci_attach(device_t dev)
AR71XX_PCI_IRQ_END) != 0)
panic("ar71xx_pci_attach: failed to set up IRQ rman");
/*
* Check if there is a base slot hint. Otherwise use default value.
*/
if (resource_int_value(device_get_name(dev),
device_get_unit(dev), "baseslot", &sc->sc_baseslot) != 0) {
device_printf(dev,
"%s: missing hint '%s', default to AR71XX_PCI_BASE_SLOT\n",
__func__, "baseslot");
sc->sc_baseslot = AR71XX_PCI_BASE_SLOT;
}
ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0);
ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0);
@ -648,11 +659,13 @@ ar71xx_pci_maxslots(device_t dev)
static int
ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin)
{
if (pci_get_slot(device) < AR71XX_PCI_BASE_SLOT)
struct ar71xx_pci_softc *sc = device_get_softc(pcib);
if (pci_get_slot(device) < sc->sc_baseslot)
panic("%s: PCI slot %d is less then AR71XX_PCI_BASE_SLOT",
__func__, pci_get_slot(device));
return (pci_get_slot(device) - AR71XX_PCI_BASE_SLOT);
return (pci_get_slot(device) - sc->sc_baseslot);
}
static device_method_t ar71xx_pci_methods[] = {

View File

@ -39,6 +39,7 @@ makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
# Board-specific support that cannot be auto-detected at runtime.
#options OCTEON_VENDOR_LANNER # Support for Lanner boards.
#options OCTEON_VENDOR_RADISYS # Support for Radisys boards.
#options OCTEON_VENDOR_UBIQUITI # Support for Ubiquiti boards.
#options OCTEON_BOARD_CAPK_0100ND # Support for CAPK-0100nd.
# Compile for a specified Octeon model. If not specified, support for

View File

@ -1,6 +1,4 @@
/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */
/*
/*-
* Copyright (c) 2001 Michael Shalayeff
* All rights reserved.
*
@ -26,7 +24,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
/*-
* Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
@ -42,6 +40,12 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $
* $FreeBSD$
*/
#ifndef _NET_IF_PFSYNC_H_
#define _NET_IF_PFSYNC_H_
@ -63,20 +67,6 @@
#define PFSYNC_ACT_EOF 12 /* end of frame */
#define PFSYNC_ACT_MAX 13
#define PFSYNC_ACTIONS "CLR ST", \
"INS ST", \
"INS ST ACK", \
"UPD ST", \
"UPD ST COMP", \
"UPD ST REQ", \
"DEL ST", \
"DEL ST COMP", \
"INS FR", \
"DEL FR", \
"BULK UPD STAT", \
"TDB UPD", \
"EOF"
#define PFSYNC_HMAC_LEN 20
/*

View File

@ -25,7 +25,14 @@
#define MY_ZCALLOC
#if defined(__FreeBSD__) && defined(_KERNEL)
#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */
#define _tr_init _zlib104_tr_init
#define _tr_align _zlib104_tr_align
#define _tr_tally _zlib104_tr_tally
#define _tr_flush_block _zlib104_tr_flush_block
#define _tr_stored_block _zlib104_tr_stored_block
#define inflate_fast _zlib104_inflate_fast
#define inflate _zlib104_inflate
#define zlibVersion _zlib104_Version
#endif

View File

@ -511,7 +511,7 @@ extern int EXPORT inflateInit OF((z_streamp strm));
*/
#if defined(__FreeBSD__) && defined(_KERNEL)
#define inflate inflate_ppp /* FreeBSD already has an inflate :-( */
#define inflate _zlib104_inflate /* FreeBSD already has an inflate :-( */
#endif
extern int EXPORT inflate OF((z_streamp strm, int flush));

View File

@ -2324,5 +2324,19 @@ ieee80211_recv_pspoll(struct ieee80211_node *ni, struct mbuf *m0)
ifp = vap->iv_ic->ic_ifp;
else
ifp = vap->iv_ifp;
(void) ifp->if_transmit(ifp, m);
/*
* Free any node ref which this mbuf may have.
*
* Much like psq_mfree(), we assume that M_ENCAP nodes have
* node references.
*/
if (ifp->if_transmit(ifp, m) != 0) {
/*
* XXX m is invalid (freed) at this point, determine M_ENCAP
* an alternate way.
*/
if (ifp == vap->iv_ic->ic_ifp)
ieee80211_free_node(ni);
}
}

View File

@ -1227,6 +1227,8 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
struct mbuf *m, *next;
uint32_t metric = 0;
const uint8_t *addr;
int is_encap;
struct ieee80211_node *ni_encap;
if (ni == vap->iv_bss ||
ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
@ -1403,11 +1405,21 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
(struct ieee80211_node *)(uintptr_t)
ieee80211_mac_hash(ic, addr)); /* either dest or ext_dest */
for (; m != NULL; m = next) {
is_encap = !! (m->m_flags & M_ENCAP);
ni_encap = (struct ieee80211_node *) m->m_pkthdr.rcvif;
next = m->m_nextpkt;
m->m_nextpkt = NULL;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"flush queued frame %p len %d", m, m->m_pkthdr.len);
ifp->if_transmit(ifp, m);
/*
* If the mbuf has M_ENCAP set, ensure we free it.
* Note that after if_transmit() is called, m is invalid.
*/
if (ifp->if_transmit(ifp, m) != 0) {
if (is_encap)
ieee80211_free_node(ni_encap);
}
}
#undef IS_PROXY
#undef PROXIED_BY_US

View File

@ -194,9 +194,20 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
/* NB: gap for netbsd definitions */
/*
* 14-17 are from Linux, they overlap the netbsd-specific
* fields.
*/
IEEE80211_RADIOTAP_RX_FLAGS = 14,
IEEE80211_RADIOTAP_TX_FLAGS = 15,
IEEE80211_RADIOTAP_RTS_RETRIES = 16,
IEEE80211_RADIOTAP_DATA_RETRIES = 17,
IEEE80211_RADIOTAP_XCHANNEL = 18,
IEEE80211_RADIOTAP_MCS = 19,
IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
IEEE80211_RADIOTAP_VENDOREXT = 30,
IEEE80211_RADIOTAP_EXT = 31,
};

View File

@ -819,19 +819,14 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin,
return (error);
/*
* Give the interface a chance to initialize if this is its first
* address, and to validate the address if necessary.
*
* Historically, drivers managed IFF_UP flag theirselves, so we
* need to check whether driver did that.
* Give the interface a chance to initialize
* if this is its first address,
* and to validate the address if necessary.
*/
flags = ifp->if_flags;
if (ifp->if_ioctl != NULL &&
(error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia)) != 0)
/* LIST_REMOVE(ia, ia_hash) is done in in_control */
return (error);
if ((ifp->if_flags & IFF_UP) && (flags & IFF_UP) == 0)
if_up(ifp);
/*
* Be compatible with network classes, if netmask isn't supplied,

Some files were not shown because too many files have changed in this diff Show More