Merge ^/head r305029 through r305080.

This commit is contained in:
dim 2016-08-30 19:29:00 +00:00
commit fc8f4da96e
56 changed files with 913 additions and 996 deletions

View File

@ -644,11 +644,8 @@ ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
}
}
/*
* Return the type and offset for a given member of a STRUCT or UNION.
*/
int
ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
static int
_ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name, ulong_t off,
ctf_membinfo_t *mip)
{
ctf_file_t *ofp = fp;
@ -673,9 +670,13 @@ ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
((uintptr_t)tp + increment);
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
if (mp->ctm_name == 0 &&
_ctf_member_info(fp, mp->ctm_type, name,
mp->ctm_offset + off, mip) == 0)
return (0);
if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
mip->ctm_type = mp->ctm_type;
mip->ctm_offset = mp->ctm_offset;
mip->ctm_offset = mp->ctm_offset + off;
return (0);
}
}
@ -684,9 +685,14 @@ ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
((uintptr_t)tp + increment);
for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
if (lmp->ctlm_name == 0 &&
_ctf_member_info(fp, lmp->ctlm_name, name,
(ulong_t)CTF_LMEM_OFFSET(lmp) + off, mip) == 0)
return (0);
if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
mip->ctm_type = lmp->ctlm_type;
mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);
mip->ctm_offset =
(ulong_t)CTF_LMEM_OFFSET(lmp) + off;
return (0);
}
}
@ -695,6 +701,17 @@ ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));
}
/*
* Return the type and offset for a given member of a STRUCT or UNION.
*/
int
ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
ctf_membinfo_t *mip)
{
return (_ctf_member_info(fp, type, name, 0, mip));
}
/*
* Return the array type, index, and size information for the specified ARRAY.
*/

View File

