MFH@260917.
This commit is contained in:
commit
e9c152dbc2
@ -29,7 +29,7 @@
|
||||
.\" @(#)df.1 8.3 (Berkeley) 5/8/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 24, 2013
|
||||
.Dd January 16, 2014
|
||||
.Dt DF 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -83,13 +83,13 @@ Use 1073741824 byte (1 Gibibyte) blocks rather than the default.
|
||||
This overrides any
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl H
|
||||
.It Fl h
|
||||
.Dq Human-readable
|
||||
output.
|
||||
Use unit suffixes: Byte, Kibibyte, Mebibyte, Gibibyte, Tebibyte and
|
||||
Pebibyte (based on powers of 1024) in order to reduce the number of
|
||||
digits to four or fewer.
|
||||
.It Fl h
|
||||
.It Fl H
|
||||
.Dq Human-readable
|
||||
output.
|
||||
Use unit suffixes: Byte, Kilobyte, Megabyte,
|
||||
|
@ -3012,6 +3012,7 @@ zdb_read_block(char *thing, spa_t *spa)
|
||||
free(dup);
|
||||
return;
|
||||
}
|
||||
i += p - &flagstr[i + 1]; /* skip over the number */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,7 @@
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <libzfs.h>
|
||||
#include <libzfs_compat.h>
|
||||
|
||||
#undef verify /* both libzfs.h and zfs_context.h want to define this */
|
||||
|
||||
|
@ -16,6 +16,7 @@ CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/lib/libnvpair
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/fs/zfs
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common/sys
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/uts/common
|
||||
CFLAGS+= -I${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/zfs/
|
||||
CFLAGS+= -I${.CURDIR}/../../contrib/opensolaris/head
|
||||
CFLAGS+= -I${.CURDIR}/../../lib/libumem
|
||||
|
||||
|
@ -302,15 +302,6 @@
|
||||
(cp_parser_objc_declaration): Parses attribute list and passes it down
|
||||
to cp_parser_objc_class_interface/cp_parser_objc_protocol_declaration.
|
||||
|
||||
2007-07-24 Fariborz Jahanian <fjahanian@apple.com>
|
||||
|
||||
Radar 5355344
|
||||
* cp-tree.h (cp_objc_protocol_id_list): New declaration
|
||||
* cp-lang.c (cp_objc_protocol_id_list): New stub
|
||||
* parser.c (cp_parser_type_name): Added code to disambiguate
|
||||
conditional from a protocol type.
|
||||
(cp_parser_objc_tentative_protocol_refs_opt): New
|
||||
|
||||
2007-07-13 Fariborz Jahanian <fjahanian@apple.com>
|
||||
|
||||
Radar 5277239
|
||||
|
@ -1827,10 +1827,6 @@ static tree cp_parser_objc_identifier_list
|
||||
/* APPLE LOCAL end radar 3803157 - objc attribute */
|
||||
static tree cp_parser_objc_protocol_refs_opt
|
||||
(cp_parser *);
|
||||
/* APPLE LOCAL begin radar 5355344 */
|
||||
static bool cp_parser_objc_tentative_protocol_refs_opt
|
||||
(cp_parser *, tree *);
|
||||
/* APPLE LOCAL end radar 5355344 */
|
||||
static void cp_parser_objc_declaration
|
||||
(cp_parser *);
|
||||
static tree cp_parser_objc_statement
|
||||
@ -17873,32 +17869,6 @@ cp_parser_objc_protocol_refs_opt (cp_parser* parser)
|
||||
return protorefs;
|
||||
}
|
||||
|
||||
/* APPLE LOCAL begin radar 5355344 */
|
||||
/* This routine also parses a list of Objective-C protocol references; except that
|
||||
if list is not valid, it returns FALSE and back-tracks parsing. */
|
||||
|
||||
static bool
|
||||
cp_parser_objc_tentative_protocol_refs_opt (cp_parser* parser, tree *protorefs)
|
||||
{
|
||||
*protorefs = NULL_TREE;
|
||||
if(cp_lexer_next_token_is (parser->lexer, CPP_LESS))
|
||||
{
|
||||
cp_parser_parse_tentatively (parser);
|
||||
cp_lexer_consume_token (parser->lexer); /* Eat '<'. */
|
||||
*protorefs = cp_parser_objc_identifier_list (parser);
|
||||
if (!cp_objc_protocol_id_list (*protorefs))
|
||||
{
|
||||
cp_parser_abort_tentative_parse (parser);
|
||||
return false;
|
||||
}
|
||||
if (cp_parser_parse_definitely (parser))
|
||||
cp_parser_require (parser, CPP_GREATER, "`>'");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/* APPLE LOCAL end radar 5355344 */
|
||||
|
||||
/* Parse a Objective-C visibility specification. */
|
||||
|
||||
static void
|
||||
|
@ -34,9 +34,9 @@ OBJS= # added to below in various ways depending on TARGET_CPUARCH
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
#
|
||||
# When upgrading GCC, get the following defintions straight from Makefile.in
|
||||
#
|
||||
# Library members defined in libgcc2.c.
|
||||
# When upgrading GCC, obtain the following list from mklibgcc.in
|
||||
#
|
||||
LIB2FUNCS= _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 \
|
||||
_cmpdi2 _ucmpdi2 \
|
||||
_enable_execute_stack _trampoline __main _absvsi2 _absvdi2 _addvsi3 \
|
||||
@ -44,7 +44,7 @@ LIB2FUNCS= _muldi3 _negdi2 _lshrdi3 _ashldi3 _ashrdi3 \
|
||||
_ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _popcount_tab \
|
||||
_popcountsi2 _popcountdi2 _paritysi2 _paritydi2 _powisf2 _powidf2 \
|
||||
_powixf2 _powitf2 _mulsc3 _muldc3 _mulxc3 _multc3 _divsc3 _divdc3 \
|
||||
_divxc3 _divtc3
|
||||
_divxc3 _divtc3 _bswapsi2 _bswapdi2
|
||||
.if ${COMPILER_TYPE} != "clang" || ${TARGET_CPUARCH} != "arm"
|
||||
LIB2FUNCS+= _clear_cache
|
||||
.endif
|
||||
@ -119,8 +119,8 @@ LIB1ASMFUNCS = _dvmd_tls _bb_init_func
|
||||
.if ${MK_ARM_EABI} != "no"
|
||||
LIB2ADDEH = unwind-arm.c libunwind.S pr-support.c unwind-c.c
|
||||
# Some compilers generate __aeabi_ functions libgcc_s is missing
|
||||
DPADD+= ${LIBGCC}
|
||||
LDADD+= -lgcc
|
||||
DPADD+= ${LIBCOMPILER_RT}
|
||||
LDADD+= -lcompiler_rt
|
||||
.else
|
||||
LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c
|
||||
.endif
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#define _TTYS_OFF "off"
|
||||
#define _TTYS_ON "on"
|
||||
#define _TTYS_ONIFCONSOLE "onifconsole"
|
||||
#define _TTYS_SECURE "secure"
|
||||
#define _TTYS_INSECURE "insecure"
|
||||
#define _TTYS_WINDOW "window"
|
||||
|
@ -40,11 +40,11 @@ CFLAGS+=${CANCELPOINTS_CFLAGS}
|
||||
.endif
|
||||
|
||||
#
|
||||
# Only link with static libgcc.a (no libgcc_eh.a).
|
||||
# Link with static libcompiler_rt.a.
|
||||
#
|
||||
DPADD+= ${LIBGCC}
|
||||
DPADD+= ${LIBCOMPILER_RT}
|
||||
LDFLAGS+= -nodefaultlibs
|
||||
LDADD+= -lgcc
|
||||
LDADD+= -lcompiler_rt
|
||||
|
||||
.if ${MK_SSP} != "no"
|
||||
LDADD+= -lssp_nonshared
|
||||
|
@ -39,6 +39,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static char zapchar;
|
||||
static FILE *tf;
|
||||
static size_t lbsize;
|
||||
@ -64,6 +67,36 @@ getttynam(const char *tty)
|
||||
return (t);
|
||||
}
|
||||
|
||||
static int
|
||||
auto_tty_status(const char *ty_name)
|
||||
{
|
||||
size_t len;
|
||||
char *buf, *cons, *nextcons;
|
||||
|
||||
/* Check if this is an enabled kernel console line */
|
||||
buf = NULL;
|
||||
if (sysctlbyname("kern.console", NULL, &len, NULL, 0) == -1)
|
||||
return (0); /* Errors mean don't enable */
|
||||
buf = malloc(len);
|
||||
if (sysctlbyname("kern.console", buf, &len, NULL, 0) == -1)
|
||||
goto done;
|
||||
|
||||
if ((cons = strchr(buf, '/')) == NULL)
|
||||
goto done;
|
||||
*cons = '\0';
|
||||
nextcons = buf;
|
||||
while ((cons = strsep(&nextcons, ",")) != NULL && strlen(cons) != 0) {
|
||||
if (strcmp(cons, ty_name) == 0) {
|
||||
free(buf);
|
||||
return (TTY_ON);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
free(buf);
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct ttyent *
|
||||
getttyent(void)
|
||||
{
|
||||
@ -126,6 +159,8 @@ getttyent(void)
|
||||
tty.ty_status &= ~TTY_ON;
|
||||
else if (scmp(_TTYS_ON))
|
||||
tty.ty_status |= TTY_ON;
|
||||
else if (scmp(_TTYS_ONIFCONSOLE))
|
||||
tty.ty_status |= auto_tty_status(tty.ty_name);
|
||||
else if (scmp(_TTYS_SECURE))
|
||||
tty.ty_status |= TTY_SECURE;
|
||||
else if (scmp(_TTYS_INSECURE))
|
||||
|
@ -679,7 +679,7 @@ fetch_ssl_setup_transport_layer(SSL_CTX *ctx, int verbose)
|
||||
if (getenv("SSL_NO_TLS1") != NULL)
|
||||
ssl_ctx_options |= SSL_OP_NO_TLSv1;
|
||||
if (verbose)
|
||||
fetch_info("SSL options: %x", ssl_ctx_options);
|
||||
fetch_info("SSL options: %lx", ssl_ctx_options);
|
||||
SSL_CTX_set_options(ctx, ssl_ctx_options);
|
||||
}
|
||||
|
||||
|
@ -371,5 +371,5 @@ _kvm_kvatop(kvm_t *kd, u_long va, off_t *ofs)
|
||||
size_t sz;
|
||||
|
||||
sz = kd->vmst->kvatop(kd, va, ofs);
|
||||
return (sz);
|
||||
return ((sz > INT_MAX) ? INT_MAX : sz);
|
||||
}
|
||||
|
@ -102,8 +102,11 @@ ttys as a group.
|
||||
.Pp
|
||||
As flag values, the strings ``on'' and ``off'' specify that
|
||||
.Xr init 8
|
||||
should (should not) execute the command given in the second field,
|
||||
while ``secure'' (if ``on'' is also specified) allows users with a
|
||||
should (should not) execute the command given in the second field.
|
||||
``onifconsole'' will cause this line to be enabled if and only if it is
|
||||
an active kernel console device (it is equivalent to ``on'' in this
|
||||
case).
|
||||
The flag ``secure'' (if the console is enabled) allows users with a
|
||||
uid of 0 to login on
|
||||
this line.
|
||||
The flag ``dialin'' indicates that a tty entry describes a dialin
|
||||
|
@ -43,11 +43,12 @@ DPADD= ${LIBC_PIC}
|
||||
LDADD= -lc_pic
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "arm" && ${MK_ARM_EABI} != "no"
|
||||
# Some of the required math functions (div & mod) are implemented in libgcc
|
||||
# on ARM. The library also needs to be placed first to be correctly linked.
|
||||
# As some of the functions are used before we have shared libraries.
|
||||
DPADD+= ${LIBGCC}
|
||||
LDADD+= -lgcc
|
||||
# Some of the required math functions (div & mod) are implemented in
|
||||
# libcompiler_rt on ARM. The library also needs to be placed first to be
|
||||
# correctly linked. As some of the functions are used before we have
|
||||
# shared libraries.
|
||||
DPADD+= ${LIBCOMPILER_RT}
|
||||
LDADD+= -lcompiler_rt
|
||||
.endif
|
||||
|
||||
|
||||
|
@ -224,9 +224,9 @@ packagesystem: base.txz kernel.txz ${EXTRA_PACKAGES}
|
||||
touch ${.TARGET}
|
||||
|
||||
pkg-stage:
|
||||
.if !defined(NOPKG) && exists(${.CURDIR}/${TARGET}/pkg-stage.conf)
|
||||
sh ${.CURDIR}/scripts/pkg-stage.sh ${.CURDIR}/${TARGET}/pkg-stage.conf \
|
||||
${REVISION}
|
||||
.if !defined(NOPKG)
|
||||
env REPOS_DIR=${.CURDIR}/pkg_repos/ \
|
||||
sh ${.CURDIR}/scripts/pkg-stage.sh
|
||||
mkdir -p ${.OBJDIR}/dvd/packages/repos/
|
||||
cp ${.CURDIR}/scripts/FreeBSD_install_cdrom.conf \
|
||||
${.OBJDIR}/dvd/packages/repos/
|
||||
|
@ -1,36 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
export PKG_ABI="freebsd:${REVISION%.[0-9]*}:x86:64"
|
||||
export ASSUME_ALWAYS_YES=1
|
||||
export __PKG_CONF="/etc/pkg/FreeBSD.conf"
|
||||
export PACKAGESITE="http://pkg.FreeBSD.org/${PKG_ABI}/latest"
|
||||
export MIRROR_TYPE="SRV"
|
||||
export REPO_AUTOUPDATE="NO"
|
||||
export PKG_DBDIR="/tmp/pkg"
|
||||
export PKG_CACHEDIR="dvd/packages/${PKG_ABI}"
|
||||
export PERMISSIVE="YES"
|
||||
export PKGCMD="/usr/sbin/pkg -d -C ${__PKG_CONF}"
|
||||
|
||||
DVD_PACKAGES="archivers/unzip
|
||||
devel/subversion
|
||||
devel/subversion-static
|
||||
emulators/linux_base-f10
|
||||
misc/freebsd-doc-all
|
||||
net/mpd5
|
||||
net/rsync
|
||||
ports-mgmt/pkg
|
||||
ports-mgmt/portaudit
|
||||
ports-mgmt/portmaster
|
||||
shells/bash
|
||||
shells/zsh
|
||||
security/sudo
|
||||
sysutils/screen
|
||||
www/firefox
|
||||
www/links
|
||||
x11-drivers/xf86-video-vmware
|
||||
x11/gnome2
|
||||
x11/kde4
|
||||
x11/xorg"
|
@ -1,45 +1,24 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN"
|
||||
"../../../share/xml/freebsd50.dtd" [
|
||||
<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN" "release.ent">
|
||||
"http://www.FreeBSD.org/XML/share/xml/freebsd50.dtd" [
|
||||
<!ENTITY % release PUBLIC "-//FreeBSD//ENTITIES Release Specification//EN"
|
||||
"http://www.FreeBSD.org/release/XML/release.ent">
|
||||
%release;
|
||||
]>
|
||||
<!--
|
||||
FreeBSD errata document. Unlike some of the other RELNOTESng
|
||||
files, this file should remain as a single SGML file, so that
|
||||
the dollar FreeBSD dollar header has a meaningful modification
|
||||
time. This file is all but useless without a datestamp on it,
|
||||
so we'll take some extra care to make sure it has one.
|
||||
|
||||
(If we didn't do this, then the file with the datestamp might
|
||||
not be the one that received the last change in the document.)
|
||||
<article xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
version="5.0">
|
||||
<info>
|
||||
<title>&os; &release; Errata </title>
|
||||
|
||||
-->
|
||||
<article xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
|
||||
<info><title>&os; &release; Errata </title>
|
||||
|
||||
|
||||
<author><orgname>
|
||||
The &os; Project
|
||||
</orgname></author>
|
||||
<author><orgname>The &os; Project</orgname></author>
|
||||
|
||||
<pubdate>$FreeBSD$</pubdate>
|
||||
|
||||
<copyright>
|
||||
<year>2000</year>
|
||||
<year>2001</year>
|
||||
<year>2002</year>
|
||||
<year>2003</year>
|
||||
<year>2004</year>
|
||||
<year>2005</year>
|
||||
<year>2006</year>
|
||||
<year>2007</year>
|
||||
<year>2008</year>
|
||||
<year>2009</year>
|
||||
<year>2010</year>
|
||||
<year>2011</year>
|
||||
<year>2012</year>
|
||||
<year>2013</year>
|
||||
<year>2014</year>
|
||||
|
||||
<holder role="mailto:doc@FreeBSD.org">The &os; Documentation Project</holder>
|
||||
</copyright>
|
||||
|
||||
@ -50,20 +29,20 @@
|
||||
&tm-attrib.general;
|
||||
</legalnotice>
|
||||
|
||||
<abstract>
|
||||
<para>This document lists errata items for &os; &release;,
|
||||
containing significant information discovered after the release
|
||||
or too late in the release cycle to be otherwise included in the
|
||||
release documentation.
|
||||
This information includes security advisories, as well as news
|
||||
relating to the software or documentation that could affect its
|
||||
operation or usability. An up-to-date version of this document
|
||||
should always be consulted before installing this version of
|
||||
&os;.</para>
|
||||
<abstract>
|
||||
<para>This document lists errata items for &os; &release;,
|
||||
containing significant information discovered after the release
|
||||
or too late in the release cycle to be otherwise included in the
|
||||
release documentation.
|
||||
This information includes security advisories, as well as news
|
||||
relating to the software or documentation that could affect its
|
||||
operation or usability. An up-to-date version of this document
|
||||
should always be consulted before installing this version of
|
||||
&os;.</para>
|
||||
|
||||
<para>This errata document for &os; &release;
|
||||
will be maintained until the release of &os; &release.next;.</para>
|
||||
</abstract>
|
||||
<para>This errata document for &os; &release;
|
||||
will be maintained until the release of &os; &release.next;.</para>
|
||||
</abstract>
|
||||
</info>
|
||||
|
||||
<sect1 xml:id="intro">
|
||||
@ -80,44 +59,35 @@
|
||||
out of date by definition, but other copies are kept updated on
|
||||
the Internet and should be consulted as the <quote>current
|
||||
errata</quote> for this release. These other copies of the
|
||||
errata are located at <uri xlink:href="http://www.FreeBSD.org/releases/">http://www.FreeBSD.org/releases/</uri>, plus any sites
|
||||
errata are located at
|
||||
<link xlink:href="http://www.FreeBSD.org/releases/" />,
|
||||
plus any sites
|
||||
which keep up-to-date mirrors of this location.</para>
|
||||
|
||||
<para>Source and binary snapshots of &os; &release.branch; also
|
||||
contain up-to-date copies of this document (as of the time of
|
||||
the snapshot).</para>
|
||||
|
||||
<para>For a list of all &os; CERT security advisories, see <uri xlink:href="http://www.FreeBSD.org/security/">http://www.FreeBSD.org/security/</uri> or <uri xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/">ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/</uri>.</para>
|
||||
|
||||
<para>For a list of all &os; CERT security advisories, see
|
||||
<link xlink:href="http://www.FreeBSD.org/security/" />
|
||||
or <link xlink:href="ftp://ftp.FreeBSD.org/pub/FreeBSD/CERT/" />.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="security">
|
||||
<title>Security Advisories</title>
|
||||
|
||||
<para releasetype="current">No advisories.</para>
|
||||
|
||||
<para releasetype="release">No advisories.</para>
|
||||
|
||||
<para releasetype="snapshot">No advisories.</para>
|
||||
<para>No advisory.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="open-issues">
|
||||
<title>Open Issues</title>
|
||||
|
||||
<para releasetype="current">No open issues.</para>
|
||||
|
||||
<para releasetype="release">No open issues.</para>
|
||||
|
||||
<para releasetype="snapshot">No open issues.</para>
|
||||
<para>No open issues.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 xml:id="late-news">
|
||||
<title>Late-Breaking News</title>
|
||||
|
||||
<para releasetype="current">No news.</para>
|
||||
|
||||
<para releasetype="release">No news.</para>
|
||||
|
||||
<para releasetype="snapshot">No news.</para>
|
||||
<para>No news.</para>
|
||||
</sect1>
|
||||
</article>
|
||||
|
@ -723,14 +723,13 @@ hv_vmbus_load="YES"</programlisting> Alternatively, the Hyper-V drivers can be
|
||||
<sect1 xml:id="upgrade">
|
||||
<title>Upgrading from previous releases of &os;</title>
|
||||
|
||||
<para arch="amd64,i386">Beginning with &os; 6.2-RELEASE,
|
||||
binary upgrades between RELEASE versions (and snapshots of the
|
||||
various security branches) are supported using the
|
||||
&man.freebsd-update.8; utility. The binary upgrade procedure will
|
||||
update unmodified userland utilities, as well as unmodified GENERIC or
|
||||
SMP kernels distributed as a part of an official &os; release.
|
||||
The &man.freebsd-update.8; utility requires that the host being
|
||||
upgraded have Internet connectivity.</para>
|
||||
<para arch="amd64,i386">Binary upgrades between RELEASE versions
|
||||
(and snapshots of the various security branches) are supported
|
||||
using the &man.freebsd-update.8; utility. The binary upgrade
|
||||
procedure will update unmodified userland utilities, as well as
|
||||
unmodified GENERIC kernels distributed as a part of an official
|
||||
&os; release. The &man.freebsd-update.8; utility requires that
|
||||
the host being upgraded have Internet connectivity.</para>
|
||||
|
||||
<para>Source-based upgrades (those based on recompiling the &os;
|
||||
base system from source code) from previous versions are
|
||||
@ -738,7 +737,7 @@ hv_vmbus_load="YES"</programlisting> Alternatively, the Hyper-V drivers can be
|
||||
<filename>/usr/src/UPDATING</filename>.</para>
|
||||
|
||||
<important>
|
||||
<para>Upgrading &os; should, of course, only be attempted after
|
||||
<para>Upgrading &os; should only be attempted after
|
||||
backing up <emphasis>all</emphasis> data and configuration
|
||||
files.</para>
|
||||
</important>
|
||||
|
@ -1,36 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $FreeBSD$
|
||||
#
|
||||
|
||||
export PKG_ABI="freebsd:${REVISION%.[0-9]*}:x86:32"
|
||||
export ASSUME_ALWAYS_YES=1
|
||||
export __PKG_CONF="/etc/pkg/FreeBSD.conf"
|
||||
export PACKAGESITE="http://pkg.FreeBSD.org/${PKG_ABI}/latest"
|
||||
export MIRROR_TYPE="SRV"
|
||||
export REPO_AUTOUPDATE="NO"
|
||||
export PKG_DBDIR="/tmp/pkg"
|
||||
export PKG_CACHEDIR="dvd/packages/${PKG_ABI}"
|
||||
export PERMISSIVE="YES"
|
||||
export PKGCMD="/usr/sbin/pkg -d -C ${__PKG_CONF}"
|
||||
|
||||
DVD_PACKAGES="archivers/unzip
|
||||
devel/subversion
|
||||
devel/subversion-static
|
||||
emulators/linux_base-f10
|
||||
misc/freebsd-doc-all
|
||||
net/mpd5
|
||||
net/rsync
|
||||
ports-mgmt/pkg
|
||||
ports-mgmt/portaudit
|
||||
ports-mgmt/portmaster
|
||||
shells/bash
|
||||
shells/zsh
|
||||
security/sudo
|
||||
sysutils/screen
|
||||
www/firefox
|
||||
www/links
|
||||
x11-drivers/xf86-video-vmware
|
||||
x11/gnome2
|
||||
x11/kde4
|
||||
x11/xorg"
|
8
release/pkg_repos/release-dvd.conf
Normal file
8
release/pkg_repos/release-dvd.conf
Normal file
@ -0,0 +1,8 @@
|
||||
# $FreeBSD$
|
||||
release: {
|
||||
url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest",
|
||||
mirror_type: "srv",
|
||||
signature_type: "fingerprints",
|
||||
fingerprints: "/usr/share/keys/pkg",
|
||||
enabled: yes
|
||||
}
|
@ -5,24 +5,31 @@
|
||||
|
||||
set -e
|
||||
|
||||
usage() {
|
||||
echo "$(basename ${0}) /path/to/pkg-stage.conf revision"
|
||||
exit 1
|
||||
}
|
||||
export ASSUME_ALWAYS_YES=1
|
||||
export PKG_DBDIR="/tmp/pkg"
|
||||
export PERMISSIVE="YES"
|
||||
export REPO_AUTOUPDATE="NO"
|
||||
export PKGCMD="/usr/sbin/pkg -d"
|
||||
|
||||
if [ ! -e "${1}" ]; then
|
||||
echo "Configuration file not specified."
|
||||
echo
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ "$#" -lt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
# Source config file for this architecture.
|
||||
REVISION="${2}"
|
||||
. "${1}" || exit 1
|
||||
DVD_PACKAGES="archivers/unzip
|
||||
devel/subversion
|
||||
devel/subversion-static
|
||||
emulators/linux_base-f10
|
||||
misc/freebsd-doc-all
|
||||
net/mpd5
|
||||
net/rsync
|
||||
ports-mgmt/pkg
|
||||
ports-mgmt/portmaster
|
||||
shells/bash
|
||||
shells/zsh
|
||||
security/sudo
|
||||
sysutils/screen
|
||||
www/firefox
|
||||
www/links
|
||||
x11-drivers/xf86-video-vmware
|
||||
x11/gnome2
|
||||
x11/kde4
|
||||
x11/xorg"
|
||||
|
||||
# If NOPORTS is set for the release, do not attempt to build pkg(8).
|
||||
if [ ! -f /usr/ports/Makefile ]; then
|
||||
@ -33,8 +40,13 @@ if [ ! -x /usr/local/sbin/pkg ]; then
|
||||
/usr/bin/make -C /usr/ports/ports-mgmt/pkg install clean
|
||||
fi
|
||||
|
||||
export PKG_ABI=$(pkg -vv | grep ^ABI | awk '{print $3}')
|
||||
export PKG_CACHEDIR="dvd/packages/${PKG_ABI}"
|
||||
|
||||
/bin/mkdir -p ${PKG_CACHEDIR}
|
||||
|
||||
# Print pkg(8) information to make debugging easier.
|
||||
${PKGCMD} -vv
|
||||
${PKGCMD} update -f
|
||||
${PKGCMD} fetch -d ${DVD_PACKAGES}
|
||||
|
||||
|
@ -543,6 +543,7 @@ MAN= aac.4 \
|
||||
${_virtio.4} \
|
||||
${_virtio_balloon.4} \
|
||||
${_virtio_blk.4} \
|
||||
${_virtio_random.4} \
|
||||
${_virtio_scsi.4} \
|
||||
vkbd.4 \
|
||||
vlan.4 \
|
||||
@ -787,6 +788,7 @@ _nxge.4= nxge.4
|
||||
_virtio.4= virtio.4
|
||||
_virtio_balloon.4=virtio_balloon.4
|
||||
_virtio_blk.4= virtio_blk.4
|
||||
_virtio_random.4= virtio_random.4
|
||||
_virtio_scsi.4= virtio_scsi.4
|
||||
_vmx.4= vmx.4
|
||||
_vtnet.4= vtnet.4
|
||||
|
61
share/man/man4/virtio_random.4
Normal file
61
share/man/man4/virtio_random.4
Normal file
@ -0,0 +1,61 @@
|
||||
.\" Copyright (c) 2013 Bryan Venteicher
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 28, 2013
|
||||
.Dt VIRTIO_RANDOM 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm virtio_random
|
||||
.Nd VirtIO Entropy driver
|
||||
.Sh SYNOPSIS
|
||||
To compile this driver into the kernel,
|
||||
place the following lines in your
|
||||
kernel configuration file:
|
||||
.Bd -ragged -offset indent
|
||||
.Cd "device virtio_random"
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a
|
||||
module at boot time, place the following line in
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
virtio_random_load="YES"
|
||||
.Ed
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
device driver provides support for VirtIO entropy devices.
|
||||
.Pp
|
||||
The entropy device supplies high-quality randomness from the
|
||||
hypervisor to the guest.
|
||||
.Sh SEE ALSO
|
||||
.Xr random 4
|
||||
.Xr virtio 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
driver was written by
|
||||
.An Bryan Venteicher Aq bryanv@FreeBSD.org .
|
@ -29,7 +29,7 @@
|
||||
.\" $NetBSD: malloc.9,v 1.3 1996/11/11 00:05:11 lukem Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 15, 2012
|
||||
.Dd January 16, 2014
|
||||
.Dt MALLOC 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -214,17 +214,6 @@ of two for requests up to the size of a page of memory.
|
||||
For larger requests, one or more pages is allocated.
|
||||
While it should not be relied upon, this information may be useful for
|
||||
optimizing the efficiency of memory use.
|
||||
.Pp
|
||||
Programmers should be careful not to confuse the malloc flags
|
||||
.Dv M_NOWAIT
|
||||
and
|
||||
.Dv M_WAITOK
|
||||
with the
|
||||
.Xr mbuf 9
|
||||
flags
|
||||
.Dv M_DONTWAIT
|
||||
and
|
||||
.Dv M_WAIT .
|
||||
.Sh CONTEXT
|
||||
.Fn malloc ,
|
||||
.Fn realloc
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 20, 2013
|
||||
.Dd January 16, 2014
|
||||
.Dt MBUF 9
|
||||
.Os
|
||||
.\"
|
||||
@ -381,17 +381,6 @@ A number of other functions and macros related to
|
||||
have the same argument because they may
|
||||
at some point need to allocate new
|
||||
.Vt mbufs .
|
||||
.Pp
|
||||
Historical
|
||||
.Vt mbuf
|
||||
allocator (See
|
||||
.Sx HISTORY
|
||||
section) used allocation flags
|
||||
.Dv M_WAIT
|
||||
and
|
||||
.Dv M_DONTWAIT .
|
||||
These constants are kept for compatibility
|
||||
and their use in new code is discouraged.
|
||||
.It Fn MGETHDR mbuf how type
|
||||
Allocate an
|
||||
.Vt mbuf
|
||||
|
@ -36,6 +36,7 @@ LIBCAPSICUM?= ${DESTDIR}${LIBDIR}/libcapsicum.a
|
||||
LIBCASPER?= ${DESTDIR}${LIBDIR}/libcasper.a
|
||||
LIBCOM_ERR?= ${DESTDIR}${LIBDIR}/libcom_err.a
|
||||
LIBCOMPAT?= ${DESTDIR}${LIBDIR}/libcompat.a
|
||||
LIBCOMPILER_RT?=${DESTDIR}${LIBDIR}/libcompiler_rt.a
|
||||
LIBCRYPT?= ${DESTDIR}${LIBDIR}/libcrypt.a
|
||||
LIBCRYPTO?= ${DESTDIR}${LIBDIR}/libcrypto.a
|
||||
LIBCTF?= ${DESTDIR}${LIBDIR}/libctf.a
|
||||
@ -53,8 +54,6 @@ LIBFETCH?= ${DESTDIR}${LIBDIR}/libfetch.a
|
||||
LIBFL?= "don't use LIBFL, use LIBL"
|
||||
LIBFORM?= ${DESTDIR}${LIBDIR}/libform.a
|
||||
LIBG2C?= ${DESTDIR}${LIBDIR}/libg2c.a
|
||||
LIBGCC?= ${DESTDIR}${LIBDIR}/libgcc.a
|
||||
LIBGCC_PIC?= ${DESTDIR}${LIBDIR}/libgcc_pic.a
|
||||
LIBGEOM?= ${DESTDIR}${LIBDIR}/libgeom.a
|
||||
LIBGNUREGEX?= ${DESTDIR}${LIBDIR}/libgnuregex.a
|
||||
LIBGSSAPI?= ${DESTDIR}${LIBDIR}/libgssapi.a
|
||||
|
@ -472,6 +472,7 @@ device vtnet # VirtIO Ethernet device
|
||||
device virtio_blk # VirtIO Block device
|
||||
device virtio_scsi # VirtIO SCSI device
|
||||
device virtio_balloon # VirtIO Memory Balloon device
|
||||
device virtio_random # VirtIO Entropy device
|
||||
|
||||
device hyperv # HyperV drivers
|
||||
|
||||
|
14
sys/amd64/conf/VT
Normal file
14
sys/amd64/conf/VT
Normal file
@ -0,0 +1,14 @@
|
||||
# VT -- kernel config using the vt(9) system console instead of legacy syscons
|
||||
#
|
||||
# For more information see https://wiki.freebsd.org/Newcons
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
include GENERIC
|
||||
ident VT
|
||||
|
||||
nodevice sc
|
||||
nodevice vga
|
||||
|
||||
device vt
|
||||
device vt_vga
|
@ -330,13 +330,19 @@ vmcs_write(uint32_t encoding, uint64_t val)
|
||||
#define EXIT_REASON_XSETBV 55
|
||||
#define EXIT_REASON_APIC_WRITE 56
|
||||
|
||||
/*
|
||||
* NMI unblocking due to IRET.
|
||||
*
|
||||
* Applies to VM-exits due to hardware exception or EPT fault.
|
||||
*/
|
||||
#define EXIT_QUAL_NMIUDTI (1 << 12)
|
||||
/*
|
||||
* VMCS interrupt information fields
|
||||
*/
|
||||
#define VMCS_INTR_INFO_VALID (1U << 31)
|
||||
#define VMCS_INTR_INFO_TYPE(info) (((info) >> 8) & 0x7)
|
||||
#define VMCS_INTR_INFO_HW_INTR (0 << 8)
|
||||
#define VMCS_INTR_INFO_NMI (2 << 8)
|
||||
#define VMCS_INTR_VALID (1U << 31)
|
||||
#define VMCS_INTR_T_MASK 0x700 /* Interruption-info type */
|
||||
#define VMCS_INTR_T_HWINTR (0 << 8)
|
||||
#define VMCS_INTR_T_NMI (2 << 8)
|
||||
|
||||
/*
|
||||
* VMCS IDT-Vectoring information fields
|
||||
|
@ -146,21 +146,6 @@ static int vmx_initialized;
|
||||
SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, initialized, CTLFLAG_RD,
|
||||
&vmx_initialized, 0, "Intel VMX initialized");
|
||||
|
||||
/*
|
||||
* Virtual NMI blocking conditions.
|
||||
*
|
||||
* Some processor implementations also require NMI to be blocked if
|
||||
* the STI_BLOCKING bit is set. It is possible to detect this at runtime
|
||||
* based on the (exit_reason,exit_qual) tuple being set to
|
||||
* (EXIT_REASON_INVAL_VMCS, EXIT_QUAL_NMI_WHILE_STI_BLOCKING).
|
||||
*
|
||||
* We take the easy way out and also include STI_BLOCKING as one of the
|
||||
* gating items for vNMI injection.
|
||||
*/
|
||||
static uint64_t nmi_blocking_bits = VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING |
|
||||
VMCS_INTERRUPTIBILITY_NMI_BLOCKING |
|
||||
VMCS_INTERRUPTIBILITY_STI_BLOCKING;
|
||||
|
||||
/*
|
||||
* Optional capabilities
|
||||
*/
|
||||
@ -1020,121 +1005,149 @@ static void __inline
|
||||
vmx_set_int_window_exiting(struct vmx *vmx, int vcpu)
|
||||
{
|
||||
|
||||
vmx->cap[vcpu].proc_ctls |= PROCBASED_INT_WINDOW_EXITING;
|
||||
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
|
||||
if ((vmx->cap[vcpu].proc_ctls & PROCBASED_INT_WINDOW_EXITING) == 0) {
|
||||
vmx->cap[vcpu].proc_ctls |= PROCBASED_INT_WINDOW_EXITING;
|
||||
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting");
|
||||
}
|
||||
}
|
||||
|
||||
static void __inline
|
||||
vmx_clear_int_window_exiting(struct vmx *vmx, int vcpu)
|
||||
{
|
||||
|
||||
KASSERT((vmx->cap[vcpu].proc_ctls & PROCBASED_INT_WINDOW_EXITING) != 0,
|
||||
("intr_window_exiting not set: %#x", vmx->cap[vcpu].proc_ctls));
|
||||
vmx->cap[vcpu].proc_ctls &= ~PROCBASED_INT_WINDOW_EXITING;
|
||||
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting");
|
||||
}
|
||||
|
||||
static void __inline
|
||||
vmx_set_nmi_window_exiting(struct vmx *vmx, int vcpu)
|
||||
{
|
||||
|
||||
vmx->cap[vcpu].proc_ctls |= PROCBASED_NMI_WINDOW_EXITING;
|
||||
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
|
||||
if ((vmx->cap[vcpu].proc_ctls & PROCBASED_NMI_WINDOW_EXITING) == 0) {
|
||||
vmx->cap[vcpu].proc_ctls |= PROCBASED_NMI_WINDOW_EXITING;
|
||||
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting");
|
||||
}
|
||||
}
|
||||
|
||||
static void __inline
|
||||
vmx_clear_nmi_window_exiting(struct vmx *vmx, int vcpu)
|
||||
{
|
||||
|
||||
KASSERT((vmx->cap[vcpu].proc_ctls & PROCBASED_NMI_WINDOW_EXITING) != 0,
|
||||
("nmi_window_exiting not set %#x", vmx->cap[vcpu].proc_ctls));
|
||||
vmx->cap[vcpu].proc_ctls &= ~PROCBASED_NMI_WINDOW_EXITING;
|
||||
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, vmx->cap[vcpu].proc_ctls);
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting");
|
||||
}
|
||||
|
||||
static int
|
||||
#define NMI_BLOCKING (VMCS_INTERRUPTIBILITY_NMI_BLOCKING | \
|
||||
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)
|
||||
#define HWINTR_BLOCKING (VMCS_INTERRUPTIBILITY_STI_BLOCKING | \
|
||||
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)
|
||||
|
||||
static void
|
||||
vmx_inject_nmi(struct vmx *vmx, int vcpu)
|
||||
{
|
||||
uint64_t info, interruptibility;
|
||||
uint32_t gi, info;
|
||||
|
||||
/* Bail out if no NMI requested */
|
||||
if (!vm_nmi_pending(vmx->vm, vcpu))
|
||||
return (0);
|
||||
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
KASSERT((gi & NMI_BLOCKING) == 0, ("vmx_inject_nmi: invalid guest "
|
||||
"interruptibility-state %#x", gi));
|
||||
|
||||
interruptibility = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
if (interruptibility & nmi_blocking_bits)
|
||||
goto nmiblocked;
|
||||
info = vmcs_read(VMCS_ENTRY_INTR_INFO);
|
||||
KASSERT((info & VMCS_INTR_VALID) == 0, ("vmx_inject_nmi: invalid "
|
||||
"VM-entry interruption information %#x", info));
|
||||
|
||||
/*
|
||||
* Inject the virtual NMI. The vector must be the NMI IDT entry
|
||||
* or the VMCS entry check will fail.
|
||||
*/
|
||||
info = VMCS_INTR_INFO_NMI | VMCS_INTR_INFO_VALID;
|
||||
info |= IDT_NMI;
|
||||
info = IDT_NMI | VMCS_INTR_T_NMI | VMCS_INTR_VALID;
|
||||
vmcs_write(VMCS_ENTRY_INTR_INFO, info);
|
||||
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Injecting vNMI");
|
||||
|
||||
/* Clear the request */
|
||||
vm_nmi_clear(vmx->vm, vcpu);
|
||||
return (1);
|
||||
|
||||
nmiblocked:
|
||||
/*
|
||||
* Set the NMI Window Exiting execution control so we can inject
|
||||
* the virtual NMI as soon as blocking condition goes away.
|
||||
*/
|
||||
vmx_set_nmi_window_exiting(vmx, vcpu);
|
||||
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Enabling NMI window exiting");
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic)
|
||||
{
|
||||
int vector;
|
||||
uint64_t info, rflags, interruptibility;
|
||||
int vector, need_nmi_exiting;
|
||||
uint64_t rflags;
|
||||
uint32_t gi, info;
|
||||
|
||||
const int HWINTR_BLOCKED = VMCS_INTERRUPTIBILITY_STI_BLOCKING |
|
||||
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING;
|
||||
if (vm_nmi_pending(vmx->vm, vcpu)) {
|
||||
/*
|
||||
* If there are no conditions blocking NMI injection then
|
||||
* inject it directly here otherwise enable "NMI window
|
||||
* exiting" to inject it as soon as we can.
|
||||
*
|
||||
* We also check for STI_BLOCKING because some implementations
|
||||
* don't allow NMI injection in this case. If we are running
|
||||
* on a processor that doesn't have this restriction it will
|
||||
* immediately exit and the NMI will be injected in the
|
||||
* "NMI window exiting" handler.
|
||||
*/
|
||||
need_nmi_exiting = 1;
|
||||
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
if ((gi & (HWINTR_BLOCKING | NMI_BLOCKING)) == 0) {
|
||||
info = vmcs_read(VMCS_ENTRY_INTR_INFO);
|
||||
if ((info & VMCS_INTR_VALID) == 0) {
|
||||
vmx_inject_nmi(vmx, vcpu);
|
||||
need_nmi_exiting = 0;
|
||||
} else {
|
||||
VCPU_CTR1(vmx->vm, vcpu, "Cannot inject NMI "
|
||||
"due to VM-entry intr info %#x", info);
|
||||
}
|
||||
} else {
|
||||
VCPU_CTR1(vmx->vm, vcpu, "Cannot inject NMI due to "
|
||||
"Guest Interruptibility-state %#x", gi);
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is already an interrupt pending then just return.
|
||||
*
|
||||
* This could happen if an interrupt was injected on a prior
|
||||
* VM entry but the actual entry into guest mode was aborted
|
||||
* because of a pending AST.
|
||||
*/
|
||||
info = vmcs_read(VMCS_ENTRY_INTR_INFO);
|
||||
if (info & VMCS_INTR_INFO_VALID)
|
||||
return;
|
||||
|
||||
/*
|
||||
* NMI injection has priority so deal with those first
|
||||
*/
|
||||
if (vmx_inject_nmi(vmx, vcpu))
|
||||
return;
|
||||
if (need_nmi_exiting)
|
||||
vmx_set_nmi_window_exiting(vmx, vcpu);
|
||||
}
|
||||
|
||||
if (virtual_interrupt_delivery) {
|
||||
vmx_inject_pir(vlapic);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is already an interrupt pending then just return. This
|
||||
* could happen for multiple reasons:
|
||||
* - A vectoring VM-entry was aborted due to astpending or rendezvous.
|
||||
* - A VM-exit happened during event injection.
|
||||
* - A NMI was injected above or after "NMI window exiting" VM-exit.
|
||||
*/
|
||||
info = vmcs_read(VMCS_ENTRY_INTR_INFO);
|
||||
if (info & VMCS_INTR_VALID)
|
||||
return;
|
||||
|
||||
/* Ask the local apic for a vector to inject */
|
||||
if (!vlapic_pending_intr(vlapic, &vector))
|
||||
return;
|
||||
|
||||
if (vector < 32 || vector > 255)
|
||||
panic("vmx_inject_interrupts: invalid vector %d\n", vector);
|
||||
KASSERT(vector >= 32 && vector <= 255, ("invalid vector %d", vector));
|
||||
|
||||
/* Check RFLAGS.IF and the interruptibility state of the guest */
|
||||
rflags = vmcs_read(VMCS_GUEST_RFLAGS);
|
||||
if ((rflags & PSL_I) == 0)
|
||||
goto cantinject;
|
||||
|
||||
interruptibility = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
if (interruptibility & HWINTR_BLOCKED)
|
||||
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
if (gi & HWINTR_BLOCKING)
|
||||
goto cantinject;
|
||||
|
||||
/* Inject the interrupt */
|
||||
info = VMCS_INTR_INFO_HW_INTR | VMCS_INTR_INFO_VALID;
|
||||
info = VMCS_INTR_T_HWINTR | VMCS_INTR_VALID;
|
||||
info |= vector;
|
||||
vmcs_write(VMCS_ENTRY_INTR_INFO, info);
|
||||
|
||||
@ -1151,8 +1164,37 @@ vmx_inject_interrupts(struct vmx *vmx, int vcpu, struct vlapic *vlapic)
|
||||
* the interrupt as soon as blocking condition goes away.
|
||||
*/
|
||||
vmx_set_int_window_exiting(vmx, vcpu);
|
||||
}
|
||||
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Enabling interrupt window exiting");
|
||||
/*
|
||||
* If the Virtual NMIs execution control is '1' then the logical processor
|
||||
* tracks virtual-NMI blocking in the Guest Interruptibility-state field of
|
||||
* the VMCS. An IRET instruction in VMX non-root operation will remove any
|
||||
* virtual-NMI blocking.
|
||||
*
|
||||
* This unblocking occurs even if the IRET causes a fault. In this case the
|
||||
* hypervisor needs to restore virtual-NMI blocking before resuming the guest.
|
||||
*/
|
||||
static void
|
||||
vmx_restore_nmi_blocking(struct vmx *vmx, int vcpuid)
|
||||
{
|
||||
uint32_t gi;
|
||||
|
||||
VCPU_CTR0(vmx->vm, vcpuid, "Restore Virtual-NMI blocking");
|
||||
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
gi |= VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
|
||||
vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi);
|
||||
}
|
||||
|
||||
static void
|
||||
vmx_clear_nmi_blocking(struct vmx *vmx, int vcpuid)
|
||||
{
|
||||
uint32_t gi;
|
||||
|
||||
VCPU_CTR0(vmx->vm, vcpuid, "Clear Virtual-NMI blocking");
|
||||
gi = vmcs_read(VMCS_GUEST_INTERRUPTIBILITY);
|
||||
gi &= ~VMCS_INTERRUPTIBILITY_NMI_BLOCKING;
|
||||
vmcs_write(VMCS_GUEST_INTERRUPTIBILITY, gi);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1448,6 +1490,8 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
uint64_t qual, gpa;
|
||||
bool retu;
|
||||
|
||||
CTASSERT((PINBASED_CTLS_ONE_SETTING & PINBASED_VIRTUAL_NMI) != 0);
|
||||
|
||||
handled = 0;
|
||||
vmxctx = &vmx->ctx[vcpu];
|
||||
|
||||
@ -1480,9 +1524,20 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
vmcs_write(VMCS_ENTRY_EXCEPTION_ERROR,
|
||||
idtvec_err);
|
||||
}
|
||||
/*
|
||||
* If 'virtual NMIs' are being used and the VM-exit
|
||||
* happened while injecting an NMI during the previous
|
||||
* VM-entry, then clear "blocking by NMI" in the Guest
|
||||
* Interruptibility-state.
|
||||
*/
|
||||
if ((idtvec_info & VMCS_INTR_T_MASK) ==
|
||||
VMCS_INTR_T_NMI) {
|
||||
vmx_clear_nmi_blocking(vmx, vcpu);
|
||||
}
|
||||
vmcs_write(VMCS_ENTRY_INST_LENGTH, vmexit->inst_length);
|
||||
}
|
||||
default:
|
||||
idtvec_info = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1543,7 +1598,6 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
case EXIT_REASON_INTR_WINDOW:
|
||||
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INTR_WINDOW, 1);
|
||||
vmx_clear_int_window_exiting(vmx, vcpu);
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Disabling interrupt window exiting");
|
||||
return (1);
|
||||
case EXIT_REASON_EXT_INTR:
|
||||
/*
|
||||
@ -1556,8 +1610,8 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
* this virtual interrupt during the subsequent VM enter.
|
||||
*/
|
||||
intr_info = vmcs_read(VMCS_EXIT_INTR_INFO);
|
||||
KASSERT((intr_info & VMCS_INTR_INFO_VALID) != 0 &&
|
||||
VMCS_INTR_INFO_TYPE(intr_info) == 0,
|
||||
KASSERT((intr_info & VMCS_INTR_VALID) != 0 &&
|
||||
(intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_HWINTR,
|
||||
("VM exit interruption info invalid: %#x", intr_info));
|
||||
vmx_trigger_hostintr(intr_info & 0xff);
|
||||
|
||||
@ -1569,9 +1623,10 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
return (1);
|
||||
case EXIT_REASON_NMI_WINDOW:
|
||||
/* Exit to allow the pending virtual NMI to be injected */
|
||||
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_NMI_WINDOW, 1);
|
||||
if (vm_nmi_pending(vmx->vm, vcpu))
|
||||
vmx_inject_nmi(vmx, vcpu);
|
||||
vmx_clear_nmi_window_exiting(vmx, vcpu);
|
||||
VCPU_CTR0(vmx->vm, vcpu, "Disabling NMI window exiting");
|
||||
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_NMI_WINDOW, 1);
|
||||
return (1);
|
||||
case EXIT_REASON_INOUT:
|
||||
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_INOUT, 1);
|
||||
@ -1587,6 +1642,23 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_CPUID, 1);
|
||||
handled = vmx_handle_cpuid(vmx->vm, vcpu, vmxctx);
|
||||
break;
|
||||
case EXIT_REASON_EXCEPTION:
|
||||
intr_info = vmcs_read(VMCS_EXIT_INTR_INFO);
|
||||
KASSERT((intr_info & VMCS_INTR_VALID) != 0,
|
||||
("VM exit interruption info invalid: %#x", intr_info));
|
||||
/*
|
||||
* If Virtual NMIs control is 1 and the VM-exit is due to a
|
||||
* fault encountered during the execution of IRET then we must
|
||||
* restore the state of "virtual-NMI blocking" before resuming
|
||||
* the guest.
|
||||
*
|
||||
* See "Resuming Guest Software after Handling an Exception".
|
||||
*/
|
||||
if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 &&
|
||||
(intr_info & 0xff) != IDT_DF &&
|
||||
(intr_info & EXIT_QUAL_NMIUDTI) != 0)
|
||||
vmx_restore_nmi_blocking(vmx, vcpu);
|
||||
break;
|
||||
case EXIT_REASON_EPT_FAULT:
|
||||
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_EPT_FAULT, 1);
|
||||
/*
|
||||
@ -1605,6 +1677,17 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
|
||||
vmexit->u.inst_emul.gla = vmcs_gla();
|
||||
vmexit->u.inst_emul.cr3 = vmcs_guest_cr3();
|
||||
}
|
||||
/*
|
||||
* If Virtual NMIs control is 1 and the VM-exit is due to an
|
||||
* EPT fault during the execution of IRET then we must restore
|
||||
* the state of "virtual-NMI blocking" before resuming.
|
||||
*
|
||||
* See description of "NMI unblocking due to IRET" in
|
||||
* "Exit Qualification for EPT Violations".
|
||||
*/
|
||||
if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 &&
|
||||
(qual & EXIT_QUAL_NMIUDTI) != 0)
|
||||
vmx_restore_nmi_blocking(vmx, vcpu);
|
||||
break;
|
||||
case EXIT_REASON_APIC_ACCESS:
|
||||
handled = vmx_handle_apic_access(vmx, vcpu, vmexit);
|
||||
@ -2039,11 +2122,11 @@ vmx_inject(void *arg, int vcpu, int type, int vector, uint32_t code,
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
if (info & VMCS_INTR_INFO_VALID)
|
||||
if (info & VMCS_INTR_VALID)
|
||||
return (EAGAIN);
|
||||
|
||||
info = vector | (type_map[type] << 8) | (code_valid ? 1 << 11 : 0);
|
||||
info |= VMCS_INTR_INFO_VALID;
|
||||
info |= VMCS_INTR_VALID;
|
||||
error = vmcs_setreg(vmcs, 0, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), info);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
296
sys/arm/at91/at91_gpio.h
Normal file
296
sys/arm/at91/at91_gpio.h
Normal file
@ -0,0 +1,296 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 M. Warner Losh. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef ARM_AT91_AT91_GPIO_H
|
||||
#define ARM_AT91_AT91_GPIO_H
|
||||
|
||||
typedef uint32_t at91_pin_t;
|
||||
|
||||
#define AT91_PIN_NONE 0xfffffffful /* No pin / Not GPIO controlled */
|
||||
|
||||
/*
|
||||
* Map Atmel PIO pins to a unique number. They are just numbered sequentially.
|
||||
*/
|
||||
|
||||
#define AT91_PIN_PA0 (at91_pin_t)0
|
||||
#define AT91_PIN_PA1 (at91_pin_t)1
|
||||
#define AT91_PIN_PA2 (at91_pin_t)2
|
||||
#define AT91_PIN_PA3 (at91_pin_t)3
|
||||
#define AT91_PIN_PA4 (at91_pin_t)4
|
||||
#define AT91_PIN_PA5 (at91_pin_t)5
|
||||
#define AT91_PIN_PA6 (at91_pin_t)6
|
||||
#define AT91_PIN_PA7 (at91_pin_t)7
|
||||
#define AT91_PIN_PA8 (at91_pin_t)8
|
||||
#define AT91_PIN_PA9 (at91_pin_t)9
|
||||
#define AT91_PIN_PA10 (at91_pin_t)10
|
||||
#define AT91_PIN_PA11 (at91_pin_t)11
|
||||
#define AT91_PIN_PA12 (at91_pin_t)12
|
||||
#define AT91_PIN_PA13 (at91_pin_t)13
|
||||
#define AT91_PIN_PA14 (at91_pin_t)14
|
||||
#define AT91_PIN_PA15 (at91_pin_t)15
|
||||
#define AT91_PIN_PA16 (at91_pin_t)16
|
||||
#define AT91_PIN_PA17 (at91_pin_t)17
|
||||
#define AT91_PIN_PA18 (at91_pin_t)18
|
||||
#define AT91_PIN_PA19 (at91_pin_t)19
|
||||
#define AT91_PIN_PA20 (at91_pin_t)20
|
||||
#define AT91_PIN_PA21 (at91_pin_t)21
|
||||
#define AT91_PIN_PA22 (at91_pin_t)22
|
||||
#define AT91_PIN_PA23 (at91_pin_t)23
|
||||
#define AT91_PIN_PA24 (at91_pin_t)24
|
||||
#define AT91_PIN_PA25 (at91_pin_t)25
|
||||
#define AT91_PIN_PA26 (at91_pin_t)26
|
||||
#define AT91_PIN_PA27 (at91_pin_t)27
|
||||
#define AT91_PIN_PA28 (at91_pin_t)28
|
||||
#define AT91_PIN_PA29 (at91_pin_t)29
|
||||
#define AT91_PIN_PA30 (at91_pin_t)30
|
||||
#define AT91_PIN_PA31 (at91_pin_t)31
|
||||
#define AT91_PIN_PB0 (at91_pin_t)32
|
||||
#define AT91_PIN_PB1 (at91_pin_t)33
|
||||
#define AT91_PIN_PB2 (at91_pin_t)34
|
||||
#define AT91_PIN_PB3 (at91_pin_t)35
|
||||
#define AT91_PIN_PB4 (at91_pin_t)36
|
||||
#define AT91_PIN_PB5 (at91_pin_t)37
|
||||
#define AT91_PIN_PB6 (at91_pin_t)38
|
||||
#define AT91_PIN_PB7 (at91_pin_t)39
|
||||
#define AT91_PIN_PB8 (at91_pin_t)40
|
||||
#define AT91_PIN_PB9 (at91_pin_t)41
|
||||
#define AT91_PIN_PB10 (at91_pin_t)42
|
||||
#define AT91_PIN_PB11 (at91_pin_t)43
|
||||
#define AT91_PIN_PB12 (at91_pin_t)44
|
||||
#define AT91_PIN_PB13 (at91_pin_t)45
|
||||
#define AT91_PIN_PB14 (at91_pin_t)46
|
||||
#define AT91_PIN_PB15 (at91_pin_t)47
|
||||
#define AT91_PIN_PB16 (at91_pin_t)48
|
||||
#define AT91_PIN_PB17 (at91_pin_t)49
|
||||
#define AT91_PIN_PB18 (at91_pin_t)50
|
||||
#define AT91_PIN_PB19 (at91_pin_t)51
|
||||
#define AT91_PIN_PB20 (at91_pin_t)52
|
||||
#define AT91_PIN_PB21 (at91_pin_t)53
|
||||
#define AT91_PIN_PB22 (at91_pin_t)54
|
||||
#define AT91_PIN_PB23 (at91_pin_t)55
|
||||
#define AT91_PIN_PB24 (at91_pin_t)56
|
||||
#define AT91_PIN_PB25 (at91_pin_t)57
|
||||
#define AT91_PIN_PB26 (at91_pin_t)58
|
||||
#define AT91_PIN_PB27 (at91_pin_t)59
|
||||
#define AT91_PIN_PB28 (at91_pin_t)60
|
||||
#define AT91_PIN_PB29 (at91_pin_t)61
|
||||
#define AT91_PIN_PB30 (at91_pin_t)62
|
||||
#define AT91_PIN_PB31 (at91_pin_t)63
|
||||
#define AT91_PIN_PC0 (at91_pin_t)64
|
||||
#define AT91_PIN_PC1 (at91_pin_t)65
|
||||
#define AT91_PIN_PC2 (at91_pin_t)66
|
||||
#define AT91_PIN_PC3 (at91_pin_t)67
|
||||
#define AT91_PIN_PC4 (at91_pin_t)68
|
||||
#define AT91_PIN_PC5 (at91_pin_t)69
|
||||
#define AT91_PIN_PC6 (at91_pin_t)70
|
||||
#define AT91_PIN_PC7 (at91_pin_t)71
|
||||
#define AT91_PIN_PC8 (at91_pin_t)72
|
||||
#define AT91_PIN_PC9 (at91_pin_t)73
|
||||
#define AT91_PIN_PC10 (at91_pin_t)74
|
||||
#define AT91_PIN_PC11 (at91_pin_t)75
|
||||
#define AT91_PIN_PC12 (at91_pin_t)76
|
||||
#define AT91_PIN_PC13 (at91_pin_t)77
|
||||
#define AT91_PIN_PC14 (at91_pin_t)78
|
||||
#define AT91_PIN_PC15 (at91_pin_t)79
|
||||
#define AT91_PIN_PC16 (at91_pin_t)80
|
||||
#define AT91_PIN_PC17 (at91_pin_t)81
|
||||
#define AT91_PIN_PC18 (at91_pin_t)82
|
||||
#define AT91_PIN_PC19 (at91_pin_t)83
|
||||
#define AT91_PIN_PC20 (at91_pin_t)84
|
||||
#define AT91_PIN_PC21 (at91_pin_t)85
|
||||
#define AT91_PIN_PC22 (at91_pin_t)86
|
||||
#define AT91_PIN_PC23 (at91_pin_t)87
|
||||
#define AT91_PIN_PC24 (at91_pin_t)88
|
||||
#define AT91_PIN_PC25 (at91_pin_t)89
|
||||
#define AT91_PIN_PC26 (at91_pin_t)90
|
||||
#define AT91_PIN_PC27 (at91_pin_t)91
|
||||
#define AT91_PIN_PC28 (at91_pin_t)92
|
||||
#define AT91_PIN_PC29 (at91_pin_t)93
|
||||
#define AT91_PIN_PC30 (at91_pin_t)94
|
||||
#define AT91_PIN_PC31 (at91_pin_t)95
|
||||
#define AT91_PIN_PD0 (at91_pin_t)96
|
||||
#define AT91_PIN_PD1 (at91_pin_t)97
|
||||
#define AT91_PIN_PD2 (at91_pin_t)98
|
||||
#define AT91_PIN_PD3 (at91_pin_t)99
|
||||
#define AT91_PIN_PD4 (at91_pin_t)100
|
||||
#define AT91_PIN_PD5 (at91_pin_t)101
|
||||
#define AT91_PIN_PD6 (at91_pin_t)102
|
||||
#define AT91_PIN_PD7 (at91_pin_t)103
|
||||
#define AT91_PIN_PD8 (at91_pin_t)104
|
||||
#define AT91_PIN_PD9 (at91_pin_t)105
|
||||
#define AT91_PIN_PD10 (at91_pin_t)106
|
||||
#define AT91_PIN_PD11 (at91_pin_t)107
|
||||
#define AT91_PIN_PD12 (at91_pin_t)108
|
||||
#define AT91_PIN_PD13 (at91_pin_t)109
|
||||
#define AT91_PIN_PD14 (at91_pin_t)110
|
||||
#define AT91_PIN_PD15 (at91_pin_t)111
|
||||
#define AT91_PIN_PD16 (at91_pin_t)112
|
||||
#define AT91_PIN_PD17 (at91_pin_t)113
|
||||
#define AT91_PIN_PD18 (at91_pin_t)114
|
||||
#define AT91_PIN_PD19 (at91_pin_t)115
|
||||
#define AT91_PIN_PD20 (at91_pin_t)116
|
||||
#define AT91_PIN_PD21 (at91_pin_t)117
|
||||
#define AT91_PIN_PD22 (at91_pin_t)118
|
||||
#define AT91_PIN_PD23 (at91_pin_t)119
|
||||
#define AT91_PIN_PD24 (at91_pin_t)120
|
||||
#define AT91_PIN_PD25 (at91_pin_t)121
|
||||
#define AT91_PIN_PD26 (at91_pin_t)122
|
||||
#define AT91_PIN_PD27 (at91_pin_t)123
|
||||
#define AT91_PIN_PD28 (at91_pin_t)124
|
||||
#define AT91_PIN_PD29 (at91_pin_t)125
|
||||
#define AT91_PIN_PD30 (at91_pin_t)126
|
||||
#define AT91_PIN_PD31 (at91_pin_t)127
|
||||
#define AT91_PIN_PE0 (at91_pin_t)128
|
||||
#define AT91_PIN_PE1 (at91_pin_t)129
|
||||
#define AT91_PIN_PE2 (at91_pin_t)130
|
||||
#define AT91_PIN_PE3 (at91_pin_t)131
|
||||
#define AT91_PIN_PE4 (at91_pin_t)132
|
||||
#define AT91_PIN_PE5 (at91_pin_t)133
|
||||
#define AT91_PIN_PE6 (at91_pin_t)134
|
||||
#define AT91_PIN_PE7 (at91_pin_t)135
|
||||
#define AT91_PIN_PE8 (at91_pin_t)136
|
||||
#define AT91_PIN_PE9 (at91_pin_t)137
|
||||
#define AT91_PIN_PE10 (at91_pin_t)138
|
||||
#define AT91_PIN_PE11 (at91_pin_t)139
|
||||
#define AT91_PIN_PE12 (at91_pin_t)140
|
||||
#define AT91_PIN_PE13 (at91_pin_t)141
|
||||
#define AT91_PIN_PE14 (at91_pin_t)142
|
||||
#define AT91_PIN_PE15 (at91_pin_t)143
|
||||
#define AT91_PIN_PE16 (at91_pin_t)144
|
||||
#define AT91_PIN_PE17 (at91_pin_t)145
|
||||
#define AT91_PIN_PE18 (at91_pin_t)146
|
||||
#define AT91_PIN_PE19 (at91_pin_t)147
|
||||
#define AT91_PIN_PE20 (at91_pin_t)148
|
||||
#define AT91_PIN_PE21 (at91_pin_t)149
|
||||
#define AT91_PIN_PE22 (at91_pin_t)150
|
||||
#define AT91_PIN_PE23 (at91_pin_t)151
|
||||
#define AT91_PIN_PE24 (at91_pin_t)152
|
||||
#define AT91_PIN_PE25 (at91_pin_t)153
|
||||
#define AT91_PIN_PE26 (at91_pin_t)154
|
||||
#define AT91_PIN_PE27 (at91_pin_t)155
|
||||
#define AT91_PIN_PE28 (at91_pin_t)156
|
||||
#define AT91_PIN_PE29 (at91_pin_t)157
|
||||
#define AT91_PIN_PE30 (at91_pin_t)158
|
||||
#define AT91_PIN_PE31 (at91_pin_t)159
|
||||
#define AT91_PIN_PF0 (at91_pin_t)160
|
||||
#define AT91_PIN_PF1 (at91_pin_t)161
|
||||
#define AT91_PIN_PF2 (at91_pin_t)162
|
||||
#define AT91_PIN_PF3 (at91_pin_t)163
|
||||
#define AT91_PIN_PF4 (at91_pin_t)164
|
||||
#define AT91_PIN_PF5 (at91_pin_t)165
|
||||
#define AT91_PIN_PF6 (at91_pin_t)166
|
||||
#define AT91_PIN_PF7 (at91_pin_t)167
|
||||
#define AT91_PIN_PF8 (at91_pin_t)168
|
||||
#define AT91_PIN_PF9 (at91_pin_t)169
|
||||
#define AT91_PIN_PF10 (at91_pin_t)170
|
||||
#define AT91_PIN_PF11 (at91_pin_t)171
|
||||
#define AT91_PIN_PF12 (at91_pin_t)172
|
||||
#define AT91_PIN_PF13 (at91_pin_t)173
|
||||
#define AT91_PIN_PF14 (at91_pin_t)174
|
||||
#define AT91_PIN_PF15 (at91_pin_t)175
|
||||
#define AT91_PIN_PF16 (at91_pin_t)176
|
||||
#define AT91_PIN_PF17 (at91_pin_t)177
|
||||
#define AT91_PIN_PF18 (at91_pin_t)178
|
||||
#define AT91_PIN_PF19 (at91_pin_t)179
|
||||
#define AT91_PIN_PF20 (at91_pin_t)180
|
||||
#define AT91_PIN_PF21 (at91_pin_t)181
|
||||
#define AT91_PIN_PF22 (at91_pin_t)182
|
||||
#define AT91_PIN_PF23 (at91_pin_t)183
|
||||
#define AT91_PIN_PF24 (at91_pin_t)184
|
||||
#define AT91_PIN_PF25 (at91_pin_t)185
|
||||
#define AT91_PIN_PF26 (at91_pin_t)186
|
||||
#define AT91_PIN_PF27 (at91_pin_t)187
|
||||
#define AT91_PIN_PF28 (at91_pin_t)188
|
||||
#define AT91_PIN_PF29 (at91_pin_t)189
|
||||
#define AT91_PIN_PF30 (at91_pin_t)190
|
||||
#define AT91_PIN_PF31 (at91_pin_t)191
|
||||
#define AT91_PIN_PG0 (at91_pin_t)192
|
||||
#define AT91_PIN_PG1 (at91_pin_t)193
|
||||
#define AT91_PIN_PG2 (at91_pin_t)194
|
||||
#define AT91_PIN_PG3 (at91_pin_t)195
|
||||
#define AT91_PIN_PG4 (at91_pin_t)196
|
||||
#define AT91_PIN_PG5 (at91_pin_t)197
|
||||
#define AT91_PIN_PG6 (at91_pin_t)198
|
||||
#define AT91_PIN_PG7 (at91_pin_t)199
|
||||
#define AT91_PIN_PG8 (at91_pin_t)200
|
||||
#define AT91_PIN_PG9 (at91_pin_t)201
|
||||
#define AT91_PIN_PG10 (at91_pin_t)202
|
||||
#define AT91_PIN_PG11 (at91_pin_t)203
|
||||
#define AT91_PIN_PG12 (at91_pin_t)204
|
||||
#define AT91_PIN_PG13 (at91_pin_t)205
|
||||
#define AT91_PIN_PG14 (at91_pin_t)206
|
||||
#define AT91_PIN_PG15 (at91_pin_t)207
|
||||
#define AT91_PIN_PG16 (at91_pin_t)208
|
||||
#define AT91_PIN_PG17 (at91_pin_t)209
|
||||
#define AT91_PIN_PG18 (at91_pin_t)210
|
||||
#define AT91_PIN_PG19 (at91_pin_t)211
|
||||
#define AT91_PIN_PG20 (at91_pin_t)212
|
||||
#define AT91_PIN_PG21 (at91_pin_t)213
|
||||
#define AT91_PIN_PG22 (at91_pin_t)214
|
||||
#define AT91_PIN_PG23 (at91_pin_t)215
|
||||
#define AT91_PIN_PG24 (at91_pin_t)216
|
||||
#define AT91_PIN_PG25 (at91_pin_t)217
|
||||
#define AT91_PIN_PG26 (at91_pin_t)218
|
||||
#define AT91_PIN_PG27 (at91_pin_t)219
|
||||
#define AT91_PIN_PG28 (at91_pin_t)220
|
||||
#define AT91_PIN_PG29 (at91_pin_t)221
|
||||
#define AT91_PIN_PG30 (at91_pin_t)222
|
||||
#define AT91_PIN_PG31 (at91_pin_t)223
|
||||
#define AT91_PIN_PH0 (at91_pin_t)224
|
||||
#define AT91_PIN_PH1 (at91_pin_t)225
|
||||
#define AT91_PIN_PH2 (at91_pin_t)226
|
||||
#define AT91_PIN_PH3 (at91_pin_t)227
|
||||
#define AT91_PIN_PH4 (at91_pin_t)228
|
||||
#define AT91_PIN_PH5 (at91_pin_t)229
|
||||
#define AT91_PIN_PH6 (at91_pin_t)230
|
||||
#define AT91_PIN_PH7 (at91_pin_t)231
|
||||
#define AT91_PIN_PH8 (at91_pin_t)232
|
||||
#define AT91_PIN_PH9 (at91_pin_t)233
|
||||
#define AT91_PIN_PH10 (at91_pin_t)234
|
||||
#define AT91_PIN_PH11 (at91_pin_t)235
|
||||
#define AT91_PIN_PH12 (at91_pin_t)236
|
||||
#define AT91_PIN_PH13 (at91_pin_t)237
|
||||
#define AT91_PIN_PH14 (at91_pin_t)238
|
||||
#define AT91_PIN_PH15 (at91_pin_t)239
|
||||
#define AT91_PIN_PH16 (at91_pin_t)240
|
||||
#define AT91_PIN_PH17 (at91_pin_t)241
|
||||
#define AT91_PIN_PH18 (at91_pin_t)242
|
||||
#define AT91_PIN_PH19 (at91_pin_t)243
|
||||
#define AT91_PIN_PH20 (at91_pin_t)244
|
||||
#define AT91_PIN_PH21 (at91_pin_t)245
|
||||
#define AT91_PIN_PH22 (at91_pin_t)246
|
||||
#define AT91_PIN_PH23 (at91_pin_t)247
|
||||
#define AT91_PIN_PH24 (at91_pin_t)248
|
||||
#define AT91_PIN_PH25 (at91_pin_t)249
|
||||
#define AT91_PIN_PH26 (at91_pin_t)250
|
||||
#define AT91_PIN_PH27 (at91_pin_t)251
|
||||
#define AT91_PIN_PH28 (at91_pin_t)252
|
||||
#define AT91_PIN_PH29 (at91_pin_t)253
|
||||
#define AT91_PIN_PH30 (at91_pin_t)254
|
||||
#define AT91_PIN_PH31 (at91_pin_t)255
|
||||
|
||||
#endif /* ARM_AT91_AT91_GPIO_H */
|
91
sys/arm/at91/at91_smc.c
Normal file
91
sys/arm/at91/at91_smc.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 M. Warner Losh. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <arm/at91/at91reg.h>
|
||||
#include <arm/at91/at91_smc.h>
|
||||
#include <arm/at91/at91sam9260reg.h>
|
||||
|
||||
/*
|
||||
* RD4HW()/WR4HW() read and write at91 hardware register space directly. They
|
||||
* serve the same purpose as the RD4()/WR4() idiom you see in many drivers,
|
||||
* except that those translate to bus_space calls, but in this code we need to
|
||||
* access some devices before bus_space is ready to use. Of course for this to
|
||||
* work the appropriate static device mappings need to be made in machdep.c.
|
||||
*/
|
||||
static inline uint32_t
|
||||
RD4HW(uint32_t devbase, uint32_t regoff)
|
||||
{
|
||||
|
||||
return *(volatile uint32_t *)(AT91_BASE + devbase + regoff);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val)
|
||||
{
|
||||
|
||||
*(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
at91_smc_setup(int id, int cs, const struct at91_smc_init *smc)
|
||||
{
|
||||
// Need a generic way to get this address for all SoCs... Assume 9260 for now...
|
||||
uint32_t base = AT91SAM9260_SMC_BASE + SMC_CS_OFF(cs);
|
||||
|
||||
WR4HW(base, SMC_SETUP, SMC_SETUP_NCS_RD_SETUP(smc->ncs_rd_setup) |
|
||||
SMC_SETUP_NRD_SETUP(smc->nrd_setup) |
|
||||
SMC_SETUP_NCS_WR_SETUP(smc->ncs_wr_setup) |
|
||||
SMC_SETUP_NWE_SETUP(smc->nwe_setup));
|
||||
WR4HW(base, SMC_PULSE, SMC_PULSE_NCS_RD_PULSE(smc->ncs_rd_pulse) |
|
||||
SMC_PULSE_NRD_PULSE(smc->nrd_pulse) |
|
||||
SMC_PULSE_NCS_WR_PULSE(smc->ncs_wr_pulse) |
|
||||
SMC_PULSE_NWE_PULSE(smc->nwe_pulse));
|
||||
WR4HW(base, SMC_CYCLE, SMC_CYCLE_NRD_CYCLE(smc->nrd_cycle) |
|
||||
SMC_CYCLE_NWE_CYCLE(smc->nwe_cycle));
|
||||
WR4HW(base, SMC_MODE, smc->mode | SMC_MODE_TDF_CYCLES(smc->tdf_cycles));
|
||||
}
|
||||
|
||||
void
|
||||
at91_ebi_enable(int bank)
|
||||
{
|
||||
|
||||
WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, (1 << bank) |
|
||||
RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
|
||||
}
|
||||
|
||||
void
|
||||
at91_ebi_disable(int bank)
|
||||
{
|
||||
|
||||
WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, ~(1 << bank) &
|
||||
RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
|
||||
}
|
116
sys/arm/at91/at91_smc.h
Normal file
116
sys/arm/at91/at91_smc.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*-
|
||||
* Copyright (c) 2014 M. Warner Losh. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#ifndef ARM_AT91_AT91_SMC_H
|
||||
#define ARM_AT91_AT91_SMC_H
|
||||
|
||||
/* Registers */
|
||||
#define SMC_SETUP 0x00
|
||||
#define SMC_PULSE 0x04
|
||||
#define SMC_CYCLE 0x08
|
||||
#define SMC_MODE 0x0C
|
||||
|
||||
#define SMC_CS_OFF(cs) (0x10 * (cs))
|
||||
|
||||
/* Setup */
|
||||
#define SMC_SETUP_NCS_RD_SETUP(x) ((x) << 24)
|
||||
#define SMC_SETUP_NRD_SETUP(x) ((x) << 16)
|
||||
#define SMC_SETUP_NCS_WR_SETUP(x) ((x) << 8)
|
||||
#define SMC_SETUP_NWE_SETUP(x) (x)
|
||||
|
||||
/* Pulse */
|
||||
#define SMC_PULSE_NCS_RD_PULSE(x) ((x) << 24)
|
||||
#define SMC_PULSE_NRD_PULSE(x) ((x) << 16)
|
||||
#define SMC_PULSE_NCS_WR_PULSE(x) ((x) << 8)
|
||||
#define SMC_PULSE_NWE_PULSE(x) (x)
|
||||
|
||||
/* Cycle */
|
||||
#define SMC_CYCLE_NRD_CYCLE(x) ((x) << 16)
|
||||
#define SMC_CYCLE_NWE_CYCLE(x) (x)
|
||||
|
||||
/* Mode */
|
||||
#define SMC_MODE_READ (1 << 0)
|
||||
#define SMC_MODE_WRITE (1 << 1)
|
||||
#define SMC_MODE_EXNW_DISABLED (0 << 4)
|
||||
#define SMC_MODE_EXNW_FROZEN_MODE (2 << 4)
|
||||
#define SMC_MODE_EXNW_READY_MODE (3 << 4)
|
||||
#define SMC_MODE_BAT (1 << 8)
|
||||
#define SMC_MODE_DBW_8BIT (0 << 12)
|
||||
#define SMC_MODE_DBW_16BIT (1 << 12)
|
||||
#define SMC_MODE_DBW_32_BIT (2 << 12)
|
||||
#define SMC_MODE_TDF_CYCLES(x) ((x) << 16)
|
||||
#define SMC_MODE_TDF_MODE (1 << 20)
|
||||
#define SMC_MODE_PMEN (1 << 24)
|
||||
#define SMC_PS_4BYTE (0 << 28)
|
||||
#define SMC_PS_8BYTE (1 << 28)
|
||||
#define SMC_PS_16BYTE (2 << 28)
|
||||
#define SMC_PS_32BYTE (3 << 28)
|
||||
|
||||
/*
|
||||
* structure to ease init. See the SMC chapter in the datasheet for
|
||||
* the appropriate SoC you are using for details.
|
||||
*/
|
||||
struct at91_smc_init
|
||||
{
|
||||
/* Setup register */
|
||||
uint8_t ncs_rd_setup;
|
||||
uint8_t nrd_setup;
|
||||
uint8_t ncs_wr_setup;
|
||||
uint8_t nwe_setup;
|
||||
|
||||
/* Pulse register */
|
||||
uint8_t ncs_rd_pulse;
|
||||
uint8_t nrd_pulse;
|
||||
uint8_t ncs_wr_pulse;
|
||||
uint8_t nwe_pulse;
|
||||
|
||||
/* Cycle register */
|
||||
uint16_t nrd_cycle;
|
||||
uint16_t nwe_cycle;
|
||||
|
||||
/* Mode register */
|
||||
uint8_t mode; /* Combo of READ/WRITE/EXNW fields */
|
||||
uint8_t bat;
|
||||
uint8_t dwb;
|
||||
uint8_t tdf_cycles;
|
||||
uint8_t tdf_mode;
|
||||
uint8_t pmen;
|
||||
uint8_t ps;
|
||||
};
|
||||
|
||||
/*
|
||||
* Convenience routine to fill in SMC registers for a given chip select.
|
||||
*/
|
||||
void at91_smc_setup(int id, int cs, const struct at91_smc_init *smc);
|
||||
|
||||
/*
|
||||
* Disable/Enable different External Bus Interfaces (EBI)
|
||||
*/
|
||||
void at91_ebi_enable(int cs);
|
||||
void at91_ebi_disable(int cs);
|
||||
|
||||
#endif /* ARM_AT91_AT91_SMC_H */
|
@ -88,6 +88,13 @@ static const int at91_irq_prio[32] =
|
||||
0 /* Advanced Interrupt Controller (IRQ6) */
|
||||
};
|
||||
|
||||
static const uint32_t at91_pio_base[] = {
|
||||
AT91RM92_PIOA_BASE,
|
||||
AT91RM92_PIOB_BASE,
|
||||
AT91RM92_PIOC_BASE,
|
||||
AT91RM92_PIOD_BASE,
|
||||
};
|
||||
|
||||
#define DEVICE(_name, _id, _unit) \
|
||||
{ \
|
||||
_name, _unit, \
|
||||
@ -195,6 +202,8 @@ static struct at91_soc_data soc_data = {
|
||||
.soc_clock_init = at91_clock_init,
|
||||
.soc_irq_prio = at91_irq_prio,
|
||||
.soc_children = at91_devs,
|
||||
.soc_pio_base = at91_pio_base,
|
||||
.soc_pio_count = nitems(at91_pio_base),
|
||||
};
|
||||
|
||||
AT91_SOC(AT91_T_RM9200, &soc_data);
|
||||
|
@ -87,6 +87,12 @@ static const int at91_irq_prio[32] =
|
||||
0, /* Advanced Interrupt Controller IRQ2 */
|
||||
};
|
||||
|
||||
static const uint32_t at91_pio_base[] = {
|
||||
AT91SAM9260_PIOA_BASE,
|
||||
AT91SAM9260_PIOB_BASE,
|
||||
AT91SAM9260_PIOC_BASE,
|
||||
};
|
||||
|
||||
#define DEVICE(_name, _id, _unit) \
|
||||
{ \
|
||||
_name, _unit, \
|
||||
@ -204,6 +210,8 @@ static struct at91_soc_data soc_data = {
|
||||
.soc_clock_init = at91_clock_init,
|
||||
.soc_irq_prio = at91_irq_prio,
|
||||
.soc_children = at91_devs,
|
||||
.soc_pio_base = at91_pio_base,
|
||||
.soc_pio_count = nitems(at91_pio_base),
|
||||
};
|
||||
|
||||
AT91_SOC(AT91_T_SAM9260, &soc_data);
|
||||
|
@ -87,6 +87,12 @@ static const int at91_irq_prio[32] =
|
||||
0, /* Advanced Interrupt Controller IRQ2 */
|
||||
};
|
||||
|
||||
static const uint32_t at91_pio_base[] = {
|
||||
AT91SAM9G20_PIOA_BASE,
|
||||
AT91SAM9G20_PIOB_BASE,
|
||||
AT91SAM9G20_PIOC_BASE,
|
||||
};
|
||||
|
||||
#define DEVICE(_name, _id, _unit) \
|
||||
{ \
|
||||
_name, _unit, \
|
||||
@ -169,6 +175,8 @@ static struct at91_soc_data soc_data = {
|
||||
.soc_clock_init = at91_clock_init,
|
||||
.soc_irq_prio = at91_irq_prio,
|
||||
.soc_children = at91_devs,
|
||||
.soc_pio_base = at91_pio_base,
|
||||
.soc_pio_count = nitems(at91_pio_base),
|
||||
};
|
||||
|
||||
AT91_SOC(AT91_T_SAM9G20, &soc_data);
|
||||
|
@ -88,6 +88,14 @@ static const int at91_irq_prio[32] =
|
||||
0, /* Advanced Interrupt Controller IRQ0 */
|
||||
};
|
||||
|
||||
static const uint32_t at91_pio_base[] = {
|
||||
AT91SAM9G45_PIOA_BASE,
|
||||
AT91SAM9G45_PIOB_BASE,
|
||||
AT91SAM9G45_PIOC_BASE,
|
||||
AT91SAM9G45_PIOD_BASE,
|
||||
AT91SAM9G45_PIOE_BASE,
|
||||
};
|
||||
|
||||
#define DEVICE(_name, _id, _unit) \
|
||||
{ \
|
||||
_name, _unit, \
|
||||
@ -155,6 +163,8 @@ static struct at91_soc_data soc_data = {
|
||||
.soc_clock_init = at91_clock_init,
|
||||
.soc_irq_prio = at91_irq_prio,
|
||||
.soc_children = at91_devs,
|
||||
.soc_pio_base = at91_pio_base,
|
||||
.soc_pio_count = nitems(at91_pio_base),
|
||||
};
|
||||
|
||||
AT91_SOC(AT91_T_SAM9G45, &soc_data);
|
||||
|
@ -87,6 +87,13 @@ static const int at91_irq_prio[32] =
|
||||
0, /* Advanced Interrupt Controller (IRQ0) */
|
||||
};
|
||||
|
||||
static const uint32_t at91_pio_base[] = {
|
||||
AT91SAM9X25_PIOA_BASE,
|
||||
AT91SAM9X25_PIOB_BASE,
|
||||
AT91SAM9X25_PIOC_BASE,
|
||||
AT91SAM9X25_PIOD_BASE,
|
||||
};
|
||||
|
||||
#define DEVICE(_name, _id, _unit) \
|
||||
{ \
|
||||
_name, _unit, \
|
||||
@ -172,6 +179,8 @@ static struct at91_soc_data soc_data = {
|
||||
.soc_clock_init = at91_clock_init,
|
||||
.soc_irq_prio = at91_irq_prio,
|
||||
.soc_children = at91_devs,
|
||||
.soc_pio_base = at91_pio_base,
|
||||
.soc_pio_count = nitems(at91_pio_base),
|
||||
};
|
||||
|
||||
AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data);
|
||||
|
@ -107,11 +107,13 @@ typedef void (*cpu_reset_t)(void);
|
||||
typedef void (*clk_init_t)(void);
|
||||
|
||||
struct at91_soc_data {
|
||||
DELAY_t soc_delay;
|
||||
cpu_reset_t soc_reset;
|
||||
clk_init_t soc_clock_init;
|
||||
const int *soc_irq_prio;
|
||||
const struct cpu_devs *soc_children;
|
||||
DELAY_t soc_delay; /* SoC specific delay function */
|
||||
cpu_reset_t soc_reset; /* SoC specific reset function */
|
||||
clk_init_t soc_clock_init; /* SoC specific clock init function */
|
||||
const int *soc_irq_prio; /* SoC specific IRQ priorities */
|
||||
const struct cpu_devs *soc_children; /* SoC specific children list */
|
||||
const uint32_t *soc_pio_base; /* SoC specific PIO base registers */
|
||||
size_t soc_pio_count; /* Count of PIO units (not pins) in SoC */
|
||||
};
|
||||
|
||||
struct at91_soc_info {
|
||||
|
@ -34,6 +34,36 @@ __FBSDID("$FreeBSD$");
|
||||
#include <arm/at91/at91sam9g20reg.h>
|
||||
#include <arm/at91/at91_piovar.h>
|
||||
#include <arm/at91/at91_pio_sam9g20.h>
|
||||
#include <arm/at91/at91_smc.h>
|
||||
#include <arm/at91/at91_gpio.h>
|
||||
#include <dev/nand/nfc_at91.h>
|
||||
|
||||
static struct at91_smc_init nand_smc = {
|
||||
.ncs_rd_setup = 0,
|
||||
.nrd_setup = 2,
|
||||
.ncs_wr_setup = 0,
|
||||
.nwe_setup = 2,
|
||||
|
||||
.ncs_rd_pulse = 4,
|
||||
.nrd_pulse = 4,
|
||||
.ncs_wr_pulse = 4,
|
||||
.nwe_pulse = 4,
|
||||
|
||||
.nrd_cycle = 7,
|
||||
.nwe_cycle = 7,
|
||||
|
||||
.mode = SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED,
|
||||
.tdf_cycles = 3,
|
||||
};
|
||||
|
||||
static struct at91_nand_params nand_param = {
|
||||
.ale = 1u << 21,
|
||||
.cle = 1u << 22,
|
||||
.width = 8,
|
||||
.rnb_pin = AT91_PIN_PC13, /* Note: These pins not confirmed */
|
||||
.nce_pin = AT91_PIN_PC14,
|
||||
.cs = 3,
|
||||
};
|
||||
|
||||
BOARD_INIT long
|
||||
board_init(void)
|
||||
@ -64,6 +94,27 @@ board_init(void)
|
||||
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA24, 0); /* ETX3 */
|
||||
at91_pio_use_periph_b(AT91SAM9G20_PIOA_BASE, AT91C_PIO_PA22, 0); /* ETXER */
|
||||
|
||||
/* Setup Static Memory Controller */
|
||||
at91_smc_setup(0, 3, &nand_smc);
|
||||
at91_enable_nand(&nand_param);
|
||||
|
||||
/*
|
||||
* This assumes
|
||||
* - RNB is on pin PC13
|
||||
* - CE is on pin PC14
|
||||
*
|
||||
* Nothing actually uses RNB right now.
|
||||
*
|
||||
* For CE, this currently asserts it during board setup and leaves it
|
||||
* that way forever.
|
||||
*
|
||||
* All this can go away when the gpio pin-renumbering happens...
|
||||
*/
|
||||
at91_pio_use_gpio(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14);
|
||||
at91_pio_gpio_input(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC13); /* RNB */
|
||||
at91_pio_gpio_output(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC14, 0); /* nCS */
|
||||
at91_pio_gpio_clear(AT91SAM9G20_PIOC_BASE, AT91C_PIO_PC14); /* Assert nCS */
|
||||
|
||||
return (at91_ramsize());
|
||||
}
|
||||
|
||||
|
@ -38,9 +38,39 @@ __FBSDID("$FreeBSD$");
|
||||
#include <arm/at91/at91_piovar.h>
|
||||
#include <arm/at91/at91board.h>
|
||||
#include <arm/at91/at91sam9260reg.h>
|
||||
#include <arm/at91/at91_smc.h>
|
||||
#include <arm/at91/at91_gpio.h>
|
||||
#include <dev/nand/nfc_at91.h>
|
||||
|
||||
BOARD_INIT long
|
||||
board_init(void)
|
||||
static struct at91_smc_init nand_smc = {
|
||||
.ncs_rd_setup = 0,
|
||||
.nrd_setup = 1,
|
||||
.ncs_wr_setup = 0,
|
||||
.nwe_setup = 1,
|
||||
|
||||
.ncs_rd_pulse = 3,
|
||||
.nrd_pulse = 3,
|
||||
.ncs_wr_pulse = 3,
|
||||
.nwe_pulse = 3,
|
||||
|
||||
.nrd_cycle = 5,
|
||||
.nwe_cycle = 5,
|
||||
|
||||
.mode = SMC_MODE_READ | SMC_MODE_WRITE | SMC_MODE_EXNW_DISABLED,
|
||||
.tdf_cycles = 2,
|
||||
};
|
||||
|
||||
static struct at91_nand_params nand_param = {
|
||||
.ale = 1u << 21,
|
||||
.cle = 1u << 22,
|
||||
.width = 8,
|
||||
.rnb_pin = AT91_PIN_PC13,
|
||||
.nce_pin = AT91_PIN_PC14,
|
||||
.cs = 3,
|
||||
};
|
||||
|
||||
static void
|
||||
bi_dbgu(void)
|
||||
{
|
||||
|
||||
/*
|
||||
@ -50,6 +80,11 @@ board_init(void)
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB14, 0);
|
||||
/* DTXD */
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB15, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_emac()
|
||||
{
|
||||
|
||||
/*
|
||||
* EMAC
|
||||
@ -91,7 +126,11 @@ board_init(void)
|
||||
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA28, 0);
|
||||
/* ECOL */
|
||||
at91_pio_use_periph_b(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA29, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_mmc(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* MMC, wired to socket B.
|
||||
@ -114,11 +153,11 @@ board_init(void)
|
||||
* don't support the dataflash. But if you did, you'd have to
|
||||
* use CS0 and CS1.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* SPI1 is wired to a audio CODEC that we don't support, so
|
||||
* give it a pass.
|
||||
*/
|
||||
static void
|
||||
bi_iic(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* TWI. Only one child on the iic bus, which we take care of
|
||||
@ -128,6 +167,11 @@ board_init(void)
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA23, 1);
|
||||
/* TWCK */
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOA_BASE, AT91C_PIO_PA24, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_usart0(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* USART0
|
||||
@ -148,7 +192,11 @@ board_init(void)
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB26, 1);
|
||||
/* CTS0 */
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB27, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_usart1(void)
|
||||
{
|
||||
/*
|
||||
* USART1
|
||||
*/
|
||||
@ -160,9 +208,54 @@ board_init(void)
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB6, 1);
|
||||
/* RXD1 */
|
||||
at91_pio_use_periph_a(AT91SAM9260_PIOB_BASE, AT91C_PIO_PB7, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
bi_nand(void)
|
||||
{
|
||||
/* Samsung 256MB SLC Flash */
|
||||
|
||||
/* Setup Static Memory Controller */
|
||||
at91_smc_setup(0, 3, &nand_smc);
|
||||
at91_enable_nand(&nand_param);
|
||||
|
||||
/*
|
||||
* This assumes
|
||||
* - RNB is on pin PC13
|
||||
* - CE is on pin PC14
|
||||
*
|
||||
* Nothing actually uses RNB right now.
|
||||
*
|
||||
* For CE, this currently asserts it during board setup and leaves it
|
||||
* that way forever.
|
||||
*
|
||||
* All this can go away when the gpio pin-renumbering happens...
|
||||
*/
|
||||
at91_pio_use_gpio(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13 | AT91C_PIO_PC14);
|
||||
at91_pio_gpio_input(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC13); /* RNB */
|
||||
at91_pio_gpio_output(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14, 0); /* nCS */
|
||||
at91_pio_gpio_clear(AT91SAM9260_PIOC_BASE, AT91C_PIO_PC14); /* Assert nCS */
|
||||
}
|
||||
|
||||
BOARD_INIT long
|
||||
board_init(void)
|
||||
{
|
||||
bi_dbgu();
|
||||
bi_emac();
|
||||
bi_mmc();
|
||||
|
||||
/*
|
||||
* SPI1 is wired to a audio CODEC that we don't support, so
|
||||
* give it a pass.
|
||||
*/
|
||||
|
||||
bi_iic();
|
||||
bi_usart0();
|
||||
bi_usart1();
|
||||
/* USART2 - USART5 aren't wired up, except via PIO pins, ignore them. */
|
||||
|
||||
bi_nand();
|
||||
|
||||
return (at91_ramsize());
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ arm/at91/at91_pit.c optional at91sam9
|
||||
arm/at91/at91_reset.S optional at91sam9
|
||||
arm/at91/at91_rst.c optional at91sam9
|
||||
arm/at91/at91_rtc.c optional at91_rtc
|
||||
arm/at91/at91_smc.c standard
|
||||
arm/at91/at91_spi.c optional at91_spi \
|
||||
dependency "spibus_if.h"
|
||||
arm/at91/at91_ssc.c optional at91_ssc
|
||||
|
@ -219,20 +219,6 @@ at91_usart_param(struct uart_bas *bas, int baudrate, int databits,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
at91_usart_grab(struct uart_bas *bas)
|
||||
{
|
||||
|
||||
WR4(bas, USART_IDR, USART_CSR_RXRDY);
|
||||
}
|
||||
|
||||
static void
|
||||
at91_usart_ungrab(struct uart_bas *bas)
|
||||
{
|
||||
|
||||
WR4(bas, USART_IER, USART_CSR_RXRDY);
|
||||
}
|
||||
|
||||
static struct uart_ops at91_usart_ops = {
|
||||
.probe = at91_usart_probe,
|
||||
.init = at91_usart_init,
|
||||
@ -240,8 +226,6 @@ static struct uart_ops at91_usart_ops = {
|
||||
.putc = at91_usart_putc,
|
||||
.rxready = at91_usart_rxready,
|
||||
.getc = at91_usart_getc,
|
||||
.grab = at91_usart_grab,
|
||||
.ungrab = at91_usart_ungrab,
|
||||
};
|
||||
|
||||
static int
|
||||
@ -331,6 +315,8 @@ static int at91_usart_bus_param(struct uart_softc *, int, int, int, int);
|
||||
static int at91_usart_bus_receive(struct uart_softc *);
|
||||
static int at91_usart_bus_setsig(struct uart_softc *, int);
|
||||
static int at91_usart_bus_transmit(struct uart_softc *);
|
||||
static void at91_usart_bus_grab(struct uart_softc *);
|
||||
static void at91_usart_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t at91_usart_methods[] = {
|
||||
KOBJMETHOD(uart_probe, at91_usart_bus_probe),
|
||||
@ -343,6 +329,8 @@ static kobj_method_t at91_usart_methods[] = {
|
||||
KOBJMETHOD(uart_receive, at91_usart_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, at91_usart_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, at91_usart_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, at91_usart_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, at91_usart_bus_ungrab),
|
||||
|
||||
KOBJMETHOD_END
|
||||
};
|
||||
@ -815,6 +803,25 @@ at91_usart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
at91_usart_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
WR4(&sc->sc_bas, USART_IDR, USART_CSR_RXRDY);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
at91_usart_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
WR4(&sc->sc_bas, USART_IER, USART_CSR_RXRDY);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
struct uart_class at91_usart_class = {
|
||||
"at91_usart",
|
||||
at91_usart_methods,
|
||||
|
@ -175,3 +175,6 @@ device at91_wdt # Atmel AT91 Watchdog Timer
|
||||
device at91_rtc
|
||||
device at91_ssc
|
||||
#device at91_tc # missing?
|
||||
|
||||
# NAND Flash - Reference design has Samsung 256MB but others possible
|
||||
device nand # NAND interface on CS3
|
||||
|
@ -37,7 +37,8 @@ options FFS #Berkeley Fast Filesystem
|
||||
#options UFS_ACL #Support for access control lists
|
||||
#options UFS_DIRHASH #Improve performance on big directories
|
||||
#options MD_ROOT #MD is a potential root device
|
||||
#options MD_ROOT_SIZE=4096 # 3MB ram disk
|
||||
#options MD_ROOT_SIZE=4096 # 4MB ram disk
|
||||
options NANDFS # NAND file system
|
||||
#options ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\"
|
||||
options NFSCL #New Network Filesystem Client
|
||||
#options NFSD #New Network Filesystem Server
|
||||
@ -131,3 +132,5 @@ device pass # Passthrough device (direct SCSI access)
|
||||
#device wlan_amrr # AMRR transmit rate control algorithm
|
||||
options ROOTDEVNAME=\"ufs:da0s1a\"
|
||||
|
||||
# NAND Flash - my board as 128MB Samsung part
|
||||
device nand # NAND interface on CS3
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Kernel configuration for Ethernut 5 boards
|
||||
# Kernel configuration for Atmel SAM9260-EK eval board
|
||||
#
|
||||
# For more information on this file, please read the config(5) manual page,
|
||||
# and/or the handbook section on Kernel Configuration Files:
|
||||
@ -37,6 +37,7 @@ options SOFTUPDATES # Enable FFS soft updates support
|
||||
options UFS_DIRHASH # Improve performance on big directories
|
||||
#options UFS_GJOURNAL # Enable gjournal-based UFS journaling
|
||||
#options MD_ROOT # MD is a potential root device
|
||||
options NANDFS # NAND file system
|
||||
options NFSCL # New Network Filesystem Client
|
||||
#options NFSD # New Network Filesystem Server
|
||||
options NFSLOCKD # Network Lock Manager
|
||||
@ -165,3 +166,6 @@ device umass # Disks/Mass storage - Requires scbus and da
|
||||
|
||||
# watchdog
|
||||
device at91_wdt # Atmel AT91 Watchdog Timer
|
||||
|
||||
# NAND Flash - Reference design has Samsung 256MB but others possible
|
||||
device nand # NAND interface on CS3
|
||||
|
@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/bus.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/fdt.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr.h>
|
||||
|
@ -203,7 +203,6 @@ s3c2410_getc(struct uart_bas *bas, struct mtx *mtx)
|
||||
|
||||
return sscom_getc(bas->bst, bas->bsh);
|
||||
}
|
||||
|
||||
static int s3c2410_bus_probe(struct uart_softc *sc);
|
||||
static int s3c2410_bus_attach(struct uart_softc *sc);
|
||||
static int s3c2410_bus_flush(struct uart_softc *, int);
|
||||
@ -214,6 +213,8 @@ static int s3c2410_bus_param(struct uart_softc *, int, int, int, int);
|
||||
static int s3c2410_bus_receive(struct uart_softc *);
|
||||
static int s3c2410_bus_setsig(struct uart_softc *, int);
|
||||
static int s3c2410_bus_transmit(struct uart_softc *);
|
||||
static void s3c2410_bus_grab(struct uart_softc *);
|
||||
static void s3c2410_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t s3c2410_methods[] = {
|
||||
KOBJMETHOD(uart_probe, s3c2410_bus_probe),
|
||||
@ -226,6 +227,8 @@ static kobj_method_t s3c2410_methods[] = {
|
||||
KOBJMETHOD(uart_receive, s3c2410_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, s3c2410_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, s3c2410_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, s3c2410_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, s3c2410_bus_ungrab),
|
||||
|
||||
{0, 0 }
|
||||
};
|
||||
@ -373,6 +376,25 @@ s3c2410_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
s3c2410_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
uintptr_t irq;
|
||||
|
||||
irq = rman_get_start(sc->sc_ires);
|
||||
arm_mask_irq(get_sub_irq(irq, RX_OFF));
|
||||
}
|
||||
|
||||
static void
|
||||
s3c2410_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
uintptr_t irq;
|
||||
|
||||
irq = rman_get_start(sc->sc_ires);
|
||||
arm_unmask_irq(get_sub_irq(irq, RX_OFF));
|
||||
}
|
||||
|
||||
struct uart_class uart_s3c2410_class = {
|
||||
"s3c2410 class",
|
||||
s3c2410_methods,
|
||||
|
@ -137,6 +137,8 @@ static int sa1110_bus_param(struct uart_softc *, int, int, int, int);
|
||||
static int sa1110_bus_receive(struct uart_softc *);
|
||||
static int sa1110_bus_setsig(struct uart_softc *, int);
|
||||
static int sa1110_bus_transmit(struct uart_softc *);
|
||||
static void sa1110_bus_grab(struct uart_softc *);
|
||||
static void sa1110_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t sa1110_methods[] = {
|
||||
KOBJMETHOD(uart_probe, sa1110_bus_probe),
|
||||
@ -149,6 +151,8 @@ static kobj_method_t sa1110_methods[] = {
|
||||
KOBJMETHOD(uart_receive, sa1110_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, sa1110_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, sa1110_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, sa1110_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, sa1110_bus_ungrab),
|
||||
|
||||
{0, 0 }
|
||||
};
|
||||
@ -164,10 +168,10 @@ sa1110_bus_probe(struct uart_softc *sc)
|
||||
static int
|
||||
sa1110_bus_attach(struct uart_softc *sc)
|
||||
{
|
||||
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
|
||||
bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas));
|
||||
|
||||
sc->sc_hwiflow = 0;
|
||||
uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
|
||||
sc->sc_hwiflow = 0;
|
||||
uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
|
||||
return (0);
|
||||
}
|
||||
static int
|
||||
@ -273,6 +277,26 @@ sa1110_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
static void
|
||||
sa1110_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
/* Turn off Rx interrupts */
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_TXE | CR3_TIE);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
sa1110_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
/* Turn on Rx interrupts */
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
struct uart_class uart_sa1110_class = {
|
||||
"sa1110",
|
||||
sa1110_methods,
|
||||
|
@ -398,6 +398,8 @@ static int cdnc_uart_bus_param(struct uart_softc *, int, int, int, int);
|
||||
static int cdnc_uart_bus_receive(struct uart_softc *);
|
||||
static int cdnc_uart_bus_setsig(struct uart_softc *, int);
|
||||
static int cdnc_uart_bus_transmit(struct uart_softc *);
|
||||
static void cdnc_uart_bus_grab(struct uart_softc *);
|
||||
static void cdnc_uart_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t cdnc_uart_bus_methods[] = {
|
||||
KOBJMETHOD(uart_probe, cdnc_uart_bus_probe),
|
||||
@ -410,6 +412,8 @@ static kobj_method_t cdnc_uart_bus_methods[] = {
|
||||
KOBJMETHOD(uart_receive, cdnc_uart_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, cdnc_uart_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, cdnc_uart_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, cdnc_uart_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, cdnc_uart_bus_ungrab),
|
||||
|
||||
KOBJMETHOD_END
|
||||
};
|
||||
@ -675,6 +679,27 @@ cdnc_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
cdnc_uart_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
/* Enable interrupts. */
|
||||
WR4(&sc->sc_bas, CDNC_UART_IEN_REG,
|
||||
CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
|
||||
CDNC_UART_INT_DMSI);
|
||||
}
|
||||
|
||||
static void
|
||||
cdnc_uart_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
/* Enable interrupts. */
|
||||
WR4(&sc->sc_bas, CDNC_UART_IEN_REG,
|
||||
CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT |
|
||||
CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR |
|
||||
CDNC_UART_INT_DMSI);
|
||||
}
|
||||
|
||||
struct uart_class uart_cdnc_class = {
|
||||
"cdnc_uart",
|
||||
cdnc_uart_bus_methods,
|
||||
|
@ -21,7 +21,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
|
||||
* Copyright (c) 2014 by Saso Kiselkov. All rights reserved.
|
||||
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
@ -4597,6 +4597,13 @@ l2arc_write_done(zio_t *zio)
|
||||
*/
|
||||
for (ab = list_prev(buflist, head); ab; ab = ab_prev) {
|
||||
ab_prev = list_prev(buflist, ab);
|
||||
abl2 = ab->b_l2hdr;
|
||||
|
||||
/*
|
||||
* Release the temporary compressed buffer as soon as possible.
|
||||
*/
|
||||
if (abl2->b_compress != ZIO_COMPRESS_OFF)
|
||||
l2arc_release_cdata_buf(ab);
|
||||
|
||||
hash_lock = HDR_LOCK(ab);
|
||||
if (!mutex_tryenter(hash_lock)) {
|
||||
@ -4609,14 +4616,6 @@ l2arc_write_done(zio_t *zio)
|
||||
continue;
|
||||
}
|
||||
|
||||
abl2 = ab->b_l2hdr;
|
||||
|
||||
/*
|
||||
* Release the temporary compressed buffer as soon as possible.
|
||||
*/
|
||||
if (abl2->b_compress != ZIO_COMPRESS_OFF)
|
||||
l2arc_release_cdata_buf(ab);
|
||||
|
||||
if (zio->io_error != 0) {
|
||||
/*
|
||||
* Error - drop L2ARC entry.
|
||||
|
@ -351,9 +351,9 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
|
||||
prefetch_dnode_metadata(td, dnp, zb->zb_objset,
|
||||
DMU_META_DNODE_OBJECT);
|
||||
if (arc_buf_size(buf) >= sizeof (objset_phys_t)) {
|
||||
prefetch_dnode_metadata(td, &osp->os_userused_dnode,
|
||||
zb->zb_objset, DMU_USERUSED_OBJECT);
|
||||
prefetch_dnode_metadata(td, &osp->os_groupused_dnode,
|
||||
zb->zb_objset, DMU_GROUPUSED_OBJECT);
|
||||
prefetch_dnode_metadata(td, &osp->os_userused_dnode,
|
||||
zb->zb_objset, DMU_USERUSED_OBJECT);
|
||||
}
|
||||
|
||||
@ -364,18 +364,18 @@ traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
|
||||
err = 0;
|
||||
}
|
||||
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
|
||||
dnp = &osp->os_userused_dnode;
|
||||
dnp = &osp->os_groupused_dnode;
|
||||
err = traverse_dnode(td, dnp, zb->zb_objset,
|
||||
DMU_USERUSED_OBJECT);
|
||||
DMU_GROUPUSED_OBJECT);
|
||||
}
|
||||
if (err && hard) {
|
||||
lasterr = err;
|
||||
err = 0;
|
||||
}
|
||||
if (err == 0 && arc_buf_size(buf) >= sizeof (objset_phys_t)) {
|
||||
dnp = &osp->os_groupused_dnode;
|
||||
dnp = &osp->os_userused_dnode;
|
||||
err = traverse_dnode(td, dnp, zb->zb_objset,
|
||||
DMU_GROUPUSED_OBJECT);
|
||||
DMU_USERUSED_OBJECT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,13 +313,16 @@ vdev_mirror_scrub_done(zio_t *zio)
|
||||
* single-copy data.
|
||||
*/
|
||||
static int
|
||||
vdev_mirror_dva_select(zio_t *zio, int preferred)
|
||||
vdev_mirror_dva_select(zio_t *zio, int p)
|
||||
{
|
||||
dva_t *dva = zio->io_bp->blk_dva;
|
||||
mirror_map_t *mm = zio->io_vsd;
|
||||
int preferred;
|
||||
int c;
|
||||
|
||||
for (c = preferred - 1; c >= 0; c--) {
|
||||
preferred = mm->mm_preferred[p];
|
||||
for (p-- ; p >= 0; p--) {
|
||||
c = mm->mm_preferred[p];
|
||||
if (DVA_GET_VDEV(&dva[c]) == DVA_GET_VDEV(&dva[preferred]))
|
||||
preferred = c;
|
||||
}
|
||||
@ -334,7 +337,7 @@ vdev_mirror_preferred_child_randomize(zio_t *zio)
|
||||
|
||||
if (mm->mm_root) {
|
||||
p = spa_get_random(mm->mm_preferred_cnt);
|
||||
return (vdev_mirror_dva_select(zio, mm->mm_preferred[p]));
|
||||
return (vdev_mirror_dva_select(zio, p));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -951,6 +951,8 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr)
|
||||
return (SET_ERROR(EDQUOT));
|
||||
}
|
||||
|
||||
getnewvnode_reserve(1);
|
||||
|
||||
tx = dmu_tx_create(zfsvfs->z_os);
|
||||
dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
|
||||
ZFS_SA_BASE_ATTR_SIZE);
|
||||
@ -985,6 +987,8 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr)
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
getnewvnode_drop_reserve();
|
||||
|
||||
*xvpp = ZTOV(xzp);
|
||||
|
||||
return (0);
|
||||
|
@ -1625,6 +1625,9 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode,
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
getnewvnode_reserve(1);
|
||||
|
||||
top:
|
||||
*vpp = NULL;
|
||||
|
||||
@ -1653,6 +1656,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode,
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
if (strcmp(name, "..") == 0)
|
||||
error = SET_ERROR(EISDIR);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -1721,6 +1725,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode,
|
||||
}
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_abort(tx);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -1787,6 +1792,7 @@ zfs_create(vnode_t *dvp, char *name, vattr_t *vap, int excl, int mode,
|
||||
}
|
||||
}
|
||||
out:
|
||||
getnewvnode_drop_reserve();
|
||||
if (dl)
|
||||
zfs_dirent_unlock(dl);
|
||||
|
||||
@ -2130,6 +2136,9 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr,
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
|
||||
getnewvnode_reserve(1);
|
||||
|
||||
/*
|
||||
* First make sure the new directory doesn't exist.
|
||||
*
|
||||
@ -2143,6 +2152,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr,
|
||||
if (error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf,
|
||||
NULL, NULL)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -2150,6 +2160,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr,
|
||||
if (error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, 0, B_FALSE, cr)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_dirent_unlock(dl);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -2157,6 +2168,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr,
|
||||
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_dirent_unlock(dl);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (SET_ERROR(EDQUOT));
|
||||
}
|
||||
@ -2189,6 +2201,7 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr,
|
||||
}
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_abort(tx);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -2218,6 +2231,8 @@ zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr,
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
getnewvnode_drop_reserve();
|
||||
|
||||
zfs_dirent_unlock(dl);
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
@ -4109,6 +4124,9 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
|
||||
getnewvnode_reserve(1);
|
||||
|
||||
top:
|
||||
/*
|
||||
* Attempt to lock directory; fail if entry already exists.
|
||||
@ -4116,6 +4134,7 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
|
||||
error = zfs_dirent_lock(&dl, dzp, name, &zp, zflg, NULL, NULL);
|
||||
if (error) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -4123,6 +4142,7 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
|
||||
if (error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_dirent_unlock(dl);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -4130,6 +4150,7 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
|
||||
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
zfs_dirent_unlock(dl);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (SET_ERROR(EDQUOT));
|
||||
}
|
||||
@ -4157,6 +4178,7 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
|
||||
}
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_abort(tx);
|
||||
getnewvnode_drop_reserve();
|
||||
ZFS_EXIT(zfsvfs);
|
||||
return (error);
|
||||
}
|
||||
@ -4195,6 +4217,8 @@ zfs_symlink(vnode_t *dvp, vnode_t **vpp, char *name, vattr_t *vap, char *link,
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
getnewvnode_drop_reserve();
|
||||
|
||||
zfs_dirent_unlock(dl);
|
||||
|
||||
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
|
||||
@ -6750,14 +6774,16 @@ vop_deleteextattr {
|
||||
UIO_SYSSPACE, attrname, xvp, td);
|
||||
error = namei(&nd);
|
||||
vp = nd.ni_vp;
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
if (error != 0) {
|
||||
ZFS_EXIT(zfsvfs);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
if (error == ENOENT)
|
||||
error = ENOATTR;
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
|
||||
vput(nd.ni_dvp);
|
||||
if (vp == nd.ni_dvp)
|
||||
|
@ -624,6 +624,8 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
|
||||
|
||||
zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
|
||||
|
||||
KASSERT(curthread->td_vp_reserv > 0,
|
||||
("zfs_znode_alloc: getnewvnode without any vnodes reserved"));
|
||||
error = getnewvnode("zfs", zfsvfs->z_parent->z_vfs, &zfs_vnodeops, &vp);
|
||||
if (error != 0) {
|
||||
kmem_cache_free(znode_cache, zp);
|
||||
@ -830,7 +832,6 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
|
||||
}
|
||||
}
|
||||
|
||||
getnewvnode_reserve(1);
|
||||
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj);
|
||||
VERIFY(0 == sa_buf_hold(zfsvfs->z_os, obj, NULL, &db));
|
||||
|
||||
@ -1016,7 +1017,6 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr,
|
||||
KASSERT(err == 0, ("insmntque() failed: error %d", err));
|
||||
}
|
||||
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj);
|
||||
getnewvnode_drop_reserve();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1644,18 +1644,28 @@ struct sf_hdtr32 {
|
||||
int trl_cnt;
|
||||
};
|
||||
|
||||
struct sf_hdtr_kq32 {
|
||||
int kq_fd;
|
||||
uint32_t kq_flags;
|
||||
uint32_t kq_udata; /* 32-bit void ptr */
|
||||
uint32_t kq_ident; /* 32-bit uintptr_t */
|
||||
};
|
||||
|
||||
static int
|
||||
freebsd32_do_sendfile(struct thread *td,
|
||||
struct freebsd32_sendfile_args *uap, int compat)
|
||||
{
|
||||
struct sf_hdtr32 hdtr32;
|
||||
struct sf_hdtr hdtr;
|
||||
struct sf_hdtr_kq32 hdtr_kq32;
|
||||
struct sf_hdtr_kq hdtr_kq;
|
||||
struct uio *hdr_uio, *trl_uio;
|
||||
struct iovec32 *iov32;
|
||||
off_t offset;
|
||||
int error;
|
||||
off_t sbytes;
|
||||
struct sendfile_sync *sfs;
|
||||
int do_kqueue = 0;
|
||||
|
||||
offset = PAIR32TO64(off_t, uap->offset);
|
||||
if (offset < 0)
|
||||
@ -1687,10 +1697,32 @@ freebsd32_do_sendfile(struct thread *td,
|
||||
if (error)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If SF_KQUEUE is set, then we need to also copy in
|
||||
* the kqueue data after the normal hdtr set and set do_kqueue=1.
|
||||
*/
|
||||
if (uap->flags & SF_KQUEUE) {
|
||||
error = copyin(((char *) uap->hdtr) + sizeof(hdtr32),
|
||||
&hdtr_kq32,
|
||||
sizeof(hdtr_kq32));
|
||||
if (error != 0)
|
||||
goto out;
|
||||
|
||||
/* 32->64 bit fields */
|
||||
CP(hdtr_kq32, hdtr_kq, kq_fd);
|
||||
CP(hdtr_kq32, hdtr_kq, kq_flags);
|
||||
PTRIN_CP(hdtr_kq32, hdtr_kq, kq_udata);
|
||||
CP(hdtr_kq32, hdtr_kq, kq_ident);
|
||||
do_kqueue = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Call sendfile */
|
||||
/* XXX stack depth! */
|
||||
error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat,
|
||||
offset, uap->nbytes, &sbytes, hdr_uio, trl_uio);
|
||||
offset, uap->nbytes, &sbytes, hdr_uio, trl_uio, &hdtr_kq);
|
||||
|
||||
if (uap->sbytes != NULL)
|
||||
copyout(&sbytes, uap->sbytes, sizeof(off_t));
|
||||
|
@ -448,6 +448,7 @@ dev/virtio/network/if_vtnet.c optional vtnet
|
||||
dev/virtio/block/virtio_blk.c optional virtio_blk
|
||||
dev/virtio/balloon/virtio_balloon.c optional virtio_balloon
|
||||
dev/virtio/scsi/virtio_scsi.c optional virtio_scsi
|
||||
dev/virtio/random/virtio_random.c optional virtio_random
|
||||
isa/syscons_isa.c optional sc
|
||||
isa/vga_isa.c optional vga
|
||||
kern/kern_clocksource.c standard
|
||||
|
@ -414,6 +414,7 @@ dev/virtio/network/if_vtnet.c optional vtnet
|
||||
dev/virtio/block/virtio_blk.c optional virtio_blk
|
||||
dev/virtio/balloon/virtio_balloon.c optional virtio_balloon
|
||||
dev/virtio/scsi/virtio_scsi.c optional virtio_scsi
|
||||
dev/virtio/random/virtio_random.c optional virtio_random
|
||||
i386/acpica/acpi_machdep.c optional acpi
|
||||
acpi_wakecode.o optional acpi \
|
||||
dependency "$S/i386/acpica/acpi_wakecode.S assym.s" \
|
||||
|
@ -543,7 +543,7 @@ MALLOC_DECLARE(M_IPFILTER);
|
||||
# ifndef ALLOC_MB_T
|
||||
# ifdef MGETHDR
|
||||
# define ALLOC_MB_T(m,l) do { \
|
||||
MGETHDR((m), M_DONTWAIT, MT_HEADER); \
|
||||
MGETHDR((m), M_NOWAIT, MT_HEADER); \
|
||||
if ((m) != NULL) { \
|
||||
(m)->m_len = (l); \
|
||||
(m)->m_pkthdr.len = (l); \
|
||||
@ -551,7 +551,7 @@ MALLOC_DECLARE(M_IPFILTER);
|
||||
} while (0)
|
||||
# else
|
||||
# define ALLOC_MB_T(m,l) do { \
|
||||
MGET((m), M_DONTWAIT, MT_HEADER); \
|
||||
MGET((m), M_NOWAIT, MT_HEADER); \
|
||||
if ((m) != NULL) { \
|
||||
(m)->m_len = (l); \
|
||||
(m)->m_pkthdr.len = (l); \
|
||||
|
@ -368,14 +368,14 @@ ipf_send_reset(fin)
|
||||
hlen = sizeof(ip_t);
|
||||
#endif
|
||||
#ifdef MGETHDR
|
||||
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||
MGETHDR(m, M_NOWAIT, MT_HEADER);
|
||||
#else
|
||||
MGET(m, M_DONTWAIT, MT_HEADER);
|
||||
MGET(m, M_NOWAIT, MT_HEADER);
|
||||
#endif
|
||||
if (m == NULL)
|
||||
return -1;
|
||||
if (sizeof(*tcp2) + hlen > MLEN) {
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
MCLGET(m, M_NOWAIT);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
FREE_MB_T(m);
|
||||
return -1;
|
||||
@ -543,9 +543,9 @@ ipf_send_icmp_err(type, fin, dst)
|
||||
if (ipf_checkl4sum(fin) == -1)
|
||||
return -1;
|
||||
#ifdef MGETHDR
|
||||
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||
MGETHDR(m, M_NOWAIT, MT_HEADER);
|
||||
#else
|
||||
MGET(m, M_DONTWAIT, MT_HEADER);
|
||||
MGET(m, M_NOWAIT, MT_HEADER);
|
||||
#endif
|
||||
if (m == NULL)
|
||||
return -1;
|
||||
@ -599,7 +599,7 @@ ipf_send_icmp_err(type, fin, dst)
|
||||
code = icmptoicmp6unreach[code];
|
||||
|
||||
if (iclen + max_linkhdr + fin->fin_plen > avail) {
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
MCLGET(m, M_NOWAIT);
|
||||
if ((m->m_flags & M_EXT) == 0) {
|
||||
FREE_MB_T(m);
|
||||
return -1;
|
||||
@ -730,7 +730,7 @@ ipf_fastroute(m0, mpp, fin, fdp)
|
||||
* problem.
|
||||
*/
|
||||
if (M_WRITABLE(m) == 0) {
|
||||
m0 = m_dup(m, M_DONTWAIT);
|
||||
m0 = m_dup(m, M_NOWAIT);
|
||||
if (m0 != 0) {
|
||||
FREE_MB_T(m);
|
||||
m = m0;
|
||||
@ -878,9 +878,9 @@ ipf_fastroute(m0, mpp, fin, fdp)
|
||||
mhlen = sizeof (struct ip);
|
||||
for (off = hlen + len; off < ntohs(ip->ip_len); off += len) {
|
||||
#ifdef MGETHDR
|
||||
MGETHDR(m, M_DONTWAIT, MT_HEADER);
|
||||
MGETHDR(m, M_NOWAIT, MT_HEADER);
|
||||
#else
|
||||
MGET(m, M_DONTWAIT, MT_HEADER);
|
||||
MGET(m, M_NOWAIT, MT_HEADER);
|
||||
#endif
|
||||
if (m == 0) {
|
||||
m = m0;
|
||||
|
@ -207,9 +207,9 @@ aha_free(struct aha_softc *aha)
|
||||
case 7:
|
||||
bus_dmamap_unload(aha->ccb_dmat, aha->ccb_dmamap);
|
||||
case 6:
|
||||
bus_dmamap_destroy(aha->ccb_dmat, aha->ccb_dmamap);
|
||||
bus_dmamem_free(aha->ccb_dmat, aha->aha_ccb_array,
|
||||
aha->ccb_dmamap);
|
||||
bus_dmamap_destroy(aha->ccb_dmat, aha->ccb_dmamap);
|
||||
case 5:
|
||||
bus_dma_tag_destroy(aha->ccb_dmat);
|
||||
case 4:
|
||||
|
@ -146,6 +146,7 @@ static struct {
|
||||
{0x78021022, 0x00, "AMD Hudson-2", 0},
|
||||
{0x78031022, 0x00, "AMD Hudson-2", 0},
|
||||
{0x78041022, 0x00, "AMD Hudson-2", 0},
|
||||
{0x06111b21, 0x00, "ASMedia ASM2106", 0},
|
||||
{0x06121b21, 0x00, "ASMedia ASM1061", 0},
|
||||
{0x26528086, 0x00, "Intel ICH6", AHCI_Q_NOFORCE},
|
||||
{0x26538086, 0x00, "Intel ICH6M", AHCI_Q_NOFORCE},
|
||||
|
@ -1174,7 +1174,7 @@ atse_rx_locked(struct atse_softc *sc)
|
||||
sc->atse_rx_cycles--;
|
||||
|
||||
if (sc->atse_rx_m == NULL) {
|
||||
m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
|
||||
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
|
||||
if (m == NULL)
|
||||
return (rx_npkts);
|
||||
m->m_len = m->m_pkthdr.len = MCLBYTES;
|
||||
|
@ -5443,7 +5443,7 @@ bxe_tx_encap(struct bxe_fastpath *fp, struct mbuf **m_head)
|
||||
} else if (error == EFBIG) {
|
||||
/* possibly recoverable with defragmentation */
|
||||
fp->eth_q_stats.mbuf_defrag_attempts++;
|
||||
m0 = m_defrag(*m_head, M_DONTWAIT);
|
||||
m0 = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m0 == NULL) {
|
||||
fp->eth_q_stats.mbuf_defrag_failures++;
|
||||
rc = ENOBUFS;
|
||||
@ -5504,7 +5504,7 @@ bxe_tx_encap(struct bxe_fastpath *fp, struct mbuf **m_head)
|
||||
/* lets try to defragment this mbuf */
|
||||
fp->eth_q_stats.mbuf_defrag_attempts++;
|
||||
|
||||
m0 = m_defrag(*m_head, M_DONTWAIT);
|
||||
m0 = m_defrag(*m_head, M_NOWAIT);
|
||||
if (m0 == NULL) {
|
||||
fp->eth_q_stats.mbuf_defrag_failures++;
|
||||
/* Ugh, just drop the frame... :( */
|
||||
@ -6564,7 +6564,7 @@ bxe_alloc_rx_bd_mbuf(struct bxe_fastpath *fp,
|
||||
rc = 0;
|
||||
|
||||
/* allocate the new RX BD mbuf */
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, fp->mbuf_alloc_size);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, fp->mbuf_alloc_size);
|
||||
if (__predict_false(m == NULL)) {
|
||||
fp->eth_q_stats.mbuf_rx_bd_alloc_failed++;
|
||||
return (ENOBUFS);
|
||||
@ -6645,7 +6645,7 @@ bxe_alloc_rx_tpa_mbuf(struct bxe_fastpath *fp,
|
||||
int rc = 0;
|
||||
|
||||
/* allocate the new TPA mbuf */
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, fp->mbuf_alloc_size);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, fp->mbuf_alloc_size);
|
||||
if (__predict_false(m == NULL)) {
|
||||
fp->eth_q_stats.mbuf_rx_tpa_alloc_failed++;
|
||||
return (ENOBUFS);
|
||||
@ -6707,7 +6707,7 @@ bxe_alloc_rx_sge_mbuf(struct bxe_fastpath *fp,
|
||||
int rc = 0;
|
||||
|
||||
/* allocate a new SGE mbuf */
|
||||
m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, SGE_PAGE_SIZE);
|
||||
m = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, SGE_PAGE_SIZE);
|
||||
if (__predict_false(m == NULL)) {
|
||||
fp->eth_q_stats.mbuf_rx_sge_alloc_failed++;
|
||||
return (ENOMEM);
|
||||
@ -6769,7 +6769,7 @@ bxe_alloc_fp_buffers(struct bxe_softc *sc)
|
||||
|
||||
#if __FreeBSD_version >= 800000
|
||||
fp->tx_br = buf_ring_alloc(BXE_BR_SIZE, M_DEVBUF,
|
||||
M_DONTWAIT, &fp->tx_mtx);
|
||||
M_NOWAIT, &fp->tx_mtx);
|
||||
if (fp->tx_br == NULL) {
|
||||
BLOGE(sc, "buf_ring alloc fail for fp[%02d]\n", i);
|
||||
goto bxe_alloc_fp_buffers_error;
|
||||
|
@ -485,7 +485,7 @@ hn_start_locked(struct ifnet *ifp)
|
||||
* bpf_mtap code has a chance to run.
|
||||
*/
|
||||
if (ifp->if_bpf) {
|
||||
mc_head = m_copypacket(m_head, M_DONTWAIT);
|
||||
mc_head = m_copypacket(m_head, M_NOWAIT);
|
||||
}
|
||||
retry_send:
|
||||
/* Set the completion routine */
|
||||
@ -594,7 +594,7 @@ hv_m_append(struct mbuf *m0, int len, c_caddr_t cp)
|
||||
* Allocate a new mbuf; could check space
|
||||
* and allocate a cluster instead.
|
||||
*/
|
||||
n = m_getjcl(M_DONTWAIT, m->m_type, 0, MJUMPAGESIZE);
|
||||
n = m_getjcl(M_NOWAIT, m->m_type, 0, MJUMPAGESIZE);
|
||||
if (n == NULL)
|
||||
break;
|
||||
n->m_len = min(MJUMPAGESIZE, remainder);
|
||||
@ -658,7 +658,7 @@ netvsc_recv(struct hv_device *device_ctx, netvsc_packet *packet)
|
||||
size = MJUMPAGESIZE;
|
||||
}
|
||||
|
||||
m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, size);
|
||||
m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, size);
|
||||
|
||||
if (m_new == NULL)
|
||||
return (0);
|
||||
|
@ -54,23 +54,29 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/nand/nandbus.h>
|
||||
#include "nfc_if.h"
|
||||
|
||||
#include <dev/nand/nfc_at91.h>
|
||||
#include <arm/at91/at91_smc.h>
|
||||
|
||||
/*
|
||||
* Data cycles are triggered by access to any address within the EBI CS3 region
|
||||
* that has A21 and A22 clear. Command cycles are any access with bit A21
|
||||
* asserted. Address cycles are any access with bit A22 asserted.
|
||||
*
|
||||
* XXX The atmel docs say that any address bits can be used instead of A21 and
|
||||
* A22; these values should be configurable.
|
||||
* asserted. Address cycles are any access with bit A22 asserted. Or vice versa.
|
||||
* We get these parameters from the nand_param that the board is required to
|
||||
* call at91_enable_nand, and enable the GPIO lines properly (that will be moved
|
||||
* into at91_enable_nand when the great GPIO pin renumbering happens). We use
|
||||
* ale (Address Latch Enable) and cle (Comand Latch Enable) to match the hardware
|
||||
* names used in NAND.
|
||||
*/
|
||||
#define AT91_NAND_DATA 0
|
||||
#define AT91_NAND_COMMAND (1 << 21)
|
||||
#define AT91_NAND_ADDRESS (1 << 22)
|
||||
|
||||
struct at91_nand_softc {
|
||||
struct nand_softc nand_sc;
|
||||
struct resource *res;
|
||||
struct at91_nand_params *nand_param;
|
||||
};
|
||||
|
||||
static struct at91_nand_params nand_param;
|
||||
|
||||
static int at91_nand_attach(device_t);
|
||||
static int at91_nand_probe(device_t);
|
||||
static uint8_t at91_nand_read_byte(device_t);
|
||||
@ -81,6 +87,12 @@ static int at91_nand_send_command(device_t, uint8_t);
|
||||
static int at91_nand_send_address(device_t, uint8_t);
|
||||
static void at91_nand_write_buf(device_t, void *, uint32_t);
|
||||
|
||||
void
|
||||
at91_enable_nand(const struct at91_nand_params *np)
|
||||
{
|
||||
nand_param = *np;
|
||||
}
|
||||
|
||||
static inline u_int8_t
|
||||
dev_read_1(struct at91_nand_softc *sc, bus_size_t offset)
|
||||
{
|
||||
@ -108,6 +120,14 @@ at91_nand_attach(device_t dev)
|
||||
int err, rid;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->nand_param = &nand_param;
|
||||
if (sc->nand_param->width != 8 && sc->nand_param->width != 16) {
|
||||
device_printf(dev, "Bad bus width (%d) defaulting to 8 bits\n",
|
||||
sc->nand_param->width);
|
||||
sc->nand_param->width = 8;
|
||||
}
|
||||
at91_ebi_enable(sc->nand_param->cs);
|
||||
|
||||
rid = 0;
|
||||
sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
||||
RF_ACTIVE);
|
||||
@ -128,10 +148,10 @@ at91_nand_send_command(device_t dev, uint8_t command)
|
||||
{
|
||||
struct at91_nand_softc *sc;
|
||||
|
||||
/* nand_debug(NDBG_DRV,"at91_nand_send_command: 0x%02x", command); */
|
||||
nand_debug(NDBG_DRV,"at91_nand_send_command: 0x%02x", command);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
dev_write_1(sc, AT91_NAND_COMMAND, command);
|
||||
dev_write_1(sc, sc->nand_param->cle, command);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -140,10 +160,10 @@ at91_nand_send_address(device_t dev, uint8_t addr)
|
||||
{
|
||||
struct at91_nand_softc *sc;
|
||||
|
||||
/* nand_debug(NDBG_DRV,"at91_nand_send_address: x%02x", addr); */
|
||||
nand_debug(NDBG_DRV,"at91_nand_send_address: x%02x", addr);
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
dev_write_1(sc, AT91_NAND_ADDRESS, addr);
|
||||
dev_write_1(sc, sc->nand_param->ale, addr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -156,7 +176,7 @@ at91_nand_read_byte(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
data = dev_read_1(sc, AT91_NAND_DATA);
|
||||
|
||||
/* nand_debug(NDBG_DRV,"at91_nand_read_byte: 0x%02x", data); */
|
||||
nand_debug(NDBG_DRV,"at91_nand_read_byte: 0x%02x", data);
|
||||
|
||||
return (data);
|
||||
}
|
||||
|
50
sys/dev/nand/nfc_at91.h
Normal file
50
sys/dev/nand/nfc_at91.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* Copyright (C) 2014 Warner Losh.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Atmel at91-family integrated NAND controller driver.
|
||||
*
|
||||
* Interface to board setup code to set parameters.
|
||||
*/
|
||||
|
||||
#ifndef DEV_NAND_NFC_AT91_H
|
||||
#define DEV_NAND_NFC_AT91_H 1
|
||||
|
||||
struct at91_nand_params
|
||||
{
|
||||
uint32_t ale; /* Address for ALE (address) NAND cycles */
|
||||
uint32_t cle; /* Address for CLE (command) NAND cycles */
|
||||
uint32_t width; /* 8 or 16 bits (specify in bits) */
|
||||
uint32_t cs; /* Chip Select NAND is connected to */
|
||||
uint32_t rnb_pin; /* GPIO pin # for Read/notBusy */
|
||||
uint32_t nce_pin; /* GPIO pin # for CE (active low) */
|
||||
};
|
||||
|
||||
void at91_enable_nand(const struct at91_nand_params *);
|
||||
|
||||
#endif /* DEV_NAND_NFC_AT91_H */
|
@ -1052,7 +1052,7 @@ netmap_get_hw_na(struct ifnet *ifp, struct netmap_adapter **na)
|
||||
* to use generic adapters, we cannot satisfy the request.
|
||||
*/
|
||||
if (!NETMAP_CAPABLE(ifp) && i == NETMAP_ADMODE_NATIVE)
|
||||
return EINVAL;
|
||||
return EOPNOTSUPP;
|
||||
|
||||
/* Otherwise, create a generic adapter and return it,
|
||||
* saving the previously used netmap adapter, if any.
|
||||
@ -1090,22 +1090,19 @@ netmap_get_hw_na(struct ifnet *ifp, struct netmap_adapter **na)
|
||||
/*
|
||||
* MUST BE CALLED UNDER NMG_LOCK()
|
||||
*
|
||||
* get a refcounted reference to an interface.
|
||||
* Get a refcounted reference to a netmap adapter attached
|
||||
* to the interface specified by nmr.
|
||||
* This is always called in the execution of an ioctl().
|
||||
*
|
||||
* Return ENXIO if the interface does not exist, EINVAL if netmap
|
||||
* is not supported by the interface.
|
||||
* If successful, hold a reference.
|
||||
* Return ENXIO if the interface specified by the request does
|
||||
* not exist, ENOTSUP if netmap is not supported by the interface,
|
||||
* EBUSY if the interface is already attached to a bridge,
|
||||
* EINVAL if parameters are invalid, ENOMEM if needed resources
|
||||
* could not be allocated.
|
||||
* If successful, hold a reference to the netmap adapter.
|
||||
*
|
||||
* When the NIC is attached to a bridge, reference is managed
|
||||
* at na->na_bdg_refcount using ADD/DROP_BDG_REF() as well as
|
||||
* virtual ports. Hence, on the final DROP_BDG_REF(), the NIC
|
||||
* is detached from the bridge, then ifp's refcount is dropped (this
|
||||
* is equivalent to that ifp is destroyed in case of virtual ports.
|
||||
*
|
||||
* This function uses if_rele() when we want to prevent the NIC from
|
||||
* being detached from the bridge in error handling. But once refcount
|
||||
* is acquired by this function, it must be released using nm_if_rele().
|
||||
* No reference is kept on the real interface, which may then
|
||||
* disappear at any time.
|
||||
*/
|
||||
int
|
||||
netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na, int create)
|
||||
@ -1135,7 +1132,7 @@ netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na, int create)
|
||||
if (ret != NULL) {
|
||||
/* Users cannot use the NIC attached to a bridge directly */
|
||||
if (NETMAP_OWNED_BY_KERN(ret)) {
|
||||
error = EINVAL;
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
error = 0;
|
||||
|
@ -261,7 +261,7 @@ generic_netmap_register(struct netmap_adapter *na, int enable)
|
||||
/* Prepare to intercept incoming traffic. */
|
||||
error = netmap_catch_rx(na, 1);
|
||||
if (error) {
|
||||
D("netdev_rx_handler_register() failed");
|
||||
D("netdev_rx_handler_register() failed (%d)", error);
|
||||
goto register_handler;
|
||||
}
|
||||
ifp->if_capenable |= IFCAP_NETMAP;
|
||||
@ -283,7 +283,11 @@ generic_netmap_register(struct netmap_adapter *na, int enable)
|
||||
rate_ctx.refcount++;
|
||||
#endif /* RATE */
|
||||
|
||||
} else { /* Disable netmap mode. */
|
||||
} else if (na->tx_rings[0].tx_pool) {
|
||||
/* Disable netmap mode. We enter here only if the previous
|
||||
generic_netmap_register(na, 1) was successfull.
|
||||
If it was not, na->tx_rings[0].tx_pool was set to NULL by the
|
||||
error handling code below. */
|
||||
rtnl_lock();
|
||||
|
||||
ifp->if_capenable &= ~IFCAP_NETMAP;
|
||||
@ -322,7 +326,7 @@ generic_netmap_register(struct netmap_adapter *na, int enable)
|
||||
#ifdef REG_RESET
|
||||
error = ifp->netdev_ops->ndo_open(ifp);
|
||||
if (error) {
|
||||
goto alloc_tx_pool;
|
||||
goto free_tx_pools;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -338,6 +342,11 @@ generic_netmap_register(struct netmap_adapter *na, int enable)
|
||||
if (na->tx_rings[r].tx_pool[i])
|
||||
m_freem(na->tx_rings[r].tx_pool[i]);
|
||||
free(na->tx_rings[r].tx_pool, M_DEVBUF);
|
||||
na->tx_rings[r].tx_pool = NULL;
|
||||
}
|
||||
netmap_mitigation_cleanup(gna);
|
||||
for (r=0; r<na->num_rx_rings; r++) {
|
||||
mbq_safe_destroy(&na->rx_rings[r].rx_queue);
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -515,7 +515,7 @@ netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na, int create)
|
||||
b = nm_find_bridge(name, create);
|
||||
if (b == NULL) {
|
||||
D("no bridges available for '%s'", name);
|
||||
return (ENXIO);
|
||||
return (create ? ENOMEM : ENXIO);
|
||||
}
|
||||
|
||||
/* Now we are sure that name starts with the bridge's name,
|
||||
@ -547,7 +547,7 @@ netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na, int create)
|
||||
needed = 2; /* in some cases we only need 1 */
|
||||
if (b->bdg_active_ports + needed >= NM_BDG_MAXPORTS) {
|
||||
D("bridge full %d, cannot create new port", b->bdg_active_ports);
|
||||
return EINVAL;
|
||||
return ENOMEM;
|
||||
}
|
||||
/* record the next two ports available, but do not allocate yet */
|
||||
cand = b->bdg_port_index[b->bdg_active_ports];
|
||||
@ -594,7 +594,7 @@ netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na, int create)
|
||||
if (NETMAP_OWNED_BY_ANY(ret)) {
|
||||
D("NIC %s busy, cannot attach to bridge",
|
||||
NM_IFPNAME(ifp));
|
||||
error = EINVAL;
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
}
|
||||
/* create a fake interface */
|
||||
@ -658,11 +658,13 @@ nm_bdg_attach(struct nmreq *nmr)
|
||||
npriv = malloc(sizeof(*npriv), M_DEVBUF, M_NOWAIT|M_ZERO);
|
||||
if (npriv == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
NMG_LOCK();
|
||||
/* XXX probably netmap_get_bdg_na() */
|
||||
|
||||
error = netmap_get_bdg_na(nmr, &na, 1 /* create if not exists */);
|
||||
if (error) /* no device, or another bridge or user owns the device */
|
||||
goto unlock_exit;
|
||||
|
||||
if (na == NULL) { /* VALE prefix missing */
|
||||
error = EINVAL;
|
||||
goto unlock_exit;
|
||||
@ -707,6 +709,7 @@ nm_bdg_detach(struct nmreq *nmr)
|
||||
if (error) { /* no device, or another bridge or user owns the device */
|
||||
goto unlock_exit;
|
||||
}
|
||||
|
||||
if (na == NULL) { /* VALE prefix missing */
|
||||
error = EINVAL;
|
||||
goto unlock_exit;
|
||||
@ -1945,7 +1948,7 @@ netmap_bwrap_notify(struct netmap_adapter *na, u_int ring_n, enum txrx tx, int f
|
||||
int error = 0;
|
||||
|
||||
if (tx == NR_TX)
|
||||
return ENXIO;
|
||||
return EINVAL;
|
||||
|
||||
kring = &na->rx_rings[ring_n];
|
||||
hw_kring = &hwna->tx_rings[ring_n];
|
||||
@ -1999,7 +2002,7 @@ netmap_bwrap_host_notify(struct netmap_adapter *na, u_int ring_n, enum txrx tx,
|
||||
struct netmap_bwrap_adapter *bna = na->na_private;
|
||||
struct netmap_adapter *port_na = &bna->up.up;
|
||||
if (tx == NR_TX || ring_n != 0)
|
||||
return ENXIO;
|
||||
return EINVAL;
|
||||
return netmap_bwrap_notify(port_na, port_na->num_rx_rings, NR_RX, flags);
|
||||
}
|
||||
|
||||
|
@ -1158,7 +1158,7 @@ qls_send(qla_host_t *ha, struct mbuf **m_headp)
|
||||
QL_DPRINT8((ha->pci_dev, "%s: EFBIG [%d]\n", __func__,
|
||||
m_head->m_pkthdr.len));
|
||||
|
||||
m = m_defrag(m_head, M_DONTWAIT);
|
||||
m = m_defrag(m_head, M_NOWAIT);
|
||||
if (m == NULL) {
|
||||
ha->err_tx_defrag++;
|
||||
m_freem(m_head);
|
||||
@ -1413,7 +1413,7 @@ qls_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
|
||||
|
||||
if (mp == NULL) {
|
||||
|
||||
mp = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, ha->msize);
|
||||
mp = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, ha->msize);
|
||||
|
||||
if (mp == NULL) {
|
||||
|
||||
|
@ -411,6 +411,13 @@ uart_bus_attach(device_t dev)
|
||||
} else
|
||||
sc = sc0;
|
||||
|
||||
/*
|
||||
* Now that we know the softc for this device, connect the back
|
||||
* pointer from the sysdev for this device, if any
|
||||
*/
|
||||
if (sc->sc_sysdev != NULL)
|
||||
sc->sc_sysdev->sc = sc;
|
||||
|
||||
/*
|
||||
* Protect ourselves against interrupts while we're not completely
|
||||
* finished attaching and initializing. We don't expect interrupts
|
||||
@ -617,3 +624,19 @@ uart_bus_resume(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
return (UART_ATTACH(sc));
|
||||
}
|
||||
|
||||
void
|
||||
uart_grab(struct uart_devinfo *di)
|
||||
{
|
||||
|
||||
if (di->sc)
|
||||
UART_GRAB(di->sc);
|
||||
}
|
||||
|
||||
void
|
||||
uart_ungrab(struct uart_devinfo *di)
|
||||
{
|
||||
|
||||
if (di->sc)
|
||||
UART_UNGRAB(di->sc);
|
||||
}
|
||||
|
@ -33,6 +33,8 @@
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
struct uart_softc;
|
||||
|
||||
/*
|
||||
* Low-level operations for use by console and/or debug port support.
|
||||
*/
|
||||
@ -43,8 +45,6 @@ struct uart_ops {
|
||||
void (*putc)(struct uart_bas *, int);
|
||||
int (*rxready)(struct uart_bas *);
|
||||
int (*getc)(struct uart_bas *, struct mtx *);
|
||||
void (*grab)(struct uart_bas *);
|
||||
void (*ungrab)(struct uart_bas *);
|
||||
};
|
||||
|
||||
extern bus_space_tag_t uart_bus_space_io;
|
||||
@ -53,7 +53,6 @@ extern bus_space_tag_t uart_bus_space_mem;
|
||||
/*
|
||||
* Console and debug port device info.
|
||||
*/
|
||||
struct uart_softc;
|
||||
struct uart_devinfo {
|
||||
SLIST_ENTRY(uart_devinfo) next;
|
||||
struct uart_ops *ops;
|
||||
@ -70,6 +69,7 @@ struct uart_devinfo {
|
||||
int (*detach)(struct uart_softc*);
|
||||
void *cookie; /* Type dependent use. */
|
||||
struct mtx *hwmtx;
|
||||
struct uart_softc *sc; /* valid only from start of attach */
|
||||
};
|
||||
|
||||
int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
|
||||
@ -137,27 +137,6 @@ uart_putc(struct uart_devinfo *di, int c)
|
||||
uart_unlock(di->hwmtx);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
uart_grab(struct uart_devinfo *di)
|
||||
{
|
||||
|
||||
uart_lock(di->hwmtx);
|
||||
if (di->ops->grab)
|
||||
di->ops->grab(&di->bas);
|
||||
uart_unlock(di->hwmtx);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
uart_ungrab(struct uart_devinfo *di)
|
||||
{
|
||||
|
||||
uart_lock(di->hwmtx);
|
||||
if (di->ops->ungrab)
|
||||
di->ops->ungrab(&di->bas);
|
||||
uart_unlock(di->hwmtx);
|
||||
}
|
||||
|
||||
|
||||
static __inline int
|
||||
uart_rxready(struct uart_devinfo *di)
|
||||
{
|
||||
@ -190,4 +169,7 @@ uart_getc(struct uart_devinfo *di)
|
||||
return (di->ops->getc(&di->bas, di->hwmtx));
|
||||
}
|
||||
|
||||
void uart_grab(struct uart_devinfo *di);
|
||||
void uart_ungrab(struct uart_devinfo *di);
|
||||
|
||||
#endif /* _DEV_UART_CPU_H_ */
|
||||
|
@ -140,6 +140,8 @@ static int imx_uart_bus_probe(struct uart_softc *);
|
||||
static int imx_uart_bus_receive(struct uart_softc *);
|
||||
static int imx_uart_bus_setsig(struct uart_softc *, int);
|
||||
static int imx_uart_bus_transmit(struct uart_softc *);
|
||||
static void imx_uart_bus_grab(struct uart_softc *);
|
||||
static void imx_uart_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t imx_uart_methods[] = {
|
||||
KOBJMETHOD(uart_attach, imx_uart_bus_attach),
|
||||
@ -153,6 +155,8 @@ static kobj_method_t imx_uart_methods[] = {
|
||||
KOBJMETHOD(uart_receive, imx_uart_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, imx_uart_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, imx_uart_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, imx_uart_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, imx_uart_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -189,12 +193,7 @@ imx_uart_bus_attach(struct uart_softc *sc)
|
||||
|
||||
(void)imx_uart_bus_getsig(sc);
|
||||
|
||||
/* XXX workaround to have working console on mount prompt */
|
||||
if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE){
|
||||
DIS(bas, UCR4, DREN);
|
||||
} else {
|
||||
ENA(bas, UCR4, DREN);
|
||||
}
|
||||
ENA(bas, UCR4, DREN);
|
||||
DIS(bas, UCR1, RRDYEN);
|
||||
DIS(bas, UCR1, IDEN);
|
||||
DIS(bas, UCR3, RXDSEN);
|
||||
@ -402,13 +401,6 @@ static int
|
||||
imx_uart_bus_setsig(struct uart_softc *sc, int sig)
|
||||
{
|
||||
|
||||
/* TODO: implement (?) */
|
||||
|
||||
/* XXX workaround to have working console on mount prompt */
|
||||
/* Enable RX interrupt */
|
||||
if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE)
|
||||
if (!IS(&sc->sc_bas, UCR4, DREN))
|
||||
ENA(&sc->sc_bas, UCR4, DREN);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -434,3 +426,25 @@ imx_uart_bus_transmit(struct uart_softc *sc)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
imx_uart_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas = &sc->sc_bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
DIS(bas, UCR4, DREN);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
imx_uart_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas = &sc->sc_bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
ENA(bas, UCR4, DREN);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
@ -401,6 +401,8 @@ static int lpc_ns8250_bus_probe(struct uart_softc *);
|
||||
static int lpc_ns8250_bus_receive(struct uart_softc *);
|
||||
static int lpc_ns8250_bus_setsig(struct uart_softc *, int);
|
||||
static int lpc_ns8250_bus_transmit(struct uart_softc *);
|
||||
static void lpc_ns8250_bus_grab(struct uart_softc *);
|
||||
static void lpc_ns8250_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t lpc_ns8250_methods[] = {
|
||||
KOBJMETHOD(uart_attach, lpc_ns8250_bus_attach),
|
||||
@ -414,6 +416,8 @@ static kobj_method_t lpc_ns8250_methods[] = {
|
||||
KOBJMETHOD(uart_receive, lpc_ns8250_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, lpc_ns8250_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, lpc_ns8250_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, lpc_ns8250_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, lpc_ns8250_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -890,3 +894,34 @@ lpc_ns8250_bus_transmit(struct uart_softc *sc)
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
lpc_ns8250_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas = &sc->sc_bas;
|
||||
|
||||
/*
|
||||
* turn off all interrupts to enter polling mode. Leave the
|
||||
* saved mask alone. We'll restore whatever it was in ungrab.
|
||||
* All pending interupt signals are reset when IER is set to 0.
|
||||
*/
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(bas, REG_IER, 0);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
void
|
||||
lpc_ns8250_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct lpc_ns8250_softc *lpc_ns8250 = (struct lpc_ns8250_softc*)sc;
|
||||
struct uart_bas *bas = &sc->sc_bas;
|
||||
|
||||
/*
|
||||
* Restore previous interrupt mask
|
||||
*/
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(bas, REG_IER, lpc_ns8250->ier);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
@ -365,6 +365,8 @@ static kobj_method_t ns8250_methods[] = {
|
||||
KOBJMETHOD(uart_receive, ns8250_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, ns8250_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, ns8250_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, ns8250_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, ns8250_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -922,3 +924,34 @@ ns8250_bus_transmit(struct uart_softc *sc)
|
||||
uart_sched_softih(sc, SER_INT_TXIDLE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ns8250_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas = &sc->sc_bas;
|
||||
|
||||
/*
|
||||
* turn off all interrupts to enter polling mode. Leave the
|
||||
* saved mask alone. We'll restore whatever it was in ungrab.
|
||||
* All pending interupt signals are reset when IER is set to 0.
|
||||
*/
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(bas, REG_IER, 0);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
void
|
||||
ns8250_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
|
||||
struct uart_bas *bas = &sc->sc_bas;
|
||||
|
||||
/*
|
||||
* Restore previous interrupt mask
|
||||
*/
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(bas, REG_IER, ns8250->ier);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
@ -56,5 +56,7 @@ int ns8250_bus_probe(struct uart_softc *);
|
||||
int ns8250_bus_receive(struct uart_softc *);
|
||||
int ns8250_bus_setsig(struct uart_softc *, int);
|
||||
int ns8250_bus_transmit(struct uart_softc *);
|
||||
void ns8250_bus_grab(struct uart_softc *);
|
||||
void ns8250_bus_ungrab(struct uart_softc *);
|
||||
|
||||
#endif /* _DEV_UART_DEV_NS8250_H_ */
|
||||
|
@ -242,6 +242,8 @@ static int uart_pl011_bus_probe(struct uart_softc *);
|
||||
static int uart_pl011_bus_receive(struct uart_softc *);
|
||||
static int uart_pl011_bus_setsig(struct uart_softc *, int);
|
||||
static int uart_pl011_bus_transmit(struct uart_softc *);
|
||||
static void uart_pl011_bus_grab(struct uart_softc *);
|
||||
static void uart_pl011_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t uart_pl011_methods[] = {
|
||||
KOBJMETHOD(uart_attach, uart_pl011_bus_attach),
|
||||
@ -255,6 +257,9 @@ static kobj_method_t uart_pl011_methods[] = {
|
||||
KOBJMETHOD(uart_receive, uart_pl011_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, uart_pl011_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, uart_pl011_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, uart_pl011_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, uart_pl011_bus_ungrab),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -441,3 +446,27 @@ uart_pl011_bus_transmit(struct uart_softc *sc)
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
uart_pl011_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
__uart_setreg(bas, UART_IMSC, /* Switch to RX polling while grabbed */
|
||||
~UART_RXREADY & __uart_getreg(bas, UART_IMSC));
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
uart_pl011_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
__uart_setreg(bas, UART_IMSC, /* Switch to RX interrupts while not grabbed */
|
||||
UART_RXREADY | __uart_getreg(bas, UART_IMSC));
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
@ -245,6 +245,8 @@ static int quicc_bus_probe(struct uart_softc *);
|
||||
static int quicc_bus_receive(struct uart_softc *);
|
||||
static int quicc_bus_setsig(struct uart_softc *, int);
|
||||
static int quicc_bus_transmit(struct uart_softc *);
|
||||
static void quicc_bus_grab(struct uart_softc *);
|
||||
static void quicc_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t quicc_methods[] = {
|
||||
KOBJMETHOD(uart_attach, quicc_bus_attach),
|
||||
@ -258,6 +260,8 @@ static kobj_method_t quicc_methods[] = {
|
||||
KOBJMETHOD(uart_receive, quicc_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, quicc_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, quicc_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, quicc_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, quicc_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -485,3 +489,34 @@ quicc_bus_transmit(struct uart_softc *sc)
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
quicc_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
uint16_t st, rb;
|
||||
|
||||
/* Disable interrupts on the receive buffer. */
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
|
||||
st = quicc_read2(bas, rb);
|
||||
quicc_write2(bas, rb, st & ~0x9000);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
quicc_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
uint16_t st, rb;
|
||||
|
||||
/* Enable interrupts on the receive buffer. */
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1));
|
||||
st = quicc_read2(bas, rb);
|
||||
quicc_write2(bas, rb, st | 0x9000);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
|
@ -365,6 +365,8 @@ static int sab82532_bus_probe(struct uart_softc *);
|
||||
static int sab82532_bus_receive(struct uart_softc *);
|
||||
static int sab82532_bus_setsig(struct uart_softc *, int);
|
||||
static int sab82532_bus_transmit(struct uart_softc *);
|
||||
static void sab82532_bus_grab(struct uart_softc *);
|
||||
static void sab82532_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t sab82532_methods[] = {
|
||||
KOBJMETHOD(uart_attach, sab82532_bus_attach),
|
||||
@ -378,6 +380,8 @@ static kobj_method_t sab82532_methods[] = {
|
||||
KOBJMETHOD(uart_receive, sab82532_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, sab82532_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, sab82532_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, sab82532_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, sab82532_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -724,3 +728,32 @@ sab82532_bus_transmit(struct uart_softc *sc)
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
sab82532_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
uint8_t imr0;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
imr0 = SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO; /* No TCD or RPF */
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(bas, SAB_IMR0, 0xff & ~imr0);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
sab82532_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
uint8_t imr0;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO|
|
||||
SAB_IMR0_RPF;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(bas, SAB_IMR0, 0xff & ~imr0);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
@ -281,6 +281,8 @@ static int z8530_bus_probe(struct uart_softc *);
|
||||
static int z8530_bus_receive(struct uart_softc *);
|
||||
static int z8530_bus_setsig(struct uart_softc *, int);
|
||||
static int z8530_bus_transmit(struct uart_softc *);
|
||||
static void z8530_bus_grab(struct uart_softc *);
|
||||
static void z8530_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t z8530_methods[] = {
|
||||
KOBJMETHOD(uart_attach, z8530_bus_attach),
|
||||
@ -294,6 +296,8 @@ static kobj_method_t z8530_methods[] = {
|
||||
KOBJMETHOD(uart_receive, z8530_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, z8530_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, z8530_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, z8530_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, z8530_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -621,3 +625,27 @@ z8530_bus_transmit(struct uart_softc *sc)
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
z8530_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
z8530_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
struct uart_bas *bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE | IDT_RIA);
|
||||
uart_barrier(bas);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
@ -141,3 +141,19 @@ METHOD int setsig {
|
||||
METHOD int transmit {
|
||||
struct uart_softc *this;
|
||||
};
|
||||
|
||||
# grab() - Up call from the console to the upper layers of the driver when
|
||||
# the kernel asks to grab the console. This is valid only for console
|
||||
# drivers. This method is responsible for transitioning the hardware
|
||||
# from an interrupt driven state to a polled state that works with the
|
||||
# low-level console interface defined for this device. The kernel
|
||||
# currently only calls this when it wants to grab input from the
|
||||
# console. Output can still happen asyncrhonously to these calls.
|
||||
METHOD void grab {
|
||||
struct uart_softc *this;
|
||||
};
|
||||
|
||||
# ungrab() - Undoes the effects of grab().
|
||||
METHOD void ungrab {
|
||||
struct uart_softc *this;
|
||||
};
|
||||
|
@ -817,6 +817,8 @@ uhso_probe_iface_auto(struct usb_device *udev, int index)
|
||||
UHSO_PORT_SERIAL | UHSO_PORT_NETWORK, port));
|
||||
case UHSO_PORT_TYPE_DIAG:
|
||||
case UHSO_PORT_TYPE_DIAG2:
|
||||
case UHSO_PORT_TYPE_GPS:
|
||||
case UHSO_PORT_TYPE_GPSCTL:
|
||||
case UHSO_PORT_TYPE_CTL:
|
||||
case UHSO_PORT_TYPE_APP:
|
||||
case UHSO_PORT_TYPE_APP2:
|
||||
|
@ -207,6 +207,11 @@ usb_ref_device(struct usb_cdev_privdata *cpd,
|
||||
DPRINTFN(2, "no device at %u\n", cpd->dev_index);
|
||||
goto error;
|
||||
}
|
||||
if (cpd->udev->state == USB_STATE_DETACHED &&
|
||||
(need_uref != 2)) {
|
||||
DPRINTFN(2, "device is detached\n");
|
||||
goto error;
|
||||
}
|
||||
if (cpd->udev->refcount == USB_DEV_REF_MAX) {
|
||||
DPRINTFN(2, "no dev ref\n");
|
||||
goto error;
|
||||
@ -597,6 +602,13 @@ usb_fifo_free(struct usb_fifo *f)
|
||||
mtx_unlock(f->priv_mtx);
|
||||
mtx_lock(&usb_ref_lock);
|
||||
|
||||
/*
|
||||
* Check if the "f->refcount" variable reached zero
|
||||
* during the unlocked time before entering wait:
|
||||
*/
|
||||
if (f->refcount == 0)
|
||||
break;
|
||||
|
||||
/* wait for sync */
|
||||
cv_wait(&f->cv_drain, &usb_ref_lock);
|
||||
}
|
||||
@ -915,23 +927,12 @@ usb_close(void *arg)
|
||||
|
||||
DPRINTFN(2, "cpd=%p\n", cpd);
|
||||
|
||||
err = usb_ref_device(cpd, &refs, 0);
|
||||
if (err)
|
||||
err = usb_ref_device(cpd, &refs,
|
||||
2 /* uref and allow detached state */);
|
||||
if (err) {
|
||||
DPRINTFN(0, "Cannot grab USB reference when "
|
||||
"closing USB file handle\n");
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* If this function is not called directly from the root HUB
|
||||
* thread, there is usually a need to lock the enumeration
|
||||
* lock. Check this.
|
||||
*/
|
||||
if (!usbd_enum_is_locked(cpd->udev)) {
|
||||
|
||||
DPRINTFN(2, "Locking enumeration\n");
|
||||
|
||||
/* reference device */
|
||||
err = usb_usb_ref_device(cpd, &refs);
|
||||
if (err)
|
||||
goto done;
|
||||
}
|
||||
if (cpd->fflags & FREAD) {
|
||||
usb_fifo_close(refs.rxfifo, cpd->fflags);
|
||||
|
@ -2070,6 +2070,8 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
|
||||
DPRINTFN(4, "udev=%p port=%d\n", udev, udev->port_no);
|
||||
|
||||
bus = udev->bus;
|
||||
|
||||
/* set DETACHED state to prevent any further references */
|
||||
usb_set_device_state(udev, USB_STATE_DETACHED);
|
||||
|
||||
#if USB_HAVE_DEVCTL
|
||||
@ -2085,16 +2087,7 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
|
||||
usb_free_symlink(udev->ugen_symlink);
|
||||
udev->ugen_symlink = NULL;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Unregister our device first which will prevent any further
|
||||
* references:
|
||||
*/
|
||||
usb_bus_port_set_device(bus, udev->parent_hub ?
|
||||
udev->parent_hub->hub->ports + udev->port_index : NULL,
|
||||
NULL, USB_ROOT_HUB_ADDR);
|
||||
|
||||
#if USB_HAVE_UGEN
|
||||
/* wait for all pending references to go away: */
|
||||
mtx_lock(&usb_ref_lock);
|
||||
udev->refcount--;
|
||||
@ -2114,6 +2107,11 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
|
||||
/* the following will get the device unconfigured in software */
|
||||
usb_unconfigure(udev, USB_UNCFG_FLAG_FREE_EP0);
|
||||
|
||||
/* final device unregister after all character devices are closed */
|
||||
usb_bus_port_set_device(bus, udev->parent_hub ?
|
||||
udev->parent_hub->hub->ports + udev->port_index : NULL,
|
||||
NULL, USB_ROOT_HUB_ADDR);
|
||||
|
||||
/* unsetup any leftover default USB transfers */
|
||||
usbd_transfer_unsetup(udev->ctrl_xfer, USB_CTRL_XFER_MAX);
|
||||
|
||||
@ -2647,8 +2645,14 @@ usb_set_device_state(struct usb_device *udev, enum usb_dev_state state)
|
||||
|
||||
DPRINTF("udev %p state %s -> %s\n", udev,
|
||||
usb_statestr(udev->state), usb_statestr(state));
|
||||
udev->state = state;
|
||||
|
||||
#if USB_HAVE_UGEN
|
||||
mtx_lock(&usb_ref_lock);
|
||||
#endif
|
||||
udev->state = state;
|
||||
#if USB_HAVE_UGEN
|
||||
mtx_unlock(&usb_ref_lock);
|
||||
#endif
|
||||
if (udev->bus->methods->device_state_change != NULL)
|
||||
(udev->bus->methods->device_state_change) (udev);
|
||||
}
|
||||
|
231
sys/dev/virtio/random/virtio_random.c
Normal file
231
sys/dev/virtio/random/virtio_random.c
Normal file
@ -0,0 +1,231 @@
|
||||
/*-
|
||||
* Copyright (c) 2013, Bryan Venteicher <bryanv@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice unmodified, this list of conditions, and the following
|
||||
* disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Driver for VirtIO entropy device. */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/sglist.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/random.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/virtio/virtio.h>
|
||||
#include <dev/virtio/virtqueue.h>
|
||||
|
||||
struct vtrnd_softc {
|
||||
device_t vtrnd_dev;
|
||||
uint64_t vtrnd_features;
|
||||
struct callout vtrnd_callout;
|
||||
struct virtqueue *vtrnd_vq;
|
||||
};
|
||||
|
||||
static int vtrnd_modevent(module_t, int, void *);
|
||||
|
||||
static int vtrnd_probe(device_t);
|
||||
static int vtrnd_attach(device_t);
|
||||
static int vtrnd_detach(device_t);
|
||||
|
||||
static void vtrnd_negotiate_features(struct vtrnd_softc *);
|
||||
static int vtrnd_alloc_virtqueue(struct vtrnd_softc *);
|
||||
static void vtrnd_harvest(struct vtrnd_softc *);
|
||||
static void vtrnd_timer(void *);
|
||||
|
||||
#define VTRND_FEATURES 0
|
||||
|
||||
static struct virtio_feature_desc vtrnd_feature_desc[] = {
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static device_method_t vtrnd_methods[] = {
|
||||
/* Device methods. */
|
||||
DEVMETHOD(device_probe, vtrnd_probe),
|
||||
DEVMETHOD(device_attach, vtrnd_attach),
|
||||
DEVMETHOD(device_detach, vtrnd_detach),
|
||||
|
||||
DEVMETHOD_END
|
||||
};
|
||||
|
||||
static driver_t vtrnd_driver = {
|
||||
"vtrnd",
|
||||
vtrnd_methods,
|
||||
sizeof(struct vtrnd_softc)
|
||||
};
|
||||
static devclass_t vtrnd_devclass;
|
||||
|
||||
DRIVER_MODULE(virtio_random, virtio_pci, vtrnd_driver, vtrnd_devclass,
|
||||
vtrnd_modevent, 0);
|
||||
MODULE_VERSION(virtio_random, 1);
|
||||
MODULE_DEPEND(virtio_random, virtio, 1, 1, 1);
|
||||
|
||||
static int
|
||||
vtrnd_modevent(module_t mod, int type, void *unused)
|
||||
{
|
||||
int error;
|
||||
|
||||
switch (type) {
|
||||
case MOD_LOAD:
|
||||
case MOD_QUIESCE:
|
||||
case MOD_UNLOAD:
|
||||
case MOD_SHUTDOWN:
|
||||
error = 0;
|
||||
break;
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
vtrnd_probe(device_t dev)
|
||||
{
|
||||
|
||||
if (virtio_get_device_type(dev) != VIRTIO_ID_ENTROPY)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "VirtIO Entropy Adapter");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
vtrnd_attach(device_t dev)
|
||||
{
|
||||
struct vtrnd_softc *sc;
|
||||
int error;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->vtrnd_dev = dev;
|
||||
|
||||
callout_init(&sc->vtrnd_callout, CALLOUT_MPSAFE);
|
||||
|
||||
virtio_set_feature_desc(dev, vtrnd_feature_desc);
|
||||
vtrnd_negotiate_features(sc);
|
||||
|
||||
error = vtrnd_alloc_virtqueue(sc);
|
||||
if (error) {
|
||||
device_printf(dev, "cannot allocate virtqueue\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
callout_reset(&sc->vtrnd_callout, 5 * hz, vtrnd_timer, sc);
|
||||
|
||||
fail:
|
||||
if (error)
|
||||
vtrnd_detach(dev);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
vtrnd_detach(device_t dev)
|
||||
{
|
||||
struct vtrnd_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
callout_stop(&sc->vtrnd_callout);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
vtrnd_negotiate_features(struct vtrnd_softc *sc)
|
||||
{
|
||||
device_t dev;
|
||||
uint64_t features;
|
||||
|
||||
dev = sc->vtrnd_dev;
|
||||
features = VTRND_FEATURES;
|
||||
|
||||
sc->vtrnd_features = virtio_negotiate_features(dev, features);
|
||||
}
|
||||
|
||||
static int
|
||||
vtrnd_alloc_virtqueue(struct vtrnd_softc *sc)
|
||||
{
|
||||
device_t dev;
|
||||
struct vq_alloc_info vq_info;
|
||||
|
||||
dev = sc->vtrnd_dev;
|
||||
|
||||
VQ_ALLOC_INFO_INIT(&vq_info, 0, NULL, sc, &sc->vtrnd_vq,
|
||||
"%s request", device_get_nameunit(dev));
|
||||
|
||||
return (virtio_alloc_virtqueues(dev, 0, 1, &vq_info));
|
||||
}
|
||||
|
||||
static void
|
||||
vtrnd_harvest(struct vtrnd_softc *sc)
|
||||
{
|
||||
struct sglist_seg segs[1];
|
||||
struct sglist sg;
|
||||
struct virtqueue *vq;
|
||||
uint32_t value;
|
||||
int error;
|
||||
|
||||
vq = sc->vtrnd_vq;
|
||||
|
||||
sglist_init(&sg, 1, segs);
|
||||
error = sglist_append(&sg, &value, sizeof(value));
|
||||
KASSERT(error == 0 && sg.sg_nseg == 1,
|
||||
("%s: error %d adding buffer to sglist", __func__, error));
|
||||
|
||||
if (!virtqueue_empty(vq))
|
||||
return;
|
||||
if (virtqueue_enqueue(vq, &value, &sg, 0, 1) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Poll for the response, but the command is likely already
|
||||
* done when we return from the notify.
|
||||
*/
|
||||
virtqueue_notify(vq);
|
||||
virtqueue_poll(vq, NULL);
|
||||
|
||||
random_harvest(&value, sizeof(value), sizeof(value) * NBBY / 2,
|
||||
RANDOM_PURE_VIRTIO);
|
||||
}
|
||||
|
||||
static void
|
||||
vtrnd_timer(void *xsc)
|
||||
{
|
||||
struct vtrnd_softc *sc;
|
||||
|
||||
sc = xsc;
|
||||
|
||||
vtrnd_harvest(sc);
|
||||
callout_schedule(&sc->vtrnd_callout, 5 * hz);
|
||||
}
|
@ -1,12 +1,9 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Rink Springer
|
||||
* Copyright (c) 2013 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 2009 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Ed Schouten
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
* This software was developed by Aleksandr Rybalko under sponsorship from the
|
||||
* FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -28,16 +25,23 @@
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/fbio.h>
|
||||
|
||||
#include "opt_platform.h"
|
||||
|
||||
#include <dev/vt/vt.h>
|
||||
#include <dev/vt/hw/fb/vt_fb.h>
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
@ -47,110 +51,32 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/xbox.h>
|
||||
|
||||
struct xbox_softc {
|
||||
bus_space_tag_t xbox_fb_tag;
|
||||
bus_space_handle_t xbox_fb_handle;
|
||||
};
|
||||
|
||||
/* Convenience macros. */
|
||||
#define MEM_WRITE4(sc, ofs, val) \
|
||||
bus_space_write_4(sc->xbox_fb_tag, sc->xbox_fb_handle, ofs, val)
|
||||
|
||||
#define VT_XBOX_WIDTH 640
|
||||
#define VT_XBOX_HEIGHT 480
|
||||
|
||||
static vd_init_t xbox_init;
|
||||
static vd_blank_t xbox_blank;
|
||||
static vd_bitbltchr_t xbox_bitbltchr;
|
||||
static vd_init_t xboxfb_init;
|
||||
|
||||
static const struct vt_driver vt_xbox_driver = {
|
||||
.vd_init = xbox_init,
|
||||
.vd_blank = xbox_blank,
|
||||
.vd_bitbltchr = xbox_bitbltchr,
|
||||
.vd_priority = VD_PRIORITY_GENERIC+1,
|
||||
static struct vt_driver xboxfb_driver = {
|
||||
.vd_init = xboxfb_init,
|
||||
.vd_blank = vt_fb_blank,
|
||||
.vd_bitbltchr = vt_fb_bitbltchr,
|
||||
.vd_priority = VD_PRIORITY_GENERIC,
|
||||
};
|
||||
|
||||
static struct xbox_softc xbox_conssoftc;
|
||||
VT_CONSDEV_DECLARE(vt_xbox_driver, PIXEL_WIDTH(VT_XBOX_WIDTH),
|
||||
PIXEL_HEIGHT(VT_XBOX_HEIGHT), &xbox_conssoftc);
|
||||
static struct fb_info xboxfb_info;
|
||||
VT_CONSDEV_DECLARE(xboxfb_driver, PIXEL_WIDTH(VT_XBOX_WIDTH),
|
||||
PIXEL_HEIGHT(VT_XBOX_HEIGHT), &xboxfb_info);
|
||||
|
||||
static const uint32_t colormap[] = {
|
||||
0x00000000, /* Black */
|
||||
0x00ff0000, /* Red */
|
||||
0x0000ff00, /* Green */
|
||||
0x00c0c000, /* Brown */
|
||||
0x000000ff, /* Blue */
|
||||
0x00c000c0, /* Magenta */
|
||||
0x0000c0c0, /* Cyan */
|
||||
0x00c0c0c0, /* Light grey */
|
||||
0x00808080, /* Dark grey */
|
||||
0x00ff8080, /* Light red */
|
||||
0x0080ff80, /* Light green */
|
||||
0x00ffff80, /* Yellow */
|
||||
0x008080ff, /* Light blue */
|
||||
0x00ff80ff, /* Light magenta */
|
||||
0x0080ffff, /* Light cyan */
|
||||
0x00ffffff, /* White */
|
||||
};
|
||||
|
||||
static void
|
||||
xbox_blank(struct vt_device *vd, term_color_t color)
|
||||
{
|
||||
struct xbox_softc *sc = vd->vd_softc;
|
||||
u_int ofs;
|
||||
uint32_t c;
|
||||
|
||||
c = colormap[color];
|
||||
for (ofs = 0; ofs < (VT_XBOX_WIDTH * VT_XBOX_HEIGHT) * 4; ofs += 4)
|
||||
MEM_WRITE4(sc, ofs, c);
|
||||
}
|
||||
|
||||
static void
|
||||
xbox_bitbltchr(struct vt_device *vd, const uint8_t *src, const uint8_t *mask,
|
||||
int bpl, vt_axis_t top, vt_axis_t left, unsigned int width,
|
||||
unsigned int height, term_color_t fg, term_color_t bg)
|
||||
{
|
||||
struct xbox_softc *sc = vd->vd_softc;
|
||||
u_long line;
|
||||
uint32_t fgc, bgc;
|
||||
int c;
|
||||
uint8_t b, m;
|
||||
|
||||
fgc = colormap[fg];
|
||||
bgc = colormap[bg];
|
||||
|
||||
/* Don't try to put off screen pixels */
|
||||
if (((left + width) > info->fb_width) || ((top + height) >
|
||||
info->fb_height))
|
||||
return;
|
||||
|
||||
line = (VT_XBOX_WIDTH * top + left) * 4;
|
||||
for (; height > 0; height--) {
|
||||
for (c = 0; c < width; c++) {
|
||||
if (c % 8 == 0)
|
||||
b = *src++;
|
||||
else
|
||||
b <<= 1;
|
||||
if (mask != NULL) {
|
||||
if (c % 8 == 0)
|
||||
m = *mask++;
|
||||
else
|
||||
m <<= 1;
|
||||
/* Skip pixel write, if mask has no bit set. */
|
||||
if ((m & 0x80) == 0)
|
||||
continue;
|
||||
}
|
||||
MEM_WRITE4(sc, line + c * 4, b & 0x80 ? fgc : bgc);
|
||||
}
|
||||
line += VT_XBOX_WIDTH * 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
xbox_initialize(struct vt_device *vd)
|
||||
static int
|
||||
xboxfb_init(struct vt_device *vd)
|
||||
{
|
||||
struct fb_info *info;
|
||||
int i;
|
||||
|
||||
if (!arch_i386_is_xbox)
|
||||
return (CN_DEAD);
|
||||
|
||||
info = &xboxfb_info;
|
||||
/*
|
||||
* We must make a mapping from video framebuffer memory
|
||||
* to real. This is very crude: we map the entire
|
||||
@ -175,25 +101,27 @@ xbox_initialize(struct vt_device *vd)
|
||||
*(uint32_t *)((i + 1) * PAGE_SIZE + XBOX_FB_START_PTR % PAGE_SIZE) =
|
||||
XBOX_FB_START;
|
||||
|
||||
/* Clear the screen. */
|
||||
xbox_blank(vd, TC_BLACK);
|
||||
}
|
||||
/* Initialize fb_info. */
|
||||
info = vd->vd_softc;
|
||||
|
||||
static int
|
||||
xbox_init(struct vt_device *vd)
|
||||
{
|
||||
struct xbox_softc *sc = vd->vd_softc;
|
||||
info->fb_width = VT_XBOX_WIDTH;
|
||||
info->fb_height = VT_XBOX_HEIGHT;
|
||||
|
||||
if (!arch_i386_is_xbox)
|
||||
return (CN_DEAD);
|
||||
info->fb_size = XBOX_FB_SIZE;
|
||||
info->fb_stride = VT_XBOX_WIDTH * 4; /* 32bits per pixel. */
|
||||
|
||||
sc->xbox_fb_tag = X86_BUS_SPACE_MEM;
|
||||
sc->xbox_fb_handle = PAGE_SIZE;
|
||||
info->fb_vbase = PAGE_SIZE;
|
||||
info->fb_pbase = XBOX_FB_START_PTR;
|
||||
|
||||
vd->vd_width = VT_XBOX_WIDTH;
|
||||
vd->vd_height = VT_XBOX_HEIGHT;
|
||||
/* Get pixel storage size. */
|
||||
info->fb_bpp = 32;
|
||||
/* Get color depth. */
|
||||
info->fb_depth = 24;
|
||||
|
||||
xbox_initialize(vd);
|
||||
vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255,
|
||||
8, 255, 16);
|
||||
fb_probe(info);
|
||||
vt_fb_init(vd);
|
||||
|
||||
return (CN_INTERNAL);
|
||||
}
|
||||
@ -201,12 +129,13 @@ xbox_init(struct vt_device *vd)
|
||||
static void
|
||||
xbox_remap(void *unused)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
||||
if (!arch_i386_is_xbox)
|
||||
return;
|
||||
|
||||
xbox_conssoftc.xbox_fb_handle =
|
||||
(bus_space_handle_t)pmap_mapdev(XBOX_FB_START, XBOX_FB_SIZE);
|
||||
info = &xboxfb_info;
|
||||
info->fb_vbase = (intptr_t)pmap_mapdev(info->fb_pbase, info->fb_size);
|
||||
}
|
||||
|
||||
SYSINIT(xboxfb, SI_SUB_DRIVERS, SI_ORDER_ANY, xbox_remap, NULL);
|
||||
|
@ -1089,7 +1089,6 @@ g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp)
|
||||
gctl_error(req, "Device %s already exist", mpname);
|
||||
return;
|
||||
}
|
||||
sc = gp->softc;
|
||||
|
||||
memset(&md, 0, sizeof(md));
|
||||
strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic));
|
||||
|
@ -800,6 +800,7 @@ device vtnet # VirtIO Ethernet device
|
||||
device virtio_blk # VirtIO Block device
|
||||
device virtio_scsi # VirtIO SCSI device
|
||||
device virtio_balloon # VirtIO Memory Balloon device
|
||||
device virtio_random # VirtIO Entropy device
|
||||
|
||||
device hyperv # HyperV drivers
|
||||
|
||||
|
14
sys/i386/conf/VT
Normal file
14
sys/i386/conf/VT
Normal file
@ -0,0 +1,14 @@
|
||||
# VT -- kernel config using the vt(9) system console instead of legacy syscons
|
||||
#
|
||||
# For more information see https://wiki.freebsd.org/Newcons
|
||||
#
|
||||
# $FreeBSD$
|
||||
|
||||
include GENERIC
|
||||
ident VT
|
||||
|
||||
nodevice sc
|
||||
nodevice vga
|
||||
|
||||
device vt
|
||||
device vt_vga
|
@ -192,7 +192,9 @@ options AH_SUPPORT_AR5416
|
||||
# Various (pseudo) devices
|
||||
device ether # Ethernet support
|
||||
device faith # IPv6-to-IPv4 relaying (translation)
|
||||
device firmware # firmware assist module
|
||||
device gif # IPv6 and IPv4 tunneling
|
||||
device kbdmux # keyboard multiplexer
|
||||
device loop # Network loopback
|
||||
device md # Memory "disks"
|
||||
device puc # Multi I/O cards and multi-channel UARTs
|
||||
@ -200,7 +202,8 @@ device random # Entropy device
|
||||
device tun # Packet tunnel.
|
||||
device uart # Serial port (UART)
|
||||
device vlan # 802.1Q VLAN support
|
||||
device firmware # firmware assist module
|
||||
device vt # Virtual terminals
|
||||
device vt_vga # VGA terminal device
|
||||
|
||||
# The `bpf' device enables the Berkeley Packet Filter.
|
||||
# Be aware of the administrative consequences of enabling this!
|
||||
|
@ -1303,6 +1303,8 @@ pmap_set_pte(struct ia64_lpte *pte, vm_offset_t va, vm_offset_t pa,
|
||||
|
||||
pte->itir = PAGE_SHIFT << 2;
|
||||
|
||||
ia64_mf();
|
||||
|
||||
pte->tag = ia64_ttag(va);
|
||||
}
|
||||
|
||||
@ -1321,8 +1323,8 @@ pmap_remove_pte(pmap_t pmap, struct ia64_lpte *pte, vm_offset_t va,
|
||||
* First remove from the VHPT.
|
||||
*/
|
||||
error = pmap_remove_vhpt(va);
|
||||
if (error)
|
||||
return (error);
|
||||
KASSERT(error == 0, ("%s: pmap_remove_vhpt returned %d",
|
||||
__func__, error));
|
||||
|
||||
pmap_invalidate_page(va);
|
||||
|
||||
|
@ -294,6 +294,7 @@ static struct {
|
||||
{ &fs_filtops }, /* EVFILT_FS */
|
||||
{ &null_filtops }, /* EVFILT_LIO */
|
||||
{ &user_filtops }, /* EVFILT_USER */
|
||||
{ &null_filtops }, /* EVFILT_SENDFILE */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -132,7 +132,7 @@ __FBSDID("$FreeBSD$");
|
||||
/* Define this to check for blessed mutexes */
|
||||
#undef BLESSING
|
||||
|
||||
#define WITNESS_COUNT 1024
|
||||
#define WITNESS_COUNT 1536
|
||||
#define WITNESS_CHILDCOUNT (WITNESS_COUNT * 4)
|
||||
#define WITNESS_HASH_SIZE 251 /* Prime, gives load factor < 2 */
|
||||
#define WITNESS_PENDLIST 1024
|
||||
|
@ -554,7 +554,7 @@ m_dup_pkthdr(struct mbuf *to, struct mbuf *from, int how)
|
||||
to->m_data = to->m_pktdat;
|
||||
to->m_pkthdr = from->m_pkthdr;
|
||||
SLIST_INIT(&to->m_pkthdr.tags);
|
||||
return (m_tag_copy_chain(to, from, MBTOM(how)));
|
||||
return (m_tag_copy_chain(to, from, how));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -813,7 +813,7 @@ sbflush_internal(struct sockbuf *sb)
|
||||
|
||||
while (sb->sb_mbcnt) {
|
||||
/*
|
||||
* Don't call sbdrop(sb, 0) if the leading mbuf is non-empty:
|
||||
* Don't call sbcut(sb, 0) if the leading mbuf is non-empty:
|
||||
* we would loop forever. Panic instead.
|
||||
*/
|
||||
if (!sb->sb_cc && (sb->sb_mb == NULL || sb->sb_mb->m_len))
|
||||
|
@ -1723,28 +1723,27 @@ soreceive_generic(struct socket *so, struct sockaddr **psa, struct uio *uio,
|
||||
moff += len;
|
||||
else {
|
||||
if (mp != NULL) {
|
||||
int copy_flag;
|
||||
|
||||
if (flags & MSG_DONTWAIT)
|
||||
copy_flag = M_NOWAIT;
|
||||
else
|
||||
copy_flag = M_WAIT;
|
||||
if (copy_flag == M_WAITOK)
|
||||
if (flags & MSG_DONTWAIT) {
|
||||
*mp = m_copym(m, 0, len,
|
||||
M_NOWAIT);
|
||||
if (*mp == NULL) {
|
||||
/*
|
||||
* m_copym() couldn't
|
||||
* allocate an mbuf.
|
||||
* Adjust uio_resid back
|
||||
* (it was adjusted
|
||||
* down by len bytes,
|
||||
* which we didn't end
|
||||
* up "copying" over).
|
||||
*/
|
||||
uio->uio_resid += len;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
SOCKBUF_UNLOCK(&so->so_rcv);
|
||||
*mp = m_copym(m, 0, len, copy_flag);
|
||||
if (copy_flag == M_WAITOK)
|
||||
*mp = m_copym(m, 0, len,
|
||||
M_WAITOK);
|
||||
SOCKBUF_LOCK(&so->so_rcv);
|
||||
if (*mp == NULL) {
|
||||
/*
|
||||
* m_copym() couldn't
|
||||
* allocate an mbuf. Adjust
|
||||
* uio_resid back (it was
|
||||
* adjusted down by len
|
||||
* bytes, which we didn't end
|
||||
* up "copying" over).
|
||||
*/
|
||||
uio->uio_resid += len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m->m_data += len;
|
||||
|
@ -123,6 +123,10 @@ static int getpeername1(struct thread *td, struct getpeername_args *uap,
|
||||
|
||||
counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)];
|
||||
|
||||
static int filt_sfsync_attach(struct knote *kn);
|
||||
static void filt_sfsync_detach(struct knote *kn);
|
||||
static int filt_sfsync(struct knote *kn, long hint);
|
||||
|
||||
/*
|
||||
* sendfile(2)-related variables and associated sysctls
|
||||
*/
|
||||
@ -132,8 +136,28 @@ static int sfreadahead = 1;
|
||||
SYSCTL_INT(_kern_ipc_sendfile, OID_AUTO, readahead, CTLFLAG_RW,
|
||||
&sfreadahead, 0, "Number of sendfile(2) read-ahead MAXBSIZE blocks");
|
||||
|
||||
#ifdef SFSYNC_DEBUG
|
||||
static int sf_sync_debug = 0;
|
||||
SYSCTL_INT(_debug, OID_AUTO, sf_sync_debug, CTLFLAG_RW,
|
||||
&sf_sync_debug, 0, "Output debugging during sf_sync lifecycle");
|
||||
#define SFSYNC_DPRINTF(s, ...) \
|
||||
do { \
|
||||
if (sf_sync_debug) \
|
||||
printf((s), ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
#else
|
||||
#define SFSYNC_DPRINTF(c, ...)
|
||||
#endif
|
||||
|
||||
static uma_zone_t zone_sfsync;
|
||||
|
||||
static struct filterops sendfile_filtops = {
|
||||
.f_isfd = 0,
|
||||
.f_attach = filt_sfsync_attach,
|
||||
.f_detach = filt_sfsync_detach,
|
||||
.f_event = filt_sfsync,
|
||||
};
|
||||
|
||||
static void
|
||||
sfstat_init(const void *unused)
|
||||
{
|
||||
@ -152,6 +176,7 @@ sf_sync_init(const void *unused)
|
||||
NULL, NULL,
|
||||
UMA_ALIGN_CACHE,
|
||||
0);
|
||||
kqueue_add_filteropts(EVFILT_SENDFILE, &sendfile_filtops);
|
||||
}
|
||||
SYSINIT(sf_sync, SI_SUB_MBUF, SI_ORDER_FIRST, sf_sync_init, NULL);
|
||||
|
||||
@ -1860,6 +1885,118 @@ getsockaddr(namp, uaddr, len)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
filt_sfsync_attach(struct knote *kn)
|
||||
{
|
||||
struct sendfile_sync *sfs = (struct sendfile_sync *) kn->kn_sdata;
|
||||
struct knlist *knl = &sfs->klist;
|
||||
|
||||
SFSYNC_DPRINTF("%s: kn=%p, sfs=%p\n", __func__, kn, sfs);
|
||||
|
||||
/*
|
||||
* Validate that we actually received this via the kernel API.
|
||||
*/
|
||||
if ((kn->kn_flags & EV_FLAG1) == 0)
|
||||
return (EPERM);
|
||||
|
||||
kn->kn_ptr.p_v = sfs;
|
||||
kn->kn_flags &= ~EV_FLAG1;
|
||||
|
||||
knl->kl_lock(knl->kl_lockarg);
|
||||
/*
|
||||
* If we're in the "freeing" state,
|
||||
* don't allow the add. That way we don't
|
||||
* end up racing with some other thread that
|
||||
* is trying to finish some setup.
|
||||
*/
|
||||
if (sfs->state == SF_STATE_FREEING) {
|
||||
knl->kl_unlock(knl->kl_lockarg);
|
||||
return (EINVAL);
|
||||
}
|
||||
knlist_add(&sfs->klist, kn, 1);
|
||||
knl->kl_unlock(knl->kl_lockarg);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when a knote is being detached.
|
||||
*/
|
||||
static void
|
||||
filt_sfsync_detach(struct knote *kn)
|
||||
{
|
||||
struct knlist *knl;
|
||||
struct sendfile_sync *sfs;
|
||||
int do_free = 0;
|
||||
|
||||
sfs = kn->kn_ptr.p_v;
|
||||
knl = &sfs->klist;
|
||||
|
||||
SFSYNC_DPRINTF("%s: kn=%p, sfs=%p\n", __func__, kn, sfs);
|
||||
|
||||
knl->kl_lock(knl->kl_lockarg);
|
||||
if (!knlist_empty(knl))
|
||||
knlist_remove(knl, kn, 1);
|
||||
|
||||
/*
|
||||
* If the list is empty _AND_ the refcount is 0
|
||||
* _AND_ we've finished the setup phase and now
|
||||
* we're in the running phase, we can free the
|
||||
* underlying sendfile_sync.
|
||||
*
|
||||
* But we shouldn't do it before finishing the
|
||||
* underlying divorce from the knote.
|
||||
*
|
||||
* So, we have the sfsync lock held; transition
|
||||
* it to "freeing", then unlock, then free
|
||||
* normally.
|
||||
*/
|
||||
if (knlist_empty(knl)) {
|
||||
if (sfs->state == SF_STATE_COMPLETED && sfs->count == 0) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p; completed, "
|
||||
"count==0, empty list: time to free!\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
sf_sync_set_state(sfs, SF_STATE_FREEING, 1);
|
||||
do_free = 1;
|
||||
}
|
||||
}
|
||||
knl->kl_unlock(knl->kl_lockarg);
|
||||
|
||||
/*
|
||||
* Only call free if we're the one who has transitioned things
|
||||
* to free. Otherwise we could race with another thread that
|
||||
* is currently tearing things down.
|
||||
*/
|
||||
if (do_free == 1) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p, %s:%d\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs,
|
||||
__FILE__,
|
||||
__LINE__);
|
||||
sf_sync_free(sfs);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
filt_sfsync(struct knote *kn, long hint)
|
||||
{
|
||||
struct sendfile_sync *sfs = (struct sendfile_sync *) kn->kn_ptr.p_v;
|
||||
int ret;
|
||||
|
||||
SFSYNC_DPRINTF("%s: kn=%p, sfs=%p\n", __func__, kn, sfs);
|
||||
|
||||
/*
|
||||
* XXX add a lock assertion here!
|
||||
*/
|
||||
ret = (sfs->count == 0 && sfs->state == SF_STATE_COMPLETED);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Detach mapped page and release resources back to the system.
|
||||
*/
|
||||
@ -1885,21 +2022,97 @@ sf_buf_mext(struct mbuf *mb, void *addr, void *args)
|
||||
sfs = addr;
|
||||
sf_sync_deref(sfs);
|
||||
}
|
||||
/*
|
||||
* sfs may be invalid at this point, don't use it!
|
||||
*/
|
||||
return (EXT_FREE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to remove a reference to a sf_sync object.
|
||||
*
|
||||
* This is generally done during the mbuf free path to signify
|
||||
* that one of the mbufs in the transaction has been completed.
|
||||
*
|
||||
* If we're doing SF_SYNC and the refcount is zero then we'll wake
|
||||
* up any waiters.
|
||||
*
|
||||
* IF we're doing SF_KQUEUE and the refcount is zero then we'll
|
||||
* fire off the knote.
|
||||
*/
|
||||
void
|
||||
sf_sync_deref(struct sendfile_sync *sfs)
|
||||
{
|
||||
int do_free = 0;
|
||||
|
||||
if (sfs == NULL)
|
||||
return;
|
||||
|
||||
mtx_lock(&sfs->mtx);
|
||||
KASSERT(sfs->count> 0, ("Sendfile sync botchup count == 0"));
|
||||
if (--sfs->count == 0)
|
||||
cv_signal(&sfs->cv);
|
||||
sfs->count --;
|
||||
|
||||
/*
|
||||
* Only fire off the wakeup / kqueue notification if
|
||||
* we are in the running state.
|
||||
*/
|
||||
if (sfs->count == 0 && sfs->state == SF_STATE_COMPLETED) {
|
||||
if (sfs->flags & SF_SYNC)
|
||||
cv_signal(&sfs->cv);
|
||||
|
||||
if (sfs->flags & SF_KQUEUE) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p: knote!\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
KNOTE_LOCKED(&sfs->klist, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're not waiting around for a sync,
|
||||
* check if the knote list is empty.
|
||||
* If it is, we transition to free.
|
||||
*
|
||||
* XXX I think it's about time I added some state
|
||||
* or flag that says whether we're supposed to be
|
||||
* waiting around until we've done a signal.
|
||||
*
|
||||
* XXX Ie, the reason that I don't free it here
|
||||
* is because the caller will free the last reference,
|
||||
* not us. That should be codified in some flag
|
||||
* that indicates "self-free" rather than checking
|
||||
* for SF_SYNC all the time.
|
||||
*/
|
||||
if ((sfs->flags & SF_SYNC) == 0 && knlist_empty(&sfs->klist)) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p; completed, "
|
||||
"count==0, empty list: time to free!\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
sf_sync_set_state(sfs, SF_STATE_FREEING, 1);
|
||||
do_free = 1;
|
||||
}
|
||||
|
||||
}
|
||||
mtx_unlock(&sfs->mtx);
|
||||
|
||||
/*
|
||||
* Attempt to do a free here.
|
||||
*
|
||||
* We do this outside of the lock because it may destroy the
|
||||
* lock in question as it frees things. We can optimise this
|
||||
* later.
|
||||
*
|
||||
* XXX yes, we should make it a requirement to hold the
|
||||
* lock across sf_sync_free().
|
||||
*/
|
||||
if (do_free == 1) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
sf_sync_free(sfs);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1917,6 +2130,10 @@ sf_sync_alloc(uint32_t flags)
|
||||
mtx_init(&sfs->mtx, "sendfile", NULL, MTX_DEF);
|
||||
cv_init(&sfs->cv, "sendfile");
|
||||
sfs->flags = flags;
|
||||
sfs->state = SF_STATE_SETUP;
|
||||
knlist_init_mtx(&sfs->klist, &sfs->mtx);
|
||||
|
||||
SFSYNC_DPRINTF("%s: sfs=%p, flags=0x%08x\n", __func__, sfs, sfs->flags);
|
||||
|
||||
return (sfs);
|
||||
}
|
||||
@ -1946,13 +2163,49 @@ sf_sync_syscall_wait(struct sendfile_sync *sfs)
|
||||
if (sfs == NULL)
|
||||
return;
|
||||
|
||||
mtx_lock(&sfs->mtx);
|
||||
KASSERT(mtx_owned(&sfs->mtx), ("%s: sfs=%p: not locked but should be!",
|
||||
__func__,
|
||||
sfs));
|
||||
|
||||
/*
|
||||
* If we're not requested to wait during the syscall,
|
||||
* don't bother waiting.
|
||||
*/
|
||||
if ((sfs->flags & SF_SYNC) == 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* This is a bit suboptimal and confusing, so bear with me.
|
||||
*
|
||||
* Ideally sf_sync_syscall_wait() will wait until
|
||||
* all pending mbuf transmit operations are done.
|
||||
* This means that when sendfile becomes async, it'll
|
||||
* run in the background and will transition from
|
||||
* RUNNING to COMPLETED when it's finished acquiring
|
||||
* new things to send. Then, when the mbufs finish
|
||||
* sending, COMPLETED + sfs->count == 0 is enough to
|
||||
* know that no further work is being done.
|
||||
*
|
||||
* So, we will sleep on both RUNNING and COMPLETED.
|
||||
* It's up to the (in progress) async sendfile loop
|
||||
* to transition the sf_sync from RUNNING to
|
||||
* COMPLETED so the wakeup above will actually
|
||||
* do the cv_signal() call.
|
||||
*/
|
||||
if (sfs->state != SF_STATE_COMPLETED && sfs->state != SF_STATE_RUNNING)
|
||||
goto out;
|
||||
|
||||
if (sfs->count != 0)
|
||||
cv_wait(&sfs->cv, &sfs->mtx);
|
||||
KASSERT(sfs->count == 0, ("sendfile sync still busy"));
|
||||
mtx_unlock(&sfs->mtx);
|
||||
|
||||
out:
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free an sf_sync if it's appropriate to.
|
||||
*/
|
||||
void
|
||||
sf_sync_free(struct sendfile_sync *sfs)
|
||||
{
|
||||
@ -1960,17 +2213,157 @@ sf_sync_free(struct sendfile_sync *sfs)
|
||||
if (sfs == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* XXX we should ensure that nothing else has this
|
||||
* locked before freeing.
|
||||
*/
|
||||
SFSYNC_DPRINTF("%s: (%lld) sfs=%p; called; state=%d, flags=0x%08x "
|
||||
"count=%d\n",
|
||||
__func__,
|
||||
(long long) curthread->td_tid,
|
||||
sfs,
|
||||
sfs->state,
|
||||
sfs->flags,
|
||||
sfs->count);
|
||||
|
||||
mtx_lock(&sfs->mtx);
|
||||
|
||||
/*
|
||||
* We keep the sf_sync around if the state is active,
|
||||
* we are doing kqueue notification and we have active
|
||||
* knotes.
|
||||
*
|
||||
* If the caller wants to free us right this second it
|
||||
* should transition this to the freeing state.
|
||||
*
|
||||
* So, complain loudly if they break this rule.
|
||||
*/
|
||||
if (sfs->state != SF_STATE_FREEING) {
|
||||
printf("%s: (%llu) sfs=%p; not freeing; let's wait!\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
mtx_unlock(&sfs->mtx);
|
||||
return;
|
||||
}
|
||||
|
||||
KASSERT(sfs->count == 0, ("sendfile sync still busy"));
|
||||
cv_destroy(&sfs->cv);
|
||||
/*
|
||||
* This doesn't call knlist_detach() on each knote; it just frees
|
||||
* the entire list.
|
||||
*/
|
||||
knlist_delete(&sfs->klist, curthread, 1);
|
||||
mtx_destroy(&sfs->mtx);
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p; freeing\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
uma_zfree(zone_sfsync, sfs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a sf_sync to post a kqueue notification when things are complete.
|
||||
*/
|
||||
int
|
||||
sf_sync_kqueue_setup(struct sendfile_sync *sfs, struct sf_hdtr_kq *sfkq)
|
||||
{
|
||||
struct kevent kev;
|
||||
int error;
|
||||
|
||||
sfs->flags |= SF_KQUEUE;
|
||||
|
||||
/* Check the flags are valid */
|
||||
if ((sfkq->kq_flags & ~(EV_CLEAR | EV_DISPATCH | EV_ONESHOT)) != 0)
|
||||
return (EINVAL);
|
||||
|
||||
SFSYNC_DPRINTF("%s: sfs=%p: kqfd=%d, flags=0x%08x, ident=%p, udata=%p\n",
|
||||
__func__,
|
||||
sfs,
|
||||
sfkq->kq_fd,
|
||||
sfkq->kq_flags,
|
||||
(void *) sfkq->kq_ident,
|
||||
(void *) sfkq->kq_udata);
|
||||
|
||||
/* Setup and register a knote on the given kqfd. */
|
||||
kev.ident = (uintptr_t) sfkq->kq_ident;
|
||||
kev.filter = EVFILT_SENDFILE;
|
||||
kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1 | sfkq->kq_flags;
|
||||
kev.data = (intptr_t) sfs;
|
||||
kev.udata = sfkq->kq_udata;
|
||||
|
||||
error = kqfd_register(sfkq->kq_fd, &kev, curthread, 1);
|
||||
if (error != 0) {
|
||||
SFSYNC_DPRINTF("%s: returned %d\n", __func__, error);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
sf_sync_set_state(struct sendfile_sync *sfs, sendfile_sync_state_t state,
|
||||
int islocked)
|
||||
{
|
||||
sendfile_sync_state_t old_state;
|
||||
|
||||
if (! islocked)
|
||||
mtx_lock(&sfs->mtx);
|
||||
|
||||
/*
|
||||
* Update our current state.
|
||||
*/
|
||||
old_state = sfs->state;
|
||||
sfs->state = state;
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p; going from %d to %d\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs,
|
||||
old_state,
|
||||
state);
|
||||
|
||||
/*
|
||||
* If we're transitioning from RUNNING to COMPLETED and the count is
|
||||
* zero, then post the knote. The caller may have completed the
|
||||
* send before we updated the state to COMPLETED and we need to make
|
||||
* sure this is communicated.
|
||||
*/
|
||||
if (old_state == SF_STATE_RUNNING
|
||||
&& state == SF_STATE_COMPLETED
|
||||
&& sfs->count == 0
|
||||
&& sfs->flags & SF_KQUEUE) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p: triggering knote!\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
KNOTE_LOCKED(&sfs->klist, 1);
|
||||
}
|
||||
|
||||
if (! islocked)
|
||||
mtx_unlock(&sfs->mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the retval/errno for the given transaction.
|
||||
*
|
||||
* This will eventually/ideally be used when the KNOTE is fired off
|
||||
* to signify the completion of this transaction.
|
||||
*
|
||||
* The sfsync lock should be held before entering this function.
|
||||
*/
|
||||
void
|
||||
sf_sync_set_retval(struct sendfile_sync *sfs, off_t retval, int xerrno)
|
||||
{
|
||||
|
||||
KASSERT(mtx_owned(&sfs->mtx), ("%s: sfs=%p: not locked but should be!",
|
||||
__func__,
|
||||
sfs));
|
||||
|
||||
SFSYNC_DPRINTF("%s: (%llu) sfs=%p: errno=%d, retval=%jd\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs,
|
||||
xerrno,
|
||||
(intmax_t) retval);
|
||||
|
||||
sfs->retval = retval;
|
||||
sfs->xerrno = xerrno;
|
||||
}
|
||||
|
||||
/*
|
||||
* sendfile(2)
|
||||
*
|
||||
@ -1992,15 +2385,21 @@ sys_sendfile(struct thread *td, struct sendfile_args *uap)
|
||||
int
|
||||
_do_sendfile(struct thread *td, int src_fd, int sock_fd, int flags,
|
||||
int compat, off_t offset, size_t nbytes, off_t *sbytes,
|
||||
struct uio *hdr_uio, struct uio *trl_uio)
|
||||
struct uio *hdr_uio,
|
||||
struct uio *trl_uio, struct sf_hdtr_kq *hdtr_kq)
|
||||
{
|
||||
cap_rights_t rights;
|
||||
struct sendfile_sync *sfs = NULL;
|
||||
struct file *fp;
|
||||
int error;
|
||||
int do_kqueue = 0;
|
||||
int do_free = 0;
|
||||
|
||||
AUDIT_ARG_FD(src_fd);
|
||||
|
||||
if (hdtr_kq != NULL)
|
||||
do_kqueue = 1;
|
||||
|
||||
/*
|
||||
* sendfile(2) can start at any offset within a file so we require
|
||||
* CAP_READ+CAP_SEEK = CAP_PREAD.
|
||||
@ -2010,21 +2409,122 @@ _do_sendfile(struct thread *td, int src_fd, int sock_fd, int flags,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* IF SF_KQUEUE is set but we haven't copied in anything for
|
||||
* kqueue data, error out.
|
||||
*/
|
||||
if (flags & SF_KQUEUE && do_kqueue == 0) {
|
||||
SFSYNC_DPRINTF("%s: SF_KQUEUE but no KQUEUE data!\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we need to wait for completion, initialise the sfsync
|
||||
* state here.
|
||||
*/
|
||||
if (flags & SF_SYNC)
|
||||
sfs = sf_sync_alloc(flags & SF_SYNC);
|
||||
if (flags & (SF_SYNC | SF_KQUEUE))
|
||||
sfs = sf_sync_alloc(flags & (SF_SYNC | SF_KQUEUE));
|
||||
|
||||
if (flags & SF_KQUEUE) {
|
||||
error = sf_sync_kqueue_setup(sfs, hdtr_kq);
|
||||
if (error) {
|
||||
SFSYNC_DPRINTF("%s: (%llu) error; sfs=%p\n",
|
||||
__func__,
|
||||
(unsigned long long) curthread->td_tid,
|
||||
sfs);
|
||||
sf_sync_set_state(sfs, SF_STATE_FREEING, 0);
|
||||
sf_sync_free(sfs);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the sendfile call.
|
||||
*
|
||||
* If this fails, it'll free the mbuf chain which will free up the
|
||||
* sendfile_sync references.
|
||||
*/
|
||||
error = fo_sendfile(fp, sock_fd, hdr_uio, trl_uio, offset,
|
||||
nbytes, sbytes, flags, compat ? SFK_COMPAT : 0, sfs, td);
|
||||
|
||||
/*
|
||||
* If appropriate, do the wait and free here.
|
||||
* If the sendfile call succeeded, transition the sf_sync state
|
||||
* to RUNNING, then COMPLETED.
|
||||
*
|
||||
* If the sendfile call failed, then the sendfile call may have
|
||||
* actually sent some data first - so we check to see whether
|
||||
* any data was sent. If some data was queued (ie, count > 0)
|
||||
* then we can't call free; we have to wait until the partial
|
||||
* transaction completes before we continue along.
|
||||
*
|
||||
* This has the side effect of firing off the knote
|
||||
* if the refcount has hit zero by the time we get here.
|
||||
*/
|
||||
if (sfs != NULL) {
|
||||
mtx_lock(&sfs->mtx);
|
||||
if (error == 0 || sfs->count > 0) {
|
||||
/*
|
||||
* When it's time to do async sendfile, the transition
|
||||
* to RUNNING signifies that we're actually actively
|
||||
* adding and completing mbufs. When the last disk
|
||||
* buffer is read (ie, when we're not doing any
|
||||
* further read IO and all subsequent stuff is mbuf
|
||||
* transmissions) we'll transition to COMPLETED
|
||||
* and when the final mbuf is freed, the completion
|
||||
* will be signaled.
|
||||
*/
|
||||
sf_sync_set_state(sfs, SF_STATE_RUNNING, 1);
|
||||
|
||||
/*
|
||||
* Set the retval before we signal completed.
|
||||
* If we do it the other way around then transitioning to
|
||||
* COMPLETED may post the knote before you set the return
|
||||
* status!
|
||||
*
|
||||
* XXX for now, errno is always 0, as we don't post
|
||||
* knotes if sendfile failed. Maybe that'll change later.
|
||||
*/
|
||||
sf_sync_set_retval(sfs, *sbytes, error);
|
||||
|
||||
/*
|
||||
* And now transition to completed, which will kick off
|
||||
* the knote if required.
|
||||
*/
|
||||
sf_sync_set_state(sfs, SF_STATE_COMPLETED, 1);
|
||||
} else {
|
||||
/*
|
||||
* Error isn't zero, sfs_count is zero, so we
|
||||
* won't have some other thing to wake things up.
|
||||
* Thus free.
|
||||
*/
|
||||
sf_sync_set_state(sfs, SF_STATE_FREEING, 1);
|
||||
do_free = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next - wait if appropriate.
|
||||
*/
|
||||
sf_sync_syscall_wait(sfs);
|
||||
|
||||
/*
|
||||
* If we're not doing kqueue notifications, we can
|
||||
* transition this immediately to the freeing state.
|
||||
*/
|
||||
if ((sfs->flags & SF_KQUEUE) == 0) {
|
||||
sf_sync_set_state(sfs, SF_STATE_FREEING, 1);
|
||||
do_free = 1;
|
||||
}
|
||||
|
||||
mtx_unlock(&sfs->mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* If do_free is set, free here.
|
||||
*
|
||||
* If we're doing no-kqueue notification and it's just sleep notification,
|
||||
* we also do free; it's the only chance we have.
|
||||
*/
|
||||
if (sfs != NULL && do_free == 1) {
|
||||
sf_sync_free(sfs);
|
||||
}
|
||||
|
||||
@ -2036,16 +2536,20 @@ _do_sendfile(struct thread *td, int src_fd, int sock_fd, int flags,
|
||||
fdrop(fp, td);
|
||||
|
||||
out:
|
||||
/* Return error */
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
|
||||
{
|
||||
struct sf_hdtr hdtr;
|
||||
struct sf_hdtr_kq hdtr_kq;
|
||||
struct uio *hdr_uio, *trl_uio;
|
||||
int error;
|
||||
off_t sbytes;
|
||||
int do_kqueue = 0;
|
||||
|
||||
/*
|
||||
* File offset must be positive. If it goes beyond EOF
|
||||
@ -2070,10 +2574,25 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
|
||||
if (error != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If SF_KQUEUE is set, then we need to also copy in
|
||||
* the kqueue data after the normal hdtr set and set
|
||||
* do_kqueue=1.
|
||||
*/
|
||||
if (uap->flags & SF_KQUEUE) {
|
||||
error = copyin(((char *) uap->hdtr) + sizeof(hdtr),
|
||||
&hdtr_kq,
|
||||
sizeof(hdtr_kq));
|
||||
if (error != 0)
|
||||
goto out;
|
||||
do_kqueue = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call sendfile */
|
||||
error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat,
|
||||
uap->offset, uap->nbytes, &sbytes, hdr_uio, trl_uio);
|
||||
uap->offset, uap->nbytes, &sbytes, hdr_uio, trl_uio, &hdtr_kq);
|
||||
|
||||
if (uap->sbytes != NULL) {
|
||||
copyout(&sbytes, uap->sbytes, sizeof(off_t));
|
||||
|
@ -149,6 +149,8 @@ static int adm5120_uart_bus_probe(struct uart_softc *);
|
||||
static int adm5120_uart_bus_receive(struct uart_softc *);
|
||||
static int adm5120_uart_bus_setsig(struct uart_softc *, int);
|
||||
static int adm5120_uart_bus_transmit(struct uart_softc *);
|
||||
static void adm5120_uart_bus_grab(struct uart_softc *);
|
||||
static void adm5120_uart_bus_ungrab(struct uart_softc *);
|
||||
|
||||
static kobj_method_t adm5120_uart_methods[] = {
|
||||
KOBJMETHOD(uart_attach, adm5120_uart_bus_attach),
|
||||
@ -162,6 +164,8 @@ static kobj_method_t adm5120_uart_methods[] = {
|
||||
KOBJMETHOD(uart_receive, adm5120_uart_bus_receive),
|
||||
KOBJMETHOD(uart_setsig, adm5120_uart_bus_setsig),
|
||||
KOBJMETHOD(uart_transmit, adm5120_uart_bus_transmit),
|
||||
KOBJMETHOD(uart_grab, adm5120_uart_bus_grab),
|
||||
KOBJMETHOD(uart_ungrab, adm5120_uart_bus_ungrab),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -450,3 +454,26 @@ adm5120_uart_bus_transmit(struct uart_softc *sc)
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
adm5120_uart_bus_grab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
/* Enable interrupts - no RX_INT or RX_TIMEOUT */
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(&sc->sc_bas, UART_CR_REG,
|
||||
UART_CR_PORT_EN | UART_CR_MODEM_STATUS_INT_EN);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
||||
static void
|
||||
adm5120_uart_bus_ungrab(struct uart_softc *sc)
|
||||
{
|
||||
|
||||
/* Enable interrupts */
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
uart_setreg(&sc->sc_bas, UART_CR_REG,
|
||||
UART_CR_PORT_EN|UART_CR_RX_INT_EN|UART_CR_RX_TIMEOUT_INT_EN|
|
||||
UART_CR_MODEM_STATUS_INT_EN);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user