MFH@260917.

This commit is contained in:
Kai Wang 2014-01-20 19:38:44 +00:00
commit 945a2095f6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/elftoolchain/; revision=260920
152 changed files with 3814 additions and 1742 deletions

View File

@ -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,

View File

@ -3012,6 +3012,7 @@ zdb_read_block(char *thing, spa_t *spa)
free(dup);
return;
}
i += p - &flagstr[i + 1]; /* skip over the number */
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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))

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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/

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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"

View 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
}

View File

@ -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}

View File

@ -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

View 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 .

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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

View File

@ -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
View 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
View 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
View 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 */

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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));
}
/*

View File

@ -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);

View File

@ -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)

View File

@ -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();
}
/*

View File

@ -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));

View File

@ -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

View File

@ -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" \

View File

@ -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); \

View File

@ -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;

View File

@ -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:

View File

@ -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},

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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
View 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 */

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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:

View File

@ -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);

View File

@ -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);
}

View 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);
}

View File

@ -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);

View File

@ -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));

View File

@ -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
View 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

View File

@ -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!

View File

@ -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);

View File

@ -294,6 +294,7 @@ static struct {
{ &fs_filtops }, /* EVFILT_FS */
{ &null_filtops }, /* EVFILT_LIO */
{ &user_filtops }, /* EVFILT_USER */
{ &null_filtops }, /* EVFILT_SENDFILE */
};
/*

View File

@ -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

View File

@ -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));
}
/*

View File

@ -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))

View File

@ -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;

View File

@ -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));

View File

@ -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