@ -33,7 +33,7 @@ basic_head()
basic_body()
{
# Begin FreeBSD
atf_tc_expect_fail "dirname //usr//bin doesn't return //usr like it used to; bug # 212193"
atf_expect_fail "dirname //usr//bin doesn't return //usr like it used to; bug # 212193"
# End FreeBSD
atf_check -o inline:"/\n" dirname /
atf_check -o inline:"/\n" dirname //

View File

@ -164,7 +164,7 @@ genkeys(char *public, char *secret)
MINT *pk = mp_itom(0);
MINT *sk = mp_itom(0);
MINT *tmp;
MINT *base = mp_itom(BASE);
MINT *base = mp_itom((short)BASE);
MINT *root = mp_itom(PROOT);
MINT *modulus = mp_xtom(HEXMODULUS);
short r;

View File

@ -98,6 +98,7 @@
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "blacklist_client.h"
extern ServerOptions options;
extern Buffer loginmsg;
@ -794,6 +795,7 @@ sshpam_query(void *ctx, char **name, char **info,
free(msg);
return (0);
}
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
error("PAM: %s for %s%.100s from %.100s", msg,
sshpam_authctxt->valid ? "" : "illegal user ",
sshpam_authctxt->user,

View File

@ -75,6 +75,7 @@ __RCSID("$FreeBSD$");
#include "authfile.h"
#include "ssherr.h"
#include "compat.h"
#include "blacklist_client.h"
/* import */
extern ServerOptions options;
@ -292,8 +293,11 @@ auth_log(Authctxt *authctxt, int authenticated, int partial,
authmsg = "Postponed";
else if (partial)
authmsg = "Partial";
else
else {
authmsg = authenticated ? "Accepted" : "Failed";
BLACKLIST_NOTIFY(authenticated ?
BLACKLIST_AUTH_OK : BLACKLIST_AUTH_FAIL);
}
authlog("%s %s%s%s for %s%.100s from %.200s port %d %s%s%s",
authmsg,
@ -640,6 +644,7 @@ getpwnamallow(const char *user)
}
#endif
if (pw == NULL) {
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
logit("Invalid user %.100s from %.100s",
user, get_remote_ipaddr());
#ifdef CUSTOM_FAILED_LOGIN

View File

@ -43,6 +43,7 @@
#endif
#include "monitor_wrap.h"
#include "buffer.h"
#include "blacklist_client.h"
/* import */
extern ServerOptions options;
@ -337,6 +338,7 @@ do_authloop(Authctxt *authctxt)
char *msg;
size_t len;
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
error("Access denied for user %s by PAM account "
"configuration", authctxt->user);
len = buffer_len(&loginmsg);
@ -404,6 +406,7 @@ do_authentication(Authctxt *authctxt)
else {
debug("do_authentication: invalid user %s", user);
authctxt->pw = fakepw();
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
}
/* Configuration may have changed as a result of Match */

View File

@ -52,6 +52,7 @@ __RCSID("$FreeBSD$");
#include "pathnames.h"
#include "buffer.h"
#include "canohost.h"
#include "blacklist_client.h"
#ifdef GSSAPI
#include "ssh-gss.h"
@ -248,6 +249,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
} else {
logit("input_userauth_request: invalid user %s", user);
authctxt->pw = fakepw();
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_INVALID_USER));
#endif

View File

@ -0,0 +1,97 @@
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
* Copyright (c) 2016 The FreeBSD Foundation, Inc.
* All rights reserved.
*
* Portions of this software were developed by Kurt Lidl
* under sponsorship from the FreeBSD Foundation.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include "ssh.h"
#include "packet.h"
#include "log.h"
#include "misc.h"
#include "servconf.h"
#include "blacklist_client.h"
#include <blacklist.h>
static struct blacklist *blstate = NULL;
/* import */
extern ServerOptions options;
/* internal definition from bl.h */
struct blacklist *bl_create(bool, char *, void (*)(int, const char *, va_list));
/* impedence match vsyslog() to sshd's internal logging levels */
void
im_log(int priority, const char *message, va_list args)
{
LogLevel imlevel;
switch (priority) {
case LOG_ERR:
imlevel = SYSLOG_LEVEL_ERROR;
break;
case LOG_DEBUG:
imlevel = SYSLOG_LEVEL_DEBUG1;
break;
case LOG_INFO:
imlevel = SYSLOG_LEVEL_INFO;
break;
default:
imlevel = SYSLOG_LEVEL_DEBUG2;
}
do_log(imlevel, message, args);
}
void
blacklist_init(void)
{
if (options.use_blacklist)
blstate = bl_create(false, NULL, im_log);
}
void
blacklist_notify(int action)
{
if (blstate != NULL && packet_connection_is_on_socket())
(void)blacklist_r(blstate, action,
packet_get_connection_in(), "ssh");
}

View File

@ -0,0 +1,57 @@
/*-
* Copyright (c) 2015 The NetBSD Foundation, Inc.
* Copyright (c) 2016 The FreeBSD Foundation, Inc.
* All rights reserved.
*
* Portions of this software were developed by Kurt Lidl
* under sponsorship from the FreeBSD Foundation.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BLACKLIST_CLIENT_H
#define BLACKLIST_CLIENT_H
enum {
BLACKLIST_AUTH_OK = 0,
BLACKLIST_AUTH_FAIL
};
#ifdef USE_BLACKLIST
void blacklist_init(void);
void blacklist_notify(int);
#define BLACKLIST_INIT() blacklist_init()
#define BLACKLIST_NOTIFY(x) blacklist_notify(x)
#else
#define BLACKLIST_INIT()
#define BLACKLIST_NOTIFY(x)
#endif
#endif /* BLACKLIST_CLIENT_H */

View File

@ -86,6 +86,7 @@ __RCSID("$FreeBSD$");
#include "packet.h"
#include "ssherr.h"
#include "sshbuf.h"
#include "blacklist_client.h"
#ifdef PACKET_DEBUG
#define DBG(x) x
@ -2071,6 +2072,7 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
case SSH_ERR_NO_KEX_ALG_MATCH:
case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
if (ssh && ssh->kex && ssh->kex->failed_choice) {
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
fatal("Unable to negotiate with %.200s port %d: %s. "
"Their offer: %s", ssh_remote_ipaddr(ssh),
ssh_remote_port(ssh), ssh_err(r),

View File

@ -172,6 +172,7 @@ initialize_server_options(ServerOptions *options)
options->ip_qos_bulk = -1;
options->version_addendum = NULL;
options->fingerprint_hash = -1;
options->use_blacklist = -1;
}
/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
@ -360,6 +361,8 @@ fill_default_server_options(ServerOptions *options)
options->fwd_opts.streamlocal_bind_unlink = 0;
if (options->fingerprint_hash == -1)
options->fingerprint_hash = SSH_FP_HASH_DEFAULT;
if (options->use_blacklist == -1)
options->use_blacklist = 0;
assemble_algorithms(options);
@ -437,6 +440,7 @@ typedef enum {
sAuthenticationMethods, sHostKeyAgent, sPermitUserRC,
sStreamLocalBindMask, sStreamLocalBindUnlink,
sAllowStreamLocalForwarding, sFingerprintHash,
sUseBlacklist,
sDeprecated, sUnsupported
} ServerOpCodes;
@ -579,6 +583,7 @@ static struct {
{ "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL },
{ "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL },
{ "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL },
{ "useblacklist", sUseBlacklist, SSHCFG_GLOBAL },
{ "noneenabled", sUnsupported, SSHCFG_ALL },
{ "hpndisabled", sDeprecated, SSHCFG_ALL },
{ "hpnbuffersize", sDeprecated, SSHCFG_ALL },
@ -1861,6 +1866,10 @@ process_server_config_line(ServerOptions *options, char *line,
options->fingerprint_hash = value;
break;
case sUseBlacklist:
intptr = &options->use_blacklist;
goto parse_flag;
case sDeprecated:
logit("%s line %d: Deprecated option %s",
filename, linenum, arg);
@ -2304,6 +2313,7 @@ dump_config(ServerOptions *o)
dump_cfg_fmtint(sAllowStreamLocalForwarding, o->allow_streamlocal_forwarding);
dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash);
dump_cfg_fmtint(sUseBlacklist, o->use_blacklist);
/* string arguments */
dump_cfg_string(sPidFile, o->pid_file);

View File

@ -195,6 +195,7 @@ typedef struct {
char *auth_methods[MAX_AUTH_METHODS];
int fingerprint_hash;
int use_blacklist;
} ServerOptions;
/* Information about the incoming connection as used by Match */

View File

@ -135,6 +135,7 @@ __RCSID("$FreeBSD$");
#include "ssh-sandbox.h"
#include "version.h"
#include "ssherr.h"
#include "blacklist_client.h"
#ifdef LIBWRAP
#include <tcpd.h>
@ -388,6 +389,8 @@ grace_alarm_handler(int sig)
kill(0, SIGTERM);
}
BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL);
/* Log error and exit. */
sigdie("Timeout before authentication for %s", get_remote_ipaddr());
}
@ -2251,6 +2254,8 @@ main(int ac, char **av)
buffer_init(&loginmsg);
auth_debug_reset();
BLACKLIST_INIT();
if (use_privsep) {
if (privsep_preauth(authctxt) == 1)
goto authenticated;

View File

@ -120,6 +120,7 @@
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#UseBlacklist no
#VersionAddendum FreeBSD-20160310
# no default banner path

View File

@ -1537,6 +1537,15 @@ for authentication using
.Cm TrustedUserCAKeys .
For more details on certificates, see the CERTIFICATES section in
.Xr ssh-keygen 1 .
.It Cm UseBlacklist
Specifies whether
.Xr sshd 8
attempts to send authentication success and failure messages
to the
.Xr blacklistd 8
daemon.
The default is
.Dq no .
.It Cm UseDNS
Specifies whether
.Xr sshd 8

View File

@ -35,15 +35,15 @@ SHLIB_MAJOR= 2
# libatf-c++ depends on the C version of the ATF library to build.
LIBADD+= atf_c
LDFLAGS+= -L${.OBJDIR}/../libatf-c
LDFLAGS+= -L${.OBJDIR:H}/libatf-c
ATF= ${.CURDIR:H:H:H}/contrib/atf
ATF= ${SRCTOP}/contrib/atf
.PATH: ${ATF}
.PATH: ${ATF}/atf-c++
.PATH: ${ATF}/atf-c++/detail
CFLAGS+= -I${ATF}
CFLAGS+= -I${.CURDIR}/../libatf-c
CFLAGS+= -I${.CURDIR:H}/libatf-c
CFLAGS+= -I.
CFLAGS+= -DHAVE_CONFIG_H

View File

@ -28,25 +28,25 @@
.include <src.opts.mk>
.include <bsd.init.mk>
_CFLAGS:= ${CFLAGS}
_CPPFLAGS:= ${CPPFLAGS}
_CXXFLAGS:= ${CXXFLAGS}
ATF_BUILD_CFLAGS:= ${CFLAGS:M-[DILOWf]*}
ATF_BUILD_CPPFLAGS:= ${CPPFLAGS:M-[DILOWf]*}
ATF_BUILD_CXXFLAGS:= ${CXXFLAGS:M-[DILOWf]*}
LIB= atf-c
PRIVATELIB= true
SHLIB_MAJOR= 1
ATF= ${.CURDIR:H:H:H}/contrib/atf
ATF= ${SRCTOP}/contrib/atf
.PATH: ${ATF}
.PATH: ${ATF}/atf-c
.PATH: ${ATF}/atf-c/detail
CFLAGS+= -DATF_BUILD_CC='"${CC}"'
CFLAGS+= -DATF_BUILD_CFLAGS='"${_CFLAGS}"'
CFLAGS+= -DATF_BUILD_CFLAGS='"${ATF_BUILD_CFLAGS}"'
CFLAGS+= -DATF_BUILD_CPP='"${CPP}"'
CFLAGS+= -DATF_BUILD_CPPFLAGS='"${_CPPFLAGS}"'
CFLAGS+= -DATF_BUILD_CPPFLAGS='"${ATF_BUILD_CPPFLAGS}"'
CFLAGS+= -DATF_BUILD_CXX='"${CXX}"'
CFLAGS+= -DATF_BUILD_CXXFLAGS='"${_CXXFLAGS}"'
CFLAGS+= -DATF_BUILD_CXXFLAGS='"${ATF_BUILD_CXXFLAGS}"'
CFLAGS+= -I${ATF}
CFLAGS+= -I${.CURDIR}
CFLAGS+= -I.

View File

@ -25,12 +25,13 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 27, 2016
.Dd August 29, 2016
.Dt DEVCTL 3
.Os
.Sh NAME
.Nm devctl ,
.Nm devctl_attach ,
.Nm devctl_clear_driver ,
.Nm devctl_delete ,
.Nm devctl_detach ,
.Nm devctl_disable ,
@ -47,6 +48,8 @@
.Ft int
.Fn devctl_attach "const char *device"
.Ft int
.Fn devctl_clear_driver "const char *device" "bool force"
.Ft int
.Fn devctl_delete "const char *device" "bool force"
.Ft int
.Fn devctl_detach "const char *device" "bool force"
@ -166,12 +169,30 @@ the device will be detached from its current device driver before it is
attached to the new device driver.
.Pp
The
.Fn devctl_clear_driver
function resets a device so that it can be attached to any valid device
driver rather than only drivers with a previously specified name.
This function is used to undo a previous call to
.Fn devctl_set_driver .
If the device is already attached and
.Fa force
is false,
the request will fail.
If the device is already attached and
.Fa force
is true,
the device will be detached from its current device driver.
After the device's name is reset,
it is reprobed and attached to a suitable device driver if one is found.
.Pp
The
.Fn devctl_rescan
function rescans a bus device checking for devices that have been added or
removed.
.Sh RETURN VALUES
.Rv -std devctl_attach devctl_delete devctl_detach devctl_disable \
devctl_enable devctl_suspend devctl_rescan devctl_resume devctl_set_driver
.Rv -std devctl_attach devctl_clear_driver devctl_delete devctl_detach \
devctl_disable devctl_enable devctl_suspend devctl_rescan devctl_resume \
devctl_set_driver
.Sh ERRORS
In addition to specific errors noted below,
all of the
@ -302,6 +323,24 @@ The new device driver failed to attach.
.El
.Pp
The
.Fn devctl_clear_driver
function may fail if:
.Bl -tag -width Er
.It Bq Er EBUSY
The device is currently attached to a device driver and
.Fa force
is false.
.It Bq Er EBUSY
The current device driver for
.Fa device
is busy and cannot detach at this time.
.It Bq Er EINVAL
The device is not configured for a specific device driver name.
.It Bq Er ENXIO
The device driver chosen after reprobing failed to attach.
.El
.Pp
The
.Fn devctl_rescan
function may fail if:
.Bl -tag -width Er

View File

@ -123,6 +123,14 @@ devctl_set_driver(const char *device, const char *driver, bool force)
return (devctl_request(DEV_SET_DRIVER, &req));
}
int
devctl_clear_driver(const char *device, bool force)
{
return (devctl_simple_request(DEV_CLEAR_DRIVER, device, force ?
DEVF_CLEAR_DRIVER_DETACH : 0));
}
int
devctl_rescan(const char *device)
{

View File

@ -38,6 +38,7 @@ int devctl_disable(const char *device, bool force_detach);
int devctl_suspend(const char *device);
int devctl_resume(const char *device);
int devctl_set_driver(const char *device, const char *driver, bool force);
int devctl_clear_driver(const char *device, bool force);
int devctl_rescan(const char *device);
int devctl_delete(const char *device, bool force);

View File

@ -313,15 +313,8 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
bpb.bpbHiddenSecs = o.hidden_sectors;
if (!(o.floppy || (o.drive_heads && o.sectors_per_track &&
o.bytes_per_sector && o.size && o.hidden_sectors_set))) {
off_t delta;
getdiskinfo(fd, fname, dtype, o.hidden_sectors_set, &bpb);
bpb.bpbHugeSectors -= (o.offset / bpb.bpbBytesPerSec);
delta = bpb.bpbHugeSectors % bpb.bpbSecPerTrack;
if (delta != 0) {
warnx("trim %d sectors to adjust to a multiple of %d",
(int)delta, bpb.bpbSecPerTrack);
bpb.bpbHugeSectors -= delta;
}
if (bpb.bpbSecPerClust == 0) { /* set defaults */
if (bpb.bpbHugeSectors <= 6000) /* about 3MB -> 512 bytes */
bpb.bpbSecPerClust = 1;
@ -563,7 +556,7 @@ mkfs_msdos(const char *fname, const char *dtype, const struct msdos_options *op)
bpb.bpbMedia = !bpb.bpbHiddenSecs ? 0xf0 : 0xf8;
if (fat == 32)
bpb.bpbRootClust = RESFTE;
if (bpb.bpbHiddenSecs + bpb.bpbHugeSectors <= MAXU16) {
if (bpb.bpbHugeSectors <= MAXU16) {
bpb.bpbSectors = bpb.bpbHugeSectors;
bpb.bpbHugeSectors = 0;
}

View File

@ -40,6 +40,13 @@ CFLAGS+= -DUSE_BSM_AUDIT -DHAVE_GETAUDIT_ADDR
LIBADD+= bsm
.endif
.if ${MK_BLACKLIST_SUPPORT} != "no"
CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include
SRCS+= blacklist.c
LIBADD+= blacklist
LDFLAGS+=-L${LIBBLACKLISTDIR}
.endif
.if ${MK_KERBEROS_SUPPORT} != "no"
CFLAGS+= -include krb5_config.h
SRCS+= krb5_config.h

View File

@ -17,6 +17,7 @@ DIRDEPS = \
kerberos5/lib/libroken \
kerberos5/lib/libwind \
lib/${CSU_DIR} \
lib/libblacklist \
lib/libbsm \
lib/libc \
lib/libcom_err \

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 29, 2016
.Dd August 30, 2016
.Dt MBUF 9
.Os
.\"
@ -255,7 +255,7 @@ The available external buffer types are defined as follows:
#define EXT_JUMBO9 4 /* jumbo cluster 9216 bytes */
#define EXT_JUMBO16 5 /* jumbo cluster 16184 bytes */
#define EXT_PACKET 6 /* mbuf+cluster from packet zone */
#define EXT_MBUF 7 /* external mbuf reference (M_IOVEC) */
#define EXT_MBUF 7 /* external mbuf reference */
#define EXT_NET_DRV 252 /* custom ext_buf provided by net driver(s) */
#define EXT_MOD_TYPE 253 /* custom module's ext_buf type */
#define EXT_DISPOSABLE 254 /* can throw this buffer away w/page flipping */

View File

@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/watchdog.h>
#include <sys/reboot.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@ -54,6 +55,7 @@ __FBSDID("$FreeBSD$");
#define A10_WDOG_CTRL 0x00
#define A31_WDOG_CTRL 0x10
#define WDOG_CTRL_RESTART (1 << 0)
#define A31_WDOG_CTRL_KEY (0xa57 << 1)
#define A10_WDOG_MODE 0x04
#define A31_WDOG_MODE 0x18
#define A10_WDOG_MODE_INTVL_SHIFT 3
@ -92,6 +94,7 @@ struct aw_wdog_softc {
struct resource * res;
struct mtx mtx;
uint8_t wdog_ctrl;
uint32_t wdog_ctrl_key;
uint8_t wdog_mode;
uint8_t wdog_mode_intvl_shift;
uint8_t wdog_mode_en;
@ -108,7 +111,8 @@ static struct ofw_compat_data compat_data[] = {
{NULL, 0}
};
static void aw_wdog_watchdog_fn(void *private, u_int cmd, int *error);
static void aw_wdog_watchdog_fn(void *, u_int, int *);
static void aw_wdog_shutdown_fn(void *, int);
static int
aw_wdog_probe(device_t dev)
@ -160,6 +164,7 @@ aw_wdog_attach(device_t dev)
break;
case A31_WATCHDOG:
sc->wdog_ctrl = A31_WDOG_CTRL;
sc->wdog_ctrl_key = A31_WDOG_CTRL_KEY;
sc->wdog_mode = A31_WDOG_MODE;
sc->wdog_mode_intvl_shift = A31_WDOG_MODE_INTVL_SHIFT;
sc->wdog_mode_en = WDOG_MODE_EN;
@ -173,6 +178,9 @@ aw_wdog_attach(device_t dev)
mtx_init(&sc->mtx, "AW Watchdog", "aw_wdog", MTX_DEF);
EVENTHANDLER_REGISTER(watchdog_list, aw_wdog_watchdog_fn, sc, 0);
EVENTHANDLER_REGISTER(shutdown_final, aw_wdog_shutdown_fn, sc,
SHUTDOWN_PRI_LAST - 1);
return (0);
}
@ -198,7 +206,8 @@ aw_wdog_watchdog_fn(void *private, u_int cmd, int *error)
WRITE(sc, sc->wdog_mode,
(wd_intervals[i].value << sc->wdog_mode_intvl_shift) |
sc->wdog_mode_en);
WRITE(sc, sc->wdog_ctrl, WDOG_CTRL_RESTART);
WRITE(sc, sc->wdog_ctrl,
WDOG_CTRL_RESTART | sc->wdog_ctrl_key);
if (sc->wdog_config)
WRITE(sc, sc->wdog_config,
sc->wdog_config_value);
@ -222,6 +231,13 @@ aw_wdog_watchdog_fn(void *private, u_int cmd, int *error)
mtx_unlock(&sc->mtx);
}
static void
aw_wdog_shutdown_fn(void *private, int howto)
{
if ((howto & (RB_POWEROFF|RB_HALT)) == 0)
aw_wdog_watchdog_reset();
}
void
aw_wdog_watchdog_reset()
{
@ -237,6 +253,8 @@ aw_wdog_watchdog_reset()
if (aw_wdog_sc->wdog_config)
WRITE(aw_wdog_sc, aw_wdog_sc->wdog_config,
aw_wdog_sc->wdog_config_value);
WRITE(aw_wdog_sc, aw_wdog_sc->wdog_ctrl,
WDOG_CTRL_RESTART | aw_wdog_sc->wdog_ctrl_key);
while(1)
;

View File

@ -310,7 +310,9 @@ ti_pruss_kqfilter(struct cdev *cdev, struct knote *kn)
case EVFILT_READ:
kn->kn_hook = sc;
kn->kn_fop = &ti_pruss_kq_read;
mtx_lock(&sc->sc_mtx);
knlist_add(&sc->sc_selinfo.si_note, kn, 1);
mtx_unlock(&sc->sc_mtx);
break;
default:
return (EINVAL);

View File

@ -2936,14 +2936,17 @@ validate:
PTE_SYNC(l3);
pmap_invalidate_page(pmap, va);
if ((pmap != pmap_kernel()) && (pmap == &curproc->p_vmspace->vm_pmap))
cpu_icache_sync_range(va, PAGE_SIZE);
if (pmap != pmap_kernel()) {
if (pmap == &curproc->p_vmspace->vm_pmap)
cpu_icache_sync_range(va, PAGE_SIZE);
if ((mpte == NULL || mpte->wire_count == NL3PG) &&
pmap_superpages_enabled() && (m->flags & PG_FICTITIOUS) == 0 &&
vm_reserv_level_iffullpop(m) == 0) {
KASSERT(lvl == 2, ("Invalid pde level %d", lvl));
pmap_promote_l2(pmap, pde, va, &lock);
if ((mpte == NULL || mpte->wire_count == NL3PG) &&
pmap_superpages_enabled() &&
(m->flags & PG_FICTITIOUS) == 0 &&
vm_reserv_level_iffullpop(m) == 0) {
KASSERT(lvl == 2, ("Invalid pde level %d", lvl));
pmap_promote_l2(pmap, pde, va, &lock);
}
}
if (lock != NULL)

View File

@ -137,7 +137,9 @@ ofw_init(void *vpd, int res, int (*openfirm)(void *), char *arg, int argl)
p = bootpath;
while (*p != '\0') {
/* Truncate partition ID */
if (*p == ':') {
ofw_close(bootdev);
*(++p) = '\0';
break;
}
@ -419,31 +421,40 @@ main(int ac, char **av)
memcpy(bootpath_full,bootpath,len+1);
if (bootpath_full[len-1] == ':') {
for (i = 0; i < 16; i++) {
if (i < 10) {
bootpath_full[len] = i + '0';
bootpath_full[len+1] = '\0';
} else {
bootpath_full[len] = '1';
bootpath_full[len+1] = i - 10 + '0';
bootpath_full[len+2] = '\0';
}
if (domount(bootpath_full,1) >= 0)
break;
if (bootpath_full[len-1] != ':') {
/* First try full volume */
if (domount(bootpath_full,1) == 0)
goto out;
if (bootdev > 0)
ofw_close(bootdev);
}
if (i >= 16)
panic("domount");
} else {
if (domount(bootpath_full,0) == -1)
panic("domount");
/* Add a : so that we try partitions if that fails */
if (bootdev > 0)
ofw_close(bootdev);
bootpath_full[len] = ':';
len += 1;
}
/* Loop through first 16 partitions to find a UFS one */
for (i = 0; i < 16; i++) {
if (i < 10) {
bootpath_full[len] = i + '0';
bootpath_full[len+1] = '\0';
} else {
bootpath_full[len] = '1';
bootpath_full[len+1] = i - 10 + '0';
bootpath_full[len+2] = '\0';
}
if (domount(bootpath_full,1) >= 0)
break;
if (bootdev > 0)
ofw_close(bootdev);
}
if (i >= 16)
panic("domount");
out:
printf(" Boot volume: %s\n",bootpath_full);
ofw_setprop(chosenh, "bootargs", bootpath_full, len+2);
load(path);

View File

@ -209,10 +209,15 @@ static int
t4iov_detach(device_t dev)
{
struct t4iov_softc *sc;
int error;
sc = device_get_softc(dev);
if (sc->sc_attached)
return (t4iov_detach_child(dev));
if (sc->sc_attached) {
error = t4iov_detach_child(dev);
if (error)
return (error);
}
device_verbose(dev);
return (0);
}

View File

@ -74,8 +74,6 @@ static void hv_nv_on_receive(struct hn_softc *sc,
static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
struct hn_softc *, struct vmbus_channel *chan,
const void *, int);
static void hn_nvs_sent_xact(struct hn_send_ctx *, struct hn_softc *sc,
struct vmbus_channel *, const void *, int);
struct hn_send_ctx hn_send_ctx_none =
HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
@ -643,7 +641,7 @@ cleanup:
* Net VSC on device remove
*/
int
hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
hv_nv_on_device_remove(struct hn_softc *sc)
{
hv_nv_disconnect_from_vsp(sc);
@ -655,7 +653,7 @@ hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
return (0);
}
static void
void
hn_nvs_sent_xact(struct hn_send_ctx *sndc,
struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
const void *data, int dlen)

View File

@ -237,8 +237,8 @@ typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *);
#define TRANSPORT_TYPE_IPV6_UDP ((TYPE_IPV6 << 16) | TYPE_UDP)
typedef struct {
uint8_t mac_addr[6]; /* Assumption unsigned long */
uint8_t link_state;
uint8_t mac_addr[ETHER_ADDR_LEN];
uint32_t link_state;
} netvsc_device_info;
#define HN_XACT_REQ_PGCNT 2
@ -351,7 +351,6 @@ typedef struct hn_softc {
int hn_initdone;
/* See hv_netvsc_drv_freebsd.c for rules on how to use */
int temp_unusable;
struct rndis_device_ *rndis_dev;
struct vmbus_channel *hn_prichan;
int hn_rx_ring_cnt;
@ -400,8 +399,7 @@ struct hn_send_ctx;
void netvsc_linkstatus_callback(struct hn_softc *sc, uint32_t status);
int hv_nv_on_device_add(struct hn_softc *sc, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
int hv_nv_on_device_remove(struct hn_softc *sc);
int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
void hv_nv_subchan_attach(struct vmbus_channel *chan,

View File

@ -154,8 +154,8 @@ __FBSDID("$FreeBSD$");
#define HN_TX_DATA_BOUNDARY PAGE_SIZE
#define HN_TX_DATA_MAXSIZE IP_MAXPACKET
#define HN_TX_DATA_SEGSIZE PAGE_SIZE
#define HN_TX_DATA_SEGCNT_MAX \
(NETVSC_PACKET_MAXPAGE - HV_RF_NUM_TX_RESERVED_PAGE_BUFS)
/* -1 for RNDIS packet message */
#define HN_TX_DATA_SEGCNT_MAX (NETVSC_PACKET_MAXPAGE - 1)
#define HN_DIRECT_TX_SIZE_DEF 128
@ -651,7 +651,7 @@ netvsc_detach(device_t dev)
* the netdevice.
*/
hv_rf_on_device_remove(sc, HV_RF_NV_DESTROY_CHANNEL);
hv_rf_on_device_remove(sc);
hn_stop_tx_tasks(sc);
@ -1029,7 +1029,8 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
}
*m_head0 = m_head;
txr->hn_gpa_cnt = nsegs + HV_RF_NUM_TX_RESERVED_PAGE_BUFS;
/* +1 RNDIS packet message */
txr->hn_gpa_cnt = nsegs + 1;
/* send packet with page buffer */
txr->hn_gpa[0].gpa_page = atop(txd->rndis_msg_paddr);
@ -1037,12 +1038,11 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
txr->hn_gpa[0].gpa_len = rndis_msg_size;
/*
* Fill the page buffers with mbuf info starting at index
* HV_RF_NUM_TX_RESERVED_PAGE_BUFS.
* Fill the page buffers with mbuf info after the page
* buffer for RNDIS packet message.
*/
for (i = 0; i < nsegs; ++i) {
struct vmbus_gpa *gpa = &txr->hn_gpa[
i + HV_RF_NUM_TX_RESERVED_PAGE_BUFS];
struct vmbus_gpa *gpa = &txr->hn_gpa[i + 1];
gpa->gpa_page = atop(segs[i].ds_addr);
gpa->gpa_ofs = segs[i].ds_addr & PAGE_MASK;
@ -1576,7 +1576,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
* MTU to take effect. This includes tearing down, but not
* deleting the channel, then bringing it back up.
*/
error = hv_rf_on_device_remove(sc, HV_RF_NV_RETAIN_CHANNEL);
error = hv_rf_on_device_remove(sc);
if (error) {
NV_LOCK(sc);
sc->temp_unusable = FALSE;

View File

@ -889,19 +889,6 @@ typedef struct rndismp_rx_bufs_info_ {
#define RNDIS_HEADER_SIZE (sizeof(rndis_msg) - sizeof(rndis_msg_container))
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
#define NDIS_PACKET_TYPE_SMT 0x00000040
#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
#define NDIS_PACKET_TYPE_GROUP 0x00000100
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00000200
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00000400
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00000800
/*
* Externs
*/

View File

@ -71,30 +71,15 @@ __FBSDID("$FreeBSD$");
/*
* Forward declarations
*/
static int hv_rf_send_request(rndis_device *device, rndis_request *request,
uint32_t message_type);
static void hv_rf_receive_response(rndis_device *device,
const rndis_msg *response);
static void hv_rf_receive_indicate_status(rndis_device *device,
static void hv_rf_receive_indicate_status(struct hn_softc *sc,
const rndis_msg *response);
static void hv_rf_receive_data(struct hn_rx_ring *rxr,
const void *data, int dlen);
static inline int hv_rf_query_device_mac(rndis_device *device);
static inline int hv_rf_query_device_link_status(rndis_device *device);
static int hv_rf_set_packet_filter(rndis_device *device, uint32_t new_filter);
static int hv_rf_init_device(rndis_device *device);
static int hv_rf_open_device(rndis_device *device);
static int hv_rf_close_device(rndis_device *device);
int
hv_rf_send_offload_request(struct hn_softc *sc,
rndis_offload_params *offloads);
static int hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr);
static int hv_rf_query_device_link_status(struct hn_softc *sc,
uint32_t *link_status);
static int hv_rf_init_device(struct hn_softc *sc);
static void hn_rndis_sent_halt(struct hn_send_ctx *sndc,
struct hn_softc *sc, struct vmbus_channel *chan,
const void *data, int dlen);
static void hn_rndis_sent_cb(struct hn_send_ctx *sndc,
struct hn_softc *sc, struct vmbus_channel *chan,
const void *data, int dlen);
static int hn_rndis_query(struct hn_softc *sc, uint32_t oid,
const void *idata, size_t idlen, void *odata, size_t *odlen0);
static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data,
@ -171,280 +156,24 @@ hv_get_ppi_data(rndis_packet *rpkt, uint32_t type)
return (NULL);
}
/*
* Allow module_param to work and override to switch to promiscuous mode.
*/
static inline rndis_device *
hv_get_rndis_device(void)
{
rndis_device *device;
device = malloc(sizeof(rndis_device), M_NETVSC, M_WAITOK | M_ZERO);
mtx_init(&device->req_lock, "HV-FRL", NULL, MTX_DEF);
/* Same effect as STAILQ_HEAD_INITIALIZER() static initializer */
STAILQ_INIT(&device->myrequest_list);
device->state = RNDIS_DEV_UNINITIALIZED;
return (device);
}
/*
*
*/
static inline void
hv_put_rndis_device(rndis_device *device)
{
mtx_destroy(&device->req_lock);
free(device, M_NETVSC);
}
/*
*
*/
static inline rndis_request *
hv_rndis_request(rndis_device *device, uint32_t message_type,
uint32_t message_length)
{
rndis_request *request;
rndis_msg *rndis_mesg;
rndis_set_request *set;
request = malloc(sizeof(rndis_request), M_NETVSC, M_WAITOK | M_ZERO);
sema_init(&request->wait_sema, 0, "rndis sema");
rndis_mesg = &request->request_msg;
rndis_mesg->ndis_msg_type = message_type;
rndis_mesg->msg_len = message_length;
/*
* Set the request id. This field is always after the rndis header
* for request/response packet types so we just use the set_request
* as a template.
*/
set = &rndis_mesg->msg.set_request;
set->request_id = atomic_fetchadd_int(&device->new_request_id, 1) &
HN_RNDIS_RID_COMPAT_MASK;
/* Add to the request list */
mtx_lock(&device->req_lock);
STAILQ_INSERT_TAIL(&device->myrequest_list, request, mylist_entry);
mtx_unlock(&device->req_lock);
return (request);
}
/*
*
*/
static inline void
hv_put_rndis_request(rndis_device *device, rndis_request *request)
{
mtx_lock(&device->req_lock);
/* Fixme: Has O(n) performance */
/*
* XXXKYS: Use Doubly linked lists.
*/
STAILQ_REMOVE(&device->myrequest_list, request, rndis_request_,
mylist_entry);
mtx_unlock(&device->req_lock);
sema_destroy(&request->wait_sema);
free(request, M_NETVSC);
}
/*
*
*/
static int
hv_rf_send_request(rndis_device *device, rndis_request *request,
uint32_t message_type)
{
struct hn_softc *sc = device->sc;
uint32_t send_buf_section_idx, tot_data_buf_len;
struct vmbus_gpa gpa[2];
int gpa_cnt, send_buf_section_size;
hn_sent_callback_t cb;
/* Set up the packet to send it */
tot_data_buf_len = request->request_msg.msg_len;
gpa_cnt = 1;
gpa[0].gpa_page = hv_get_phys_addr(&request->request_msg) >> PAGE_SHIFT;
gpa[0].gpa_len = request->request_msg.msg_len;
gpa[0].gpa_ofs = (unsigned long)&request->request_msg & (PAGE_SIZE - 1);
if (gpa[0].gpa_ofs + gpa[0].gpa_len > PAGE_SIZE) {
gpa_cnt = 2;
gpa[0].gpa_len = PAGE_SIZE - gpa[0].gpa_ofs;
gpa[1].gpa_page =
hv_get_phys_addr((char*)&request->request_msg +
gpa[0].gpa_len) >> PAGE_SHIFT;
gpa[1].gpa_ofs = 0;
gpa[1].gpa_len = request->request_msg.msg_len - gpa[0].gpa_len;
}
if (message_type != REMOTE_NDIS_HALT_MSG)
cb = hn_rndis_sent_cb;
else
cb = hn_rndis_sent_halt;
if (tot_data_buf_len < sc->hn_chim_szmax) {
send_buf_section_idx = hn_chim_alloc(sc);
if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
uint8_t *dest = sc->hn_chim +
(send_buf_section_idx * sc->hn_chim_szmax);
memcpy(dest, &request->request_msg, request->request_msg.msg_len);
send_buf_section_size = tot_data_buf_len;
gpa_cnt = 0;
goto sendit;
}
/* Failed to allocate chimney send buffer; move on */
}
send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
sendit:
hn_send_ctx_init(&request->send_ctx, cb, request,
send_buf_section_idx, send_buf_section_size);
return hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL,
&request->send_ctx, gpa, gpa_cnt);
}
/*
* RNDIS filter receive response
*/
static void
hv_rf_receive_response(rndis_device *device, const rndis_msg *response)
{
rndis_request *request = NULL;
rndis_request *next_request;
boolean_t found = FALSE;
mtx_lock(&device->req_lock);
request = STAILQ_FIRST(&device->myrequest_list);
while (request != NULL) {
/*
* All request/response message contains request_id as the
* first field
*/
if (request->request_msg.msg.init_request.request_id ==
response->msg.init_complete.request_id) {
found = TRUE;
break;
}
next_request = STAILQ_NEXT(request, mylist_entry);
request = next_request;
}
mtx_unlock(&device->req_lock);
if (found) {
if (response->msg_len <= sizeof(rndis_msg)) {
memcpy(&request->response_msg, response,
response->msg_len);
} else {
request->response_msg.msg.init_complete.status =
RNDIS_STATUS_BUFFER_OVERFLOW;
}
sema_post(&request->wait_sema);
}
}
int
hv_rf_send_offload_request(struct hn_softc *sc,
rndis_offload_params *offloads)
{
rndis_request *request;
rndis_set_request *set;
rndis_offload_params *offload_req;
rndis_set_complete *set_complete;
rndis_device *rndis_dev = sc->rndis_dev;
device_t dev = sc->hn_dev;
uint32_t extlen = sizeof(rndis_offload_params);
int ret;
if (sc->hn_nvs_ver <= NVSP_PROTOCOL_VERSION_4) {
extlen = VERSION_4_OFFLOAD_SIZE;
/* On NVSP_PROTOCOL_VERSION_4 and below, we do not support
* UDP checksum offload.
*/
offloads->udp_ipv4_csum = 0;
offloads->udp_ipv6_csum = 0;
}
request = hv_rndis_request(rndis_dev, REMOTE_NDIS_SET_MSG,
RNDIS_MESSAGE_SIZE(rndis_set_request) + extlen);
if (!request)
return (ENOMEM);
set = &request->request_msg.msg.set_request;
set->oid = RNDIS_OID_TCP_OFFLOAD_PARAMETERS;
set->info_buffer_length = extlen;
set->info_buffer_offset = sizeof(rndis_set_request);
set->device_vc_handle = 0;
offload_req = (rndis_offload_params *)((unsigned long)set +
set->info_buffer_offset);
*offload_req = *offloads;
offload_req->header.type = RNDIS_OBJECT_TYPE_DEFAULT;
offload_req->header.revision = RNDIS_OFFLOAD_PARAMETERS_REVISION_3;
offload_req->header.size = extlen;
ret = hv_rf_send_request(rndis_dev, request, REMOTE_NDIS_SET_MSG);
if (ret != 0) {
device_printf(dev, "hv send offload request failed, ret=%d!\n",
ret);
goto cleanup;
}
ret = sema_timedwait(&request->wait_sema, 5 * hz);
if (ret != 0) {
device_printf(dev, "hv send offload request timeout\n");
goto cleanup;
}
set_complete = &request->response_msg.msg.set_complete;
if (set_complete->status == RNDIS_STATUS_SUCCESS) {
device_printf(dev, "hv send offload request succeeded\n");
ret = 0;
} else {
if (set_complete->status == RNDIS_STATUS_NOT_SUPPORTED) {
device_printf(dev, "HV Not support offload\n");
ret = 0;
} else {
ret = set_complete->status;
}
}
cleanup:
hv_put_rndis_request(rndis_dev, request);
return (ret);
}
/*
* RNDIS filter receive indicate status
*/
static void
hv_rf_receive_indicate_status(rndis_device *device, const rndis_msg *response)
hv_rf_receive_indicate_status(struct hn_softc *sc, const rndis_msg *response)
{
const rndis_indicate_status *indicate = &response->msg.indicate_status;
switch(indicate->status) {
case RNDIS_STATUS_MEDIA_CONNECT:
netvsc_linkstatus_callback(device->sc, 1);
netvsc_linkstatus_callback(sc, 1);
break;
case RNDIS_STATUS_MEDIA_DISCONNECT:
netvsc_linkstatus_callback(device->sc, 0);
netvsc_linkstatus_callback(sc, 0);
break;
default:
/* TODO: */
device_printf(device->sc->hn_dev,
if_printf(sc->hn_ifp,
"unknown status %d received\n", indicate->status);
break;
}
@ -574,14 +303,9 @@ int
hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
const void *data, int dlen)
{
rndis_device *rndis_dev;
const rndis_msg *rndis_hdr;
const struct rndis_comp_hdr *comp;
rndis_dev = sc->rndis_dev;
if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED)
return (EINVAL);
rndis_hdr = data;
switch (rndis_hdr->ndis_msg_type) {
/* data message */
@ -595,17 +319,14 @@ hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
case REMOTE_NDIS_SET_CMPLT:
case REMOTE_NDIS_KEEPALIVE_CMPLT:
comp = data;
if (comp->rm_rid <= HN_RNDIS_RID_COMPAT_MAX) {
/* Transition time compat code */
hv_rf_receive_response(rndis_dev, rndis_hdr);
} else {
vmbus_xact_ctx_wakeup(sc->hn_xact, data, dlen);
}
KASSERT(comp->rm_rid > HN_RNDIS_RID_COMPAT_MAX,
("invalid rid 0x%08x\n", comp->rm_rid));
vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen);
break;
/* notification message */
case REMOTE_NDIS_INDICATE_STATUS_MSG:
hv_rf_receive_indicate_status(rndis_dev, rndis_hdr);
hv_rf_receive_indicate_status(sc, rndis_hdr);
break;
case REMOTE_NDIS_RESET_CMPLT:
@ -631,19 +352,18 @@ hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
* RNDIS filter query device MAC address
*/
static int
hv_rf_query_device_mac(rndis_device *device)
hv_rf_query_device_mac(struct hn_softc *sc, uint8_t *eaddr)
{
struct hn_softc *sc = device->sc;
size_t hwaddr_len;
size_t eaddr_len;
int error;
hwaddr_len = ETHER_ADDR_LEN;
eaddr_len = ETHER_ADDR_LEN;
error = hn_rndis_query(sc, OID_802_3_PERMANENT_ADDRESS, NULL, 0,
device->hw_mac_addr, &hwaddr_len);
eaddr, &eaddr_len);
if (error)
return (error);
if (hwaddr_len != ETHER_ADDR_LEN) {
if_printf(sc->hn_ifp, "invalid hwaddr len %zu\n", hwaddr_len);
if (eaddr_len != ETHER_ADDR_LEN) {
if_printf(sc->hn_ifp, "invalid eaddr len %zu\n", eaddr_len);
return (EINVAL);
}
return (0);
@ -652,16 +372,15 @@ hv_rf_query_device_mac(rndis_device *device)
/*
* RNDIS filter query device link status
*/
static inline int
hv_rf_query_device_link_status(rndis_device *device)
static int
hv_rf_query_device_link_status(struct hn_softc *sc, uint32_t *link_status)
{
struct hn_softc *sc = device->sc;
size_t size;
int error;
size = sizeof(uint32_t);
size = sizeof(*link_status);
error = hn_rndis_query(sc, OID_GEN_MEDIA_CONNECT_STATUS, NULL, 0,
&device->link_status, &size);
link_status, &size);
if (error)
return (error);
if (size != sizeof(uint32_t)) {
@ -679,87 +398,16 @@ static uint8_t netvsc_hash_key[NDIS_HASH_KEYSIZE_TOEPLITZ] = {
0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
};
/*
* RNDIS filter set packet filter
* Sends an rndis request with the new filter, then waits for a response
* from the host.
* Returns zero on success, non-zero on failure.
*/
static int
hv_rf_set_packet_filter(rndis_device *device, uint32_t new_filter)
{
rndis_request *request;
rndis_set_request *set;
rndis_set_complete *set_complete;
uint32_t status;
int ret;
request = hv_rndis_request(device, REMOTE_NDIS_SET_MSG,
RNDIS_MESSAGE_SIZE(rndis_set_request) + sizeof(uint32_t));
if (request == NULL) {
ret = -1;
goto cleanup;
}
/* Set up the rndis set */
set = &request->request_msg.msg.set_request;
set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
set->info_buffer_length = sizeof(uint32_t);
set->info_buffer_offset = sizeof(rndis_set_request);
memcpy((void *)((unsigned long)set + sizeof(rndis_set_request)),
&new_filter, sizeof(uint32_t));
ret = hv_rf_send_request(device, request, REMOTE_NDIS_SET_MSG);
if (ret != 0) {
goto cleanup;
}
/*
* Wait for the response from the host. Another thread will signal
* us when the response has arrived. In the failure case,
* sema_timedwait() returns a non-zero status after waiting 5 seconds.
*/
ret = sema_timedwait(&request->wait_sema, 5 * hz);
if (ret == 0) {
/* Response received, check status */
set_complete = &request->response_msg.msg.set_complete;
status = set_complete->status;
if (status != RNDIS_STATUS_SUCCESS) {
/* Bad response status, return error */
ret = -2;
}
} else {
/*
* We cannot deallocate the request since we may still
* receive a send completion for it.
*/
goto exit;
}
cleanup:
if (request != NULL) {
hv_put_rndis_request(device, request);
}
exit:
return (ret);
}
static const void *
hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid,
size_t reqlen, size_t *comp_len0, uint32_t comp_type)
hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen,
struct hn_send_ctx *sndc, size_t *comp_len)
{
struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT];
const struct rndis_comp_hdr *comp;
bus_addr_t paddr;
size_t comp_len, min_complen = *comp_len0;
int gpa_cnt, error;
bus_addr_t paddr;
KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid));
KASSERT(reqlen <= HN_XACT_REQ_SIZE && reqlen > 0,
("invalid request length %zu", reqlen));
KASSERT(min_complen >= sizeof(*comp),
("invalid minimum complete len %zu", min_complen));
/*
* Setup the SG list.
@ -788,14 +436,34 @@ hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid
* message.
*/
vmbus_xact_activate(xact);
error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL,
&hn_send_ctx_none, gpa, gpa_cnt);
error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, sndc,
gpa, gpa_cnt);
if (error) {
vmbus_xact_deactivate(xact);
if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
return (NULL);
}
comp = vmbus_xact_wait(xact, &comp_len);
return (vmbus_xact_wait(xact, comp_len));
}
static const void *
hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid,
size_t reqlen, size_t *comp_len0, uint32_t comp_type)
{
const struct rndis_comp_hdr *comp;
size_t comp_len, min_complen = *comp_len0;
KASSERT(rid > HN_RNDIS_RID_COMPAT_MAX, ("invalid rid %u\n", rid));
KASSERT(min_complen >= sizeof(*comp),
("invalid minimum complete len %zu", min_complen));
/*
* Execute the xact setup by the caller.
*/
comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_send_ctx_none,
&comp_len);
if (comp == NULL)
return (NULL);
/*
* Check this RNDIS complete message.
@ -941,7 +609,7 @@ hn_rndis_get_rsscaps(struct hn_softc *sc, int *rxr_cnt)
in.ndis_hdr.ndis_size = NDIS_RSS_CAPS_SIZE;
caps_len = NDIS_RSS_CAPS_SIZE;
error = hn_rndis_query(sc, OID_GEN_RSS_CAPABILITIES,
error = hn_rndis_query(sc, OID_GEN_RECEIVE_SCALE_CAPABILITIES,
&in, NDIS_RSS_CAPS_SIZE, &caps, &caps_len);
if (error)
return (error);
@ -1092,7 +760,8 @@ hn_rndis_conf_rss(struct hn_softc *sc, int nchan)
for (i = 0; i < NDIS_HASH_INDCNT; ++i)
rss->rss_ind[i] = i % nchan;
error = hn_rndis_set(sc, OID_GEN_RSS_PARAMETERS, rss, sizeof(*rss));
error = hn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS,
rss, sizeof(*rss));
if (error) {
if_printf(sc->hn_ifp, "RSS config failed: %d\n", error);
} else {
@ -1102,13 +771,31 @@ hn_rndis_conf_rss(struct hn_softc *sc, int nchan)
return (error);
}
static int
hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter)
{
int error;
error = hn_rndis_set(sc, OID_GEN_CURRENT_PACKET_FILTER,
&filter, sizeof(filter));
if (error) {
if_printf(sc->hn_ifp, "set RX filter 0x%08x failed: %d\n",
filter, error);
} else {
if (bootverbose) {
if_printf(sc->hn_ifp, "set RX filter 0x%08x done\n",
filter);
}
}
return (error);
}
/*
* RNDIS filter init device
*/
static int
hv_rf_init_device(rndis_device *device)
hv_rf_init_device(struct hn_softc *sc)
{
struct hn_softc *sc = device->sc;
struct rndis_init_req *req;
const struct rndis_init_comp *comp;
struct vmbus_xact *xact;
@ -1116,9 +803,6 @@ hv_rf_init_device(rndis_device *device)
uint32_t rid;
int error;
/* XXX */
device->state = RNDIS_DEV_INITIALIZED;
xact = vmbus_xact_get(sc->hn_xact, sizeof(*req));
if (xact == NULL) {
if_printf(sc->hn_ifp, "no xact for RNDIS init\n");
@ -1149,115 +833,48 @@ hv_rf_init_device(rndis_device *device)
goto done;
}
if (bootverbose) {
if_printf(sc->hn_ifp, "RNDIS ver %u.%u, pktsz %u, pktcnt %u\n",
comp->rm_ver_major, comp->rm_ver_minor,
comp->rm_pktmaxsz, comp->rm_pktmaxcnt);
if_printf(sc->hn_ifp, "RNDIS ver %u.%u, pktsz %u, pktcnt %u, "
"align %u\n", comp->rm_ver_major, comp->rm_ver_minor,
comp->rm_pktmaxsz, comp->rm_pktmaxcnt,
1U << comp->rm_align);
}
error = 0;
done:
if (xact != NULL)
vmbus_xact_put(xact);
vmbus_xact_put(xact);
return (error);
}
#define HALT_COMPLETION_WAIT_COUNT 25
/*
* RNDIS filter halt device
*/
static int
hv_rf_halt_device(rndis_device *device)
hv_rf_halt_device(struct hn_softc *sc)
{
rndis_request *request;
int i, ret;
struct vmbus_xact *xact;
struct rndis_halt_req *halt;
struct hn_send_ctx sndc;
size_t comp_len;
/* Attempt to do a rndis device halt */
request = hv_rndis_request(device, REMOTE_NDIS_HALT_MSG,
RNDIS_MESSAGE_SIZE(rndis_halt_request));
if (request == NULL) {
return (-1);
xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt));
if (xact == NULL) {
if_printf(sc->hn_ifp, "no xact for RNDIS halt\n");
return (ENXIO);
}
halt = vmbus_xact_req_data(xact);
halt->rm_type = REMOTE_NDIS_HALT_MSG;
halt->rm_len = sizeof(*halt);
halt->rm_rid = hn_rndis_rid(sc);
/* initialize "poor man's semaphore" */
request->halt_complete_flag = 0;
ret = hv_rf_send_request(device, request, REMOTE_NDIS_HALT_MSG);
if (ret != 0) {
return (-1);
}
/*
* Wait for halt response from halt callback. We must wait for
* the transaction response before freeing the request and other
* resources.
*/
for (i=HALT_COMPLETION_WAIT_COUNT; i > 0; i--) {
if (request->halt_complete_flag != 0) {
break;
}
DELAY(400);
}
if (i == 0) {
return (-1);
}
device->state = RNDIS_DEV_UNINITIALIZED;
hv_put_rndis_request(device, request);
/* No RNDIS completion; rely on NVS message send completion */
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len);
vmbus_xact_put(xact);
if (bootverbose)
if_printf(sc->hn_ifp, "RNDIS halt done\n");
return (0);
}
/*
* RNDIS filter open device
*/
static int
hv_rf_open_device(rndis_device *device)
{
int ret;
if (device->state != RNDIS_DEV_INITIALIZED) {
return (0);
}
if (hv_promisc_mode != 1) {
ret = hv_rf_set_packet_filter(device,
NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED);
} else {
ret = hv_rf_set_packet_filter(device,
NDIS_PACKET_TYPE_PROMISCUOUS);
}
if (ret == 0) {
device->state = RNDIS_DEV_DATAINITIALIZED;
}
return (ret);
}
/*
* RNDIS filter close device
*/
static int
hv_rf_close_device(rndis_device *device)
{
int ret;
if (device->state != RNDIS_DEV_DATAINITIALIZED) {
return (0);
}
ret = hv_rf_set_packet_filter(device, 0);
if (ret == 0) {
device->state = RNDIS_DEV_INITIALIZED;
}
return (ret);
}
/*
* RNDIS filter on device add
*/
@ -1266,7 +883,6 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int *nchan0, struct hn_rx_ring *rxr)
{
int ret;
rndis_device *rndis_dev;
netvsc_device_info *dev_info = (netvsc_device_info *)additl_info;
device_t dev = sc->hn_dev;
struct hn_nvs_subch_req *req;
@ -1277,13 +893,6 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int nchan = *nchan0;
int rxr_cnt;
rndis_dev = hv_get_rndis_device();
if (rndis_dev == NULL) {
return (ENOMEM);
}
sc->rndis_dev = rndis_dev;
rndis_dev->sc = sc;
/*
* Let the inner driver handle this first to create the netvsc channel
* NOTE! Once the channel is created, we may get a receive callback
@ -1291,17 +900,15 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
* Note: Earlier code used a function pointer here.
*/
ret = hv_nv_on_device_add(sc, rxr);
if (ret != 0) {
hv_put_rndis_device(rndis_dev);
if (ret != 0)
return (ret);
}
/*
* Initialize the rndis device
*/
/* Send the rndis initialization message */
ret = hv_rf_init_device(rndis_dev);
ret = hv_rf_init_device(sc);
if (ret != 0) {
/*
* TODO: If rndis init failed, we will need to shut down
@ -1310,19 +917,15 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
}
/* Get the mac address */
ret = hv_rf_query_device_mac(rndis_dev);
ret = hv_rf_query_device_mac(sc, dev_info->mac_addr);
if (ret != 0) {
/* TODO: shut down rndis device and the channel */
}
/* Configure NDIS offload settings */
hn_rndis_conf_offload(sc);
memcpy(dev_info->mac_addr, rndis_dev->hw_mac_addr, ETHER_ADDR_LEN);
hv_rf_query_device_link_status(rndis_dev);
dev_info->link_state = rndis_dev->link_status;
hv_rf_query_device_link_status(sc, &dev_info->link_state);
if (sc->hn_ndis_ver < NDIS_VERSION_6_30 || nchan == 1) {
/*
@ -1418,19 +1021,15 @@ out:
* RNDIS filter on device remove
*/
int
hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
hv_rf_on_device_remove(struct hn_softc *sc)
{
rndis_device *rndis_dev = sc->rndis_dev;
int ret;
/* Halt and release the rndis device */
ret = hv_rf_halt_device(rndis_dev);
sc->rndis_dev = NULL;
hv_put_rndis_device(rndis_dev);
ret = hv_rf_halt_device(sc);
/* Pass control to inner driver to remove the device */
ret |= hv_nv_on_device_remove(sc, destroy_channel);
ret |= hv_nv_on_device_remove(sc);
return (ret);
}
@ -1441,8 +1040,17 @@ hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
int
hv_rf_on_open(struct hn_softc *sc)
{
uint32_t filter;
return (hv_rf_open_device(sc->rndis_dev));
/* XXX */
if (hv_promisc_mode != 1) {
filter = NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_ALL_MULTICAST |
NDIS_PACKET_TYPE_DIRECTED;
} else {
filter = NDIS_PACKET_TYPE_PROMISCUOUS;
}
return (hn_rndis_set_rxfilter(sc, filter));
}
/*
@ -1452,34 +1060,7 @@ int
hv_rf_on_close(struct hn_softc *sc)
{
return (hv_rf_close_device(sc->rndis_dev));
}
static void
hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct hn_softc *sc,
struct vmbus_channel *chan __unused, const void *data __unused,
int dlen __unused)
{
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(sc, sndc->hn_chim_idx);
}
static void
hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct hn_softc *sc,
struct vmbus_channel *chan __unused, const void *data __unused,
int dlen __unused)
{
rndis_request *request = sndc->hn_cbarg;
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(sc, sndc->hn_chim_idx);
/*
* Notify hv_rf_halt_device() about halt completion.
* The halt code must wait for completion before freeing
* the transaction resources.
*/
request->halt_complete_flag = 1;
return (hn_rndis_set_rxfilter(sc, 0));
}
void

View File

@ -35,80 +35,6 @@
#include <net/ethernet.h>
#include <dev/hyperv/netvsc/if_hnvar.h>
/*
* Defines
*/
/* Destroy or preserve channel on filter/netvsc teardown */
#define HV_RF_NV_DESTROY_CHANNEL TRUE
#define HV_RF_NV_RETAIN_CHANNEL FALSE
/*
* Number of page buffers to reserve for the RNDIS filter packet in the
* transmitted message.
*/
#define HV_RF_NUM_TX_RESERVED_PAGE_BUFS 1
/*
* Data types
*/
typedef enum {
RNDIS_DEV_UNINITIALIZED = 0,
RNDIS_DEV_INITIALIZING,
RNDIS_DEV_INITIALIZED,
RNDIS_DEV_DATAINITIALIZED,
} rndis_device_state;
typedef struct rndis_request_ {
STAILQ_ENTRY(rndis_request_) mylist_entry;
struct sema wait_sema;
/*
* The max response size is sizeof(rndis_msg) + PAGE_SIZE.
*
* XXX
* This is ugly and should be cleaned up once we busdma-fy
* RNDIS request bits.
*/
rndis_msg response_msg;
uint8_t buf_resp[PAGE_SIZE];
/* Simplify allocation by having a netvsc packet inline */
struct hn_send_ctx send_ctx;
/*
* The max request size is sizeof(rndis_msg) + PAGE_SIZE.
*
* NOTE:
* This is required for the large request like RSS settings.
*
* XXX
* This is ugly and should be cleaned up once we busdma-fy
* RNDIS request bits.
*/
rndis_msg request_msg;
uint8_t buf_req[PAGE_SIZE];
/* Fixme: Poor man's semaphore. */
uint32_t halt_complete_flag;
} rndis_request;
typedef struct rndis_device_ {
struct hn_softc *sc;
rndis_device_state state;
uint32_t link_status;
uint32_t new_request_id;
struct mtx req_lock;
STAILQ_HEAD(RQ, rndis_request_) myrequest_list;
uint8_t hw_mac_addr[ETHER_ADDR_LEN];
} rndis_device;
/*
* Externs
*/
@ -119,7 +45,7 @@ int hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
int hv_rf_on_device_add(struct hn_softc *sc, void *additl_info, int *nchan,
struct hn_rx_ring *rxr);
int hv_rf_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel);
int hv_rf_on_device_remove(struct hn_softc *sc);
int hv_rf_on_open(struct hn_softc *sc);
int hv_rf_on_close(struct hn_softc *sc);

View File

@ -112,6 +112,8 @@ struct vmbus_xact;
const void *hn_nvs_xact_execute(struct hn_softc *sc,
struct vmbus_xact *xact, void *req, int reqlen,
size_t *resp_len);
void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
struct vmbus_channel *chan, const void *data, int dlen);
uint32_t hn_chim_alloc(struct hn_softc *sc);
void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);

View File

@ -29,46 +29,41 @@
#ifndef _NET_NDIS_H_
#define _NET_NDIS_H_
#define NDIS_MEDIA_STATE_CONNECTED 0
#define NDIS_MEDIA_STATE_DISCONNECTED 1
#define NDIS_MEDIA_STATE_CONNECTED 0
#define NDIS_MEDIA_STATE_DISCONNECTED 1
#define OID_GEN_RSS_CAPABILITIES 0x00010203
#define OID_GEN_RSS_PARAMETERS 0x00010204
#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C
#define NDIS_OBJTYPE_DEFAULT 0x80
#define NDIS_OBJTYPE_RSS_CAPS 0x88
#define NDIS_OBJTYPE_RSS_PARAMS 0x89
/* common_set */
#define NDIS_OFFLOAD_SET_NOCHG 0
#define NDIS_OFFLOAD_SET_ON 1
#define NDIS_OFFLOAD_SET_OFF 2
#define NDIS_OFFLOAD_SET_NOCHG 0
#define NDIS_OFFLOAD_SET_ON 1
#define NDIS_OFFLOAD_SET_OFF 2
/* a.k.a GRE MAC */
#define NDIS_ENCAP_TYPE_NVGRE 0x00000001
#define NDIS_ENCAP_TYPE_NVGRE 0x00000001
#define NDIS_HASH_FUNCTION_MASK 0x000000FF /* see hash function */
#define NDIS_HASH_TYPE_MASK 0x00FFFF00 /* see hash type */
#define NDIS_HASH_FUNCTION_MASK 0x000000FF /* see hash function */
#define NDIS_HASH_TYPE_MASK 0x00FFFF00 /* see hash type */
/* hash function */
#define NDIS_HASH_FUNCTION_TOEPLITZ 0x00000001
#define NDIS_HASH_FUNCTION_TOEPLITZ 0x00000001
/* hash type */
#define NDIS_HASH_IPV4 0x00000100
#define NDIS_HASH_TCP_IPV4 0x00000200
#define NDIS_HASH_IPV6 0x00000400
#define NDIS_HASH_IPV6_EX 0x00000800
#define NDIS_HASH_TCP_IPV6 0x00001000
#define NDIS_HASH_TCP_IPV6_EX 0x00002000
#define NDIS_HASH_IPV4 0x00000100
#define NDIS_HASH_TCP_IPV4 0x00000200
#define NDIS_HASH_IPV6 0x00000400
#define NDIS_HASH_IPV6_EX 0x00000800
#define NDIS_HASH_TCP_IPV6 0x00001000
#define NDIS_HASH_TCP_IPV6_EX 0x00002000
#define NDIS_HASH_KEYSIZE_TOEPLITZ 40
#define NDIS_HASH_INDCNT 128
#define NDIS_HASH_KEYSIZE_TOEPLITZ 40
#define NDIS_HASH_INDCNT 128
#define NDIS_OBJTYPE_DEFAULT 0x80
#define NDIS_OBJTYPE_RSS_CAPS 0x88
#define NDIS_OBJTYPE_RSS_PARAMS 0x89
struct ndis_object_hdr {
uint8_t ndis_type; /* NDIS_OBJTYPE_ */
uint8_t ndis_rev; /* type specific */
uint16_t ndis_size; /* incl. this hdr */
uint8_t ndis_type; /* NDIS_OBJTYPE_ */
uint8_t ndis_rev; /* type specific */
uint16_t ndis_size; /* incl. this hdr */
};
/*
@ -77,73 +72,67 @@ struct ndis_object_hdr {
*/
struct ndis_offload_params {
struct ndis_object_hdr ndis_hdr;
uint8_t ndis_ip4csum; /* param_set */
uint8_t ndis_tcp4csum; /* param_set */
uint8_t ndis_udp4csum; /* param_set */
uint8_t ndis_tcp6csum; /* param_set */
uint8_t ndis_udp6csum; /* param_set */
uint8_t ndis_lsov1; /* lsov1_set */
uint8_t ndis_ipsecv1; /* ipsecv1_set */
uint8_t ndis_lsov2_ip4; /* lsov2_set */
uint8_t ndis_lsov2_ip6; /* lsov2_set */
uint8_t ndis_tcp4conn; /* PARAM_NOCHG */
uint8_t ndis_tcp6conn; /* PARAM_NOCHG */
uint32_t ndis_flags; /* 0 */
uint8_t ndis_ip4csum; /* NDIS_OFFLOAD_PARAM_ */
uint8_t ndis_tcp4csum; /* NDIS_OFFLOAD_PARAM_ */
uint8_t ndis_udp4csum; /* NDIS_OFFLOAD_PARAM_ */
uint8_t ndis_tcp6csum; /* NDIS_OFFLOAD_PARAM_ */
uint8_t ndis_udp6csum; /* NDIS_OFFLOAD_PARAM_ */
uint8_t ndis_lsov1; /* NDIS_OFFLOAD_PARAM_ */
uint8_t ndis_ipsecv1; /* NDIS_OFFLOAD_IPSECV1_ */
uint8_t ndis_lsov2_ip4; /* NDIS_OFFLOAD_LSOV2_ */
uint8_t ndis_lsov2_ip6; /* NDIS_OFFLOAD_LSOV2_ */
uint8_t ndis_tcp4conn; /* 0 */
uint8_t ndis_tcp6conn; /* 0 */
uint32_t ndis_flags; /* 0 */
/* NDIS >= 6.1 */
uint8_t ndis_ipsecv2; /* ipsecv2_set */
uint8_t ndis_ipsecv2_ip4; /* ipsecv2_set */
uint8_t ndis_ipsecv2; /* NDIS_OFFLOAD_IPSECV2_ */
uint8_t ndis_ipsecv2_ip4;/* NDIS_OFFLOAD_IPSECV2_ */
/* NDIS >= 6.30 */
uint8_t ndis_rsc_ip4; /* rsc_set */
uint8_t ndis_rsc_ip6; /* rsc_set */
uint8_t ndis_encap; /* common_set */
uint8_t ndis_encap_types; /* NDIS_ENCAP_TYPE_ */
uint8_t ndis_rsc_ip4; /* NDIS_OFFLOAD_RSC_ */
uint8_t ndis_rsc_ip6; /* NDIS_OFFLOAD_RSC_ */
uint8_t ndis_encap; /* NDIS_OFFLOAD_SET_ */
uint8_t ndis_encap_types;/* NDIS_ENCAP_TYPE_ */
};
#define NDIS_OFFLOAD_PARAMS_SIZE sizeof(struct ndis_offload_params)
#define NDIS_OFFLOAD_PARAMS_SIZE_6_1 \
#define NDIS_OFFLOAD_PARAMS_SIZE sizeof(struct ndis_offload_params)
#define NDIS_OFFLOAD_PARAMS_SIZE_6_1 \
__offsetof(struct ndis_offload_params, ndis_rsc_ip4)
#define NDIS_OFFLOAD_PARAMS_REV_2 2 /* NDIS 6.1 */
#define NDIS_OFFLOAD_PARAMS_REV_3 3 /* NDIS 6.30 */
#define NDIS_OFFLOAD_PARAMS_REV_2 2 /* NDIS 6.1 */
#define NDIS_OFFLOAD_PARAMS_REV_3 3 /* NDIS 6.30 */
/* param_set */
#define NDIS_OFFLOAD_PARAM_NOCHG 0 /* common to all sets */
#define NDIS_OFFLOAD_PARAM_OFF 1
#define NDIS_OFFLOAD_PARAM_TX 2
#define NDIS_OFFLOAD_PARAM_RX 3
#define NDIS_OFFLOAD_PARAM_TXRX 4
#define NDIS_OFFLOAD_PARAM_NOCHG 0 /* common */
#define NDIS_OFFLOAD_PARAM_OFF 1
#define NDIS_OFFLOAD_PARAM_TX 2
#define NDIS_OFFLOAD_PARAM_RX 3
#define NDIS_OFFLOAD_PARAM_TXRX 4
/* lsov1_set */
/* NDIS_OFFLOAD_PARAM_NOCHG */
#define NDIS_OFFLOAD_LSOV1_OFF 1
#define NDIS_OFFLOAD_LSOV1_ON 2
#define NDIS_OFFLOAD_LSOV1_OFF 1
#define NDIS_OFFLOAD_LSOV1_ON 2
/* ipsecv1_set */
/* NDIS_OFFLOAD_PARAM_NOCHG */
#define NDIS_OFFLOAD_IPSECV1_OFF 1
#define NDIS_OFFLOAD_IPSECV1_AH 2
#define NDIS_OFFLOAD_IPSECV1_ESP 3
#define NDIS_OFFLOAD_IPSECV1_AH_ESP 4
#define NDIS_OFFLOAD_IPSECV1_OFF 1
#define NDIS_OFFLOAD_IPSECV1_AH 2
#define NDIS_OFFLOAD_IPSECV1_ESP 3
#define NDIS_OFFLOAD_IPSECV1_AH_ESP 4
/* lsov2_set */
/* NDIS_OFFLOAD_PARAM_NOCHG */
#define NDIS_OFFLOAD_LSOV2_OFF 1
#define NDIS_OFFLOAD_LSOV2_ON 2
#define NDIS_OFFLOAD_LSOV2_OFF 1
#define NDIS_OFFLOAD_LSOV2_ON 2
/* ipsecv2_set */
/* NDIS_OFFLOAD_PARAM_NOCHG */
#define NDIS_OFFLOAD_IPSECV2_OFF 1
#define NDIS_OFFLOAD_IPSECV2_AH 2
#define NDIS_OFFLOAD_IPSECV2_ESP 3
#define NDIS_OFFLOAD_IPSECV2_AH_ESP 4
#define NDIS_OFFLOAD_IPSECV2_OFF 1
#define NDIS_OFFLOAD_IPSECV2_AH 2
#define NDIS_OFFLOAD_IPSECV2_ESP 3
#define NDIS_OFFLOAD_IPSECV2_AH_ESP 4
/* rsc_set */
/* NDIS_OFFLOAD_PARAM_NOCHG */
#define NDIS_OFFLOAD_RSC_OFF 1
#define NDIS_OFFLOAD_RSC_ON 2
#define NDIS_OFFLOAD_RSC_OFF 1
#define NDIS_OFFLOAD_RSC_ON 2
/*
* OID_GEN_RSS_CAPABILITIES
* OID_GEN_RECEIVE_SCALE_CAPABILITIES
* ndis_type: NDIS_OBJTYPE_RSS_CAPS
*/
struct ndis_rss_caps {
@ -156,25 +145,25 @@ struct ndis_rss_caps {
uint16_t ndis_pad;
};
#define NDIS_RSS_CAPS_SIZE \
#define NDIS_RSS_CAPS_SIZE \
__offsetof(struct ndis_rss_caps, ndis_pad)
#define NDIS_RSS_CAPS_SIZE_6_0 \
#define NDIS_RSS_CAPS_SIZE_6_0 \
__offsetof(struct ndis_rss_caps, ndis_nind)
#define NDIS_RSS_CAPS_REV_1 1 /* NDIS 6.{0,1,20} */
#define NDIS_RSS_CAPS_REV_2 2 /* NDIS 6.30 */
#define NDIS_RSS_CAPS_REV_1 1 /* NDIS 6.{0,1,20} */
#define NDIS_RSS_CAPS_REV_2 2 /* NDIS 6.30 */
#define NDIS_RSS_CAP_MSI 0x01000000
#define NDIS_RSS_CAP_CLASSIFY_ISR 0x02000000
#define NDIS_RSS_CAP_CLASSIFY_DPC 0x04000000
#define NDIS_RSS_CAP_MSIX 0x08000000
#define NDIS_RSS_CAP_IPV4 0x00000100
#define NDIS_RSS_CAP_IPV6 0x00000200
#define NDIS_RSS_CAP_IPV6_EX 0x00000400
#define NDIS_RSS_CAP_HASH_TOEPLITZ 0x00000001
#define NDIS_RSS_CAP_MSI 0x01000000
#define NDIS_RSS_CAP_CLASSIFY_ISR 0x02000000
#define NDIS_RSS_CAP_CLASSIFY_DPC 0x04000000
#define NDIS_RSS_CAP_MSIX 0x08000000
#define NDIS_RSS_CAP_IPV4 0x00000100
#define NDIS_RSS_CAP_IPV6 0x00000200
#define NDIS_RSS_CAP_IPV6_EX 0x00000400
#define NDIS_RSS_CAP_HASH_TOEPLITZ 0x00000001
/*
* OID_GEN_RSS_PARAMETERS
* OID_GEN_RECEIVE_SCALE_PARAMETERS
* ndis_type: NDIS_OBJTYPE_RSS_PARAMS
*/
struct ndis_rss_params {
@ -192,18 +181,18 @@ struct ndis_rss_params {
uint32_t ndis_cpumaskentsz;
};
#define NDIS_RSS_PARAMS_SIZE sizeof(struct ndis_rss_params)
#define NDIS_RSS_PARAMS_SIZE_6_0 \
#define NDIS_RSS_PARAMS_SIZE sizeof(struct ndis_rss_params)
#define NDIS_RSS_PARAMS_SIZE_6_0 \
__offsetof(struct ndis_rss_params, ndis_cpumaskoffset)
#define NDIS_RSS_PARAMS_REV_1 1 /* NDIS 6.0 */
#define NDIS_RSS_PARAMS_REV_2 2 /* NDIS 6.20 */
#define NDIS_RSS_PARAMS_REV_1 1 /* NDIS 6.0 */
#define NDIS_RSS_PARAMS_REV_2 2 /* NDIS 6.20 */
#define NDIS_RSS_FLAG_BCPU_UNCHG 0x0001
#define NDIS_RSS_FLAG_HASH_UNCHG 0x0002
#define NDIS_RSS_FLAG_IND_UNCHG 0x0004
#define NDIS_RSS_FLAG_KEY_UNCHG 0x0008
#define NDIS_RSS_FLAG_DISABLE 0x0010
#define NDIS_RSS_FLAG_BCPU_UNCHG 0x0001
#define NDIS_RSS_FLAG_HASH_UNCHG 0x0002
#define NDIS_RSS_FLAG_IND_UNCHG 0x0004
#define NDIS_RSS_FLAG_KEY_UNCHG 0x0008
#define NDIS_RSS_FLAG_DISABLE 0x0010
/* non-standard convenient struct */
struct ndis_rssprm_toeplitz {

View File

@ -356,7 +356,7 @@ typedef struct text_req {
typedef struct logout_req {
char cmd; // 0x06
char reason; // 0 - close session
u_char reason; // 0 - close session
// 1 - close connection
// 2 - remove the connection for recovery
char _2[2];

View File

@ -150,9 +150,9 @@ struct kbdmux_state
int ks_flags; /* flags */
#define COMPOSE (1 << 0) /* compose char flag */
#define POLLING (1 << 1) /* polling */
#define TASK (1 << 2) /* interrupt task queued */
int ks_polling; /* poll nesting count */
int ks_mode; /* K_XLATE, K_RAW, K_CODE */
int ks_state; /* state */
int ks_accents; /* accent key index (> 0) */
@ -666,7 +666,7 @@ next_code:
/* see if there is something in the keyboard queue */
scancode = kbdmux_kbd_getc(state);
if (scancode == -1) {
if (state->ks_flags & POLLING) {
if (state->ks_polling != 0) {
kbdmux_kbd_t *k;
SLIST_FOREACH(k, &state->ks_kbds, next) {
@ -1244,7 +1244,8 @@ kbdmux_clear_state_locked(kbdmux_state_t *state)
{
KBDMUX_LOCK_ASSERT(state, MA_OWNED);
state->ks_flags &= ~(COMPOSE|POLLING);
state->ks_flags &= ~COMPOSE;
state->ks_polling = 0;
state->ks_state &= LOCK_MASK; /* preserve locking key state */
state->ks_accents = 0;
state->ks_composed_char = 0;
@ -1304,9 +1305,9 @@ kbdmux_poll(keyboard_t *kbd, int on)
KBDMUX_LOCK(state);
if (on)
state->ks_flags |= POLLING;
state->ks_polling++;
else
state->ks_flags &= ~POLLING;
state->ks_polling--;
/* set poll on slave keyboards */
SLIST_FOREACH(k, &state->ks_kbds, next)

View File

@ -1648,6 +1648,7 @@ sc_cnterm(struct consdev *cp)
}
static void sccnclose(sc_softc_t *sc, struct sc_cnstate *sp);
static int sc_cngetc_locked(struct sc_cnstate *sp);
static void sccnopen(sc_softc_t *sc, struct sc_cnstate *sp, int flags);
static void sccnscrlock(sc_softc_t *sc, struct sc_cnstate *sp);
static void sccnscrunlock(sc_softc_t *sc, struct sc_cnstate *sp);
@ -1823,16 +1824,29 @@ sc_cnputc(struct consdev *cd, int c)
static int
sc_cngetc(struct consdev *cd)
{
int c, s;
/* assert(sc_console != NULL) */
s = spltty(); /* block sckbdevent and scrn_timer while we poll */
if (sc_console->sc->kbd == NULL) {
splx(s);
return -1;
}
c = sc_cngetc_locked(NULL);
splx(s);
return c;
}
static int
sc_cngetc_locked(struct sc_cnstate *sp)
{
static struct fkeytab fkey;
static int fkeycp;
scr_stat *scp;
const u_char *p;
int s = spltty(); /* block sckbdevent and scrn_timer while we poll */
int c;
/* assert(sc_console != NULL) */
/*
* Stop the screen saver and update the screen if necessary.
* What if we have been running in the screen saver code... XXX
@ -1841,15 +1855,8 @@ sc_cngetc(struct consdev *cd)
scp = sc_console->sc->cur_scp; /* XXX */
sccnupdate(scp);
if (fkeycp < fkey.len) {
splx(s);
if (fkeycp < fkey.len)
return fkey.str[fkeycp++];
}
if (scp->sc->kbd == NULL) {
splx(s);
return -1;
}
c = scgetc(scp->sc, SCGETC_CN | SCGETC_NONBLOCK, NULL);

View File

@ -135,6 +135,7 @@ struct tsec_softc {
int phyaddr;
bus_space_tag_t phy_bst;
bus_space_handle_t phy_bsh;
int phy_regoff;
};
/* interface to get/put generic objects */
@ -258,9 +259,11 @@ extern struct mtx tsec_phy_mtx;
#define TSEC_PHY_LOCK(sc) mtx_lock(&tsec_phy_mtx)
#define TSEC_PHY_UNLOCK(sc) mtx_unlock(&tsec_phy_mtx)
#define TSEC_PHY_READ(sc, reg) \
bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, (reg))
bus_space_read_4((sc)->phy_bst, (sc)->phy_bsh, \
(reg) + (sc)->phy_regoff)
#define TSEC_PHY_WRITE(sc, reg, val) \
bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, (reg), (val))
bus_space_write_4((sc)->phy_bst, (sc)->phy_bsh, \
(reg) + (sc)->phy_regoff, (val))
/* Lock for transmitter */
#define TSEC_TRANSMIT_LOCK(sc) do { \

View File

@ -121,25 +121,33 @@ tsec_fdt_probe(device_t dev)
sc = device_get_softc(dev);
sc->sc_rrid = 0;
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
RF_ACTIVE);
if (sc->sc_rres == NULL)
return (ENXIO);
/*
* Device trees with "fsl,etsec2" compatible nodes don't have a reg
* property, as it's been relegated to the queue-group children.
*/
if (ofw_bus_is_compatible(dev, "fsl,etsec2"))
sc->is_etsec = 1;
else {
sc->sc_rrid = 0;
sc->sc_rres = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rrid,
RF_ACTIVE);
if (sc->sc_rres == NULL)
return (ENXIO);
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
sc->sc_bas.bst = rman_get_bustag(sc->sc_rres);
/* Check if we are eTSEC (enhanced TSEC) */
id = TSEC_READ(sc, TSEC_REG_ID);
sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
id |= TSEC_READ(sc, TSEC_REG_ID2);
/* Check if we are eTSEC (enhanced TSEC) */
id = TSEC_READ(sc, TSEC_REG_ID);
sc->is_etsec = ((id >> 16) == TSEC_ETSEC_ID) ? 1 : 0;
id |= TSEC_READ(sc, TSEC_REG_ID2);
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_rrid, sc->sc_rres);
if (id == 0) {
device_printf(dev, "could not identify TSEC type\n");
return (ENXIO);
if (id == 0) {
device_printf(dev, "could not identify TSEC type\n");
return (ENXIO);
}
}
if (sc->is_etsec)
@ -154,13 +162,31 @@ static int
tsec_fdt_attach(device_t dev)
{
struct tsec_softc *sc;
phandle_t phy;
struct resource_list *rl;
phandle_t child, mdio, phy;
int acells, scells;
int error = 0;
sc = device_get_softc(dev);
sc->dev = dev;
sc->node = ofw_bus_get_node(dev);
if (fdt_addrsize_cells(sc->node, &acells, &scells) != 0) {
acells = 1;
scells = 1;
}
if (ofw_bus_is_compatible(dev, "fsl,etsec2")) {
rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
/*
* TODO: Add all children resources to the list. Will be
* required to support multigroup mode.
*/
child = OF_child(sc->node);
ofw_bus_reg_to_rl(dev, child, acells, scells, rl);
ofw_bus_intr_to_rl(dev, child, rl, NULL);
}
/* Get phy address from fdt */
if (OF_getencprop(sc->node, "phy-handle", &phy, sizeof(phy)) <= 0) {
device_printf(dev, "PHY not found in device tree");
@ -168,9 +194,17 @@ tsec_fdt_attach(device_t dev)
}
phy = OF_node_from_xref(phy);
OF_decode_addr(OF_parent(phy), 0, &sc->phy_bst, &sc->phy_bsh, NULL);
mdio = OF_parent(phy);
OF_decode_addr(mdio, 0, &sc->phy_bst, &sc->phy_bsh, NULL);
OF_getencprop(phy, "reg", &sc->phyaddr, sizeof(sc->phyaddr));
/*
* etsec2 MDIO nodes are given the MDIO module base address, so we need
* to add the MII offset to get the PHY registers.
*/
if (ofw_bus_node_is_compatible(mdio, "fsl,etsec2-mdio"))
sc->phy_regoff = TSEC_REG_MIIBASE;
/* Init timer */
callout_init(&sc->tsec_callout, 1);

View File

@ -292,8 +292,8 @@ urndis_attach(device_t dev)
memcpy(&sc->sc_ue.ue_eaddr, buf, ETHER_ADDR_LEN);
/* Initialize packet filter */
sc->sc_filter = RNDIS_PACKET_TYPE_BROADCAST |
RNDIS_PACKET_TYPE_ALL_MULTICAST;
sc->sc_filter = NDIS_PACKET_TYPE_BROADCAST |
NDIS_PACKET_TYPE_ALL_MULTICAST;
msg.ibuf.filter = htole32(sc->sc_filter);
URNDIS_LOCK(sc);
error = urndis_ctrl_set(sc, OID_GEN_CURRENT_PACKET_FILTER,

View File

@ -5349,6 +5349,7 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
case DEV_SUSPEND:
case DEV_RESUME:
case DEV_SET_DRIVER:
case DEV_CLEAR_DRIVER:
case DEV_RESCAN:
case DEV_DELETE:
error = priv_check(td, PRIV_DRIVER);
@ -5514,6 +5515,25 @@ devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag,
error = device_probe_and_attach(dev);
break;
}
case DEV_CLEAR_DRIVER:
if (!(dev->flags & DF_FIXEDCLASS)) {
error = 0;
break;
}
if (device_is_attached(dev)) {
if (req->dr_flags & DEVF_CLEAR_DRIVER_DETACH)
error = device_detach(dev);
else
error = EBUSY;
if (error)
break;
}
dev->flags &= ~DF_FIXEDCLASS;
dev->flags |= DF_WILDCARD;
devclass_delete_device(dev->devclass, dev);
error = device_probe_and_attach(dev);
break;
case DEV_RESCAN:
if (!device_is_attached(dev)) {
error = ENXIO;

View File

@ -779,15 +779,8 @@ smp_rendezvous(void (*setup_func)(void *),
void *arg)
{
/* Look comments in the smp_rendezvous_cpus() case. */
spinlock_enter();
if (setup_func != NULL)
setup_func(arg);
if (action_func != NULL)
action_func(arg);
if (teardown_func != NULL)
teardown_func(arg);
spinlock_exit();
smp_rendezvous_cpus(all_cpus, setup_func, action_func, teardown_func,
arg);
}
/*

View File

@ -62,6 +62,8 @@
#define OID_GEN_SUPPORTED_GUIDS 0x00010117
#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118
#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119
#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203
#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204
#define OID_GEN_MACHINE_NAME 0x0001021A
#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B
#define OID_GEN_VLAN_ID 0x0001021C
@ -82,6 +84,8 @@
#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206
#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
#define OID_TCP_OFFLOAD_PARAMETERS 0xFC01020C
#define RNDIS_MEDIUM_802_3 0x00000000
/* Device flags */
@ -262,18 +266,18 @@ struct rndis_keepalive_comp {
};
/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
#define RNDIS_PACKET_TYPE_DIRECTED 0x00000001
#define RNDIS_PACKET_TYPE_MULTICAST 0x00000002
#define RNDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
#define RNDIS_PACKET_TYPE_BROADCAST 0x00000008
#define RNDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
#define RNDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
#define RNDIS_PACKET_TYPE_SMT 0x00000040
#define RNDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
#define RNDIS_PACKET_TYPE_GROUP 0x00001000
#define RNDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000
#define RNDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
#define RNDIS_PACKET_TYPE_MAC_FRAME 0x00008000
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
#define NDIS_PACKET_TYPE_BROADCAST 0x00000008
#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
#define NDIS_PACKET_TYPE_SMT 0x00000040
#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
#define NDIS_PACKET_TYPE_GROUP 0x00001000
#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000
/* RNDIS offsets */
#define RNDIS_HEADER_OFFSET 8 /* bytes */

View File

@ -120,11 +120,16 @@ PLATFORM_DEF(mpc85xx_platform);
static int
mpc85xx_probe(platform_t plat)
{
u_int pvr = mfpvr() >> 16;
if ((pvr & 0xfff0) == FSL_E500v1)
return (BUS_PROBE_DEFAULT);
u_int pvr = (mfpvr() >> 16) & 0xFFFF;
switch (pvr) {
case FSL_E500v1:
case FSL_E500v2:
case FSL_E500mc:
case FSL_E5500:
case FSL_E6500:
return (BUS_PROBE_DEFAULT);
}
return (ENXIO);
}
@ -135,9 +140,8 @@ mpc85xx_attach(platform_t plat)
const char *soc_name_guesses[] = {"/soc", "soc", NULL};
const char **name;
pcell_t ranges[6], acells, pacells, scells;
uint32_t sr;
uint64_t ccsrbar, ccsrsize;
int i, law_max, tgt;
int i;
if ((cpus = OF_finddevice("/cpus")) != -1) {
for (maxcpu = 0, child = OF_child(cpus); child != 0;
@ -194,23 +198,6 @@ mpc85xx_attach(platform_t plat)
mpc85xx_fix_errata(ccsrbar_va);
mpc85xx_enable_l3_cache();
/*
* Clear local access windows. Skip DRAM entries, so we don't shoot
* ourselves in the foot.
*/
law_max = law_getmax();
for (i = 0; i < law_max; i++) {
sr = ccsr_read4(OCP85XX_LAWSR(i));
if ((sr & OCP85XX_ENA_MASK) == 0)
continue;
tgt = (sr & 0x01f00000) >> 20;
if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
tgt == OCP85XX_TGTIF_RAM_INTL)
continue;
ccsr_write4(OCP85XX_LAWSR(i), sr & OCP85XX_DIS_MASK);
}
return (0);
}

View File

@ -117,6 +117,7 @@ struct devreq {
#define DEV_SUSPEND _IOW('D', 5, struct devreq)
#define DEV_RESUME _IOW('D', 6, struct devreq)
#define DEV_SET_DRIVER _IOW('D', 7, struct devreq)
#define DEV_CLEAR_DRIVER _IOW('D', 8, struct devreq)
#define DEV_RESCAN _IOW('D', 9, struct devreq)
#define DEV_DELETE _IOW('D', 10, struct devreq)
@ -126,6 +127,9 @@ struct devreq {
/* Flags for DEV_SET_DRIVER. */
#define DEVF_SET_DRIVER_DETACH 0x0000001 /* Detach existing driver. */
/* Flags for DEV_CLEAR_DRIVER. */
#define DEVF_CLEAR_DRIVER_DETACH 0x0000001 /* Detach existing driver. */
/* Flags for DEV_DELETE. */
#define DEVF_FORCE_DELETE 0x0000001

View File

@ -391,7 +391,7 @@ struct mbuf {
#define EXT_JUMBO9 4 /* jumbo cluster 9216 bytes */
#define EXT_JUMBO16 5 /* jumbo cluster 16184 bytes */
#define EXT_PACKET 6 /* mbuf+cluster from packet zone */
#define EXT_MBUF 7 /* external mbuf reference (M_IOVEC) */
#define EXT_MBUF 7 /* external mbuf reference */
#define EXT_SFBUF_NOCACHE 8 /* sendfile(2)'s sf_buf not to be cached */
#define EXT_VENDOR1 224 /* for vendor-internal use */

View File

@ -990,22 +990,21 @@ swap_pager_copy(vm_object_t srcobject, vm_object_t dstobject,
* page and return TRUE if it does, FALSE if it doesn't.
*
* If TRUE, we also try to determine how much valid, contiguous backing
* store exists before and after the requested page within a reasonable
* distance. We do not try to restrict it to the swap device stripe
* (that is handled in getpages/putpages). It probably isn't worth
* doing here.
* store exists before and after the requested page.
*/
static boolean_t
swap_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before, int *after)
swap_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before,
int *after)
{
daddr_t blk0;
daddr_t blk, blk0;
int i;
VM_OBJECT_ASSERT_LOCKED(object);
/*
* do we have good backing store at the requested index ?
*/
blk0 = swp_pager_meta_ctl(object, pindex, 0);
if (blk0 == SWAPBLK_NONE) {
if (before)
*before = 0;
@ -1018,34 +1017,26 @@ swap_pager_haspage(vm_object_t object, vm_pindex_t pindex, int *before, int *aft
* find backwards-looking contiguous good backing store
*/
if (before != NULL) {
int i;
for (i = 1; i < (SWB_NPAGES/2); ++i) {
daddr_t blk;
for (i = 1; i < SWB_NPAGES; i++) {
if (i > pindex)
break;
blk = swp_pager_meta_ctl(object, pindex - i, 0);
if (blk != blk0 - i)
break;
}
*before = (i - 1);
*before = i - 1;
}
/*
* find forward-looking contiguous good backing store
*/
if (after != NULL) {
int i;
for (i = 1; i < (SWB_NPAGES/2); ++i) {
daddr_t blk;
for (i = 1; i < SWB_NPAGES; i++) {
blk = swp_pager_meta_ctl(object, pindex + i, 0);
if (blk != blk0 + i)
break;
}
*after = (i - 1);
*after = i - 1;
}
return (TRUE);
}
@ -1077,62 +1068,107 @@ swap_pager_unswapped(vm_page_t m)
}
/*
* SWAP_PAGER_GETPAGES() - bring pages in from swap
* swap_pager_getpages() - bring pages in from swap
*
* Attempt to retrieve (m, count) pages from backing store, but make
* sure we retrieve at least m[reqpage]. We try to load in as large
* a chunk surrounding m[reqpage] as is contiguous in swap and which
* belongs to the same object.
* Attempt to page in the pages in array "m" of length "count". The caller
* may optionally specify that additional pages preceding and succeeding
* the specified range be paged in. The number of such pages is returned
* in the "rbehind" and "rahead" parameters, and they will be in the
* inactive queue upon return.
*
* The code is designed for asynchronous operation and
* immediate-notification of 'reqpage' but tends not to be
* used that way. Please do not optimize-out this algorithmic
* feature, I intend to improve on it in the future.
*
* The parent has a single vm_object_pip_add() reference prior to
* calling us and we should return with the same.
*
* The parent has BUSY'd the pages. We should return with 'm'
* left busy, but the others adjusted.
* The pages in "m" must be busied and will remain busied upon return.
*/
static int
swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int *rbehind,
int *rahead)
{
struct buf *bp;
vm_page_t mpred, msucc, p;
vm_pindex_t pindex;
daddr_t blk;
int i, j, reqcount, shift;
/*
* Calculate range to retrieve. The pages have already been assigned
* their swapblks. We require a *contiguous* range but we know it to
* not span devices. If we do not supply it, bad things
* happen. Note that blk, iblk & jblk can be SWAPBLK_NONE, but the
* loops are set up such that the case(s) are handled implicitly.
*
* The swp_*() calls must be made with the object locked.
*/
blk = swp_pager_meta_ctl(m[0]->object, m[0]->pindex, 0);
reqcount = count;
if (blk == SWAPBLK_NONE)
return (VM_PAGER_FAIL);
#ifdef INVARIANTS
for (int i = 0; i < count; i++)
KASSERT(blk + i ==
swp_pager_meta_ctl(m[i]->object, m[i]->pindex, 0),
("%s: range is not contiguous", __func__));
#endif
/*
* Getpbuf() can sleep.
*/
VM_OBJECT_WUNLOCK(object);
/*
* Get a swap buffer header to perform the IO
*/
bp = getpbuf(&nsw_rcount);
bp->b_flags |= B_PAGING;
VM_OBJECT_WLOCK(object);
if (!swap_pager_haspage(object, m[0]->pindex, rbehind, rahead)) {
relpbuf(bp, &nsw_rcount);
return (VM_PAGER_FAIL);
}
/*
* Clip the readahead and readbehind ranges to exclude resident pages.
*/
if (rahead != NULL) {
KASSERT(reqcount - 1 <= *rahead,
("page count %d extends beyond swap block", reqcount));
*rahead -= reqcount - 1;
pindex = m[reqcount - 1]->pindex;
msucc = TAILQ_NEXT(m[reqcount - 1], listq);
if (msucc != NULL && msucc->pindex - pindex - 1 < *rahead)
*rahead = msucc->pindex - pindex - 1;
}
if (rbehind != NULL) {
pindex = m[0]->pindex;
mpred = TAILQ_PREV(m[0], pglist, listq);
if (mpred != NULL && pindex - mpred->pindex - 1 < *rbehind)
*rbehind = pindex - mpred->pindex - 1;
}
/*
* Allocate readahead and readbehind pages.
*/
shift = rbehind != NULL ? *rbehind : 0;
if (shift != 0) {
for (i = 1; i <= shift; i++) {
p = vm_page_alloc(object, m[0]->pindex - i,
VM_ALLOC_NORMAL | VM_ALLOC_IFNOTCACHED);
if (p == NULL) {
/* Shift allocated pages to the left. */
for (j = 0; j < i - 1; j++)
bp->b_pages[j] =
bp->b_pages[j + shift - i + 1];
break;
}
bp->b_pages[shift - i] = p;
}
shift = i - 1;
*rbehind = shift;
}
for (i = 0; i < reqcount; i++)
bp->b_pages[i + shift] = m[i];
if (rahead != NULL) {
for (i = 0; i < *rahead; i++) {
p = vm_page_alloc(object,
m[reqcount - 1]->pindex + i + 1,
VM_ALLOC_NORMAL | VM_ALLOC_IFNOTCACHED);
if (p == NULL)
break;
bp->b_pages[shift + reqcount + i] = p;
}
*rahead = i;
}
if (rbehind != NULL)
count += *rbehind;
if (rahead != NULL)
count += *rahead;
vm_object_pip_add(object, count);
for (i = 0; i < count; i++)
bp->b_pages[i]->oflags |= VPO_SWAPINPROG;
pindex = bp->b_pages[0]->pindex;
blk = swp_pager_meta_ctl(object, pindex, 0);
KASSERT(blk != SWAPBLK_NONE,
("no swap blocking containing %p(%jx)", object, (uintmax_t)pindex));
VM_OBJECT_WUNLOCK(object);
bp->b_flags |= B_PAGING;
bp->b_iocmd = BIO_READ;
bp->b_iodone = swp_pager_async_iodone;
bp->b_rcred = crhold(thread0.td_ucred);
@ -1141,22 +1177,11 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int *rbehind,
bp->b_bcount = PAGE_SIZE * count;
bp->b_bufsize = PAGE_SIZE * count;
bp->b_npages = count;
VM_OBJECT_WLOCK(object);
for (int i = 0; i < count; i++) {
bp->b_pages[i] = m[i];
m[i]->oflags |= VPO_SWAPINPROG;
}
bp->b_pgbefore = rbehind != NULL ? *rbehind : 0;
bp->b_pgafter = rahead != NULL ? *rahead : 0;
PCPU_INC(cnt.v_swapin);
PCPU_ADD(cnt.v_swappgsin, bp->b_npages);
/*
* We still hold the lock on mreq, and our automatic completion routine
* does not remove it.
*/
vm_object_pip_add(object, bp->b_npages);
VM_OBJECT_WUNLOCK(object);
PCPU_ADD(cnt.v_swappgsin, count);
/*
* perform the I/O. NOTE!!! bp cannot be considered valid after
@ -1173,9 +1198,9 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int *rbehind,
swp_pager_strategy(bp);
/*
* wait for the page we want to complete. VPO_SWAPINPROG is always
* Wait for the pages we want to complete. VPO_SWAPINPROG is always
* cleared on completion. If an I/O error occurs, SWAPBLK_NONE
* is set in the meta-data.
* is set in the metadata for each page in the request.
*/
VM_OBJECT_WLOCK(object);
while ((m[0]->oflags & VPO_SWAPINPROG) != 0) {
@ -1192,15 +1217,10 @@ swap_pager_getpages(vm_object_t object, vm_page_t *m, int count, int *rbehind,
/*
* If we had an unrecoverable read error pages will not be valid.
*/
for (int i = 0; i < count; i++)
for (i = 0; i < reqcount; i++)
if (m[i]->valid != VM_PAGE_BITS_ALL)
return (VM_PAGER_ERROR);
if (rbehind)
*rbehind = 0;
if (rahead)
*rahead = 0;
return (VM_PAGER_OK);
/*
@ -1518,7 +1538,11 @@ swp_pager_async_iodone(struct buf *bp)
("swp_pager_async_iodone: page %p is mapped", m));
KASSERT(m->dirty == 0,
("swp_pager_async_iodone: page %p is dirty", m));
m->valid = VM_PAGE_BITS_ALL;
if (i < bp->b_pgbefore ||
i >= bp->b_npages - bp->b_pgafter)
vm_page_readahead_finish(m);
} else {
/*
* For write success, clear the dirty

View File

@ -1030,8 +1030,8 @@ vm_page_free_zero(vm_page_t m)
}
/*
* Unbusy and handle the page queueing for a page from the VOP_GETPAGES()
* array which was optionally read ahead or behind.
* Unbusy and handle the page queueing for a page from a getpages request that
* was optionally read ahead or behind.
*/
void
vm_page_readahead_finish(vm_page_t m)

View File

@ -126,9 +126,10 @@ struct alg {
{ "blf", 0, 8, 5, 56, CRYPTO_BLF_CBC },
{ "cast", 0, 8, 5, 16, CRYPTO_CAST_CBC },
{ "skj", 0, 8, 10, 10, CRYPTO_SKIPJACK_CBC },
{ "aes", 0, 16, 16, 16, CRYPTO_RIJNDAEL128_CBC},
{ "aes192", 0, 16, 24, 24, CRYPTO_RIJNDAEL128_CBC},
{ "aes256", 0, 16, 32, 32, CRYPTO_RIJNDAEL128_CBC},
{ "rij", 0, 16, 16, 16, CRYPTO_RIJNDAEL128_CBC},
{ "aes", 0, 16, 16, 16, CRYPTO_AES_CBC},
{ "aes192", 0, 16, 24, 24, CRYPTO_AES_CBC},
{ "aes256", 0, 16, 32, 32, CRYPTO_AES_CBC},
#ifdef notdef
{ "arc4", 0, 8, 1, 32, CRYPTO_ARC4 },
#endif
@ -139,19 +140,20 @@ struct alg {
{ "sha512", 1, 8, 64, 64, CRYPTO_SHA2_512_HMAC },
};
static void
void
usage(const char* cmd)
{
printf("usage: %s [-czsbv] [-d dev] [-a algorithm] [count] [size ...]\n",
cmd);
printf("where algorithm is one of:\n");
printf(" des 3des (default) blowfish cast skipjack\n");
printf(" aes (aka rijndael) aes192 aes256 arc4\n");
printf(" des 3des (default) blowfish cast skipjack rij\n");
printf(" aes aes192 aes256 arc4\n");
printf("count is the number of encrypt/decrypt ops to do\n");
printf("size is the number of bytes of text to encrypt+decrypt\n");
printf("\n");
printf("-c check the results (slows timing)\n");
printf("-d use specific device\n");
printf("-d use specific device, specify 'soft' for testing software implementations\n");
printf("\tNOTE: to use software you must set:\n\t sysctl kern.cryptodevallowsoft=1\n");
printf("-z run all available algorithms on a variety of sizes\n");
printf("-v be verbose\n");
printf("-b mark operations for batching\n");
@ -159,7 +161,7 @@ usage(const char* cmd)
exit(-1);
}
static struct alg*
struct alg*
getalgbycode(int cipher)
{
int i;
@ -170,7 +172,7 @@ getalgbycode(int cipher)
return NULL;
}
static struct alg*
struct alg*
getalgbyname(const char* name)
{
int i;
@ -181,10 +183,10 @@ getalgbyname(const char* name)
return NULL;
}
static int
int
devcrypto(void)
{
static int fd = -1;
int fd = -1;
if (fd < 0) {
fd = open(_PATH_DEV "crypto", O_RDWR, 0);
@ -196,11 +198,14 @@ devcrypto(void)
return fd;
}
static int
int
crlookup(const char *devname)
{
struct crypt_find_op find;
if (strncmp(devname, "soft", 4) == 0)
return CRYPTO_FLAG_SOFTWARE;
find.crid = -1;
strlcpy(find.name, devname, sizeof(find.name));
if (ioctl(devcrypto(), CIOCFINDDEV, &find) == -1)
@ -208,10 +213,10 @@ crlookup(const char *devname)
return find.crid;
}
static const char *
const char *
crfind(int crid)
{
static struct crypt_find_op find;
struct crypt_find_op find;
bzero(&find, sizeof(find));
find.crid = crid;
@ -220,7 +225,7 @@ crfind(int crid)
return find.name;
}
static int
int
crget(void)
{
int fd;
@ -232,7 +237,7 @@ crget(void)
return fd;
}
static char
char
rdigit(void)
{
const char a[] = {
@ -242,7 +247,7 @@ rdigit(void)
return 0x20+a[random()%nitems(a)];
}
static void
void
runtest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv)
{
int i, fd = crget();
@ -386,7 +391,7 @@ runtest(struct alg *alg, int count, int size, u_long cmd, struct timeval *tv)
}
#ifdef __FreeBSD__
static void
void
resetstats()
{
struct cryptostats stats;
@ -409,7 +414,7 @@ resetstats()
perror("kern.cryptostats");
}
static void
void
printt(const char* tag, struct cryptotstat *ts)
{
uint64_t avg, min, max;
@ -424,7 +429,7 @@ printt(const char* tag, struct cryptotstat *ts)
}
#endif
static void
void
runtests(struct alg *alg, int count, int size, u_long cmd, int threads, int profile)
{
int i, status;

View File

@ -82,7 +82,7 @@ genkeys(char *public, char *secret, char *pass)
MINT *pk = mp_itom(0);
MINT *sk = mp_itom(0);
MINT *tmp;
MINT *base = mp_itom(BASE);
MINT *base = mp_itom((short)BASE);
MINT *root = mp_itom(PROOT);
MINT *modulus = mp_xtom(HEXMODULUS);
short r;

View File

@ -2273,7 +2273,7 @@ e82545_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
int mac_provided;
/* Setup our softc */
sc = calloc(sizeof(*sc), 1);
sc = calloc(1, sizeof(*sc));
pi->pi_arg = sc;
sc->esc_pi = pi;

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 27, 2016
.Dd August 29, 2016
.Dt DEVCTL 8
.Os
.Sh NAME
@ -36,6 +36,10 @@
.Cm attach
.Ar device
.Nm
.Cm clear driver
.Op Fl f
.Ar device
.Nm
.Cm detach
.Op Fl f
.Ar device
@ -133,6 +137,21 @@ If the device is already attached to a device driver and the
.Fl f
flag is not specified,
the device will not be changed.
.It Xo Cm clear driver
.Op Fl f
.Ar device
.Xc
Clear a previously-forced driver name so that the device is able to use any
valid device driver.
After the previous name has been cleared,
the device is reprobed so that other device drivers may attach to it.
This can be used to undo an earlier
.Cm set driver
command.
If the device is currently attached to a device driver and the
.Fl f
flag is not specified,
the device will not be changed.
.It Cm rescan Ar device
Rescan a bus device checking for devices that have been added or
removed.

View File

@ -65,12 +65,13 @@ static int devctl_table_handler(struct devctl_command **start,
SET_DECLARE(DEVCTL_DATASET(top), struct devctl_command);
DEVCTL_TABLE(top, clear);
DEVCTL_TABLE(top, set);
static void
usage(void)
{
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
"usage: devctl attach device",
" devctl detach [-f] device",
" devctl disable [-f] device",
@ -78,6 +79,7 @@ usage(void)
" devctl suspend device",
" devctl resume device",
" devctl set driver [-f] device driver",
" devctl clear driver [-f] device",
" devctl rescan device",
" devctl delete [-f] device");
exit(1);
@ -261,6 +263,40 @@ set_driver(int ac, char **av)
}
DEVCTL_COMMAND(set, driver, set_driver);
static void
clear_driver_usage(void)
{
fprintf(stderr, "usage: devctl clear driver [-f] device\n");
exit(1);
}
static int
clear_driver(int ac, char **av)
{
bool force;
int ch;
force = false;
while ((ch = getopt(ac, av, "f")) != -1)
switch (ch) {
case 'f':
force = true;
break;
default:
clear_driver_usage();
}
ac -= optind;
av += optind;
if (ac != 1)
clear_driver_usage();
if (devctl_clear_driver(av[0], force) < 0)
err(1, "Failed to clear %s driver", av[0]);
return (0);
}
DEVCTL_COMMAND(clear, driver, clear_driver);
static int
rescan(int ac, char **av)
{