summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-10-19 21:02:05 +0000
committerdim <dim@FreeBSD.org>2010-10-19 21:02:05 +0000
commitacc1b913a3297e19f9ffe7d2b7b8a3142926d3b4 (patch)
tree3ba42afae5a4abd129ca596650d0c27112d3953e
parentba43e0ffe7a883f062e502acf73190ce6534b0fe (diff)
parentf0ce9e3f305fe6039937eade02551429beef30ac (diff)
downloadFreeBSD-src-acc1b913a3297e19f9ffe7d2b7b8a3142926d3b4.zip
FreeBSD-src-acc1b913a3297e19f9ffe7d2b7b8a3142926d3b4.tar.gz
Sync: merge r213992 through r214076 from ^/head.
-rw-r--r--contrib/bsnmp/lib/bsnmplib.31
-rw-r--r--contrib/netcat/nc.113
-rw-r--r--contrib/netcat/netcat.c32
-rw-r--r--contrib/netcat/socks.c18
-rw-r--r--include/pthread.h16
-rw-r--r--lib/libc/include/namespace.h2
-rw-r--r--lib/libc/include/un-namespace.h2
-rw-r--r--lib/libradius/Makefile33
-rw-r--r--lib/libthr/pthread.map4
-rw-r--r--lib/libthr/thread/thr_private.h3
-rw-r--r--lib/libthr/thread/thr_rwlock.c25
-rw-r--r--lib/libthr/thread/thr_rwlockattr.c21
-rw-r--r--libexec/bootpd/bootptab.51
-rw-r--r--sbin/camcontrol/camcontrol.83
-rw-r--r--sbin/camcontrol/camcontrol.c10
-rw-r--r--sbin/routed/routed.81
-rw-r--r--sbin/setkey/setkey.84
-rw-r--r--sbin/sunlabel/sunlabel.81
-rw-r--r--share/man/man4/lagg.46
-rw-r--r--share/man/man4/man4.arm/mge.42
-rw-r--r--share/man/man4/man4.i386/ep.42
-rw-r--r--share/man/man4/man4.i386/mse.41
-rw-r--r--share/man/man4/man4.powerpc/tsec.42
-rw-r--r--share/man/man4/nxge.42
-rw-r--r--share/man/man5/freebsd-update.conf.51
-rw-r--r--share/man/man9/Makefile8
-rw-r--r--share/man/man9/vrele.92
-rw-r--r--share/man/man9/zone.97
-rw-r--r--sys/arm/mv/mv_sata.c2
-rw-r--r--sys/conf/files1
-rw-r--r--sys/dev/acpica/acpi.c153
-rw-r--r--sys/dev/acpica/acpi_if.m3
-rw-r--r--sys/dev/acpica/acpi_pci.c10
-rw-r--r--sys/dev/ata/ata-all.c21
-rw-r--r--sys/dev/ata/ata-all.h11
-rw-r--r--sys/dev/ata/ata-pci.c1
-rw-r--r--sys/dev/ata/ata-sata.c91
-rw-r--r--sys/dev/ata/chipsets/ata-ahci.c40
-rw-r--r--sys/dev/ata/chipsets/ata-intel.c406
-rw-r--r--sys/dev/ata/chipsets/ata-marvell.c2
-rw-r--r--sys/dev/ata/chipsets/ata-nvidia.c2
-rw-r--r--sys/dev/ata/chipsets/ata-promise.c38
-rw-r--r--sys/dev/ata/chipsets/ata-siliconimage.c42
-rw-r--r--sys/dev/ata/chipsets/ata-via.c15
-rw-r--r--sys/dev/firewire/fwohci.c4
-rw-r--r--sys/dev/if_ndis/if_ndis.c4
-rw-r--r--sys/dev/md/md.c24
-rw-r--r--sys/dev/mii/brgphy.c4
-rw-r--r--sys/dev/pci/pci.c11
-rw-r--r--sys/fs/msdosfs/msdosfs_lookup.c11
-rw-r--r--sys/fs/nfsclient/nfs_clnode.c8
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c44
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c5
-rw-r--r--sys/fs/nfsclient/nfsmount.h17
-rw-r--r--sys/geom/geom_dev.c12
-rw-r--r--sys/kern/kern_resource.c8
-rw-r--r--sys/kern/kern_shutdown.c13
-rw-r--r--sys/kern/vfs_mount.c4
-rw-r--r--sys/kern/vfs_mountroot.c1065
-rw-r--r--sys/modules/mps/Makefile2
-rw-r--r--sys/modules/wlan/Makefile4
-rw-r--r--sys/net80211/ieee80211_ratectl.c18
-rw-r--r--sys/net80211/ieee80211_ratectl.h3
-rw-r--r--sys/net80211/ieee80211_ratectl_none.c113
-rw-r--r--sys/netinet/libalias/libalias.31
-rw-r--r--sys/nfs/nfs_lock.c12
-rw-r--r--sys/nfs/nfs_lock.h2
-rw-r--r--sys/nfs/nfs_mountcommon.h51
-rw-r--r--sys/nfsclient/nfs.h2
-rw-r--r--sys/nfsclient/nfs_bio.c26
-rw-r--r--sys/nfsclient/nfs_nfsiod.c95
-rw-r--r--sys/nfsclient/nfs_node.c2
-rw-r--r--sys/nfsclient/nfs_vfsops.c27
-rw-r--r--sys/nfsclient/nfs_vnops.c2
-rw-r--r--sys/nfsclient/nfsmount.h21
-rw-r--r--sys/nfsclient/nfsnode.h8
-rw-r--r--sys/nfsserver/nfs_serv.c25
-rw-r--r--sys/nlm/nlm_advlock.c15
-rw-r--r--sys/nlm/nlm_prot_impl.c4
-rw-r--r--sys/sparc64/include/tick.h2
-rw-r--r--sys/sparc64/sparc64/mp_machdep.c2
-rw-r--r--sys/sparc64/sparc64/tick.c32
-rw-r--r--sys/sys/systm.h3
-rw-r--r--sys/vm/uma_core.c4
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd2
-rw-r--r--usr.bin/nc/Makefile2
-rw-r--r--usr.bin/uudecode/uudecode.c98
-rw-r--r--usr.sbin/apmd/apmd.82
-rw-r--r--usr.sbin/gpioctl/gpioctl.81
-rwxr-xr-xusr.sbin/pc-sysinstall/backend-query/list-tzones.sh17
-rwxr-xr-xusr.sbin/pc-sysinstall/backend-query/sys-mem.sh5
-rw-r--r--usr.sbin/ppp/ipcp.c5
92 files changed, 1991 insertions, 912 deletions
diff --git a/contrib/bsnmp/lib/bsnmplib.3 b/contrib/bsnmp/lib/bsnmplib.3
index 4512b8c..dfbffc4 100644
--- a/contrib/bsnmp/lib/bsnmplib.3
+++ b/contrib/bsnmp/lib/bsnmplib.3
@@ -134,7 +134,6 @@ is not zero,
.Fa v.octetstring.octets
points to a string allocated by
.Xr malloc 3 .
-.Pp
.Bd -literal -offset indent
#define SNMP_COMMUNITY_MAXLEN 128
#define SNMP_MAX_BINDINGS 100
diff --git a/contrib/netcat/nc.1 b/contrib/netcat/nc.1
index 41f5f09..9a6e836 100644
--- a/contrib/netcat/nc.1
+++ b/contrib/netcat/nc.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: nc.1,v 1.53 2010/02/23 23:00:52 schwarze Exp $
+.\" $OpenBSD: nc.1,v 1.55 2010/07/25 07:51:39 guenther Exp $
.\"
.\" Copyright (c) 1996 David Sacerdote
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 3, 2010
+.Dd July 25, 2010
.Dt NC 1
.Os
.Sh NAME
@@ -46,7 +46,7 @@
.Op Fl p Ar source_port
.Op Fl s Ar source_ip_address
.Op Fl T Ar ToS
-.Op Fl V Ar fib
+.Op Fl V Ar rtable
.Op Fl w Ar timeout
.Op Fl X Ar proxy_protocol
.Oo Xo
@@ -158,7 +158,6 @@ TCP_NOOPT
socket option.
.It Fl O Ar length
Specifies the size of the TCP send buffer.
-When
.It Fl P Ar proxy_username
Specifies a username to present to a proxy server that requires authentication.
If no username is specified then authentication will not be attempted.
@@ -202,8 +201,10 @@ Specifies to use
sockets.
.It Fl u
Use UDP instead of the default option of TCP.
-.It Fl V Ar fib
-Set the routing table (FIB).
+.It Fl V Ar rtable
+Set the routing table
+.Pq Dq FIB
+to be used.
The default is 0.
.It Fl v
Have
diff --git a/contrib/netcat/netcat.c b/contrib/netcat/netcat.c
index 28a9823..fe87e96 100644
--- a/contrib/netcat/netcat.c
+++ b/contrib/netcat/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.95 2010/02/27 00:58:56 nicm Exp $ */
+/* $OpenBSD: netcat.c,v 1.98 2010/07/03 04:44:51 guenther Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*
@@ -93,7 +93,7 @@ int Iflag; /* TCP receive buffer size */
int Oflag; /* TCP send buffer size */
int Sflag; /* TCP MD5 signature option */
int Tflag = -1; /* IP Type of Service */
-u_int rdomain;
+u_int rtableid;
int timeout = -1;
int family = AF_UNSPEC;
@@ -139,7 +139,6 @@ main(int argc, char *argv[])
{ NULL, 0, NULL, 0 }
};
- rdomain = 0;
ret = 1;
ipsec_count = 0;
s = 0;
@@ -235,10 +234,10 @@ main(int argc, char *argv[])
case 'V':
if (sysctlbyname("net.fibs", &numfibs, &intsize, NULL, 0) == -1)
errx(1, "Multiple FIBS not supported");
- rdomain = (unsigned int)strtonum(optarg, 0,
+ rtableid = (unsigned int)strtonum(optarg, 0,
numfibs - 1, &errstr);
if (errstr)
- errx(1, "FIB %s: %s", errstr, optarg);
+ errx(1, "rtable %s: %s", errstr, optarg);
break;
case 'v':
vflag = 1;
@@ -371,11 +370,11 @@ main(int argc, char *argv[])
*/
if (uflag) {
int rv, plen;
- char buf[8192];
+ char buf[16384];
struct sockaddr_storage z;
len = sizeof(z);
- plen = jflag ? 8192 : 1024;
+ plen = jflag ? 16384 : 2048;
rv = recvfrom(s, buf, plen, MSG_PEEK,
(struct sockaddr *)&z, &len);
if (rv < 0)
@@ -561,8 +560,8 @@ remote_connect(const char *host, const char *port, struct addrinfo hints)
add_ipsec_policy(s, ipsec_policy[1]);
#endif
- if (rdomain) {
- if (setfib(rdomain) == -1)
+ if (rtableid) {
+ if (setfib(rtableid) == -1)
err(1, "setfib");
}
@@ -634,8 +633,8 @@ local_listen(char *host, char *port, struct addrinfo hints)
res0->ai_protocol)) < 0)
continue;
- if (rdomain) {
- if (setfib(rdomain) == -1)
+ if (rtableid) {
+ if (setfib(rtableid) == -1)
err(1, "setfib");
}
@@ -680,12 +679,12 @@ void
readwrite(int nfd)
{
struct pollfd pfd[2];
- unsigned char buf[8192];
+ unsigned char buf[16384];
int n, wfd = fileno(stdin);
int lfd = fileno(stdout);
int plen;
- plen = jflag ? 8192 : 1024;
+ plen = jflag ? 16384 : 2048;
/* Setup Network FD */
pfd[0].fd = nfd;
@@ -827,10 +826,9 @@ build_ports(char *p)
hi = strtonum(p, 1, PORT_MAX, &errstr);
if (errstr)
errx(1, "port number %s: %s", errstr, p);
- portlist[0] = calloc(1, PORT_MAX_LEN);
+ portlist[0] = strdup(p);
if (portlist[0] == NULL)
err(1, NULL);
- portlist[0] = p;
}
}
@@ -947,7 +945,7 @@ help(void)
\t-t Answer TELNET negotiation\n\
\t-U Use UNIX domain socket\n\
\t-u UDP mode\n\
- \t-V fib Specify alternate routing table (FIB)\n\
+ \t-V rtable Specify alternate routing table\n\
\t-v Verbose\n\
\t-w secs\t Timeout for connects and final net reads\n\
\t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\
@@ -992,7 +990,7 @@ usage(int ret)
"usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n"
#endif
"\t [-P proxy_username] [-p source_port] [-s source_ip_address] [-T ToS]\n"
- "\t [-V fib] [-w timeout] [-X proxy_protocol]\n"
+ "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n"
"\t [-x proxy_address[:port]] [hostname] [port]\n");
if (ret)
exit(1);
diff --git a/contrib/netcat/socks.c b/contrib/netcat/socks.c
index da7bd0c..b38dff7 100644
--- a/contrib/netcat/socks.c
+++ b/contrib/netcat/socks.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: socks.c,v 1.17 2006/09/25 04:51:20 ray Exp $ */
+/* $OpenBSD: socks.c,v 1.18 2010/04/20 07:26:35 nicm Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
@@ -167,11 +167,11 @@ socks_connect(const char *host, const char *port,
buf[2] = SOCKS_NOAUTH;
cnt = atomicio(vwrite, proxyfd, buf, 3);
if (cnt != 3)
- err(1, "write failed (%d/3)", cnt);
+ err(1, "write failed (%zu/3)", cnt);
cnt = atomicio(read, proxyfd, buf, 2);
if (cnt != 2)
- err(1, "read failed (%d/3)", cnt);
+ err(1, "read failed (%zu/3)", cnt);
if (buf[1] == SOCKS_NOMETHOD)
errx(1, "authentication method negotiation failed");
@@ -220,11 +220,11 @@ socks_connect(const char *host, const char *port,
cnt = atomicio(vwrite, proxyfd, buf, wlen);
if (cnt != wlen)
- err(1, "write failed (%d/%d)", cnt, wlen);
+ err(1, "write failed (%zu/%zu)", cnt, wlen);
cnt = atomicio(read, proxyfd, buf, 10);
if (cnt != 10)
- err(1, "read failed (%d/10)", cnt);
+ err(1, "read failed (%zu/10)", cnt);
if (buf[1] != 0)
errx(1, "connection failed, SOCKS error %d", buf[1]);
} else if (socksv == 4) {
@@ -242,11 +242,11 @@ socks_connect(const char *host, const char *port,
cnt = atomicio(vwrite, proxyfd, buf, wlen);
if (cnt != wlen)
- err(1, "write failed (%d/%d)", cnt, wlen);
+ err(1, "write failed (%zu/%zu)", cnt, wlen);
cnt = atomicio(read, proxyfd, buf, 8);
if (cnt != 8)
- err(1, "read failed (%d/8)", cnt);
+ err(1, "read failed (%zu/8)", cnt);
if (buf[1] != 90)
errx(1, "connection failed, SOCKS error %d", buf[1]);
} else if (socksv == -1) {
@@ -272,7 +272,7 @@ socks_connect(const char *host, const char *port,
cnt = atomicio(vwrite, proxyfd, buf, r);
if (cnt != r)
- err(1, "write failed (%d/%d)", cnt, r);
+ err(1, "write failed (%zu/%d)", cnt, r);
if (authretry > 1) {
char resp[1024];
@@ -290,7 +290,7 @@ socks_connect(const char *host, const char *port,
errx(1, "Proxy auth response too long");
r = strlen(buf);
if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != r)
- err(1, "write failed (%d/%d)", cnt, r);
+ err(1, "write failed (%zu/%d)", cnt, r);
}
/* Terminate headers */
diff --git a/include/pthread.h b/include/pthread.h
index 56f6ef4..9a8e2ae 100644
--- a/include/pthread.h
+++ b/include/pthread.h
@@ -135,6 +135,15 @@ enum pthread_mutextype {
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_ERRORCHECK
+enum pthread_rwlocktype_np
+{
+ PTHREAD_RWLOCK_PREFER_READER_NP,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
+ PTHREAD_RWLOCK_PREFER_WRITER_NP,
+ PTHREAD_RWLOCK_DEFAULT_NP =
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
+};
+
struct _pthread_cleanup_info {
__uintptr_t pthread_cleanup_pad[8];
};
@@ -233,11 +242,14 @@ int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
int pthread_rwlock_unlock(pthread_rwlock_t *);
int pthread_rwlock_wrlock(pthread_rwlock_t *);
-int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *,
+ int *);
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *,
int *);
+int pthread_rwlockattr_init(pthread_rwlockattr_t *);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *, int);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
pthread_t pthread_self(void);
int pthread_setspecific(pthread_key_t, const void *);
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h
index 6ba8bab..590eba7 100644
--- a/lib/libc/include/namespace.h
+++ b/lib/libc/include/namespace.h
@@ -177,8 +177,10 @@
#define pthread_rwlock_unlock _pthread_rwlock_unlock
#define pthread_rwlock_wrlock _pthread_rwlock_wrlock
#define pthread_rwlockattr_destroy _pthread_rwlockattr_destroy
+#define pthread_rwlockattr_getkind_np _pthread_rwlockattr_getkind_np
#define pthread_rwlockattr_getpshared _pthread_rwlockattr_getpshared
#define pthread_rwlockattr_init _pthread_rwlockattr_init
+#define pthread_rwlockattr_setkind_np _pthread_rwlockattr_setkind_np
#define pthread_rwlockattr_setpshared _pthread_rwlockattr_setpshared
#define pthread_self _pthread_self
#define pthread_set_name_np _pthread_set_name_np
diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h
index 00f0df2..7a8f9d9 100644
--- a/lib/libc/include/un-namespace.h
+++ b/lib/libc/include/un-namespace.h
@@ -158,8 +158,10 @@
#undef pthread_rwlock_unlock
#undef pthread_rwlock_wrlock
#undef pthread_rwlockattr_destroy
+#undef pthread_rwlockattr_getkind_np
#undef pthread_rwlockattr_getpshared
#undef pthread_rwlockattr_init
+#undef pthread_rwlockattr_setkind_np
#undef pthread_rwlockattr_setpshared
#undef pthread_self
#undef pthread_set_name_np
diff --git a/lib/libradius/Makefile b/lib/libradius/Makefile
index f49f65c..5723bf1 100644
--- a/lib/libradius/Makefile
+++ b/lib/libradius/Makefile
@@ -33,6 +33,39 @@ CFLAGS+= -Wall
SHLIB_MAJOR= 4
MAN= libradius.3 radius.conf.5
+MLINKS+=libradius.3 rad_acct_open.3 \
+ libradius.3 rad_add_server.3 \
+ libradius.3 rad_auth_open.3 \
+ libradius.3 rad_close.3 \
+ libradius.3 rad_config.3 \
+ libradius.3 rad_continue_send_request.3 \
+ libradius.3 rad_create_request.3 \
+ libradius.3 rad_create_response.3 \
+ libradius.3 rad_cvt_addr.3 \
+ libradius.3 rad_cvt_int.3 \
+ libradius.3 rad_cvt_string.3 \
+ libradius.3 rad_demangle.3 \
+ libradius.3 rad_demangle_mppe_key.3 \
+ libradius.3 rad_get_attr.3 \
+ libradius.3 rad_get_vendor_attr.3 \
+ libradius.3 rad_init_send_request.3 \
+ libradius.3 rad_put_addr.3 \
+ libradius.3 rad_put_attr.3 \
+ libradius.3 rad_put_int.3 \
+ libradius.3 rad_put_message_authentic.3 \
+ libradius.3 rad_put_string.3 \
+ libradius.3 rad_put_vendor_addr.3 \
+ libradius.3 rad_put_vendor_attr.3 \
+ libradius.3 rad_put_vendor_int.3 \
+ libradius.3 rad_put_vendor_string.3 \
+ libradius.3 rad_receive_request.3 \
+ libradius.3 rad_request_authenticator.3 \
+ libradius.3 rad_send_request.3 \
+ libradius.3 rad_send_response.3 \
+ libradius.3 rad_server_open.3 \
+ libradius.3 rad_server_secret.3 \
+ libradius.3 rad_strerror.3
+
WARNS?= 3
.if ${MK_OPENSSL} == "no"
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 5e36239..4094016 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -318,7 +318,9 @@ FBSDprivate_1.0 {
_pthread_rwlock_wrlock;
_pthread_rwlockattr_destroy;
_pthread_rwlockattr_getpshared;
+ _pthread_rwlockattr_getkind_np;
_pthread_rwlockattr_init;
+ _pthread_rwlockattr_setkind_np;
_pthread_rwlockattr_setpshared;
_pthread_self;
_pthread_set_name_np;
@@ -401,6 +403,8 @@ FBSD_1.1 {
FBSD_1.2 {
openat;
+ pthread_rwlockattr_getkind_np;
+ pthread_rwlockattr_setkind_np;
setcontext;
swapcontext;
};
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index aa9feef..5d0c301 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -285,11 +285,14 @@ struct pthread_prio {
struct pthread_rwlockattr {
int pshared;
+ int kind;
};
struct pthread_rwlock {
struct urwlock lock;
struct pthread *owner;
+ int recurse;
+ int kind;
};
/*
diff --git a/lib/libthr/thread/thr_rwlock.c b/lib/libthr/thread/thr_rwlock.c
index ebdeae7..20b9b79 100644
--- a/lib/libthr/thread/thr_rwlock.c
+++ b/lib/libthr/thread/thr_rwlock.c
@@ -63,13 +63,19 @@ __weak_reference(_pthread_rwlock_timedwrlock, pthread_rwlock_timedwrlock);
*/
static int
-rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr __unused)
+rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
pthread_rwlock_t prwlock;
prwlock = (pthread_rwlock_t)calloc(1, sizeof(struct pthread_rwlock));
if (prwlock == NULL)
return (ENOMEM);
+ if (attr != NULL)
+ prwlock->kind = (*attr)->kind;
+ else
+ prwlock->kind = PTHREAD_RWLOCK_DEFAULT_NP;
+ if (prwlock->kind == PTHREAD_RWLOCK_PREFER_READER_NP)
+ prwlock->lock.rw_flags |= URWLOCK_PREFER_READER;
*rwlock = prwlock;
return (0);
}
@@ -112,7 +118,7 @@ init_static(struct pthread *thread, pthread_rwlock_t *rwlock)
}
int
-_pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+_pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
*rwlock = NULL;
return (rwlock_init(rwlock, attr));
@@ -260,6 +266,14 @@ rwlock_wrlock_common (pthread_rwlock_t *rwlock, const struct timespec *abstime)
CHECK_AND_INIT_RWLOCK
+ if (__predict_false(prwlock->owner == curthread)) {
+ if (__predict_false(
+ prwlock->kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)) {
+ prwlock->recurse++;
+ return (0);
+ }
+ }
+
/*
* POSIX said the validity of the abstimeout parameter need
* not be checked if the lock can be immediately acquired.
@@ -335,6 +349,13 @@ _pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
if (state & URWLOCK_WRITE_OWNER) {
if (__predict_false(prwlock->owner != curthread))
return (EPERM);
+ if (__predict_false(
+ prwlock->kind == PTHREAD_RWLOCK_PREFER_WRITER_NP)) {
+ if (prwlock->recurse > 0) {
+ prwlock->recurse--;
+ return (0);
+ }
+ }
prwlock->owner = NULL;
}
diff --git a/lib/libthr/thread/thr_rwlockattr.c b/lib/libthr/thread/thr_rwlockattr.c
index b47d167..23ea73e 100644
--- a/lib/libthr/thread/thr_rwlockattr.c
+++ b/lib/libthr/thread/thr_rwlockattr.c
@@ -36,8 +36,10 @@
__weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy);
__weak_reference(_pthread_rwlockattr_getpshared, pthread_rwlockattr_getpshared);
+__weak_reference(_pthread_rwlockattr_getkind_np, pthread_rwlockattr_getkind_np);
__weak_reference(_pthread_rwlockattr_init, pthread_rwlockattr_init);
__weak_reference(_pthread_rwlockattr_setpshared, pthread_rwlockattr_setpshared);
+__weak_reference(_pthread_rwlockattr_setkind_np, pthread_rwlockattr_setkind_np);
int
_pthread_rwlockattr_destroy(pthread_rwlockattr_t *rwlockattr)
@@ -81,6 +83,7 @@ _pthread_rwlockattr_init(pthread_rwlockattr_t *rwlockattr)
return(ENOMEM);
prwlockattr->pshared = PTHREAD_PROCESS_PRIVATE;
+ prwlockattr->kind = PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP;
*rwlockattr = prwlockattr;
return(0);
@@ -98,3 +101,21 @@ _pthread_rwlockattr_setpshared(pthread_rwlockattr_t *rwlockattr, int pshared)
return(0);
}
+int
+_pthread_rwlockattr_setkind_np(pthread_rwlockattr_t *attr, int kind)
+{
+ if (kind != PTHREAD_RWLOCK_PREFER_READER_NP &&
+ kind != PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP &&
+ kind != PTHREAD_RWLOCK_PREFER_WRITER_NP) {
+ return (EINVAL);
+ }
+ (*attr)->kind = kind;
+ return (0);
+}
+
+int
+_pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t *attr, int *kind)
+{
+ *kind = (*attr)->kind;
+ return (0);
+}
diff --git a/libexec/bootpd/bootptab.5 b/libexec/bootpd/bootptab.5
index c10d26b..bfc535c 100644
--- a/libexec/bootpd/bootptab.5
+++ b/libexec/bootpd/bootptab.5
@@ -388,7 +388,6 @@ hardware address.
An example
.Pa /etc/bootptab
file follows:
-.Pp
.Bd -literal -offset indent
# Sample bootptab file (domain=andrew.cmu.edu)
diff --git a/sbin/camcontrol/camcontrol.8 b/sbin/camcontrol/camcontrol.8
index f9c8eee..b85f81d 100644
--- a/sbin/camcontrol/camcontrol.8
+++ b/sbin/camcontrol/camcontrol.8
@@ -207,9 +207,6 @@ A device identifier can take one of three forms:
.Bl -tag -width 14n
.It deviceUNIT
Specify a device name and unit number combination, like "da5" or "cd3".
-Note that character device node names (e.g.\& /dev/da0) are
-.Em not
-allowed here.
.It bus:target
Specify a bus number and target id.
The bus number can be determined from
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index 9f26906..b92cc4c1 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -4605,15 +4605,7 @@ main(int argc, char **argv)
char name[30];
int rv;
- /*
- * First catch people who try to do things like:
- * camcontrol tur /dev/da0
- * camcontrol doesn't take device nodes as arguments.
- */
- if (argv[2][0] == '/') {
- warnx("%s is not a valid device identifier", argv[2]);
- errx(1, "please read the camcontrol(8) man page");
- } else if (isdigit(argv[2][0])) {
+ if (isdigit(argv[2][0])) {
/* device specified as bus:target[:lun] */
rv = parse_btl(argv[2], &bus, &target, &lun, &arglist);
if (rv < 2)
diff --git a/sbin/routed/routed.8 b/sbin/routed/routed.8
index c285ef3..570e20b 100644
--- a/sbin/routed/routed.8
+++ b/sbin/routed/routed.8
@@ -440,7 +440,6 @@ The
file is comprised of a series of lines, each in
one of the following two formats or consist of parameters described later.
Blank lines and lines starting with '#' are comments.
-.Pp
.Bd -ragged
.Cm net
.Ar Nname[/mask]
diff --git a/sbin/setkey/setkey.8 b/sbin/setkey/setkey.8
index c66860f..7103e1f 100644
--- a/sbin/setkey/setkey.8
+++ b/sbin/setkey/setkey.8
@@ -565,7 +565,6 @@ There are small, but important, differences in the syntax.
See
.Xr ipsec_set_policy 3
for details.
-.Pp
.El
.Pp
.\"
@@ -583,7 +582,6 @@ in the
of the
.Ar protocol
parameter:
-.Pp
.Bd -literal -offset indent
algorithm keylen (bits) comment
hmac-md5 128 ah: rfc2403
@@ -616,7 +614,6 @@ in the
of the
.Ar protocol
parameter:
-.Pp
.Bd -literal -offset indent
algorithm keylen (bits) comment
des-cbc 64 esp-old: rfc1829, esp: rfc2405
@@ -643,7 +640,6 @@ in the
of the
.Ar protocol
parameter:
-.Pp
.Bd -literal -offset indent
algorithm comment
deflate rfc2394
diff --git a/sbin/sunlabel/sunlabel.8 b/sbin/sunlabel/sunlabel.8
index 7e3d3f2..5fc815d 100644
--- a/sbin/sunlabel/sunlabel.8
+++ b/sbin/sunlabel/sunlabel.8
@@ -120,7 +120,6 @@ Options are listed in alphabetical order here.
Note that only those option combinations listed under
.Sx SYNOPSIS
are allowable.
-.Pp
.Bl -tag -width ".Fl b Ar bootpath"
.It Fl b Ar bootpath
Specify that
diff --git a/share/man/man4/lagg.4 b/share/man/man4/lagg.4
index a8604ac..1dd5142 100644
--- a/share/man/man4/lagg.4
+++ b/share/man/man4/lagg.4
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 8, 2010
+.Dd October 18, 2010
.Dt LAGG 4
.Os
.Sh NAME
@@ -73,14 +73,14 @@ The interface link state is used to validate if the port is active or
not.
.Bl -tag -width loadbalance
.It Ic failover
-Sends traffic only through the master port.
+Sends traffic only through the active port.
If the master port becomes unavailable,
the next active port is used.
The first interface added is the master port;
any interfaces added after that are used as failover devices.
.Pp
By default, received traffic is only accepted when they are received
-through the master port.
+through the active port.
This constraint can be relaxed by setting the
.Va net.link.lagg.failover_rx_all
.Xr sysctl 8
diff --git a/share/man/man4/man4.arm/mge.4 b/share/man/man4/man4.arm/mge.4
index adc90ca..a0f05bd 100644
--- a/share/man/man4/man4.arm/mge.4
+++ b/share/man/man4/man4.arm/mge.4
@@ -47,7 +47,6 @@ system-on-chip devices.
The
.Nm
driver supports the following media types:
-.Pp
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.It autoselect
Enable autoselection of the media type and options
@@ -62,7 +61,6 @@ Set 1000baseT operation
The
.Nm
driver supports the following media options:
-.Pp
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.It full-duplex
Set full duplex operation
diff --git a/share/man/man4/man4.i386/ep.4 b/share/man/man4/man4.i386/ep.4
index 3916754..446eb04 100644
--- a/share/man/man4/man4.i386/ep.4
+++ b/share/man/man4/man4.i386/ep.4
@@ -57,7 +57,6 @@ Parallel Tasking chipset.
.Pp
Various models of these cards come with a different assortment of
connectors:
-.Pp
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.It AUI/DIX
Standard 15 pin connector, also known as 10base5 (thick-net)
@@ -74,7 +73,6 @@ To override this, use the following media options with
or in your
.Pa /etc/rc.conf
file.
-.Pp
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.It 10base5/AUI
Use the AUI port.
diff --git a/share/man/man4/man4.i386/mse.4 b/share/man/man4/man4.i386/mse.4
index a5cb3f7..bea73e1 100644
--- a/share/man/man4/man4.i386/mse.4
+++ b/share/man/man4/man4.i386/mse.4
@@ -147,7 +147,6 @@ or in the User Configuration Menu at
the boot time
(see
.Xr boot 8 ) .
-.Pp
.Bl -tag -width MOUSE
.It bit 4..7 ACCELERATION
This flag controls the amount of acceleration effect.
diff --git a/share/man/man4/man4.powerpc/tsec.4 b/share/man/man4/man4.powerpc/tsec.4
index 6e535a5..84db70e 100644
--- a/share/man/man4/man4.powerpc/tsec.4
+++ b/share/man/man4/man4.powerpc/tsec.4
@@ -47,7 +47,6 @@ some of the Freescale system-on-chip devices.
The
.Nm
driver supports the following media types:
-.Pp
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.It autoselect
Enable autoselection of the media type and options
@@ -62,7 +61,6 @@ Set 1000baseT operation
The
.Nm
driver supports the following media options:
-.Pp
.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
.It full-duplex
Set full duplex operation
diff --git a/share/man/man4/nxge.4 b/share/man/man4/nxge.4
index 891ffad..4550535 100644
--- a/share/man/man4/nxge.4
+++ b/share/man/man4/nxge.4
@@ -49,7 +49,7 @@ The
.Nm
driver provides support for Neterion Xframe-I and Xframe-II adapters.
The driver supports TCP Segmentation Offload (TSO/LSO),
-Large Receive Offlaod (LRO), Jumbo Frames (5 buffer mode),
+Large Receive Offload (LRO), Jumbo Frames (5 buffer mode),
Header Separation (Rx 2 buffer mode), VLAN, and Promiscuous mode.
.Pp
For general information and support, please visit the Neterion support page
diff --git a/share/man/man5/freebsd-update.conf.5 b/share/man/man5/freebsd-update.conf.5
index d372102..653b055 100644
--- a/share/man/man5/freebsd-update.conf.5
+++ b/share/man/man5/freebsd-update.conf.5
@@ -47,7 +47,6 @@ Unless stated otherwise, specifying an option multiple times is an
error.
.Pp
The possible options and their meanings are as follows:
-.Pp
.Bl -tag -width ".Cm BackupKernelSymbolFiles"
.It Cm KeyPrint
The single parameter following this keyword is the SHA256 hash
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 2198a6f..261be4f 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1212,11 +1212,17 @@ MLINKS+=sysctl_ctx_init.9 sysctl_ctx_entry_add.9 \
sysctl_ctx_init.9 sysctl_ctx_free.9
MLINKS+=taskqueue.9 TASK_INIT.9 \
taskqueue.9 taskqueue_create.9 \
+ taskqueue.9 taskqueue_create_fast.9 \
taskqueue.9 TASKQUEUE_DECLARE.9 \
taskqueue.9 TASKQUEUE_DEFINE.9 \
+ taskqueue.9 TASKQUEUE_DEFINE_THREAD.9 \
+ taskqueue.9 taskqueue_drain.9 \
taskqueue.9 taskqueue_enqueue.9 \
- taskqueue.9 taskqueue_find.9 \
+ taskqueue.9 taskqueue_enqueue_fast.9 \
+ taskqueue.9 TASKQUEUE_FAST_DEFINE.9 \
+ taskqueue.9 TASKQUEUE_FAST_DEFINE_THREAD.9 \
taskqueue.9 taskqueue_free.9 \
+ taskqueue.9 taskqueue_member.9 \
taskqueue.9 taskqueue_run.9
MLINKS+=time.9 boottime.9 \
time.9 time_second.9 \
diff --git a/share/man/man9/vrele.9 b/share/man/man9/vrele.9
index 8d28d5e..0b9b736 100644
--- a/share/man/man9/vrele.9
+++ b/share/man/man9/vrele.9
@@ -59,7 +59,7 @@ The
.Fn vrele
function takes an unlocked vnode and returns with the vnode unlocked.
.Pp
-.The
+The
.Fn vput
function should be given a locked vnode as argument, the vnode is unlocked
after the function returned.
diff --git a/share/man/man9/zone.9 b/share/man/man9/zone.9
index 304b7f0..a2132b5 100644
--- a/share/man/man9/zone.9
+++ b/share/man/man9/zone.9
@@ -153,6 +153,13 @@ Items are released back to the zone from which they were allocated by
calling
.Fn uma_zfree
with a pointer to the zone and a pointer to the item.
+If
+.Fa item
+is
+.Dv NULL ,
+then
+.Fn uma_zfree
+does nothing.
.Pp
The variations
.Fn uma_zalloc_arg
diff --git a/sys/arm/mv/mv_sata.c b/sys/arm/mv/mv_sata.c
index 13ae1e0..277c837 100644
--- a/sys/arm/mv/mv_sata.c
+++ b/sys/arm/mv/mv_sata.c
@@ -710,7 +710,7 @@ sata_channel_status(device_t dev)
if ((icr & SATA_ICR_DEV(ch->unit)) || iecr) {
/* Disable EDMA before accessing SATA registers */
sata_edma_ctrl(dev, 0);
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
/* Ack device and error interrupt */
SATA_OUTL(sc, SATA_ICR, ~SATA_ICR_DEV(ch->unit));
diff --git a/sys/conf/files b/sys/conf/files
index c1bc03a..75f16e5 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -2453,6 +2453,7 @@ net80211/ieee80211_power.c optional wlan
net80211/ieee80211_proto.c optional wlan
net80211/ieee80211_radiotap.c optional wlan
net80211/ieee80211_ratectl.c optional wlan
+net80211/ieee80211_ratectl_none.c optional wlan
net80211/ieee80211_regdomain.c optional wlan
net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt
net80211/ieee80211_scan.c optional wlan
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index f9b981b..24982fe 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -66,10 +66,6 @@ __FBSDID("$FreeBSD$");
#include <dev/acpica/acpivar.h>
#include <dev/acpica/acpiio.h>
-#include "pci_if.h"
-#include <dev/pci/pcivar.h>
-#include <dev/pci/pci_private.h>
-
#include <vm/vm_param.h>
MALLOC_DEFINE(M_ACPIDEV, "acpidev", "ACPI devices");
@@ -133,8 +129,7 @@ static ACPI_STATUS acpi_device_scan_cb(ACPI_HANDLE h, UINT32 level,
void *context, void **retval);
static ACPI_STATUS acpi_device_scan_children(device_t bus, device_t dev,
int max_depth, acpi_scan_cb_t user_fn, void *arg);
-static int acpi_set_powerstate_method(device_t bus, device_t child,
- int state);
+static int acpi_set_powerstate(device_t child, int state);
static int acpi_isa_pnp_probe(device_t bus, device_t child,
struct isa_pnp_id *ids);
static void acpi_probe_children(device_t bus);
@@ -205,9 +200,6 @@ static device_method_t acpi_methods[] = {
DEVMETHOD(acpi_pwr_for_sleep, acpi_device_pwr_for_sleep),
DEVMETHOD(acpi_scan_children, acpi_device_scan_children),
- /* PCI emulation */
- DEVMETHOD(pci_set_powerstate, acpi_set_powerstate_method),
-
/* ISA emulation */
DEVMETHOD(isa_pnp_probe, acpi_isa_pnp_probe),
@@ -262,12 +254,6 @@ TUNABLE_INT("debug.acpi.interpreter_slack", &acpi_interpreter_slack);
SYSCTL_INT(_debug_acpi, OID_AUTO, interpreter_slack, CTLFLAG_RDTUN,
&acpi_interpreter_slack, 1, "Turn on interpreter slack mode.");
-/* Power devices off and on in suspend and resume. XXX Remove once tested. */
-static int acpi_do_powerstate = 1;
-TUNABLE_INT("debug.acpi.do_powerstate", &acpi_do_powerstate);
-SYSCTL_INT(_debug_acpi, OID_AUTO, do_powerstate, CTLFLAG_RW,
- &acpi_do_powerstate, 1, "Turn off devices when suspending.");
-
/* Reset system clock while resuming. XXX Remove once tested. */
static int acpi_reset_clock = 1;
TUNABLE_INT("debug.acpi.reset_clock", &acpi_reset_clock);
@@ -668,45 +654,43 @@ acpi_attach(device_t dev)
return_VALUE (error);
}
+static void
+acpi_set_power_children(device_t dev, int state)
+{
+ device_t child, parent;
+ device_t *devlist;
+ struct pci_devinfo *dinfo;
+ int dstate, i, numdevs;
+
+ if (device_get_children(dev, &devlist, &numdevs) != 0)
+ return;
+
+ /*
+ * Retrieve and set D-state for the sleep state if _SxD is present.
+ * Skip children who aren't attached since they are handled separately.
+ */
+ parent = device_get_parent(dev);
+ for (i = 0; i < numdevs; i++) {
+ child = devlist[i];
+ dinfo = device_get_ivars(child);
+ dstate = state;
+ if (device_is_attached(child) &&
+ acpi_device_pwr_for_sleep(parent, dev, &dstate) == 0)
+ acpi_set_powerstate(child, dstate);
+ }
+ free(devlist, M_TEMP);
+}
+
static int
acpi_suspend(device_t dev)
{
- device_t child, *devlist;
- int error, i, numdevs, pstate;
+ int error;
GIANT_REQUIRED;
- /* First give child devices a chance to suspend. */
error = bus_generic_suspend(dev);
- if (error)
- return (error);
-
- /*
- * Now, set them into the appropriate power state, usually D3. If the
- * device has an _SxD method for the next sleep state, use that power
- * state instead.
- */
- error = device_get_children(dev, &devlist, &numdevs);
- if (error)
- return (error);
- for (i = 0; i < numdevs; i++) {
- /* If the device is not attached, we've powered it down elsewhere. */
- child = devlist[i];
- if (!device_is_attached(child))
- continue;
-
- /*
- * Default to D3 for all sleep states. The _SxD method is optional
- * so set the powerstate even if it's absent.
- */
- pstate = PCI_POWERSTATE_D3;
- error = acpi_device_pwr_for_sleep(device_get_parent(child),
- child, &pstate);
- if ((error == 0 || error == ESRCH) && acpi_do_powerstate)
- pci_set_powerstate(child, pstate);
- }
- free(devlist, M_TEMP);
- error = 0;
+ if (error == 0)
+ acpi_set_power_children(dev, ACPI_STATE_D3);
return (error);
}
@@ -714,28 +698,10 @@ acpi_suspend(device_t dev)
static int
acpi_resume(device_t dev)
{
- ACPI_HANDLE handle;
- int i, numdevs, error;
- device_t child, *devlist;
GIANT_REQUIRED;
- /*
- * Put all devices in D0 before resuming them. Call _S0D on each one
- * since some systems expect this.
- */
- error = device_get_children(dev, &devlist, &numdevs);
- if (error)
- return (error);
- for (i = 0; i < numdevs; i++) {
- child = devlist[i];
- handle = acpi_get_handle(child);
- if (handle)
- AcpiEvaluateObject(handle, "_S0D", NULL, NULL);
- if (device_is_attached(child) && acpi_do_powerstate)
- pci_set_powerstate(child, PCI_POWERSTATE_D0);
- }
- free(devlist, M_TEMP);
+ acpi_set_power_children(dev, ACPI_STATE_D0);
return (bus_generic_resume(dev));
}
@@ -811,7 +777,7 @@ static void
acpi_probe_nomatch(device_t bus, device_t child)
{
#ifdef ACPI_ENABLE_POWERDOWN_NODRIVER
- pci_set_powerstate(child, PCI_POWERSTATE_D3);
+ acpi_set_powerstate(child, ACPI_STATE_D3);
#endif
}
@@ -833,9 +799,9 @@ acpi_driver_added(device_t dev, driver_t *driver)
child = devlist[i];
if (device_get_state(child) == DS_NOTPRESENT) {
#ifdef ACPI_ENABLE_POWERDOWN_NODRIVER
- pci_set_powerstate(child, PCI_POWERSTATE_D0);
+ acpi_set_powerstate(child, ACPI_STATE_D0);
if (device_probe_and_attach(child) != 0)
- pci_set_powerstate(child, PCI_POWERSTATE_D3);
+ acpi_set_powerstate(child, ACPI_STATE_D3);
#else
device_probe_and_attach(child);
#endif
@@ -1401,9 +1367,7 @@ acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate)
ACPI_HANDLE handle;
ACPI_STATUS status;
char sxd[8];
- int error;
- sc = device_get_softc(bus);
handle = acpi_get_handle(dev);
/*
@@ -1412,7 +1376,7 @@ acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate)
* set to D3 and it appears that such legacy devices may
* need special handling in their drivers.
*/
- if (handle == NULL ||
+ if (dstate == NULL || handle == NULL ||
acpi_MatchHid(handle, "PNP0500") ||
acpi_MatchHid(handle, "PNP0501") ||
acpi_MatchHid(handle, "PNP0502") ||
@@ -1421,28 +1385,19 @@ acpi_device_pwr_for_sleep(device_t bus, device_t dev, int *dstate)
return (ENXIO);
/*
- * Override next state with the value from _SxD, if present. If no
- * dstate argument was provided, don't fetch the return value.
+ * Override next state with the value from _SxD, if present.
+ * Note illegal _S0D is evaluated because some systems expect this.
*/
+ sc = device_get_softc(bus);
snprintf(sxd, sizeof(sxd), "_S%dD", sc->acpi_sstate);
- if (dstate)
- status = acpi_GetInteger(handle, sxd, dstate);
- else
- status = AcpiEvaluateObject(handle, sxd, NULL, NULL);
-
- switch (status) {
- case AE_OK:
- error = 0;
- break;
- case AE_NOT_FOUND:
- error = ESRCH;
- break;
- default:
- error = ENXIO;
- break;
+ status = acpi_GetInteger(handle, sxd, dstate);
+ if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+ device_printf(dev, "failed to get %s on %s: %s\n", sxd,
+ acpi_name(handle), AcpiFormatException(status));
+ return (ENXIO);
}
- return (error);
+ return (0);
}
/* Callback arg for our implementation of walking the namespace. */
@@ -1524,13 +1479,11 @@ acpi_device_scan_children(device_t bus, device_t dev, int max_depth,
* device power states since it's close enough to ACPI.
*/
static int
-acpi_set_powerstate_method(device_t bus, device_t child, int state)
+acpi_set_powerstate(device_t child, int state)
{
ACPI_HANDLE h;
ACPI_STATUS status;
- int error;
- error = 0;
h = acpi_get_handle(child);
if (state < ACPI_STATE_D0 || state > ACPI_D_STATES_MAX)
return (EINVAL);
@@ -1539,12 +1492,16 @@ acpi_set_powerstate_method(device_t bus, device_t child, int state)
/* Ignore errors if the power methods aren't present. */
status = acpi_pwr_switch_consumer(h, state);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND
- && status != AE_BAD_PARAMETER)
- device_printf(bus, "failed to set ACPI power state D%d on %s: %s\n",
- state, acpi_name(h), AcpiFormatException(status));
+ if (ACPI_SUCCESS(status)) {
+ if (bootverbose)
+ device_printf(child, "set ACPI power state D%d on %s\n",
+ state, acpi_name(h));
+ } else if (status != AE_NOT_FOUND)
+ device_printf(child,
+ "failed to set ACPI power state D%d on %s: %s\n", state,
+ acpi_name(h), AcpiFormatException(status));
- return (error);
+ return (0);
}
static int
diff --git a/sys/dev/acpica/acpi_if.m b/sys/dev/acpica/acpi_if.m
index 36fad85..f0a68e3 100644
--- a/sys/dev/acpica/acpi_if.m
+++ b/sys/dev/acpica/acpi_if.m
@@ -123,8 +123,7 @@ METHOD ACPI_STATUS evaluate_object {
#
# int *dstate: if successful, contains the highest valid sleep state
#
-# Returns: 0 on success, ESRCH if device has no special state, or
-# some other error value.
+# Returns: 0 on success or some other error value.
#
METHOD int pwr_for_sleep {
device_t bus;
diff --git a/sys/dev/acpica/acpi_pci.c b/sys/dev/acpica/acpi_pci.c
index 9cf064e..bf7cf2e 100644
--- a/sys/dev/acpica/acpi_pci.c
+++ b/sys/dev/acpica/acpi_pci.c
@@ -186,11 +186,15 @@ acpi_pci_set_powerstate_method(device_t dev, device_t child, int state)
}
h = acpi_get_handle(child);
status = acpi_pwr_switch_consumer(h, state);
- if (ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+ if (ACPI_SUCCESS(status)) {
+ if (bootverbose)
+ device_printf(dev, "set ACPI power state D%d on %s\n",
+ state, acpi_name(h));
+ } else if (status != AE_NOT_FOUND)
device_printf(dev,
- "Failed to set ACPI power state D%d on %s: %s\n",
+ "failed to set ACPI power state D%d on %s: %s\n",
state, acpi_name(h), AcpiFormatException(status));
- if (old_state > state)
+ if (old_state > state && pci_do_power_resume)
error = pci_set_powerstate_method(dev, child, state);
out:
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 8c0ea9d..f40dcc2 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -83,6 +83,7 @@ static void bswap(int8_t *, int);
static void btrim(int8_t *, int);
static void bpack(int8_t *, int8_t *, int);
static void ata_interrupt_locked(void *data);
+static void ata_periodic_poll(void *data);
/* global vars */
MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer");
@@ -173,6 +174,7 @@ ata_attach(device_t dev)
ch->curr[i] = ch->user[i];
}
#endif
+ callout_init(&ch->poll_callout, 1);
/* reset the controller HW, the channel and device(s) */
while (ATA_LOCKING(dev, ATA_LF_LOCK) != ch->unit)
@@ -200,6 +202,8 @@ ata_attach(device_t dev)
device_printf(dev, "unable to setup interrupt\n");
return error;
}
+ if (ch->flags & ATA_PERIODIC_POLL)
+ callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch);
#ifndef ATA_CAM
/* probe and attach devices on this channel unless we are in early boot */
@@ -246,6 +250,8 @@ err2:
err1:
bus_release_resource(dev, SYS_RES_IRQ, rid, ch->r_irq);
mtx_unlock(&ch->state_mtx);
+ if (ch->flags & ATA_PERIODIC_POLL)
+ callout_drain(&ch->poll_callout);
return (error);
#endif
}
@@ -267,6 +273,8 @@ ata_detach(device_t dev)
mtx_lock(&ch->state_mtx);
ch->state |= ATA_STALL_QUEUE;
mtx_unlock(&ch->state_mtx);
+ if (ch->flags & ATA_PERIODIC_POLL)
+ callout_drain(&ch->poll_callout);
#ifndef ATA_CAM
/* detach & delete all children */
@@ -454,6 +462,8 @@ ata_suspend(device_t dev)
if (!dev || !(ch = device_get_softc(dev)))
return ENXIO;
+ if (ch->flags & ATA_PERIODIC_POLL)
+ callout_drain(&ch->poll_callout);
#ifdef ATA_CAM
mtx_lock(&ch->state_mtx);
xpt_freeze_simq(ch->sim, 1);
@@ -498,6 +508,8 @@ ata_resume(device_t dev)
/* kick off requests on the queue */
ata_start(dev);
#endif
+ if (ch->flags & ATA_PERIODIC_POLL)
+ callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch);
return error;
}
@@ -564,6 +576,15 @@ ata_interrupt_locked(void *data)
#endif
}
+static void
+ata_periodic_poll(void *data)
+{
+ struct ata_channel *ch = (struct ata_channel *)data;
+
+ callout_reset(&ch->poll_callout, hz, ata_periodic_poll, ch);
+ ata_interrupt(ch);
+}
+
void
ata_print_cable(device_t dev, u_int8_t *who)
{
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 0f09a1f..17a28c0 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -114,13 +114,6 @@
#define ATA_SS_IPM_PARTIAL 0x00000200
#define ATA_SS_IPM_SLUMBER 0x00000600
-#define ATA_SS_CONWELL_MASK \
- (ATA_SS_DET_MASK|ATA_SS_SPD_MASK|ATA_SS_IPM_MASK)
-#define ATA_SS_CONWELL_GEN1 \
- (ATA_SS_DET_PHY_ONLINE|ATA_SS_SPD_GEN1|ATA_SS_IPM_ACTIVE)
-#define ATA_SS_CONWELL_GEN2 \
- (ATA_SS_DET_PHY_ONLINE|ATA_SS_SPD_GEN2|ATA_SS_IPM_ACTIVE)
-
#define ATA_SERROR 14
#define ATA_SE_DATA_CORRECTED 0x00000001
#define ATA_SE_COMM_CORRECTED 0x00000002
@@ -567,6 +560,7 @@ struct ata_channel {
#define ATA_DMA_BEFORE_CMD 0x100
#define ATA_KNOWN_PRESENCE 0x200
#define ATA_STATUS_IS_LONG 0x400
+#define ATA_PERIODIC_POLL 0x800
int pm_level; /* power management level */
int devices; /* what is present */
@@ -593,6 +587,7 @@ struct ata_channel {
struct ata_cam_device user[16]; /* User-specified settings */
struct ata_cam_device curr[16]; /* Current settings */
#endif
+ struct callout poll_callout; /* Periodic status poll. */
};
/* disk bay/enclosure related */
@@ -666,7 +661,7 @@ void ata_dmainit(device_t);
void ata_dmafini(device_t dev);
/* ata-sata.c: */
-void ata_sata_phy_check_events(device_t dev);
+void ata_sata_phy_check_events(device_t dev, int port);
int ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val);
int ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val);
int ata_sata_phy_reset(device_t dev, int port, int quick);
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index c847e90..cf579f8 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -615,6 +615,7 @@ ata_pcichannel_attach(device_t dev)
return (0);
ch->attached = 1;
+ ch->dev = dev;
ch->unit = (intptr_t)device_get_ivars(dev);
resource_int_value(device_get_name(dev),
diff --git a/sys/dev/ata/ata-sata.c b/sys/dev/ata/ata-sata.c
index d4c52fd..d3df7ce 100644
--- a/sys/dev/ata/ata-sata.c
+++ b/sys/dev/ata/ata-sata.c
@@ -48,20 +48,23 @@ __FBSDID("$FreeBSD$");
#include <ata_if.h>
void
-ata_sata_phy_check_events(device_t dev)
+ata_sata_phy_check_events(device_t dev, int port)
{
struct ata_channel *ch = device_get_softc(dev);
- u_int32_t error = ATA_IDX_INL(ch, ATA_SERROR);
+ u_int32_t error, status;
- /* clear error bits/interrupt */
- ATA_IDX_OUTL(ch, ATA_SERROR, error);
+ ata_sata_scr_read(ch, port, ATA_SERROR, &error);
+ /* Clear set error bits/interrupt. */
+ if (error)
+ ata_sata_scr_write(ch, port, ATA_SERROR, error);
/* if we have a connection event deal with it */
if ((error & ATA_SE_PHY_CHANGED) && (ch->pm_level == 0)) {
if (bootverbose) {
- u_int32_t status = ATA_IDX_INL(ch, ATA_SSTATUS);
- if (((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1) ||
- ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)) {
+ ata_sata_scr_read(ch, port, ATA_SSTATUS, &status);
+ if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
+ ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+ ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE)) {
device_printf(dev, "CONNECT requested\n");
} else
device_printf(dev, "DISCONNECT requested\n");
@@ -73,69 +76,51 @@ ata_sata_phy_check_events(device_t dev)
int
ata_sata_scr_read(struct ata_channel *ch, int port, int reg, uint32_t *val)
{
- int r;
- if (port < 0) {
+ if (ch->hw.pm_read != NULL)
+ return (ch->hw.pm_read(ch->dev, port, reg, val));
+ if (ch->r_io[reg].res) {
*val = ATA_IDX_INL(ch, reg);
return (0);
- } else {
- switch (reg) {
- case ATA_SSTATUS:
- r = 0;
- break;
- case ATA_SERROR:
- r = 1;
- break;
- case ATA_SCONTROL:
- r = 2;
- break;
- default:
- return (EINVAL);
- }
- return (ch->hw.pm_read(ch->dev, port, r, val));
}
+ return (-1);
}
int
ata_sata_scr_write(struct ata_channel *ch, int port, int reg, uint32_t val)
{
- int r;
- if (port < 0) {
+ if (ch->hw.pm_write != NULL)
+ return (ch->hw.pm_write(ch->dev, port, reg, val));
+ if (ch->r_io[reg].res) {
ATA_IDX_OUTL(ch, reg, val);
return (0);
- } else {
- switch (reg) {
- case ATA_SERROR:
- r = 1;
- break;
- case ATA_SCONTROL:
- r = 2;
- break;
- default:
- return (EINVAL);
- }
- return (ch->hw.pm_write(ch->dev, port, r, val));
}
+ return (-1);
}
static int
-ata_sata_connect(struct ata_channel *ch, int port)
+ata_sata_connect(struct ata_channel *ch, int port, int quick)
{
u_int32_t status;
- int timeout;
+ int timeout, t;
/* wait up to 1 second for "connect well" */
- for (timeout = 0; timeout < 100 ; timeout++) {
+ timeout = (quick == 2) ? 0 : 100;
+ t = 0;
+ while (1) {
if (ata_sata_scr_read(ch, port, ATA_SSTATUS, &status))
return (0);
- if ((status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN1 ||
- (status & ATA_SS_CONWELL_MASK) == ATA_SS_CONWELL_GEN2)
+ if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
+ ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
+ ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE))
+ break;
+ if (++t > timeout)
break;
ata_udelay(10000);
}
- if (timeout >= 100) {
- if (bootverbose) {
+ if (bootverbose) {
+ if (t > timeout) {
if (port < 0) {
device_printf(ch->dev, "SATA connect timeout status=%08x\n",
status);
@@ -143,23 +128,19 @@ ata_sata_connect(struct ata_channel *ch, int port)
device_printf(ch->dev, "p%d: SATA connect timeout status=%08x\n",
port, status);
}
- }
- return 0;
- }
- if (bootverbose) {
- if (port < 0) {
+ } else if (port < 0) {
device_printf(ch->dev, "SATA connect time=%dms status=%08x\n",
- timeout * 10, status);
+ t * 10, status);
} else {
device_printf(ch->dev, "p%d: SATA connect time=%dms status=%08x\n",
- port, timeout * 10, status);
+ port, t * 10, status);
}
}
/* clear SATA error register */
ata_sata_scr_write(ch, port, ATA_SERROR, 0xffffffff);
- return 1;
+ return ((t > timeout) ? 0 : 1);
}
int
@@ -173,7 +154,7 @@ ata_sata_phy_reset(device_t dev, int port, int quick)
if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
return (0);
if ((val & ATA_SC_DET_MASK) == ATA_SC_DET_IDLE)
- return ata_sata_connect(ch, port);
+ return ata_sata_connect(ch, port, quick);
}
if (bootverbose) {
@@ -203,7 +184,7 @@ ata_sata_phy_reset(device_t dev, int port, int quick)
if (ata_sata_scr_read(ch, port, ATA_SCONTROL, &val))
return (0);
if ((val & ATA_SC_DET_MASK) == 0)
- return ata_sata_connect(ch, port);
+ return ata_sata_connect(ch, port, 0);
}
}
return 0;
diff --git a/sys/dev/ata/chipsets/ata-ahci.c b/sys/dev/ata/chipsets/ata-ahci.c
index 7496f6b..4a240d7 100644
--- a/sys/dev/ata/chipsets/ata-ahci.c
+++ b/sys/dev/ata/chipsets/ata-ahci.c
@@ -403,7 +403,7 @@ ata_ahci_status(device_t dev)
/* do we have any PHY events ? */
if (istatus & (ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC))
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
/* do we have a potentially hanging engine to take care of? */
/* XXX SOS what todo on NCQ */
@@ -623,6 +623,25 @@ ata_ahci_pm_read(device_t dev, int port, int reg, u_int32_t *result)
(struct ata_ahci_cmd_tab *)(ch->dma.work + ATA_AHCI_CT_OFFSET);
u_int8_t *fis = ch->dma.work + ATA_AHCI_FB_OFFSET + 0x40;
+ if (port < 0) {
+ *result = ATA_IDX_INL(ch, reg);
+ return (0);
+ }
+ if (port < ATA_PM) {
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
bzero(ctp->cfis, 64);
ctp->cfis[0] = 0x27; /* host to device */
ctp->cfis[1] = 0x8f; /* command FIS to PM port */
@@ -649,6 +668,25 @@ ata_ahci_pm_write(device_t dev, int port, int reg, u_int32_t value)
(struct ata_ahci_cmd_tab *)(ch->dma.work + ATA_AHCI_CT_OFFSET);
int offset = ch->unit << 7;
+ if (port < 0) {
+ ATA_IDX_OUTL(ch, reg, value);
+ return (0);
+ }
+ if (port < ATA_PM) {
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
bzero(ctp->cfis, 64);
ctp->cfis[0] = 0x27; /* host to device */
ctp->cfis[1] = 0x8f; /* command FIS to PM port */
diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c
index 0f47bc7..ba602aa 100644
--- a/sys/dev/ata/chipsets/ata-intel.c
+++ b/sys/dev/ata/chipsets/ata-intel.c
@@ -59,6 +59,15 @@ static int ata_intel_old_setmode(device_t dev, int target, int mode);
static int ata_intel_new_setmode(device_t dev, int target, int mode);
static int ata_intel_sch_setmode(device_t dev, int target, int mode);
static int ata_intel_sata_getrev(device_t dev, int target);
+static int ata_intel_sata_status(device_t dev);
+static int ata_intel_sata_cscr_read(device_t dev, int port,
+ int reg, u_int32_t *result);
+static int ata_intel_sata_sidpr_read(device_t dev, int port,
+ int reg, u_int32_t *result);
+static int ata_intel_sata_cscr_write(device_t dev, int port,
+ int reg, u_int32_t result);
+static int ata_intel_sata_sidpr_write(device_t dev, int port,
+ int reg, u_int32_t result);
static int ata_intel_31244_ch_attach(device_t dev);
static int ata_intel_31244_ch_detach(device_t dev);
static int ata_intel_31244_status(device_t dev);
@@ -67,7 +76,9 @@ static void ata_intel_31244_reset(device_t dev);
/* misc defines */
#define INTEL_AHCI 1
-
+#define INTEL_ICH5 2
+#define INTEL_6CH 4
+#define INTEL_6CH2 8
/*
* Intel chipset support functions
@@ -92,74 +103,74 @@ ata_intel_probe(device_t dev)
{ ATA_I82801DB, 0, 0, 2, ATA_UDMA5, "ICH4" },
{ ATA_I82801DB_1, 0, 0, 2, ATA_UDMA5, "ICH4" },
{ ATA_I82801EB, 0, 0, 2, ATA_UDMA5, "ICH5" },
- { ATA_I82801EB_S1, 0, 0, 2, ATA_SA150, "ICH5" },
- { ATA_I82801EB_R1, 0, 0, 2, ATA_SA150, "ICH5" },
+ { ATA_I82801EB_S1, 0, INTEL_ICH5, 2, ATA_SA150, "ICH5" },
+ { ATA_I82801EB_R1, 0, INTEL_ICH5, 2, ATA_SA150, "ICH5" },
{ ATA_I6300ESB, 0, 0, 2, ATA_UDMA5, "6300ESB" },
- { ATA_I6300ESB_S1, 0, 0, 2, ATA_SA150, "6300ESB" },
- { ATA_I6300ESB_R1, 0, 0, 2, ATA_SA150, "6300ESB" },
+ { ATA_I6300ESB_S1, 0, INTEL_ICH5, 2, ATA_SA150, "6300ESB" },
+ { ATA_I6300ESB_R1, 0, INTEL_ICH5, 2, ATA_SA150, "6300ESB" },
{ ATA_I82801FB, 0, 0, 2, ATA_UDMA5, "ICH6" },
{ ATA_I82801FB_S1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6" },
{ ATA_I82801FB_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6" },
{ ATA_I82801FBM, 0, INTEL_AHCI, 0, ATA_SA150, "ICH6M" },
{ ATA_I82801GB, 0, 0, 1, ATA_UDMA5, "ICH7" },
- { ATA_I82801GB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" },
- { ATA_I82801GB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" },
+ { ATA_I82801GB_S1, 0, 0, 0, ATA_SA300, "ICH7" },
+ { ATA_I82801GB_R1, 0, 0, 0, ATA_SA300, "ICH7" },
{ ATA_I82801GB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH7" },
- { ATA_I82801GBM_S1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" },
- { ATA_I82801GBM_R1, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" },
+ { ATA_I82801GBM_S1, 0, 0, 0, ATA_SA150, "ICH7M" },
+ { ATA_I82801GBM_R1, 0, 0, 0, ATA_SA150, "ICH7M" },
{ ATA_I82801GBM_AH, 0, INTEL_AHCI, 0, ATA_SA150, "ICH7M" },
{ ATA_I63XXESB2, 0, 0, 1, ATA_UDMA5, "63XXESB2" },
- { ATA_I63XXESB2_S1, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" },
+ { ATA_I63XXESB2_S1, 0, 0, 0, ATA_SA300, "63XXESB2" },
{ ATA_I63XXESB2_S2, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" },
{ ATA_I63XXESB2_R1, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" },
{ ATA_I63XXESB2_R2, 0, INTEL_AHCI, 0, ATA_SA300, "63XXESB2" },
- { ATA_I82801HB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" },
- { ATA_I82801HB_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" },
+ { ATA_I82801HB_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH8" },
+ { ATA_I82801HB_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH8" },
{ ATA_I82801HB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" },
{ ATA_I82801HB_AH4, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" },
{ ATA_I82801HB_AH6, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8" },
{ ATA_I82801HBM, 0, 0, 1, ATA_UDMA5, "ICH8M" },
- { ATA_I82801HBM_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8M" },
+ { ATA_I82801HBM_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH8M" },
{ ATA_I82801HBM_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8M" },
{ ATA_I82801HBM_S3, 0, INTEL_AHCI, 0, ATA_SA300, "ICH8M" },
- { ATA_I82801IB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" },
- { ATA_I82801IB_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" },
+ { ATA_I82801IB_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH9" },
+ { ATA_I82801IB_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH9" },
{ ATA_I82801IB_AH2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" },
{ ATA_I82801IB_AH4, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" },
{ ATA_I82801IB_AH6, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" },
{ ATA_I82801IB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH9" },
- { ATA_I82801JIB_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
+ { ATA_I82801JIB_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JIB_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JIB_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
- { ATA_I82801JIB_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
- { ATA_I82801JD_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
+ { ATA_I82801JIB_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH10" },
+ { ATA_I82801JD_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JD_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JD_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
- { ATA_I82801JD_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
- { ATA_I82801JI_S1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
+ { ATA_I82801JD_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH10" },
+ { ATA_I82801JI_S1, 0, INTEL_6CH, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JI_AH, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
{ ATA_I82801JI_R1, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
- { ATA_I82801JI_S2, 0, INTEL_AHCI, 0, ATA_SA300, "ICH10" },
- { ATA_5Series_S1, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
- { ATA_5Series_S2, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
+ { ATA_I82801JI_S2, 0, INTEL_6CH2, 0, ATA_SA300, "ICH10" },
+ { ATA_5Series_S1, 0, INTEL_6CH, 0, ATA_SA300, "5 Series/3400 Series PCH" },
+ { ATA_5Series_S2, 0, INTEL_6CH2, 0, ATA_SA300, "5 Series/3400 Series PCH" },
{ ATA_5Series_AH1, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
{ ATA_5Series_AH2, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
{ ATA_5Series_R1, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
- { ATA_5Series_S3, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
- { ATA_5Series_S4, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
+ { ATA_5Series_S3, 0, INTEL_6CH2, 0, ATA_SA300, "5 Series/3400 Series PCH" },
+ { ATA_5Series_S4, 0, INTEL_6CH, 0, ATA_SA300, "5 Series/3400 Series PCH" },
{ ATA_5Series_AH3, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
{ ATA_5Series_R2, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
- { ATA_5Series_S5, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
- { ATA_5Series_S6, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
+ { ATA_5Series_S5, 0, INTEL_6CH2, 0, ATA_SA300, "5 Series/3400 Series PCH" },
+ { ATA_5Series_S6, 0, INTEL_6CH, 0, ATA_SA300, "5 Series/3400 Series PCH" },
{ ATA_5Series_AH4, 0, INTEL_AHCI, 0, ATA_SA300, "5 Series/3400 Series PCH" },
- { ATA_CPT_S1, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
- { ATA_CPT_S2, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
+ { ATA_CPT_S1, 0, INTEL_6CH, 0, ATA_SA300, "Cougar Point" },
+ { ATA_CPT_S2, 0, INTEL_6CH, 0, ATA_SA300, "Cougar Point" },
{ ATA_CPT_AH1, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
{ ATA_CPT_AH2, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
{ ATA_CPT_R1, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
{ ATA_CPT_R2, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
- { ATA_CPT_S3, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
- { ATA_CPT_S4, 0, INTEL_AHCI, 0, ATA_SA300, "Cougar Point" },
+ { ATA_CPT_S3, 0, INTEL_6CH2, 0, ATA_SA300, "Cougar Point" },
+ { ATA_CPT_S4, 0, INTEL_6CH2, 0, ATA_SA300, "Cougar Point" },
{ ATA_I31244, 0, 0, 2, ATA_SA150, "31244" },
{ ATA_ISCH, 0, 0, 1, ATA_UDMA5, "SCH" },
{ 0, 0, 0, 0, 0, 0}};
@@ -183,6 +194,8 @@ ata_intel_chipinit(device_t dev)
if (ata_setup_interrupt(dev, ata_generic_intr))
return ENXIO;
+ ctlr->chipset_data = NULL;
+
/* good old PIIX needs special treatment (not implemented) */
if (ctlr->chip->chipid == ATA_I82371FB) {
ctlr->setmode = ata_intel_old_setmode;
@@ -233,7 +246,7 @@ ata_intel_chipinit(device_t dev)
* if we have AHCI capability and AHCI or RAID mode enabled
* in BIOS we try for AHCI mode
*/
- if ((ctlr->chip->cfg1 == INTEL_AHCI) &&
+ if ((ctlr->chip->cfg1 & INTEL_AHCI) &&
(pci_read_config(dev, 0x90, 1) & 0xc0) &&
(ata_ahci_chipinit(dev) != ENXIO))
return 0;
@@ -242,7 +255,8 @@ ata_intel_chipinit(device_t dev)
ctlr->r_type2 = SYS_RES_IOPORT;
ctlr->r_rid2 = PCIR_BAR(5);
if ((ctlr->r_res2 = bus_alloc_resource_any(dev, ctlr->r_type2,
- &ctlr->r_rid2, RF_ACTIVE)))
+ &ctlr->r_rid2, RF_ACTIVE))
+ || (ctlr->chip->cfg1 & INTEL_ICH5))
ctlr->getrev = ata_intel_sata_getrev;
ctlr->setmode = ata_sata_setmode;
}
@@ -252,63 +266,142 @@ ata_intel_chipinit(device_t dev)
static int
ata_intel_ch_attach(device_t dev)
{
- struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev));
- struct ata_channel *ch = device_get_softc(dev);
-
- /* setup the usual register normal pci style */
- if (ata_pci_ch_attach(dev))
- return ENXIO;
-
- /* if r_res2 is valid it points to SATA interface registers */
- if (ctlr->r_res2) {
- ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;
- ch->r_io[ATA_IDX_ADDR].offset = 0x00;
- ch->r_io[ATA_IDX_DATA].res = ctlr->r_res2;
- ch->r_io[ATA_IDX_DATA].offset = 0x04;
- }
+ struct ata_pci_controller *ctlr;
+ struct ata_channel *ch;
+ u_char *smap;
+ u_int map;
+
+ /* setup the usual register normal pci style */
+ if (ata_pci_ch_attach(dev))
+ return (ENXIO);
+
+ ctlr = device_get_softc(device_get_parent(dev));
+ ch = device_get_softc(dev);
+
+ /* if r_res2 is valid it points to SATA interface registers */
+ if (ctlr->r_res2) {
+ ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;
+ ch->r_io[ATA_IDX_ADDR].offset = 0x00;
+ ch->r_io[ATA_IDX_DATA].res = ctlr->r_res2;
+ ch->r_io[ATA_IDX_DATA].offset = 0x04;
+ }
- ch->flags |= ATA_ALWAYS_DMASTAT;
- if (ctlr->chip->max_dma >= ATA_SA150) {
- if (ctlr->chip->cfg1 == 0 &&
- (pci_read_config(device_get_parent(dev), 0x90, 1) & 0x04) == 0)
- ch->flags |= ATA_NO_SLAVE;
- ch->flags |= ATA_SATA;
- } else if (ctlr->chip->chipid != ATA_ISCH)
- ch->flags |= ATA_CHECKS_CABLE;
- return 0;
+ ch->flags |= ATA_ALWAYS_DMASTAT;
+ if (ctlr->chip->max_dma >= ATA_SA150) {
+ smap = (u_char *)&ctlr->chipset_data + ch->unit * 2;
+ map = pci_read_config(device_get_parent(dev), 0x90, 1);
+ if (ctlr->chip->cfg1 & INTEL_ICH5) {
+ map &= 0x07;
+ if ((map & 0x04) == 0) {
+ ch->flags |= ATA_SATA;
+ ch->flags |= ATA_NO_SLAVE;
+ smap[0] = (map & 0x01) ^ ch->unit;
+ smap[1] = 0;
+ } else if ((map & 0x02) == 0 && ch->unit == 0) {
+ ch->flags |= ATA_SATA;
+ smap[0] = (map & 0x01) ? 1 : 0;
+ smap[1] = (map & 0x01) ? 0 : 1;
+ } else if ((map & 0x02) != 0 && ch->unit == 1) {
+ ch->flags |= ATA_SATA;
+ smap[0] = (map & 0x01) ? 1 : 0;
+ smap[1] = (map & 0x01) ? 0 : 1;
+ }
+ } else if (ctlr->chip->cfg1 & INTEL_6CH2) {
+ ch->flags |= ATA_SATA;
+ ch->flags |= ATA_NO_SLAVE;
+ smap[0] = (ch->unit == 0) ? 4 : 5;
+ smap[1] = 0;
+ } else {
+ map &= 0x03;
+ if (map == 0x00) {
+ ch->flags |= ATA_SATA;
+ smap[ch->unit] = (ch->unit == 0) ? 0x20 : 0x31;
+ smap[0] = (ch->unit == 0) ? 0 : 1;
+ smap[1] = (ch->unit == 0) ? 2 : 3;
+ } else if (map == 0x02 && ch->unit == 0) {
+ ch->flags |= ATA_SATA;
+ smap[0] = 0;
+ smap[1] = 2;
+ } else if (map == 0x01 && ch->unit == 1) {
+ ch->flags |= ATA_SATA;
+ smap[0] = 1;
+ smap[1] = 3;
+ }
+ }
+ if (ch->flags & ATA_SATA) {
+ if ((ctlr->chip->cfg1 & INTEL_ICH5)) {
+ ch->flags |= ATA_PERIODIC_POLL;
+ ch->hw.status = ata_intel_sata_status;
+ ch->hw.pm_read = ata_intel_sata_cscr_read;
+ ch->hw.pm_write = ata_intel_sata_cscr_write;
+ } else if (ctlr->r_res2) {
+ ch->flags |= ATA_PERIODIC_POLL;
+ ch->hw.status = ata_intel_sata_status;
+ ch->hw.pm_read = ata_intel_sata_sidpr_read;
+ ch->hw.pm_write = ata_intel_sata_sidpr_write;
+ }
+ if (ch->hw.pm_write != NULL) {
+ ata_sata_scr_write(ch, 0,
+ ATA_SERROR, 0xffffffff);
+ if ((ch->flags & ATA_NO_SLAVE) == 0) {
+ ata_sata_scr_write(ch, 1,
+ ATA_SERROR, 0xffffffff);
+ }
+ }
+ } else
+ ctlr->setmode = ata_intel_new_setmode;
+ } else if (ctlr->chip->chipid != ATA_ISCH)
+ ch->flags |= ATA_CHECKS_CABLE;
+ return (0);
}
static void
ata_intel_reset(device_t dev)
{
- device_t parent = device_get_parent(dev);
- struct ata_pci_controller *ctlr = device_get_softc(parent);
- struct ata_channel *ch = device_get_softc(dev);
- int mask, timeout;
+ device_t parent = device_get_parent(dev);
+ struct ata_pci_controller *ctlr = device_get_softc(parent);
+ struct ata_channel *ch = device_get_softc(dev);
+ int mask, pmask, timeout, devs;
+ u_char *smap;
+
+ /* In combined mode, skip SATA stuff for PATA channel. */
+ if ((ch->flags & ATA_SATA) == 0)
+ return (ata_generic_reset(dev));
+
+ /* Do hard-reset on respective SATA ports. */
+ smap = (u_char *)&ctlr->chipset_data + ch->unit * 2;
+ mask = 1 << smap[0];
+ if ((ch->flags & ATA_NO_SLAVE) == 0)
+ mask |= (1 << smap[1]);
+ pci_write_config(parent, 0x92,
+ pci_read_config(parent, 0x92, 2) & ~mask, 2);
+ DELAY(10);
+ pci_write_config(parent, 0x92,
+ pci_read_config(parent, 0x92, 2) | mask, 2);
+
+ /* Wait up to 1 sec for "connect well". */
+ if (ctlr->chip->cfg1 & (INTEL_6CH | INTEL_6CH2))
+ pmask = mask << 8;
+ else
+ pmask = mask << 4;
+ for (timeout = 0; timeout < 100 ; timeout++) {
+ if (((pci_read_config(parent, 0x92, 2) & pmask) == pmask) &&
+ (ATA_IDX_INB(ch, ATA_STATUS) != 0xff))
+ break;
+ ata_udelay(10000);
+ }
- /* ICH6 & ICH7 in compat mode has 4 SATA ports as master/slave on 2 ch's */
- if (ctlr->chip->cfg1) {
- mask = (0x0005 << ch->unit);
- }
- else {
- /* ICH5 in compat mode has SATA ports as master/slave on 1 channel */
- if (pci_read_config(parent, 0x90, 1) & 0x04)
- mask = 0x0003;
+ /* If any device found, do soft-reset. */
+ if (ch->hw.pm_read != NULL) {
+ devs = ata_sata_phy_reset(dev, 0, 2);
+ if ((ch->flags & ATA_NO_SLAVE) == 0)
+ devs += ata_sata_phy_reset(dev, 1, 2);
+ } else
+ devs = 1;
+ if (devs)
+ ata_generic_reset(dev);
else
- mask = (0x0001 << ch->unit);
- }
- pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) & ~mask, 2);
- DELAY(10);
- pci_write_config(parent, 0x92, pci_read_config(parent, 0x92, 2) | mask, 2);
-
- /* wait up to 1 sec for "connect well" */
- for (timeout = 0; timeout < 100 ; timeout++) {
- if (((pci_read_config(parent, 0x92, 2) & (mask << 4)) == (mask << 4)) &&
- (ATA_IDX_INB(ch, ATA_STATUS) != 0xff))
- break;
- ata_udelay(10000);
- }
- ata_generic_reset(dev);
+ ch->devices = 0;
}
static int
@@ -339,6 +432,10 @@ ata_intel_new_setmode(device_t dev, int target, int mode)
u_int8_t timings[] = { 0x00, 0x00, 0x10, 0x21, 0x23, 0x00, 0x21, 0x23 };
u_int8_t utimings[] = { 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02 };
+ /* In combined mode, skip PATA stuff for SATA channel. */
+ if (ch->flags & ATA_SATA)
+ return (ata_sata_setmode(dev, target, mode));
+
mode = min(mode, ctlr->chip->max_dma);
if (ata_dma_check_80pin && mode > ATA_UDMA2 &&
!(reg54 & (0x10 << devno))) {
@@ -421,12 +518,145 @@ static int
ata_intel_sata_getrev(device_t dev, int target)
{
struct ata_channel *ch = device_get_softc(dev);
- int devno = (ch->unit << 1) + target;
+ uint32_t status;
- /* set ATA_SSTATUS register offset */
- ATA_IDX_OUTL(ch, ATA_IDX_ADDR, devno * 0x100);
- /* query SATA STATUS for the speed */
- return ((ATA_IDX_INL(ch, ATA_IDX_DATA) & 0x0f0) >> 4);
+ if (ata_sata_scr_read(ch, target, ATA_SSTATUS, &status) == 0)
+ return ((status & 0x0f0) >> 4);
+ return (0xff);
+}
+
+static int
+ata_intel_sata_status(device_t dev)
+{
+ struct ata_channel *ch = device_get_softc(dev);
+
+ ata_sata_phy_check_events(dev, 0);
+ if ((ch->flags & ATA_NO_SLAVE) == 0)
+ ata_sata_phy_check_events(dev, 1);
+
+ return ata_pci_status(dev);
+}
+
+static int
+ata_intel_sata_cscr_read(device_t dev, int port, int reg, u_int32_t *result)
+{
+ struct ata_pci_controller *ctlr;
+ struct ata_channel *ch;
+ device_t parent;
+ u_char *smap;
+
+ parent = device_get_parent(dev);
+ ctlr = device_get_softc(parent);
+ ch = device_get_softc(dev);
+ smap = (u_char *)&ctlr->chipset_data + ch->unit * 2;
+ port = (port == 1) ? 1 : 0;
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ pci_write_config(parent, 0xa0,
+ 0x50 + smap[port] * 0x10 + reg * 4, 4);
+ *result = pci_read_config(parent, 0xa4, 4);
+ return (0);
+}
+
+static int
+ata_intel_sata_sidpr_read(device_t dev, int port, int reg, u_int32_t *result)
+{
+ struct ata_pci_controller *ctlr;
+ struct ata_channel *ch;
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ ctlr = device_get_softc(parent);
+ ch = device_get_softc(dev);
+ port = (port == 1) ? 1 : 0;
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SCONTROL:
+ reg = 1;
+ break;
+ case ATA_SERROR:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ ATA_IDX_OUTL(ch, ATA_IDX_ADDR, ((ch->unit * 2 + port) << 8) + reg);
+ *result = ATA_IDX_INL(ch, ATA_IDX_DATA);
+ return (0);
+}
+
+static int
+ata_intel_sata_cscr_write(device_t dev, int port, int reg, u_int32_t value)
+{
+ struct ata_pci_controller *ctlr;
+ struct ata_channel *ch;
+ device_t parent;
+ u_char *smap;
+
+ parent = device_get_parent(dev);
+ ctlr = device_get_softc(parent);
+ ch = device_get_softc(dev);
+ smap = (u_char *)&ctlr->chipset_data + ch->unit * 2;
+ port = (port == 1) ? 1 : 0;
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ pci_write_config(parent, 0xa0,
+ 0x50 + smap[port] * 0x10 + reg * 4, 4);
+ pci_write_config(parent, 0xa4, value, 4);
+ return (0);
+}
+
+static int
+ata_intel_sata_sidpr_write(device_t dev, int port, int reg, u_int32_t value)
+{
+ struct ata_pci_controller *ctlr;
+ struct ata_channel *ch;
+ device_t parent;
+
+ parent = device_get_parent(dev);
+ ctlr = device_get_softc(parent);
+ ch = device_get_softc(dev);
+ port = (port == 1) ? 1 : 0;
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SCONTROL:
+ reg = 1;
+ break;
+ case ATA_SERROR:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ ATA_IDX_OUTL(ch, ATA_IDX_ADDR, ((ch->unit * 2 + port) << 8) + reg);
+ ATA_IDX_OUTL(ch, ATA_IDX_DATA, value);
+ return (0);
}
static int
@@ -492,7 +722,7 @@ static int
ata_intel_31244_status(device_t dev)
{
/* do we have any PHY events ? */
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
/* any drive action to take care of ? */
return ata_pci_status(dev);
diff --git a/sys/dev/ata/chipsets/ata-marvell.c b/sys/dev/ata/chipsets/ata-marvell.c
index 371d951..eb6414e 100644
--- a/sys/dev/ata/chipsets/ata-marvell.c
+++ b/sys/dev/ata/chipsets/ata-marvell.c
@@ -374,7 +374,7 @@ ata_marvell_edma_status(device_t dev)
ATA_OUTL(ctlr->r_res1, 0x02008 + ATA_MV_EDMA_BASE(ch), 0x0);
/* do we have any PHY events ? */
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
}
/* do we have any device action ? */
diff --git a/sys/dev/ata/chipsets/ata-nvidia.c b/sys/dev/ata/chipsets/ata-nvidia.c
index 344e5a4..b1da6f0 100644
--- a/sys/dev/ata/chipsets/ata-nvidia.c
+++ b/sys/dev/ata/chipsets/ata-nvidia.c
@@ -281,7 +281,7 @@ ata_nvidia_status(device_t dev)
/* do we have any PHY events ? */
if (istatus & (0x0c << shift))
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
/* clear interrupt(s) */
if (ctlr->chip->cfg1 & NVQ)
diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c
index 8a7bceb..622352b 100644
--- a/sys/dev/ata/chipsets/ata-promise.c
+++ b/sys/dev/ata/chipsets/ata-promise.c
@@ -830,6 +830,25 @@ ata_promise_mio_pm_read(device_t dev, int port, int reg, u_int32_t *result)
struct ata_channel *ch = device_get_softc(dev);
int timeout = 0;
+ if (port < 0) {
+ *result = ATA_IDX_INL(ch, reg);
+ return (0);
+ }
+ if (port < ATA_PM) {
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
/* set portmultiplier port */
ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);
@@ -862,6 +881,25 @@ ata_promise_mio_pm_write(device_t dev, int port, int reg, u_int32_t value)
struct ata_channel *ch = device_get_softc(dev);
int timeout = 0;
+ if (port < 0) {
+ ATA_IDX_OUTL(ch, reg, value);
+ return (0);
+ }
+ if (port < ATA_PM) {
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
/* set portmultiplier port */
ATA_OUTB(ctlr->r_res2, 0x4e8 + (ch->unit << 8), 0x0f);
diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c
index f9b90f6..fa7619c 100644
--- a/sys/dev/ata/chipsets/ata-siliconimage.c
+++ b/sys/dev/ata/chipsets/ata-siliconimage.c
@@ -354,7 +354,7 @@ ata_sii_status(device_t dev)
/* do we have any PHY events ? */
if (ctlr->chip->max_dma >= ATA_SA150 &&
(ATA_INL(ctlr->r_res2, 0x10 + offset0) & 0x00000010))
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
if (ATA_INL(ctlr->r_res2, 0xa0 + offset1) & 0x00000800)
return ata_pci_status(dev);
@@ -510,7 +510,7 @@ ata_siiprb_status(device_t dev)
u_int32_t istatus = ATA_INL(ctlr->r_res2, 0x1008 + offset);
/* do we have any PHY events ? */
- ata_sata_phy_check_events(dev);
+ ata_sata_phy_check_events(dev, -1);
/* clear interrupt(s) */
ATA_OUTL(ctlr->r_res2, 0x1008 + offset, istatus);
@@ -700,6 +700,25 @@ ata_siiprb_pm_read(device_t dev, int port, int reg, u_int32_t *result)
struct ata_siiprb_command *prb = (struct ata_siiprb_command *)ch->dma.work;
int offset = ch->unit * 0x2000;
+ if (port < 0) {
+ *result = ATA_IDX_INL(ch, reg);
+ return (0);
+ }
+ if (port < ATA_PM) {
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
bzero(prb, sizeof(struct ata_siiprb_command));
prb->fis[0] = 0x27; /* host to device */
prb->fis[1] = 0x8f; /* command FIS to PM port */
@@ -724,6 +743,25 @@ ata_siiprb_pm_write(device_t dev, int port, int reg, u_int32_t value)
struct ata_siiprb_command *prb = (struct ata_siiprb_command *)ch->dma.work;
int offset = ch->unit * 0x2000;
+ if (port < 0) {
+ ATA_IDX_OUTL(ch, reg, value);
+ return (0);
+ }
+ if (port < ATA_PM) {
+ switch (reg) {
+ case ATA_SSTATUS:
+ reg = 0;
+ break;
+ case ATA_SERROR:
+ reg = 1;
+ break;
+ case ATA_SCONTROL:
+ reg = 2;
+ break;
+ default:
+ return (EINVAL);
+ }
+ }
bzero(prb, sizeof(struct ata_siiprb_command));
prb->fis[0] = 0x27; /* host to device */
prb->fis[1] = 0x8f; /* command FIS to PM port */
diff --git a/sys/dev/ata/chipsets/ata-via.c b/sys/dev/ata/chipsets/ata-via.c
index 8d87f31..284a892 100644
--- a/sys/dev/ata/chipsets/ata-via.c
+++ b/sys/dev/ata/chipsets/ata-via.c
@@ -56,6 +56,7 @@ static int ata_via_chipinit(device_t dev);
static int ata_via_ch_attach(device_t dev);
static int ata_via_ch_detach(device_t dev);
static void ata_via_reset(device_t dev);
+static int ata_via_status(device_t dev);
static int ata_via_old_setmode(device_t dev, int target, int mode);
static void ata_via_southbridge_fixup(device_t dev);
static int ata_via_new_setmode(device_t dev, int target, int mode);
@@ -249,11 +250,13 @@ ata_via_ch_attach(device_t dev)
ch->r_io[ATA_SERROR].offset = 0x04 + (ch->unit << ctlr->chip->cfg1);
ch->r_io[ATA_SCONTROL].res = ctlr->r_res2;
ch->r_io[ATA_SCONTROL].offset = 0x08 + (ch->unit << ctlr->chip->cfg1);
+ ch->hw.status = ata_via_status;
ch->flags |= ATA_NO_SLAVE;
ch->flags |= ATA_SATA;
+ ch->flags |= ATA_PERIODIC_POLL;
+
+ ata_sata_scr_write(ch, -1, ATA_SERROR, 0xffffffff);
- /* XXX SOS PHY hotplug handling missing in VIA chip ?? */
- /* XXX SOS unknown how to enable PHY state change interrupt */
return 0;
}
@@ -299,6 +302,14 @@ ata_via_reset(device_t dev)
}
static int
+ata_via_status(device_t dev)
+{
+
+ ata_sata_phy_check_events(dev, -1);
+ return (ata_pci_status(dev));
+}
+
+static int
ata_via_new_setmode(device_t dev, int target, int mode)
{
device_t parent = device_get_parent(dev);
diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c
index edfc047..07a1a42 100644
--- a/sys/dev/firewire/fwohci.c
+++ b/sys/dev/firewire/fwohci.c
@@ -1971,8 +1971,8 @@ fwohci_intr_dma(struct fwohci_softc *sc, uint32_t stat, int count)
OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCTIMER);
#endif
OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST);
- device_printf(fc->dev, "too many cycle lost, "
- "no cycle master presents?\n");
+ device_printf(fc->dev, "too many cycles lost, "
+ "no cycle master present?\n");
}
}
if (stat & OHCI_INT_DMA_ATRQ) {
diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c
index bde2d5b..763ed74 100644
--- a/sys/dev/if_ndis/if_ndis.c
+++ b/sys/dev/if_ndis/if_ndis.c
@@ -1644,10 +1644,6 @@ ndis_linksts_done(adapter)
default:
break;
}
-
- /* Notify possible listners of interface change. */
-
- rt_ifmsg(ifp);
}
static void
diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c
index 47aa751..6c3484e 100644
--- a/sys/dev/md/md.c
+++ b/sys/dev/md/md.c
@@ -909,18 +909,26 @@ mdcreate_vnode(struct md_s *sc, struct md_ioctl *mdio, struct thread *td)
{
struct vattr vattr;
struct nameidata nd;
+ char *fname;
int error, flags, vfslocked;
- error = copyinstr(mdio->md_file, sc->file, sizeof(sc->file), NULL);
- if (error != 0)
- return (error);
- flags = FREAD|FWRITE;
/*
- * If the user specified that this is a read only device, unset the
- * FWRITE mask before trying to open the backing store.
+ * Kernel-originated requests must have the filename appended
+ * to the mdio structure to protect against malicious software.
+ */
+ fname = mdio->md_file;
+ if ((void *)fname != (void *)(mdio + 1)) {
+ error = copyinstr(fname, sc->file, sizeof(sc->file), NULL);
+ if (error != 0)
+ return (error);
+ } else
+ strlcpy(sc->file, fname, sizeof(sc->file));
+
+ /*
+ * If the user specified that this is a read only device, don't
+ * set the FWRITE mask before trying to open the backing store.
*/
- if ((mdio->md_options & MD_READONLY) != 0)
- flags &= ~FWRITE;
+ flags = FREAD | ((mdio->md_options & MD_READONLY) ? 0 : FWRITE);
NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, sc->file, td);
error = vn_open(&nd, &flags, 0, NULL);
if (error != 0)
diff --git a/sys/dev/mii/brgphy.c b/sys/dev/mii/brgphy.c
index cf88d20..9f915df 100644
--- a/sys/dev/mii/brgphy.c
+++ b/sys/dev/mii/brgphy.c
@@ -280,6 +280,10 @@ brgphy_attach(device_t dev)
brgphy_reset(sc);
+ /* Read the PHY's capabilities. */
+ sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ if (sc->mii_capabilities & BMSR_EXTSTAT)
+ sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
device_printf(dev, " ");
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 450cb3e..d1b211a 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -2911,15 +2911,12 @@ pci_set_power_children(device_t dev, device_t *devlist, int numdevs,
struct pci_devinfo *dinfo;
int dstate, i;
- if (!pci_do_power_resume)
- return;
-
/*
* Set the device to the given state. If the firmware suggests
* a different power state, use it instead. If power management
* is not present, the firmware is responsible for managing
* device power. Skip children who aren't attached since they
- * are handled separately. Only manage type 0 devices for now.
+ * are handled separately.
*/
pcib = device_get_parent(dev);
for (i = 0; i < numdevs; i++) {
@@ -2927,8 +2924,6 @@ pci_set_power_children(device_t dev, device_t *devlist, int numdevs,
dinfo = device_get_ivars(child);
dstate = state;
if (device_is_attached(child) &&
- (dinfo->cfg.hdrtype & PCIM_HDRTYPE) ==
- PCIM_HDRTYPE_NORMAL &&
PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0)
pci_set_powerstate(child, dstate);
}
@@ -2976,7 +2971,9 @@ pci_resume(device_t dev)
*/
if ((error = device_get_children(dev, &devlist, &numdevs)) != 0)
return (error);
- pci_set_power_children(dev, devlist, numdevs, PCI_POWERSTATE_D0);
+ if (pci_do_power_resume)
+ pci_set_power_children(dev, devlist, numdevs,
+ PCI_POWERSTATE_D0);
/* Now the device is powered up, restore its config space. */
for (i = 0; i < numdevs; i++) {
diff --git a/sys/fs/msdosfs/msdosfs_lookup.c b/sys/fs/msdosfs/msdosfs_lookup.c
index 999125d..51b6dc8 100644
--- a/sys/fs/msdosfs/msdosfs_lookup.c
+++ b/sys/fs/msdosfs/msdosfs_lookup.c
@@ -594,10 +594,15 @@ msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff,
vfs_unbusy(mp);
if (error == 0)
*rvp = DETOV(rdp);
- vn_lock(vp, ltype | LK_RETRY);
+ if (*rvp != vp)
+ vn_lock(vp, ltype | LK_RETRY);
if (vp->v_iflag & VI_DOOMED) {
- if (error == 0)
- vput(*rvp);
+ if (error == 0) {
+ if (*rvp == vp)
+ vunref(*rvp);
+ else
+ vput(*rvp);
+ }
error = ENOENT;
}
return (error);
diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
index 7d76be0..8ca1c43 100644
--- a/sys/fs/nfsclient/nfs_clnode.c
+++ b/sys/fs/nfsclient/nfs_clnode.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
@@ -53,12 +54,13 @@ __FBSDID("$FreeBSD$");
#include <fs/nfsclient/nfsmount.h>
#include <fs/nfsclient/nfs.h>
+#include <nfs/nfs_lock.h>
+
extern struct vop_vector newnfs_vnodeops;
extern struct buf_ops buf_ops_newnfs;
MALLOC_DECLARE(M_NEWNFSREQ);
uma_zone_t newnfsnode_zone;
-vop_reclaim_t *ncl_reclaim_p = NULL;
void
ncl_nhinit(void)
@@ -238,8 +240,8 @@ ncl_reclaim(struct vop_reclaim_args *ap)
* If the NLM is running, give it a chance to abort pending
* locks.
*/
- if (ncl_reclaim_p)
- ncl_reclaim_p(ap);
+ if (nfs_reclaim_p != NULL)
+ nfs_reclaim_p(ap);
/*
* Destroy the vm object and flush associated pages.
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index b2cd92b..d7245ee 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -96,10 +96,13 @@ SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_DELAY,
static void nfs_sec_name(char *, int *);
static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
- struct nfs_args *argp, struct ucred *, struct thread *);
+ struct nfs_args *argp, const char *, struct ucred *,
+ struct thread *);
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, u_char *, u_char *, u_char *,
struct vnode **, struct ucred *, struct thread *, int);
+static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
+ struct sockaddr_storage *, int *, off_t *);
static vfs_mount_t nfs_mount;
static vfs_cmount_t nfs_cmount;
static vfs_unmount_t nfs_unmount;
@@ -518,10 +521,11 @@ nfs_sec_name(char *sec, int *flagsp)
static void
nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
- struct ucred *cred, struct thread *td)
+ const char *hostname, struct ucred *cred, struct thread *td)
{
int s;
int adjsock;
+ char *p;
s = splnet();
@@ -659,6 +663,14 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
nmp->nm_sotype = argp->sotype;
nmp->nm_soproto = argp->proto;
}
+
+ if (hostname != NULL) {
+ strlcpy(nmp->nm_hostname, hostname,
+ sizeof(nmp->nm_hostname));
+ p = strchr(nmp->nm_hostname, ':');
+ if (p != NULL)
+ *p = '\0';
+ }
}
static const char *nfs_opts[] = { "from",
@@ -933,7 +945,7 @@ nfs_mount(struct mount *mp)
NFSMNT_INTEGRITY |
NFSMNT_PRIVACY |
NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
- nfs_decode_args(mp, nmp, &args, td->td_ucred, td);
+ nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
goto out;
}
@@ -1110,13 +1122,14 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
nmp->nm_sockreq.nr_cred = crhold(cred);
mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
mp->mnt_data = nmp;
+ nmp->nm_getinfo = nfs_getnlminfo;
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
nmp->nm_negnametimeo = negnametimeo;
- nfs_decode_args(mp, nmp, argp, cred, td);
+ nfs_decode_args(mp, nmp, argp, hst, cred, td);
/*
* V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
@@ -1447,3 +1460,26 @@ nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
return (0);
}
+/*
+ * Extract the information needed by the nlm from the nfs vnode.
+ */
+static void
+nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
+ struct sockaddr_storage *sp, int *is_v3p, off_t *sizep)
+{
+ struct nfsmount *nmp;
+ struct nfsnode *np = VTONFS(vp);
+
+ nmp = VFSTONFS(vp->v_mount);
+ if (fhlenp != NULL)
+ *fhlenp = (size_t)np->n_fhp->nfh_len;
+ if (fhp != NULL)
+ bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
+ if (sp != NULL)
+ bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
+ if (is_v3p != NULL)
+ *is_v3p = NFS_ISV3(vp);
+ if (sizep != NULL)
+ *sizep = np->n_size;
+}
+
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 8f1ec27..b02c4bf 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
extern struct nfsstats newnfsstats;
MALLOC_DECLARE(M_NEWNFSREQ);
-vop_advlock_t *ncl_advlock_p = NULL;
/*
* Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
@@ -2937,8 +2936,8 @@ nfs_advlock(struct vop_advlock_args *ap)
VOP_UNLOCK(vp, 0);
error = lf_advlock(ap, &(vp->v_lockf), size);
} else {
- if (ncl_advlock_p)
- error = ncl_advlock_p(ap);
+ if (nfs_advlock_p != NULL)
+ error = nfs_advlock_p(ap);
else {
VOP_UNLOCK(vp, 0);
error = ENOLCK;
diff --git a/sys/fs/nfsclient/nfsmount.h b/sys/fs/nfsclient/nfsmount.h
index 9fd9331..5bc69f8 100644
--- a/sys/fs/nfsclient/nfsmount.h
+++ b/sys/fs/nfsclient/nfsmount.h
@@ -35,22 +35,19 @@
#ifndef _NFSCLIENT_NFSMOUNT_H_
#define _NFSCLIENT_NFSMOUNT_H_
+#include <nfs/nfs_mountcommon.h>
+
/*
* Mount structure.
* One allocated on every NFS mount.
* Holds NFS specific information for mount.
*/
struct nfsmount {
- struct mtx nm_mtx;
- int nm_flag; /* Flags for soft/hard... */
- int nm_state; /* Internal state flags */
- struct mount *nm_mountp; /* Vfs structure for this filesystem */
+ struct nfsmount_common nm_com; /* Common fields for nlm */
int nm_numgrps; /* Max. size of groupslist */
u_char nm_fh[NFSX_FHMAX]; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
struct nfssockreq nm_sockreq; /* Socket Info */
- int nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */
- int nm_retry; /* Max retries */
int nm_timeouts; /* Request timeouts */
int nm_rsize; /* Max size of read rpc */
int nm_wsize; /* Max size of write rpc */
@@ -89,6 +86,14 @@ struct nfsmount {
#define nm_soproto nm_sockreq.nr_soproto
#define nm_client nm_sockreq.nr_client
#define nm_krbname nm_name
+#define nm_mtx nm_com.nmcom_mtx
+#define nm_flag nm_com.nmcom_flag
+#define nm_state nm_com.nmcom_state
+#define nm_mountp nm_com.nmcom_mountp
+#define nm_timeo nm_com.nmcom_timeo
+#define nm_retry nm_com.nmcom_retry
+#define nm_hostname nm_com.nmcom_hostname
+#define nm_getinfo nm_com.nmcom_getinfo
#define NFSMNT_DIRPATH(m) (&((m)->nm_name[(m)->nm_krbnamelen + 1]))
#define NFSMNT_SRVKRBNAME(m) \
diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c
index 173e326..e4cbbe3 100644
--- a/sys/geom/geom_dev.c
+++ b/sys/geom/geom_dev.c
@@ -126,8 +126,16 @@ g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
error = g_attach(cp, pp);
KASSERT(error == 0,
("g_dev_taste(%s) failed to g_attach, err=%d", pp->name, error));
- dev = make_dev(&g_dev_cdevsw, 0,
- UID_ROOT, GID_OPERATOR, 0640, "%s", gp->name);
+ error = make_dev_p(MAKEDEV_CHECKNAME | MAKEDEV_WAITOK, &dev,
+ &g_dev_cdevsw, NULL, UID_ROOT, GID_OPERATOR, 0640, "%s", gp->name);
+ if (error != 0) {
+ printf("%s: make_dev_p() failed (gp->name=%s, error=%d)\n",
+ __func__, gp->name, error);
+ g_detach(cp);
+ g_destroy_consumer(cp);
+ g_destroy_geom(gp);
+ return (NULL);
+ }
if (pp->flags & G_PF_CANDELETE)
dev->si_flags |= SI_CANDELETE;
dev->si_iosize_max = MAXPHYS;
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index 09c8603..0da0075 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -699,8 +699,8 @@ kern_setrlimit(td, which, limp)
if (limp->rlim_max > maxssiz)
limp->rlim_max = maxssiz;
oldssiz = *alimp;
- if (td->td_proc->p_sysent->sv_fixlimit != NULL)
- td->td_proc->p_sysent->sv_fixlimit(&oldssiz,
+ if (p->p_sysent->sv_fixlimit != NULL)
+ p->p_sysent->sv_fixlimit(&oldssiz,
RLIMIT_STACK);
break;
@@ -722,8 +722,8 @@ kern_setrlimit(td, which, limp)
limp->rlim_max = 1;
break;
}
- if (td->td_proc->p_sysent->sv_fixlimit != NULL)
- td->td_proc->p_sysent->sv_fixlimit(limp, which);
+ if (p->p_sysent->sv_fixlimit != NULL)
+ p->p_sysent->sv_fixlimit(limp, which);
*alimp = *limp;
p->p_limit = newlim;
PROC_UNLOCK(p);
diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c
index 0f14623..c20a1c6 100644
--- a/sys/kern/kern_shutdown.c
+++ b/sys/kern/kern_shutdown.c
@@ -133,7 +133,6 @@ static struct dumperinfo dumper; /* our selected dumper */
static struct pcb dumppcb; /* Registers. */
static lwpid_t dumptid; /* Thread ID. */
-static void boot(int) __dead2;
static void poweroff_wait(void *, int);
static void shutdown_halt(void *junk, int howto);
static void shutdown_panic(void *junk, int howto);
@@ -173,7 +172,7 @@ reboot(struct thread *td, struct reboot_args *uap)
error = priv_check(td, PRIV_REBOOT);
if (error == 0) {
mtx_lock(&Giant);
- boot(uap->opt);
+ kern_reboot(uap->opt);
mtx_unlock(&Giant);
}
return (error);
@@ -197,7 +196,7 @@ shutdown_nice(int howto)
PROC_UNLOCK(initproc);
} else {
/* No init(8) running, so simply reboot */
- boot(RB_NOSYNC);
+ kern_reboot(RB_NOSYNC);
}
return;
}
@@ -269,8 +268,8 @@ isbufbusy(struct buf *bp)
/*
* Shutdown the system cleanly to prepare for reboot, halt, or power off.
*/
-static void
-boot(int howto)
+void
+kern_reboot(int howto)
{
static int first_buf_printf = 1;
@@ -283,7 +282,7 @@ boot(int howto)
thread_lock(curthread);
sched_bind(curthread, 0);
thread_unlock(curthread);
- KASSERT(PCPU_GET(cpuid) == 0, ("boot: not running on cpu 0"));
+ KASSERT(PCPU_GET(cpuid) == 0, ("%s: not running on cpu 0", __func__));
#endif
/* We're in the process of rebooting. */
rebooting = 1;
@@ -589,7 +588,7 @@ panic(const char *fmt, ...)
if (!sync_on_panic)
bootopt |= RB_NOSYNC;
critical_exit();
- boot(bootopt);
+ kern_reboot(bootopt);
}
/*
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 5b0fd00..83cbc60 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1424,15 +1424,17 @@ vfs_filteropt(struct vfsoptlist *opts, const char **legal)
continue;
snprintf(errmsg, sizeof(errmsg),
"mount option <%s> is unknown", p);
- printf("%s\n", errmsg);
ret = EINVAL;
}
if (ret != 0) {
TAILQ_FOREACH(opt, opts, link) {
if (strcmp(opt->name, "errmsg") == 0) {
strncpy((char *)opt->value, errmsg, opt->len);
+ break;
}
}
+ if (opt == NULL)
+ printf("%s\n", errmsg);
}
return (ret);
}
diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c
index 8685547..07c2988 100644
--- a/sys/kern/vfs_mountroot.c
+++ b/sys/kern/vfs_mountroot.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2010 Marcel Moolenaar
* Copyright (c) 1999-2004 Poul-Henning Kamp
* Copyright (c) 1999 Michael Smith
* Copyright (c) 1989, 1993
@@ -34,6 +35,8 @@
* SUCH DAMAGE.
*/
+#include "opt_rootdevname.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -44,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/libkern.h>
#include <sys/malloc.h>
+#include <sys/mdioctl.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@@ -51,6 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/filedesc.h>
#include <sys/reboot.h>
+#include <sys/stat.h>
#include <sys/syscallsubr.h>
#include <sys/sysproto.h>
#include <sys/sx.h>
@@ -58,25 +63,9 @@ __FBSDID("$FreeBSD$");
#include <sys/sysent.h>
#include <sys/systm.h>
#include <sys/vnode.h>
-#include <vm/uma.h>
#include <geom/geom.h>
-#include <machine/stdarg.h>
-
-#include "opt_rootdevname.h"
-
-#define ROOTNAME "root_device"
-
-static int vfs_mountroot_ask(void);
-static int vfs_mountroot_try(const char *mountfrom, const char *options);
-
-/*
- * The vnode of the system's root (/ in the filesystem, without chroot
- * active.)
- */
-struct vnode *rootvnode;
-
/*
* The root filesystem is detailed in the kernel environment variable
* vfs.root.mountfrom, which is expected to be in the general format
@@ -96,21 +85,16 @@ struct vnode *rootvnode;
* by nmount() in the kernel.
*/
+static int parse_mount(char **);
+static struct mntarg *parse_mountroot_options(struct mntarg *, const char *);
+
/*
- * The root specifiers we will try if RB_CDROM is specified.
+ * The vnode of the system's root (/ in the filesystem, without chroot
+ * active.)
*/
-static char *cdrom_rootdevnames[] = {
- "cd9660:cd0",
- "cd9660:acd0",
- NULL
-};
+struct vnode *rootvnode;
-/* legacy find-root code */
-char *rootdevnames[2] = {NULL, NULL};
-#ifndef ROOTDEVNAME
-# define ROOTDEVNAME NULL
-#endif
-static const char *ctrootdevname = ROOTDEVNAME;
+char *rootdevnames[2] = {NULL, NULL};
struct root_hold_token {
const char *who;
@@ -120,8 +104,21 @@ struct root_hold_token {
static LIST_HEAD(, root_hold_token) root_holds =
LIST_HEAD_INITIALIZER(root_holds);
+enum action {
+ A_CONTINUE,
+ A_PANIC,
+ A_REBOOT,
+ A_RETRY
+};
+
+static enum action root_mount_onfail = A_CONTINUE;
+
+static int root_mount_mddev;
static int root_mount_complete;
+/* By default wait up to 3 seconds for devices to appear. */
+static int root_mount_timeout = 3;
+
struct root_hold_token *
root_mount_hold(const char *identifier)
{
@@ -151,52 +148,6 @@ root_mount_rel(struct root_hold_token *h)
free(h, M_DEVBUF);
}
-static void
-root_mount_prepare(void)
-{
- struct root_hold_token *h;
- struct timeval lastfail;
- int curfail = 0;
-
- for (;;) {
- DROP_GIANT();
- g_waitidle();
- PICKUP_GIANT();
- mtx_lock(&mountlist_mtx);
- if (LIST_EMPTY(&root_holds)) {
- mtx_unlock(&mountlist_mtx);
- break;
- }
- if (ppsratecheck(&lastfail, &curfail, 1)) {
- printf("Root mount waiting for:");
- LIST_FOREACH(h, &root_holds, list)
- printf(" %s", h->who);
- printf("\n");
- }
- msleep(&root_holds, &mountlist_mtx, PZERO | PDROP, "roothold",
- hz);
- }
-}
-
-static void
-root_mount_done(void)
-{
-
- /* Keep prison0's root in sync with the global rootvnode. */
- mtx_lock(&prison0.pr_mtx);
- prison0.pr_root = rootvnode;
- vref(prison0.pr_root);
- mtx_unlock(&prison0.pr_mtx);
- /*
- * Use a mutex to prevent the wakeup being missed and waiting for
- * an extra 1 second sleep.
- */
- mtx_lock(&mountlist_mtx);
- root_mount_complete = 1;
- wakeup(&root_mount_complete);
- mtx_unlock(&mountlist_mtx);
-}
-
int
root_mounted(void)
{
@@ -251,26 +202,27 @@ set_rootvnode(void)
EVENTHANDLER_INVOKE(mountroot);
}
-static void
-devfs_first(void)
+static int
+vfs_mountroot_devfs(struct thread *td, struct mount **mpp)
{
- struct thread *td = curthread;
struct vfsoptlist *opts;
struct vfsconf *vfsp;
- struct mount *mp = NULL;
+ struct mount *mp;
int error;
+ *mpp = NULL;
+
vfsp = vfs_byname("devfs");
KASSERT(vfsp != NULL, ("Could not find devfs by name"));
if (vfsp == NULL)
- return;
+ return (ENOENT);
mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred);
error = VFS_MOUNT(mp);
KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error));
if (error)
- return;
+ return (error);
opts = malloc(sizeof(struct vfsoptlist), M_MOUNT, M_WAITOK);
TAILQ_INIT(opts);
@@ -280,170 +232,764 @@ devfs_first(void)
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
mtx_unlock(&mountlist_mtx);
+ *mpp = mp;
set_rootvnode();
error = kern_symlink(td, "/", "dev", UIO_SYSSPACE);
if (error)
printf("kern_symlink /dev -> / returns %d\n", error);
+
+ return (error);
}
-static void
-devfs_fixup(struct thread *td)
+static int
+vfs_mountroot_shuffle(struct thread *td, struct mount *mpdevfs)
{
struct nameidata nd;
- struct vnode *vp, *dvp;
- struct mount *mp;
+ struct mount *mporoot, *mpnroot;
+ struct vnode *vp, *vporoot, *vpdevfs;
+ char *fspath;
int error;
- /* Remove our devfs mount from the mountlist and purge the cache */
+ mpnroot = TAILQ_NEXT(mpdevfs, mnt_list);
+
+ /* Shuffle the mountlist. */
mtx_lock(&mountlist_mtx);
- mp = TAILQ_FIRST(&mountlist);
- TAILQ_REMOVE(&mountlist, mp, mnt_list);
+ mporoot = TAILQ_FIRST(&mountlist);
+ TAILQ_REMOVE(&mountlist, mpdevfs, mnt_list);
+ if (mporoot != mpdevfs) {
+ TAILQ_REMOVE(&mountlist, mpnroot, mnt_list);
+ TAILQ_INSERT_HEAD(&mountlist, mpnroot, mnt_list);
+ }
+ TAILQ_INSERT_TAIL(&mountlist, mpdevfs, mnt_list);
mtx_unlock(&mountlist_mtx);
- cache_purgevfs(mp);
- VFS_ROOT(mp, LK_EXCLUSIVE, &dvp);
- VI_LOCK(dvp);
- dvp->v_iflag &= ~VI_MOUNT;
- VI_UNLOCK(dvp);
- dvp->v_mountedhere = NULL;
+ cache_purgevfs(mporoot);
+ if (mporoot != mpdevfs)
+ cache_purgevfs(mpdevfs);
+
+ VFS_ROOT(mporoot, LK_EXCLUSIVE, &vporoot);
- /* Set up the real rootvnode, and purge the cache */
- TAILQ_FIRST(&mountlist)->mnt_vnodecovered = NULL;
+ VI_LOCK(vporoot);
+ vporoot->v_iflag &= ~VI_MOUNT;
+ VI_UNLOCK(vporoot);
+ vporoot->v_mountedhere = NULL;
+ mporoot->mnt_flag &= ~MNT_ROOTFS;
+ mporoot->mnt_vnodecovered = NULL;
+ vput(vporoot);
+
+ /* Set up the new rootvnode, and purge the cache */
+ mpnroot->mnt_vnodecovered = NULL;
set_rootvnode();
cache_purgevfs(rootvnode->v_mount);
+ if (mporoot != mpdevfs) {
+ /* Remount old root under /.mount or /mnt */
+ fspath = "/.mount";
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
+ fspath, td);
+ error = namei(&nd);
+ if (error) {
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ fspath = "/mnt";
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
+ fspath, td);
+ error = namei(&nd);
+ }
+ if (!error) {
+ vp = nd.ni_vp;
+ error = (vp->v_type == VDIR) ? 0 : ENOTDIR;
+ if (!error)
+ error = vinvalbuf(vp, V_SAVE, 0, 0);
+ if (!error) {
+ cache_purge(vp);
+ mporoot->mnt_vnodecovered = vp;
+ vp->v_mountedhere = mporoot;
+ strlcpy(mporoot->mnt_stat.f_mntonname,
+ fspath, MNAMELEN);
+ VOP_UNLOCK(vp, 0);
+ } else
+ vput(vp);
+ }
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+
+ if (error && bootverbose)
+ printf("mountroot: unable to remount previous root "
+ "under /.mount or /mnt (error %d).\n", error);
+ }
+
+ /* Remount devfs under /dev */
NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev", td);
error = namei(&nd);
- if (error) {
- printf("Lookup of /dev for devfs, error: %d\n", error);
- vput(dvp);
- vfs_unbusy(mp);
- return;
+ if (!error) {
+ vp = nd.ni_vp;
+ error = (vp->v_type == VDIR) ? 0 : ENOTDIR;
+ if (!error)
+ error = vinvalbuf(vp, V_SAVE, 0, 0);
+ if (!error) {
+ vpdevfs = mpdevfs->mnt_vnodecovered;
+ if (vpdevfs != NULL) {
+ cache_purge(vpdevfs);
+ vpdevfs->v_mountedhere = NULL;
+ vrele(vpdevfs);
+ }
+ mpdevfs->mnt_vnodecovered = vp;
+ vp->v_mountedhere = mpdevfs;
+ VOP_UNLOCK(vp, 0);
+ } else
+ vput(vp);
}
+ if (error && bootverbose)
+ printf("mountroot: unable to remount devfs under /dev "
+ "(error %d).\n", error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- vp = nd.ni_vp;
- if (vp->v_type != VDIR) {
- printf("/dev is not a directory\n");
- vput(dvp);
- vput(vp);
- vfs_unbusy(mp);
- return;
+
+ if (mporoot == mpdevfs) {
+ vfs_unbusy(mpdevfs);
+ /* Unlink the no longer needed /dev/dev -> / symlink */
+ error = kern_unlink(td, "/dev/dev", UIO_SYSSPACE);
+ if (error && bootverbose)
+ printf("mountroot: unable to unlink /dev/dev "
+ "(error %d)\n", error);
}
- error = vinvalbuf(vp, V_SAVE, 0, 0);
- if (error) {
- printf("vinvalbuf() of /dev failed, error: %d\n", error);
- vput(dvp);
- vput(vp);
- vfs_unbusy(mp);
- return;
+
+ return (0);
+}
+
+/*
+ * Configuration parser.
+ */
+
+/* Parser character classes. */
+#define CC_WHITESPACE -1
+#define CC_NONWHITESPACE -2
+
+/* Parse errors. */
+#define PE_EOF -1
+#define PE_EOL -2
+
+static __inline int
+parse_peek(char **conf)
+{
+
+ return (**conf);
+}
+
+static __inline void
+parse_poke(char **conf, int c)
+{
+
+ **conf = c;
+}
+
+static __inline void
+parse_advance(char **conf)
+{
+
+ (*conf)++;
+}
+
+static __inline int
+parse_isspace(int c)
+{
+
+ return ((c == ' ' || c == '\t' || c == '\n') ? 1 : 0);
+}
+
+static int
+parse_skipto(char **conf, int mc)
+{
+ int c, match;
+
+ while (1) {
+ c = parse_peek(conf);
+ if (c == 0)
+ return (PE_EOF);
+ switch (mc) {
+ case CC_WHITESPACE:
+ match = (c == ' ' || c == '\t' || c == '\n') ? 1 : 0;
+ break;
+ case CC_NONWHITESPACE:
+ if (c == '\n')
+ return (PE_EOL);
+ match = (c != ' ' && c != '\t') ? 1 : 0;
+ break;
+ default:
+ match = (c == mc) ? 1 : 0;
+ break;
+ }
+ if (match)
+ break;
+ parse_advance(conf);
}
- cache_purge(vp);
- mp->mnt_vnodecovered = vp;
- vp->v_mountedhere = mp;
- mtx_lock(&mountlist_mtx);
- TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- mtx_unlock(&mountlist_mtx);
- VOP_UNLOCK(vp, 0);
- vput(dvp);
- vfs_unbusy(mp);
+ return (0);
+}
+
+static int
+parse_token(char **conf, char **tok)
+{
+ char *p;
+ size_t len;
+ int error;
- /* Unlink the no longer needed /dev/dev -> / symlink */
- error = kern_unlink(td, "/dev/dev", UIO_SYSSPACE);
+ *tok = NULL;
+ error = parse_skipto(conf, CC_NONWHITESPACE);
if (error)
- printf("kern_unlink of /dev/dev failed, error: %d\n", error);
+ return (error);
+ p = *conf;
+ error = parse_skipto(conf, CC_WHITESPACE);
+ len = *conf - p;
+ *tok = malloc(len + 1, M_TEMP, M_WAITOK | M_ZERO);
+ bcopy(p, *tok, len);
+ return (0);
}
-void
-vfs_mountroot(void)
+static void
+parse_dir_ask_printenv(const char *var)
+{
+ char *val;
+
+ val = getenv(var);
+ if (val != NULL) {
+ printf(" %s=%s\n", var, val);
+ freeenv(val);
+ }
+}
+
+static int
+parse_dir_ask(char **conf)
{
- char *cp, *cpt, *options, *tmpdev;
- int error, i, asked = 0;
+ char name[80];
+ char *mnt;
+ int error;
+
+ printf("\nLoader variables:\n");
+ parse_dir_ask_printenv("vfs.root.mountfrom");
+ parse_dir_ask_printenv("vfs.root.mountfrom.options");
+
+ printf("\nManual root filesystem specification:\n");
+ printf(" <fstype>:<device> [options]\n");
+ printf(" Mount <device> using filesystem <fstype>\n");
+ printf(" and with the specified (optional) option list.\n");
+ printf("\n");
+ printf(" eg. ufs:/dev/da0s1a\n");
+ printf(" zfs:tank\n");
+ printf(" cd9660:/dev/acd0 ro\n");
+ printf(" (which is equivalent to: ");
+ printf("mount -t cd9660 -o ro /dev/acd0 /)\n");
+ printf("\n");
+ printf(" ? List valid disk boot devices\n");
+ printf(" . Yield 1 second (for background tasks)\n");
+ printf(" <empty line> Abort manual input\n");
+
+ again:
+ printf("\nmountroot> ");
+ gets(name, sizeof(name), 1);
+ if (name[0] == '\0')
+ return (0);
+ if (name[0] == '?') {
+ printf("\nList of GEOM managed disk devices:\n ");
+ g_dev_print();
+ goto again;
+ }
+ if (name[0] == '.') {
+ pause("rmask", hz);
+ goto again;
+ }
+ mnt = name;
+ error = parse_mount(&mnt);
+ if (error == -1) {
+ printf("Invalid specification.\n");
+ goto again;
+ }
+ return (error);
+}
- options = NULL;
+static int
+parse_dir_md(char **conf)
+{
+ struct stat sb;
+ struct thread *td;
+ struct md_ioctl *mdio;
+ char *path, *tok;
+ int error, fd, len;
- root_mount_prepare();
+ td = curthread;
- devfs_first();
+ error = parse_token(conf, &tok);
+ if (error)
+ return (error);
- /*
- * We are booted with instructions to prompt for the root filesystem.
- */
- if (boothowto & RB_ASKNAME) {
- if (!vfs_mountroot_ask())
- goto mounted;
- asked = 1;
+ len = strlen(tok);
+ mdio = malloc(sizeof(*mdio) + len + 1, M_TEMP, M_WAITOK | M_ZERO);
+ path = (void *)(mdio + 1);
+ bcopy(tok, path, len);
+ free(tok, M_TEMP);
+
+ /* Get file status. */
+ error = kern_stat(td, path, UIO_SYSSPACE, &sb);
+ if (error)
+ goto out;
+
+ /* Open /dev/mdctl so that we can attach/detach. */
+ error = kern_open(td, "/dev/" MDCTL_NAME, UIO_SYSSPACE, O_RDWR, 0);
+ if (error)
+ goto out;
+
+ fd = td->td_retval[0];
+ mdio->md_version = MDIOVERSION;
+ mdio->md_type = MD_VNODE;
+
+ if (root_mount_mddev != -1) {
+ mdio->md_unit = root_mount_mddev;
+ DROP_GIANT();
+ error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio);
+ PICKUP_GIANT();
+ /* Ignore errors. We don't care. */
+ root_mount_mddev = -1;
}
- options = getenv("vfs.root.mountfrom.options");
+ mdio->md_file = (void *)(mdio + 1);
+ mdio->md_options = MD_AUTOUNIT | MD_READONLY;
+ mdio->md_mediasize = sb.st_size;
+ mdio->md_unit = 0;
+ DROP_GIANT();
+ error = kern_ioctl(td, fd, MDIOCATTACH, (void *)mdio);
+ PICKUP_GIANT();
+ if (error)
+ goto out;
- /*
- * The root filesystem information is compiled in, and we are
- * booted with instructions to use it.
- */
- if (ctrootdevname != NULL && (boothowto & RB_DFLTROOT)) {
- if (!vfs_mountroot_try(ctrootdevname, options))
- goto mounted;
- ctrootdevname = NULL;
+ if (mdio->md_unit > 9) {
+ printf("rootmount: too many md units\n");
+ mdio->md_file = NULL;
+ mdio->md_options = 0;
+ mdio->md_mediasize = 0;
+ DROP_GIANT();
+ error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio);
+ PICKUP_GIANT();
+ /* Ignore errors. We don't care. */
+ error = ERANGE;
+ goto out;
+ }
+
+ root_mount_mddev = mdio->md_unit;
+ printf(MD_NAME "%u attached to %s\n", root_mount_mddev, mdio->md_file);
+
+ error = kern_close(td, fd);
+
+ out:
+ free(mdio, M_TEMP);
+ return (error);
+}
+
+static int
+parse_dir_onfail(char **conf)
+{
+ char *action;
+ int error;
+
+ error = parse_token(conf, &action);
+ if (error)
+ return (error);
+
+ if (!strcmp(action, "continue"))
+ root_mount_onfail = A_CONTINUE;
+ else if (!strcmp(action, "panic"))
+ root_mount_onfail = A_PANIC;
+ else if (!strcmp(action, "reboot"))
+ root_mount_onfail = A_REBOOT;
+ else if (!strcmp(action, "retry"))
+ root_mount_onfail = A_RETRY;
+ else {
+ printf("rootmount: %s: unknown action\n", action);
+ error = EINVAL;
}
+ free(action, M_TEMP);
+ return (0);
+}
+
+static int
+parse_dir_timeout(char **conf)
+{
+ char *tok, *endtok;
+ long secs;
+ int error;
+
+ error = parse_token(conf, &tok);
+ if (error)
+ return (error);
+
+ secs = strtol(tok, &endtok, 0);
+ error = (secs < 0 || *endtok != '\0') ? EINVAL : 0;
+ if (!error)
+ root_mount_timeout = secs;
+ free(tok, M_TEMP);
+ return (error);
+}
+
+static int
+parse_directive(char **conf)
+{
+ char *dir;
+ int error;
+
+ error = parse_token(conf, &dir);
+ if (error)
+ return (error);
+
+ if (strcmp(dir, ".ask") == 0)
+ error = parse_dir_ask(conf);
+ else if (strcmp(dir, ".md") == 0)
+ error = parse_dir_md(conf);
+ else if (strcmp(dir, ".onfail") == 0)
+ error = parse_dir_onfail(conf);
+ else if (strcmp(dir, ".timeout") == 0)
+ error = parse_dir_timeout(conf);
+ else {
+ printf("mountroot: invalid directive `%s'\n", dir);
+ /* Ignore the rest of the line. */
+ (void)parse_skipto(conf, '\n');
+ error = EINVAL;
+ }
+ free(dir, M_TEMP);
+ return (error);
+}
+
+static int
+parse_mount_dev_present(const char *dev)
+{
+ struct nameidata nd;
+ int error;
+
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, dev, curthread);
+ error = namei(&nd);
+ if (!error)
+ vput(nd.ni_vp);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ return (error != 0) ? 0 : 1;
+}
+
+static int
+parse_mount(char **conf)
+{
+ char errmsg[255];
+ struct mntarg *ma;
+ char *dev, *fs, *opts, *tok;
+ int delay, error, timeout;
+
+ error = parse_token(conf, &tok);
+ if (error)
+ return (error);
+ fs = tok;
+ error = parse_skipto(&tok, ':');
+ if (error) {
+ free(fs, M_TEMP);
+ return (error);
+ }
+ parse_poke(&tok, '\0');
+ parse_advance(&tok);
+ dev = tok;
+
+ if (root_mount_mddev != -1) {
+ /* Handle substitution for the md unit number. */
+ tok = strstr(dev, "md#");
+ if (tok != NULL)
+ tok[2] = '0' + root_mount_mddev;
+ }
+
+ /* Parse options. */
+ error = parse_token(conf, &tok);
+ opts = (error == 0) ? tok : NULL;
+
+ printf("Trying to mount root from %s:%s [%s]...\n", fs, dev,
+ (opts != NULL) ? opts : "");
+
+ bzero(errmsg, sizeof(errmsg));
+
+ if (vfs_byname(fs) == NULL) {
+ strlcpy(errmsg, "unknown file system", sizeof(errmsg));
+ error = ENOENT;
+ goto out;
+ }
+
+ if (strcmp(fs, "zfs") != 0 && dev[0] != '\0' &&
+ !parse_mount_dev_present(dev)) {
+ printf("mountroot: waiting for device %s ...\n", dev);
+ delay = hz / 10;
+ timeout = root_mount_timeout * hz;
+ do {
+ pause("rmdev", delay);
+ timeout -= delay;
+ } while (timeout > 0 && !parse_mount_dev_present(dev));
+ if (timeout <= 0) {
+ error = ENODEV;
+ goto out;
+ }
+ }
+
+ ma = NULL;
+ ma = mount_arg(ma, "fstype", fs, -1);
+ ma = mount_arg(ma, "fspath", "/", -1);
+ ma = mount_arg(ma, "from", dev, -1);
+ ma = mount_arg(ma, "errmsg", errmsg, sizeof(errmsg));
+ ma = mount_arg(ma, "ro", NULL, 0);
+ ma = parse_mountroot_options(ma, opts);
+ error = kernel_mount(ma, MNT_ROOTFS);
+
+ out:
+ if (error) {
+ printf("Mounting from %s:%s failed with error %d",
+ fs, dev, error);
+ if (errmsg[0] != '\0')
+ printf(": %s", errmsg);
+ printf(".\n");
+ }
+ free(fs, M_TEMP);
+ if (opts != NULL)
+ free(opts, M_TEMP);
+ /* kernel_mount can return -1 on error. */
+ return ((error < 0) ? EDOOFUS : error);
+}
+
+static int
+vfs_mountroot_parse(struct sbuf *sb, struct mount *mpdevfs)
+{
+ struct mount *mp;
+ char *conf;
+ int error;
+
+ root_mount_mddev = -1;
+
+retry:
+ conf = sbuf_data(sb);
+ mp = TAILQ_NEXT(mpdevfs, mnt_list);
+ error = (mp == NULL) ? 0 : EDOOFUS;
+ root_mount_onfail = A_CONTINUE;
+ while (mp == NULL) {
+ error = parse_skipto(&conf, CC_NONWHITESPACE);
+ if (error == PE_EOL) {
+ parse_advance(&conf);
+ continue;
+ }
+ if (error < 0)
+ break;
+ switch (parse_peek(&conf)) {
+ case '#':
+ error = parse_skipto(&conf, '\n');
+ break;
+ case '.':
+ error = parse_directive(&conf);
+ break;
+ default:
+ error = parse_mount(&conf);
+ break;
+ }
+ if (error < 0)
+ break;
+ /* Ignore any trailing garbage on the line. */
+ if (parse_peek(&conf) != '\n') {
+ printf("mountroot: advancing to next directive...\n");
+ (void)parse_skipto(&conf, '\n');
+ }
+ mp = TAILQ_NEXT(mpdevfs, mnt_list);
+ }
+ if (mp != NULL)
+ return (0);
+
/*
- * We've been given the generic "use CDROM as root" flag. This is
- * necessary because one media may be used in many different
- * devices, so we need to search for them.
+ * We failed to mount (a new) root.
*/
+ switch (root_mount_onfail) {
+ case A_CONTINUE:
+ break;
+ case A_PANIC:
+ panic("mountroot: unable to (re-)mount root.");
+ /* NOTREACHED */
+ case A_RETRY:
+ goto retry;
+ case A_REBOOT:
+ kern_reboot(RB_NOSYNC);
+ /* NOTREACHED */
+ }
+
+ return (error);
+}
+
+static void
+vfs_mountroot_conf0(struct sbuf *sb)
+{
+ char *s, *tok, *mnt, *opt;
+ int error;
+
+ sbuf_printf(sb, ".onfail panic\n");
+ sbuf_printf(sb, ".timeout %d\n", root_mount_timeout);
+ if (boothowto & RB_ASKNAME)
+ sbuf_printf(sb, ".ask\n");
+#ifdef ROOTDEVNAME
+ if (boothowto & RB_DFLTROOT)
+ sbuf_printf(sb, "%s\n", ROOTDEVNAME);
+#endif
if (boothowto & RB_CDROM) {
- for (i = 0; cdrom_rootdevnames[i] != NULL; i++) {
- if (!vfs_mountroot_try(cdrom_rootdevnames[i], options))
- goto mounted;
+ sbuf_printf(sb, "cd9660:cd0\n");
+ sbuf_printf(sb, ".timeout 0\n");
+ sbuf_printf(sb, "cd9660:acd0\n");
+ sbuf_printf(sb, ".timeout %d\n", root_mount_timeout);
+ }
+ s = getenv("vfs.root.mountfrom");
+ if (s != NULL) {
+ opt = getenv("vfs.root.mountfrom.options");
+ tok = s;
+ error = parse_token(&tok, &mnt);
+ while (!error) {
+ sbuf_printf(sb, "%s %s\n", mnt,
+ (opt != NULL) ? opt : "");
+ free(mnt, M_TEMP);
+ error = parse_token(&tok, &mnt);
}
+ if (opt != NULL)
+ freeenv(opt);
+ freeenv(s);
}
+ if (rootdevnames[0] != NULL)
+ sbuf_printf(sb, "%s\n", rootdevnames[0]);
+ if (rootdevnames[1] != NULL)
+ sbuf_printf(sb, "%s\n", rootdevnames[1]);
+#ifdef ROOTDEVNAME
+ if (!(boothowto & RB_DFLTROOT))
+ sbuf_printf(sb, "%s\n", ROOTDEVNAME);
+#endif
+ if (!(boothowto & RB_ASKNAME))
+ sbuf_printf(sb, ".ask\n");
+}
- /*
- * Try to use the value read by the loader from /etc/fstab, or
- * supplied via some other means. This is the preferred
- * mechanism.
- */
- cp = getenv("vfs.root.mountfrom");
- if (cp != NULL) {
- cpt = cp;
- while ((tmpdev = strsep(&cpt, " \t")) != NULL) {
- error = vfs_mountroot_try(tmpdev, options);
- if (error == 0) {
- freeenv(cp);
- goto mounted;
+static int
+vfs_mountroot_readconf(struct thread *td, struct sbuf *sb)
+{
+ static char buf[128];
+ struct nameidata nd;
+ off_t ofs;
+ int error, flags;
+ int len, resid;
+ int vfslocked;
+
+ NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE,
+ "/.mount.conf", td);
+ flags = FREAD;
+ error = vn_open(&nd, &flags, 0, NULL);
+ if (error)
+ return (error);
+
+ vfslocked = NDHASGIANT(&nd);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ ofs = 0;
+ len = sizeof(buf) - 1;
+ while (1) {
+ error = vn_rdwr(UIO_READ, nd.ni_vp, buf, len, ofs,
+ UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
+ NOCRED, &resid, td);
+ if (error)
+ break;
+ if (resid == len)
+ break;
+ buf[len - resid] = 0;
+ sbuf_printf(sb, "%s", buf);
+ ofs += len - resid;
+ }
+
+ VOP_UNLOCK(nd.ni_vp, 0);
+ vn_close(nd.ni_vp, FREAD, td->td_ucred, td);
+ VFS_UNLOCK_GIANT(vfslocked);
+ return (error);
+}
+
+static void
+vfs_mountroot_wait(void)
+{
+ struct root_hold_token *h;
+ struct timeval lastfail;
+ int curfail;
+
+ curfail = 0;
+ while (1) {
+ DROP_GIANT();
+ g_waitidle();
+ PICKUP_GIANT();
+ mtx_lock(&mountlist_mtx);
+ if (LIST_EMPTY(&root_holds)) {
+ mtx_unlock(&mountlist_mtx);
+ break;
+ }
+ if (ppsratecheck(&lastfail, &curfail, 1)) {
+ printf("Root mount waiting for:");
+ LIST_FOREACH(h, &root_holds, list)
+ printf(" %s", h->who);
+ printf("\n");
+ }
+ msleep(&root_holds, &mountlist_mtx, PZERO | PDROP, "roothold",
+ hz);
+ }
+}
+
+void
+vfs_mountroot(void)
+{
+ struct mount *mp;
+ struct sbuf *sb;
+ struct thread *td;
+ time_t timebase;
+ int error;
+
+ td = curthread;
+
+ vfs_mountroot_wait();
+
+ sb = sbuf_new_auto();
+ vfs_mountroot_conf0(sb);
+ sbuf_finish(sb);
+
+ error = vfs_mountroot_devfs(td, &mp);
+ while (!error) {
+ error = vfs_mountroot_parse(sb, mp);
+ if (!error) {
+ error = vfs_mountroot_shuffle(td, mp);
+ if (!error) {
+ sbuf_clear(sb);
+ error = vfs_mountroot_readconf(td, sb);
+ sbuf_finish(sb);
}
}
- freeenv(cp);
}
- /*
- * Try values that may have been computed by code during boot
- */
- if (!vfs_mountroot_try(rootdevnames[0], options))
- goto mounted;
- if (!vfs_mountroot_try(rootdevnames[1], options))
- goto mounted;
+ sbuf_delete(sb);
/*
- * If we (still) have a compiled-in default, try it.
+ * Iterate over all currently mounted file systems and use
+ * the time stamp found to check and/or initialize the RTC.
+ * Call inittodr() only once and pass it the largest of the
+ * timestamps we encounter.
*/
- if (ctrootdevname != NULL)
- if (!vfs_mountroot_try(ctrootdevname, options))
- goto mounted;
- /*
- * Everything so far has failed, prompt on the console if we haven't
- * already tried that.
- */
- if (!asked)
- if (!vfs_mountroot_ask())
- goto mounted;
+ timebase = 0;
+ mtx_lock(&mountlist_mtx);
+ mp = TAILQ_FIRST(&mountlist);
+ while (mp != NULL) {
+ if (mp->mnt_time > timebase)
+ timebase = mp->mnt_time;
+ mp = TAILQ_NEXT(mp, mnt_list);
+ }
+ mtx_unlock(&mountlist_mtx);
+ inittodr(timebase);
- panic("Root mount failed, startup aborted.");
+ /* Keep prison0's root in sync with the global rootvnode. */
+ mtx_lock(&prison0.pr_mtx);
+ prison0.pr_root = rootvnode;
+ vref(prison0.pr_root);
+ mtx_unlock(&prison0.pr_mtx);
-mounted:
- root_mount_done();
- freeenv(options);
+ mtx_lock(&mountlist_mtx);
+ atomic_store_rel_int(&root_mount_complete, 1);
+ wakeup(&root_mount_complete);
+ mtx_unlock(&mountlist_mtx);
}
static struct mntarg *
@@ -460,7 +1006,7 @@ parse_mountroot_options(struct mntarg *ma, const char *options)
p = opts = strdup(options, M_MOUNT);
if (opts == NULL) {
return (ma);
- }
+ }
while((name = strsep(&p, ",")) != NULL) {
if (name[0] == '\0')
@@ -482,7 +1028,7 @@ parse_mountroot_options(struct mntarg *ma, const char *options)
}
name_arg = strdup(name, M_MOUNT);
val_arg = NULL;
- if (val != NULL)
+ if (val != NULL)
val_arg = strdup(val, M_MOUNT);
ma = mount_arg(ma, name_arg, val_arg,
@@ -491,136 +1037,3 @@ parse_mountroot_options(struct mntarg *ma, const char *options)
free(opts, M_MOUNT);
return (ma);
}
-
-/*
- * Mount (mountfrom) as the root filesystem.
- */
-static int
-vfs_mountroot_try(const char *mountfrom, const char *options)
-{
- struct mount *mp;
- struct mntarg *ma;
- char *vfsname, *path;
- time_t timebase;
- int error;
- char patt[32];
- char errmsg[255];
-
- vfsname = NULL;
- path = NULL;
- mp = NULL;
- ma = NULL;
- error = EINVAL;
- bzero(errmsg, sizeof(errmsg));
-
- if (mountfrom == NULL)
- return (error); /* don't complain */
- printf("Trying to mount root from %s\n", mountfrom);
-
- /* parse vfs name and path */
- vfsname = malloc(MFSNAMELEN, M_MOUNT, M_WAITOK);
- path = malloc(MNAMELEN, M_MOUNT, M_WAITOK);
- vfsname[0] = path[0] = 0;
- sprintf(patt, "%%%d[a-z0-9]:%%%ds", MFSNAMELEN, MNAMELEN);
- if (sscanf(mountfrom, patt, vfsname, path) < 1)
- goto out;
-
- if (path[0] == '\0')
- strcpy(path, ROOTNAME);
-
- ma = mount_arg(ma, "fstype", vfsname, -1);
- ma = mount_arg(ma, "fspath", "/", -1);
- ma = mount_arg(ma, "from", path, -1);
- ma = mount_arg(ma, "errmsg", errmsg, sizeof(errmsg));
- ma = mount_arg(ma, "ro", NULL, 0);
- ma = parse_mountroot_options(ma, options);
- error = kernel_mount(ma, MNT_ROOTFS);
-
- if (error == 0) {
- /*
- * We mount devfs prior to mounting the / FS, so the first
- * entry will typically be devfs.
- */
- mp = TAILQ_FIRST(&mountlist);
- KASSERT(mp != NULL, ("%s: mountlist is empty", __func__));
-
- /*
- * Iterate over all currently mounted file systems and use
- * the time stamp found to check and/or initialize the RTC.
- * Typically devfs has no time stamp and the only other FS
- * is the actual / FS.
- * Call inittodr() only once and pass it the largest of the
- * timestamps we encounter.
- */
- timebase = 0;
- do {
- if (mp->mnt_time > timebase)
- timebase = mp->mnt_time;
- mp = TAILQ_NEXT(mp, mnt_list);
- } while (mp != NULL);
- inittodr(timebase);
-
- devfs_fixup(curthread);
- }
-
- if (error != 0 ) {
- printf("ROOT MOUNT ERROR: %s\n", errmsg);
- printf("If you have invalid mount options, reboot, and ");
- printf("first try the following from\n");
- printf("the loader prompt:\n\n");
- printf(" set vfs.root.mountfrom.options=rw\n\n");
- printf("and then remove invalid mount options from ");
- printf("/etc/fstab.\n\n");
- }
-out:
- free(path, M_MOUNT);
- free(vfsname, M_MOUNT);
- return (error);
-}
-
-static int
-vfs_mountroot_ask(void)
-{
- char name[128];
- char *mountfrom;
- char *options;
-
- for(;;) {
- printf("Loader variables:\n");
- printf("vfs.root.mountfrom=");
- mountfrom = getenv("vfs.root.mountfrom");
- if (mountfrom != NULL) {
- printf("%s", mountfrom);
- }
- printf("\n");
- printf("vfs.root.mountfrom.options=");
- options = getenv("vfs.root.mountfrom.options");
- if (options != NULL) {
- printf("%s", options);
- }
- printf("\n");
- freeenv(mountfrom);
- freeenv(options);
- printf("\nManual root filesystem specification:\n");
- printf(" <fstype>:<device> Mount <device> using filesystem <fstype>\n");
- printf(" eg. zfs:tank\n");
- printf(" eg. ufs:/dev/da0s1a\n");
- printf(" eg. cd9660:/dev/acd0\n");
- printf(" This is equivalent to: ");
- printf("mount -t cd9660 /dev/acd0 /\n");
- printf("\n");
- printf(" ? List valid disk boot devices\n");
- printf(" <empty line> Abort manual input\n");
- printf("\nmountroot> ");
- gets(name, sizeof(name), 1);
- if (name[0] == '\0')
- return (1);
- if (name[0] == '?') {
- printf("\nList of GEOM managed disk devices:\n ");
- g_dev_print();
- continue;
- }
- if (!vfs_mountroot_try(name, NULL))
- return (0);
- }
-}
diff --git a/sys/modules/mps/Makefile b/sys/modules/mps/Makefile
index 5e91084..49e65da 100644
--- a/sys/modules/mps/Makefile
+++ b/sys/modules/mps/Makefile
@@ -4,7 +4,7 @@
KMOD= mps
SRCS= mps_pci.c mps.c mps_sas.c mps_table.c mps_user.c
-SRCS+= opt_compat.h
+SRCS+= opt_mps.h opt_cam.h opt_compat.h
SRCS+= device_if.h bus_if.h pci_if.h
#CFLAGS += -DMPS_DEBUG
diff --git a/sys/modules/wlan/Makefile b/sys/modules/wlan/Makefile
index 79d5e75..682aab3 100644
--- a/sys/modules/wlan/Makefile
+++ b/sys/modules/wlan/Makefile
@@ -3,13 +3,13 @@
.PATH: ${.CURDIR}/../../net80211
KMOD= wlan
-SRCS= ieee80211.c ieee80211_action.c ieee80211_ageq.c ieee80211_amrr.c \
+SRCS= ieee80211.c ieee80211_action.c ieee80211_ageq.c \
ieee80211_crypto.c ieee80211_crypto_none.c ieee80211_dfs.c \
ieee80211_freebsd.c ieee80211_input.c ieee80211_ioctl.c \
ieee80211_mesh.c ieee80211_node.c ieee80211_output.c ieee80211_phy.c \
ieee80211_power.c ieee80211_proto.c ieee80211_scan.c \
ieee80211_scan_sta.c ieee80211_radiotap.c ieee80211_ratectl.c \
- ieee80211_regdomain.c ieee80211_rssadapt.c \
+ ieee80211_ratectl_none.c ieee80211_regdomain.c \
ieee80211_ht.c ieee80211_hwmp.c ieee80211_adhoc.c ieee80211_hostap.c \
ieee80211_monitor.c ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c
SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h opt_ipx.h opt_wlan.h \
diff --git a/sys/net80211/ieee80211_ratectl.c b/sys/net80211/ieee80211_ratectl.c
index 2e8eb7e..ea3d8d4 100644
--- a/sys/net80211/ieee80211_ratectl.c
+++ b/sys/net80211/ieee80211_ratectl.c
@@ -39,6 +39,14 @@ __FBSDID("$FreeBSD$");
static const struct ieee80211_ratectl *ratectls[IEEE80211_RATECTL_MAX];
+static const char *ratectl_modnames[IEEE80211_RATECTL_MAX] = {
+ [IEEE80211_RATECTL_AMRR] = "wlan_amrr",
+ [IEEE80211_RATECTL_RSSADAPT] = "wlan_rssadapt",
+ [IEEE80211_RATECTL_ONOE] = "wlan_onoe",
+ [IEEE80211_RATECTL_SAMPLE] = "wlan_sample",
+ [IEEE80211_RATECTL_NONE] = "wlan_none",
+};
+
MALLOC_DEFINE(M_80211_RATECTL, "80211ratectl", "802.11 rate control");
void
@@ -62,5 +70,15 @@ ieee80211_ratectl_set(struct ieee80211vap *vap, int type)
{
if (type >= IEEE80211_RATECTL_MAX)
return;
+ if (ratectls[type] == NULL) {
+ ieee80211_load_module(ratectl_modnames[type]);
+ if (ratectls[type] == NULL) {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_RATECTL,
+ "%s: unable to load algo %u, module %s\n",
+ __func__, type, ratectl_modnames[type]);
+ vap->iv_rate = ratectls[IEEE80211_RATECTL_NONE];
+ return;
+ }
+ }
vap->iv_rate = ratectls[type];
}
diff --git a/sys/net80211/ieee80211_ratectl.h b/sys/net80211/ieee80211_ratectl.h
index 73b4f32..87b2698 100644
--- a/sys/net80211/ieee80211_ratectl.h
+++ b/sys/net80211/ieee80211_ratectl.h
@@ -26,10 +26,11 @@
*/
enum ieee80211_ratealgs {
- IEEE80211_RATECTL_AMRR = 0,
+ IEEE80211_RATECTL_AMRR = 0,
IEEE80211_RATECTL_RSSADAPT = 1,
IEEE80211_RATECTL_ONOE = 2,
IEEE80211_RATECTL_SAMPLE = 3,
+ IEEE80211_RATECTL_NONE = 4,
IEEE80211_RATECTL_MAX
};
diff --git a/sys/net80211/ieee80211_ratectl_none.c b/sys/net80211/ieee80211_ratectl_none.c
new file mode 100644
index 0000000..0979e9d
--- /dev/null
+++ b/sys/net80211/ieee80211_ratectl_none.c
@@ -0,0 +1,113 @@
+/*-
+ * Copyright (c) 2010 Bernhard Schmidt <bschmidt@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_wlan.h"
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_ratectl.h>
+
+static void
+none_init(struct ieee80211vap *vap)
+{
+}
+
+static void
+none_deinit(struct ieee80211vap *vap)
+{
+ free(vap->iv_rs, M_80211_RATECTL);
+}
+
+static void
+none_node_init(struct ieee80211_node *ni)
+{
+}
+
+static void
+none_node_deinit(struct ieee80211_node *ni)
+{
+}
+
+static int
+none_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused)
+{
+ int rix = 0;
+
+ ni->ni_txrate = ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL;
+ return rix;
+}
+
+static void
+none_tx_complete(const struct ieee80211vap *vap,
+ const struct ieee80211_node *ni, int ok,
+ void *arg1, void *arg2 __unused)
+{
+}
+
+static void
+none_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni,
+ void *arg1, void *arg2, void *arg3)
+{
+}
+
+static void
+none_setinterval(const struct ieee80211vap *vap, int msecs)
+{
+}
+
+/* number of references from net80211 layer */
+static int nrefs = 0;
+
+static const struct ieee80211_ratectl none = {
+ .ir_name = "none",
+ .ir_attach = NULL,
+ .ir_detach = NULL,
+ .ir_init = none_init,
+ .ir_deinit = none_deinit,
+ .ir_node_init = none_node_init,
+ .ir_node_deinit = none_node_deinit,
+ .ir_rate = none_rate,
+ .ir_tx_complete = none_tx_complete,
+ .ir_tx_update = none_tx_update,
+ .ir_setinterval = none_setinterval,
+};
+IEEE80211_RATECTL_MODULE(ratectl_none, 1);
+IEEE80211_RATECTL_ALG(none, IEEE80211_RATECTL_NONE, none);
diff --git a/sys/netinet/libalias/libalias.3 b/sys/netinet/libalias/libalias.3
index 8f7d93f..31702e8 100644
--- a/sys/netinet/libalias/libalias.3
+++ b/sys/netinet/libalias/libalias.3
@@ -899,7 +899,6 @@ protocols (except for IP, TCP and UDP) to external modules.
.Sh ACKNOWLEDGMENTS
Listed below, in approximate chronological order, are individuals who
have provided valuable comments and/or debugging assistance.
-.Pp
.Bd -ragged -offset indent
.An -split
.An Gary Roberts
diff --git a/sys/nfs/nfs_lock.c b/sys/nfs/nfs_lock.c
index 89ad654..4c220e2 100644
--- a/sys/nfs/nfs_lock.c
+++ b/sys/nfs/nfs_lock.c
@@ -62,6 +62,9 @@ __FBSDID("$FreeBSD$");
extern void (*nlminfo_release_p)(struct proc *p);
+vop_advlock_t *nfs_advlock_p = nfs_dolock;
+vop_reclaim_t *nfs_reclaim_p = NULL;
+
MALLOC_DEFINE(M_NFSLOCK, "nfsclient_lock", "NFS lock request");
MALLOC_DEFINE(M_NLMINFO, "nfsclient_nlminfo", "NFS lock process structure");
@@ -236,20 +239,19 @@ nfs_dolock(struct vop_advlock_args *ap)
int error;
struct flock *fl;
struct proc *p;
+ struct nfsmount *nmp;
td = curthread;
p = td->td_proc;
vp = ap->a_vp;
fl = ap->a_fl;
+ nmp = VFSTONFS(vp->v_mount);
ASSERT_VOP_LOCKED(vp, "nfs_dolock");
- bcopy(VFSTONFS(vp->v_mount)->nm_nam, &msg.lm_addr,
- min(sizeof msg.lm_addr, VFSTONFS(vp->v_mount)->nm_nam->sa_len));
- msg.lm_fh_len = NFS_ISV3(vp) ? VTONFS(vp)->n_fhsize : NFSX_V2FH;
- bcopy(VTONFS(vp)->n_fhp, msg.lm_fh, msg.lm_fh_len);
- msg.lm_nfsv3 = NFS_ISV3(vp);
+ nmp->nm_getinfo(vp, msg.lm_fh, &msg.lm_fh_len, &msg.lm_addr,
+ &msg.lm_nfsv3, NULL);
VOP_UNLOCK(vp, 0);
/*
diff --git a/sys/nfs/nfs_lock.h b/sys/nfs/nfs_lock.h
index aa99996..ff5feb2 100644
--- a/sys/nfs/nfs_lock.h
+++ b/sys/nfs/nfs_lock.h
@@ -87,4 +87,6 @@ struct lockd_ans {
#ifdef _KERNEL
int nfs_dolock(struct vop_advlock_args *ap);
+extern vop_advlock_t *nfs_advlock_p;
+extern vop_reclaim_t *nfs_reclaim_p;
#endif
diff --git a/sys/nfs/nfs_mountcommon.h b/sys/nfs/nfs_mountcommon.h
new file mode 100644
index 0000000..c004b9c
--- /dev/null
+++ b/sys/nfs/nfs_mountcommon.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2009 Rick Macklem, University of Guelph
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _NFS_MOUNTCOMMON_H_
+#define _NFS_MOUNTCOMMON_H_
+
+/*
+ * The common fields of the nfsmount structure for the two clients
+ * used by the nlm. It includes a function pointer that provides
+ * a mechanism for getting the client specific info for an nfs vnode.
+ */
+typedef void nfs_getinfofromvp_ftype(struct vnode *, uint8_t *, size_t *,
+ struct sockaddr_storage *, int *, off_t *);
+
+struct nfsmount_common {
+ struct mtx nmcom_mtx;
+ int nmcom_flag; /* Flags for soft/hard... */
+ int nmcom_state; /* Internal state flags */
+ struct mount *nmcom_mountp; /* Vfs structure for this filesystem */
+ int nmcom_timeo; /* Init timer for NFSMNT_DUMBTIMR */
+ int nmcom_retry; /* Max retries */
+ char nmcom_hostname[MNAMELEN]; /* server's name */
+ nfs_getinfofromvp_ftype *nmcom_getinfo; /* Get info from nfsnode */
+};
+
+#endif /* _NFS_MOUNTCOMMON_H_ */
diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h
index da61175..99b86f8 100644
--- a/sys/nfsclient/nfs.h
+++ b/sys/nfsclient/nfs.h
@@ -253,7 +253,7 @@ int nfs_writerpc(struct vnode *, struct uio *, struct ucred *, int *,
int nfs_commit(struct vnode *vp, u_quad_t offset, int cnt,
struct ucred *cred, struct thread *td);
int nfs_readdirrpc(struct vnode *, struct uio *, struct ucred *);
-int nfs_nfsiodnew(int);
+void nfs_nfsiodnew(void);
void nfs_nfsiodnew_tq(__unused void *, int);
int nfs_asyncio(struct nfsmount *, struct buf *, struct ucred *, struct thread *);
int nfs_doio(struct vnode *, struct buf *, struct ucred *, struct thread *);
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index 2f40bb2..047df94 100644
--- a/sys/nfsclient/nfs_bio.c
+++ b/sys/nfsclient/nfs_bio.c
@@ -1375,13 +1375,9 @@ again:
/*
* Try to create one if none are free.
*/
- if (!gotiod) {
- iod = nfs_nfsiodnew(1);
- if (iod != -1)
- gotiod = TRUE;
- }
-
- if (gotiod) {
+ if (!gotiod)
+ nfs_nfsiodnew();
+ else {
/*
* Found one, so wake it up and tell it which
* mount to process.
@@ -1401,7 +1397,7 @@ again:
if (!gotiod) {
if (nmp->nm_bufqiods > 0) {
NFS_DPF(ASYNCIO,
- ("nfs_asyncio: %d iods are already processing mount %p\n",
+ ("nfs_asyncio: %d iods are already processing mount %p\n",
nmp->nm_bufqiods, nmp));
gotiod = TRUE;
}
@@ -1416,9 +1412,9 @@ again:
* Ensure that the queue never grows too large. We still want
* to asynchronize so we block rather then return EIO.
*/
- while (nmp->nm_bufqlen >= 2*nfs_numasync) {
+ while (nmp->nm_bufqlen >= 2 * nfs_numasync) {
NFS_DPF(ASYNCIO,
- ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp));
+ ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp));
nmp->nm_bufqwant = TRUE;
error = nfs_msleep(td, &nmp->nm_bufq, &nfs_iod_mtx,
slpflag | PRIBIO,
@@ -1426,7 +1422,7 @@ again:
if (error) {
error2 = nfs_sigintr(nmp, td);
if (error2) {
- mtx_unlock(&nfs_iod_mtx);
+ mtx_unlock(&nfs_iod_mtx);
return (error2);
}
if (slpflag == NFS_PCATCH) {
@@ -1438,17 +1434,13 @@ again:
* We might have lost our iod while sleeping,
* so check and loop if nescessary.
*/
- if (nmp->nm_bufqiods == 0) {
- NFS_DPF(ASYNCIO,
- ("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp));
- goto again;
- }
+ goto again;
}
/* We might have lost our nfsiod */
if (nmp->nm_bufqiods == 0) {
NFS_DPF(ASYNCIO,
- ("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp));
+("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp));
goto again;
}
diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c
index 5e2fbcc..fcb987e 100644
--- a/sys/nfsclient/nfs_nfsiod.c
+++ b/sys/nfsclient/nfs_nfsiod.c
@@ -76,16 +76,6 @@ static MALLOC_DEFINE(M_NFSSVC, "nfsclient_srvsock", "Nfs server structure");
static void nfssvc_iod(void *);
-struct nfsiod_str {
- STAILQ_ENTRY(nfsiod_str) ni_links;
- int *ni_inst;
- int ni_iod;
- int ni_error;
- int ni_done;
-};
-static STAILQ_HEAD(, nfsiod_str) nfsiodhead =
- STAILQ_HEAD_INITIALIZER(nfsiodhead);
-
static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
SYSCTL_DECL(_vfs_nfs);
@@ -101,6 +91,8 @@ unsigned int nfs_iodmax = 20;
/* Minimum number of nfsiod kthreads to keep as spares */
static unsigned int nfs_iodmin = 0;
+static int nfs_nfsiodnew_sync(void);
+
static int
sysctl_iodmin(SYSCTL_HANDLER_ARGS)
{
@@ -124,7 +116,7 @@ sysctl_iodmin(SYSCTL_HANDLER_ARGS)
* than the new minimum, create some more.
*/
for (i = nfs_iodmin - nfs_numasync; i > 0; i--)
- nfs_nfsiodnew(0);
+ nfs_nfsiodnew_sync();
out:
mtx_unlock(&nfs_iod_mtx);
return (0);
@@ -170,68 +162,55 @@ SYSCTL_PROC(_vfs_nfs, OID_AUTO, iodmax, CTLTYPE_UINT | CTLFLAG_RW, 0,
sizeof (nfs_iodmax), sysctl_iodmax, "IU",
"Max number of nfsiod kthreads");
+static int
+nfs_nfsiodnew_sync(void)
+{
+ int error, i;
+
+ mtx_assert(&nfs_iod_mtx, MA_OWNED);
+ for (i = 0; i < nfs_iodmax; i++) {
+ if (nfs_asyncdaemon[i] == 0) {
+ nfs_asyncdaemon[i] = 1;
+ break;
+ }
+ }
+ if (i == nfs_iodmax)
+ return (0);
+ mtx_unlock(&nfs_iod_mtx);
+ error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL,
+ RFHIGHPID, 0, "nfsiod %d", i);
+ mtx_lock(&nfs_iod_mtx);
+ if (error == 0) {
+ nfs_numasync++;
+ nfs_iodwant[i] = NFSIOD_AVAILABLE;
+ } else
+ nfs_asyncdaemon[i] = 0;
+ return (error);
+}
+
void
nfs_nfsiodnew_tq(__unused void *arg, int pending)
{
- struct nfsiod_str *nip;
mtx_lock(&nfs_iod_mtx);
- while ((nip = STAILQ_FIRST(&nfsiodhead)) != NULL) {
- STAILQ_REMOVE_HEAD(&nfsiodhead, ni_links);
- mtx_unlock(&nfs_iod_mtx);
- nip->ni_error = kproc_create(nfssvc_iod, nip->ni_inst, NULL,
- RFHIGHPID, 0, "nfsiod %d", nip->ni_iod);
- nip->ni_done = 1;
- mtx_lock(&nfs_iod_mtx);
- wakeup(nip);
+ while (pending > 0) {
+ pending--;
+ nfs_nfsiodnew_sync();
}
mtx_unlock(&nfs_iod_mtx);
}
-int
-nfs_nfsiodnew(int set_iodwant)
+void
+nfs_nfsiodnew(void)
{
- int error, i;
- int newiod;
- struct nfsiod_str *nip;
- if (nfs_numasync >= nfs_iodmax)
- return (-1);
- newiod = -1;
- for (i = 0; i < nfs_iodmax; i++)
- if (nfs_asyncdaemon[i] == 0) {
- nfs_asyncdaemon[i]++;
- newiod = i;
- break;
- }
- if (newiod == -1)
- return (-1);
- if (set_iodwant > 0)
- nfs_iodwant[i] = NFSIOD_CREATED_FOR_NFS_ASYNCIO;
- mtx_unlock(&nfs_iod_mtx);
- nip = malloc(sizeof(*nip), M_TEMP, M_WAITOK | M_ZERO);
- nip->ni_inst = nfs_asyncdaemon + i;
- nip->ni_iod = newiod;
- mtx_lock(&nfs_iod_mtx);
- STAILQ_INSERT_TAIL(&nfsiodhead, nip, ni_links);
+ mtx_assert(&nfs_iod_mtx, MA_OWNED);
taskqueue_enqueue(taskqueue_thread, &nfs_nfsiodnew_task);
- while (!nip->ni_done)
- mtx_sleep(nip, &nfs_iod_mtx, 0, "niwt", 0);
- error = nip->ni_error;
- free(nip, M_TEMP);
- if (error) {
- if (set_iodwant > 0)
- nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE;
- return (-1);
- }
- nfs_numasync++;
- return (newiod);
}
static void
nfsiod_setup(void *dummy)
{
- int i;
int error;
TUNABLE_INT_FETCH("vfs.nfs.iodmin", &nfs_iodmin);
@@ -240,8 +219,8 @@ nfsiod_setup(void *dummy)
if (nfs_iodmin > NFS_MAXASYNCDAEMON)
nfs_iodmin = NFS_MAXASYNCDAEMON;
- for (i = 0; i < nfs_iodmin; i++) {
- error = nfs_nfsiodnew(0);
+ while (nfs_numasync < nfs_iodmin) {
+ error = nfs_nfsiodnew_sync();
if (error == -1)
panic("nfsiod_setup: nfs_nfsiodnew failed");
}
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 9e558f4..5b87bd7 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/fcntl.h>
#include <sys/fnv_hash.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -51,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
#include <nfs/nfsproto.h>
+#include <nfs/nfs_lock.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsnode.h>
#include <nfsclient/nfsmount.h>
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index f07bf16..fd50ca8 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -115,6 +115,8 @@ static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, struct vnode **,
struct ucred *cred, int);
+static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
+ struct sockaddr_storage *, int *, off_t *);
static vfs_mount_t nfs_mount;
static vfs_cmount_t nfs_cmount;
static vfs_unmount_t nfs_unmount;
@@ -1202,6 +1204,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
bzero((caddr_t)nmp, sizeof (struct nfsmount));
TAILQ_INIT(&nmp->nm_bufq);
mp->mnt_data = nmp;
+ nmp->nm_getinfo = nfs_getnlminfo;
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
@@ -1490,3 +1493,27 @@ nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
}
return (0);
}
+
+/*
+ * Extract the information needed by the nlm from the nfs vnode.
+ */
+static void
+nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
+ struct sockaddr_storage *sp, int *is_v3p, off_t *sizep)
+{
+ struct nfsmount *nmp;
+ struct nfsnode *np = VTONFS(vp);
+
+ nmp = VFSTONFS(vp->v_mount);
+ if (fhlenp != NULL)
+ *fhlenp = (size_t)np->n_fhsize;
+ if (fhp != NULL)
+ bcopy(np->n_fhp, fhp, np->n_fhsize);
+ if (sp != NULL)
+ bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
+ if (is_v3p != NULL)
+ *is_v3p = NFS_ISV3(vp);
+ if (sizep != NULL)
+ *sizep = np->n_size;
+}
+
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 828a739..cb2a126 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -215,8 +215,6 @@ struct mtx nfs_iod_mtx;
enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON];
struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
int nfs_numasync = 0;
-vop_advlock_t *nfs_advlock_p = nfs_dolock;
-vop_reclaim_t *nfs_reclaim_p = NULL;
#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
SYSCTL_DECL(_vfs_nfs);
diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h
index d47957c..515c64e 100644
--- a/sys/nfsclient/nfsmount.h
+++ b/sys/nfsclient/nfsmount.h
@@ -36,6 +36,10 @@
#ifndef _NFSCLIENT_NFSMOUNT_H_
#define _NFSCLIENT_NFSMOUNT_H_
+#include <sys/socket.h>
+
+#include <nfs/nfs_mountcommon.h>
+
#include <rpc/types.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
@@ -47,10 +51,7 @@
* Holds NFS specific information for mount.
*/
struct nfsmount {
- struct mtx nm_mtx;
- int nm_flag; /* Flags for soft/hard... */
- int nm_state; /* Internal state flags */
- struct mount *nm_mountp; /* Vfs structure for this filesystem */
+ struct nfsmount_common nm_com; /* Common fields for nlm */
int nm_numgrps; /* Max. size of groupslist */
u_char nm_fh[NFSX_V4FH]; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
@@ -58,8 +59,6 @@ struct nfsmount {
int nm_soproto; /* and protocol */
int nm_soflags; /* pr_flags for socket protocol */
struct sockaddr *nm_nam; /* Addr of server */
- int nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */
- int nm_retry; /* Max retries */
int nm_deadthresh; /* Threshold of timeouts-->dead server*/
int nm_rsize; /* Max size of read rpc */
int nm_wsize; /* Max size of write rpc */
@@ -79,7 +78,6 @@ struct nfsmount {
struct nfs_rpcops *nm_rpcops;
int nm_tprintf_initial_delay; /* initial delay */
int nm_tprintf_delay; /* interval for messages */
- char nm_hostname[MNAMELEN]; /* server's name */
int nm_secflavor; /* auth flavor to use for rpc */
struct __rpc_client *nm_client;
struct rpc_timers nm_timers[NFS_MAX_TIMER]; /* RTT Timers for rpcs */
@@ -94,6 +92,15 @@ struct nfsmount {
time_t nm_last_renewal;
};
+#define nm_mtx nm_com.nmcom_mtx
+#define nm_flag nm_com.nmcom_flag
+#define nm_state nm_com.nmcom_state
+#define nm_mountp nm_com.nmcom_mountp
+#define nm_timeo nm_com.nmcom_timeo
+#define nm_retry nm_com.nmcom_retry
+#define nm_hostname nm_com.nmcom_hostname
+#define nm_getinfo nm_com.nmcom_getinfo
+
#if defined(_KERNEL)
/*
* Convert mount ptr to nfsmount ptr.
diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h
index 5254689..19c1c47 100644
--- a/sys/nfsclient/nfsnode.h
+++ b/sys/nfsclient/nfsnode.h
@@ -165,16 +165,13 @@ struct nfsnode {
#define NFS_TIMESPEC_COMPARE(T1, T2) (((T1)->tv_sec != (T2)->tv_sec) || ((T1)->tv_nsec != (T2)->tv_nsec))
/*
- * NFS iod threads can be in one of these three states once spawned.
+ * NFS iod threads can be in one of these two states once spawned.
* NFSIOD_NOT_AVAILABLE - Cannot be assigned an I/O operation at this time.
* NFSIOD_AVAILABLE - Available to be assigned an I/O operation.
- * NFSIOD_CREATED_FOR_NFS_ASYNCIO - Newly created for nfs_asyncio() and
- * will be used by the thread that called nfs_asyncio().
*/
enum nfsiod_state {
NFSIOD_NOT_AVAILABLE = 0,
NFSIOD_AVAILABLE = 1,
- NFSIOD_CREATED_FOR_NFS_ASYNCIO = 2,
};
/*
@@ -190,9 +187,6 @@ extern struct vop_vector nfs_fifoops;
extern struct vop_vector nfs_vnodeops;
extern struct buf_ops buf_ops_nfs;
-extern vop_advlock_t *nfs_advlock_p;
-extern vop_reclaim_t *nfs_reclaim_p;
-
/*
* Prototypes for NFS vnode operations
*/
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
index 833bfc7..4a3876f 100644
--- a/sys/nfsserver/nfs_serv.c
+++ b/sys/nfsserver/nfs_serv.c
@@ -3036,7 +3036,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
struct iovec iv;
struct vattr va, at, *vap = &va;
struct nfs_fattr *fp;
- int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1;
+ int len, nlen, rem, xfer, tsiz, i, error = 0, error1, getret = 1;
int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies;
u_quad_t off, toff, verf;
u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
@@ -3240,24 +3240,25 @@ again:
}
if (!VOP_ISLOCKED(vp))
vn_lock(vp, LK_SHARED | LK_RETRY);
- if (VOP_LOOKUP(vp, &nvp, &cn) != 0)
+ if ((vp->v_vflag & VV_ROOT) != 0 &&
+ (cn.cn_flags & ISDOTDOT) != 0) {
+ vref(vp);
+ nvp = vp;
+ } else if (VOP_LOOKUP(vp, &nvp, &cn) != 0)
goto invalid;
}
bzero((caddr_t)nfhp, NFSX_V3FH);
nfhp->fh_fsid = nvp->v_mount->mnt_stat.f_fsid;
- if (VOP_VPTOFH(nvp, &nfhp->fh_fid)) {
- vput(nvp);
- nvp = NULL;
- goto invalid;
- }
- if (VOP_GETATTR(nvp, vap, cred)) {
+ if ((error1 = VOP_VPTOFH(nvp, &nfhp->fh_fid)) == 0)
+ error1 = VOP_GETATTR(nvp, vap, cred);
+ if (vp == nvp)
+ vunref(nvp);
+ else
vput(nvp);
- nvp = NULL;
- goto invalid;
- }
- vput(nvp);
nvp = NULL;
+ if (error1 != 0)
+ goto invalid;
/*
* If either the dircount or maxcount will be
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
index b179595..b4edb4d 100644
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/unistd.h>
@@ -47,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
-#include <nfsclient/nfsnode.h>
#include <nfsclient/nfsmount.h>
#include <nlm/nlm_prot.h>
@@ -196,7 +196,6 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
{
struct thread *td = curthread;
struct nfsmount *nmp;
- struct nfsnode *np;
off_t size;
size_t fhlen;
union nfsfh fh;
@@ -214,6 +213,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
struct nlm_file_svid *ns;
int svid;
int error;
+ int is_v3;
ASSERT_VOP_LOCKED(vp, "nlm_advlock_1");
@@ -225,18 +225,13 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
if (op == F_SETLK || op == F_UNLCK)
nfs_vinvalbuf(vp, V_SAVE, td, 1);
- np = VTONFS(vp);
nmp = VFSTONFS(vp->v_mount);
- size = np->n_size;
- sa = nmp->nm_nam;
- memcpy(&ss, sa, sa->sa_len);
- sa = (struct sockaddr *) &ss;
strcpy(servername, nmp->nm_hostname);
- fhlen = np->n_fhsize;
- memcpy(&fh.fh_bytes, np->n_fhp, fhlen);
+ nmp->nm_getinfo(vp, fh.fh_bytes, &fhlen, &ss, &is_v3, &size);
+ sa = (struct sockaddr *) &ss;
timo.tv_sec = nmp->nm_timeo / NFS_HZ;
timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
- if (NFS_ISV3(vp))
+ if (is_v3 != 0)
vers = NLM_VERS4;
else
vers = NLM_VERS;
diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c
index 5f7f8e1..ea4baca 100644
--- a/sys/nlm/nlm_prot_impl.c
+++ b/sys/nlm/nlm_prot_impl.c
@@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsnode.h>
+#include <nfs/nfs_lock.h>
#include <nlm/nlm_prot.h>
#include <nlm/sm_inter.h>
@@ -2432,4 +2431,5 @@ DECLARE_MODULE(nfslockd, nfslockd_mod, SI_SUB_VFS, SI_ORDER_ANY);
/* So that loader and kldload(2) can find us, wherever we are.. */
MODULE_DEPEND(nfslockd, krpc, 1, 1, 1);
MODULE_DEPEND(nfslockd, nfs, 1, 1, 1);
+MODULE_DEPEND(nfslockd, nfslock, 1, 1, 1);
MODULE_VERSION(nfslockd, 1);
diff --git a/sys/sparc64/include/tick.h b/sys/sparc64/include/tick.h
index 979e93f..201a3e6 100644
--- a/sys/sparc64/include/tick.h
+++ b/sys/sparc64/include/tick.h
@@ -29,7 +29,7 @@
#ifndef _MACHINE_TICK_H_
#define _MACHINE_TICK_H_
-extern u_int hardclock_use_stick;
+extern u_int tick_et_use_stick;
void tick_clear(u_int cpu_impl);
void tick_stop(u_int cpu_impl);
diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c
index 5a4bba6..588a0ca 100644
--- a/sys/sparc64/sparc64/mp_machdep.c
+++ b/sys/sparc64/sparc64/mp_machdep.c
@@ -318,7 +318,7 @@ ap_start(phandle_t node, u_int mid, u_int cpu_impl)
if (OF_getprop(node, "clock-frequency", &clock, sizeof(clock)) <= 0)
panic("%s: couldn't determine CPU frequency", __func__);
if (clock != PCPU_GET(clock))
- hardclock_use_stick = 1;
+ tick_et_use_stick = 1;
csa = &cpu_start_args;
csa->csa_state = 0;
diff --git a/sys/sparc64/sparc64/tick.c b/sys/sparc64/sparc64/tick.c
index 3291687..82c24a5 100644
--- a/sys/sparc64/sparc64/tick.c
+++ b/sys/sparc64/sparc64/tick.c
@@ -74,9 +74,9 @@ static int adjust_ticks = 0;
SYSCTL_INT(_machdep_tick, OID_AUTO, adjust_ticks, CTLFLAG_RD, &adjust_ticks,
0, "total number of tick interrupts with adjustment");
-u_int hardclock_use_stick = 0;
-SYSCTL_INT(_machdep_tick, OID_AUTO, hardclock_use_stick, CTLFLAG_RD,
- &hardclock_use_stick, 0, "hardclock uses STICK instead of TICK timer");
+u_int tick_et_use_stick = 0;
+SYSCTL_INT(_machdep_tick, OID_AUTO, tick_et_use_stick, CTLFLAG_RD,
+ &tick_et_use_stick, 0, "tick event timer uses STICK instead of TICK");
static struct timecounter stick_tc;
static struct timecounter tick_tc;
@@ -96,9 +96,9 @@ static int tick_et_start(struct eventtimer *et,
static int tick_et_stop(struct eventtimer *et);
static void tick_intr(struct trapframe *tf);
static void tick_intr_bbwar(struct trapframe *tf);
-static inline void tick_hardclock_periodic(struct trapframe *tf, u_long tick,
- u_long tick_increment, u_long adj);
static inline void tick_process(struct trapframe *tf);
+static inline void tick_process_periodic(struct trapframe *tf, u_long tick,
+ u_long tick_increment, u_long adj);
static void stick_intr(struct trapframe *tf);
static uint64_t
@@ -127,7 +127,7 @@ cpu_initclocks(void)
* Given that the STICK timers typically are driven at rather low
* frequencies they shouldn't be used except when really necessary.
*/
- if (hardclock_use_stick != 0) {
+ if (tick_et_use_stick != 0) {
intr_setup(PIL_TICK, stick_intr, -1, NULL, NULL);
/*
* We don't provide a CPU ticker as long as the frequency
@@ -180,11 +180,11 @@ cpu_initclocks(void)
#endif
tc_init(&stick_tc);
}
- tick_et.et_name = hardclock_use_stick ? "stick" : "tick";
+ tick_et.et_name = tick_et_use_stick ? "stick" : "tick";
tick_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
ET_FLAGS_PERCPU;
tick_et.et_quality = 1000;
- tick_et.et_frequency = hardclock_use_stick ? sclock : clock;
+ tick_et.et_frequency = tick_et_use_stick ? sclock : clock;
tick_et.et_min_period.sec = 0;
tick_et.et_min_period.frac = 0x00010000LLU << 32; /* To be safe. */
tick_et.et_max_period.sec = 3600 * 24; /* No practical limit. */
@@ -203,6 +203,7 @@ tick_process(struct trapframe *tf)
struct trapframe *oldframe;
struct thread *td;
+ critical_enter();
if (tick_et.et_active) {
td = curthread;
oldframe = td->td_intr_frame;
@@ -210,13 +211,14 @@ tick_process(struct trapframe *tf)
tick_et.et_event_cb(&tick_et, tick_et.et_arg);
td->td_intr_frame = oldframe;
}
+ critical_exit();
}
/*
* NB: the sequence of reading the (S)TICK register, calculating the value
* of the next tick and writing it to the (S)TICK_COMPARE register must not
* be interrupted, not even by an IPI, otherwise a value that is in the past
- * could be written in the worst case, causing hardclock to stop.
+ * could be written in the worst case, causing the periodic timer to stop.
*/
static void
@@ -232,7 +234,7 @@ tick_intr(struct trapframe *tf)
tick = rd(tick);
wr(tick_cmpr, tick + tick_increment - adj, 0);
intr_restore(s);
- tick_hardclock_periodic(tf, tick, tick_increment, adj);
+ tick_process_periodic(tf, tick, tick_increment, adj);
} else {
intr_restore(s);
tick_process(tf);
@@ -252,7 +254,7 @@ tick_intr_bbwar(struct trapframe *tf)
tick = rd(tick);
wrtickcmpr(tick + tick_increment - adj, 0);
intr_restore(s);
- tick_hardclock_periodic(tf, tick, tick_increment, adj);
+ tick_process_periodic(tf, tick, tick_increment, adj);
} else {
intr_restore(s);
tick_process(tf);
@@ -272,7 +274,7 @@ stick_intr(struct trapframe *tf)
stick = rdstick();
wrstickcmpr(stick + tick_increment - adj, 0);
intr_restore(s);
- tick_hardclock_periodic(tf, stick, tick_increment, adj);
+ tick_process_periodic(tf, stick, tick_increment, adj);
} else {
intr_restore(s);
tick_process(tf);
@@ -280,7 +282,7 @@ stick_intr(struct trapframe *tf)
}
static inline void
-tick_hardclock_periodic(struct trapframe *tf, u_long tick,
+tick_process_periodic(struct trapframe *tf, u_long tick,
u_long tick_increment, u_long adj)
{
u_long ref;
@@ -385,7 +387,7 @@ tick_et_start(struct eventtimer *et, struct bintime *first,
* out one tick to make sure that it is not missed.
*/
s = intr_disable();
- if (hardclock_use_stick != 0)
+ if (tick_et_use_stick != 0)
base = rdstick();
else
base = rd(tick);
@@ -394,7 +396,7 @@ tick_et_start(struct eventtimer *et, struct bintime *first,
base = roundup(base, div);
}
PCPU_SET(tickref, base);
- if (hardclock_use_stick != 0)
+ if (tick_et_use_stick != 0)
wrstickcmpr(base + fdiv, 0);
else
wrtickcmpr(base + fdiv, 0);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 8e98ef4..39e9e8c 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -46,7 +46,7 @@
#include <sys/stdint.h> /* for people using printf mainly */
extern int cold; /* nonzero if we are doing a cold boot */
-extern int rebooting; /* boot() has been called. */
+extern int rebooting; /* kern_reboot() has been called. */
extern const char *panicstr; /* panic message */
extern char version[]; /* system version */
extern char copyright[]; /* system copyright */
@@ -291,6 +291,7 @@ void cpu_initclocks_ap(void);
void usrinfoinit(void);
/* Finalize the world */
+void kern_reboot(int) __dead2;
void shutdown_nice(int);
/* Timeouts */
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index dfd4403..43e3703 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -2517,6 +2517,10 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread,
zone->uz_name);
+ /* uma_zfree(..., NULL) does nothing, to match free(9). */
+ if (item == NULL)
+ return;
+
if (zone->uz_dtor)
zone->uz_dtor(item, zone->uz_size, udata);
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index 416b5a2..4c553aa 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -302,7 +302,7 @@
11/19 Konstantin Belousov <kib@FreeBSD.org> born in Kiev, USSR, 1972
11/20 Dmitry Morozovsky <marck@FreeBSD.org> born in Moscow, USSR, 1968
11/20 Gavin Atkinson <gavin@FreeBSD.org> born in Middlesbrough, United Kingdom, 1979
-11/22 Frederic Culot <culot@FreeBSD.org> born in Saint-Germain-En-Laye, France, 1976
+11/22 Frederic Culot <culot@FreeBSD.org> born in Saint-Germain-En-Laye, France, 1976
11/23 Josef Lawrence Karthauser <joe@FreeBSD.org> born in Pembury, Kent, United Kingdom, 1972
11/24 Andrey Zakhvatov <andy@FreeBSD.org> born in Chelyabinsk, Russian Federation, 1974
11/24 Daniel Gerzo <danger@FreeBSD.org> born in Bratislava, Slovakia, 1986
diff --git a/usr.bin/nc/Makefile b/usr.bin/nc/Makefile
index 84d20d3..17cea06 100644
--- a/usr.bin/nc/Makefile
+++ b/usr.bin/nc/Makefile
@@ -9,6 +9,6 @@ CFLAGS+=-DIPSEC
LDADD= -lipsec
DPADD= ${LIBIPSEC}
-WARNS?= 1
+WARNS?= 2
.include <bsd.prog.mk>
diff --git a/usr.bin/uudecode/uudecode.c b/usr.bin/uudecode/uudecode.c
index 093af7d..58c0878 100644
--- a/usr.bin/uudecode/uudecode.c
+++ b/usr.bin/uudecode/uudecode.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
+#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -87,7 +88,7 @@ main(int argc, char *argv[])
base64 = 1;
while ((ch = getopt(argc, argv, "cimo:prs")) != -1) {
- switch(ch) {
+ switch (ch) {
case 'c':
if (oflag || rflag)
usage();
@@ -125,10 +126,10 @@ main(int argc, char *argv[])
usage();
}
}
- argc -= optind;
- argv += optind;
+ argc -= optind;
+ argv += optind;
- if (*argv) {
+ if (*argv != NULL) {
rval = 0;
do {
infp = fopen(infile = *argv, "r");
@@ -184,7 +185,7 @@ decode2(void)
void *handle;
struct passwd *pw;
struct stat st;
- char buf[MAXPATHLEN+1];
+ char buf[MAXPATHLEN + 1];
base64 = 0;
/* search for header line */
@@ -259,7 +260,7 @@ decode2(void)
if (pflag || strcmp(outfile, "/dev/stdout") == 0)
outfp = stdout;
else {
- flags = O_WRONLY|O_CREAT|O_EXCL;
+ flags = O_WRONLY | O_CREAT | O_EXCL;
if (lstat(outfile, &st) == 0) {
if (iflag) {
warnc(EEXIST, "%s: %s", infile, outfile);
@@ -305,6 +306,7 @@ decode2(void)
static int
getline(char *buf, size_t size)
{
+
if (fgets(buf, size, infp) != NULL)
return (2);
if (rflag)
@@ -341,17 +343,19 @@ uu_decode(void)
/* for each input line */
for (;;) {
switch (getline(buf, sizeof(buf))) {
- case 0: return (0);
- case 1: return (1);
+ case 0:
+ return (0);
+ case 1:
+ return (1);
}
-#define DEC(c) (((c) - ' ') & 077) /* single character decode */
-#define IS_DEC(c) ( (((c) - ' ') >= 0) && (((c) - ' ') <= 077 + 1) )
+#define DEC(c) (((c) - ' ') & 077) /* single character decode */
+#define IS_DEC(c) ( (((c) - ' ') >= 0) && (((c) - ' ') <= 077 + 1) )
#define OUT_OF_RANGE do { \
warnx("%s: %s: character out of range: [%d-%d]", \
infile, outfile, 1 + ' ', 077 + ' ' + 1); \
- return (1); \
+ return (1); \
} while (0)
/*
@@ -364,8 +368,8 @@ uu_decode(void)
for (++p; i > 0; p += 4, i -= 3)
if (i >= 3) {
if (!(IS_DEC(*p) && IS_DEC(*(p + 1)) &&
- IS_DEC(*(p + 2)) && IS_DEC(*(p + 3))))
- OUT_OF_RANGE;
+ IS_DEC(*(p + 2)) && IS_DEC(*(p + 3))))
+ OUT_OF_RANGE;
ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4;
putc(ch, outfp);
@@ -373,8 +377,7 @@ uu_decode(void)
putc(ch, outfp);
ch = DEC(p[2]) << 6 | DEC(p[3]);
putc(ch, outfp);
- }
- else {
+ } else {
if (i >= 1) {
if (!(IS_DEC(*p) && IS_DEC(*(p + 1))))
OUT_OF_RANGE;
@@ -383,56 +386,85 @@ uu_decode(void)
}
if (i >= 2) {
if (!(IS_DEC(*(p + 1)) &&
- IS_DEC(*(p + 2))))
- OUT_OF_RANGE;
+ IS_DEC(*(p + 2))))
+ OUT_OF_RANGE;
ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
putc(ch, outfp);
}
if (i >= 3) {
if (!(IS_DEC(*(p + 2)) &&
- IS_DEC(*(p + 3))))
- OUT_OF_RANGE;
+ IS_DEC(*(p + 3))))
+ OUT_OF_RANGE;
ch = DEC(p[2]) << 6 | DEC(p[3]);
putc(ch, outfp);
}
}
}
switch (getline(buf, sizeof(buf))) {
- case 0: return (0);
- case 1: return (1);
- default: return (checkend(buf, "end", "no \"end\" line"));
+ case 0:
+ return (0);
+ case 1:
+ return (1);
+ default:
+ return (checkend(buf, "end", "no \"end\" line"));
}
}
static int
base64_decode(void)
{
- int n;
- char inbuf[MAXPATHLEN+1];
+ int n, count, count4;
+ char inbuf[MAXPATHLEN + 1], *p;
unsigned char outbuf[MAXPATHLEN * 4];
+ char leftover[MAXPATHLEN + 1];
+ leftover[0] = '\0';
for (;;) {
- switch (getline(inbuf, sizeof(inbuf))) {
- case 0: return (0);
- case 1: return (1);
+ strcpy(inbuf, leftover);
+ switch (getline(inbuf + strlen(inbuf),
+ sizeof(inbuf) - strlen(inbuf))) {
+ case 0:
+ return (0);
+ case 1:
+ return (1);
}
+
+ count = 0;
+ count4 = -1;
+ p = inbuf;
+ while (*p != '\0') {
+ /*
+ * Base64 encoded strings have the following
+ * characters in them: A-Z, a-z, 0-9 and +, / and =
+ */
+ if (isalnum(*p) || *p == '+' || *p == '/' || *p == '=')
+ count++;
+ if (count % 4 == 0)
+ count4 = p - inbuf;
+ p++;
+ }
+
+ strcpy(leftover, inbuf + count4 + 1);
+ inbuf[count4 + 1] = 0;
+
n = b64_pton(inbuf, outbuf, sizeof(outbuf));
+
if (n < 0)
break;
fwrite(outbuf, 1, n, outfp);
}
- return (checkend(inbuf, "====",
- "error decoding base64 input stream"));
+ return (checkend(inbuf, "====", "error decoding base64 input stream"));
}
static void
usage(void)
{
+
(void)fprintf(stderr,
-"usage: uudecode [-cimprs] [file ...]\n"
-" uudecode [-i] -o output_file [file]\n"
-" b64decode [-cimprs] [file ...]\n"
-" b64decode [-i] -o output_file [file]\n");
+ "usage: uudecode [-cimprs] [file ...]\n"
+ " uudecode [-i] -o output_file [file]\n"
+ " b64decode [-cimprs] [file ...]\n"
+ " b64decode [-i] -o output_file [file]\n");
exit(1);
}
diff --git a/usr.sbin/apmd/apmd.8 b/usr.sbin/apmd/apmd.8
index 892826c..4ca8aae 100644
--- a/usr.sbin/apmd/apmd.8
+++ b/usr.sbin/apmd/apmd.8
@@ -143,7 +143,6 @@ The structure of the
.Nm
configuration file is quite simple.
For example:
-.Pp
.Bd -literal
apm_event SUSPENDREQ {
exec "sync && sync && sync";
@@ -161,7 +160,6 @@ to receive the APM event
command 3 times and wait for a while, then execute
.Nm zzz ( Ns Nm apm Fl z )
to put the system in the suspend state.
-.Pp
.Bl -bullet
.It
The apm_event keyword
diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8
index 6747f8e..12bae3a 100644
--- a/usr.sbin/gpioctl/gpioctl.8
+++ b/usr.sbin/gpioctl/gpioctl.8
@@ -95,7 +95,6 @@ toggle value of provided pin number
be verbose: for each listed pin print current configuration
.El
.Sh EXAMPLES
-.Pp
.Bl -bullet
.It
List pins available on GPIO controller defined by device /dev/gpioctl0
diff --git a/usr.sbin/pc-sysinstall/backend-query/list-tzones.sh b/usr.sbin/pc-sysinstall/backend-query/list-tzones.sh
index 640272e..c7009b0 100755
--- a/usr.sbin/pc-sysinstall/backend-query/list-tzones.sh
+++ b/usr.sbin/pc-sysinstall/backend-query/list-tzones.sh
@@ -25,19 +25,10 @@
#
# $FreeBSD$
-rm ${TMPDIR}/.tzonetmp >/dev/null 2>/dev/null
-
# Backend script which lists all the available timezones for front-ends to display
-while read line
-do
- echo "$line" | grep "^#" >/dev/null 2>/dev/null
- if [ "$?" != "0" ]
- then
- echo "$line" | tr -s "\t" ":" | cut -d ":" -f 3-4 >>${TMPDIR}/.tzonetmp
- fi
-done < /usr/share/zoneinfo/zone.tab
-
-sort ${TMPDIR}/.tzonetmp
-rm -f ${TMPDIR}/.tzonetmp >/dev/null 2>/dev/null
+egrep -v '^#' /usr/share/zoneinfo/zone.tab |\
+ tr -s "\t" ":" |\
+ cut -d ":" -f 3-4 |\
+ sort
exit 0
diff --git a/usr.sbin/pc-sysinstall/backend-query/sys-mem.sh b/usr.sbin/pc-sysinstall/backend-query/sys-mem.sh
index d8555af..bc0e3a2 100755
--- a/usr.sbin/pc-sysinstall/backend-query/sys-mem.sh
+++ b/usr.sbin/pc-sysinstall/backend-query/sys-mem.sh
@@ -25,7 +25,4 @@
#
# $FreeBSD$
-MEM=`sysctl hw.realmem | sed "s|hw.realmem: ||g"`
-MEM=`expr $MEM / 1024`
-MEM=`expr $MEM / 1024`
-echo $MEM
+expr $(sysctl -n hw.realmem) / 1048576
diff --git a/usr.sbin/ppp/ipcp.c b/usr.sbin/ppp/ipcp.c
index 31aa07d..80b3a1b 100644
--- a/usr.sbin/ppp/ipcp.c
+++ b/usr.sbin/ppp/ipcp.c
@@ -319,8 +319,11 @@ ipcp_WriteDNS(struct ipcp *ipcp)
strerror(errno));
return 0;
}
- } else
+ } else {
umask(mask);
+ log_Printf(LogERROR,"fopen(\"%s\", \"w\") failed: %s\n", _PATH_RESCONF,
+ strerror(errno));
+ }
return 1;
}
OpenPOWER on IntegriCloud