summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-11-25 18:36:44 +0000
committerdim <dim@FreeBSD.org>2010-11-25 18:36:44 +0000
commitce4ad7ab6156be02b01fdf19735a19a9c4d5a8ad (patch)
tree7fb434479af2e2b02b32b54ca0e7312065b0f6ed
parent71b42433f68a7680bcd07cef6c81b5a9bbe4e948 (diff)
parent835f186e056004cd67b3e5a1ee17f3ae1202646c (diff)
downloadFreeBSD-src-ce4ad7ab6156be02b01fdf19735a19a9c4d5a8ad.zip
FreeBSD-src-ce4ad7ab6156be02b01fdf19735a19a9c4d5a8ad.tar.gz
Sync: merge r215709 through r215824 from ^/head.
-rw-r--r--bin/sh/arith_lex.l10
-rw-r--r--bin/sh/cd.c19
-rw-r--r--bin/sh/eval.c3
-rw-r--r--bin/sh/expand.c17
-rw-r--r--bin/sh/histedit.c3
-rw-r--r--bin/sh/memalloc.c17
-rw-r--r--bin/sh/memalloc.h4
-rw-r--r--bin/sh/miscbltin.c11
-rw-r--r--bin/sh/parser.c13
-rw-r--r--etc/defaults/rc.conf2
-rwxr-xr-xetc/rc.d/gptboot1
-rwxr-xr-xetc/rc.d/mountcritlocal4
-rw-r--r--share/man/man4/bge.423
-rw-r--r--share/man/man4/msk.423
-rw-r--r--share/man/man4/nge.423
-rw-r--r--share/man/man4/sk.423
-rw-r--r--share/man/man4/stge.423
-rw-r--r--share/man/man4/vge.423
-rw-r--r--share/man/man5/rc.conf.513
-rw-r--r--share/man/man9/vrele.96
-rw-r--r--share/misc/bsd-family-tree29
-rw-r--r--sys/amd64/acpica/acpi_switch.S6
-rw-r--r--sys/amd64/acpica/acpi_wakecode.S2
-rw-r--r--sys/amd64/acpica/acpi_wakeup.c2
-rw-r--r--sys/amd64/amd64/cpu_switch.S2
-rw-r--r--sys/amd64/amd64/mp_machdep.c1
-rw-r--r--sys/amd64/amd64/pmap.c3
-rw-r--r--sys/amd64/include/specialreg.h9
-rw-r--r--sys/boot/common/load_elf.c3
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c3
-rw-r--r--sys/compat/ia32/ia32_signal.h5
-rw-r--r--sys/compat/ia32/ia32_util.h5
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h1
-rw-r--r--sys/compat/ndis/subr_ndis.c24
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c131
-rw-r--r--sys/dev/ahci/ahci.c2
-rw-r--r--sys/dev/cas/if_cas.c39
-rw-r--r--sys/dev/e1000/e1000_api.c2
-rw-r--r--sys/dev/e1000/e1000_hw.h2
-rw-r--r--sys/dev/e1000/if_em.c138
-rw-r--r--sys/dev/e1000/if_igb.c326
-rw-r--r--sys/dev/e1000/if_igb.h17
-rw-r--r--sys/dev/fxp/if_fxp.c36
-rw-r--r--sys/dev/fxp/if_fxpvar.h4
-rw-r--r--sys/dev/gem/if_gem.c16
-rw-r--r--sys/dev/mii/bmtphy.c67
-rw-r--r--sys/dev/mii/gentbi.c2
-rw-r--r--sys/dev/mii/inphy.c5
-rw-r--r--sys/dev/mii/mii.c10
-rw-r--r--sys/dev/mii/miidevs2
-rw-r--r--sys/dev/mii/nsgphy.c2
-rw-r--r--sys/dev/mii/nsphyter.c6
-rw-r--r--sys/dev/mii/ukphy.c2
-rw-r--r--sys/dev/pci/pci.c29
-rw-r--r--sys/dev/pci/pci_pci.c2
-rw-r--r--sys/dev/usb/controller/usb_controller.c8
-rw-r--r--sys/dev/usb/serial/u3g.c2
-rw-r--r--sys/dev/usb/usb_bus.h2
-rw-r--r--sys/dev/usb/usb_pf.c1661
-rw-r--r--sys/dev/usb/usb_pf.h225
-rw-r--r--sys/dev/usb/usbdevs10
-rw-r--r--sys/i386/i386/pmap.c3
-rw-r--r--sys/i386/include/specialreg.h9
-rw-r--r--sys/i386/include/xen/hypercall.h3
-rw-r--r--sys/i386/isa/npx.c2
-rw-r--r--sys/i386/pci/pci_bus.c5
-rw-r--r--sys/i386/xen/pmap.c12
-rw-r--r--sys/i386/xen/xen_machdep.c22
-rw-r--r--sys/kern/kern_tc.c2
-rw-r--r--sys/kern/subr_taskqueue.c4
-rw-r--r--sys/kern/vfs_mount.c6
-rw-r--r--sys/kern/vfs_subr.c20
-rw-r--r--sys/net/bpf_buffer.c4
-rw-r--r--sys/net/if_vlan.c42
-rw-r--r--sys/netgraph/ng_pipe.c232
-rw-r--r--sys/netinet/ip_carp.c31
-rw-r--r--sys/netinet/sctp_cc_functions.c58
-rw-r--r--sys/netinet/sctp_dtrace_declare.h73
-rw-r--r--sys/netinet/sctp_dtrace_define.h201
-rw-r--r--sys/netinet/sctp_pcb.c1
-rw-r--r--sys/netinet/sctp_uio.h2
-rw-r--r--sys/sys/elf_common.h1
-rw-r--r--sys/sys/sysctl.h1
-rw-r--r--sys/vm/vm_object.c4
-rw-r--r--sys/x86/x86/local_apic.c2
-rw-r--r--tools/tools/sysbuild/sysbuild.sh51
-rw-r--r--usr.bin/locate/locate/locate.h8
-rw-r--r--usr.bin/netstat/inet.c5
-rw-r--r--usr.sbin/iostat/iostat.818
-rw-r--r--usr.sbin/kernbb/Makefile12
-rw-r--r--usr.sbin/kernbb/kernbb.882
-rw-r--r--usr.sbin/kernbb/kernbb.c145
-rw-r--r--usr.sbin/usbdump/usbdump.c76
93 files changed, 1412 insertions, 2829 deletions
diff --git a/bin/sh/arith_lex.l b/bin/sh/arith_lex.l
index 1113d29..b4a04d3 100644
--- a/bin/sh/arith_lex.l
+++ b/bin/sh/arith_lex.l
@@ -53,7 +53,15 @@ int yylex(void);
#undef YY_INPUT
#define YY_INPUT(buf,result,max) \
- result = (*buf = *arith_buf++) ? 1 : YY_NULL;
+ do { \
+ result = strnlen(arith_buf, max); \
+ if (result == 0) \
+ result = YY_NULL; \
+ else { \
+ memcpy(buf, arith_buf, result); \
+ arith_buf += result; \
+ } \
+ } while (0);
#define YY_NO_UNPUT
#define YY_NO_INPUT
%}
diff --git a/bin/sh/cd.c b/bin/sh/cd.c
index cec7496..068dfb7 100644
--- a/bin/sh/cd.c
+++ b/bin/sh/cd.c
@@ -192,8 +192,7 @@ cdlogical(char *dest)
STPUTC('/', p);
first = 0;
component = q;
- while (*q)
- STPUTC(*q++, p);
+ STPUTS(q, p);
if (equal(component, ".."))
continue;
STACKSTRNUL(p);
@@ -219,10 +218,13 @@ cdphysical(char *dest)
char *p;
INTOFF;
- if (chdir(dest) < 0 || (p = findcwd(NULL)) == NULL) {
+ if (chdir(dest) < 0) {
INTON;
return (-1);
}
+ p = findcwd(NULL);
+ if (p == NULL)
+ out2fmt_flush("cd: warning: failed to get name of current directory\n");
updatepwd(p);
INTON;
return (0);
@@ -270,10 +272,8 @@ findcwd(char *dir)
scopy(dir, cdcomppath);
STARTSTACKSTR(new);
if (*dir != '/') {
- p = curdir;
- while (*p)
- STPUTC(*p++, new);
- if (p[-1] == '/')
+ STPUTS(curdir, new);
+ if (STTOPC(new) == '/')
STUNPUTC(new);
}
while ((p = getcomponent()) != NULL) {
@@ -281,8 +281,7 @@ findcwd(char *dir)
while (new > stackblock() && (STUNPUTC(new), *new) != '/');
} else if (*p != '\0' && ! equal(p, ".")) {
STPUTC('/', new);
- while (*p)
- STPUTC(*p++, new);
+ STPUTS(p, new);
}
}
if (new == stackblock())
@@ -304,7 +303,7 @@ updatepwd(char *dir)
if (prevdir)
ckfree(prevdir);
prevdir = curdir;
- curdir = savestr(dir);
+ curdir = dir ? savestr(dir) : NULL;
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
}
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index c306e73..5bae2f2 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -135,8 +135,7 @@ evalcmd(int argc, char **argv)
STARTSTACKSTR(concat);
ap = argv + 2;
for (;;) {
- while (*p)
- STPUTC(*p++, concat);
+ STPUTS(p, concat);
if ((p = *ap++) == NULL)
break;
STPUTC(' ', concat);
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index d251ed0..7a3b9d9 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -225,6 +225,7 @@ argstr(char *p, int flag)
if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE)))
p = exptilde(p, flag);
for (;;) {
+ CHECKSTRSPACE(2, expdest);
switch (c = *p++) {
case '\0':
case CTLENDVAR:
@@ -235,16 +236,16 @@ argstr(char *p, int flag)
if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=')
break;
if ((flag & EXP_FULL) != 0)
- STPUTC(c, expdest);
+ USTPUTC(c, expdest);
break;
case CTLQUOTEEND:
lit_quoted = 0;
break;
case CTLESC:
if (quotes)
- STPUTC(c, expdest);
+ USTPUTC(c, expdest);
c = *p++;
- STPUTC(c, expdest);
+ USTPUTC(c, expdest);
if (split_lit && !lit_quoted)
recordregion(expdest - stackblock() -
(quotes ? 2 : 1),
@@ -267,7 +268,7 @@ argstr(char *p, int flag)
* sort of a hack - expand tildes in variable
* assignments (after the first '=' and after ':'s).
*/
- STPUTC(c, expdest);
+ USTPUTC(c, expdest);
if (split_lit && !lit_quoted)
recordregion(expdest - stackblock() - 1,
expdest - stackblock(), 0);
@@ -279,7 +280,7 @@ argstr(char *p, int flag)
}
break;
default:
- STPUTC(c, expdest);
+ USTPUTC(c, expdest);
if (split_lit && !lit_quoted)
recordregion(expdest - stackblock() - 1,
expdest - stackblock(), 0);
@@ -902,8 +903,7 @@ varvalue(char *name, int quoted, int subtype, int flag)
STPUTC(*p++, expdest); \
} \
} else \
- while (*p) \
- STPUTC(*p++, expdest); \
+ STPUTS(p, expdest); \
} while (0)
@@ -1573,8 +1573,7 @@ cvtnum(int num, char *buf)
if (neg)
*--p = '-';
- while (*p)
- STPUTC(*p++, buf);
+ STPUTS(p, buf);
return buf;
}
diff --git a/bin/sh/histedit.c b/bin/sh/histedit.c
index 3fc1782..26d46a8 100644
--- a/bin/sh/histedit.c
+++ b/bin/sh/histedit.c
@@ -411,8 +411,7 @@ fc_replace(const char *s, char *p, char *r)
STARTSTACKSTR(dest);
while (*s) {
if (*s == *p && strncmp(s, p, plen) == 0) {
- while (*r)
- STPUTC(*r++, dest);
+ STPUTS(r, dest);
s += plen;
*p = '\0'; /* so no more matches */
} else
diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c
index 9158719..d00b4d9 100644
--- a/bin/sh/memalloc.c
+++ b/bin/sh/memalloc.c
@@ -340,3 +340,20 @@ ungrabstackstr(char *s, char *p)
stacknxt = s;
sstrnleft = stacknleft - (p - s);
}
+
+
+char *
+stputbin(const char *data, int len, char *p)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ STPUTC(data[i], p);
+ return (p);
+}
+
+char *
+stputs(const char *data, char *p)
+{
+ return (stputbin(data, strlen(data), p));
+}
diff --git a/bin/sh/memalloc.h b/bin/sh/memalloc.h
index 563927a..88848dd 100644
--- a/bin/sh/memalloc.h
+++ b/bin/sh/memalloc.h
@@ -61,6 +61,8 @@ void grabstackblock(int);
char *growstackstr(void);
char *makestrspace(void);
void ungrabstackstr(char *, char *);
+char *stputbin(const char *data, int len, char *p);
+char *stputs(const char *data, char *p);
@@ -82,3 +84,5 @@ void ungrabstackstr(char *, char *);
#define STTOPC(p) p[-1]
#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount))
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
+#define STPUTBIN(s, len, p) p = stputbin((s), (len), p)
+#define STPUTS(s, p) p = stputs((s), p)
diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c
index d9ac8a3..dc200b6 100644
--- a/bin/sh/miscbltin.c
+++ b/bin/sh/miscbltin.c
@@ -172,11 +172,12 @@ readcmd(int argc __unused, char **argv __unused)
}
if (c == '\0')
continue;
+ CHECKSTRSPACE(1, p);
if (backslash) {
backslash = 0;
startword = 0;
if (c != '\n')
- STPUTC(c, p);
+ USTPUTC(c, p);
continue;
}
if (!rflag && c == '\\') {
@@ -194,14 +195,14 @@ readcmd(int argc __unused, char **argv __unused)
if (is_ifs == 1) {
/* Ignore leading IFS whitespace */
if (saveall)
- STPUTC(c, p);
+ USTPUTC(c, p);
continue;
}
if (is_ifs == 2 && startword == 1) {
/* Only one non-whitespace IFS per word */
startword = 2;
if (saveall)
- STPUTC(c, p);
+ USTPUTC(c, p);
continue;
}
}
@@ -212,7 +213,7 @@ readcmd(int argc __unused, char **argv __unused)
if (saveall)
/* Not just a spare terminator */
saveall++;
- STPUTC(c, p);
+ USTPUTC(c, p);
continue;
}
@@ -222,7 +223,7 @@ readcmd(int argc __unused, char **argv __unused)
if (ap[1] == NULL) {
/* Last variable needs all IFS chars */
saveall++;
- STPUTC(c, p);
+ USTPUTC(c, p);
continue;
}
diff --git a/bin/sh/parser.c b/bin/sh/parser.c
index 01907e8..2687003 100644
--- a/bin/sh/parser.c
+++ b/bin/sh/parser.c
@@ -1017,6 +1017,7 @@ parsebackq(char *out, struct nodelist **pbqlist,
setprompt(2);
needprompt = 0;
}
+ CHECKSTRSPACE(2, oout);
switch (c = pgetc()) {
case '`':
goto done;
@@ -1031,14 +1032,14 @@ parsebackq(char *out, struct nodelist **pbqlist,
/*
* If eating a newline, avoid putting
* the newline into the new character
- * stream (via the STPUTC after the
+ * stream (via the USTPUTC after the
* switch).
*/
continue;
}
if (c != '\\' && c != '`' && c != '$'
&& (!dblquote || c != '"'))
- STPUTC('\\', oout);
+ USTPUTC('\\', oout);
break;
case '\n':
@@ -1054,10 +1055,10 @@ parsebackq(char *out, struct nodelist **pbqlist,
default:
break;
}
- STPUTC(c, oout);
+ USTPUTC(c, oout);
}
done:
- STPUTC('\0', oout);
+ USTPUTC('\0', oout);
olen = oout - stackblock();
INTOFF;
ostr = ckmalloc(olen);
@@ -1444,7 +1445,6 @@ parsesub: {
char *p;
static const char types[] = "}-+?=";
int bracketed_name = 0; /* used to handle ${[0-9]*} variables */
- int i;
int linno;
int length;
@@ -1498,8 +1498,7 @@ parsesub: {
linno -= funclinno - 1;
snprintf(buf, sizeof(buf), "%d", linno);
STADJUST(-6, out);
- for (i = 0; buf[i] != '\0'; i++)
- STPUTC(buf[i], out);
+ STPUTS(buf, out);
flags |= VSLINENO;
}
} else if (is_digit(c)) {
diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index 7109086..e542f9b 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -58,6 +58,8 @@ rc_conf_files="/etc/rc.conf /etc/rc.conf.local"
# ZFS support
zfs_enable="NO" # Set to YES to automatically mount ZFS file systems
+gptboot_enable="YES" # GPT boot success/failure reporting.
+
# Experimental - test before enabling
gbde_autoattach_all="NO" # YES automatically mounts gbde devices from fstab
gbde_devices="NO" # Devices to automatically attach (list, or AUTO)
diff --git a/etc/rc.d/gptboot b/etc/rc.d/gptboot
index ace94b8..abfcaa1 100755
--- a/etc/rc.d/gptboot
+++ b/etc/rc.d/gptboot
@@ -34,6 +34,7 @@
. /etc/rc.subr
name="gptboot"
+rcvar=`set_rcvar`
start_cmd="gptboot_report"
gptboot_report()
diff --git a/etc/rc.d/mountcritlocal b/etc/rc.d/mountcritlocal
index acd269e..06bf464 100755
--- a/etc/rc.d/mountcritlocal
+++ b/etc/rc.d/mountcritlocal
@@ -5,13 +5,13 @@
# PROVIDE: mountcritlocal
# REQUIRE: root hostid_save mdconfig
-# KEYWORD: nojail
+# KEYWORD: nojail shutdown
. /etc/rc.subr
name="mountcritlocal"
start_cmd="mountcritlocal_start"
-stop_cmd=":"
+stop_cmd=sync
mountcritlocal_start()
{
diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4
index 086045f..cf0d84a 100644
--- a/share/man/man4/bge.4
+++ b/share/man/man4/bge.4
@@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 7, 2010
+.Dd November 23, 2010
.Dt BGE 4
.Os
.Sh NAME
@@ -144,27 +144,6 @@ Force full duplex operation.
Force half duplex operation.
.El
.Pp
-The
-.Nm
-driver also supports one special link option for 1000baseTX cards:
-.Bl -tag -width ".Cm link0"
-.It Cm link0
-With 1000baseTX cards, establishing a link between two ports requires
-that one port be configured as a master and the other a slave.
-With autonegotiation,
-the master/slave settings will be chosen automatically.
-However when manually selecting the link state, it is necessary to
-force one side of the link to be a master and the other a slave.
-The
-.Nm
-driver configures the ports as slaves by default.
-Setting the
-.Cm link0
-flag with
-.Xr ifconfig 8
-will set a port as a master instead.
-.El
-.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh HARDWARE
diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4
index 7ea12dd..fe32a68 100644
--- a/share/man/man4/msk.4
+++ b/share/man/man4/msk.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd April 30, 2010
+.Dd November 23, 2010
.Dt MSK 4
.Os
.Sh NAME
@@ -125,27 +125,6 @@ Force full duplex operation.
Force half duplex operation.
.El
.Pp
-The
-.Nm
-driver also supports one special link option for 1000baseTX cards:
-.Bl -tag -width ".Cm link0"
-.It Cm link0
-With 1000baseTX cards, establishing a link between two ports requires
-that one port is configured as master and the other one as slave.
-With autonegotiation,
-the master/slave settings will be chosen automatically.
-However when manually selecting the link state, it is necessary to
-force one side of the link to be a master and the other a slave.
-The
-.Nm
-driver configures the ports as slaves by default.
-Setting the
-.Cm link0
-flag with
-.Xr ifconfig 8
-will set a port as a master instead.
-.El
-.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh HARDWARE
diff --git a/share/man/man4/nge.4 b/share/man/man4/nge.4
index 7c69247..ec02052 100644
--- a/share/man/man4/nge.4
+++ b/share/man/man4/nge.4
@@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 21, 2009
+.Dd November 23, 2010
.Dt NGE 4
.Os
.Sh NAME
@@ -131,27 +131,6 @@ Force full duplex operation.
Force half duplex operation.
.El
.Pp
-The
-.Nm
-driver also supports one special link option for 1000baseTX cards:
-.Bl -tag -width link0
-.It Cm link0
-With 1000baseTX cards, establishing a link between two ports requires
-that one port be configured as a master and the other a slave.
-With autonegotiation,
-the master/slave settings will be chosen automatically.
-However when manually selecting the link state, it is necessary to
-force one side of the link to be a master and the other a slave.
-The
-.Nm
-driver configures the ports as slaves by default.
-Setting the
-.Cm link0
-flag with
-.Xr ifconfig 8
-will set a port as a master instead.
-.El
-.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh HARDWARE
diff --git a/share/man/man4/sk.4 b/share/man/man4/sk.4
index 88a4286..71e30c9 100644
--- a/share/man/man4/sk.4
+++ b/share/man/man4/sk.4
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 23, 2009
+.Dd November 23, 2010
.Dt SK 4
.Os
.Sh NAME
@@ -132,27 +132,6 @@ Force full duplex operation
Force half duplex operation.
.El
.Pp
-The
-.Nm
-driver also supports one special link option for 1000baseTX cards:
-.Bl -tag -width xxxxxxxxxxxxxxxxxxxx
-.It link0
-With 1000baseTX cards, establishing a link between two ports requires
-that one port is configured as master and the other one as slave.
-With autonegotiation,
-the master/slave settings will be chosen automatically.
-However when manually selecting the link state, it is necessary to
-force one side of the link to be a master and the other a slave.
-The
-.Nm
-driver configures the ports as slaves by default.
-Setting the
-.Ar link0
-flag with
-.Xr ifconfig 8
-will set a port as a master instead.
-.El
-.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh HARDWARE
diff --git a/share/man/man4/stge.4 b/share/man/man4/stge.4
index d9c75ef..bfcaab0 100644
--- a/share/man/man4/stge.4
+++ b/share/man/man4/stge.4
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2006
+.Dd November 23, 2010
.Dt STGE 4
.Os
.Sh NAME
@@ -129,27 +129,6 @@ Force full duplex operation.
Force half duplex operation.
.El
.Pp
-The
-.Nm
-driver also supports one special link option for 1000baseTX cards:
-.Bl -tag -width ".Cm link0"
-.It Cm link0
-With 1000baseTX cards, establishing a link between two ports requires
-that one port is configured as master and the other one as slave.
-With autonegotiation,
-the master/slave settings will be chosen automatically.
-However when manually selecting the link state, it is necessary to
-force one side of the link to be a master and the other a slave.
-The
-.Nm
-driver configures the ports as slaves by default.
-Setting the
-.Cm link0
-flag with
-.Xr ifconfig 8
-will set a port as a master instead.
-.El
-.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh HARDWARE
diff --git a/share/man/man4/vge.4 b/share/man/man4/vge.4
index f6ce47c..ae0206a 100644
--- a/share/man/man4/vge.4
+++ b/share/man/man4/vge.4
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 18, 2009
+.Dd November 23, 2010
.Dt VGE 4
.Os
.Sh NAME
@@ -137,27 +137,6 @@ Force full duplex operation.
Force half duplex operation.
.El
.Pp
-The
-.Nm
-driver also supports one special link option for 1000baseTX cards:
-.Bl -tag -width ".Cm link0"
-.It Cm link0
-With 1000baseTX cards, establishing a link between two ports requires
-that one port be configured as a master and the other a slave.
-With autonegotiation,
-the master/slave settings will be chosen automatically.
-However when manually selecting the link state, it is necessary to
-force one side of the link to be a master and the other a slave.
-The
-.Nm
-driver configures the ports as slaves by default.
-Setting the
-.Cm link0
-flag with
-.Xr ifconfig 8
-will set a port as a master instead.
-.El
-.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
.Sh HARDWARE
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 2a4ff49..990222f 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd November 13, 2010
+.Dd November 24, 2010
.Dt RC.CONF 5
.Os
.Sh NAME
@@ -1575,6 +1575,17 @@ If set to
.Pa /etc/rc.d/zfs
will attempt to automatically mount ZFS file systems and initialize ZFS volumes
(ZVOLs).
+.It Va gptboot_enable
+.Pq Vt bool
+If set to
+.Dq Li YES ,
+.Pa /etc/rc.d/gptboot
+will log if the system successfully (or not) booted from a GPT partition,
+which had the
+.Ar bootonce
+attribute set using
+.Xr gpart 8
+utility.
.It Va gbde_autoattach_all
.Pq Vt bool
If set to
diff --git a/share/man/man9/vrele.9 b/share/man/man9/vrele.9
index 0b9b736..d29ca5b 100644
--- a/share/man/man9/vrele.9
+++ b/share/man/man9/vrele.9
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 17, 2010
+.Dd November 20, 2010
.Dt VRELE 9
.Os
.Sh NAME
@@ -74,10 +74,6 @@ with less overhead.
The
.Fn vunref
function takes a locked vnode as argument, and returns with the vnode locked.
-Nonetheless, the
-.Fn vunref
-might drop the vnode lock during the operation, so caller should not expect
-that non-doomed vnode is still non-doomed after the function returned.
.Pp
Any code in the system which signified its use of a vnode by usecount
should call one of the listed function to decrement use counter.
diff --git a/share/misc/bsd-family-tree b/share/misc/bsd-family-tree
index edbd689..9e20ad2 100644
--- a/share/misc/bsd-family-tree
+++ b/share/misc/bsd-family-tree
@@ -228,20 +228,20 @@ FreeBSD 5.2 | | | |
| FreeBSD 7.1 | | | |
| | | | | DragonFly 2.2.0
| FreeBSD 7.2 | NetBSD 5.0 OpenBSD 4.5 |
- | \ | | | |
- | | | | | DragonFly 2.4.0
- | | | | OpenBSD 4.6 |
- | | | | | |
- *--FreeBSD | | | | |
- | 8.0 | | | | |
- | | FreeBSD | | | |
- | | 7.3 | | | DragonFly 2.6.0
- | | | | OpenBSD 4.7 |
- | FreeBSD | | | |
- | 8.1 | | | |
- | | | | | DragonFly 2.8.0
- | | | | OpenBSD 4.8 |
- | V | | | |
+ | \ | | | | |
+ | | | | | | DragonFly 2.4.0
+ | | | | | OpenBSD 4.6 |
+ | | | | | | |
+ *--FreeBSD | | | | | |
+ | 8.0 | | | | | |
+ | | FreeBSD | | | | |
+ | | 7.3 | | | | DragonFly 2.6.0
+ | | | | | OpenBSD 4.7 |
+ | FreeBSD | | | | |
+ | 8.1 | | | | |
+ | | | | | | DragonFly 2.8.0
+ | | | | | OpenBSD 4.8 |
+ | V | | NetBSD 5.1 | |
| | | | |
FreeBSD 9 -current | NetBSD -current OpenBSD -current |
| | | | |
@@ -523,6 +523,7 @@ OpenBSD 4.7 2010-05-19 [OBD]
FreeBSD 8.1 2010-07-24 [FBD]
DragonFly 2.8.0 2010-10-30 [DFB]
OpenBSD 4.8 2010-11-01 [OBD]
+NetBSD 5.1 2010-11-19 [NBD]
Bibliography
------------------------
diff --git a/sys/amd64/acpica/acpi_switch.S b/sys/amd64/acpica/acpi_switch.S
index fbe4097..45bad1f 100644
--- a/sys/amd64/acpica/acpi_switch.S
+++ b/sys/amd64/acpica/acpi_switch.S
@@ -76,12 +76,6 @@ ENTRY(acpi_restorecpu)
movl WAKEUP_CTX(efer), %eax
wrmsr
- /* Restore PAT. */
- movl $MSR_PAT, %ecx
- movl WAKEUP_CTX(pat), %eax
- movl 4 + WAKEUP_CTX(pat), %edx
- wrmsr
-
/* Restore fast syscall stuff. */
movl $MSR_STAR, %ecx
movl WAKEUP_CTX(star), %eax
diff --git a/sys/amd64/acpica/acpi_wakecode.S b/sys/amd64/acpica/acpi_wakecode.S
index e131c97..49d14f5 100644
--- a/sys/amd64/acpica/acpi_wakecode.S
+++ b/sys/amd64/acpica/acpi_wakecode.S
@@ -274,8 +274,6 @@ wakeup_gdt:
ALIGN_DATA
wakeup_efer:
.quad 0
-wakeup_pat:
- .quad 0
wakeup_star:
.quad 0
wakeup_lstar:
diff --git a/sys/amd64/acpica/acpi_wakeup.c b/sys/amd64/acpica/acpi_wakeup.c
index c25d802..57341c9 100644
--- a/sys/amd64/acpica/acpi_wakeup.c
+++ b/sys/amd64/acpica/acpi_wakeup.c
@@ -278,6 +278,7 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
for (;;)
ia32_pause();
} else {
+ pmap_init_pat();
PCPU_SET(switchtime, 0);
PCPU_SET(switchticks, ticks);
#ifdef SMP
@@ -372,7 +373,6 @@ acpi_install_wakeup_handler(struct acpi_softc *sc)
WAKECODE_FIXUP(wakeup_ctx, vm_offset_t,
WAKECODE_VADDR(sc) + wakeup_ctx);
WAKECODE_FIXUP(wakeup_efer, uint64_t, rdmsr(MSR_EFER));
- WAKECODE_FIXUP(wakeup_pat, uint64_t, rdmsr(MSR_PAT));
WAKECODE_FIXUP(wakeup_star, uint64_t, rdmsr(MSR_STAR));
WAKECODE_FIXUP(wakeup_lstar, uint64_t, rdmsr(MSR_LSTAR));
WAKECODE_FIXUP(wakeup_cstar, uint64_t, rdmsr(MSR_CSTAR));
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index 952a70b..3ad0ef7 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -276,7 +276,7 @@ load_dr:
do_tss: movq %rdx,PCPU(TSSP)
movq %rdx,%rcx
movq PCPU(TSS),%rax
- movw %rcx,2(%rax)
+ movw %cx,2(%rax)
shrq $16,%rcx
movb %cl,4(%rax)
shrq $8,%rcx
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 07380ff..2e85d5f 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -1410,6 +1410,7 @@ cpususpend_handler(void)
wbinvd();
atomic_set_int(&stopped_cpus, cpumask);
} else {
+ pmap_init_pat();
PCPU_SET(switchtime, 0);
PCPU_SET(switchticks, ticks);
}
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index c89affd..3794967 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -183,8 +183,7 @@ pt_entry_t pg_nx;
SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
static int pat_works = 1;
-TUNABLE_INT("vm.pmap.pat_works", &pat_works);
-SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RDTUN, &pat_works, 1,
+SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RD, &pat_works, 1,
"Is page attribute table fully functional?");
static int pg_ps_enabled = 1;
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index 23d1149..49513d9 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -136,6 +136,15 @@
#define CPUID2_AESNI 0x02000000
/*
+ * Important bits in the Thermal and Power Management flags
+ * CPUID.6 EAX and ECX.
+ */
+#define CPUTPM1_SENSOR 0x00000001
+#define CPUTPM1_TURBO 0x00000002
+#define CPUTPM1_ARAT 0x00000004
+#define CPUTPM2_EFFREQ 0x00000001
+
+/*
* Important bits in the AMD extended cpuid flags
*/
#define AMDID_SYSCALL 0x00000800
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index 35b3f0b..f0880b1 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -453,7 +453,8 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
}
result = archsw.arch_readin(ef->fd, lastaddr, shdr[i].sh_size);
if (result < 0 || (size_t)result != shdr[i].sh_size) {
- printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not read symbols - skipped!");
+ printf("\nelf" __XSTRING(__ELF_WORD_SIZE) "_loadimage: could not read symbols - skipped! (%ju != %ju)", (uintmax_t)result,
+ (uintmax_t)shdr[i].sh_size);
lastaddr = ssym;
ssym = 0;
goto nosyms;
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 8da3833..326cf03 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2365,7 +2365,8 @@ freebsd32_nmount(struct thread *td,
* Filter out MNT_ROOTFS. We do not want clients of nmount() in
* userspace to set this flag, but we must filter it out if we want
* MNT_UPDATE on the root file system to work.
- * MNT_ROOTFS should only be set in the kernel in vfs_mountroot_try().
+ * MNT_ROOTFS should only be set by the kernel when mounting its
+ * root file system.
*/
uap->flags &= ~MNT_ROOTFS;
diff --git a/sys/compat/ia32/ia32_signal.h b/sys/compat/ia32/ia32_signal.h
index 717ae74..757e384 100644
--- a/sys/compat/ia32/ia32_signal.h
+++ b/sys/compat/ia32/ia32_signal.h
@@ -29,6 +29,9 @@
* $FreeBSD$
*/
+#ifndef _COMPAT_IA32_IA32_SIGNAL_H
+#define _COMPAT_IA32_IA32_SIGNAL_H
+
struct ia32_mcontext {
u_int32_t mc_onstack; /* XXX - sigcontext compat. */
u_int32_t mc_gs; /* machine state (struct trapframe) */
@@ -188,3 +191,5 @@ extern int sz_freebsd4_ia32_sigcode;
extern void ia32_sendsig(sig_t, struct ksiginfo *, sigset_t *);
extern void ia32_setregs(struct thread *td, struct image_params *imgp,
u_long stack);
+
+#endif
diff --git a/sys/compat/ia32/ia32_util.h b/sys/compat/ia32/ia32_util.h
index d91bfde..f1cc6ed 100644
--- a/sys/compat/ia32/ia32_util.h
+++ b/sys/compat/ia32/ia32_util.h
@@ -28,6 +28,9 @@
* $FreeBSD$
*/
+#ifndef _COMPAT_IA32_IA32_UTIL_H
+#define _COMPAT_IA32_IA32_UTIL_H
+
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
@@ -51,3 +54,5 @@
struct syscall_args;
int ia32_fetch_syscall_args(struct thread *td, struct syscall_args *sa);
void ia32_set_syscall_retval(struct thread *, int);
+
+#endif
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index 769f93c..84c2a7f 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -1282,6 +1282,7 @@ typedef struct driver_object driver_object;
#define STATUS_PENDING 0x00000103
#define STATUS_FAILURE 0xC0000001
#define STATUS_NOT_IMPLEMENTED 0xC0000002
+#define STATUS_ACCESS_VIOLATION 0xC0000005
#define STATUS_INVALID_PARAMETER 0xC000000D
#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c
index a2905c2..a5caa88 100644
--- a/sys/compat/ndis/subr_ndis.c
+++ b/sys/compat/ndis/subr_ndis.c
@@ -254,6 +254,7 @@ static uint8_t
void *, void *);
static void NdisGetCurrentSystemTime(uint64_t *);
static void NdisGetSystemUpTime(uint32_t *);
+static uint32_t NdisGetVersion(void);
static void NdisInitializeString(unicode_string *, char *);
static void NdisInitAnsiString(ansi_string *, char *);
static void NdisInitUnicodeString(unicode_string *, uint16_t *);
@@ -274,6 +275,7 @@ static void NdisMapFile(ndis_status *, void **, ndis_handle);
static void NdisUnmapFile(ndis_handle);
static void NdisCloseFile(ndis_handle);
static uint8_t NdisSystemProcessorCount(void);
+static void NdisGetCurrentProcessorCounts(uint32_t *, uint32_t *, uint32_t *);
static void NdisMIndicateStatusComplete(ndis_handle);
static void NdisMIndicateStatus(ndis_handle, ndis_status,
void *, uint32_t);
@@ -2067,6 +2069,12 @@ NdisInterlockedDecrement(addend)
return (*addend);
}
+static uint32_t
+NdisGetVersion(void)
+{
+ return (0x00050001);
+}
+
static void
NdisInitializeEvent(event)
ndis_event *event;
@@ -2950,6 +2958,20 @@ NdisSystemProcessorCount()
return (mp_ncpus);
}
+static void
+NdisGetCurrentProcessorCounts(idle_count, kernel_and_user, index)
+ uint32_t *idle_count;
+ uint32_t *kernel_and_user;
+ uint32_t *index;
+{
+ struct pcpu *pcpu;
+
+ pcpu = pcpu_find(curthread->td_oncpu);
+ *index = pcpu->pc_cpuid;
+ *idle_count = pcpu->pc_cp_time[CP_IDLE];
+ *kernel_and_user = pcpu->pc_cp_time[CP_INTR];
+}
+
typedef void (*ndis_statusdone_handler)(ndis_handle);
typedef void (*ndis_status_handler)(ndis_handle, ndis_status,
void *, uint32_t);
@@ -3207,6 +3229,7 @@ image_patch_table ndis_functbl[] = {
IMPORT_SFUNC(NdisMIndicateStatusComplete, 1),
IMPORT_SFUNC(NdisMIndicateStatus, 4),
IMPORT_SFUNC(NdisSystemProcessorCount, 0),
+ IMPORT_SFUNC(NdisGetCurrentProcessorCounts, 3),
IMPORT_SFUNC(NdisUnchainBufferAtBack, 2),
IMPORT_SFUNC(NdisGetFirstBufferFromPacket, 5),
IMPORT_SFUNC(NdisGetFirstBufferFromPacketSafe, 6),
@@ -3224,6 +3247,7 @@ image_patch_table ndis_functbl[] = {
IMPORT_SFUNC(NdisFreeString, 1),
IMPORT_SFUNC(NdisGetCurrentSystemTime, 1),
IMPORT_SFUNC(NdisGetSystemUpTime, 1),
+ IMPORT_SFUNC(NdisGetVersion, 0),
IMPORT_SFUNC(NdisMSynchronizeWithInterrupt, 3),
IMPORT_SFUNC(NdisMAllocateSharedMemoryAsync, 4),
IMPORT_SFUNC(NdisInterlockedInsertHeadList, 3),
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index 80b1d98..c575eb9 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -128,6 +128,7 @@ static kspin_lock ntoskrnl_intlock;
static uint8_t RtlEqualUnicodeString(unicode_string *,
unicode_string *, uint8_t);
+static void RtlCopyString(ansi_string *, const ansi_string *);
static void RtlCopyUnicodeString(unicode_string *,
unicode_string *);
static irp *IoBuildSynchronousFsdRequest(uint32_t, device_object *,
@@ -180,7 +181,9 @@ static uint64_t _aullrem(uint64_t, uint64_t);
static uint64_t _aullshr(uint64_t, uint8_t);
static uint64_t _aullshl(uint64_t, uint8_t);
static slist_entry *ntoskrnl_pushsl(slist_header *, slist_entry *);
+static void InitializeSListHead(slist_header *);
static slist_entry *ntoskrnl_popsl(slist_header *);
+static void ExFreePoolWithTag(void *, uint32_t);
static void ExInitializePagedLookasideList(paged_lookaside_list *,
lookaside_alloc_func *, lookaside_free_func *,
uint32_t, size_t, uint32_t, uint16_t);
@@ -210,6 +213,10 @@ static void *MmMapLockedPagesSpecifyCache(mdl *,
static void MmUnmapLockedPages(void *, mdl *);
static device_t ntoskrnl_finddev(device_t, uint64_t, struct resource **);
static void RtlZeroMemory(void *, size_t);
+static void RtlSecureZeroMemory(void *, size_t);
+static void RtlFillMemory(void *, size_t, uint8_t);
+static void RtlMoveMemory(void *, const void *, size_t);
+static ndis_status RtlCharToInteger(const char *, uint32_t, uint32_t *);
static void RtlCopyMemory(void *, const void *, size_t);
static size_t RtlCompareMemory(const void *, const void *, size_t);
static ndis_status RtlUnicodeStringToInteger(unicode_string *,
@@ -538,6 +545,20 @@ RtlEqualUnicodeString(unicode_string *str1, unicode_string *str2,
}
static void
+RtlCopyString(dst, src)
+ ansi_string *dst;
+ const ansi_string *src;
+{
+ if (src != NULL && src->as_buf != NULL && dst->as_buf != NULL) {
+ dst->as_len = min(src->as_len, dst->as_maxlen);
+ memcpy(dst->as_buf, src->as_buf, dst->as_len);
+ if (dst->as_len < dst->as_maxlen)
+ dst->as_buf[dst->as_len] = 0;
+ } else
+ dst->as_len = 0;
+}
+
+static void
RtlCopyUnicodeString(dest, src)
unicode_string *dest;
unicode_string *src;
@@ -650,6 +671,14 @@ ExAllocatePoolWithTag(pooltype, len, tag)
return (buf);
}
+static void
+ExFreePoolWithTag(buf, tag)
+ void *buf;
+ uint32_t tag;
+{
+ ExFreePool(buf);
+}
+
void
ExFreePool(buf)
void *buf;
@@ -2056,6 +2085,13 @@ ntoskrnl_pushsl(head, entry)
return (oldhead);
}
+static void
+InitializeSListHead(head)
+ slist_header *head;
+{
+ memset(head, 0, sizeof(*head));
+}
+
static slist_entry *
ntoskrnl_popsl(head)
slist_header *head;
@@ -2725,6 +2761,59 @@ ntoskrnl_workitem_thread(arg)
return; /* notreached */
}
+static ndis_status
+RtlCharToInteger(src, base, val)
+ const char *src;
+ uint32_t base;
+ uint32_t *val;
+{
+ int negative = 0;
+ uint32_t res;
+
+ if (!src || !val)
+ return (STATUS_ACCESS_VIOLATION);
+ while (*src != '\0' && *src <= ' ')
+ src++;
+ if (*src == '+')
+ src++;
+ else if (*src == '-') {
+ src++;
+ negative = 1;
+ }
+ if (base == 0) {
+ base = 10;
+ if (*src == '0') {
+ src++;
+ if (*src == 'b') {
+ base = 2;
+ src++;
+ } else if (*src == 'o') {
+ base = 8;
+ src++;
+ } else if (*src == 'x') {
+ base = 16;
+ src++;
+ }
+ }
+ } else if (!(base == 2 || base == 8 || base == 10 || base == 16))
+ return (STATUS_INVALID_PARAMETER);
+
+ for (res = 0; *src; src++) {
+ int v;
+ if (isdigit(*src))
+ v = *src - '0';
+ else if (isxdigit(*src))
+ v = tolower(*src) - 'a' + 10;
+ else
+ v = base;
+ if (v >= base)
+ return (STATUS_INVALID_PARAMETER);
+ res = res * base + v;
+ }
+ *val = negative ? -res : res;
+ return (STATUS_SUCCESS);
+}
+
static void
ntoskrnl_destroy_workitem_threads(void)
{
@@ -2905,6 +2994,32 @@ RtlZeroMemory(dst, len)
}
static void
+RtlSecureZeroMemory(dst, len)
+ void *dst;
+ size_t len;
+{
+ memset(dst, 0, len);
+}
+
+static void
+RtlFillMemory(dst, len, c)
+ void *dst;
+ size_t len;
+ uint8_t c;
+{
+ memset(dst, c, len);
+}
+
+static void
+RtlMoveMemory(dst, src, len)
+ void *dst;
+ const void *src;
+ size_t len;
+{
+ memmove(dst, src, len);
+}
+
+static void
RtlCopyMemory(dst, src, len)
void *dst;
const void *src;
@@ -2919,17 +3034,14 @@ RtlCompareMemory(s1, s2, len)
const void *s2;
size_t len;
{
- size_t i, total = 0;
+ size_t i;
uint8_t *m1, *m2;
m1 = __DECONST(char *, s1);
m2 = __DECONST(char *, s2);
- for (i = 0; i < len; i++) {
- if (m1[i] == m2[i])
- total++;
- }
- return (total);
+ for (i = 0; i < len && m1[i] == m2[i]; i++);
+ return (i);
}
void
@@ -4124,7 +4236,12 @@ dummy()
image_patch_table ntoskrnl_functbl[] = {
IMPORT_SFUNC(RtlZeroMemory, 2),
+ IMPORT_SFUNC(RtlSecureZeroMemory, 2),
+ IMPORT_SFUNC(RtlFillMemory, 3),
+ IMPORT_SFUNC(RtlMoveMemory, 3),
+ IMPORT_SFUNC(RtlCharToInteger, 3),
IMPORT_SFUNC(RtlCopyMemory, 3),
+ IMPORT_SFUNC(RtlCopyString, 2),
IMPORT_SFUNC(RtlCompareMemory, 3),
IMPORT_SFUNC(RtlEqualUnicodeString, 3),
IMPORT_SFUNC(RtlCopyUnicodeString, 2),
@@ -4211,6 +4328,7 @@ image_patch_table ntoskrnl_functbl[] = {
IMPORT_SFUNC(ExInitializeNPagedLookasideList, 7),
IMPORT_SFUNC(ExDeleteNPagedLookasideList, 1),
IMPORT_FFUNC(InterlockedPopEntrySList, 1),
+ IMPORT_FFUNC(InitializeSListHead, 1),
IMPORT_FFUNC(InterlockedPushEntrySList, 2),
IMPORT_SFUNC(ExQueryDepthSList, 1),
IMPORT_FFUNC_MAP(ExpInterlockedPopEntrySList,
@@ -4220,6 +4338,7 @@ image_patch_table ntoskrnl_functbl[] = {
IMPORT_FFUNC(ExInterlockedPopEntrySList, 2),
IMPORT_FFUNC(ExInterlockedPushEntrySList, 3),
IMPORT_SFUNC(ExAllocatePoolWithTag, 3),
+ IMPORT_SFUNC(ExFreePoolWithTag, 2),
IMPORT_SFUNC(ExFreePool, 1),
#ifdef __i386__
IMPORT_FFUNC(KefAcquireSpinLockAtDpcLevel, 1),
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 6794f45..4b93d9b 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -858,7 +858,7 @@ ahci_ch_attach(device_t dev)
ch->caps = ctlr->caps;
ch->caps2 = ctlr->caps2;
ch->quirks = ctlr->quirks;
- ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1,
+ ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1;
mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF);
resource_int_value(device_get_name(dev),
device_get_unit(dev), "pm_level", &ch->pm_level);
diff --git a/sys/dev/cas/if_cas.c b/sys/dev/cas/if_cas.c
index e454fa1..0fe4fc5 100644
--- a/sys/dev/cas/if_cas.c
+++ b/sys/dev/cas/if_cas.c
@@ -346,7 +346,7 @@ cas_attach(struct cas_softc *sc)
}
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK,
- MII_PHY_ANY, MII_OFFSET_ANY, 0);
+ MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE);
}
/*
* Fall back on an internal PHY if no external PHY was found.
@@ -366,7 +366,7 @@ cas_attach(struct cas_softc *sc)
}
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK,
- MII_PHY_ANY, MII_OFFSET_ANY, 0);
+ MII_PHY_ANY, MII_OFFSET_ANY, MIIF_DOPAUSE);
}
} else {
/*
@@ -388,7 +388,7 @@ cas_attach(struct cas_softc *sc)
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
cas_mediachange, cas_mediastatus, BMSR_DEFCAPMASK,
- CAS_PHYAD_EXTERNAL, MII_OFFSET_ANY, 0);
+ CAS_PHYAD_EXTERNAL, MII_OFFSET_ANY, MIIF_DOPAUSE);
}
if (error != 0) {
device_printf(sc->sc_dev, "attaching PHYs failed\n");
@@ -1093,8 +1093,7 @@ cas_init_locked(struct cas_softc *sc)
/* Set the PAUSE thresholds. We use the maximum OFF threshold. */
CAS_WRITE_4(sc, CAS_RX_PTHRS,
- ((111 * 64) << CAS_RX_PTHRS_XOFF_SHFT) |
- ((15 * 64) << CAS_RX_PTHRS_XON_SHFT));
+ (111 << CAS_RX_PTHRS_XOFF_SHFT) | (15 << CAS_RX_PTHRS_XON_SHFT));
/* RX blanking */
CAS_WRITE_4(sc, CAS_RX_BLANK,
@@ -1339,7 +1338,7 @@ cas_init_regs(struct cas_softc *sc)
CAS_WRITE_4(sc, CAS_MAC_PREAMBLE_LEN, 0x7);
CAS_WRITE_4(sc, CAS_MAC_JAM_SIZE, 0x4);
CAS_WRITE_4(sc, CAS_MAC_ATTEMPT_LIMIT, 0x10);
- CAS_WRITE_4(sc, CAS_MAC_CTRL_TYPE, 0x8088);
+ CAS_WRITE_4(sc, CAS_MAC_CTRL_TYPE, 0x8808);
/* random number seed */
CAS_WRITE_4(sc, CAS_MAC_RANDOM_SEED,
@@ -1572,11 +1571,11 @@ cas_tint(struct cas_softc *sc)
}
#ifdef CAS_DEBUG
- CTR4(KTR_CAS, "%s: CAS_TX_STATE_MACHINE %x CAS_TX_DESC_BASE %llx "
+ CTR5(KTR_CAS, "%s: CAS_TX_SM1 %x CAS_TX_SM2 %x CAS_TX_DESC_BASE %llx "
"CAS_TX_COMP3 %x",
- __func__, CAS_READ_4(sc, CAS_TX_STATE_MACHINE),
- ((long long)CAS_READ_4(sc, CAS_TX_DESC_BASE_HI3) << 32) |
- CAS_READ_4(sc, CAS_TX_DESC_BASE_LO3),
+ __func__, CAS_READ_4(sc, CAS_TX_SM1), CAS_READ_4(sc, CAS_TX_SM2),
+ ((long long)CAS_READ_4(sc, CAS_TX_DESC3_BASE_HI) << 32) |
+ CAS_READ_4(sc, CAS_TX_DESC3_BASE_LO),
CAS_READ_4(sc, CAS_TX_COMP3));
#endif
@@ -1638,7 +1637,7 @@ cas_rint(struct cas_softc *sc)
rxhead = CAS_READ_4(sc, CAS_RX_COMP_HEAD);
#ifdef CAS_DEBUG
CTR4(KTR_CAS, "%s: sc->sc_rxcptr %d, sc->sc_rxdptr %d, head %d",
- __func__, sc->rxcptr, sc->sc_rxdptr, rxhead);
+ __func__, sc->sc_rxcptr, sc->sc_rxdptr, rxhead);
#endif
skip = 0;
CAS_CDSYNC(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -1865,7 +1864,7 @@ cas_rint(struct cas_softc *sc)
#ifdef CAS_DEBUG
CTR4(KTR_CAS, "%s: done sc->sc_rxcptr %d, sc->sc_rxdptr %d, head %d",
- __func__, sc->rxcptr, sc->sc_rxdptr,
+ __func__, sc->sc_rxcptr, sc->sc_rxdptr,
CAS_READ_4(sc, CAS_RX_COMP_HEAD));
#endif
}
@@ -1988,7 +1987,7 @@ cas_intr_task(void *arg, int pending __unused)
#ifdef CAS_DEBUG
CTR4(KTR_CAS, "%s: %s: cplt %x, status %x",
device_get_name(sc->sc_dev), __func__,
- (status >> CAS_STATUS_TX_COMP3_SHIFT), (u_int)status);
+ (status >> CAS_STATUS_TX_COMP3_SHFT), (u_int)status);
/*
* PCS interrupts must be cleared, otherwise no traffic is passed!
@@ -2100,15 +2099,15 @@ cas_watchdog(struct cas_softc *sc)
#ifdef CAS_DEBUG
CTR4(KTR_CAS,
- "%s: CAS_RX_CONFIG %x CAS_MAC_RX_STATUS %x CAS_MAC_RX_CONFIG %x",
- __func__, CAS_READ_4(sc, CAS_RX_CONFIG),
+ "%s: CAS_RX_CONF %x CAS_MAC_RX_STATUS %x CAS_MAC_RX_CONF %x",
+ __func__, CAS_READ_4(sc, CAS_RX_CONF),
CAS_READ_4(sc, CAS_MAC_RX_STATUS),
- CAS_READ_4(sc, CAS_MAC_RX_CONFIG));
+ CAS_READ_4(sc, CAS_MAC_RX_CONF));
CTR4(KTR_CAS,
- "%s: CAS_TX_CONFIG %x CAS_MAC_TX_STATUS %x CAS_MAC_TX_CONFIG %x",
- __func__, CAS_READ_4(sc, CAS_TX_CONFIG),
+ "%s: CAS_TX_CONF %x CAS_MAC_TX_STATUS %x CAS_MAC_TX_CONF %x",
+ __func__, CAS_READ_4(sc, CAS_TX_CONF),
CAS_READ_4(sc, CAS_MAC_TX_STATUS),
- CAS_READ_4(sc, CAS_MAC_TX_CONFIG));
+ CAS_READ_4(sc, CAS_MAC_TX_CONF));
#endif
if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0)
@@ -2356,14 +2355,12 @@ cas_mii_statchg(device_t dev)
v = CAS_READ_4(sc, CAS_MAC_CTRL_CONF) &
~(CAS_MAC_CTRL_CONF_TXP | CAS_MAC_CTRL_CONF_RXP);
-#ifdef notyet
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
IFM_ETH_RXPAUSE) != 0)
v |= CAS_MAC_CTRL_CONF_RXP;
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
IFM_ETH_TXPAUSE) != 0)
v |= CAS_MAC_CTRL_CONF_TXP;
-#endif
CAS_WRITE_4(sc, CAS_MAC_CTRL_CONF, v);
/*
diff --git a/sys/dev/e1000/e1000_api.c b/sys/dev/e1000/e1000_api.c
index 3ae023c..b3a7ef9 100644
--- a/sys/dev/e1000/e1000_api.c
+++ b/sys/dev/e1000/e1000_api.c
@@ -312,6 +312,8 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82580_SGMII:
case E1000_DEV_ID_82580_COPPER_DUAL:
case E1000_DEV_ID_82580_QUAD_FIBER:
+ case E1000_DEV_ID_DH89XXCC_SGMII:
+ case E1000_DEV_ID_DH89XXCC_SERDES:
mac->type = e1000_82580;
break;
case E1000_DEV_ID_82576_VF:
diff --git a/sys/dev/e1000/e1000_hw.h b/sys/dev/e1000/e1000_hw.h
index ca9c97d..e80e870 100644
--- a/sys/dev/e1000/e1000_hw.h
+++ b/sys/dev/e1000/e1000_hw.h
@@ -150,6 +150,8 @@ struct e1000_hw;
#define E1000_DEV_ID_82580_SGMII 0x1511
#define E1000_DEV_ID_82580_COPPER_DUAL 0x1516
#define E1000_DEV_ID_82580_QUAD_FIBER 0x1527
+#define E1000_DEV_ID_DH89XXCC_SGMII 0x0436
+#define E1000_DEV_ID_DH89XXCC_SERDES 0x0438
#define E1000_REVISION_0 0
#define E1000_REVISION_1 1
#define E1000_REVISION_2 2
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index c41e144..6728a98 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -93,7 +93,7 @@ int em_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char em_driver_version[] = "7.1.7";
+char em_driver_version[] = "7.1.8";
/*********************************************************************
* PCI Device ID Table
@@ -272,6 +272,7 @@ static void em_get_wakeup(device_t);
static void em_enable_wakeup(device_t);
static int em_enable_phy_wakeup(struct adapter *);
static void em_led_func(void *, int);
+static void em_disable_aspm(struct adapter *);
static int em_irq_fast(void *);
@@ -1229,9 +1230,9 @@ em_init_locked(struct adapter *adapter)
break;
case e1000_ich9lan:
case e1000_ich10lan:
- case e1000_pchlan:
pba = E1000_PBA_10K;
break;
+ case e1000_pchlan:
case e1000_pch2lan:
pba = E1000_PBA_26K;
break;
@@ -2762,6 +2763,7 @@ em_reset(struct adapter *adapter)
/* Issue a global reset */
e1000_reset_hw(hw);
E1000_WRITE_REG(hw, E1000_WUC, 0);
+ em_disable_aspm(adapter);
if (e1000_init_hw(hw) < 0) {
device_printf(dev, "Hardware Initialization Failed\n");
@@ -4205,68 +4207,66 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
len = le16toh(cur->length);
eop = (status & E1000_RXD_STAT_EOP) != 0;
- count--;
- if (((cur->errors & E1000_RXD_ERR_FRAME_ERR_MASK) == 0) &&
- (rxr->discard == FALSE)) {
+ if ((rxr->discard == TRUE) || (cur->errors &
+ E1000_RXD_ERR_FRAME_ERR_MASK)) {
+ ifp->if_ierrors++;
+ ++rxr->rx_discarded;
+ if (!eop) /* Catch subsequent segs */
+ rxr->discard = TRUE;
+ else
+ rxr->discard = FALSE;
+ em_rx_discard(rxr, i);
+ goto next_desc;
+ }
- /* Assign correct length to the current fragment */
- mp = rxr->rx_buffers[i].m_head;
- mp->m_len = len;
+ /* Assign correct length to the current fragment */
+ mp = rxr->rx_buffers[i].m_head;
+ mp->m_len = len;
- /* Trigger for refresh */
- rxr->rx_buffers[i].m_head = NULL;
+ /* Trigger for refresh */
+ rxr->rx_buffers[i].m_head = NULL;
- if (rxr->fmp == NULL) {
- mp->m_pkthdr.len = len;
- rxr->fmp = mp; /* Store the first mbuf */
- rxr->lmp = mp;
- } else {
- /* Chain mbuf's together */
- mp->m_flags &= ~M_PKTHDR;
- rxr->lmp->m_next = mp;
- rxr->lmp = rxr->lmp->m_next;
- rxr->fmp->m_pkthdr.len += len;
- }
+ /* First segment? */
+ if (rxr->fmp == NULL) {
+ mp->m_pkthdr.len = len;
+ rxr->fmp = rxr->lmp = mp;
+ } else {
+ /* Chain mbuf's together */
+ mp->m_flags &= ~M_PKTHDR;
+ rxr->lmp->m_next = mp;
+ rxr->lmp = mp;
+ rxr->fmp->m_pkthdr.len += len;
+ }
- if (eop) {
- rxr->fmp->m_pkthdr.rcvif = ifp;
- ifp->if_ipackets++;
- em_receive_checksum(cur, rxr->fmp);
+ if (eop) {
+ --count;
+ sendmp = rxr->fmp;
+ sendmp->m_pkthdr.rcvif = ifp;
+ ifp->if_ipackets++;
+ em_receive_checksum(cur, sendmp);
#ifndef __NO_STRICT_ALIGNMENT
- if (adapter->max_frame_size >
- (MCLBYTES - ETHER_ALIGN) &&
- em_fixup_rx(rxr) != 0)
- goto skip;
+ if (adapter->max_frame_size >
+ (MCLBYTES - ETHER_ALIGN) &&
+ em_fixup_rx(rxr) != 0)
+ goto skip;
#endif
- if (status & E1000_RXD_STAT_VP) {
- rxr->fmp->m_pkthdr.ether_vtag =
- (le16toh(cur->special) &
- E1000_RXD_SPC_VLAN_MASK);
- rxr->fmp->m_flags |= M_VLANTAG;
- }
+ if (status & E1000_RXD_STAT_VP) {
+ sendmp->m_pkthdr.ether_vtag =
+ (le16toh(cur->special) &
+ E1000_RXD_SPC_VLAN_MASK);
+ sendmp->m_flags |= M_VLANTAG;
+ }
#ifdef EM_MULTIQUEUE
- rxr->fmp->m_pkthdr.flowid = rxr->msix;
- rxr->fmp->m_flags |= M_FLOWID;
+ sendmp->m_pkthdr.flowid = rxr->msix;
+ sendmp->m_flags |= M_FLOWID;
#endif
#ifndef __NO_STRICT_ALIGNMENT
skip:
#endif
- sendmp = rxr->fmp;
- rxr->fmp = NULL;
- rxr->lmp = NULL;
- }
- } else {
- ifp->if_ierrors++;
- ++rxr->rx_discarded;
- if (!eop) /* Catch subsequent segs */
- rxr->discard = TRUE;
- else
- rxr->discard = FALSE;
- em_rx_discard(rxr, i);
- sendmp = NULL;
+ rxr->fmp = rxr->lmp = NULL;
}
-
+next_desc:
/* Zero out the receive descriptors status. */
cur->status = 0;
++rxdone; /* cumulative for POLL */
@@ -4293,10 +4293,7 @@ skip:
}
/* Catch any remaining refresh work */
- if (processed != 0) {
- em_refresh_mbufs(rxr, i);
- processed = 0;
- }
+ em_refresh_mbufs(rxr, i);
rxr->next_to_check = i;
if (done != NULL)
@@ -4878,6 +4875,37 @@ em_led_func(void *arg, int onoff)
EM_CORE_UNLOCK(adapter);
}
+/*
+** Disable the L0S and L1 LINK states
+*/
+static void
+em_disable_aspm(struct adapter *adapter)
+{
+ int base, reg;
+ u16 link_cap,link_ctrl;
+ device_t dev = adapter->dev;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_82573:
+ case e1000_82574:
+ case e1000_82583:
+ break;
+ default:
+ return;
+ }
+ if (pci_find_extcap(dev, PCIY_EXPRESS, &base) != 0)
+ return;
+ reg = base + PCIR_EXPRESS_LINK_CAP;
+ link_cap = pci_read_config(dev, reg, 2);
+ if ((link_cap & PCIM_LINK_CAP_ASPM) == 0)
+ return;
+ reg = base + PCIR_EXPRESS_LINK_CTL;
+ link_ctrl = pci_read_config(dev, reg, 2);
+ link_ctrl &= 0xFFFC; /* turn off bit 1 and 2 */
+ pci_write_config(dev, reg, link_ctrl, 2);
+ return;
+}
+
/**********************************************************************
*
* Update the board statistics counters.
diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c
index ee7ba71..14ccede 100644
--- a/sys/dev/e1000/if_igb.c
+++ b/sys/dev/e1000/if_igb.c
@@ -99,7 +99,7 @@ int igb_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
-char igb_driver_version[] = "version - 2.0.4";
+char igb_driver_version[] = "version - 2.0.7";
/*********************************************************************
@@ -137,6 +137,10 @@ static igb_vendor_info_t igb_vendor_info_array[] =
{ 0x8086, E1000_DEV_ID_82580_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_82580_COPPER_DUAL,
PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_82580_QUAD_FIBER,
+ PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_DH89XXCC_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
+ { 0x8086, E1000_DEV_ID_DH89XXCC_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */
{ 0, 0, 0, 0, 0}
};
@@ -307,11 +311,19 @@ static int igb_enable_msix = 1;
TUNABLE_INT("hw.igb.enable_msix", &igb_enable_msix);
/*
- * Header split has seemed to be beneficial in
- * many circumstances tested, however there have
- * been some stability issues, so the default is
- * off.
- */
+** Tuneable Interrupt rate
+*/
+static int igb_max_interrupt_rate = 8000;
+TUNABLE_INT("hw.igb.max_interrupt_rate", &igb_max_interrupt_rate);
+
+/*
+** Header split causes the packet header to
+** be dma'd to a seperate mbuf from the payload.
+** this can have memory alignment benefits. But
+** another plus is that small packets often fit
+** into the header and thus use no cluster. Its
+** a very workload dependent type feature.
+*/
static bool igb_header_split = FALSE;
TUNABLE_INT("hw.igb.hdr_split", &igb_header_split);
@@ -330,15 +342,6 @@ TUNABLE_INT("hw.igb.rx_process_limit", &igb_rx_process_limit);
static int igb_fc_setting = e1000_fc_full;
TUNABLE_INT("hw.igb.fc_setting", &igb_fc_setting);
-/*
-** Shadow VFTA table, this is needed because
-** the real filter table gets cleared during
-** a soft reset and the driver needs to be able
-** to repopulate it.
-*/
-static u32 igb_shadow_vfta[IGB_VFTA_SIZE];
-
-
/*********************************************************************
* Device identification routine
*
@@ -818,7 +821,7 @@ igb_start_locked(struct tx_ring *txr, struct ifnet *ifp)
/* Set watchdog on */
txr->watchdog_time = ticks;
- txr->watchdog_check = TRUE;
+ txr->queue_status = IGB_QUEUE_WORKING;
}
}
@@ -922,7 +925,7 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
}
if (enq > 0) {
/* Set the watchdog */
- txr->watchdog_check = TRUE;
+ txr->queue_status = IGB_QUEUE_WORKING;
txr->watchdog_time = ticks;
}
return (err);
@@ -1049,6 +1052,11 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
break;
case SIOCSIFMEDIA:
+ /*
+ ** As the speed/duplex settings are being
+ ** changed, we need toreset the PHY.
+ */
+ adapter->hw.phy.reset_disable = FALSE;
/* Check SOL/IDER usage */
IGB_CORE_LOCK(adapter);
if (e1000_check_reset_block(&adapter->hw)) {
@@ -1161,19 +1169,6 @@ igb_init_locked(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
- /* Use real VLAN Filter support? */
- if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
- if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
- /* Use real VLAN Filter support */
- igb_setup_vlan_hw_support(adapter);
- else {
- u32 ctrl;
- ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
- ctrl |= E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
- }
- }
-
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
if (ifp->if_capenable & IFCAP_TXCSUM) {
@@ -1201,10 +1196,12 @@ igb_init_locked(struct adapter *adapter)
** Figure out the desired mbuf pool
** for doing jumbo/packetsplit
*/
- if (ifp->if_mtu > ETHERMTU)
+ if (adapter->max_frame_size <= 2048)
+ adapter->rx_mbuf_sz = MCLBYTES;
+ else if (adapter->max_frame_size <= 4096)
adapter->rx_mbuf_sz = MJUMPAGESIZE;
else
- adapter->rx_mbuf_sz = MCLBYTES;
+ adapter->rx_mbuf_sz = MJUM9BYTES;
/* Prepare receive descriptors and buffers */
if (igb_setup_receive_structures(adapter)) {
@@ -1213,6 +1210,19 @@ igb_init_locked(struct adapter *adapter)
}
igb_initialize_receive_units(adapter);
+ /* Use real VLAN Filter support? */
+ if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ /* Use real VLAN Filter support */
+ igb_setup_vlan_hw_support(adapter);
+ else {
+ u32 ctrl;
+ ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
+ ctrl |= E1000_CTRL_VME;
+ E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
+ }
+ }
+
/* Don't lose promiscuous settings */
igb_set_promisc(adapter);
@@ -1225,9 +1235,6 @@ igb_init_locked(struct adapter *adapter)
if (adapter->msix > 1) /* Set up queue routing */
igb_configure_queues(adapter);
- /* Set up VLAN tag offload and filter */
- igb_setup_vlan_hw_support(adapter);
-
/* this clears any pending interrupts */
E1000_READ_REG(&adapter->hw, E1000_ICR);
#ifdef DEVICE_POLLING
@@ -1627,11 +1634,6 @@ igb_media_change(struct ifnet *ifp)
device_printf(adapter->dev, "Unsupported media type\n");
}
- /* As the speed/duplex settings my have changed we need to
- * reset the PHY.
- */
- adapter->hw.phy.reset_disable = FALSE;
-
igb_init_locked(adapter);
IGB_CORE_UNLOCK(adapter);
@@ -1947,18 +1949,9 @@ igb_local_timer(void *arg)
/*
** Watchdog: check for time since any descriptor was cleaned
*/
- for (int i = 0; i < adapter->num_queues; i++, txr++) {
- IGB_TX_LOCK(txr);
- if ((txr->watchdog_check == FALSE) ||
- (txr->tx_avail == adapter->num_tx_desc)) {
- IGB_TX_UNLOCK(txr);
- continue;
- }
- if ((ticks - txr->watchdog_time) > IGB_WATCHDOG)
+ for (int i = 0; i < adapter->num_queues; i++, txr++)
+ if (txr->queue_status == IGB_QUEUE_HUNG)
goto timeout;
- IGB_TX_UNLOCK(txr);
- }
-
out:
callout_reset(&adapter->timer, hz, igb_local_timer, adapter);
return;
@@ -1973,7 +1966,6 @@ timeout:
txr->me, txr->tx_avail, txr->next_to_clean);
adapter->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
adapter->watchdog_events++;
- IGB_TX_UNLOCK(txr);
igb_init_locked(adapter);
}
@@ -2037,7 +2029,7 @@ igb_update_link_status(struct adapter *adapter)
if_link_state_change(ifp, LINK_STATE_DOWN);
/* Turn off watchdogs */
for (int i = 0; i < adapter->num_queues; i++, txr++)
- txr->watchdog_check = FALSE;
+ txr->queue_status = IGB_QUEUE_IDLE;
}
}
@@ -2069,7 +2061,7 @@ igb_stop(void *arg)
/* Unarm watchdog timer. */
for (int i = 0; i < adapter->num_queues; i++, txr++) {
IGB_TX_LOCK(txr);
- txr->watchdog_check = FALSE;
+ txr->queue_status = IGB_QUEUE_IDLE;
IGB_TX_UNLOCK(txr);
}
@@ -2280,8 +2272,7 @@ igb_configure_queues(struct adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
struct igb_queue *que;
- u32 tmp, ivar = 0;
- u32 newitr = IGB_DEFAULT_ITR;
+ u32 tmp, ivar = 0, newitr = 0;
/* First turn on RSS capability */
if (adapter->hw.mac.type > e1000_82575)
@@ -2398,6 +2389,9 @@ igb_configure_queues(struct adapter *adapter)
}
/* Set the starting interrupt rate */
+ if (igb_max_interrupt_rate > 0)
+ newitr = (4000000 / igb_max_interrupt_rate) & 0x7FFC;
+
if (hw->mac.type == e1000_82575)
newitr |= newitr << 16;
else
@@ -2509,6 +2503,8 @@ igb_setup_msix(struct adapter *adapter)
/* Manual override */
if (igb_num_queues != 0)
queues = igb_num_queues;
+ if (queues > 8) /* max queues */
+ queues = 8;
/* Can have max of 4 queues on 82575 */
if ((adapter->hw.mac.type == e1000_82575) && (queues > 4))
@@ -2636,7 +2632,7 @@ igb_reset(struct adapter *adapter)
fc->send_xon = TRUE;
/* Set Flow control, use the tunable location if sane */
- if ((igb_fc_setting >= 0) || (igb_fc_setting < 4))
+ if ((igb_fc_setting >= 0) && (igb_fc_setting < 4))
fc->requested_mode = igb_fc_setting;
else
fc->requested_mode = e1000_fc_none;
@@ -2728,10 +2724,11 @@ igb_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWCSUM;
ifp->if_capabilities |= IFCAP_TSO4;
ifp->if_capabilities |= IFCAP_JUMBO_MTU;
- if (igb_header_split)
- ifp->if_capabilities |= IFCAP_LRO;
-
ifp->if_capenable = ifp->if_capabilities;
+
+ /* Don't enable LRO by default */
+ ifp->if_capabilities |= IFCAP_LRO;
+
#ifdef DEVICE_POLLING
ifp->if_capabilities |= IFCAP_POLLING;
#endif
@@ -3172,7 +3169,7 @@ igb_initialize_transmit_units(struct adapter *adapter)
E1000_READ_REG(hw, E1000_TDBAL(i)),
E1000_READ_REG(hw, E1000_TDLEN(i)));
- txr->watchdog_check = FALSE;
+ txr->queue_status = IGB_QUEUE_IDLE;
txdctl |= IGB_TX_PTHRESH;
txdctl |= IGB_TX_HTHRESH << 8;
@@ -3184,14 +3181,14 @@ igb_initialize_transmit_units(struct adapter *adapter)
if (adapter->hw.mac.type == e1000_vfadapt)
return;
+ e1000_config_collision_dist(hw);
+
/* Program the Transmit Control Register */
tctl = E1000_READ_REG(hw, E1000_TCTL);
tctl &= ~E1000_TCTL_CT;
tctl |= (E1000_TCTL_PSP | E1000_TCTL_RTLC | E1000_TCTL_EN |
(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT));
- e1000_config_collision_dist(hw);
-
/* This write will effectively turn on the transmit unit. */
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
}
@@ -3500,16 +3497,19 @@ static bool
igb_txeof(struct tx_ring *txr)
{
struct adapter *adapter = txr->adapter;
- int first, last, done;
+ int first, last, done, processed;
struct igb_tx_buffer *tx_buffer;
struct e1000_tx_desc *tx_desc, *eop_desc;
struct ifnet *ifp = adapter->ifp;
IGB_TX_LOCK_ASSERT(txr);
- if (txr->tx_avail == adapter->num_tx_desc)
+ if (txr->tx_avail == adapter->num_tx_desc) {
+ txr->queue_status = IGB_QUEUE_IDLE;
return FALSE;
+ }
+ processed = 0;
first = txr->next_to_clean;
tx_desc = &txr->tx_base[first];
tx_buffer = &txr->tx_buffers[first];
@@ -3536,6 +3536,7 @@ igb_txeof(struct tx_ring *txr)
tx_desc->lower.data = 0;
tx_desc->buffer_addr = 0;
++txr->tx_avail;
+ ++processed;
if (tx_buffer->m_head) {
txr->bytes +=
@@ -3575,6 +3576,15 @@ igb_txeof(struct tx_ring *txr)
txr->next_to_clean = first;
+ /*
+ ** Watchdog calculation, we know there's
+ ** work outstanding or the first return
+ ** would have been taken, so none processed
+ ** for too long indicates a hang.
+ */
+ if ((!processed) && ((ticks - txr->watchdog_time) > IGB_WATCHDOG))
+ txr->queue_status = IGB_QUEUE_HUNG;
+
/*
* If we have enough room, clear IFF_DRV_OACTIVE
* to tell the stack that it is OK to send packets.
@@ -3583,7 +3593,7 @@ igb_txeof(struct tx_ring *txr)
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
/* All clean, turn off the watchdog */
if (txr->tx_avail == adapter->num_tx_desc) {
- txr->watchdog_check = FALSE;
+ txr->queue_status = IGB_QUEUE_IDLE;
return (FALSE);
}
}
@@ -3615,51 +3625,59 @@ igb_refresh_mbufs(struct rx_ring *rxr, int limit)
cleaned = -1; /* Signify no completions */
while (i != limit) {
rxbuf = &rxr->rx_buffers[i];
- if ((rxbuf->m_head == NULL) && (rxr->hdr_split)) {
+ /* No hdr mbuf used with header split off */
+ if (rxr->hdr_split == FALSE)
+ goto no_split;
+ if (rxbuf->m_head == NULL) {
mh = m_gethdr(M_DONTWAIT, MT_DATA);
if (mh == NULL)
goto update;
- mh->m_pkthdr.len = mh->m_len = MHLEN;
- mh->m_len = MHLEN;
- mh->m_flags |= M_PKTHDR;
- m_adj(mh, ETHER_ALIGN);
- /* Get the memory mapping */
- error = bus_dmamap_load_mbuf_sg(rxr->htag,
- rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT);
- if (error != 0) {
- printf("GET BUF: dmamap load"
- " failure - %d\n", error);
- m_free(mh);
- goto update;
- }
- rxbuf->m_head = mh;
- bus_dmamap_sync(rxr->htag, rxbuf->hmap,
- BUS_DMASYNC_PREREAD);
- rxr->rx_base[i].read.hdr_addr =
- htole64(hseg[0].ds_addr);
- }
+ } else
+ mh = rxbuf->m_head;
+ mh->m_pkthdr.len = mh->m_len = MHLEN;
+ mh->m_len = MHLEN;
+ mh->m_flags |= M_PKTHDR;
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->htag,
+ rxbuf->hmap, mh, hseg, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("Refresh mbufs: hdr dmamap load"
+ " failure - %d\n", error);
+ m_free(mh);
+ rxbuf->m_head = NULL;
+ goto update;
+ }
+ rxbuf->m_head = mh;
+ bus_dmamap_sync(rxr->htag, rxbuf->hmap,
+ BUS_DMASYNC_PREREAD);
+ rxr->rx_base[i].read.hdr_addr =
+ htole64(hseg[0].ds_addr);
+no_split:
if (rxbuf->m_pack == NULL) {
mp = m_getjcl(M_DONTWAIT, MT_DATA,
M_PKTHDR, adapter->rx_mbuf_sz);
if (mp == NULL)
goto update;
- mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
- /* Get the memory mapping */
- error = bus_dmamap_load_mbuf_sg(rxr->ptag,
- rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT);
- if (error != 0) {
- printf("GET BUF: dmamap load"
- " failure - %d\n", error);
- m_free(mp);
- goto update;
- }
- rxbuf->m_pack = mp;
- bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
- BUS_DMASYNC_PREREAD);
- rxr->rx_base[i].read.pkt_addr =
- htole64(pseg[0].ds_addr);
+ } else
+ mp = rxbuf->m_pack;
+
+ mp->m_pkthdr.len = mp->m_len = adapter->rx_mbuf_sz;
+ /* Get the memory mapping */
+ error = bus_dmamap_load_mbuf_sg(rxr->ptag,
+ rxbuf->pmap, mp, pseg, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("Refresh mbufs: payload dmamap load"
+ " failure - %d\n", error);
+ m_free(mp);
+ rxbuf->m_pack = NULL;
+ goto update;
}
+ rxbuf->m_pack = mp;
+ bus_dmamap_sync(rxr->ptag, rxbuf->pmap,
+ BUS_DMASYNC_PREREAD);
+ rxr->rx_base[i].read.pkt_addr =
+ htole64(pseg[0].ds_addr);
cleaned = i;
/* Calculate next index */
@@ -3722,9 +3740,9 @@ igb_allocate_receive_buffers(struct rx_ring *rxr)
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
- MJUMPAGESIZE, /* maxsize */
+ MJUM9BYTES, /* maxsize */
1, /* nsegments */
- MJUMPAGESIZE, /* maxsegsize */
+ MJUM9BYTES, /* maxsegsize */
0, /* flags */
NULL, /* lockfunc */
NULL, /* lockfuncarg */
@@ -3826,7 +3844,7 @@ igb_setup_receive_ring(struct rx_ring *rxr)
rxr->hdr_split = TRUE;
/* Now replenish the ring mbufs */
- for (int j = 0; j != adapter->num_rx_desc; ++j) {
+ for (int j = 0; j < adapter->num_rx_desc; ++j) {
struct mbuf *mh, *mp;
rxbuf = &rxr->rx_buffers[j];
@@ -3897,8 +3915,8 @@ skip_head:
** are undesireable in similar setups.
*/
if (ifp->if_capenable & IFCAP_LRO) {
- int err = tcp_lro_init(lro);
- if (err) {
+ error = tcp_lro_init(lro);
+ if (error) {
device_printf(dev, "LRO Initialization failed!\n");
goto fail;
}
@@ -3940,7 +3958,9 @@ fail:
*/
for (int j = 0; j > i; ++j) {
rxr = &adapter->rx_rings[i];
+ IGB_RX_LOCK(rxr);
igb_free_receive_ring(rxr);
+ IGB_RX_UNLOCK(rxr);
}
return (ENOBUFS);
@@ -3983,9 +4003,13 @@ igb_initialize_receive_units(struct adapter *adapter)
*/
if (ifp->if_mtu > ETHERMTU) {
rctl |= E1000_RCTL_LPE;
- srrctl |= 4096 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
- rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
-
+ if (adapter->rx_mbuf_sz == MJUMPAGESIZE) {
+ srrctl |= 4096 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+ rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX;
+ } else if (adapter->rx_mbuf_sz > MJUMPAGESIZE) {
+ srrctl |= 8192 >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+ rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX;
+ }
/* Set maximum packet len */
psize = adapter->max_frame_size;
/* are we on a vlan? */
@@ -4194,11 +4218,11 @@ igb_free_receive_buffers(struct rx_ring *rxr)
static __inline void
igb_rx_discard(struct rx_ring *rxr, int i)
{
- struct adapter *adapter = rxr->adapter;
struct igb_rx_buf *rbuf;
- struct mbuf *mh, *mp;
rbuf = &rxr->rx_buffers[i];
+
+ /* Partially received? Free the chain */
if (rxr->fmp != NULL) {
rxr->fmp->m_flags |= M_PKTHDR;
m_freem(rxr->fmp);
@@ -4206,19 +4230,23 @@ igb_rx_discard(struct rx_ring *rxr, int i)
rxr->lmp = NULL;
}
- mh = rbuf->m_head;
- mp = rbuf->m_pack;
+ /*
+ ** With advanced descriptors the writeback
+ ** clobbers the buffer addrs, so its easier
+ ** to just free the existing mbufs and take
+ ** the normal refresh path to get new buffers
+ ** and mapping.
+ */
+ if (rbuf->m_head) {
+ m_free(rbuf->m_head);
+ rbuf->m_head = NULL;
+ }
- /* Reuse loaded DMA map and just update mbuf chain */
- if (mh) { /* with no hdr split would be null */
- mh->m_len = MHLEN;
- mh->m_flags |= M_PKTHDR;
- mh->m_next = NULL;
+ if (rbuf->m_pack) {
+ m_free(rbuf->m_pack);
+ rbuf->m_pack = NULL;
}
- mp->m_len = mp->m_pkthdr.len = adapter->rx_mbuf_sz;
- mp->m_data = mp->m_ext.ext_buf;
- mp->m_next = NULL;
return;
}
@@ -4333,10 +4361,9 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
E1000_RXDADV_HDRBUFLEN_SHIFT;
if (hlen > IGB_HDR_BUF)
hlen = IGB_HDR_BUF;
- /* Handle the header mbuf */
mh = rxr->rx_buffers[i].m_head;
mh->m_len = hlen;
- /* clear buf info for refresh */
+ /* clear buf pointer for refresh */
rxbuf->m_head = NULL;
/*
** Get the payload length, this
@@ -4347,7 +4374,7 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
mp = rxr->rx_buffers[i].m_pack;
mp->m_len = plen;
mh->m_next = mp;
- /* clear buf info for refresh */
+ /* clear buf pointer */
rxbuf->m_pack = NULL;
rxr->rx_split_packets++;
}
@@ -4368,7 +4395,7 @@ igb_rxeof(struct igb_queue *que, int count, int *done)
/* Initial frame - setup */
if (rxr->fmp == NULL) {
mh->m_pkthdr.len = mh->m_len;
- /* Store the first mbuf */
+ /* Save the head of the chain */
rxr->fmp = mh;
rxr->lmp = mh;
if (mp != NULL) {
@@ -4533,12 +4560,15 @@ igb_register_vlan(void *arg, struct ifnet *ifp, u16 vtag)
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return;
+ IGB_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
- igb_shadow_vfta[index] |= (1 << bit);
+ adapter->shadow_vfta[index] |= (1 << bit);
++adapter->num_vlans;
/* Re-init to load the changes */
- igb_init(adapter);
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ igb_init_locked(adapter);
+ IGB_CORE_UNLOCK(adapter);
}
/*
@@ -4557,12 +4587,15 @@ igb_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag)
if ((vtag == 0) || (vtag > 4095)) /* Invalid */
return;
+ IGB_CORE_LOCK(adapter);
index = (vtag >> 5) & 0x7F;
bit = vtag & 0x1F;
- igb_shadow_vfta[index] &= ~(1 << bit);
+ adapter->shadow_vfta[index] &= ~(1 << bit);
--adapter->num_vlans;
/* Re-init to load the changes */
- igb_init(adapter);
+ if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
+ igb_init_locked(adapter);
+ IGB_CORE_UNLOCK(adapter);
}
static void
@@ -4585,12 +4618,13 @@ igb_setup_vlan_hw_support(struct adapter *adapter)
** we need to repopulate it now.
*/
for (int i = 0; i < IGB_VFTA_SIZE; i++)
- if (igb_shadow_vfta[i] != 0) {
+ if (adapter->shadow_vfta[i] != 0) {
if (hw->mac.type == e1000_vfadapt)
- e1000_vfta_set_vf(hw, igb_shadow_vfta[i], TRUE);
+ e1000_vfta_set_vf(hw,
+ adapter->shadow_vfta[i], TRUE);
else
E1000_WRITE_REG_ARRAY(hw, E1000_VFTA,
- i, igb_shadow_vfta[i]);
+ i, adapter->shadow_vfta[i]);
}
if (hw->mac.type == e1000_vfadapt)
@@ -4994,6 +5028,28 @@ igb_sysctl_reg_handler(SYSCTL_HANDLER_ARGS)
}
/*
+** Tuneable interrupt rate handler
+*/
+static int
+igb_sysctl_interrupt_rate_handler(SYSCTL_HANDLER_ARGS)
+{
+ struct igb_queue *que = ((struct igb_queue *)oidp->oid_arg1);
+ int error;
+ u32 reg, usec, rate;
+
+ reg = E1000_READ_REG(&que->adapter->hw, E1000_EITR(que->msix));
+ usec = ((reg & 0x7FFC) >> 2);
+ if (usec > 0)
+ rate = 1000000 / usec;
+ else
+ rate = 0;
+ error = sysctl_handle_int(oidp, &rate, 0, req);
+ if (error || !req->newptr)
+ return error;
+ return 0;
+}
+
+/*
* Add sysctl variables, one per statistic, to the system.
*/
static void
@@ -5065,6 +5121,12 @@ igb_add_hw_stats(struct adapter *adapter)
CTLFLAG_RD, NULL, "Queue Name");
queue_list = SYSCTL_CHILDREN(queue_node);
+ SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "interrupt_rate",
+ CTLFLAG_RD, &adapter->queues[i],
+ sizeof(&adapter->queues[i]),
+ igb_sysctl_interrupt_rate_handler,
+ "IU", "Interrupt Rate");
+
SYSCTL_ADD_PROC(ctx, queue_list, OID_AUTO, "txd_head",
CTLFLAG_RD, adapter, E1000_TDH(txr->me),
igb_sysctl_reg_handler, "IU",
diff --git a/sys/dev/e1000/if_igb.h b/sys/dev/e1000/if_igb.h
index 059a8b9..15fdceb 100644
--- a/sys/dev/e1000/if_igb.h
+++ b/sys/dev/e1000/if_igb.h
@@ -190,6 +190,9 @@
#define IGB_TX_BUFFER_SIZE ((uint32_t) 1514)
#define IGB_FC_PAUSE_TIME 0x0680
#define IGB_EEPROM_APME 0x400;
+#define IGB_QUEUE_IDLE 0
+#define IGB_QUEUE_WORKING 1
+#define IGB_QUEUE_HUNG 2
/*
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
@@ -237,7 +240,7 @@
/* Define the starting Interrupt rate per Queue */
#define IGB_INTS_PER_SEC 8000
-#define IGB_DEFAULT_ITR 1000000000/(IGB_INTS_PER_SEC * 256)
+#define IGB_DEFAULT_ITR ((1000000/IGB_INTS_PER_SEC) << 2)
#define IGB_LINK_ITR 2000
@@ -300,7 +303,7 @@ struct tx_ring {
u32 bytes;
u32 packets;
- bool watchdog_check;
+ int queue_status;
int watchdog_time;
int tdt;
int tdh;
@@ -384,7 +387,15 @@ struct adapter {
int wol;
int has_manage;
- /* Info about the board itself */
+ /*
+ ** Shadow VFTA table, this is needed because
+ ** the real vlan filter table gets cleared during
+ ** a soft reset and the driver needs to be able
+ ** to repopulate it.
+ */
+ u32 shadow_vfta[IGB_VFTA_SIZE];
+
+ /* Info about the interface */
u8 link_active;
u16 link_speed;
u16 link_duplex;
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 5710ca7..2d522c3 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -107,11 +107,11 @@ static int tx_threshold = 64;
/*
* The configuration byte map has several undefined fields which
* must be one or must be zero. Set up a template for these bits.
- * The actual configuration is performed in fxp_init.
+ * The actual configuration is performed in fxp_init_body.
*
* See struct fxp_cb_config for the bit definitions.
*/
-static u_char fxp_cb_config_template[] = {
+static const u_char const fxp_cb_config_template[] = {
0x0, 0x0, /* cb_status */
0x0, 0x0, /* cb_command */
0x0, 0x0, 0x0, 0x0, /* link_addr */
@@ -155,7 +155,7 @@ static u_char fxp_cb_config_template[] = {
* particular variants, but we don't currently differentiate between
* them.
*/
-static struct fxp_ident fxp_ident_table[] = {
+static const struct fxp_ident const fxp_ident_table[] = {
{ 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" },
{ 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" },
{ 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
@@ -217,7 +217,7 @@ static int fxp_shutdown(device_t dev);
static int fxp_suspend(device_t dev);
static int fxp_resume(device_t dev);
-static struct fxp_ident *fxp_find_ident(device_t dev);
+static const struct fxp_ident *fxp_find_ident(device_t dev);
static void fxp_intr(void *xsc);
static void fxp_rxcsum(struct fxp_softc *sc, struct ifnet *ifp,
struct mbuf *m, uint16_t status, int pos);
@@ -366,12 +366,12 @@ fxp_dma_wait(struct fxp_softc *sc, volatile uint16_t *status,
device_printf(sc->dev, "DMA timeout\n");
}
-static struct fxp_ident *
+static const struct fxp_ident *
fxp_find_ident(device_t dev)
{
uint16_t devid;
uint8_t revid;
- struct fxp_ident *ident;
+ const struct fxp_ident *ident;
if (pci_get_vendor(dev) == FXP_VENDORID_INTEL) {
devid = pci_get_device(dev);
@@ -392,7 +392,7 @@ fxp_find_ident(device_t dev)
static int
fxp_probe(device_t dev)
{
- struct fxp_ident *ident;
+ const struct fxp_ident *ident;
ident = fxp_find_ident(dev);
if (ident != NULL) {
@@ -1614,21 +1614,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
/*
* Advance the end of list forward.
*/
-
-#ifdef __alpha__
- /*
- * On platforms which can't access memory in 16-bit
- * granularities, we must prevent the card from DMA'ing
- * up the status while we update the command field.
- * This could cause us to overwrite the completion status.
- * XXX This is probably bogus and we're _not_ looking
- * for atomicity here.
- */
- atomic_clear_16(&sc->fxp_desc.tx_last->tx_cb->cb_command,
- htole16(FXP_CB_COMMAND_S));
-#else
sc->fxp_desc.tx_last->tx_cb->cb_command &= htole16(~FXP_CB_COMMAND_S);
-#endif /*__alpha__*/
sc->fxp_desc.tx_last = txp;
/*
@@ -2985,13 +2971,13 @@ static uint32_t fxp_ucode_d102e[] = D102_E_RCVBUNDLE_UCODE;
#define UCODE(x) x, sizeof(x)/sizeof(uint32_t)
-struct ucode {
+static const struct ucode {
uint32_t revision;
uint32_t *ucode;
int length;
u_short int_delay_offset;
u_short bundle_max_offset;
-} ucode_table[] = {
+} const ucode_table[] = {
{ FXP_REV_82558_A4, UCODE(fxp_ucode_d101a), D101_CPUSAVER_DWORD, 0 },
{ FXP_REV_82558_B0, UCODE(fxp_ucode_d101b0), D101_CPUSAVER_DWORD, 0 },
{ FXP_REV_82559_A0, UCODE(fxp_ucode_d101ma),
@@ -3010,7 +2996,7 @@ struct ucode {
static void
fxp_load_ucode(struct fxp_softc *sc)
{
- struct ucode *uc;
+ const struct ucode *uc;
struct fxp_cb_ucode *cbp;
int i;
@@ -3177,11 +3163,13 @@ sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
static int
sysctl_hw_fxp_int_delay(SYSCTL_HANDLER_ARGS)
{
+
return (sysctl_int_range(oidp, arg1, arg2, req, 300, 3000));
}
static int
sysctl_hw_fxp_bundle_max(SYSCTL_HANDLER_ARGS)
{
+
return (sysctl_int_range(oidp, arg1, arg2, req, 1, 0xffff));
}
diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h
index de44636..ca7f7f5 100644
--- a/sys/dev/fxp/if_fxpvar.h
+++ b/sys/dev/fxp/if_fxpvar.h
@@ -146,7 +146,7 @@ struct fxp_ident {
uint16_t devid;
int16_t revid; /* -1 matches anything */
uint8_t ich;
- char *name;
+ const char *name;
};
struct fxp_hwstats {
@@ -182,7 +182,7 @@ struct fxp_softc {
struct resource *fxp_res[2]; /* I/O and IRQ resources */
struct resource_spec *fxp_spec; /* the resource spec we used */
void *ih; /* interrupt handler cookie */
- struct fxp_ident *ident;
+ const struct fxp_ident *ident;
struct mtx sc_mtx;
bus_dma_tag_t fxp_txmtag; /* bus DMA tag for Tx mbufs */
bus_dma_tag_t fxp_rxmtag; /* bus DMA tag for Rx mbufs */
diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c
index 5c5750e..e8d9400 100644
--- a/sys/dev/gem/if_gem.c
+++ b/sys/dev/gem/if_gem.c
@@ -302,7 +302,7 @@ gem_attach(struct gem_softc *sc)
}
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
gem_mediachange, gem_mediastatus, BMSR_DEFCAPMASK, phy,
- MII_OFFSET_ANY, 0);
+ MII_OFFSET_ANY, MIIF_DOPAUSE);
}
/*
@@ -330,7 +330,7 @@ gem_attach(struct gem_softc *sc)
}
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
gem_mediachange, gem_mediastatus, BMSR_DEFCAPMASK, phy,
- MII_OFFSET_ANY, 0);
+ MII_OFFSET_ANY, MIIF_DOPAUSE);
}
/*
@@ -352,7 +352,7 @@ gem_attach(struct gem_softc *sc)
sc->sc_flags |= GEM_SERDES;
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp,
gem_mediachange, gem_mediastatus, BMSR_DEFCAPMASK,
- GEM_PHYAD_EXTERNAL, MII_OFFSET_ANY, 0);
+ GEM_PHYAD_EXTERNAL, MII_OFFSET_ANY, MIIF_DOPAUSE);
}
if (error != 0) {
device_printf(sc->sc_dev, "attaching PHYs failed\n");
@@ -712,6 +712,9 @@ gem_reset_rx(struct gem_softc *sc)
if (!GEM_BANK1_BITWAIT(sc, GEM_RX_CONFIG, GEM_RX_CONFIG_RXDMA_EN, 0))
device_printf(sc->sc_dev, "cannot disable RX DMA\n");
+ /* Wait 5ms extra. */
+ DELAY(5000);
+
/* Finally, reset the ERX. */
GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_RX);
GEM_BANK2_BARRIER(sc, GEM_RESET, 4,
@@ -784,6 +787,9 @@ gem_reset_tx(struct gem_softc *sc)
if (!GEM_BANK1_BITWAIT(sc, GEM_TX_CONFIG, GEM_TX_CONFIG_TXDMA_EN, 0))
device_printf(sc->sc_dev, "cannot disable TX DMA\n");
+ /* Wait 5ms extra. */
+ DELAY(5000);
+
/* Finally, reset the ETX. */
GEM_BANK2_WRITE_4(sc, GEM_RESET, GEM_RESET_TX);
GEM_BANK2_BARRIER(sc, GEM_RESET, 4,
@@ -1239,7 +1245,7 @@ gem_init_regs(struct gem_softc *sc)
GEM_BANK1_WRITE_4(sc, GEM_MAC_PREAMBLE_LEN, 0x7);
GEM_BANK1_WRITE_4(sc, GEM_MAC_JAM_SIZE, 0x4);
GEM_BANK1_WRITE_4(sc, GEM_MAC_ATTEMPT_LIMIT, 0x10);
- GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_TYPE, 0x8088);
+ GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_TYPE, 0x8808);
/* random number seed */
GEM_BANK1_WRITE_4(sc, GEM_MAC_RANDOM_SEED,
@@ -2039,14 +2045,12 @@ gem_mii_statchg(device_t dev)
v = GEM_BANK1_READ_4(sc, GEM_MAC_CONTROL_CONFIG) &
~(GEM_MAC_CC_RX_PAUSE | GEM_MAC_CC_TX_PAUSE);
-#ifdef notyet
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
IFM_ETH_RXPAUSE) != 0)
v |= GEM_MAC_CC_RX_PAUSE;
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) &
IFM_ETH_TXPAUSE) != 0)
v |= GEM_MAC_CC_TX_PAUSE;
-#endif
GEM_BANK1_WRITE_4(sc, GEM_MAC_CONTROL_CONFIG, v);
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) == 0 &&
diff --git a/sys/dev/mii/bmtphy.c b/sys/dev/mii/bmtphy.c
index 63d1df1..6f53349 100644
--- a/sys/dev/mii/bmtphy.c
+++ b/sys/dev/mii/bmtphy.c
@@ -85,6 +85,11 @@ __FBSDID("$FreeBSD$");
static int bmtphy_probe(device_t);
static int bmtphy_attach(device_t);
+struct bmtphy_softc {
+ struct mii_softc mii_sc;
+ int mii_model;
+};
+
static device_method_t bmtphy_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bmtphy_probe),
@@ -100,18 +105,21 @@ static devclass_t bmtphy_devclass;
static driver_t bmtphy_driver = {
"bmtphy",
bmtphy_methods,
- sizeof(struct mii_softc)
+ sizeof(struct bmtphy_softc)
};
DRIVER_MODULE(bmtphy, miibus, bmtphy_driver, bmtphy_devclass, 0, 0);
static int bmtphy_service(struct mii_softc *, struct mii_data *, int);
static void bmtphy_status(struct mii_softc *);
+static void bmtphy_reset(struct mii_softc *);
static const struct mii_phydesc bmtphys_dp[] = {
MII_PHY_DESC(BROADCOM, BCM4401),
MII_PHY_DESC(BROADCOM, BCM5201),
+ MII_PHY_DESC(BROADCOM, BCM5214),
MII_PHY_DESC(BROADCOM, BCM5221),
+ MII_PHY_DESC(BROADCOM, BCM5222),
MII_PHY_END
};
@@ -137,11 +145,13 @@ bmtphy_probe(device_t dev)
static int
bmtphy_attach(device_t dev)
{
- struct mii_softc *sc;
- struct mii_attach_args *ma;
- struct mii_data *mii;
+ struct bmtphy_softc *bsc;
+ struct mii_softc *sc;
+ struct mii_attach_args *ma;
+ struct mii_data *mii;
- sc = device_get_softc(dev);
+ bsc = device_get_softc(dev);
+ sc = &bsc->mii_sc;
ma = device_get_ivars(dev);
sc->mii_dev = device_get_parent(dev);
mii = ma->mii_data;
@@ -153,7 +163,11 @@ bmtphy_attach(device_t dev)
sc->mii_service = bmtphy_service;
sc->mii_pdata = mii;
- mii_phy_reset(sc);
+ sc->mii_flags |= MIIF_NOMANPAUSE;
+
+ bsc->mii_model = MII_MODEL(ma->mii_id2);
+
+ bmtphy_reset(sc);
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
device_printf(dev, " ");
@@ -194,16 +208,15 @@ bmtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
/* Callback if something changed. */
mii_phy_update(sc, cmd);
-
return (0);
}
static void
bmtphy_status(struct mii_softc *sc)
{
- struct mii_data *mii;
- struct ifmedia_entry *ife;
- int bmsr, bmcr, aux_csr;
+ struct mii_data *mii;
+ struct ifmedia_entry *ife;
+ int bmsr, bmcr, aux_csr;
mii = sc->mii_pdata;
ife = mii->mii_media.ifm_cur;
@@ -212,7 +225,6 @@ bmtphy_status(struct mii_softc *sc)
mii->mii_media_active = IFM_ETHER;
bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
- aux_csr = PHY_READ(sc, MII_BMTPHY_AUX_CSR);
if (bmsr & BMSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
@@ -238,14 +250,45 @@ bmtphy_status(struct mii_softc *sc)
return;
}
+ aux_csr = PHY_READ(sc, MII_BMTPHY_AUX_CSR);
if (aux_csr & AUX_CSR_SPEED)
mii->mii_media_active |= IFM_100_TX;
else
mii->mii_media_active |= IFM_10_T;
if (aux_csr & AUX_CSR_FDX)
- mii->mii_media_active |= IFM_FDX;
+ mii->mii_media_active |=
+ IFM_FDX | mii_phy_flowstatus(sc);
else
mii->mii_media_active |= IFM_HDX;
} else
mii->mii_media_active = ife->ifm_media;
}
+
+static void
+bmtphy_reset(struct mii_softc *sc)
+{
+ struct bmtphy_softc *bsc;
+ u_int16_t data;
+
+ bsc = (struct bmtphy_softc *)sc;
+
+ mii_phy_reset(sc);
+
+ if (bsc->mii_model == MII_MODEL_BROADCOM_BCM5221) {
+ /* Enable shadow register mode. */
+ data = PHY_READ(sc, 0x1f);
+ PHY_WRITE(sc, 0x1f, data | 0x0080);
+
+ /* Enable APD (Auto PowerDetect). */
+ data = PHY_READ(sc, MII_BMTPHY_AUX2);
+ PHY_WRITE(sc, MII_BMTPHY_AUX2, data | 0x0020);
+
+ /* Enable clocks across APD for Auto-MDIX functionality. */
+ data = PHY_READ(sc, MII_BMTPHY_INTR);
+ PHY_WRITE(sc, MII_BMTPHY_INTR, data | 0x0004);
+
+ /* Disable shadow register mode. */
+ data = PHY_READ(sc, 0x1f);
+ PHY_WRITE(sc, 0x1f, data & ~0x0080);
+ }
+}
diff --git a/sys/dev/mii/gentbi.c b/sys/dev/mii/gentbi.c
index f5d3a8b..a36f16a 100644
--- a/sys/dev/mii/gentbi.c
+++ b/sys/dev/mii/gentbi.c
@@ -172,6 +172,8 @@ gentbi_attach(device_t dev)
sc->mii_service = gentbi_service;
sc->mii_pdata = mii;
+ sc->mii_flags |= MIIF_NOMANPAUSE;
+
mii_phy_reset(sc);
/*
diff --git a/sys/dev/mii/inphy.c b/sys/dev/mii/inphy.c
index 6830b5a..1293641 100644
--- a/sys/dev/mii/inphy.c
+++ b/sys/dev/mii/inphy.c
@@ -113,6 +113,8 @@ inphy_attach(device_t dev)
sc->mii_service = inphy_service;
sc->mii_pdata = mii;
+ sc->mii_flags |= MIIF_NOMANPAUSE;
+
ifmedia_add(&mii->mii_media,
IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
MII_MEDIA_100_TX, NULL);
@@ -197,7 +199,8 @@ inphy_status(struct mii_softc *sc)
else
mii->mii_media_active |= IFM_10_T;
if (scr & SCR_FDX)
- mii->mii_media_active |= IFM_FDX;
+ mii->mii_media_active |=
+ IFM_FDX | mii_phy_flowstatus(sc);
else
mii->mii_media_active |= IFM_HDX;
} else
diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c
index 3df5dfa..8485691 100644
--- a/sys/dev/mii/mii.c
+++ b/sys/dev/mii/mii.c
@@ -137,7 +137,7 @@ miibus_attach(device_t dev)
free(children, M_TEMP);
}
if (nchildren == 0) {
- device_printf(dev, "cannot get children");
+ device_printf(dev, "cannot get children\n");
return (ENXIO);
}
ivars = device_get_ivars(dev);
@@ -311,12 +311,12 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
int bmsr, first, i, nchildren, offset, phymax, phymin, rv;
if (phyloc != MII_PHY_ANY && offloc != MII_OFFSET_ANY) {
- printf("%s: phyloc and offloc specified", __func__);
+ printf("%s: phyloc and offloc specified\n", __func__);
return (EINVAL);
}
if (offloc != MII_OFFSET_ANY && (offloc < 0 || offloc >= MII_NPHY)) {
- printf("%s: ivalid offloc %d", __func__, offloc);
+ printf("%s: ivalid offloc %d\n", __func__, offloc);
return (EINVAL);
}
@@ -325,7 +325,7 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
phymax = MII_NPHY - 1;
} else {
if (phyloc < 0 || phyloc >= MII_NPHY) {
- printf("%s: ivalid phyloc %d", __func__, phyloc);
+ printf("%s: ivalid phyloc %d\n", __func__, phyloc);
return (EINVAL);
}
phymin = phymax = phyloc;
@@ -352,7 +352,7 @@ mii_attach(device_t dev, device_t *miibus, struct ifnet *ifp,
if (ivars->ifp != ifp || ivars->ifmedia_upd != ifmedia_upd ||
ivars->ifmedia_sts != ifmedia_sts ||
ivars->mii_flags != flags) {
- printf("%s: non-matching invariant", __func__);
+ printf("%s: non-matching invariant\n", __func__);
return (EINVAL);
}
/*
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index ec0b846..24cd551 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -128,7 +128,9 @@ model ATHEROS F1_7 0x0007 Atheros F1 10/100/1000 PHY
model BROADCOM 3C905B 0x0012 3c905B 10/100 internal PHY
model BROADCOM 3C905C 0x0017 3c905C 10/100 internal PHY
model BROADCOM BCM5201 0x0021 BCM5201 10/100baseTX PHY
+model BROADCOM BCM5214 0x0028 BCM5214 Quad 10/100 PHY
model BROADCOM BCM5221 0x001e BCM5221 10/100baseTX PHY
+model BROADCOM BCM5222 0x0032 BCM5222 Dual 10/100 PHY
model BROADCOM BCM4401 0x0036 BCM4401 10/100baseTX PHY
model xxBROADCOM BCM5400 0x0004 Broadcom 1000baseTX PHY
model xxBROADCOM BCM5401 0x0005 BCM5401 10/100/1000baseTX PHY
diff --git a/sys/dev/mii/nsgphy.c b/sys/dev/mii/nsgphy.c
index 7cdee42..4177912 100644
--- a/sys/dev/mii/nsgphy.c
+++ b/sys/dev/mii/nsgphy.c
@@ -135,6 +135,8 @@ nsgphy_attach(device_t dev)
sc->mii_service = nsgphy_service;
sc->mii_pdata = mii;
+ sc->mii_flags |= MIIF_NOMANPAUSE;
+
mii_phy_reset(sc);
/*
diff --git a/sys/dev/mii/nsphyter.c b/sys/dev/mii/nsphyter.c
index 5489504..c302181 100644
--- a/sys/dev/mii/nsphyter.c
+++ b/sys/dev/mii/nsphyter.c
@@ -143,6 +143,8 @@ nsphyter_attach(device_t dev)
sc->mii_service = nsphyter_service;
sc->mii_pdata = mii;
+ sc->mii_flags |= MIIF_NOMANPAUSE;
+
#if 1
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
@@ -242,12 +244,8 @@ nsphyter_status(struct mii_softc *sc)
else
mii->mii_media_active |= IFM_100_TX;
if ((physts & PHYSTS_DUPLEX) != 0)
-#ifdef notyet
mii->mii_media_active |=
IFM_FDX | mii_phy_flowstatus(sc);
-#else
- mii->mii_media_active |= IFM_FDX;
-#endif
else
mii->mii_media_active |= IFM_HDX;
} else
diff --git a/sys/dev/mii/ukphy.c b/sys/dev/mii/ukphy.c
index 05b1b45..10842b7 100644
--- a/sys/dev/mii/ukphy.c
+++ b/sys/dev/mii/ukphy.c
@@ -136,6 +136,8 @@ ukphy_attach(device_t dev)
sc->mii_service = ukphy_service;
sc->mii_pdata = mii;
+ sc->mii_flags |= MIIF_NOMANPAUSE;
+
mii_phy_reset(sc);
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 6069b6d..e3b6159 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -3022,8 +3022,35 @@ pci_resume(device_t dev)
if (!device_is_attached(child))
pci_cfg_save(child, dinfo, 1);
}
+
+ /*
+ * Resume critical devices first, then everything else later.
+ */
+ for (i = 0; i < numdevs; i++) {
+ child = devlist[i];
+ switch (pci_get_class(child)) {
+ case PCIC_DISPLAY:
+ case PCIC_MEMORY:
+ case PCIC_BRIDGE:
+ case PCIC_BASEPERIPH:
+ DEVICE_RESUME(child);
+ break;
+ }
+ }
+ for (i = 0; i < numdevs; i++) {
+ child = devlist[i];
+ switch (pci_get_class(child)) {
+ case PCIC_DISPLAY:
+ case PCIC_MEMORY:
+ case PCIC_BRIDGE:
+ case PCIC_BASEPERIPH:
+ break;
+ default:
+ DEVICE_RESUME(child);
+ }
+ }
free(devlist, M_TEMP);
- return (bus_generic_resume(dev));
+ return (0);
}
static void
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c
index 7915818..199c132 100644
--- a/sys/dev/pci/pci_pci.c
+++ b/sys/dev/pci/pci_pci.c
@@ -860,7 +860,9 @@ host_pcib_get_busno(pci_read_config_fn read_config, int bus, int slot, int func,
case 0x00171166:
case 0x01011166:
case 0x010f1014:
+ case 0x01101166:
case 0x02011166:
+ case 0x02251166:
case 0x03021014:
*busnum = read_config(bus, slot, func, 0x44, 1);
break;
diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c
index afc2118..d774d34 100644
--- a/sys/dev/usb/controller/usb_controller.c
+++ b/sys/dev/usb/controller/usb_controller.c
@@ -207,6 +207,8 @@ usb_detach(device_t dev)
usb_proc_free(&bus->control_xfer_proc);
+ usbpf_detach(bus);
+
return (0);
}
@@ -435,6 +437,8 @@ usb_attach_sub(device_t dev, struct usb_bus *bus)
usb_devclass_ptr = devclass_find("usbus");
mtx_unlock(&Giant);
+ usbpf_attach(bus);
+
/* Initialise USB process messages */
bus->explore_msg[0].hdr.pm_callback = &usb_bus_explore;
bus->explore_msg[0].bus = bus;
@@ -548,8 +552,6 @@ usb_bus_mem_alloc_all(struct usb_bus *bus, bus_dma_tag_t dmat,
TAILQ_INIT(&bus->intr_q.head);
- usbpf_attach(bus, &bus->uif);
-
#if USB_HAVE_BUSDMA
usb_dma_tag_setup(bus->dma_parent_tag, bus->dma_tags,
dmat, &bus->bus_mtx, NULL, 32, USB_BUS_DMA_TAG_MAX);
@@ -597,8 +599,6 @@ usb_bus_mem_free_all(struct usb_bus *bus, usb_bus_mem_cb_t *cb)
usb_dma_tag_unsetup(bus->dma_parent_tag);
#endif
- usbpf_detach(bus);
-
mtx_destroy(&bus->bus_mtx);
}
diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c
index 646063a..c19f1fd 100644
--- a/sys/dev/usb/serial/u3g.c
+++ b/sys/dev/usb/serial/u3g.c
@@ -281,12 +281,12 @@ static const struct usb_device_id u3g_devs[] = {
U3G_DEV(HUAWEI, E143D, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E143E, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E143F, U3GINIT_HUAWEI),
- U3G_DEV(HUAWEI, E14AC, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E180V, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E220, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E220BIS, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, MOBILE, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, E1752, U3GINIT_HUAWEISCSI),
+ U3G_DEV(HUAWEI, E1820, U3GINIT_HUAWEISCSI),
U3G_DEV(HUAWEI, K3765, U3GINIT_HUAWEI),
U3G_DEV(HUAWEI, K3765_INIT, U3GINIT_HUAWEISCSI),
U3G_DEV(KYOCERA2, CDMA_MSM_K, 0),
diff --git a/sys/dev/usb/usb_bus.h b/sys/dev/usb/usb_bus.h
index c5dfeff..1dd9d6a 100644
--- a/sys/dev/usb/usb_bus.h
+++ b/sys/dev/usb/usb_bus.h
@@ -86,7 +86,7 @@ struct usb_bus {
struct usb_bus_methods *methods; /* filled by HC driver */
struct usb_device **devices;
- struct usbpf_if *uif; /* USB Packet Filter */
+ struct ifnet *ifp; /* only for USB Packet Filter */
usb_power_mask_t hw_power_state; /* see USB_HW_POWER_XXX */
usb_size_t uframe_usage[USB_HS_MICRO_FRAMES_MAX];
diff --git a/sys/dev/usb/usb_pf.c b/sys/dev/usb/usb_pf.c
index 3f5f204..c2925c2 100644
--- a/sys/dev/usb/usb_pf.c
+++ b/sys/dev/usb/usb_pf.c
@@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
+#include <net/if_types.h>
+#include <net/bpf.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -55,1623 +57,39 @@ __FBSDID("$FreeBSD$");
#include <dev/usb/usb_pf.h>
#include <dev/usb/usb_transfer.h>
-/*
- * All usbpf implementations are extracted from bpf(9) APIs and it's
- * specialized for USB packet filtering between the driver and the host
- * controller.
- */
-
-MALLOC_DEFINE(M_USBPF, "USBPktFilter", "USB Packet Filter");
-
-/*
- * Rotate the packet buffers in descriptor ud. Move the store buffer into the
- * hold slot, and the free buffer ino the store slot. Zero the length of the
- * new store buffer. Descriptor lock should be held.
- */
-#define USBPF_ROTATE_BUFFERS(ud) do { \
- (ud)->ud_hbuf = (ud)->ud_sbuf; \
- (ud)->ud_hlen = (ud)->ud_slen; \
- (ud)->ud_sbuf = (ud)->ud_fbuf; \
- (ud)->ud_slen = 0; \
- (ud)->ud_fbuf = NULL; \
- usbpf_bufheld(ud); \
-} while (0)
-
-#ifndef __i386__
-#define USBPF_ALIGN
-#endif
-
-#ifndef USBPF_ALIGN
-#define USBPF_EXTRACT_SHORT(p) ((u_int16_t)ntohs(*(u_int16_t *)p))
-#define USBPF_EXTRACT_LONG(p) (ntohl(*(u_int32_t *)p))
-#else
-#define USBPF_EXTRACT_SHORT(p) \
- ((u_int16_t) \
- ((u_int16_t)*((u_char *)p+0)<<8| \
- (u_int16_t)*((u_char *)p+1)<<0))
-#define USBPF_EXTRACT_LONG(p) \
- ((u_int32_t)*((u_char *)p+0)<<24| \
- (u_int32_t)*((u_char *)p+1)<<16| \
- (u_int32_t)*((u_char *)p+2)<<8| \
- (u_int32_t)*((u_char *)p+3)<<0)
-#endif
-
-/*
- * Number of scratch memory words (for USBPF_LD|USBPF_MEM and USBPF_ST).
- */
-#define USBPF_MEMWORDS 16
-
-/* Values for ud_state */
-#define USBPF_IDLE 0 /* no select in progress */
-#define USBPF_WAITING 1 /* waiting for read timeout in select */
-#define USBPF_TIMED_OUT 2 /* read timeout has expired in select */
-
-#define PRIUSB 26 /* interruptible */
-
-/* Frame directions */
-enum usbpf_direction {
- USBPF_D_IN, /* See incoming frames */
- USBPF_D_INOUT, /* See incoming and outgoing frames */
- USBPF_D_OUT /* See outgoing frames */
-};
-
-static void usbpf_append_bytes(struct usbpf_d *, caddr_t, u_int, void *,
- u_int);
-static void usbpf_attachd(struct usbpf_d *, struct usbpf_if *);
-static void usbpf_detachd(struct usbpf_d *);
-static int usbpf_canfreebuf(struct usbpf_d *);
-static void usbpf_buf_reclaimed(struct usbpf_d *);
-static int usbpf_canwritebuf(struct usbpf_d *);
-
-static d_open_t usbpf_open;
-static d_read_t usbpf_read;
-static d_write_t usbpf_write;
-static d_ioctl_t usbpf_ioctl;
-static d_poll_t usbpf_poll;
-static d_kqfilter_t usbpf_kqfilter;
-
-static struct cdevsw usbpf_cdevsw = {
- .d_version = D_VERSION,
- .d_open = usbpf_open,
- .d_read = usbpf_read,
- .d_write = usbpf_write,
- .d_ioctl = usbpf_ioctl,
- .d_poll = usbpf_poll,
- .d_name = "usbpf",
- .d_kqfilter = usbpf_kqfilter,
-};
-
-static LIST_HEAD(, usbpf_if) usbpf_iflist;
-static struct mtx usbpf_mtx; /* global lock */
-static int usbpf_uifd_cnt;
-
-static int usbpf_bufsize = 4096;
-#define USBPF_MINBUFSIZE 32
-#define USBPF_MAXBUFSIZE 0x80000
-static int usbpf_maxbufsize = USBPF_MAXBUFSIZE;
-#define USBPF_MAXINSNS 512
-static int usbpf_maxinsns = USBPF_MAXINSNS;
-
-static void
-usbpf_buffer_init(struct usbpf_d *ud)
-{
-
- ud->ud_bufsize = usbpf_bufsize;
-}
-
-/*
- * Free USBPF kernel buffers on device close.
- */
-static void
-usbpf_buffer_free(struct usbpf_d *ud)
-{
-
- if (ud->ud_sbuf != NULL)
- free(ud->ud_sbuf, M_USBPF);
- if (ud->ud_hbuf != NULL)
- free(ud->ud_hbuf, M_USBPF);
- if (ud->ud_fbuf != NULL)
- free(ud->ud_fbuf, M_USBPF);
-
-#ifdef INVARIANTS
- ud->ud_sbuf = ud->ud_hbuf = ud->ud_fbuf = (caddr_t)~0;
-#endif
-}
-
-static void
-usbpf_buffer_alloc(struct usbpf_d *ud)
-{
-
- KASSERT(ud->ud_fbuf == NULL, ("%s: ud_fbuf != NULL", __func__));
- KASSERT(ud->ud_sbuf == NULL, ("%s: ud_sbuf != NULL", __func__));
- KASSERT(ud->ud_hbuf == NULL, ("%s: ud_hbuf != NULL", __func__));
-
- ud->ud_fbuf = (caddr_t)malloc(ud->ud_bufsize, M_USBPF, M_WAITOK);
- ud->ud_sbuf = (caddr_t)malloc(ud->ud_bufsize, M_USBPF, M_WAITOK);
- ud->ud_hbuf = NULL;
- ud->ud_slen = 0;
- ud->ud_hlen = 0;
-}
-
-/*
- * Copy buffer storage to user space in read().
- */
-static int
-usbpf_buffer_uiomove(struct usbpf_d *ud, caddr_t buf, u_int len,
- struct uio *uio)
-{
-
- return (uiomove(buf, len, uio));
-}
-
-/*
- * Simple data copy to the current kernel buffer.
- */
-static void
-usbpf_buffer_append_bytes(struct usbpf_d *ud, caddr_t buf, u_int offset,
- void *src, u_int len)
-{
- u_char *src_bytes;
-
- src_bytes = (u_char *)src;
- bcopy(src_bytes, buf + offset, len);
-}
-
-/*
- * Allocate or resize buffers.
- */
-static int
-usbpf_buffer_ioctl_sblen(struct usbpf_d *ud, u_int *i)
-{
- u_int size;
-
- USBPFD_LOCK(ud);
- if (ud->ud_bif != NULL) {
- USBPFD_UNLOCK(ud);
- return (EINVAL);
- }
- size = *i;
- if (size > usbpf_maxbufsize)
- *i = size = usbpf_maxbufsize;
- else if (size < USBPF_MINBUFSIZE)
- *i = size = USBPF_MINBUFSIZE;
- ud->ud_bufsize = size;
- USBPFD_UNLOCK(ud);
- return (0);
-}
-
-static const u_short usbpf_code_map[] = {
- 0x10ff, /* 0x00-0x0f: 1111111100001000 */
- 0x3070, /* 0x10-0x1f: 0000111000001100 */
- 0x3131, /* 0x20-0x2f: 1000110010001100 */
- 0x3031, /* 0x30-0x3f: 1000110000001100 */
- 0x3131, /* 0x40-0x4f: 1000110010001100 */
- 0x1011, /* 0x50-0x5f: 1000100000001000 */
- 0x1013, /* 0x60-0x6f: 1100100000001000 */
- 0x1010, /* 0x70-0x7f: 0000100000001000 */
- 0x0093, /* 0x80-0x8f: 1100100100000000 */
- 0x0000, /* 0x90-0x9f: 0000000000000000 */
- 0x0000, /* 0xa0-0xaf: 0000000000000000 */
- 0x0002, /* 0xb0-0xbf: 0100000000000000 */
- 0x0000, /* 0xc0-0xcf: 0000000000000000 */
- 0x0000, /* 0xd0-0xdf: 0000000000000000 */
- 0x0000, /* 0xe0-0xef: 0000000000000000 */
- 0x0000 /* 0xf0-0xff: 0000000000000000 */
-};
-
-#define USBPF_VALIDATE_CODE(c) \
- ((c) <= 0xff && (usbpf_code_map[(c) >> 4] & (1 << ((c) & 0xf))) != 0)
-
-/*
- * Return true if the 'fcode' is a valid filter program.
- * The constraints are that each jump be forward and to a valid
- * code. The code must terminate with either an accept or reject.
- *
- * The kernel needs to be able to verify an application's filter code.
- * Otherwise, a bogus program could easily crash the system.
- */
-static int
-usbpf_validate(const struct usbpf_insn *f, int len)
-{
- register int i;
- register const struct usbpf_insn *p;
-
- /* Do not accept negative length filter. */
- if (len < 0)
- return (0);
-
- /* An empty filter means accept all. */
- if (len == 0)
- return (1);
-
- for (i = 0; i < len; ++i) {
- p = &f[i];
- /*
- * Check that the code is valid.
- */
- if (!USBPF_VALIDATE_CODE(p->code))
- return (0);
- /*
- * Check that that jumps are forward, and within
- * the code block.
- */
- if (USBPF_CLASS(p->code) == USBPF_JMP) {
- register u_int offset;
-
- if (p->code == (USBPF_JMP|USBPF_JA))
- offset = p->k;
- else
- offset = p->jt > p->jf ? p->jt : p->jf;
- if (offset >= (u_int)(len - i) - 1)
- return (0);
- continue;
- }
- /*
- * Check that memory operations use valid addresses.
- */
- if (p->code == USBPF_ST || p->code == USBPF_STX ||
- p->code == (USBPF_LD|USBPF_MEM) ||
- p->code == (USBPF_LDX|USBPF_MEM)) {
- if (p->k >= USBPF_MEMWORDS)
- return (0);
- continue;
- }
- /*
- * Check for constant division by 0.
- */
- if (p->code == (USBPF_ALU|USBPF_DIV|USBPF_K) && p->k == 0)
- return (0);
- }
- return (USBPF_CLASS(f[len - 1].code) == USBPF_RET);
-}
-
-#ifdef _KERNEL
-#define MINDEX(m, k) \
-{ \
- register int len = m->m_len; \
- \
- while (k >= len) { \
- k -= len; \
- m = m->m_next; \
- if (m == 0) \
- return (0); \
- len = m->m_len; \
- } \
-}
-
-static u_int16_t m_xhalf(struct mbuf *m, usbpf_u_int32 k, int *err);
-static u_int32_t m_xword(struct mbuf *m, usbpf_u_int32 k, int *err);
-
-static u_int32_t
-m_xword(struct mbuf *m, usbpf_u_int32 k, int *err)
-{
- size_t len;
- u_char *cp, *np;
- struct mbuf *m0;
-
- len = m->m_len;
- while (k >= len) {
- k -= len;
- m = m->m_next;
- if (m == 0)
- goto bad;
- len = m->m_len;
- }
- cp = mtod(m, u_char *) + k;
- if (len - k >= 4) {
- *err = 0;
- return (USBPF_EXTRACT_LONG(cp));
- }
- m0 = m->m_next;
- if (m0 == 0 || m0->m_len + len - k < 4)
- goto bad;
- *err = 0;
- np = mtod(m0, u_char *);
- switch (len - k) {
- case 1:
- return (((u_int32_t)cp[0] << 24) |
- ((u_int32_t)np[0] << 16) |
- ((u_int32_t)np[1] << 8) |
- (u_int32_t)np[2]);
-
- case 2:
- return (((u_int32_t)cp[0] << 24) |
- ((u_int32_t)cp[1] << 16) |
- ((u_int32_t)np[0] << 8) |
- (u_int32_t)np[1]);
-
- default:
- return (((u_int32_t)cp[0] << 24) |
- ((u_int32_t)cp[1] << 16) |
- ((u_int32_t)cp[2] << 8) |
- (u_int32_t)np[0]);
- }
- bad:
- *err = 1;
- return (0);
-}
-
-static u_int16_t
-m_xhalf(struct mbuf *m, usbpf_u_int32 k, int *err)
-{
- size_t len;
- u_char *cp;
- struct mbuf *m0;
-
- len = m->m_len;
- while (k >= len) {
- k -= len;
- m = m->m_next;
- if (m == 0)
- goto bad;
- len = m->m_len;
- }
- cp = mtod(m, u_char *) + k;
- if (len - k >= 2) {
- *err = 0;
- return (USBPF_EXTRACT_SHORT(cp));
- }
- m0 = m->m_next;
- if (m0 == 0)
- goto bad;
- *err = 0;
- return ((cp[0] << 8) | mtod(m0, u_char *)[0]);
- bad:
- *err = 1;
- return (0);
-}
-#endif
-
-/*
- * Execute the filter program starting at pc on the packet p
- * wirelen is the length of the original packet
- * buflen is the amount of data present
- */
-static u_int
-usbpf_filter(const struct usbpf_insn *pc, u_char *p, u_int wirelen,
- u_int buflen)
-{
- u_int32_t A = 0, X = 0;
- usbpf_u_int32 k;
- u_int32_t mem[USBPF_MEMWORDS];
-
- /*
- * XXX temporarily the filter system is disabled because currently it
- * could not handle the some machine code properly that leads to
- * kernel crash by invalid usage.
- */
- return ((u_int)-1);
-
- if (pc == NULL)
- /*
- * No filter means accept all.
- */
- return ((u_int)-1);
-
- --pc;
- while (1) {
- ++pc;
- switch (pc->code) {
- default:
-#ifdef _KERNEL
- return (0);
-#else
- abort();
-#endif
-
- case USBPF_RET|USBPF_K:
- return ((u_int)pc->k);
-
- case USBPF_RET|USBPF_A:
- return ((u_int)A);
-
- case USBPF_LD|USBPF_W|USBPF_ABS:
- k = pc->k;
- if (k > buflen || sizeof(int32_t) > buflen - k) {
-#ifdef _KERNEL
- int merr;
-
- if (buflen != 0)
- return (0);
- A = m_xword((struct mbuf *)p, k, &merr);
- if (merr != 0)
- return (0);
- continue;
-#else
- return (0);
-#endif
- }
-#ifdef USBPF_ALIGN
- if (((intptr_t)(p + k) & 3) != 0)
- A = USBPF_EXTRACT_LONG(&p[k]);
- else
-#endif
- A = ntohl(*(int32_t *)(p + k));
- continue;
-
- case USBPF_LD|USBPF_H|USBPF_ABS:
- k = pc->k;
- if (k > buflen || sizeof(int16_t) > buflen - k) {
-#ifdef _KERNEL
- int merr;
-
- if (buflen != 0)
- return (0);
- A = m_xhalf((struct mbuf *)p, k, &merr);
- continue;
-#else
- return (0);
-#endif
- }
- A = USBPF_EXTRACT_SHORT(&p[k]);
- continue;
-
- case USBPF_LD|USBPF_B|USBPF_ABS:
- k = pc->k;
- if (k >= buflen) {
-#ifdef _KERNEL
- struct mbuf *m;
-
- if (buflen != 0)
- return (0);
- m = (struct mbuf *)p;
- MINDEX(m, k);
- A = mtod(m, u_char *)[k];
- continue;
-#else
- return (0);
-#endif
- }
- A = p[k];
- continue;
-
- case USBPF_LD|USBPF_W|USBPF_LEN:
- A = wirelen;
- continue;
-
- case USBPF_LDX|USBPF_W|USBPF_LEN:
- X = wirelen;
- continue;
-
- case USBPF_LD|USBPF_W|USBPF_IND:
- k = X + pc->k;
- if (pc->k > buflen || X > buflen - pc->k ||
- sizeof(int32_t) > buflen - k) {
-#ifdef _KERNEL
- int merr;
-
- if (buflen != 0)
- return (0);
- A = m_xword((struct mbuf *)p, k, &merr);
- if (merr != 0)
- return (0);
- continue;
-#else
- return (0);
-#endif
- }
-#ifdef USBPF_ALIGN
- if (((intptr_t)(p + k) & 3) != 0)
- A = USBPF_EXTRACT_LONG(&p[k]);
- else
-#endif
- A = ntohl(*(int32_t *)(p + k));
- continue;
-
- case USBPF_LD|USBPF_H|USBPF_IND:
- k = X + pc->k;
- if (X > buflen || pc->k > buflen - X ||
- sizeof(int16_t) > buflen - k) {
-#ifdef _KERNEL
- int merr;
-
- if (buflen != 0)
- return (0);
- A = m_xhalf((struct mbuf *)p, k, &merr);
- if (merr != 0)
- return (0);
- continue;
-#else
- return (0);
-#endif
- }
- A = USBPF_EXTRACT_SHORT(&p[k]);
- continue;
-
- case USBPF_LD|USBPF_B|USBPF_IND:
- k = X + pc->k;
- if (pc->k >= buflen || X >= buflen - pc->k) {
-#ifdef _KERNEL
- struct mbuf *m;
-
- if (buflen != 0)
- return (0);
- m = (struct mbuf *)p;
- MINDEX(m, k);
- A = mtod(m, u_char *)[k];
- continue;
-#else
- return (0);
-#endif
- }
- A = p[k];
- continue;
-
- case USBPF_LDX|USBPF_MSH|USBPF_B:
- k = pc->k;
- if (k >= buflen) {
-#ifdef _KERNEL
- register struct mbuf *m;
-
- if (buflen != 0)
- return (0);
- m = (struct mbuf *)p;
- MINDEX(m, k);
- X = (mtod(m, u_char *)[k] & 0xf) << 2;
- continue;
-#else
- return (0);
-#endif
- }
- X = (p[pc->k] & 0xf) << 2;
- continue;
-
- case USBPF_LD|USBPF_IMM:
- A = pc->k;
- continue;
-
- case USBPF_LDX|USBPF_IMM:
- X = pc->k;
- continue;
-
- case USBPF_LD|USBPF_MEM:
- A = mem[pc->k];
- continue;
-
- case USBPF_LDX|USBPF_MEM:
- X = mem[pc->k];
- continue;
-
- case USBPF_ST:
- mem[pc->k] = A;
- continue;
-
- case USBPF_STX:
- mem[pc->k] = X;
- continue;
-
- case USBPF_JMP|USBPF_JA:
- pc += pc->k;
- continue;
-
- case USBPF_JMP|USBPF_JGT|USBPF_K:
- pc += (A > pc->k) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JGE|USBPF_K:
- pc += (A >= pc->k) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JEQ|USBPF_K:
- pc += (A == pc->k) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JSET|USBPF_K:
- pc += (A & pc->k) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JGT|USBPF_X:
- pc += (A > X) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JGE|USBPF_X:
- pc += (A >= X) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JEQ|USBPF_X:
- pc += (A == X) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_JMP|USBPF_JSET|USBPF_X:
- pc += (A & X) ? pc->jt : pc->jf;
- continue;
-
- case USBPF_ALU|USBPF_ADD|USBPF_X:
- A += X;
- continue;
-
- case USBPF_ALU|USBPF_SUB|USBPF_X:
- A -= X;
- continue;
-
- case USBPF_ALU|USBPF_MUL|USBPF_X:
- A *= X;
- continue;
-
- case USBPF_ALU|USBPF_DIV|USBPF_X:
- if (X == 0)
- return (0);
- A /= X;
- continue;
-
- case USBPF_ALU|USBPF_AND|USBPF_X:
- A &= X;
- continue;
-
- case USBPF_ALU|USBPF_OR|USBPF_X:
- A |= X;
- continue;
-
- case USBPF_ALU|USBPF_LSH|USBPF_X:
- A <<= X;
- continue;
-
- case USBPF_ALU|USBPF_RSH|USBPF_X:
- A >>= X;
- continue;
-
- case USBPF_ALU|USBPF_ADD|USBPF_K:
- A += pc->k;
- continue;
-
- case USBPF_ALU|USBPF_SUB|USBPF_K:
- A -= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_MUL|USBPF_K:
- A *= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_DIV|USBPF_K:
- A /= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_AND|USBPF_K:
- A &= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_OR|USBPF_K:
- A |= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_LSH|USBPF_K:
- A <<= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_RSH|USBPF_K:
- A >>= pc->k;
- continue;
-
- case USBPF_ALU|USBPF_NEG:
- A = -A;
- continue;
-
- case USBPF_MISC|USBPF_TAX:
- X = A;
- continue;
-
- case USBPF_MISC|USBPF_TXA:
- A = X;
- continue;
- }
- }
-}
-
-static void
-usbpf_free(struct usbpf_d *ud)
-{
-
- switch (ud->ud_bufmode) {
- case USBPF_BUFMODE_BUFFER:
- return (usbpf_buffer_free(ud));
- default:
- panic("usbpf_buf_free");
- }
-}
-
-/*
- * Notify the buffer model that a buffer has moved into the hold position.
- */
-static void
-usbpf_bufheld(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
-}
-
-/*
- * Free buffers currently in use by a descriptor.
- * Called on close.
- */
-static void
-usbpf_freed(struct usbpf_d *ud)
-{
-
- /*
- * We don't need to lock out interrupts since this descriptor has
- * been detached from its interface and it yet hasn't been marked
- * free.
- */
- usbpf_free(ud);
- if (ud->ud_rfilter != NULL)
- free((caddr_t)ud->ud_rfilter, M_USBPF);
- if (ud->ud_wfilter != NULL)
- free((caddr_t)ud->ud_wfilter, M_USBPF);
- mtx_destroy(&ud->ud_mtx);
-}
-
-/*
- * Close the descriptor by detaching it from its interface,
- * deallocating its buffers, and marking it free.
- */
-static void
-usbpf_dtor(void *data)
-{
- struct usbpf_d *ud = data;
-
- USBPFD_LOCK(ud);
- if (ud->ud_state == USBPF_WAITING)
- callout_stop(&ud->ud_callout);
- ud->ud_state = USBPF_IDLE;
- USBPFD_UNLOCK(ud);
- funsetown(&ud->ud_sigio);
- mtx_lock(&usbpf_mtx);
- if (ud->ud_bif)
- usbpf_detachd(ud);
- mtx_unlock(&usbpf_mtx);
- selwakeuppri(&ud->ud_sel, PRIUSB);
- knlist_destroy(&ud->ud_sel.si_note);
- callout_drain(&ud->ud_callout);
- usbpf_freed(ud);
- free(ud, M_USBPF);
-}
-
-/*
- * Open device. Returns ENXIO for illegal minor device number,
- * EBUSY if file is open by another process.
- */
-/* ARGSUSED */
-static int
-usbpf_open(struct cdev *dev, int flags, int fmt, struct thread *td)
-{
- struct usbpf_d *ud;
- int error;
-
- ud = malloc(sizeof(*ud), M_USBPF, M_WAITOK | M_ZERO);
- error = devfs_set_cdevpriv(ud, usbpf_dtor);
- if (error != 0) {
- free(ud, M_USBPF);
- return (error);
- }
-
- usbpf_buffer_init(ud);
- ud->ud_bufmode = USBPF_BUFMODE_BUFFER;
- ud->ud_sig = SIGIO;
- ud->ud_direction = USBPF_D_INOUT;
- ud->ud_pid = td->td_proc->p_pid;
- mtx_init(&ud->ud_mtx, devtoname(dev), "usbpf cdev lock", MTX_DEF);
- callout_init_mtx(&ud->ud_callout, &ud->ud_mtx, 0);
- knlist_init_mtx(&ud->ud_sel.si_note, &ud->ud_mtx);
-
- return (0);
-}
-
-static int
-usbpf_uiomove(struct usbpf_d *ud, caddr_t buf, u_int len, struct uio *uio)
-{
-
- if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER)
- return (EOPNOTSUPP);
- return (usbpf_buffer_uiomove(ud, buf, len, uio));
-}
-
-/*
- * usbpf_read - read next chunk of packets from buffers
- */
-static int
-usbpf_read(struct cdev *dev, struct uio *uio, int ioflag)
-{
- struct usbpf_d *ud;
- int error;
- int non_block;
- int timed_out;
-
- error = devfs_get_cdevpriv((void **)&ud);
- if (error != 0)
- return (error);
-
- /*
- * Restrict application to use a buffer the same size as
- * as kernel buffers.
- */
- if (uio->uio_resid != ud->ud_bufsize)
- return (EINVAL);
-
- non_block = ((ioflag & O_NONBLOCK) != 0);
-
- USBPFD_LOCK(ud);
- ud->ud_pid = curthread->td_proc->p_pid;
- if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER) {
- USBPFD_UNLOCK(ud);
- return (EOPNOTSUPP);
- }
- if (ud->ud_state == USBPF_WAITING)
- callout_stop(&ud->ud_callout);
- timed_out = (ud->ud_state == USBPF_TIMED_OUT);
- ud->ud_state = USBPF_IDLE;
- /*
- * If the hold buffer is empty, then do a timed sleep, which
- * ends when the timeout expires or when enough packets
- * have arrived to fill the store buffer.
- */
- while (ud->ud_hbuf == NULL) {
- if (ud->ud_slen != 0) {
- /*
- * A packet(s) either arrived since the previous
- * read or arrived while we were asleep.
- */
- if (ud->ud_immediate || non_block || timed_out) {
- /*
- * Rotate the buffers and return what's here
- * if we are in immediate mode, non-blocking
- * flag is set, or this descriptor timed out.
- */
- USBPF_ROTATE_BUFFERS(ud);
- break;
- }
- }
-
- /*
- * No data is available, check to see if the usbpf device
- * is still pointed at a real interface. If not, return
- * ENXIO so that the userland process knows to rebind
- * it before using it again.
- */
- if (ud->ud_bif == NULL) {
- USBPFD_UNLOCK(ud);
- return (ENXIO);
- }
-
- if (non_block) {
- USBPFD_UNLOCK(ud);
- return (EWOULDBLOCK);
- }
- error = msleep(ud, &ud->ud_mtx, PRIUSB|PCATCH,
- "uff", ud->ud_rtout);
- if (error == EINTR || error == ERESTART) {
- USBPFD_UNLOCK(ud);
- return (error);
- }
- if (error == EWOULDBLOCK) {
- /*
- * On a timeout, return what's in the buffer,
- * which may be nothing. If there is something
- * in the store buffer, we can rotate the buffers.
- */
- if (ud->ud_hbuf)
- /*
- * We filled up the buffer in between
- * getting the timeout and arriving
- * here, so we don't need to rotate.
- */
- break;
-
- if (ud->ud_slen == 0) {
- USBPFD_UNLOCK(ud);
- return (0);
- }
- USBPF_ROTATE_BUFFERS(ud);
- break;
- }
- }
- /*
- * At this point, we know we have something in the hold slot.
- */
- USBPFD_UNLOCK(ud);
-
- /*
- * Move data from hold buffer into user space.
- * We know the entire buffer is transferred since
- * we checked above that the read buffer is usbpf_bufsize bytes.
- *
- * XXXRW: More synchronization needed here: what if a second thread
- * issues a read on the same fd at the same time? Don't want this
- * getting invalidated.
- */
- error = usbpf_uiomove(ud, ud->ud_hbuf, ud->ud_hlen, uio);
-
- USBPFD_LOCK(ud);
- ud->ud_fbuf = ud->ud_hbuf;
- ud->ud_hbuf = NULL;
- ud->ud_hlen = 0;
- usbpf_buf_reclaimed(ud);
- USBPFD_UNLOCK(ud);
-
- return (error);
-}
-
-static int
-usbpf_write(struct cdev *dev, struct uio *uio, int ioflag)
-{
-
- /* NOT IMPLEMENTED */
- return (ENOSYS);
-}
-
-static int
-usbpf_ioctl_sblen(struct usbpf_d *ud, u_int *i)
-{
-
- if (ud->ud_bufmode != USBPF_BUFMODE_BUFFER)
- return (EOPNOTSUPP);
- return (usbpf_buffer_ioctl_sblen(ud, i));
-}
-
-/*
- * Reset a descriptor by flushing its packet buffer and clearing the receive
- * and drop counts. This is doable for kernel-only buffers, but with
- * zero-copy buffers, we can't write to (or rotate) buffers that are
- * currently owned by userspace. It would be nice if we could encapsulate
- * this logic in the buffer code rather than here.
- */
-static void
-usbpf_reset_d(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
-
- if ((ud->ud_hbuf != NULL) &&
- (ud->ud_bufmode != USBPF_BUFMODE_ZBUF || usbpf_canfreebuf(ud))) {
- /* Free the hold buffer. */
- ud->ud_fbuf = ud->ud_hbuf;
- ud->ud_hbuf = NULL;
- ud->ud_hlen = 0;
- usbpf_buf_reclaimed(ud);
- }
- if (usbpf_canwritebuf(ud))
- ud->ud_slen = 0;
- ud->ud_rcount = 0;
- ud->ud_dcount = 0;
- ud->ud_fcount = 0;
- ud->ud_wcount = 0;
- ud->ud_wfcount = 0;
- ud->ud_wdcount = 0;
- ud->ud_zcopy = 0;
-}
-
-static int
-usbpf_setif(struct usbpf_d *ud, struct usbpf_ifreq *ufr)
-{
- struct usbpf_if *uif;
- struct usb_bus *theywant;
-
- theywant = usb_bus_find(ufr->ufr_name);
- if (theywant == NULL || theywant->uif == NULL)
- return (ENXIO);
-
- uif = theywant->uif;
-
- switch (ud->ud_bufmode) {
- case USBPF_BUFMODE_BUFFER:
- if (ud->ud_sbuf == NULL)
- usbpf_buffer_alloc(ud);
- KASSERT(ud->ud_sbuf != NULL, ("%s: ud_sbuf == NULL", __func__));
- break;
-
- default:
- panic("usbpf_setif: bufmode %d", ud->ud_bufmode);
- }
- if (uif != ud->ud_bif) {
- if (ud->ud_bif)
- /*
- * Detach if attached to something else.
- */
- usbpf_detachd(ud);
-
- usbpf_attachd(ud, uif);
- }
- USBPFD_LOCK(ud);
- usbpf_reset_d(ud);
- USBPFD_UNLOCK(ud);
- return (0);
-}
-
-/*
- * Set d's packet filter program to fp. If this file already has a filter,
- * free it and replace it. Returns EINVAL for bogus requests.
- */
-static int
-usbpf_setf(struct usbpf_d *ud, struct usbpf_program *fp, u_long cmd)
-{
- struct usbpf_insn *fcode, *old;
- u_int wfilter, flen, size;
-
- if (cmd == UIOCSETWF) {
- old = ud->ud_wfilter;
- wfilter = 1;
- } else {
- wfilter = 0;
- old = ud->ud_rfilter;
- }
- if (fp->uf_insns == NULL) {
- if (fp->uf_len != 0)
- return (EINVAL);
- USBPFD_LOCK(ud);
- if (wfilter)
- ud->ud_wfilter = NULL;
- else {
- ud->ud_rfilter = NULL;
- if (cmd == UIOCSETF)
- usbpf_reset_d(ud);
- }
- USBPFD_UNLOCK(ud);
- if (old != NULL)
- free((caddr_t)old, M_USBPF);
- return (0);
- }
- flen = fp->uf_len;
- if (flen > usbpf_maxinsns)
- return (EINVAL);
-
- size = flen * sizeof(*fp->uf_insns);
- fcode = (struct usbpf_insn *)malloc(size, M_USBPF, M_WAITOK);
- if (copyin((caddr_t)fp->uf_insns, (caddr_t)fcode, size) == 0 &&
- usbpf_validate(fcode, (int)flen)) {
- USBPFD_LOCK(ud);
- if (wfilter)
- ud->ud_wfilter = fcode;
- else {
- ud->ud_rfilter = fcode;
- if (cmd == UIOCSETF)
- usbpf_reset_d(ud);
- }
- USBPFD_UNLOCK(ud);
- if (old != NULL)
- free((caddr_t)old, M_USBPF);
-
- return (0);
- }
- free((caddr_t)fcode, M_USBPF);
- return (EINVAL);
-}
-
-static int
-usbpf_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
- struct thread *td)
-{
- struct usbpf_d *ud;
- int error;
-
- error = devfs_get_cdevpriv((void **)&ud);
- if (error != 0)
- return (error);
-
- /*
- * Refresh PID associated with this descriptor.
- */
- USBPFD_LOCK(ud);
- ud->ud_pid = td->td_proc->p_pid;
- if (ud->ud_state == USBPF_WAITING)
- callout_stop(&ud->ud_callout);
- ud->ud_state = USBPF_IDLE;
- USBPFD_UNLOCK(ud);
-
- if (ud->ud_locked == 1) {
- switch (cmd) {
- case UIOCGBLEN:
- case UIOCSBLEN:
- case UIOCVERSION:
- break;
- default:
- return (EPERM);
- }
- }
-
- switch (cmd) {
-
- default:
- error = EINVAL;
- break;
-
- /*
- * Get buffer len [for read()].
- */
- case UIOCGBLEN:
- *(u_int *)addr = ud->ud_bufsize;
- break;
-
- /*
- * Set buffer length.
- */
- case UIOCSBLEN:
- error = usbpf_ioctl_sblen(ud, (u_int *)addr);
- break;
-
- /*
- * Set read filter.
- */
- case UIOCSETF:
- error = usbpf_setf(ud, (struct usbpf_program *)addr, cmd);
- break;
-
- /*
- * Set read timeout.
- */
- case UIOCSRTIMEOUT:
- {
- struct timeval *tv = (struct timeval *)addr;
-
- /*
- * Subtract 1 tick from tvtohz() since this isn't
- * a one-shot timer.
- */
- if ((error = itimerfix(tv)) == 0)
- ud->ud_rtout = tvtohz(tv) - 1;
- break;
- }
-
- /*
- * Get read timeout.
- */
- case UIOCGRTIMEOUT:
- {
- struct timeval *tv = (struct timeval *)addr;
-
- tv->tv_sec = ud->ud_rtout / hz;
- tv->tv_usec = (ud->ud_rtout % hz) * tick;
- break;
- }
-
- /*
- * Get packet stats.
- */
- case UIOCGSTATS:
- {
- struct usbpf_stat *us = (struct usbpf_stat *)addr;
-
- /* XXXCSJP overflow */
- us->us_recv = ud->ud_rcount;
- us->us_drop = ud->ud_dcount;
- break;
- }
-
- case UIOCVERSION:
- {
- struct usbpf_version *uv = (struct usbpf_version *)addr;
-
- uv->uv_major = USBPF_MAJOR_VERSION;
- uv->uv_minor = USBPF_MINOR_VERSION;
- break;
- }
-
- /*
- * Set interface.
- */
- case UIOCSETIF:
- error = usbpf_setif(ud, (struct usbpf_ifreq *)addr);
- break;
-
- }
- return (error);
-}
-
-/*
- * Support for select() and poll() system calls
- *
- * Return true iff the specific operation will not block indefinitely.
- * Otherwise, return false but make a note that a selwakeup() must be done.
- */
-static int
-usbpf_poll(struct cdev *dev, int events, struct thread *td)
-{
-
- /* NOT IMPLEMENTED */
- return (ENOSYS);
-}
-
-/*
- * Support for kevent() system call. Register EVFILT_READ filters and
- * reject all others.
- */
-int
-usbpf_kqfilter(struct cdev *dev, struct knote *kn)
-{
-
- /* NOT IMPLEMENTED */
- return (ENOSYS);
-}
-
-/*
- * Attach file to the usbpf interface, i.e. make d listen on bp.
- */
-static void
-usbpf_attachd(struct usbpf_d *ud, struct usbpf_if *uif)
+void
+usbpf_attach(struct usb_bus *ubus)
{
+ struct ifnet *ifp;
- USBPFIF_LOCK(uif);
- ud->ud_bif = uif;
- LIST_INSERT_HEAD(&uif->uif_dlist, ud, ud_next);
+ ifp = ubus->ifp = if_alloc(IFT_USB);
+ if_initname(ifp, "usbus", device_get_unit(ubus->bdev));
+ if_attach(ifp);
- usbpf_uifd_cnt++;
- USBPFIF_UNLOCK(uif);
-}
-
-/*
- * Detach a file from its interface.
- */
-static void
-usbpf_detachd(struct usbpf_d *ud)
-{
- struct usbpf_if *uif;
- struct usb_bus *ubus;
-
- uif = ud->ud_bif;
- USBPFIF_LOCK(uif);
- USBPFD_LOCK(ud);
- ubus = ud->ud_bif->uif_ubus;
+ KASSERT(sizeof(struct usbpf_pkthdr) == USBPF_HDR_LEN,
+ ("wrong USB pf header length (%zd)", sizeof(struct usbpf_pkthdr)));
/*
- * Remove d from the interface's descriptor list.
+ * XXX According to the specification of DLT_USB, it indicates packets
+ * beginning with USB setup header. But not sure all packets would be.
*/
- LIST_REMOVE(ud, ud_next);
-
- usbpf_uifd_cnt--;
- ud->ud_bif = NULL;
- USBPFD_UNLOCK(ud);
- USBPFIF_UNLOCK(uif);
-}
-
-void
-usbpf_attach(struct usb_bus *ubus, struct usbpf_if **driverp)
-{
- struct usbpf_if *uif;
-
- uif = malloc(sizeof(*uif), M_USBPF, M_WAITOK | M_ZERO);
- LIST_INIT(&uif->uif_dlist);
- uif->uif_ubus = ubus;
- mtx_init(&uif->uif_mtx, "usbpf interface lock", NULL, MTX_DEF);
- KASSERT(*driverp == NULL,
- ("usbpf_attach: driverp already initialized"));
- *driverp = uif;
-
- mtx_lock(&usbpf_mtx);
- LIST_INSERT_HEAD(&usbpf_iflist, uif, uif_next);
- mtx_unlock(&usbpf_mtx);
+ bpfattach(ifp, DLT_USB, USBPF_HDR_LEN);
if (bootverbose)
device_printf(ubus->parent, "usbpf attached\n");
}
-/*
- * If there are processes sleeping on this descriptor, wake them up.
- */
-static __inline void
-usbpf_wakeup(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
- if (ud->ud_state == USBPF_WAITING) {
- callout_stop(&ud->ud_callout);
- ud->ud_state = USBPF_IDLE;
- }
- wakeup(ud);
- if (ud->ud_async && ud->ud_sig && ud->ud_sigio)
- pgsigio(&ud->ud_sigio, ud->ud_sig, 0);
-
- selwakeuppri(&ud->ud_sel, PRIUSB);
- KNOTE_LOCKED(&ud->ud_sel.si_note, 0);
-}
-
void
usbpf_detach(struct usb_bus *ubus)
{
- struct usbpf_if *uif;
- struct usbpf_d *ud;
-
- /* Locate USBPF interface information */
- mtx_lock(&usbpf_mtx);
- LIST_FOREACH(uif, &usbpf_iflist, uif_next) {
- if (ubus == uif->uif_ubus)
- break;
- }
-
- /* Interface wasn't attached */
- if ((uif == NULL) || (uif->uif_ubus == NULL)) {
- mtx_unlock(&usbpf_mtx);
- printf("usbpf_detach: not attached\n"); /* XXX */
- return;
- }
-
- LIST_REMOVE(uif, uif_next);
- mtx_unlock(&usbpf_mtx);
-
- while ((ud = LIST_FIRST(&uif->uif_dlist)) != NULL) {
- usbpf_detachd(ud);
- USBPFD_LOCK(ud);
- usbpf_wakeup(ud);
- USBPFD_UNLOCK(ud);
- }
-
- mtx_destroy(&uif->uif_mtx);
- free(uif, M_USBPF);
-}
-
-/* Time stamping functions */
-#define USBPF_T_MICROTIME 0x0000
-#define USBPF_T_NANOTIME 0x0001
-#define USBPF_T_BINTIME 0x0002
-#define USBPF_T_NONE 0x0003
-#define USBPF_T_FORMAT_MASK 0x0003
-#define USBPF_T_NORMAL 0x0000
-#define USBPF_T_FAST 0x0100
-#define USBPF_T_MONOTONIC 0x0200
-#define USBPF_T_FORMAT(t) ((t) & USBPF_T_FORMAT_MASK)
-
-#define USBPF_TSTAMP_NONE 0
-#define USBPF_TSTAMP_FAST 1
-#define USBPF_TSTAMP_NORMAL 2
-
-static int
-usbpf_ts_quality(int tstype)
-{
-
- if (tstype == USBPF_T_NONE)
- return (USBPF_TSTAMP_NONE);
- if ((tstype & USBPF_T_FAST) != 0)
- return (USBPF_TSTAMP_FAST);
-
- return (USBPF_TSTAMP_NORMAL);
-}
-
-static int
-usbpf_gettime(struct bintime *bt, int tstype)
-{
- int quality;
-
- quality = usbpf_ts_quality(tstype);
- if (quality == USBPF_TSTAMP_NONE)
- return (quality);
- if (quality == USBPF_TSTAMP_NORMAL)
- binuptime(bt);
- else
- getbinuptime(bt);
-
- return (quality);
-}
-
-/*
- * If the buffer mechanism has a way to decide that a held buffer can be made
- * free, then it is exposed via the usbpf_canfreebuf() interface. (1) is
- * returned if the buffer can be discarded, (0) is returned if it cannot.
- */
-static int
-usbpf_canfreebuf(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
-
- return (0);
-}
-
-/*
- * Allow the buffer model to indicate that the current store buffer is
- * immutable, regardless of the appearance of space. Return (1) if the
- * buffer is writable, and (0) if not.
- */
-static int
-usbpf_canwritebuf(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
- return (1);
-}
+ struct ifnet *ifp = ubus->ifp;
-/*
- * Notify buffer model that an attempt to write to the store buffer has
- * resulted in a dropped packet, in which case the buffer may be considered
- * full.
- */
-static void
-usbpf_buffull(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
-}
-
-/*
- * This function gets called when the free buffer is re-assigned.
- */
-static void
-usbpf_buf_reclaimed(struct usbpf_d *ud)
-{
-
- USBPFD_LOCK_ASSERT(ud);
-
- switch (ud->ud_bufmode) {
- case USBPF_BUFMODE_BUFFER:
- return;
-
- default:
- panic("usbpf_buf_reclaimed");
+ if (ifp != NULL) {
+ bpfdetach(ifp);
+ if_detach(ifp);
+ if_free(ifp);
}
-}
-
-#define SIZEOF_USBPF_HDR(type) \
- (offsetof(type, uh_hdrlen) + sizeof(((type *)0)->uh_hdrlen))
-
-static int
-usbpf_hdrlen(struct usbpf_d *ud)
-{
- int hdrlen;
-
- hdrlen = ud->ud_bif->uif_hdrlen;
- hdrlen += SIZEOF_USBPF_HDR(struct usbpf_xhdr);
- hdrlen = USBPF_WORDALIGN(hdrlen);
-
- return (hdrlen - ud->ud_bif->uif_hdrlen);
-}
-
-static void
-usbpf_bintime2ts(struct bintime *bt, struct usbpf_ts *ts, int tstype)
-{
- struct bintime bt2;
- struct timeval tsm;
- struct timespec tsn;
-
- if ((tstype & USBPF_T_MONOTONIC) == 0) {
- bt2 = *bt;
- bintime_add(&bt2, &boottimebin);
- bt = &bt2;
- }
- switch (USBPF_T_FORMAT(tstype)) {
- case USBPF_T_MICROTIME:
- bintime2timeval(bt, &tsm);
- ts->ut_sec = tsm.tv_sec;
- ts->ut_frac = tsm.tv_usec;
- break;
- case USBPF_T_NANOTIME:
- bintime2timespec(bt, &tsn);
- ts->ut_sec = tsn.tv_sec;
- ts->ut_frac = tsn.tv_nsec;
- break;
- case USBPF_T_BINTIME:
- ts->ut_sec = bt->sec;
- ts->ut_frac = bt->frac;
- break;
- }
-}
-
-/*
- * Move the packet data from interface memory (pkt) into the
- * store buffer. "cpfn" is the routine called to do the actual data
- * transfer. bcopy is passed in to copy contiguous chunks, while
- * usbpf_append_mbuf is passed in to copy mbuf chains. In the latter case,
- * pkt is really an mbuf.
- */
-static void
-catchpacket(struct usbpf_d *ud, u_char *pkt, u_int pktlen, u_int snaplen,
- void (*cpfn)(struct usbpf_d *, caddr_t, u_int, void *, u_int),
- struct bintime *bt)
-{
- struct usbpf_xhdr hdr;
- int caplen, curlen, hdrlen, totlen;
- int do_wakeup = 0;
- int do_timestamp;
- int tstype;
-
- USBPFD_LOCK_ASSERT(ud);
-
- /*
- * Detect whether user space has released a buffer back to us, and if
- * so, move it from being a hold buffer to a free buffer. This may
- * not be the best place to do it (for example, we might only want to
- * run this check if we need the space), but for now it's a reliable
- * spot to do it.
- */
- if (ud->ud_fbuf == NULL && usbpf_canfreebuf(ud)) {
- ud->ud_fbuf = ud->ud_hbuf;
- ud->ud_hbuf = NULL;
- ud->ud_hlen = 0;
- usbpf_buf_reclaimed(ud);
- }
-
- /*
- * Figure out how many bytes to move. If the packet is
- * greater or equal to the snapshot length, transfer that
- * much. Otherwise, transfer the whole packet (unless
- * we hit the buffer size limit).
- */
- hdrlen = usbpf_hdrlen(ud);
- totlen = hdrlen + min(snaplen, pktlen);
- if (totlen > ud->ud_bufsize)
- totlen = ud->ud_bufsize;
-
- /*
- * Round up the end of the previous packet to the next longword.
- *
- * Drop the packet if there's no room and no hope of room
- * If the packet would overflow the storage buffer or the storage
- * buffer is considered immutable by the buffer model, try to rotate
- * the buffer and wakeup pending processes.
- */
- curlen = USBPF_WORDALIGN(ud->ud_slen);
- if (curlen + totlen > ud->ud_bufsize || !usbpf_canwritebuf(ud)) {
- if (ud->ud_fbuf == NULL) {
- /*
- * There's no room in the store buffer, and no
- * prospect of room, so drop the packet. Notify the
- * buffer model.
- */
- usbpf_buffull(ud);
- ++ud->ud_dcount;
- return;
- }
- USBPF_ROTATE_BUFFERS(ud);
- do_wakeup = 1;
- curlen = 0;
- } else if (ud->ud_immediate || ud->ud_state == USBPF_TIMED_OUT)
- /*
- * Immediate mode is set, or the read timeout has already
- * expired during a select call. A packet arrived, so the
- * reader should be woken up.
- */
- do_wakeup = 1;
- caplen = totlen - hdrlen;
- tstype = ud->ud_tstamp;
- do_timestamp = tstype != USBPF_T_NONE;
-
- /*
- * Append the usbpf header. Note we append the actual header size, but
- * move forward the length of the header plus padding.
- */
- bzero(&hdr, sizeof(hdr));
- if (do_timestamp)
- usbpf_bintime2ts(bt, &hdr.uh_tstamp, tstype);
- hdr.uh_datalen = pktlen;
- hdr.uh_hdrlen = hdrlen;
- hdr.uh_caplen = caplen;
- usbpf_append_bytes(ud, ud->ud_sbuf, curlen, &hdr, sizeof(hdr));
-
- /*
- * Copy the packet data into the store buffer and update its length.
- */
- (*cpfn)(ud, ud->ud_sbuf, curlen + hdrlen, pkt, caplen);
- ud->ud_slen = curlen + totlen;
-
- if (do_wakeup)
- usbpf_wakeup(ud);
-}
-
-/*
- * Incoming linkage from device drivers. Process the packet pkt, of length
- * pktlen, which is stored in a contiguous buffer. The packet is parsed
- * by each process' filter, and if accepted, stashed into the corresponding
- * buffer.
- */
-static void
-usbpf_tap(struct usbpf_if *uif, u_char *pkt, u_int pktlen)
-{
- struct bintime bt;
- struct usbpf_d *ud;
- u_int slen;
- int gottime;
-
- gottime = USBPF_TSTAMP_NONE;
- USBPFIF_LOCK(uif);
- LIST_FOREACH(ud, &uif->uif_dlist, ud_next) {
- USBPFD_LOCK(ud);
- ++ud->ud_rcount;
- slen = usbpf_filter(ud->ud_rfilter, pkt, pktlen, pktlen);
- if (slen != 0) {
- ud->ud_fcount++;
- if (gottime < usbpf_ts_quality(ud->ud_tstamp))
- gottime = usbpf_gettime(&bt, ud->ud_tstamp);
- catchpacket(ud, pkt, pktlen, slen,
- usbpf_append_bytes, &bt);
- }
- USBPFD_UNLOCK(ud);
- }
- USBPFIF_UNLOCK(uif);
+ ubus->ifp = NULL;
}
static uint32_t
@@ -1763,11 +181,7 @@ usbpf_xfertap(struct usb_xfer *xfer, int type)
int i;
char *buf, *ptr, *end;
- /*
- * NB: usbpf_uifd_cnt isn't protected by USBPFIF_LOCK() because it's
- * not harmful.
- */
- if (usbpf_uifd_cnt == 0)
+ if (!bpf_peers_present(bus->ifp->if_bpf))
return;
/*
@@ -1777,7 +191,7 @@ usbpf_xfertap(struct usb_xfer *xfer, int type)
* read filter to pass a virtually linear buffer.
*/
buf = ptr = malloc(sizeof(struct usbpf_pkthdr) + (USB_PAGE_SIZE * 5),
- M_USBPF, M_NOWAIT);
+ M_TEMP, M_NOWAIT);
if (buf == NULL) {
printf("usbpf_xfertap: out of memory\n"); /* XXX */
return;
@@ -1827,36 +241,7 @@ usbpf_xfertap(struct usb_xfer *xfer, int type)
ptr += xfer->frlengths[i];
}
- usbpf_tap(bus->uif, buf, ptr - buf);
+ bpf_tap(bus->ifp->if_bpf, buf, ptr - buf);
done:
- free(buf, M_USBPF);
+ free(buf, M_TEMP);
}
-
-static void
-usbpf_append_bytes(struct usbpf_d *ud, caddr_t buf, u_int offset, void *src,
- u_int len)
-{
-
- USBPFD_LOCK_ASSERT(ud);
-
- switch (ud->ud_bufmode) {
- case USBPF_BUFMODE_BUFFER:
- return (usbpf_buffer_append_bytes(ud, buf, offset, src, len));
- default:
- panic("usbpf_buf_append_bytes");
- }
-}
-
-static void
-usbpf_drvinit(void *unused)
-{
- struct cdev *dev;
-
- mtx_init(&usbpf_mtx, "USB packet filter global lock", NULL,
- MTX_DEF);
- LIST_INIT(&usbpf_iflist);
-
- dev = make_dev(&usbpf_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "usbpf");
-}
-
-SYSINIT(usbpf_dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, usbpf_drvinit, NULL);
diff --git a/sys/dev/usb/usb_pf.h b/sys/dev/usb/usb_pf.h
index f5ed9a0..58b9ce9 100644
--- a/sys/dev/usb/usb_pf.h
+++ b/sys/dev/usb/usb_pf.h
@@ -37,190 +37,6 @@
#ifndef _DEV_USB_PF_H
#define _DEV_USB_PF_H
-#ifdef _KERNEL
-#include <sys/callout.h>
-#include <sys/selinfo.h>
-#include <sys/queue.h>
-#include <sys/conf.h>
-#endif
-
-typedef int32_t usbpf_int32;
-typedef u_int32_t usbpf_u_int32;
-typedef int64_t usbpf_int64;
-typedef u_int64_t usbpf_u_int64;
-
-struct usbpf_if;
-
-/*
- * Alignment macros. USBPF_WORDALIGN rounds up to the next
- * even multiple of USBPF_ALIGNMENT.
- */
-#define USBPF_ALIGNMENT sizeof(long)
-#define USBPF_WORDALIGN(x) (((x)+(USBPF_ALIGNMENT-1))&~(USBPF_ALIGNMENT-1))
-
-/*
- * The instruction encodings.
- */
-
-/* instruction classes */
-#define USBPF_CLASS(code) ((code) & 0x07)
-#define USBPF_LD 0x00
-#define USBPF_LDX 0x01
-#define USBPF_ST 0x02
-#define USBPF_STX 0x03
-#define USBPF_ALU 0x04
-#define USBPF_JMP 0x05
-#define USBPF_RET 0x06
-#define USBPF_MISC 0x07
-
-/* ld/ldx fields */
-#define USBPF_SIZE(code) ((code) & 0x18)
-#define USBPF_W 0x00
-#define USBPF_H 0x08
-#define USBPF_B 0x10
-#define USBPF_MODE(code) ((code) & 0xe0)
-#define USBPF_IMM 0x00
-#define USBPF_ABS 0x20
-#define USBPF_IND 0x40
-#define USBPF_MEM 0x60
-#define USBPF_LEN 0x80
-#define USBPF_MSH 0xa0
-
-/* alu/jmp fields */
-#define USBPF_OP(code) ((code) & 0xf0)
-#define USBPF_ADD 0x00
-#define USBPF_SUB 0x10
-#define USBPF_MUL 0x20
-#define USBPF_DIV 0x30
-#define USBPF_OR 0x40
-#define USBPF_AND 0x50
-#define USBPF_LSH 0x60
-#define USBPF_RSH 0x70
-#define USBPF_NEG 0x80
-#define USBPF_JA 0x00
-#define USBPF_JEQ 0x10
-#define USBPF_JGT 0x20
-#define USBPF_JGE 0x30
-#define USBPF_JSET 0x40
-#define USBPF_SRC(code) ((code) & 0x08)
-#define USBPF_K 0x00
-#define USBPF_X 0x08
-
-/* ret - USBPF_K and USBPF_X also apply */
-#define USBPF_RVAL(code) ((code) & 0x18)
-#define USBPF_A 0x10
-
-/* misc */
-#define USBPF_MISCOP(code) ((code) & 0xf8)
-#define USBPF_TAX 0x00
-#define USBPF_TXA 0x80
-
-/*
- * The instruction data structure.
- */
-struct usbpf_insn {
- u_short code;
- u_char jt;
- u_char jf;
- usbpf_u_int32 k;
-};
-
-#ifdef _KERNEL
-
-/*
- * Descriptor associated with each open uff file.
- */
-
-struct usbpf_d {
- LIST_ENTRY(usbpf_d) ud_next; /* Linked list of descriptors */
- /*
- * Buffer slots: two memory buffers store the incoming packets.
- * The model has three slots. Sbuf is always occupied.
- * sbuf (store) - Receive interrupt puts packets here.
- * hbuf (hold) - When sbuf is full, put buffer here and
- * wakeup read (replace sbuf with fbuf).
- * fbuf (free) - When read is done, put buffer here.
- * On receiving, if sbuf is full and fbuf is 0, packet is dropped.
- */
- caddr_t ud_sbuf; /* store slot */
- caddr_t ud_hbuf; /* hold slot */
- caddr_t ud_fbuf; /* free slot */
- int ud_slen; /* current length of store buffer */
- int ud_hlen; /* current length of hold buffer */
-
- int ud_bufsize; /* absolute length of buffers */
-
- struct usbpf_if *ud_bif; /* interface descriptor */
- u_long ud_rtout; /* Read timeout in 'ticks' */
- struct usbpf_insn *ud_rfilter; /* read filter code */
- struct usbpf_insn *ud_wfilter; /* write filter code */
- void *ud_bfilter; /* binary filter code */
- u_int64_t ud_rcount; /* number of packets received */
- u_int64_t ud_dcount; /* number of packets dropped */
-
- u_char ud_promisc; /* true if listening promiscuously */
- u_char ud_state; /* idle, waiting, or timed out */
- u_char ud_immediate; /* true to return on packet arrival */
- int ud_hdrcmplt; /* false to fill in src lladdr automatically */
- int ud_direction; /* select packet direction */
- int ud_tstamp; /* select time stamping function */
- int ud_feedback; /* true to feed back sent packets */
- int ud_async; /* non-zero if packet reception should generate signal */
- int ud_sig; /* signal to send upon packet reception */
- struct sigio * ud_sigio; /* information for async I/O */
- struct selinfo ud_sel; /* bsd select info */
- struct mtx ud_mtx; /* mutex for this descriptor */
- struct callout ud_callout; /* for USBPF timeouts with select */
- struct label *ud_label; /* MAC label for descriptor */
- u_int64_t ud_fcount; /* number of packets which matched filter */
- pid_t ud_pid; /* PID which created descriptor */
- int ud_locked; /* true if descriptor is locked */
- u_int ud_bufmode; /* Current buffer mode. */
- u_int64_t ud_wcount; /* number of packets written */
- u_int64_t ud_wfcount; /* number of packets that matched write filter */
- u_int64_t ud_wdcount; /* number of packets dropped during a write */
- u_int64_t ud_zcopy; /* number of zero copy operations */
- u_char ud_compat32; /* 32-bit stream on LP64 system */
-};
-
-#define USBPFD_LOCK(ud) mtx_lock(&(ud)->ud_mtx)
-#define USBPFD_UNLOCK(ud) mtx_unlock(&(ud)->ud_mtx)
-#define USBPFD_LOCK_ASSERT(ud) mtx_assert(&(ud)->ud_mtx, MA_OWNED)
-
-/*
- * Descriptor associated with each attached hardware interface.
- */
-struct usbpf_if {
- LIST_ENTRY(usbpf_if) uif_next; /* list of all interfaces */
- LIST_HEAD(, usbpf_d) uif_dlist; /* descriptor list */
- u_int uif_hdrlen; /* length of link header */
- struct usb_bus *uif_ubus; /* corresponding interface */
- struct mtx uif_mtx; /* mutex for interface */
-};
-
-#define USBPFIF_LOCK(uif) mtx_lock(&(uif)->uif_mtx)
-#define USBPFIF_UNLOCK(uif) mtx_unlock(&(uif)->uif_mtx)
-
-#endif
-
-/*
- * Structure prepended to each packet.
- */
-struct usbpf_ts {
- usbpf_int64 ut_sec; /* seconds */
- usbpf_u_int64 ut_frac; /* fraction */
-};
-struct usbpf_xhdr {
- struct usbpf_ts uh_tstamp; /* time stamp */
- usbpf_u_int32 uh_caplen; /* length of captured portion */
- usbpf_u_int32 uh_datalen; /* original length of packet */
- u_short uh_hdrlen; /* length of uff header (this struct
- plus alignment padding) */
-};
-
-#define USBPF_BUFMODE_BUFFER 1 /* Kernel buffers with read(). */
-#define USBPF_BUFMODE_ZBUF 2 /* Zero-copy buffers. */
-
struct usbpf_pkthdr {
int up_busunit; /* Host controller unit number */
u_char up_address; /* USB device address */
@@ -268,50 +84,13 @@ struct usbpf_pkthdr {
u_char up_reserved[96];
};
-struct usbpf_version {
- u_short uv_major;
- u_short uv_minor;
-};
-#define USBPF_MAJOR_VERSION 1
-#define USBPF_MINOR_VERSION 1
-
-#define USBPF_IFNAMSIZ 32
-struct usbpf_ifreq {
- /* bus name, e.g. "usbus0" */
- char ufr_name[USBPF_IFNAMSIZ];
-};
-
-/*
- * Structure for UIOCSETF.
- */
-struct usbpf_program {
- u_int uf_len;
- struct usbpf_insn *uf_insns;
-};
-
-/*
- * Struct returned by UIOCGSTATS.
- */
-struct usbpf_stat {
- u_int us_recv; /* number of packets received */
- u_int us_drop; /* number of packets dropped */
-};
-
-#define UIOCGBLEN _IOR('U', 102, u_int)
-#define UIOCSBLEN _IOWR('U', 102, u_int)
-#define UIOCSETF _IOW('U', 103, struct usbpf_program)
-#define UIOCSETIF _IOW('U', 108, struct usbpf_ifreq)
-#define UIOCSRTIMEOUT _IOW('U', 109, struct timeval)
-#define UIOCGRTIMEOUT _IOR('U', 110, struct timeval)
-#define UIOCGSTATS _IOR('U', 111, struct usbpf_stat)
-#define UIOCVERSION _IOR('U', 113, struct usbpf_version)
-#define UIOCSETWF _IOW('U', 123, struct usbpf_program)
+#define USBPF_HDR_LEN 128
#define USBPF_XFERTAP_SUBMIT 0
#define USBPF_XFERTAP_DONE 1
#ifdef _KERNEL
-void usbpf_attach(struct usb_bus *, struct usbpf_if **);
+void usbpf_attach(struct usb_bus *);
void usbpf_detach(struct usb_bus *);
void usbpf_xfertap(struct usb_xfer *, int);
#endif
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 91fe9f4..a34ec3c 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -1789,8 +1789,8 @@ product HTC LEGENDINTERNET 0x0ffe HTC Legend Internet Sharing
/* HUAWEI products */
product HUAWEI MOBILE 0x1001 Huawei Mobile
-product HUAWEI E220 0x1003 Huawei HSDPA modem
-product HUAWEI E220BIS 0x1004 Huawei HSDPA modem
+product HUAWEI E220 0x1003 HSDPA modem
+product HUAWEI E220BIS 0x1004 HSDPA modem
product HUAWEI E1401 0x1401 3G modem
product HUAWEI E1402 0x1402 3G modem
product HUAWEI E1403 0x1403 3G modem
@@ -1802,7 +1802,7 @@ product HUAWEI E1408 0x1408 3G modem
product HUAWEI E1409 0x1409 3G modem
product HUAWEI E140A 0x140a 3G modem
product HUAWEI E140B 0x140b 3G modem
-product HUAWEI E180V 0x140c Huawei Mobile E180V
+product HUAWEI E180V 0x140c E180V
product HUAWEI E140D 0x140d 3G modem
product HUAWEI E140E 0x140e 3G modem
product HUAWEI E140F 0x140f 3G modem
@@ -1856,8 +1856,8 @@ product HUAWEI E143E 0x143e 3G modem
product HUAWEI E143F 0x143f 3G modem
product HUAWEI E1752 0x1446 3G modem
product HUAWEI K3765 0x1465 3G modem
-product HUAWEI E14AC 0x14ac 3G modem
-product HUAWEI K3765_INIT 0x1520 HUAWEI Mobile K3765 Initial
+product HUAWEI E1820 0x14ac E1820 HSPA+ USB Slider
+product HUAWEI K3765_INIT 0x1520 K3765 Initial
/* HUAWEI 3com products */
product HUAWEI3COM WUB320G 0x0009 Aolynk WUB320g
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index b15e9b7..7efa29c 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -220,8 +220,7 @@ static uma_zone_t pdptzone;
SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
static int pat_works = 1;
-TUNABLE_INT("vm.pmap.pat_works", &pat_works);
-SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RDTUN, &pat_works, 1,
+SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RD, &pat_works, 1,
"Is page attribute table fully functional?");
static int pg_ps_enabled = 1;
diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
index dd0d4ee..73e7a84 100644
--- a/sys/i386/include/specialreg.h
+++ b/sys/i386/include/specialreg.h
@@ -133,6 +133,15 @@
#define CPUID2_AESNI 0x02000000
/*
+ * Important bits in the Thermal and Power Management flags
+ * CPUID.6 EAX and ECX.
+ */
+#define CPUTPM1_SENSOR 0x00000001
+#define CPUTPM1_TURBO 0x00000002
+#define CPUTPM1_ARAT 0x00000004
+#define CPUTPM2_EFFREQ 0x00000001
+
+/*
* Important bits in the AMD extended cpuid flags
*/
#define AMDID_SYSCALL 0x00000800
diff --git a/sys/i386/include/xen/hypercall.h b/sys/i386/include/xen/hypercall.h
index b33626f..2631a9b 100644
--- a/sys/i386/include/xen/hypercall.h
+++ b/sys/i386/include/xen/hypercall.h
@@ -234,8 +234,9 @@ HYPERVISOR_memory_op(
return _hypercall2(int, memory_op, cmd, arg);
}
+int HYPERVISOR_multicall(multicall_entry_t *, int);
static inline int
-HYPERVISOR_multicall(
+_HYPERVISOR_multicall(
void *call_list, int nr_calls)
{
return _hypercall2(int, multicall, call_list, nr_calls);
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index f8dc11c..8d37562 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -938,7 +938,7 @@ fpu_clean_state(void)
* the x87 stack, but we don't care since we're about to call
* fxrstor() anyway.
*/
- __asm __volatile("ffree %%st(7); fld %0" : : "m" (dummy_variable));
+ __asm __volatile("ffree %%st(7); flds %0" : : "m" (dummy_variable));
}
#endif /* CPU_ENABLE_SSE */
diff --git a/sys/i386/pci/pci_bus.c b/sys/i386/pci/pci_bus.c
index ae4d520..b7fa7d1 100644
--- a/sys/i386/pci/pci_bus.c
+++ b/sys/i386/pci/pci_bus.c
@@ -204,6 +204,9 @@ legacy_pcib_is_host_bridge(int bus, int slot, int func,
break;
}
break;
+ case 0x1A308086:
+ s = "Intel 82845 Host to PCI bridge";
+ break;
/* AMD -- vendor 0x1022 */
case 0x30001022:
@@ -304,6 +307,8 @@ legacy_pcib_is_host_bridge(int bus, int slot, int func,
case 0x00171166:
/* FALLTHROUGH */
case 0x01011166:
+ case 0x01101166:
+ case 0x02251166:
s = "ServerWorks host to PCI bridge(unknown chipset)";
*busnum = legacy_pcib_read_config(0, bus, slot, func, 0x44, 1);
break;
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index c44bf18..7671dd9 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -1292,7 +1292,19 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
mclp->args[0] = va;
mclp->args[1] = (uint32_t)(pa & 0xffffffff);
mclp->args[2] = (uint32_t)(pa >> 32);
+#if 0
mclp->args[3] = (*pte & PG_V) ? UVMF_INVLPG|UVMF_ALL : 0;
+#else
+ /*
+ * Somehow we seem to be ending up with pages which are in
+ * the TLB in spite of not having PG_V set, resulting in
+ * pages newly loaded into the bufcache not showing up
+ * immediately (i.e., accessing them provides the old data).
+ * As a workaround, always perform a TLB flush, even if the
+ * old page didn't have PG_V.
+ */
+ mclp->args[3] = UVMF_INVLPG|UVMF_ALL;
+#endif
va += PAGE_SIZE;
pte++;
diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c
index aaad5d4..a9180fc 100644
--- a/sys/i386/xen/xen_machdep.c
+++ b/sys/i386/xen/xen_machdep.c
@@ -482,7 +482,6 @@ xen_pt_pin(vm_paddr_t ma)
struct mmuext_op op;
op.cmd = MMUEXT_PIN_L1_TABLE;
op.arg1.mfn = ma >> PAGE_SHIFT;
- printk("xen_pt_pin(): mfn=%x\n", op.arg1.mfn);
xen_flush_queue();
PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0);
}
@@ -1178,6 +1177,27 @@ trap_info_t trap_table[] = {
{ 0, 0, 0, 0 }
};
+/* Perform a multicall and check that individual calls succeeded. */
+int
+HYPERVISOR_multicall(struct multicall_entry * call_list, int nr_calls)
+{
+ int ret = 0;
+ int i;
+
+ /* Perform the multicall. */
+ PANIC_IF(_HYPERVISOR_multicall(call_list, nr_calls));
+
+ /* Check the results of individual hypercalls. */
+ for (i = 0; i < nr_calls; i++)
+ if (unlikely(call_list[i].result < 0))
+ ret++;
+ if (unlikely(ret > 0))
+ panic("%d multicall(s) failed: cpu %d\n",
+ ret, smp_processor_id());
+
+ /* If we didn't panic already, everything succeeded. */
+ return (0);
+}
/********** CODE WORTH KEEPING ABOVE HERE *****************/
diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c
index 2487b6b..bfa39f7 100644
--- a/sys/kern/kern_tc.c
+++ b/sys/kern/kern_tc.c
@@ -448,7 +448,7 @@ tc_windup(void)
th->th_offset.sec++;
}
if ((delta > th->th_counter->tc_frequency / 2) &&
- (th->th_scale * delta < (uint64_t)1 << 63)) {
+ (th->th_scale * delta < ((uint64_t)1 << 63))) {
/* The product th_scale * delta just barely overflows. */
th->th_offset.sec++;
}
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index 49ddce2..20b6a0b 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -53,7 +53,6 @@ struct taskqueue_busy {
struct taskqueue {
STAILQ_HEAD(, task) tq_queue;
- const char *tq_name;
taskqueue_enqueue_fn tq_enqueue;
void *tq_context;
TAILQ_HEAD(, taskqueue_busy) tq_active;
@@ -94,7 +93,7 @@ TQ_SLEEP(struct taskqueue *tq, void *p, struct mtx *m, int pri, const char *wm,
}
static struct taskqueue *
-_taskqueue_create(const char *name, int mflags,
+_taskqueue_create(const char *name __unused, int mflags,
taskqueue_enqueue_fn enqueue, void *context,
int mtxflags, const char *mtxname)
{
@@ -106,7 +105,6 @@ _taskqueue_create(const char *name, int mflags,
STAILQ_INIT(&queue->tq_queue);
TAILQ_INIT(&queue->tq_active);
- queue->tq_name = name;
queue->tq_enqueue = enqueue;
queue->tq_context = context;
queue->tq_spin = (mtxflags & MTX_SPIN) != 0;
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 83cbc60..4971a25 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -383,7 +383,8 @@ nmount(td, uap)
* Filter out MNT_ROOTFS. We do not want clients of nmount() in
* userspace to set this flag, but we must filter it out if we want
* MNT_UPDATE on the root file system to work.
- * MNT_ROOTFS should only be set in the kernel in vfs_mountroot_try().
+ * MNT_ROOTFS should only be set by the kernel when mounting its
+ * root file system.
*/
uap->flags &= ~MNT_ROOTFS;
@@ -720,7 +721,8 @@ mount(td, uap)
* Filter out MNT_ROOTFS. We do not want clients of mount() in
* userspace to set this flag, but we must filter it out if we want
* MNT_UPDATE on the root file system to work.
- * MNT_ROOTFS should only be set in the kernel in vfs_mountroot_try().
+ * MNT_ROOTFS should only be set by the kernel when mounting its
+ * root file system.
*/
uap->flags &= ~MNT_ROOTFS;
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index b032513..8cff685 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -2186,7 +2186,7 @@ vputx(struct vnode *vp, int func)
KASSERT(vp != NULL, ("vputx: null vp"));
if (func == VPUTX_VUNREF)
- ASSERT_VOP_ELOCKED(vp, "vunref");
+ ASSERT_VOP_LOCKED(vp, "vunref");
else if (func == VPUTX_VPUT)
ASSERT_VOP_LOCKED(vp, "vput");
else
@@ -2224,12 +2224,22 @@ vputx(struct vnode *vp, int func)
* as VI_DOINGINACT to avoid recursion.
*/
vp->v_iflag |= VI_OWEINACT;
- if (func == VPUTX_VRELE) {
+ switch (func) {
+ case VPUTX_VRELE:
error = vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK);
VI_LOCK(vp);
- } else if (func == VPUTX_VPUT && VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
- error = VOP_LOCK(vp, LK_UPGRADE | LK_INTERLOCK | LK_NOWAIT);
- VI_LOCK(vp);
+ break;
+ case VPUTX_VPUT:
+ if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
+ error = VOP_LOCK(vp, LK_UPGRADE | LK_INTERLOCK |
+ LK_NOWAIT);
+ VI_LOCK(vp);
+ }
+ break;
+ case VPUTX_VUNREF:
+ if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE)
+ error = EBUSY;
+ break;
}
if (vp->v_usecount > 0)
vp->v_iflag &= ~VI_OWEINACT;
diff --git a/sys/net/bpf_buffer.c b/sys/net/bpf_buffer.c
index 8924c88..6920c70 100644
--- a/sys/net/bpf_buffer.c
+++ b/sys/net/bpf_buffer.c
@@ -88,10 +88,10 @@ __FBSDID("$FreeBSD$");
static int bpf_bufsize = 4096;
SYSCTL_INT(_net_bpf, OID_AUTO, bufsize, CTLFLAG_RW,
- &bpf_bufsize, 0, "Maximum capture buffer size in bytes");
+ &bpf_bufsize, 0, "Default capture buffer size in bytes");
static int bpf_maxbufsize = BPF_MAXBUFSIZE;
SYSCTL_INT(_net_bpf, OID_AUTO, maxbufsize, CTLFLAG_RW,
- &bpf_maxbufsize, 0, "Default capture buffer in bytes");
+ &bpf_maxbufsize, 0, "Maximum capture buffer in bytes");
void
bpf_buffer_alloc(struct bpf_d *d)
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 63fc026..4e24a5f 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -206,6 +206,11 @@ static void vlan_iflladdr(void *arg, struct ifnet *ifp);
static struct if_clone vlan_cloner = IFC_CLONE_INITIALIZER(VLANNAME, NULL,
IF_MAXUNIT, NULL, vlan_clone_match, vlan_clone_create, vlan_clone_destroy);
+#ifdef VIMAGE
+static VNET_DEFINE(struct if_clone, vlan_cloner);
+#define V_vlan_cloner VNET(vlan_cloner)
+#endif
+
#ifndef VLAN_ARRAY
#define HASH(n, m) ((((n) >> 8) ^ ((n) >> 4) ^ (n)) & (m))
@@ -588,7 +593,9 @@ vlan_modevent(module_t mod, int type, void *data)
vlan_input_p = vlan_input;
vlan_link_state_p = vlan_link_state;
vlan_trunk_cap_p = vlan_trunk_capabilities;
+#ifndef VIMAGE
if_clone_attach(&vlan_cloner);
+#endif
if (bootverbose)
printf("vlan: initialized, using "
#ifdef VLAN_ARRAY
@@ -600,7 +607,9 @@ vlan_modevent(module_t mod, int type, void *data)
"\n");
break;
case MOD_UNLOAD:
+#ifndef VIMAGE
if_clone_detach(&vlan_cloner);
+#endif
EVENTHANDLER_DEREGISTER(ifnet_departure_event, ifdetach_tag);
EVENTHANDLER_DEREGISTER(iflladdr_event, iflladdr_tag);
vlan_input_p = NULL;
@@ -625,6 +634,27 @@ static moduledata_t vlan_mod = {
DECLARE_MODULE(if_vlan, vlan_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
MODULE_VERSION(if_vlan, 3);
+#ifdef VIMAGE
+static void
+vnet_vlan_init(const void *unused __unused)
+{
+
+ V_vlan_cloner = vlan_cloner;
+ if_clone_attach(&V_vlan_cloner);
+}
+VNET_SYSINIT(vnet_vlan_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
+ vnet_vlan_init, NULL);
+
+static void
+vnet_vlan_uninit(const void *unused __unused)
+{
+
+ if_clone_detach(&V_vlan_cloner);
+}
+VNET_SYSUNINIT(vnet_vlan_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_FIRST,
+ vnet_vlan_uninit, NULL);
+#endif
+
static struct ifnet *
vlan_clone_match_ethertag(struct if_clone *ifc, const char *name, int *tag)
{
@@ -1432,6 +1462,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCSETVLAN:
+#ifdef VIMAGE
+ if (ifp->if_vnet != ifp->if_home_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
error = copyin(ifr->ifr_data, &vlr, sizeof(vlr));
if (error)
break;
@@ -1461,6 +1497,12 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
case SIOCGETVLAN:
+#ifdef VIMAGE
+ if (ifp->if_vnet != ifp->if_home_vnet) {
+ error = EPERM;
+ break;
+ }
+#endif
bzero(&vlr, sizeof(vlr));
VLAN_LOCK();
if (TRUNK(ifv) != NULL) {
diff --git a/sys/netgraph/ng_pipe.c b/sys/netgraph/ng_pipe.c
index 77009bf..3efd6d9 100644
--- a/sys/netgraph/ng_pipe.c
+++ b/sys/netgraph/ng_pipe.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2004-2008 University of Zagreb
+ * Copyright (c) 2004-2010 University of Zagreb
* Copyright (c) 2007-2008 FreeBSD Foundation
*
* This software was developed by the University of Zagreb and the
@@ -62,8 +62,6 @@
static MALLOC_DEFINE(M_NG_PIPE, "ng_pipe", "ng_pipe");
-struct mtx ng_pipe_giant;
-
/* Packet header struct */
struct ngp_hdr {
TAILQ_ENTRY(ngp_hdr) ngp_link; /* next pkt in queue */
@@ -88,7 +86,6 @@ struct hookinfo {
int noqueue; /* bypass any processing */
TAILQ_HEAD(, ngp_fifo) fifo_head; /* FIFO queues */
TAILQ_HEAD(, ngp_hdr) qout_head; /* delay queue head */
- LIST_ENTRY(hookinfo) active_le; /* active hooks */
struct timeval qin_utime;
struct ng_pipe_hookcfg cfg;
struct ng_pipe_hookrun run;
@@ -103,6 +100,8 @@ struct node_priv {
u_int32_t header_offset;
struct hookinfo lower;
struct hookinfo upper;
+ struct callout timer;
+ int timer_scheduled;
};
typedef struct node_priv *priv_p;
@@ -131,17 +130,9 @@ typedef struct node_priv *priv_p;
static void parse_cfg(struct ng_pipe_hookcfg *, struct ng_pipe_hookcfg *,
struct hookinfo *, priv_p);
static void pipe_dequeue(struct hookinfo *, struct timeval *);
-static void pipe_scheduler(void *);
-static void pipe_poll(void);
+static void ngp_callout(node_p, hook_p, void *, int);
static int ngp_modevent(module_t, int, void *);
-/* linked list of active "pipe" hooks */
-static LIST_HEAD(, hookinfo) active_head;
-static int active_gen_id = 0;
-
-/* timeout handle for pipe_scheduler */
-static struct callout polling_timer;
-
/* zone for storing ngp_hdr-s */
static uma_zone_t ngp_zone;
@@ -267,6 +258,11 @@ ngp_constructor(node_p node)
return (ENOMEM);
NG_NODE_SET_PRIVATE(node, priv);
+ /* Mark node as single-threaded */
+ NG_NODE_FORCE_WRITER(node);
+
+ ng_callout_init(&priv->timer);
+
return (0);
}
@@ -310,8 +306,6 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
struct ng_pipe_cfg *cfg;
int error = 0;
- mtx_lock(&ng_pipe_giant);
-
NGI_GET_MSG(item, msg);
switch (msg->header.typecookie) {
case NGM_PIPE_COOKIE:
@@ -326,7 +320,7 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
error = ENOMEM;
break;
}
- stats = (struct ng_pipe_stats *)resp->data;
+ stats = (struct ng_pipe_stats *) resp->data;
bcopy(&priv->upper.stats, &stats->downstream,
sizeof(stats->downstream));
bcopy(&priv->lower.stats, &stats->upstream,
@@ -345,7 +339,7 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
error = ENOMEM;
break;
}
- run = (struct ng_pipe_run *)resp->data;
+ run = (struct ng_pipe_run *) resp->data;
bcopy(&priv->upper.run, &run->downstream,
sizeof(run->downstream));
bcopy(&priv->lower.run, &run->upstream,
@@ -357,7 +351,7 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
error = ENOMEM;
break;
}
- cfg = (struct ng_pipe_cfg *)resp->data;
+ cfg = (struct ng_pipe_cfg *) resp->data;
bcopy(&priv->upper.cfg, &cfg->downstream,
sizeof(cfg->downstream));
bcopy(&priv->lower.cfg, &cfg->upstream,
@@ -374,7 +368,7 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
cfg->bandwidth = 0;
break;
case NGM_PIPE_SET_CFG:
- cfg = (struct ng_pipe_cfg *)msg->data;
+ cfg = (struct ng_pipe_cfg *) msg->data;
if (msg->header.arglen != sizeof(*cfg)) {
error = EINVAL;
break;
@@ -401,7 +395,8 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
if (cfg->overhead == -1)
priv->overhead = 0;
- else if (cfg->overhead > 0 && cfg->overhead < 256)
+ else if (cfg->overhead > 0 &&
+ cfg->overhead < MAX_OHSIZE)
priv->overhead = cfg->overhead;
if (cfg->header_offset == -1)
@@ -411,9 +406,9 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
priv->header_offset = cfg->header_offset;
parse_cfg(&priv->upper.cfg, &cfg->downstream,
- &priv->upper, priv);
+ &priv->upper, priv);
parse_cfg(&priv->lower.cfg, &cfg->upstream,
- &priv->lower, priv);
+ &priv->lower, priv);
break;
default:
error = EINVAL;
@@ -427,8 +422,6 @@ ngp_rcvmsg(node_p node, item_p item, hook_p lasthook)
NG_RESPOND_MSG(error, node, item, resp);
NG_FREE_MSG(msg);
- mtx_unlock(&ng_pipe_giant);
-
return (error);
}
@@ -449,9 +442,9 @@ parse_cfg(struct ng_pipe_hookcfg *current, struct ng_pipe_hookcfg *new,
uint32_t fsize, i;
if (hinfo->ber_p == NULL)
- hinfo->ber_p = malloc(\
- (MAX_FSIZE + MAX_OHSIZE)*sizeof(uint64_t), \
- M_NG_PIPE, M_NOWAIT);
+ hinfo->ber_p =
+ malloc((MAX_FSIZE + MAX_OHSIZE) * sizeof(uint64_t),
+ M_NG_PIPE, M_NOWAIT);
current->ber = new->ber;
/*
@@ -467,10 +460,10 @@ parse_cfg(struct ng_pipe_hookcfg *current, struct ng_pipe_hookcfg *new,
p = one;
for (fsize = 0; fsize < MAX_FSIZE + MAX_OHSIZE; fsize++) {
hinfo->ber_p[fsize] = p;
- for (i=0; i<8; i++)
- p = (p*(p0&0xffff)>>48) + \
- (p*((p0>>16)&0xffff)>>32) + \
- (p*(p0>>32)>>16);
+ for (i = 0; i < 8; i++)
+ p = (p * (p0 & 0xffff) >> 48) +
+ (p * ((p0 >> 16) & 0xffff) >> 32) +
+ (p * (p0 >> 32) >> 16);
}
}
@@ -575,25 +568,42 @@ ngp_rcvdata(hook_p hook, item_p item)
struct ngp_fifo *ngp_f = NULL, *ngp_f1;
struct ngp_hdr *ngp_h = NULL;
struct mbuf *m;
- int hash;
+ int hash, plen;
int error = 0;
- if (hinfo->noqueue) {
+ /*
+ * Shortcut from inbound to outbound hook when neither of
+ * bandwidth, delay, BER or duplication probability is
+ * configured, nor we have queued frames to drain.
+ */
+ if (hinfo->run.qin_frames == 0 && hinfo->run.qout_frames == 0 &&
+ hinfo->noqueue) {
struct hookinfo *dest;
if (hinfo == &priv->lower)
dest = &priv->upper;
else
dest = &priv->lower;
+
+ /* Send the frame. */
+ plen = NGI_M(item)->m_pkthdr.len;
NG_FWD_ITEM_HOOK(error, item, dest->hook);
- return error;
+
+ /* Update stats. */
+ if (error) {
+ hinfo->stats.out_disc_frames++;
+ hinfo->stats.out_disc_octets += plen;
+ } else {
+ hinfo->stats.fwd_frames++;
+ hinfo->stats.fwd_octets += plen;
+ }
+
+ return (error);
}
- mtx_lock(&ng_pipe_giant);
microuptime(now);
/*
- * Attach us to the list of active ng_pipes if this was an empty
- * one before, and also update the queue service deadline time.
+ * If this was an empty queue, update service deadline time.
*/
if (hinfo->run.qin_frames == 0) {
struct timeval *when = &hinfo->qin_utime;
@@ -602,8 +612,6 @@ ngp_rcvdata(hook_p hook, item_p item)
when->tv_sec = now->tv_sec;
when->tv_usec = now->tv_usec;
}
- if (hinfo->run.qout_frames == 0)
- LIST_INSERT_HEAD(&active_head, hinfo, active_le);
}
/* Populate the packet header */
@@ -702,9 +710,7 @@ ngp_rcvdata(hook_p hook, item_p item)
}
/*
- * Try to start the dequeuing process immediately. We must
- * hold the ng_pipe_giant lock here and pipe_dequeue() will
- * release it
+ * Try to start the dequeuing process immediately.
*/
pipe_dequeue(hinfo, now);
@@ -720,27 +726,21 @@ ngp_rcvdata(hook_p hook, item_p item)
* to outbound (delay) queue;
* 4) Loop to 2) until bandwidth quota for this timeslice is reached, or
* inbound queue is flushed completely;
- * 5) Extract the first frame from the outbound queue, if it's time has
- * come. Queue the frame for transmission on the outbound hook;
- * 6) Loop to 5) until outbound queue is flushed completely, or the next
- * frame in the queue is not scheduled to be dequeued yet;
- * 7) Transimit all frames queued in 5)
- *
- * Note: the caller must hold the ng_pipe_giant lock; this function
- * returns with the lock released.
+ * 5) Dequeue frames from the outbound queue and send them downstream until
+ * outbound queue is flushed completely, or the next frame in the queue
+ * is not due to be dequeued yet
*/
static void
pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
static uint64_t rand, oldrand;
- const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hinfo->hook));
+ const node_p node = NG_HOOK_NODE(hinfo->hook);
+ const priv_p priv = NG_NODE_PRIVATE(node);
struct hookinfo *dest;
struct ngp_fifo *ngp_f, *ngp_f1;
struct ngp_hdr *ngp_h;
struct timeval *when;
- struct mbuf *q_head = NULL;
- struct mbuf *q_tail = NULL;
struct mbuf *m;
- int error = 0;
+ int plen, error = 0;
/* Which one is the destination hook? */
if (hinfo == &priv->lower)
@@ -791,13 +791,13 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
/* Calculate the serialization delay */
if (hinfo->cfg.bandwidth) {
- hinfo->qin_utime.tv_usec += ((uint64_t) m->m_pkthdr.len
- + priv->overhead ) *
- 8000000 / hinfo->cfg.bandwidth;
+ hinfo->qin_utime.tv_usec +=
+ ((uint64_t) m->m_pkthdr.len + priv->overhead ) *
+ 8000000 / hinfo->cfg.bandwidth;
hinfo->qin_utime.tv_sec +=
- hinfo->qin_utime.tv_usec / 1000000;
+ hinfo->qin_utime.tv_usec / 1000000;
hinfo->qin_utime.tv_usec =
- hinfo->qin_utime.tv_usec % 1000000;
+ hinfo->qin_utime.tv_usec % 1000000;
}
when = &ngp_h->when;
when->tv_sec = hinfo->qin_utime.tv_sec;
@@ -853,95 +853,57 @@ pipe_dequeue(struct hookinfo *hinfo, struct timeval *now) {
/* Delay queue processing */
while ((ngp_h = TAILQ_FIRST(&hinfo->qout_head))) {
- struct mbuf *m = ngp_h->m;
-
when = &ngp_h->when;
+ m = ngp_h->m;
if (when->tv_sec > now->tv_sec ||
(when->tv_sec == now->tv_sec &&
when->tv_usec > now->tv_usec))
break;
/* Update outbound queue stats */
- hinfo->stats.fwd_frames++;
- hinfo->stats.fwd_octets += m->m_pkthdr.len;
+ plen = m->m_pkthdr.len;
hinfo->run.qout_frames--;
- hinfo->run.qout_octets -= m->m_pkthdr.len;
+ hinfo->run.qout_octets -= plen;
/* Dequeue the packet from qout */
TAILQ_REMOVE(&hinfo->qout_head, ngp_h, ngp_link);
uma_zfree(ngp_zone, ngp_h);
- /* Enqueue locally for sending downstream */
- if (q_head == NULL)
- q_head = m;
- if (q_tail)
- q_tail->m_nextpkt = m;
- q_tail = m;
- m->m_nextpkt = NULL;
- }
-
- /* If both queues are empty detach us from the list of active queues */
- if (hinfo->run.qin_frames + hinfo->run.qout_frames == 0) {
- LIST_REMOVE(hinfo, active_le);
- active_gen_id++;
+ NG_SEND_DATA(error, dest->hook, m, meta);
+ if (error) {
+ hinfo->stats.out_disc_frames++;
+ hinfo->stats.out_disc_octets += plen;
+ } else {
+ hinfo->stats.fwd_frames++;
+ hinfo->stats.fwd_octets += plen;
+ }
}
- mtx_unlock(&ng_pipe_giant);
-
- while ((m = q_head) != NULL) {
- q_head = m->m_nextpkt;
- m->m_nextpkt = NULL;
- NG_SEND_DATA(error, dest->hook, m, meta);
+ if ((hinfo->run.qin_frames != 0 || hinfo->run.qout_frames != 0) &&
+ !priv->timer_scheduled) {
+ ng_callout(&priv->timer, node, NULL, 1, ngp_callout, NULL, 0);
+ priv->timer_scheduled = 1;
}
}
-
/*
- * This routine is called on every clock tick. We poll all nodes/hooks
+ * This routine is called on every clock tick. We poll connected hooks
* for queued frames by calling pipe_dequeue().
*/
static void
-pipe_scheduler(void *arg)
+ngp_callout(node_p node, hook_p hook, void *arg1, int arg2)
{
- pipe_poll();
-
- /* Reschedule */
- callout_reset(&polling_timer, 1, &pipe_scheduler, NULL);
-}
-
-
-/*
- * Traverse the list of all active hooks and attempt to dequeue
- * some packets. Hooks with empty queues are not traversed since
- * they are not linked into this list.
- */
-static void
-pipe_poll(void)
-{
- struct hookinfo *hinfo;
+ const priv_p priv = NG_NODE_PRIVATE(node);
struct timeval now;
- int old_gen_id = active_gen_id;
-
- mtx_lock(&ng_pipe_giant);
+
+ priv->timer_scheduled = 0;
microuptime(&now);
- LIST_FOREACH(hinfo, &active_head, active_le) {
- CURVNET_SET(NG_HOOK_NODE(hinfo->hook)->nd_vnet);
- pipe_dequeue(hinfo, &now);
- CURVNET_RESTORE();
- mtx_lock(&ng_pipe_giant);
- if (old_gen_id != active_gen_id) {
- /* the list was updated; restart traversing */
- hinfo = LIST_FIRST(&active_head);
- if (hinfo == NULL)
- break;
- old_gen_id = active_gen_id;
- continue;
- }
- }
- mtx_unlock(&ng_pipe_giant);
+ if (priv->upper.hook != NULL)
+ pipe_dequeue(&priv->upper, &now);
+ if (priv->lower.hook != NULL)
+ pipe_dequeue(&priv->lower, &now);
}
-
/*
* Shutdown processing
*
@@ -955,6 +917,8 @@ ngp_shutdown(node_p node)
{
const priv_p priv = NG_NODE_PRIVATE(node);
+ if (priv->timer_scheduled)
+ ng_uncallout(&priv->timer, node);
if (priv->lower.hook && priv->upper.hook)
ng_bypass(priv->lower.hook, priv->upper.hook);
else {
@@ -978,9 +942,6 @@ ngp_disconnect(hook_p hook)
struct hookinfo *const hinfo = NG_HOOK_PRIVATE(hook);
struct ngp_fifo *ngp_f;
struct ngp_hdr *ngp_h;
- int removed = 0;
-
- mtx_lock(&ng_pipe_giant);
KASSERT(hinfo != NULL, ("%s: null info", __FUNCTION__));
hinfo->hook = NULL;
@@ -991,7 +952,6 @@ ngp_disconnect(hook_p hook)
TAILQ_REMOVE(&ngp_f->packet_head, ngp_h, ngp_link);
m_freem(ngp_h->m);
uma_zfree(ngp_zone, ngp_h);
- removed++;
}
TAILQ_REMOVE(&hinfo->fifo_head, ngp_f, fifo_le);
uma_zfree(ngp_zone, ngp_f);
@@ -1002,27 +962,12 @@ ngp_disconnect(hook_p hook)
TAILQ_REMOVE(&hinfo->qout_head, ngp_h, ngp_link);
m_freem(ngp_h->m);
uma_zfree(ngp_zone, ngp_h);
- removed++;
}
- /*
- * Both queues should be empty by now, so detach us from
- * the list of active queues
- */
- if (removed) {
- LIST_REMOVE(hinfo, active_le);
- active_gen_id++;
- }
- if (hinfo->run.qin_frames + hinfo->run.qout_frames != removed)
- printf("Mismatch: queued=%d but removed=%d !?!",
- hinfo->run.qin_frames + hinfo->run.qout_frames, removed);
-
/* Release the packet loss probability table (BER) */
if (hinfo->ber_p)
free(hinfo->ber_p, M_NG_PIPE);
- mtx_unlock(&ng_pipe_giant);
-
return (0);
}
@@ -1038,16 +983,9 @@ ngp_modevent(module_t mod, int type, void *unused)
UMA_ALIGN_PTR, 0);
if (ngp_zone == NULL)
panic("ng_pipe: couldn't allocate descriptor zone");
-
- mtx_init(&ng_pipe_giant, "ng_pipe_giant", NULL, MTX_DEF);
- LIST_INIT(&active_head);
- callout_init(&polling_timer, CALLOUT_MPSAFE);
- callout_reset(&polling_timer, 1, &pipe_scheduler, NULL);
break;
case MOD_UNLOAD:
- callout_drain(&polling_timer);
uma_zdestroy(ngp_zone);
- mtx_destroy(&ng_pipe_giant);
break;
default:
error = EOPNOTSUPP;
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index d2d99b9..1354d5e 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -218,7 +218,7 @@ static void carp_set_state(struct carp_softc *, int);
static int carp_addrcount(struct carp_if *, struct in_ifaddr *, int);
enum { CARP_COUNT_MASTER, CARP_COUNT_RUNNING };
-static void carp_multicast_cleanup(struct carp_softc *);
+static void carp_multicast_cleanup(struct carp_softc *, int dofree);
static int carp_set_addr(struct carp_softc *, struct sockaddr_in *);
static int carp_del_addr(struct carp_softc *, struct sockaddr_in *);
static void carp_carpdev_state_locked(struct carp_if *);
@@ -227,7 +227,7 @@ static void carp_sc_state_locked(struct carp_softc *);
static void carp_send_na(struct carp_softc *);
static int carp_set_addr6(struct carp_softc *, struct sockaddr_in6 *);
static int carp_del_addr6(struct carp_softc *, struct sockaddr_in6 *);
-static void carp_multicast6_cleanup(struct carp_softc *);
+static void carp_multicast6_cleanup(struct carp_softc *, int dofree);
#endif
static LIST_HEAD(, carp_softc) carpif_list;
@@ -466,9 +466,11 @@ carp_clone_destroy(struct ifnet *ifp)
/*
* This function can be called on CARP interface destroy path,
* and in case of the removal of the underlying interface as
- * well. We differentiate these two cases. In the latter case
- * we do not cleanup our multicast memberships, since they
- * are already freed. Also, in the latter case we do not
+ * well. We differentiate these two cases: in case of destruction
+ * of the underlying interface, we do not cleanup our multicast
+ * memberships, since they are already freed. But we purge pointers
+ * to multicast structures, since they are no longer valid, to
+ * avoid panic in future calls to carpdetach(). Also, we do not
* release the lock on return, because the function will be
* called once more, for another CARP instance on the same
* interface.
@@ -493,10 +495,9 @@ carpdetach(struct carp_softc *sc, int unlock)
carp_set_state(sc, INIT);
SC2IFP(sc)->if_flags &= ~IFF_UP;
carp_setrun(sc, 0);
- if (unlock)
- carp_multicast_cleanup(sc);
+ carp_multicast_cleanup(sc, unlock);
#ifdef INET6
- carp_multicast6_cleanup(sc);
+ carp_multicast6_cleanup(sc, unlock);
#endif
if (sc->sc_carpdev != NULL) {
@@ -1444,7 +1445,7 @@ carp_setrun(struct carp_softc *sc, sa_family_t af)
}
static void
-carp_multicast_cleanup(struct carp_softc *sc)
+carp_multicast_cleanup(struct carp_softc *sc, int dofree)
{
struct ip_moptions *imo = &sc->sc_imo;
u_int16_t n = imo->imo_num_memberships;
@@ -1452,7 +1453,8 @@ carp_multicast_cleanup(struct carp_softc *sc)
/* Clean up our own multicast memberships */
while (n-- > 0) {
if (imo->imo_membership[n] != NULL) {
- in_delmulti(imo->imo_membership[n]);
+ if (dofree)
+ in_delmulti(imo->imo_membership[n]);
imo->imo_membership[n] = NULL;
}
}
@@ -1464,14 +1466,15 @@ carp_multicast_cleanup(struct carp_softc *sc)
#ifdef INET6
static void
-carp_multicast6_cleanup(struct carp_softc *sc)
+carp_multicast6_cleanup(struct carp_softc *sc, int dofree)
{
struct ip6_moptions *im6o = &sc->sc_im6o;
u_int16_t n = im6o->im6o_num_memberships;
while (n-- > 0) {
if (im6o->im6o_membership[n] != NULL) {
- in6_mc_leave(im6o->im6o_membership[n], NULL);
+ if (dofree)
+ in6_mc_leave(im6o->im6o_membership[n], NULL);
im6o->im6o_membership[n] = NULL;
}
}
@@ -1831,7 +1834,7 @@ carp_set_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6)
cleanup:
if (!sc->sc_naddrs6)
- carp_multicast6_cleanup(sc);
+ carp_multicast6_cleanup(sc, 1);
ifa_free(&ia->ia_ifa);
return (error);
}
@@ -1849,7 +1852,7 @@ carp_del_addr6(struct carp_softc *sc, struct sockaddr_in6 *sin6)
SC2IFP(sc)->if_flags &= ~IFF_UP;
SC2IFP(sc)->if_drv_flags &= ~IFF_DRV_RUNNING;
sc->sc_vhid = -1;
- carp_multicast6_cleanup(sc);
+ carp_multicast6_cleanup(sc, 1);
TAILQ_REMOVE(&cif->vhif_vrs, sc, sc_list);
if (!--cif->vhif_nvrs) {
CARP_LOCK_DESTROY(cif);
diff --git a/sys/netinet/sctp_cc_functions.c b/sys/netinet/sctp_cc_functions.c
index e40639b..b7b4118 100644
--- a/sys/netinet/sctp_cc_functions.c
+++ b/sys/netinet/sctp_cc_functions.c
@@ -42,6 +42,7 @@
#include <netinet/sctp_auth.h>
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_cc_functions.h>
+#include <netinet/sctp_dtrace_declare.h>
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -63,6 +64,9 @@ sctp_set_initial_cc_param(struct sctp_tcb *stcb, struct sctp_nets *net)
net->cwnd = (net->mtu - sizeof(struct sctphdr)) * cwnd_in_mtu;
net->ssthresh = assoc->peers_rwnd;
+ SDT_PROBE(sctp, cwnd, net, init,
+ stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
+ 0, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) &
(SCTP_CWND_MONITOR_ENABLE | SCTP_CWND_LOGGING_ENABLE)) {
sctp_log_cwnd(stcb, net, 0, SCTP_CWND_INITIALIZATION);
@@ -98,6 +102,9 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
net->ssthresh = 2 * net->mtu;
}
net->cwnd = net->ssthresh;
+ SDT_PROBE(sctp, cwnd, net, fr,
+ stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
SCTP_CWND_LOG_FROM_FR);
@@ -155,6 +162,7 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
int accum_moved, int reneged_all, int will_exit)
{
struct sctp_nets *net;
+ int old_cwnd;
/******************************/
/* update cwnd and Early FR */
@@ -246,7 +254,11 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
(asoc->sctp_cmt_pf > 0) &&
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
net->dest_state &= ~SCTP_ADDR_PF;
+ old_cwnd = net->cwnd;
net->cwnd = net->mtu * asoc->sctp_cmt_pf;
+ SDT_PROBE(sctp, cwnd, net, ack,
+ stcb->asoc.my_vtag, ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)), net,
+ old_cwnd, net->cwnd);
SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n",
net, net->cwnd);
/*
@@ -290,13 +302,26 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
/* We are in slow start */
if (net->flight_size + net->net_ack >= net->cwnd) {
if (net->net_ack > (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable))) {
+ old_cwnd = net->cwnd;
net->cwnd += (net->mtu * SCTP_BASE_SYSCTL(sctp_L2_abc_variable));
+ SDT_PROBE(sctp, cwnd, net, ack,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, net->mtu,
SCTP_CWND_LOG_FROM_SS);
}
} else {
+ old_cwnd = net->cwnd;
net->cwnd += net->net_ack;
+ SDT_PROBE(sctp, cwnd, net, ack,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
+
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, net->net_ack,
SCTP_CWND_LOG_FROM_SS);
@@ -318,7 +343,13 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
if ((net->flight_size + net->net_ack >= net->cwnd) &&
(net->partial_bytes_acked >= net->cwnd)) {
net->partial_bytes_acked -= net->cwnd;
+ old_cwnd = net->cwnd;
net->cwnd += net->mtu;
+ SDT_PROBE(sctp, cwnd, net, ack,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, net->mtu,
SCTP_CWND_LOG_FROM_CA);
@@ -364,7 +395,11 @@ sctp_cwnd_update_after_timeout(struct sctp_tcb *stcb, struct sctp_nets *net)
net->ssthresh = max(net->cwnd / 2, 4 * net->mtu);
net->cwnd = net->mtu;
net->partial_bytes_acked = 0;
-
+ SDT_PROBE(sctp, cwnd, net, to,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, net->cwnd - old_cwnd, SCTP_CWND_LOG_FROM_RTX);
}
@@ -383,6 +418,11 @@ sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net)
net->RTO <<= 1;
}
net->cwnd = net->ssthresh;
+ SDT_PROBE(sctp, cwnd, net, ecn,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_SAT);
}
@@ -492,6 +532,11 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb,
}
if (net->cwnd - old_cwnd != 0) {
/* log only changes */
+ SDT_PROBE(sctp, cwnd, net, pd,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd),
SCTP_CWND_LOG_FROM_SAT);
@@ -508,7 +553,11 @@ sctp_cwnd_update_after_output(struct sctp_tcb *stcb,
if (net->ssthresh < net->cwnd)
net->ssthresh = net->cwnd;
net->cwnd = (net->flight_size + (burst_limit * net->mtu));
-
+ SDT_PROBE(sctp, cwnd, net, bl,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_BRST);
}
@@ -530,6 +579,11 @@ sctp_cwnd_update_after_fr_timer(struct sctp_inpcb *inp,
if (net->cwnd < net->ssthresh)
/* still in SS move to CA */
net->ssthresh = net->cwnd - 1;
+ SDT_PROBE(sctp, cwnd, net, fr,
+ stcb->asoc.my_vtag,
+ ((stcb->sctp_ep->sctp_lport << 16) | (stcb->rport)),
+ net,
+ old_cwnd, net->cwnd);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_MONITOR_ENABLE) {
sctp_log_cwnd(stcb, net, (old_cwnd - net->cwnd), SCTP_CWND_LOG_FROM_FR);
}
diff --git a/sys/netinet/sctp_dtrace_declare.h b/sys/netinet/sctp_dtrace_declare.h
new file mode 100644
index 0000000..76e63d5
--- /dev/null
+++ b/sys/netinet/sctp_dtrace_declare.h
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2010, by Randall Stewart & Michael Tuexen,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * a) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * b) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * c) Neither the name of Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#ifndef __sctp_dtrace_declare_h__
+#include "opt_kdtrace.h"
+#include <sys/kernel.h>
+#include <sys/sdt.h>
+
+/* Declare the SCTP provider */
+SDT_PROVIDER_DECLARE(sctp);
+
+/* The probes we have so far: */
+
+/* One to track a net's cwnd */
+/* initial */
+SDT_PROBE_DECLARE(sctp, cwnd, net, init);
+/* update at a ack -- increase */
+SDT_PROBE_DECLARE(sctp, cwnd, net, ack);
+/* update at a fast retransmit -- decrease */
+SDT_PROBE_DECLARE(sctp, cwnd, net, fr);
+/* update at a time-out -- decrease */
+SDT_PROBE_DECLARE(sctp, cwnd, net, to);
+/* update at a burst-limit -- decrease */
+SDT_PROBE_DECLARE(sctp, cwnd, net, bl);
+/* update at a ECN -- decrease */
+SDT_PROBE_DECLARE(sctp, cwnd, net, ecn);
+/* update at a Packet-Drop -- decrease */
+SDT_PROBE_DECLARE(sctp, cwnd, net, pd);
+
+/* One to track an associations rwnd */
+SDT_PROBE_DECLARE(sctp, rwnd, assoc, val);
+
+/* One to track a net's flight size */
+SDT_PROBE_DECLARE(sctp, flightsize, net, val);
+
+/* One to track an associations flight size */
+SDT_PROBE_DECLARE(sctp, flightsize, assoc, val);
+
+
+
+
+
+
+#endif
diff --git a/sys/netinet/sctp_dtrace_define.h b/sys/netinet/sctp_dtrace_define.h
new file mode 100644
index 0000000..3c74fc5
--- /dev/null
+++ b/sys/netinet/sctp_dtrace_define.h
@@ -0,0 +1,201 @@
+/*-
+ * Copyright (c) 2010, by Randall Stewart & Michael Tuexen,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * a) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * b) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * c) Neither the name of Cisco Systems, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+#ifndef __sctp_dtrace_define_h__
+#include "opt_kdtrace.h"
+#include <sys/kernel.h>
+#include <sys/sdt.h>
+
+SDT_PROVIDER_DEFINE(sctp);
+
+/********************************************************/
+/* Cwnd probe - tracks changes in the congestion window on a netp */
+/********************************************************/
+/* Initial */
+SDT_PROBE_DEFINE(sctp, cwnd, net, init, init);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, init, 4, "int");
+
+
+/* ACK-INCREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, ack, ack);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ack, 4, "int");
+
+/* FastRetransmit-DECREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, fr, fr);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, fr, 4, "int");
+
+
+/* TimeOut-DECREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, to, to);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, to, 4, "int");
+
+
+/* BurstLimit-DECREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, bl, bl);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, bl, 4, "int");
+
+
+/* ECN-DECREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, ecn, ecn);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, ecn, 4, "int");
+
+
+/* PacketDrop-DECREASE */
+SDT_PROBE_DEFINE(sctp, cwnd, net, pd, pd);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 2, "uintptr_t");
+/* The old value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, cwnd, net, pd, 4, "int");
+
+
+
+/********************************************************/
+/* Rwnd probe - tracks changes in the receiver window for an assoc */
+/********************************************************/
+SDT_PROBE_DEFINE(sctp, rwnd, assoc, val, val);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 1, "uint32_t");
+/* The up/down amount */
+SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 2, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, rwnd, assoc, val, 3, "int");
+
+/********************************************************/
+/* flight probe - tracks changes in the flight size on a net or assoc */
+/********************************************************/
+SDT_PROBE_DEFINE(sctp, flightsize, net, val, val);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 1, "uint32_t");
+/* The pointer to the struct sctp_nets * changing */
+SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 2, "uintptr_t");
+/* The up/down amount */
+SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 3, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, flightsize, net, val, 4, "int");
+/********************************************************/
+/* The total flight version */
+/********************************************************/
+SDT_PROBE_DEFINE(sctp, flightsize, assoc, val, val);
+/* The Vtag for this end */
+SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 0, "uint32_t");
+/* The port number of the local side << 16 | port number of remote
+ * in network byte order.
+ */
+SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 1, "uint32_t");
+/* The up/down amount */
+SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 2, "int");
+/* The new value of the cwnd */
+SDT_PROBE_ARGTYPE(sctp, flightsize, assoc, val, 3, "int");
+
+#endif
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index aaa0500..949121e 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_output.h>
#include <netinet/sctp_timer.h>
#include <netinet/sctp_bsd_addr.h>
+#include <netinet/sctp_dtrace_define.h>
#include <netinet/udp.h>
diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h
index 1cb62f3..8109f0f 100644
--- a/sys/netinet/sctp_uio.h
+++ b/sys/netinet/sctp_uio.h
@@ -942,7 +942,7 @@ struct sctpstat {
uint32_t sctps_wu_sacks_sent; /* Window Update only sacks sent */
uint32_t sctps_sends_with_flags; /* number of sends with
* sinfo_flags !=0 */
- uint32_t sctps_sends_with_unord; /* number of unordered sends */
+ uint32_t sctps_sends_with_unord; /* number of unordered sends */
uint32_t sctps_sends_with_eof; /* number of sends with EOF flag set */
uint32_t sctps_sends_with_abort; /* number of sends with ABORT
* flag set */
diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h
index afb7f76..568d15f 100644
--- a/sys/sys/elf_common.h
+++ b/sys/sys/elf_common.h
@@ -325,6 +325,7 @@ typedef struct {
#define PT_LOOS 0x60000000 /* First OS-specific. */
#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
#define PT_GNU_EH_FRAME 0x6474e550
+#define PT_GNU_STACK 0x6474e551
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index fbfd6e8..10256c5 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -452,6 +452,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
{ "logsigexit", CTLTYPE_INT }, \
{ "iov_max", CTLTYPE_INT }, \
{ "hostuuid", CTLTYPE_STRING }, \
+ { "arc4rand", CTLTYPE_OPAQUE }, \
}
/*
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index ecbef05..94a96bd 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -821,9 +821,11 @@ rescan:
np = TAILQ_NEXT(p, listq);
if (p->valid == 0)
continue;
- while (vm_page_sleep_if_busy(p, TRUE, "vpcwai")) {
+ if (vm_page_sleep_if_busy(p, TRUE, "vpcwai")) {
if (object->generation != curgeneration)
goto rescan;
+ np = vm_page_find_least(object, pi);
+ continue;
}
vm_page_test_dirty(p);
if (p->dirty == 0)
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 7f8e583..d6da578 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -251,7 +251,7 @@ lapic_init(vm_paddr_t addr)
/* Intel CPUID 0x06 EAX[2] set if APIC timer runs in C3. */
if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high >= 6) {
do_cpuid(0x06, regs);
- if (regs[0] & 0x4)
+ if ((regs[0] & CPUTPM1_ARAT) != 0)
arat = 1;
}
bzero(&lapic_et, sizeof(lapic_et));
diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh
index 07a26f2..b269da1 100644
--- a/tools/tools/sysbuild/sysbuild.sh
+++ b/tools/tools/sysbuild/sysbuild.sh
@@ -163,29 +163,47 @@ log_it() (
ports_recurse() (
set +x
+ t=$1
+ shift
+ if [ "x$t" = "x." ] ; then
+ true > /tmp/_.plist
+ true > /tmp/_.plist.tdone
+ echo 'digraph {' > /tmp/_.plist.dot
+ fi
+ if grep -q "^$t\$" /tmp/_.plist.tdone ; then
+ return
+ fi
+ echo "$t" >> /tmp/_.plist.tdone
for d
do
if [ ! -d $d ] ; then
echo "Missing port $d" 1>&2
exit 2
fi
+ if [ "x$t" != "x." ] ; then
+ echo "\"$t\" -> \"$d\"" >> /tmp/_.plist.dot
+ fi
if grep -q "^$d\$" /tmp/_.plist ; then
true
+ elif grep -q "^$d\$" /tmp/_.plist.tdone ; then
+ true
else
(
cd $d
- ports_recurse `make -V _DEPEND_DIRS ${PORTS_OPTS}`
+ ports_recurse $d `make -V _DEPEND_DIRS ${PORTS_OPTS}`
)
- echo $d >> /tmp/_.plist
+ echo "$d" >> /tmp/_.plist
fi
done
+ if [ "x$t" = "x." ] ; then
+ echo '}' >> /tmp/_.plist.dot
+ fi
)
ports_build() (
set +x
- true > /tmp/_.plist
- ports_recurse $PORTS_WE_WANT
+ ports_recurse . $PORTS_WE_WANT
# Now build & install them
for p in `cat /tmp/_.plist`
@@ -226,22 +244,31 @@ ports_build() (
ports_prefetch() (
(
set +x
- true > /tmp/_.plist
- ports_recurse $PORTS_WE_WANT
-
true > /mnt/_.prefetch
+ echo "Building /tmp/_.plist" >> /mnt/_.prefetch
+
+ ports_recurse . $PORTS_WE_WANT
+
+ echo "Completed /tmp/_.plist" >> /mnt/_.prefetch
# Now checksump/fetch them
for p in `cat /tmp/_.plist`
do
- echo "Prefetching $p" >> /mnt/_.prefetch
b=`echo $p | tr / _`
(
cd $p
if make checksum $PORTS_OPTS ; then
- true
+ rm -f /mnt/_.prefetch.$b
+ echo "OK $p" >> /mnt/_.prefetch
+ exit 0
+ fi
+ make distclean
+ make checksum $PORTS_OPTS || true
+
+ if make checksum $PORTS_OPTS > /dev/null 2>&1 ; then
+ rm -f /mnt/_.prefetch.$b
+ echo "OK $p" >> /mnt/_.prefetch
else
- make distclean
- make checksum $PORTS_OPTS || true
+ echo "BAD $p" >> /mnt/_.prefetch
fi
) > /mnt/_.prefetch.$b 2>&1
done
@@ -411,7 +438,7 @@ if [ "x${REMOTEDISTFILES}" != "x" ] ; then
fi
log_it copy ports config files
-(cd / ; find var/db/ports -print | cpio -dumpv /mnt )
+(cd / ; find var/db/ports -print | cpio -dumpv /mnt > /dev/null 2>&1)
log_it "Start prefetch of ports distfiles"
ports_prefetch &
diff --git a/usr.bin/locate/locate/locate.h b/usr.bin/locate/locate/locate.h
index 24df8d4..c2f27fb 100644
--- a/usr.bin/locate/locate/locate.h
+++ b/usr.bin/locate/locate/locate.h
@@ -48,15 +48,15 @@
#define LDC_MAX 28
/* 128-255 bigram codes (128 most common, as determined by 'updatedb') */
-#define BIGRAM_MIN (UCHAR_MAX - CHAR_MAX)
+#define BIGRAM_MIN (UCHAR_MAX - SCHAR_MAX)
#define BIGRAM_MAX UCHAR_MAX
/* 32-127 single character (printable) ascii residue (ie, literal) */
#define ASCII_MIN 32
-#define ASCII_MAX CHAR_MAX
+#define ASCII_MAX SCHAR_MAX
-/* #define TO7BIT(x) (x = ( ((u_char)x) & CHAR_MAX )) */
-#define TO7BIT(x) (x = x & CHAR_MAX )
+/* #define TO7BIT(x) (x = ( ((u_char)x) & SCHAR_MAX )) */
+#define TO7BIT(x) (x = x & SCHAR_MAX )
#if UCHAR_MAX >= 4096
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index 01a0242..07be206 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -428,13 +428,14 @@ protopr(u_long off, const char *name, int af1, int proto)
"2msl", "delack", "rcvtime",
"(state)");
}
- if (!xflag && !Tflag)
+ if (!xflag && !Tflag) {
printf((Aflag && !Wflag) ?
"%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s" :
"%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s",
"Proto", "Recv-Q", "Send-Q",
"Local Address", "Foreign Address");
-
+ printf("(state)\n");
+ }
first = 0;
}
if (Lflag && so->so_qlimit == 0)
diff --git a/usr.sbin/iostat/iostat.8 b/usr.sbin/iostat/iostat.8
index 69fadcf..aab668a 100644
--- a/usr.sbin/iostat/iostat.8
+++ b/usr.sbin/iostat/iostat.8
@@ -60,7 +60,7 @@
.\"
.\" @(#)iostat.8 8.1 (Berkeley) 6/6/93
.\"
-.Dd April 17, 2006
+.Dd November 24, 2010
.Dt IOSTAT 8
.Os
.Sh NAME
@@ -102,11 +102,18 @@ Repeat the display
times.
If no repeat
.Ar count
-is specified, the default is infinity.
+is specified, the default depends on whether
+.Fl w
+is specified.
+With
+.Fl w
+the default repeat count is infinity, otherwise it is 1.
.It Fl C
Display CPU statistics.
This is on by default, unless
.Fl d
+or
+.Fl x
is specified.
.It Fl d
Display only device statistics.
@@ -231,6 +238,8 @@ output, up to the number of devices that can be displayed in
Display TTY statistics.
This is on by default, unless
.Fl d
+or
+.Fl x
is specified.
.It Fl w
Pause
@@ -255,6 +264,11 @@ so your mileage may vary.
.It Fl x
Show extended disk statistics.
Each disk is displayed on a line of its own with all available statistics.
+If this flag is turned on, only disk statistics will be displayed, unless
+.Fl C
+or
+.Fl T
+is also specified to enable the display of CPU or TTY statistics.
.It Fl z
If
.Fl x
diff --git a/usr.sbin/kernbb/Makefile b/usr.sbin/kernbb/Makefile
deleted file mode 100644
index f3bf37c..0000000
--- a/usr.sbin/kernbb/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# $FreeBSD$
-
-PROG= kernbb
-MAN= kernbb.8
-
-DPADD= ${LIBKVM}
-LDADD= -lkvm
-
-CFLAGS+= -I${.CURDIR}/../../contrib/gcc
-
-.include <bsd.prog.mk>
-
diff --git a/usr.sbin/kernbb/kernbb.8 b/usr.sbin/kernbb/kernbb.8
deleted file mode 100644
index 3d6fe02..0000000
--- a/usr.sbin/kernbb/kernbb.8
+++ /dev/null
@@ -1,82 +0,0 @@
-.\" Copyright (c) 1983, 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd May 22, 1995
-.Dt KERNBB 8
-.Os
-.Sh NAME
-.Nm kernbb
-.Nd generate a dump of the kernels basic-block profile buffers
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-The
-.Nm
-utility is used to extract the basic-block profiling buffers of the running
-kernel into the files needed for the
-.Xr gcov 1
-tool.
-.Pp
-At least one source file in the running kernel must have been compiled
-with the
-.Fl Fl test-coverage
-and
-.Fl Fl profile-arcs
-options.
-.Pp
-The output is stored in the filenames compiled into the kernel by
-.Xr gcc 1 .
-If the absolute pathname cannot be written to, the directory part
-of the filename is discarded and the file stored in the current
-directory under its basename.
-.Pp
-The output files are named
-.Pa *.da ,
-and the
-.Xr gcov 1
-program will extract the counts and merge them with the source
-file to show actual execution counts.
-.Sh FILES
-.Bl -tag -width /boot/kernel/kernel -compact
-.It Pa /boot/kernel/kernel
-the default system
-.It Pa /dev/kmem
-the default memory
-.El
-.Sh SEE ALSO
-.Xr cc 1 ,
-.Xr gcov 1
-.Sh AUTHORS
-The
-.Nm
-utility was written by
-.An Poul-Henning Kamp ,
-along with the kernel-support.
-.Sh BUGS
-There are far too much magic and internal knowledge from GCC in this.
diff --git a/usr.sbin/kernbb/kernbb.c b/usr.sbin/kernbb/kernbb.c
deleted file mode 100644
index 1ecd5ad..0000000
--- a/usr.sbin/kernbb/kernbb.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <err.h>
-#include <fcntl.h>
-#include <kvm.h>
-#include <nlist.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/endian.h>
-
-typedef long long gcov_type;
-
-#define PARAMS(foo) foo
-#define ATTRIBUTE_UNUSED __unused
-#include "gcov-io.h"
-
-struct bbf {
- long checksum;
- int arc_count;
- u_long name;
-};
-
-struct bb {
- u_long zero_one;
- u_long filename;
- u_long counts;
- u_long ncounts;
- u_long next;
- u_long sizeof_bb;
- u_long funcs;
-};
-
-struct nlist namelist[] = {
- { "bbhead", 0, 0, 0, 0 },
- { NULL, 0, 0, 0, 0 }
-};
-
-kvm_t *kv;
-
-int
-main(int argc __unused, char **argv __unused)
-{
- int i, funcs;
- u_long l1,l2,l4;
- struct bb bb;
- struct bbf bbf;
- char buf[BUFSIZ], *p;
- gcov_type *q, *qr;
-
- FILE *f;
-
- kv = kvm_open(NULL,NULL,NULL,O_RDWR,"dnc");
- if (!kv)
- err(1,"kvm_open");
- i = kvm_nlist(kv,namelist);
- if (i)
- err(1,"kvm_nlist");
-
- l1 = namelist[0].n_value;
- kvm_read(kv,l1,&l2,sizeof l2);
- while(l2) {
- l1 += sizeof l1;
- kvm_read(kv,l2,&bb,sizeof bb);
-#if 0
-printf("%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n%lx\n",
- bb.zero_one, bb.filename, bb.counts, bb.ncounts, bb.next,
- bb.sizeof_bb, bb.funcs);
-#endif
-
- funcs = 0;
- for (l4 = bb.funcs; ; l4 += sizeof (bbf)) {
- kvm_read(kv, l4, &bbf, sizeof(bbf));
- if (bbf.arc_count == -1)
- break;
- funcs++;
- }
-
- l2 = bb.next;
-
- kvm_read(kv, bb.filename, buf, sizeof(buf));
- p = buf;
- f = fopen(p, "w");
- if (f != NULL) {
- printf("Writing \"%s\"\n", p);
- } else {
- p = strrchr(buf, '/');
- if (p == NULL)
- p = buf;
- else
- p++;
- printf("Writing \"%s\" (spec \"%s\")\n", p, buf);
- f = fopen(p, "w");
- }
- if (f == NULL)
- err(1,"%s", p);
- __write_long(-123, f, 4);
-
- __write_long(funcs, f, 4);
-
- __write_long(4 + 8 + 8 + 4 + 8 + 8, f, 4);
-
- __write_long(bb.ncounts, f, 4);
- __write_long(0, f, 8);
- __write_long(0, f, 8);
-
- __write_long(bb.ncounts, f, 4);
- __write_long(0, f, 8);
- __write_long(0, f, 8);
-
- qr = malloc(bb.ncounts * 8);
- kvm_read(kv, bb.counts, qr, bb.ncounts * 8);
- q = qr;
- for (l4 = bb.funcs; ; l4 += sizeof (bbf)) {
- kvm_read(kv, l4, &bbf, sizeof(bbf));
- if (bbf.arc_count == -1)
- break;
- kvm_read(kv, bbf.name, buf, sizeof(buf));
-
- __write_gcov_string(buf, strlen(buf), f, -1);
-
- __write_long(bbf.checksum, f, 4);
- __write_long(bbf.arc_count, f, 4);
- for (i = 0; i < bbf.arc_count; i++) {
- __write_gcov_type(*q, f, 8);
- q++;
- }
- }
- fclose(f);
- free(qr);
- }
- return 0;
-}
diff --git a/usr.sbin/usbdump/usbdump.c b/usr.sbin/usbdump/usbdump.c
index 6545f1c..93e9f21 100644
--- a/usr.sbin/usbdump/usbdump.c
+++ b/usr.sbin/usbdump/usbdump.c
@@ -32,8 +32,11 @@
#include <sys/param.h>
#include <sys/endian.h>
#include <sys/ioctl.h>
+#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/utsname.h>
+#include <net/if.h>
+#include <net/bpf.h>
#include <dev/usb/usb.h>
#include <dev/usb/usb_pf.h>
#include <dev/usb/usbdi.h>
@@ -216,7 +219,7 @@ hexdump(const char *region, size_t len)
}
static void
-print_apacket(const struct usbpf_xhdr *hdr, struct usbpf_pkthdr *up,
+print_apacket(const struct bpf_xhdr *hdr, struct usbpf_pkthdr *up,
const char *payload)
{
struct tm *tm;
@@ -235,8 +238,8 @@ print_apacket(const struct usbpf_xhdr *hdr, struct usbpf_pkthdr *up,
up->up_error = le32toh(up->up_error);
up->up_interval = le32toh(up->up_interval);
- tv.tv_sec = hdr->uh_tstamp.ut_sec;
- tv.tv_usec = hdr->uh_tstamp.ut_frac;
+ tv.tv_sec = hdr->bh_tstamp.bt_sec;
+ tv.tv_usec = hdr->bh_tstamp.bt_frac;
tm = localtime(&tv.tv_sec);
len = strftime(buf, sizeof(buf), "%H:%M:%S", tm);
@@ -267,20 +270,19 @@ print_apacket(const struct usbpf_xhdr *hdr, struct usbpf_pkthdr *up,
print_status(up->up_status);
}
}
-
static void
print_packets(char *data, const int datalen)
{
struct usbpf_pkthdr *up;
- const struct usbpf_xhdr *hdr;
+ const struct bpf_xhdr *hdr;
u_int32_t framelen, x;
char *ptr, *next;
for (ptr = data; ptr < (data + datalen); ptr = next) {
- hdr = (const struct usbpf_xhdr *)ptr;
- up = (struct usbpf_pkthdr *)(ptr + hdr->uh_hdrlen);
- next = ptr + USBPF_WORDALIGN(hdr->uh_hdrlen + hdr->uh_caplen);
+ hdr = (const struct bpf_xhdr *)ptr;
+ up = (struct usbpf_pkthdr *)(ptr + hdr->bh_hdrlen);
+ next = ptr + BPF_WORDALIGN(hdr->bh_hdrlen + hdr->bh_caplen);
ptr = ((char *)up) + sizeof(struct usbpf_pkthdr);
if (w_arg == NULL)
@@ -404,12 +406,12 @@ int
main(int argc, char *argv[])
{
struct timeval tv;
- struct usbpf_insn total_insn;
- struct usbpf_program total_prog;
- struct usbpf_stat us;
- struct usbpf_version uv;
+ struct bpf_insn total_insn;
+ struct bpf_program total_prog;
+ struct bpf_stat us;
+ struct bpf_version bv;
struct usbcap uc, *p = &uc;
- struct usbpf_ifreq ufr;
+ struct ifreq ifr;
long snapshot = 192;
u_int v;
int fd, o;
@@ -454,37 +456,37 @@ main(int argc, char *argv[])
exit(EXIT_SUCCESS);
}
- p->fd = fd = open("/dev/usbpf", O_RDONLY);
+ p->fd = fd = open("/dev/bpf", O_RDONLY);
if (p->fd < 0) {
fprintf(stderr, "(no devices found)\n");
return (EXIT_FAILURE);
}
- if (ioctl(fd, UIOCVERSION, (caddr_t)&uv) < 0) {
- fprintf(stderr, "UIOCVERSION: %s\n", strerror(errno));
+ if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
+ fprintf(stderr, "BIOCVERSION: %s\n", strerror(errno));
return (EXIT_FAILURE);
}
- if (uv.uv_major != USBPF_MAJOR_VERSION ||
- uv.uv_minor < USBPF_MINOR_VERSION) {
+ if (bv.bv_major != BPF_MAJOR_VERSION ||
+ bv.bv_minor < BPF_MINOR_VERSION) {
fprintf(stderr, "kernel bpf filter out of date");
return (EXIT_FAILURE);
}
- if ((ioctl(fd, UIOCGBLEN, (caddr_t)&v) < 0) || v < 65536)
- v = 65536;
+ if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) || v < 4096)
+ v = 4096;
for ( ; v != 0; v >>= 1) {
- (void)ioctl(fd, UIOCSBLEN, (caddr_t)&v);
- (void)strncpy(ufr.ufr_name, i_arg, sizeof(ufr.ufr_name));
- if (ioctl(fd, UIOCSETIF, (caddr_t)&ufr) >= 0)
+ (void)ioctl(fd, BIOCSBLEN, (caddr_t)&v);
+ (void)strncpy(ifr.ifr_name, i_arg, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
break;
}
if (v == 0) {
- fprintf(stderr, "UIOCSBLEN: %s: No buffer size worked", i_arg);
+ fprintf(stderr, "BIOCSBLEN: %s: No buffer size worked", i_arg);
return (EXIT_FAILURE);
}
- if (ioctl(fd, UIOCGBLEN, (caddr_t)&v) < 0) {
- fprintf(stderr, "UIOCGBLEN: %s", strerror(errno));
+ if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
+ fprintf(stderr, "BIOCGBLEN: %s", strerror(errno));
return (EXIT_FAILURE);
}
@@ -496,23 +498,23 @@ main(int argc, char *argv[])
}
/* XXX no read filter rules yet so at this moment accept everything */
- total_insn.code = (u_short)(USBPF_RET | USBPF_K);
+ total_insn.code = (u_short)(BPF_RET | BPF_K);
total_insn.jt = 0;
total_insn.jf = 0;
total_insn.k = snapshot;
- total_prog.uf_len = 1;
- total_prog.uf_insns = &total_insn;
- if (ioctl(p->fd, UIOCSETF, (caddr_t)&total_prog) < 0) {
- fprintf(stderr, "UIOCSETF: %s", strerror(errno));
+ total_prog.bf_len = 1;
+ total_prog.bf_insns = &total_insn;
+ if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
+ fprintf(stderr, "BIOCSETF: %s", strerror(errno));
return (EXIT_FAILURE);
}
/* 1 second read timeout */
tv.tv_sec = 1;
tv.tv_usec = 0;
- if (ioctl(p->fd, UIOCSRTIMEOUT, (caddr_t)&tv) < 0) {
- fprintf(stderr, "UIOCSRTIMEOUT: %s", strerror(errno));
+ if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&tv) < 0) {
+ fprintf(stderr, "BIOCSRTIMEOUT: %s", strerror(errno));
return (EXIT_FAILURE);
}
@@ -520,16 +522,16 @@ main(int argc, char *argv[])
do_loop(p);
- if (ioctl(fd, UIOCGSTATS, (caddr_t)&us) < 0) {
- fprintf(stderr, "UIOCGSTATS: %s", strerror(errno));
+ if (ioctl(fd, BIOCGSTATS, (caddr_t)&us) < 0) {
+ fprintf(stderr, "BIOCGSTATS: %s", strerror(errno));
return (EXIT_FAILURE);
}
/* XXX what's difference between pkt_captured and us.us_recv? */
printf("\n");
printf("%d packets captured\n", pkt_captured);
- printf("%d packets received by filter\n", us.us_recv);
- printf("%d packets dropped by kernel\n", us.us_drop);
+ printf("%d packets received by filter\n", us.bs_recv);
+ printf("%d packets dropped by kernel\n", us.bs_drop);
if (p->fd > 0)
close(p->fd);
OpenPOWER on IntegriCloud