MFC @r257107.

This commit is contained in:
ray 2013-10-25 08:41:36 +00:00
commit f690470e36
122 changed files with 3665 additions and 1521 deletions

View File

@ -58,6 +58,7 @@
# use that new version. And the new (dynamically-linked) /bin/sh
# will expect to find appropriate libraries in /lib and /libexec.
#
SRCDIR?= ${.CURDIR}
.if defined(SUBDIR_OVERRIDE)
SUBDIR= ${SUBDIR_OVERRIDE}
.else
@ -84,6 +85,9 @@ SUBDIR+=secure
SUBDIR+=share
.endif
SUBDIR+=sys usr.bin usr.sbin
.if ${MK_TESTS} != "no"
SUBDIR+= tests
.endif
.if ${MK_OFED} != "no"
SUBDIR+=contrib/ofed
.endif
@ -128,10 +132,10 @@ OSRELDATE= 0
.endif
.if !defined(VERSION)
REVISION!= make -C ${.CURDIR}/release -V REVISION
BRANCH!= make -C ${.CURDIR}/release -V BRANCH
REVISION!= make -C ${SRCDIR}/release -V REVISION
BRANCH!= make -C ${SRCDIR}/release -V BRANCH
SRCRELDATE!= awk '/^\#define[[:space:]]*__FreeBSD_version/ { print $$3 }' \
${.CURDIR}/sys/sys/param.h
${SRCDIR}/sys/sys/param.h
VERSION= FreeBSD ${REVISION}-${BRANCH} ${TARGET_ARCH} ${SRCRELDATE}
.endif
@ -488,6 +492,10 @@ _worldtmp:
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.debug.dist \
-p ${WORLDTMP}/usr/lib >/dev/null
.endif
.if ${MK_TESTS} != "no"
mtree -deU -f ${.CURDIR}/etc/mtree/BSD.tests.dist \
-p ${WORLDTMP}${TESTSBASE} >/dev/null
.endif
.for _mtree in ${LOCAL_MTREE}
mtree -deU -f ${.CURDIR}/${_mtree} -p ${WORLDTMP} > /dev/null
.endfor

View File

@ -38,6 +38,8 @@
# xargs -n1 | sort | uniq -d;
# done
# 20131023: remove never used iscsi directory
OLD_DIRS+=usr/share/examples/iscsi
# 20131014: libbsdyml becomes private
OLD_FILES+=usr/lib/libbsdyml.a
OLD_FILES+=usr/lib/libbsdyml.so
@ -2491,6 +2493,7 @@ OLD_FILES+=usr/sbin/zfs
OLD_FILES+=usr/sbin/zpool
# 20070423: rc.bluetooth (examples) removed
OLD_FILES+=usr/share/examples/netgraph/bluetooth/rc.bluetooth
OLD_DIRS+=usr/share/examples/netgraph/bluetooth
# 20070421: worm.4 removed
OLD_FILES+=usr/share/man/man4/worm.4.gz
# 20070417: trunk(4) renamed to lagg(4)

View File

@ -25,10 +25,11 @@
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
.\" Copyright (c) 2013 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2013, Joyent, Inc. All rights reserved.
.\" Copyright (c) 2013, Steven Hartland <smh@FreeBSD.org>
.\"
.\" $FreeBSD$
.\"
.Dd September 20, 2013
.Dd October 23, 2013
.Dt ZFS 8
.Os
.Sh NAME
@ -61,7 +62,7 @@
.Op , Ns ...
.Sm on
.Nm
.Cm snapshot
.Cm snapshot Ns | Ns Cm snap
.Op Fl r
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Ar filesystem@snapname Ns | Ns Ar volume@snapname
@ -157,7 +158,7 @@
.Op Fl o Ar property Ns Oo , Ns Ar property Oc Ns ...
.Fl a | Ar filesystem
.Nm
.Cm unmount
.Cm unmount Ns | Ns Cm umount
.Op Fl f
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
.Nm
@ -172,11 +173,11 @@
.Op Fl i Ar snapshot | Fl I Ar snapshot
.Ar snapshot
.Nm
.Cm receive
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
.Cm receive
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl d | e
.Ar filesystem
@ -1653,7 +1654,7 @@ options, as they can destroy large portions of a pool and cause unexpected
behavior for mounted file systems in use.
.It Xo
.Nm
.Cm snapshot
.Cm snapshot Ns | Ns Cm snap
.Op Fl r
.Oo Fl o Ar property Ns = Ns Ar value Oc Ns ...
.Ar filesystem@snapname Ns | Ns volume@snapname
@ -1865,7 +1866,7 @@ syntax.
A comma-separated list of types to display, where
.Ar type
is one of
.Sy filesystem , snapshot , volume , No or Sy all .
.Sy filesystem , snapshot , snap, volume , No or Sy all .
For example, specifying
.Fl t Cm snapshot
displays only snapshots.
@ -2194,7 +2195,7 @@ Mount the specified filesystem.
.El
.It Xo
.Nm
.Cm unmount
.Cm unmount Ns | Ns Cm umount
.Op Fl f
.Fl a | Ar filesystem Ns | Ns Ar mountpoint
.Xc
@ -2377,13 +2378,13 @@ on future versions of
.Tn ZFS .
.It Xo
.Nm
.Cm receive
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Xc
.It Xo
.Nm
.Cm receive
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl d | e
.Ar filesystem

View File

@ -259,9 +259,9 @@ get_usage(zfs_help_t idx)
case HELP_PROMOTE:
return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE:
return (gettext("\treceive [-vnFu] <filesystem|volume|"
return (gettext("\treceive|recv [-vnFu] <filesystem|volume|"
"snapshot>\n"
"\treceive [-vnFu] [-d | -e] <filesystem>\n"));
"\treceive|recv [-vnFu] [-d | -e] <filesystem>\n"));
case HELP_RENAME:
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
"<filesystem|volume|snapshot>\n"
@ -280,10 +280,10 @@ get_usage(zfs_help_t idx)
case HELP_SHARE:
return (gettext("\tshare <-a | filesystem>\n"));
case HELP_SNAPSHOT:
return (gettext("\tsnapshot [-r] [-o property=value] ... "
return (gettext("\tsnapshot|snap [-r] [-o property=value] ... "
"<filesystem@snapname|volume@snapname> ...\n"));
case HELP_UNMOUNT:
return (gettext("\tunmount [-f] "
return (gettext("\tunmount|umount [-f] "
"<-a | filesystem|mountpoint>\n"));
case HELP_UNSHARE:
return (gettext("\tunshare "
@ -3027,7 +3027,7 @@ zfs_do_list(int argc, char **argv)
flags &= ~ZFS_ITER_PROP_LISTSNAPS;
while (*optarg != '\0') {
static char *type_subopts[] = { "filesystem",
"volume", "snapshot", "all", NULL };
"volume", "snapshot", "snap", "all", NULL };
switch (getsubopt(&optarg, type_subopts,
&value)) {
@ -3038,9 +3038,10 @@ zfs_do_list(int argc, char **argv)
types |= ZFS_TYPE_VOLUME;
break;
case 2:
case 3:
types |= ZFS_TYPE_SNAPSHOT;
break;
case 3:
case 4:
types = ZFS_TYPE_DATASET;
break;
@ -6725,6 +6726,12 @@ main(int argc, char **argv)
if (strcmp(cmdname, "recv") == 0)
cmdname = "receive";
/*
* The 'snap' command is an alias for 'snapshot'
*/
if (strcmp(cmdname, "snap") == 0)
cmdname = "snapshot";
/*
* Special case '-?'
*/

View File

@ -36,7 +36,10 @@
/* ============================== Portability ============================== */
/* Assume ISO C++ 'for' scoping rule. */
#define for if (0) ; else for
/* This code is used to work around scoping issues with visual studio 6 from
* 1998. Comment it out here to queisce numerous -Wdangling-else warnings
* from clang.
#define for if (0) ; else for */
/* Dynamically allocated array with dynamic extent:

View File

@ -139,6 +139,9 @@ BIN1+= regdomain.xml
BIN2= netstart pccard_ether rc.suspend rc.resume
MTREE= BSD.include.dist BSD.root.dist BSD.usr.dist BSD.var.dist
.if ${MK_TESTS} != "no"
MTREE+= BSD.tests.dist
.endif
.if ${MK_SENDMAIL} != "no"
MTREE+= BSD.sendmail.dist
.endif
@ -314,6 +317,9 @@ MTREES+= mtree/BSD.debug.dist /usr/lib
.if ${MK_GROFF} != "no"
MTREES+= mtree/BSD.groff.dist /usr
.endif
.if ${MK_TESTS} != "no"
MTREES+= mtree/BSD.tests.dist ${TESTSBASE}
.endif
.if ${MK_SENDMAIL} != "no"
MTREES+= mtree/BSD.sendmail.dist /
.endif

12
etc/mtree/BSD.tests.dist Normal file
View File

@ -0,0 +1,12 @@
# $FreeBSD$
#
# Please see the file src/etc/mtree/README before making changes to this file.
#
/set type=dir uname=root gname=wheel mode=0755
.
lib
libcrypt
..
..
..

View File

@ -325,8 +325,6 @@
..
ipfw
..
iscsi
..
jails
..
kld
@ -360,8 +358,6 @@
mdoc
..
netgraph
bluetooth
..
..
pc-sysinstall
..

View File

@ -37,4 +37,9 @@ WARNS?= 2
PRECIOUSLIB=
.if ${MK_TESTS} != "no"
SUBDIR+= tests
.endif
.include <bsd.lib.mk>
.include <bsd.subdir.mk>

View File

@ -2,6 +2,8 @@
# exercise libcrypt
TESTSDIR= ${TESTSBASE}/lib/libcrypt
ATF_TESTS_C= crypt_tests
CFLAGS+= -I${.CURDIR:H}

View File

@ -65,7 +65,7 @@ eascan(struct inodesc *idesc, struct ufs2_dinode *dp)
char dbuf[DIRBLKSIZ];
printf("Inode %ju extsize %ju\n",
(intmax_t)idesc->id_number, (intmax_t)dp->di_extsize);
(intmax_t)idesc->id_number, (uintmax_t)dp->di_extsize);
if (dp->di_extsize == 0)
return 0;
if (dp->di_extsize <= sblock.fs_fsize)

View File

@ -364,7 +364,11 @@ gpart_autofill_resize(struct gctl_req *req)
}
offset = (pp->lg_stripeoffset / pp->lg_sectorsize) % alignment;
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
s = find_geomcfg(gp, "last");
if (s == NULL)
errx(EXIT_FAILURE, "Final block not found for geom %s",
gp->lg_name);
last = (off_t)strtoimax(s, NULL, 0);
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
s = find_provcfg(pp, "index");
if (s == NULL)
@ -502,8 +506,16 @@ gpart_autofill(struct gctl_req *req)
if (size > alignment)
size = ALIGNDOWN(size, alignment);
first = (off_t)strtoimax(find_geomcfg(gp, "first"), NULL, 0);
last = (off_t)strtoimax(find_geomcfg(gp, "last"), NULL, 0);
s = find_geomcfg(gp, "first");
if (s == NULL)
errx(EXIT_FAILURE, "Starting block not found for geom %s",
gp->lg_name);
first = (off_t)strtoimax(s, NULL, 0);
s = find_geomcfg(gp, "last");
if (s == NULL)
errx(EXIT_FAILURE, "Final block not found for geom %s",
gp->lg_name);
last = (off_t)strtoimax(s, NULL, 0);
grade = ~0ULL;
a_first = ALIGNUP(first + offset, alignment);
last = ALIGNDOWN(last + offset, alignment);
@ -587,12 +599,22 @@ gpart_show_geom(struct ggeom *gp, const char *element, int show_providers)
int idx, wblocks, wname, wmax;
scheme = find_geomcfg(gp, "scheme");
if (scheme == NULL)
errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name);
s = find_geomcfg(gp, "first");
if (s == NULL)
errx(EXIT_FAILURE, "Starting block not found for geom %s",
gp->lg_name);
first = (off_t)strtoimax(s, NULL, 0);
s = find_geomcfg(gp, "last");
if (s == NULL)
errx(EXIT_FAILURE, "Final block not found for geom %s",
gp->lg_name);
last = (off_t)strtoimax(s, NULL, 0);
wblocks = strlen(s);
s = find_geomcfg(gp, "state");
if (s == NULL)
errx(EXIT_FAILURE, "State not found for geom %s", gp->lg_name);
if (s != NULL && *s != 'C')
s = NULL;
wmax = strlen(gp->lg_name);
@ -748,6 +770,8 @@ gpart_backup(struct gctl_req *req, unsigned int fl __unused)
abort();
pp = LIST_FIRST(&gp->lg_consumer)->lg_provider;
s = find_geomcfg(gp, "last");
if (s == NULL)
abort();
wblocks = strlen(s);
wtype = 0;
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
@ -757,6 +781,8 @@ gpart_backup(struct gctl_req *req, unsigned int fl __unused)
wtype = i;
}
s = find_geomcfg(gp, "entries");
if (s == NULL)
abort();
windex = strlen(s);
printf("%s %s\n", scheme, s);
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
@ -1177,6 +1203,8 @@ gpart_bootcode(struct gctl_req *req, unsigned int fl)
if (gp == NULL)
errx(EXIT_FAILURE, "No such geom: %s.", s);
s = find_geomcfg(gp, "scheme");
if (s == NULL)
errx(EXIT_FAILURE, "Scheme not found for geom %s", gp->lg_name);
vtoc8 = 0;
if (strcmp(s, "VTOC8") == 0)
vtoc8 = 1;

View File

@ -765,7 +765,7 @@ dbg_dump_ufs2_ino(struct fs *sb, const char *comment, struct ufs2_dinode *ino)
fprintf(dbg_log, "gen int32_t 0x%08x\n", ino->di_gen);
fprintf(dbg_log, "kernflags u_int32_t 0x%08x\n", ino->di_kernflags);
fprintf(dbg_log, "flags u_int32_t 0x%08x\n", ino->di_flags);
fprintf(dbg_log, "extsize int32_t 0x%08x\n", ino->di_extsize);
fprintf(dbg_log, "extsize u_int32_t 0x%08x\n", ino->di_extsize);
/* XXX: What do we do with di_extb[NXADDR]? */

View File

@ -481,12 +481,18 @@ md_list(const char *units, int opt, const char *fflag)
printf("\n");
/* XXX: Check if it's enough to clean everything. */
geom_stats_snapshot_free(sq);
if (((opt & OPT_UNIT) && (fflag == NULL) && ufound) ||
((opt & OPT_UNIT) == 0 && (fflag != NULL) && ffound) ||
((opt & OPT_UNIT) && (fflag != NULL) && ufound && ffound))
return (0);
else
return (-1);
if (opt & OPT_UNIT) {
if (((fflag == NULL) && ufound) ||
((fflag == NULL) && (units != NULL) && ufound) ||
((fflag != NULL) && ffound) ||
((fflag != NULL) && (units != NULL) && ufound && ffound))
return (0);
} else if (opt & OPT_LIST) {
if ((fflag == NULL) ||
((fflag != NULL) && ffound))
return (0);
}
return (-1);
}
/*

View File

@ -1,7 +1,7 @@
.\" DO NOT EDIT-- this file is automatically generated.
.\" from FreeBSD: head/tools/build/options/makeman 255964 2013-10-01 07:22:04Z des
.\" $FreeBSD$
.Dd October 6, 2013
.Dd October 24, 2013
.Dt SRC.CONF 5
.Os
.Sh NAME
@ -208,10 +208,6 @@ When set, it also enforces the following options:
.Va WITHOUT_CLANG_EXTRAS
.It
.Va WITHOUT_CLANG_FULL
.It
.Va WITHOUT_CLANG_IS_CC
.It
.Va WITHOUT_LLDB
.El
.It Va WITH_CLANG
.\" from FreeBSD: head/tools/build/options/WITH_CLANG 221730 2011-05-10 11:14:40Z ru
@ -323,11 +319,7 @@ When set, it also enforces the following options:
.It
.Va WITHOUT_CLANG_FULL
.It
.Va WITHOUT_CLANG_IS_CC
.It
.Va WITHOUT_GROFF
.It
.Va WITHOUT_LLDB
.El
.It Va WITH_DEBUG_FILES
.\" from FreeBSD: head/tools/build/options/WITH_DEBUG_FILES 251512 2013-06-07 21:40:02Z emaste
@ -910,7 +902,7 @@ This includes
.Xr rsh 1 ,
etc.
.It Va WITHOUT_RCS
.\" from FreeBSD: head/tools/build/options/WITHOUT_RCS 156932 2006-03-21 07:50:50Z ru
.\" from FreeBSD: head/tools/build/options/WITHOUT_RCS 256198 2013-10-09 17:07:20Z gjb
Set to not build
.Xr rcs 1
and related utilities.
@ -1030,13 +1022,9 @@ When set, it also enforces the following options:
.It
.Va WITHOUT_CLANG_FULL
.It
.Va WITHOUT_CLANG_IS_CC
.It
.Va WITHOUT_GCC
.It
.Va WITHOUT_GDB
.It
.Va WITHOUT_LLDB
.El
.It Va WITHOUT_UNBOUND
.\" from FreeBSD: head/tools/build/options/WITHOUT_UNBOUND 255597 2013-09-15 14:51:23Z des

View File

@ -29,6 +29,10 @@ MAN= adding_user.7 \
sticky.7 \
tuning.7
.if ${MK_TESTS} != "no"
MAN+= tests.7
.endif
MLINKS= intro.7 miscellaneous.7
MLINKS+= security.7 securelevel.7
MLINKS+= c99.7 c.7

View File

@ -32,7 +32,7 @@
.\" @(#)hier.7 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
.Dd January 21, 2010
.Dd October 19, 2013
.Dt HIER 7
.Os
.Sh NAME
@ -692,6 +692,12 @@ source code for files in
source code for files in
.Pa /usr/sbin
.El
.Pp
.It Pa tests/
The
.Fx
test suite.
See tests(7) for more details.
.El
.It Pa /var/
multi-purpose log, temporary, transient, and spool files

199
share/man/man7/tests.7 Normal file
View File

@ -0,0 +1,199 @@
.\" $FreeBSD$
.\" $NetBSD: tests.kyua.7,v 1.2 2013/07/20 21:39:59 wiz Exp $
.\"
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
.\" 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 NETBSD FOUNDATION, INC. AND
.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
.\" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd October 19, 2013
.Dt TESTS 7
.Os
.Sh NAME
.Nm tests
.Nd introduction to the FreeBSD test suite
.Sh DESCRIPTION
The
.Fx
test suite provides a collection of automated tests for two major purposes.
On the one hand, the test suite aids
.Em developers
in catching bugs and regressions in the code when they performing modifications
to the source tree.
On the other hand, the test suite allows
.Em end users
(and, in particular, system administrators) to verify that fresh installations
of the
.Fx
operating system behave correctly in their hardware platform and also to ensure
that the system does not suffer from regressions during regular system
operation and maintenance.
.Pp
The
.Fx
test suite is installed under the
.Pa /usr/tests
hierarchy.
.Pp
This manual page describes how to execute the test suite and how to configure
some of its optional features.
.Ss When to run the tests?
Before diving into the details of how to run the test suite, here are some
scenarios in which you should be running them:
.Bl -bullet -offset indent
.It
After a fresh installation of
.Fx
to ensure that the system works correctly on your hardware platform.
.It
After an upgrade of
.Fx
to a different version to ensure that the new code works well on your
hardware platform and that the upgrade did not introduce regressions in your
configuration.
.It
After performing changes to the source tree to catch any bugs and/or regressions
introduced by the modifications.
.It
Periodically, maybe from a
.Xr cron 8
job, to ensure that any changes to the system (such as the installation of
third-party packages or manual modifications to configuration files) do not
introduce unexpected failures.
.El
.Ss Running the tests
First of all, you will need to install the
.Sq ports/devel/kyua
package.
.Pp
Use the following command to run the whole test suite:
.Bd -literal -offset indent
$ kyua test -k /usr/tests/Kyuafile
.Ed
.Pp
The above will go through all test programs in
.Pa /usr/tests
recursively, execute them, store their results and debugging data in Kyua
database (by default in
.Pa ~/.kyua/store.db ) ,
and print a summary of the results.
This summary includes a brief count of all total tests run and how many of
them failed.
.Pp
It is possible to restrict which tests to run by providing their names in
the command line.
For example, this would execute the tests for the
.Xr cp 1
and
.Xr cut 1
utilities:
.Bd -literal -offset indent
$ kyua test -k /usr/tests/Kyuafile bin/cp usr.bin/cut
.Ed
.Ss Obtaining reports of the tests execution
Additional information of the results of the execution can be later extracted
from the database by using the various reporting commands of Kyua.
For example, the following would extract a plain-text report of the executed
tests and show which ones failed:
.Bd -literal -offset indent
$ kyua report
.Ed
.Pp
This other example would generate an HTML report ready to be published on a
web server:
.Bd -literal -offset indent
$ kyua report-html --output ~/public_html/tests
.Ed
.Pp
For further details on the command-line interface of Kyua, please refer
to its manual page
.Xr kyua 1 .
.\".Ss Configuring the tests
.\"Some test cases in the
.\".Fx
.\"test suite require the administrator to manually set up some configuration
.\"properties before they can run.
.\"Unless these properties are defined, the tests that require them will be marked
.\"as skipped and thus they will not be really executed.
.\".Pp
.\"Test suites are configured by defining the values to their configuration
.\"variables in
.\".Pa /usr/local/etc/kyua/kyua.conf .
.\"The format of this file is detailed in
.\".Xr kyua.conf 5 .
.\".Pp
.\"The following configuration variables are available in the
.\".Fx
.\"test suite:
.\".Bl -tag
.\".It NONE REGISTERED YET
.\"TBD.
.Ss What to do if something fails?
If there is
.Em any failure
during the execution of the test suite, please considering reporting it to the
.Fx
developers so that the failure can be analyzed and fixed.
To do so, either send a message to the appropriate mailing list or file a
problem report.
For more details please refer to:
.Bl -bullet -offset indent -compact
.It
.Lk http://lists.freebsd.org/ "FreeBSD Mailing Lists"
.It
.Lk http://www.freebsd.org/send-pr.html "Submit a FreeBSD Problem Report"
.El
.Sh FILES
.Bl -tag -compact -width usrXlocalXetcXkyuaXkyuaXconfXX
.It Pa /usr/local/etc/kyua/kyua.conf
System-wide configuration file for
.Xr kyua 1 .
.It Pa ~/.kyua/kyua.conf
User-specific configuration file for
.Xr kyua 1 ;
overrides the system file.
.It Pa ~/.kyua/store.db
Default database used by Kyua to maintain the data of the executed tests.
.It Pa /usr/tests/
Location of the
.Fx
test suite.
.It Pa /usr/tests/Kyuafile
Top-level test suite definition file.
.El
.Sh SEE ALSO
.Xr kyua 1 .
.Sh HISTORY
The collection of test programs in
.Pa /usr/tests
first appeared in
.Fx 11.0 .
.Pp
The
.Nm
manual page first appeared in
.Nx 6.0
and was later ported to
.Fx 11.0 .
.Sh AUTHORS
.An Julio Merino Aq Mt jmmv@google.com

View File

@ -14,9 +14,9 @@ buildfiles: ${${group}}
all: buildfiles
.if !target(installfiles)
.for group in ${FILESGROUPS}
.if defined(${group}) && !empty(${group})
installfiles: installfiles-${group}
${group}OWN?= ${SHAREOWN}
${group}GRP?= ${SHAREGRP}
@ -37,7 +37,7 @@ ${group}NAME_${file:T}?= ${${group}NAME}
.else
${group}NAME_${file:T}?= ${file:T}
.endif
installfiles: _${group}INS_${file:T}
installfiles-${group}: _${group}INS_${file:T}
_${group}INS_${file:T}: ${file}
${INSTALL} -o ${${group}OWN_${.ALLSRC:T}} \
-g ${${group}GRP_${.ALLSRC:T}} -m ${${group}MODE_${.ALLSRC:T}} \
@ -48,7 +48,7 @@ _${group}FILES+= ${file}
.endif
.endfor
.if !empty(_${group}FILES)
installfiles: _${group}INS
installfiles-${group}: _${group}INS
_${group}INS: ${_${group}FILES}
.if defined(${group}NAME)
${INSTALL} -o ${${group}OWN} -g ${${group}GRP} \
@ -63,7 +63,5 @@ _${group}INS: ${_${group}FILES}
.endif # defined(${group}) && !empty(${group})
.endfor
.endif # !target(installfiles)
realinstall: installfiles
.ORDER: beforeinstall installfiles

View File

@ -377,6 +377,7 @@ __DEFAULT_NO_OPTIONS = \
PKGTOOLS \
SHARED_TOOLCHAIN \
SVN \
TESTS \
USB_GADGET_EXAMPLES
#
@ -664,4 +665,8 @@ $xGRP= ${_gid}
.endif # !_WITHOUT_SRCCONF
# Pointer to the top directory into which tests are installed. Should not be
# overriden by Makefiles, but the user may choose to set this in src.conf(5).
TESTSBASE?= /usr/tests
.endif # !target(__<bsd.own.mk>__)

View File

@ -12,10 +12,6 @@
.include <bsd.init.mk>
# Pointer to the top directory into which tests are installed. Should not be
# overriden by Makefiles, but the user may choose to set this in src.conf(5).
TESTSBASE?= /usr/tests
# Directory in which to install tests defined by the current Makefile.
# Makefiles have to override this to point to a subdirectory of TESTSBASE.
TESTSDIR?= .

51
share/mk/plain.test.mk Normal file
View File

@ -0,0 +1,51 @@
# $FreeBSD$
#
# Logic to build and install plain test programs. A plain test programs it not
# supposed to use any specific testing framework: all it does is run some code
# and report the test's pass or fail status via a 0 or 1 exit code.
.include <bsd.init.mk>
# List of C, C++ and shell test programs to build.
#
# Programs listed here are built according to the semantics of bsd.prog.mk for
# PROGS, PROGS_CXX and SCRIPTS, respectively.
#
# Test programs registered in this manner are set to be installed into TESTSDIR
# (which should be overriden by the Makefile) and are not required to provide a
# manpage.
PLAIN_TESTS_C?=
PLAIN_TESTS_CXX?=
PLAIN_TESTS_SH?=
.if !empty(PLAIN_TESTS_C)
PROGS+= ${PLAIN_TESTS_C}
_TESTS+= ${PLAIN_TESTS_C}
.for _T in ${PLAIN_TESTS_C}
BINDIR.${_T}= ${TESTSDIR}
MAN.${_T}?= # empty
TEST_INTERFACE.${_T}= plain
.endfor
.endif
.if !empty(PLAIN_TESTS_CXX)
PROGS_CXX+= ${PLAIN_TESTS_CXX}
PROGS+= ${PLAIN_TESTS_CXX}
_TESTS+= ${PLAIN_TESTS_CXX}
.for _T in ${PLAIN_TESTS_CXX}
BINDIR.${_T}= ${TESTSDIR}
MAN.${_T}?= # empty
TEST_INTERFACE.${_T}= plain
.endfor
.endif
.if !empty(PLAIN_TESTS_SH)
SCRIPTS+= ${PLAIN_TESTS_SH}
_TESTS+= ${PLAIN_TESTS_SH}
.for _T in ${PLAIN_TESTS_SH}
SCRIPTSDIR_${_T}= ${TESTSDIR}
TEST_INTERFACE.${_T}= plain
.endfor
.endif
.include <bsd.test.mk>

View File

@ -0,0 +1,521 @@
/*-
* Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
* Copyright (c) 2013 Luiz Otavio O Souza <loos@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/resource.h>
#include <machine/fdt.h>
#include <machine/frame.h>
#include <machine/intr.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
#include <arm/broadcom/bcm2835/bcm2835_gpio.h>
#include <arm/broadcom/bcm2835/bcm2835_spireg.h>
#include <arm/broadcom/bcm2835/bcm2835_spivar.h>
#include "spibus_if.h"
static void bcm_spi_intr(void *);
#ifdef BCM_SPI_DEBUG
static void
bcm_spi_printr(device_t dev)
{
struct bcm_spi_softc *sc;
uint32_t reg;
sc = device_get_softc(dev);
reg = BCM_SPI_READ(sc, SPI_CS);
device_printf(dev, "CS=%b\n", reg,
"\20\1CS0\2CS1\3CPHA\4CPOL\7CSPOL"
"\10TA\11DMAEN\12INTD\13INTR\14ADCS\15REN\16LEN"
"\21DONE\22RXD\23TXD\24RXR\25RXF\26CSPOL0\27CSPOL1"
"\30CSPOL2\31DMA_LEN\32LEN_LONG");
reg = BCM_SPI_READ(sc, SPI_CLK) & SPI_CLK_MASK;
if (reg % 2)
reg--;
if (reg == 0)
reg = 65536;
device_printf(dev, "CLK=%uMhz/%d=%luhz\n",
SPI_CORE_CLK / 1000000, reg, SPI_CORE_CLK / reg);
reg = BCM_SPI_READ(sc, SPI_DLEN) & SPI_DLEN_MASK;
device_printf(dev, "DLEN=%d\n", reg);
reg = BCM_SPI_READ(sc, SPI_LTOH) & SPI_LTOH_MASK;
device_printf(dev, "LTOH=%d\n", reg);
reg = BCM_SPI_READ(sc, SPI_DC);
device_printf(dev, "DC=RPANIC=%#x RDREQ=%#x TPANIC=%#x TDREQ=%#x\n",
(reg & SPI_DC_RPANIC_MASK) >> SPI_DC_RPANIC_SHIFT,
(reg & SPI_DC_RDREQ_MASK) >> SPI_DC_RDREQ_SHIFT,
(reg & SPI_DC_TPANIC_MASK) >> SPI_DC_TPANIC_SHIFT,
(reg & SPI_DC_TDREQ_MASK) >> SPI_DC_TDREQ_SHIFT);
}
#endif
static void
bcm_spi_modifyreg(struct bcm_spi_softc *sc, uint32_t off, uint32_t mask,
uint32_t value)
{
uint32_t reg;
mtx_assert(&sc->sc_mtx, MA_OWNED);
reg = BCM_SPI_READ(sc, off);
reg &= ~mask;
reg |= value;
BCM_SPI_WRITE(sc, off, reg);
}
static int
bcm_spi_clock_proc(SYSCTL_HANDLER_ARGS)
{
struct bcm_spi_softc *sc;
uint32_t clk;
int error;
sc = (struct bcm_spi_softc *)arg1;
BCM_SPI_LOCK(sc);
clk = BCM_SPI_READ(sc, SPI_CLK);
BCM_SPI_UNLOCK(sc);
clk &= 0xffff;
if (clk == 0)
clk = 65536;
clk = SPI_CORE_CLK / clk;
error = sysctl_handle_int(oidp, &clk, sizeof(clk), req);
if (error != 0 || req->newptr == NULL)
return (error);
clk = SPI_CORE_CLK / clk;
if (clk <= 1)
clk = 2;
else if (clk % 2)
clk--;
if (clk > 0xffff)
clk = 0;
BCM_SPI_LOCK(sc);
BCM_SPI_WRITE(sc, SPI_CLK, clk);
BCM_SPI_UNLOCK(sc);
return (0);
}
static int
bcm_spi_cs_bit_proc(SYSCTL_HANDLER_ARGS, uint32_t bit)
{
struct bcm_spi_softc *sc;
uint32_t reg;
int error;
sc = (struct bcm_spi_softc *)arg1;
BCM_SPI_LOCK(sc);
reg = BCM_SPI_READ(sc, SPI_CS);
BCM_SPI_UNLOCK(sc);
reg = (reg & bit) ? 1 : 0;
error = sysctl_handle_int(oidp, &reg, sizeof(reg), req);
if (error != 0 || req->newptr == NULL)
return (error);
if (reg)
reg = bit;
BCM_SPI_LOCK(sc);
bcm_spi_modifyreg(sc, SPI_CS, bit, reg);
BCM_SPI_UNLOCK(sc);
return (0);
}
static int
bcm_spi_cpol_proc(SYSCTL_HANDLER_ARGS)
{
return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CPOL));
}
static int
bcm_spi_cpha_proc(SYSCTL_HANDLER_ARGS)
{
return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CPHA));
}
static int
bcm_spi_cspol0_proc(SYSCTL_HANDLER_ARGS)
{
return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CSPOL0));
}
static int
bcm_spi_cspol1_proc(SYSCTL_HANDLER_ARGS)
{
return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CSPOL1));
}
static void
bcm_spi_sysctl_init(struct bcm_spi_softc *sc)
{
struct sysctl_ctx_list *ctx;
struct sysctl_oid *tree_node;
struct sysctl_oid_list *tree;
/*
* Add system sysctl tree/handlers.
*/
ctx = device_get_sysctl_ctx(sc->sc_dev);
tree_node = device_get_sysctl_tree(sc->sc_dev);
tree = SYSCTL_CHILDREN(tree_node);
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "clock",
CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
bcm_spi_clock_proc, "IU", "SPI BUS clock frequency");
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cpol",
CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
bcm_spi_cpol_proc, "IU", "SPI BUS clock polarity");
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cpha",
CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
bcm_spi_cpha_proc, "IU", "SPI BUS clock phase");
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cspol0",
CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
bcm_spi_cspol0_proc, "IU", "SPI BUS chip select 0 polarity");
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cspol1",
CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc),
bcm_spi_cspol1_proc, "IU", "SPI BUS chip select 1 polarity");
}
static int
bcm_spi_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-spi"))
return (ENXIO);
device_set_desc(dev, "BCM2708/2835 SPI controller");
return (BUS_PROBE_DEFAULT);
}
static int
bcm_spi_attach(device_t dev)
{
struct bcm_spi_softc *sc;
device_t gpio;
int i, rid;
if (device_get_unit(dev) != 0) {
device_printf(dev, "only one SPI controller supported\n");
return (ENXIO);
}
sc = device_get_softc(dev);
sc->sc_dev = dev;
/* Configure the GPIO pins to ALT0 function to enable SPI the pins. */
gpio = devclass_get_device(devclass_find("gpio"), 0);
if (!gpio) {
device_printf(dev, "cannot find gpio0\n");
return (ENXIO);
}
for (i = 0; i < nitems(bcm_spi_pins); i++)
bcm_gpio_set_alternate(gpio, bcm_spi_pins[i], BCM_GPIO_ALT0);
rid = 0;
sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
RF_ACTIVE);
if (!sc->sc_mem_res) {
device_printf(dev, "cannot allocate memory window\n");
return (ENXIO);
}
sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
rid = 0;
sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (!sc->sc_irq_res) {
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
device_printf(dev, "cannot allocate interrupt\n");
return (ENXIO);
}
/* Hook up our interrupt handler. */
if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, bcm_spi_intr, sc, &sc->sc_intrhand)) {
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
device_printf(dev, "cannot setup the interrupt handler\n");
return (ENXIO);
}
mtx_init(&sc->sc_mtx, "bcm_spi", NULL, MTX_DEF);
/* Add sysctl nodes. */
bcm_spi_sysctl_init(sc);
#ifdef BCM_SPI_DEBUG
bcm_spi_printr(dev);
#endif
/*
* Enable the SPI controller. Clear the rx and tx FIFO.
* Defaults to SPI mode 0.
*/
BCM_SPI_WRITE(sc, SPI_CS, SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO);
/* Set the SPI clock to 500Khz. */
BCM_SPI_WRITE(sc, SPI_CLK, SPI_CORE_CLK / 500000);
#ifdef BCM_SPI_DEBUG
bcm_spi_printr(dev);
#endif
device_add_child(dev, "spibus", -1);
return (bus_generic_attach(dev));
}
static int
bcm_spi_detach(device_t dev)
{
struct bcm_spi_softc *sc;
bus_generic_detach(dev);
sc = device_get_softc(dev);
mtx_destroy(&sc->sc_mtx);
if (sc->sc_intrhand)
bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand);
if (sc->sc_irq_res)
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
if (sc->sc_mem_res)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
return (0);
}
static void
bcm_spi_fill_fifo(struct bcm_spi_softc *sc)
{
struct spi_command *cmd;
uint32_t cs, written;
uint8_t *data;
cmd = sc->sc_cmd;
cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD);
while (sc->sc_written < sc->sc_len &&
cs == (SPI_CS_TA | SPI_CS_TXD)) {
data = (uint8_t *)cmd->tx_cmd;
written = sc->sc_written++;
if (written >= cmd->tx_cmd_sz) {
data = (uint8_t *)cmd->tx_data;
written -= cmd->tx_cmd_sz;
}
BCM_SPI_WRITE(sc, SPI_FIFO, data[written]);
cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD);
}
}
static void
bcm_spi_drain_fifo(struct bcm_spi_softc *sc)
{
struct spi_command *cmd;
uint32_t cs, read;
uint8_t *data;
cmd = sc->sc_cmd;
cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD;
while (sc->sc_read < sc->sc_len && cs == SPI_CS_RXD) {
data = (uint8_t *)cmd->rx_cmd;
read = sc->sc_read++;
if (read >= cmd->rx_cmd_sz) {
data = (uint8_t *)cmd->rx_data;
read -= cmd->rx_cmd_sz;
}
data[read] = BCM_SPI_READ(sc, SPI_FIFO) & 0xff;
cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD;
}
}
static void
bcm_spi_intr(void *arg)
{
struct bcm_spi_softc *sc;
sc = (struct bcm_spi_softc *)arg;
BCM_SPI_LOCK(sc);
/* Filter stray interrupts. */
if ((sc->sc_flags & BCM_SPI_BUSY) == 0) {
BCM_SPI_UNLOCK(sc);
return;
}
/* TX - Fill up the FIFO. */
bcm_spi_fill_fifo(sc);
/* RX - Drain the FIFO. */
bcm_spi_drain_fifo(sc);
/* Check for end of transfer. */
if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) {
/* Disable interrupts and the SPI engine. */
bcm_spi_modifyreg(sc, SPI_CS,
SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0);
wakeup(sc->sc_dev);
}
BCM_SPI_UNLOCK(sc);
}
static int
bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
{
struct bcm_spi_softc *sc;
int cs, err;
sc = device_get_softc(dev);
KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
("TX/RX command sizes should be equal"));
KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
("TX/RX data sizes should be equal"));
BCM_SPI_LOCK(sc);
/* If the controller is in use wait until it is available. */
while (sc->sc_flags & BCM_SPI_BUSY)
mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", 0);
/* Now we have control over SPI controller. */
sc->sc_flags = BCM_SPI_BUSY;
/* Clear the FIFO. */
bcm_spi_modifyreg(sc, SPI_CS,
SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO,
SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO);
/* Get the proper chip select for this child. */
spibus_get_cs(child, &cs);
if (cs < 0 || cs > 2) {
device_printf(dev,
"Invalid chip select %d requested by %s\n", cs,
device_get_nameunit(child));
BCM_SPI_UNLOCK(sc);
return (EINVAL);
}
/* Save a pointer to the SPI command. */
sc->sc_cmd = cmd;
sc->sc_read = 0;
sc->sc_written = 0;
sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz;
/*
* Set the CS for this transaction, enable interrupts and announce
* we're ready to tx. This will kick off the first interrupt.
*/
bcm_spi_modifyreg(sc, SPI_CS,
SPI_CS_MASK | SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD,
cs | SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD);
/* Wait for the transaction to complete. */
err = mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", hz * 2);
/* Make sure the SPI engine and interrupts are disabled. */
bcm_spi_modifyreg(sc, SPI_CS, SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0);
/* Clear the controller flags. */
sc->sc_flags = 0;
/*
* Check for transfer timeout. The SPI controller doesn't
* return errors.
*/
if (err == EWOULDBLOCK) {
device_printf(sc->sc_dev, "SPI error\n");
err = EIO;
}
BCM_SPI_UNLOCK(sc);
return (err);
}
static phandle_t
bcm_spi_get_node(device_t bus, device_t dev)
{
/* We only have one child, the SPI bus, which needs our own node. */
return (ofw_bus_get_node(bus));
}
static device_method_t bcm_spi_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bcm_spi_probe),
DEVMETHOD(device_attach, bcm_spi_attach),
DEVMETHOD(device_detach, bcm_spi_detach),
/* SPI interface */
DEVMETHOD(spibus_transfer, bcm_spi_transfer),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, bcm_spi_get_node),
DEVMETHOD_END
};
static devclass_t bcm_spi_devclass;
static driver_t bcm_spi_driver = {
"spi",
bcm_spi_methods,
sizeof(struct bcm_spi_softc),
};
DRIVER_MODULE(bcm2835_spi, simplebus, bcm_spi_driver, bcm_spi_devclass, 0, 0);

View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
* Copyright (c) 2013 Luiz Otavio O Souza <loos@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _BCM2835_SPIREG_H_
#define _BCM2835_SPIREG_H_
#define SPI_CORE_CLK 250000000U
#define SPI_CS 0x00
#define SPI_CS_LEN_LONG (1 << 25)
#define SPI_CS_DMA_LEN (1 << 24)
#define SPI_CS_CSPOL2 (1 << 23)
#define SPI_CS_CSPOL1 (1 << 22)
#define SPI_CS_CSPOL0 (1 << 21)
#define SPI_CS_RXF (1 << 20)
#define SPI_CS_RXR (1 << 19)
#define SPI_CS_TXD (1 << 18)
#define SPI_CS_RXD (1 << 17)
#define SPI_CS_DONE (1 << 16)
#define SPI_CS_LEN (1 << 13)
#define SPI_CS_REN (1 << 12)
#define SPI_CS_ADCS (1 << 11)
#define SPI_CS_INTR (1 << 10)
#define SPI_CS_INTD (1 << 9)
#define SPI_CS_DMAEN (1 << 8)
#define SPI_CS_TA (1 << 7)
#define SPI_CS_CSPOL (1 << 6)
#define SPI_CS_CLEAR_RXFIFO (1 << 5)
#define SPI_CS_CLEAR_TXFIFO (1 << 4)
#define SPI_CS_CPOL (1 << 3)
#define SPI_CS_CPHA (1 << 2)
#define SPI_CS_MASK 0x3
#define SPI_FIFO 0x04
#define SPI_CLK 0x08
#define SPI_CLK_MASK 0xffff
#define SPI_DLEN 0x0c
#define SPI_DLEN_MASK 0xffff
#define SPI_LTOH 0x10
#define SPI_LTOH_MASK 0xf
#define SPI_DC 0x14
#define SPI_DC_RPANIC_SHIFT 24
#define SPI_DC_RPANIC_MASK (0xff << SPI_DC_RPANIC_SHIFT)
#define SPI_DC_RDREQ_SHIFT 16
#define SPI_DC_RDREQ_MASK (0xff << SPI_DC_RDREQ_SHIFT)
#define SPI_DC_TPANIC_SHIFT 8
#define SPI_DC_TPANIC_MASK (0xff << SPI_DC_TPANIC_SHIFT)
#define SPI_DC_TDREQ_SHIFT 0
#define SPI_DC_TDREQ_MASK 0xff
#endif /* _BCM2835_SPIREG_H_ */

View File

@ -0,0 +1,72 @@
/*-
* Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
* Copyright (c) 2013 Luiz Otavio O Souza <loos@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _BCM2835_SPIVAR_H_
#define _BCM2835_SPIVAR_H_
/*
* Only the available pins are listed here.
* i.e. CS2 isn't available.
*/
uint32_t bcm_spi_pins[] = {
7, /* CS1 */
8, /* CS0 */
9, /* MISO */
10, /* MOSI */
11 /* SCLK */
};
struct bcm_spi_softc {
device_t sc_dev;
struct mtx sc_mtx;
struct resource * sc_mem_res;
struct resource * sc_irq_res;
struct spi_command *sc_cmd;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
uint32_t sc_len;
uint32_t sc_read;
uint32_t sc_flags;
uint32_t sc_written;
void * sc_intrhand;
};
#define BCM_SPI_BUSY 0x1
#define BCM_SPI_WRITE(_sc, _off, _val) \
bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
#define BCM_SPI_READ(_sc, _off) \
bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
#define BCM_SPI_LOCK(_sc) \
mtx_lock(&(_sc)->sc_mtx)
#define BCM_SPI_UNLOCK(_sc) \
mtx_unlock(&(_sc)->sc_mtx)
#endif /* _BCM2835_SPIVAR_H_ */

View File

@ -8,6 +8,7 @@ arm/broadcom/bcm2835/bcm2835_intr.c standard
arm/broadcom/bcm2835/bcm2835_machdep.c standard
arm/broadcom/bcm2835/bcm2835_mbox.c standard
arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci
arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi
arm/broadcom/bcm2835/bcm2835_systimer.c standard
arm/broadcom/bcm2835/bcm2835_wdog.c standard
arm/broadcom/bcm2835/bus_space.c optional fdt

View File

@ -107,6 +107,10 @@ device smcphy
device mii
device smsc
# SPI
device spibus
device bcm2835_spi
# Flattened Device Tree
options FDT
# Note: DTB is normally loaded and modified by RPi boot loader, then

View File

@ -605,7 +605,6 @@ int
platform_gpio_init(void)
{
phandle_t child, parent, root, ctrl;
ihandle_t ctrl_ihandle;
pcell_t gpios[MAX_PINS_PER_NODE * GPIOS_PROP_CELLS];
struct gpio_ctrl_entry *e;
int len, rv;
@ -639,9 +638,7 @@ platform_gpio_init(void)
* contain a ref. to a node defining GPIO
* controller.
*/
ctrl_ihandle = (ihandle_t)gpios[0];
ctrl_ihandle = fdt32_to_cpu(ctrl_ihandle);
ctrl = OF_instance_to_package(ctrl_ihandle);
ctrl = OF_xref_phandle(fdt32_to_cpu(gpios[0]));
if (fdt_is_compatible(ctrl, e->compat))
/* Call a handler. */

View File

@ -412,6 +412,14 @@
interrupt-parent = <&intc>;
};
spi0 {
compatible = "broadcom,bcm2835-spi",
"broadcom,bcm2708-spi";
reg = <0x204000 0x20>;
interrupts = <62>;
interrupt-parent = <&intc>;
};
dma: dma {
compatible = "broadcom,bcm2835-dma",
"broadcom,bcm2708-dma";

View File

@ -80,7 +80,7 @@ typedef enum {
ADA_FLAG_CAN_NCQ = 0x0008,
ADA_FLAG_CAN_DMA = 0x0010,
ADA_FLAG_NEED_OTAG = 0x0020,
ADA_FLAG_WENT_IDLE = 0x0040,
ADA_FLAG_WAS_OTAG = 0x0040,
ADA_FLAG_CAN_TRIM = 0x0080,
ADA_FLAG_OPEN = 0x0100,
ADA_FLAG_SCTX_INIT = 0x0200,
@ -130,12 +130,12 @@ struct trim_request {
struct ada_softc {
struct bio_queue_head bio_queue;
struct bio_queue_head trim_queue;
int outstanding_cmds; /* Number of active commands */
int refcount; /* Active xpt_action() calls */
ada_state state;
ada_flags flags;
ada_quirks quirks;
int sort_io_queue;
int ordered_tag_count;
int outstanding_cmds;
int trim_max_ranges;
int trim_running;
int read_ahead;
@ -153,7 +153,6 @@ struct ada_softc {
struct sysctl_oid *sysctl_tree;
struct callout sendordered_c;
struct trim_request trim_req;
int refcount;
};
struct ada_quirk_entry {
@ -1489,7 +1488,7 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
if ((bp->bio_flags & BIO_ORDERED) != 0
|| (softc->flags & ADA_FLAG_NEED_OTAG) != 0) {
softc->flags &= ~ADA_FLAG_NEED_OTAG;
softc->ordered_tag_count++;
softc->flags |= ADA_FLAG_WAS_OTAG;
tag_code = 0;
} else {
tag_code = 1;
@ -1743,7 +1742,7 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
}
softc->outstanding_cmds--;
if (softc->outstanding_cmds == 0)
softc->flags |= ADA_FLAG_WENT_IDLE;
softc->flags |= ADA_FLAG_WAS_OTAG;
xpt_release_ccb(done_ccb);
if (state == ADA_CCB_TRIM) {
TAILQ_HEAD(, bio) queue;
@ -1905,14 +1904,11 @@ adasendorderedtag(void *arg)
struct ada_softc *softc = arg;
if (ada_send_ordered) {
if ((softc->ordered_tag_count == 0)
&& ((softc->flags & ADA_FLAG_WENT_IDLE) == 0)) {
softc->flags |= ADA_FLAG_NEED_OTAG;
if (softc->outstanding_cmds > 0) {
if ((softc->flags & ADA_FLAG_WAS_OTAG) == 0)
softc->flags |= ADA_FLAG_NEED_OTAG;
softc->flags &= ~ADA_FLAG_WAS_OTAG;
}
if (softc->outstanding_cmds > 0)
softc->flags &= ~ADA_FLAG_WENT_IDLE;
softc->ordered_tag_count = 0;
}
/* Queue us up again */
callout_reset(&softc->sendordered_c,

View File

@ -5293,7 +5293,6 @@ camisr_runqueue(void)
while ((ccb_h = STAILQ_FIRST(&queue->cam_doneq)) != NULL) {
STAILQ_REMOVE_HEAD(&queue->cam_doneq, sim_links.stqe);
mtx_unlock(&queue->cam_doneq_mtx);
ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
xpt_done_process(ccb_h);
mtx_lock(&queue->cam_doneq_mtx);
}

View File

@ -1604,18 +1604,6 @@ ctl_be_block_open(struct ctl_be_block_softc *softc,
return (0);
}
static int
ctl_be_block_mem_ctor(void *mem, int size, void *arg, int flags)
{
return (0);
}
static void
ctl_be_block_mem_dtor(void *mem, int size, void *arg)
{
bzero(mem, size);
}
static int
ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
{
@ -1644,8 +1632,7 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
mtx_init(&be_lun->lock, be_lun->lunname, NULL, MTX_DEF);
be_lun->lun_zone = uma_zcreate(be_lun->lunname, MAXPHYS,
ctl_be_block_mem_ctor, ctl_be_block_mem_dtor, NULL, NULL,
/*align*/ 0, /*flags*/0);
NULL, NULL, NULL, NULL, /*align*/ 0, /*flags*/0);
if (be_lun->lun_zone == NULL) {
snprintf(req->error_str, sizeof(req->error_str),

View File

@ -84,7 +84,7 @@ typedef enum {
DA_FLAG_PACK_LOCKED = 0x004,
DA_FLAG_PACK_REMOVABLE = 0x008,
DA_FLAG_NEED_OTAG = 0x020,
DA_FLAG_WENT_IDLE = 0x040,
DA_FLAG_WAS_OTAG = 0x040,
DA_FLAG_RETRY_UA = 0x080,
DA_FLAG_OPEN = 0x100,
DA_FLAG_SCTX_INIT = 0x200,
@ -198,19 +198,17 @@ struct da_softc {
struct bio_queue_head bio_queue;
struct bio_queue_head delete_queue;
struct bio_queue_head delete_run_queue;
SLIST_ENTRY(da_softc) links;
LIST_HEAD(, ccb_hdr) pending_ccbs;
int tur; /* TEST UNIT READY should be sent */
int refcount; /* Active xpt_action() calls */
da_state state;
da_flags flags;
da_quirks quirks;
int sort_io_queue;
int minimum_cmd_size;
int error_inject;
int ordered_tag_count;
int outstanding_cmds;
int trim_max_ranges;
int delete_running;
int tur;
int delete_available; /* Delete methods possibly available */
uint32_t unmap_max_ranges;
uint32_t unmap_max_lba;
@ -228,7 +226,6 @@ struct da_softc {
uint8_t unmap_buf[UNMAP_BUF_SIZE];
struct scsi_read_capacity_data_long rcaplong;
struct callout mediapoll_c;
int refcount;
};
#define dadeleteflag(softc, delete_method, enable) \
@ -2244,7 +2241,7 @@ skipstate:
if ((bp->bio_flags & BIO_ORDERED) != 0 ||
(softc->flags & DA_FLAG_NEED_OTAG) != 0) {
softc->flags &= ~DA_FLAG_NEED_OTAG;
softc->ordered_tag_count++;
softc->flags |= DA_FLAG_WAS_OTAG;
tag_code = MSG_ORDERED_Q_TAG;
} else {
tag_code = MSG_SIMPLE_Q_TAG;
@ -2297,13 +2294,8 @@ skipstate:
start_ccb->ccb_h.flags |= CAM_UNLOCKED;
out:
/*
* Block out any asynchronous callbacks
* while we touch the pending ccb list.
*/
LIST_INSERT_HEAD(&softc->pending_ccbs,
&start_ccb->ccb_h, periph_links.le);
softc->outstanding_cmds++;
/* We expect a unit attention from this device */
if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
@ -2969,14 +2961,9 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
}
}
/*
* Block out any asynchronous callbacks
* while we touch the pending ccb list.
*/
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
softc->outstanding_cmds--;
if (softc->outstanding_cmds == 0)
softc->flags |= DA_FLAG_WENT_IDLE;
if (LIST_EMPTY(&softc->pending_ccbs))
softc->flags |= DA_FLAG_WAS_OTAG;
xpt_release_ccb(done_ccb);
if (state == DA_CCB_DELETE) {
@ -3583,7 +3570,7 @@ damediapoll(void *arg)
struct cam_periph *periph = arg;
struct da_softc *softc = periph->softc;
if (!softc->tur && softc->outstanding_cmds == 0) {
if (!softc->tur && LIST_EMPTY(&softc->pending_ccbs)) {
if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
softc->tur = 1;
daschedule(periph);
@ -3755,14 +3742,11 @@ dasendorderedtag(void *arg)
struct da_softc *softc = arg;
if (da_send_ordered) {
if ((softc->ordered_tag_count == 0)
&& ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
softc->flags |= DA_FLAG_NEED_OTAG;
if (!LIST_EMPTY(&softc->pending_ccbs)) {
if ((softc->flags & DA_FLAG_WAS_OTAG) == 0)
softc->flags |= DA_FLAG_NEED_OTAG;
softc->flags &= ~DA_FLAG_WAS_OTAG;
}
if (softc->outstanding_cmds > 0)
softc->flags &= ~DA_FLAG_WENT_IDLE;
softc->ordered_tag_count = 0;
}
/* Queue us up again */
callout_reset(&softc->sendordered_c,

View File

@ -49,7 +49,8 @@
/* Offset to the LR Save word (ppc32) */
#define RETURN_OFFSET 4
#define RETURN_OFFSET64 8
/* Offset to LR Save word (ppc64). CR Save area sits between back chain and LR */
#define RETURN_OFFSET64 16
#define INKERNEL(x) ((x) <= VM_MAX_KERNEL_ADDRESS && \
(x) >= VM_MIN_KERNEL_ADDRESS)

View File

@ -127,7 +127,7 @@ options BLKDEV_IOSIZE=8192
# devices and DFLTPHYS for the rest. Some applications have better
# performance with larger raw I/O access sizes. Note that certain VM
# parameters are derived from these values and making them too large
# can make an an unbootable kernel.
# can make an unbootable kernel.
#
# The defaults are 64K and 128K respectively.
options DFLTPHYS=(64*1024)
@ -1281,8 +1281,7 @@ hint.sa.1.target="6"
# to incoming commands that do not otherwise have a logical unit assigned
# to them.
#
# The "unknown" device (uk? in pre-2.0.5) is now part of the base SCSI
# configuration as the "pass" driver.
# The pass driver provides a passthrough API to access the CAM subsystem.
device scbus #base SCSI code
device ch #SCSI media changers

View File

@ -2178,6 +2178,7 @@ dev/sound/midi/mpu_if.m optional sound
dev/sound/midi/mpufoi_if.m optional sound
dev/sound/midi/sequencer.c optional sound
dev/sound/midi/synth_if.m optional sound
dev/spibus/ofw_spibus.c optional fdt spibus
dev/spibus/spibus.c optional spibus \
dependency "spibus_if.h"
dev/spibus/spibus_if.m optional spibus

View File

@ -46,6 +46,7 @@ dev/ofw/ofw_bus_subr.c optional aim
dev/ofw/ofw_console.c optional aim
dev/ofw/ofw_disk.c optional ofwd aim
dev/ofw/ofw_iicbus.c optional iicbus aim
dev/ofw/ofw_nexus.c optional aim | fdt
dev/ofw/ofw_standard.c optional aim powerpc
dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac
dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx

View File

@ -514,7 +514,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
pcell_t *intr;
pcell_t intr_cells;
int interrupt, trig, pol;
int i, intr_num, irq, rv;
int i, intr_num, rv;
if (OF_getproplen(node, "interrupts") <= 0)
/* Node does not have 'interrupts' property. */
@ -523,7 +523,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
/*
* Find #interrupt-cells of the interrupt domain.
*/
if (OF_getprop(node, "interrupt-parent", &iph, sizeof(iph)) <= 0) {
if (OF_getencprop(node, "interrupt-parent", &iph, sizeof(iph)) <= 0) {
debugf("no intr-parent phandle\n");
intr_par = OF_parent(node);
} else {
@ -566,8 +566,7 @@ fdt_intr_to_rl(phandle_t node, struct resource_list *rl,
intr_sl[i].trig = trig;
intr_sl[i].pol = pol;
irq = FDT_MAP_IRQ(iph, interrupt);
resource_list_add(rl, SYS_RES_IRQ, i, irq, irq, 1);
resource_list_add(rl, SYS_RES_IRQ, i, interrupt, interrupt, 1);
}
out:
@ -583,7 +582,7 @@ fdt_get_phyaddr(phandle_t node, device_t dev, int *phy_addr, void **phy_sc)
uint32_t i;
device_t parent, child;
if (OF_getprop(node, "phy-handle", (void *)&phy_handle,
if (OF_getencprop(node, "phy-handle", (void *)&phy_handle,
sizeof(phy_handle)) <= 0)
return (ENXIO);

View File

@ -255,7 +255,7 @@ fdt_pci_route_intr(int bus, int slot, int func, int pin,
struct fdt_pci_intr *intr_info, int *interrupt)
{
pcell_t child_spec[4], masked[4];
ihandle_t iph;
phandle_t iph;
pcell_t intr_par;
pcell_t *map_ptr;
uint32_t addr;
@ -280,7 +280,7 @@ fdt_pci_route_intr(int bus, int slot, int func, int pin,
i = 0;
while (i < map_len) {
iph = fdt32_to_cpu(map_ptr[par_idx]);
intr_par = OF_instance_to_package(iph);
intr_par = OF_xref_phandle(iph);
err = fdt_addr_cells(intr_par, &par_addr_cells);
if (err != 0) {

View File

@ -339,8 +339,7 @@ simplebus_get_interrupt_parent(device_t dev)
struct simplebus_devinfo *di;
struct fdt_ic *ic;
device_t ip;
ihandle_t iph;
phandle_t ph;
phandle_t ph, iph;
ip = NULL;
@ -348,10 +347,9 @@ simplebus_get_interrupt_parent(device_t dev)
if (di == NULL)
return (NULL);
if (OF_getprop(di->di_ofw.obd_node, "interrupt-parent", &iph,
if (OF_getencprop(di->di_ofw.obd_node, "interrupt-parent", &iph,
sizeof(iph)) > 0) {
iph = fdt32_to_cpu(iph);
ph = OF_instance_to_package(iph);
ph = OF_xref_phandle(iph);
SLIST_FOREACH(ic, &fdt_ic_list_head, fdt_ics) {
if (ic->iph == ph) {
ip = ic->dev;

View File

@ -723,11 +723,7 @@ icl_receive_thread(void *arg)
for (;;) {
if (ic->ic_disconnecting) {
//ICL_DEBUG("terminating");
ICL_CONN_LOCK(ic);
ic->ic_receive_running = false;
ICL_CONN_UNLOCK(ic);
kthread_exit();
return;
break;
}
SOCKBUF_LOCK(&so->so_rcv);
@ -740,6 +736,11 @@ icl_receive_thread(void *arg)
icl_conn_receive_pdus(ic, available);
}
ICL_CONN_LOCK(ic);
ic->ic_receive_running = false;
ICL_CONN_UNLOCK(ic);
kthread_exit();
}
static int
@ -879,22 +880,19 @@ icl_send_thread(void *arg)
ICL_CONN_LOCK(ic);
ic->ic_send_running = true;
ICL_CONN_UNLOCK(ic);
for (;;) {
ICL_CONN_LOCK(ic);
if (ic->ic_disconnecting) {
//ICL_DEBUG("terminating");
ic->ic_send_running = false;
ICL_CONN_UNLOCK(ic);
kthread_exit();
return;
break;
}
if (TAILQ_EMPTY(&ic->ic_to_send))
cv_wait(&ic->ic_send_cv, &ic->ic_lock);
icl_conn_send_pdus(ic);
ICL_CONN_UNLOCK(ic);
cv_wait(&ic->ic_send_cv, &ic->ic_lock);
}
ic->ic_send_running = false;
ICL_CONN_UNLOCK(ic);
kthread_exit();
}
static int

View File

@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$");
#include <dev/iwn/if_iwnreg.h>
#include <dev/iwn/if_iwnvar.h>
#include <dev/iwn/if_iwn_devid.h>
#include <dev/iwn/if_iwn_debug.h>
struct iwn_ident {
uint16_t vendor;
@ -331,80 +332,6 @@ static char *iwn_get_csr_string(int);
static void iwn_debug_register(struct iwn_softc *);
#endif
#ifdef IWN_DEBUG
enum {
IWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
IWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
IWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
IWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */
IWN_DEBUG_RESET = 0x00000010, /* reset processing */
IWN_DEBUG_OPS = 0x00000020, /* iwn_ops processing */
IWN_DEBUG_BEACON = 0x00000040, /* beacon handling */
IWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
IWN_DEBUG_INTR = 0x00000100, /* ISR */
IWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
IWN_DEBUG_NODE = 0x00000400, /* node management */
IWN_DEBUG_LED = 0x00000800, /* led management */
IWN_DEBUG_CMD = 0x00001000, /* cmd submission */
IWN_DEBUG_TXRATE = 0x00002000, /* TX rate debugging */
IWN_DEBUG_PWRSAVE = 0x00004000, /* Power save operations */
IWN_DEBUG_REGISTER = 0x20000000, /* print chipset register */
IWN_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
IWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
IWN_DEBUG_ANY = 0xffffffff
};
#define DPRINTF(sc, m, fmt, ...) do { \
if (sc->sc_debug & (m)) \
printf(fmt, __VA_ARGS__); \
} while (0)
static const char *
iwn_intr_str(uint8_t cmd)
{
switch (cmd) {
/* Notifications */
case IWN_UC_READY: return "UC_READY";
case IWN_ADD_NODE_DONE: return "ADD_NODE_DONE";
case IWN_TX_DONE: return "TX_DONE";
case IWN_START_SCAN: return "START_SCAN";
case IWN_STOP_SCAN: return "STOP_SCAN";
case IWN_RX_STATISTICS: return "RX_STATS";
case IWN_BEACON_STATISTICS: return "BEACON_STATS";
case IWN_STATE_CHANGED: return "STATE_CHANGED";
case IWN_BEACON_MISSED: return "BEACON_MISSED";
case IWN_RX_PHY: return "RX_PHY";
case IWN_MPDU_RX_DONE: return "MPDU_RX_DONE";
case IWN_RX_DONE: return "RX_DONE";
/* Command Notifications */
case IWN_CMD_RXON: return "IWN_CMD_RXON";
case IWN_CMD_RXON_ASSOC: return "IWN_CMD_RXON_ASSOC";
case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS";
case IWN_CMD_TIMING: return "IWN_CMD_TIMING";
case IWN_CMD_LINK_QUALITY: return "IWN_CMD_LINK_QUALITY";
case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED";
case IWN5000_CMD_WIMAX_COEX: return "IWN5000_CMD_WIMAX_COEX";
case IWN5000_CMD_CALIB_CONFIG: return "IWN5000_CMD_CALIB_CONFIG";
case IWN5000_CMD_CALIB_RESULT: return "IWN5000_CMD_CALIB_RESULT";
case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";
case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE";
case IWN_CMD_SCAN: return "IWN_CMD_SCAN";
case IWN_CMD_SCAN_RESULTS: return "IWN_CMD_SCAN_RESULTS";
case IWN_CMD_TXPOWER: return "IWN_CMD_TXPOWER";
case IWN_CMD_TXPOWER_DBM: return "IWN_CMD_TXPOWER_DBM";
case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG";
case IWN_CMD_BT_COEX: return "IWN_CMD_BT_COEX";
case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
case IWN_CMD_SET_SENSITIVITY: return "IWN_CMD_SET_SENSITIVITY";
case IWN_CMD_PHY_CALIB: return "IWN_CMD_PHY_CALIB";
}
return "UNKNOWN INTR NOTIF/CMD";
}
#else
#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
#endif
static device_method_t iwn_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, iwn_probe),

102
sys/dev/iwn/if_iwn_debug.h Normal file
View File

@ -0,0 +1,102 @@
/*-
* Copyright (c) 2013 Cedric GROSS <c.gross@kreiz-it.fr>
* Copyright (c) 2011 Intel Corporation
* Copyright (c) 2007-2009
* Damien Bergamini <damien.bergamini@free.fr>
* Copyright (c) 2008
* Benjamin Close <benjsc@FreeBSD.org>
* Copyright (c) 2008 Sam Leffler, Errno Consulting
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* $FreeBSD$
*/
#ifndef __IF_IWN_DEBUG_H__
#define __IF_IWN_DEBUG_H__
#ifdef IWN_DEBUG
enum {
IWN_DEBUG_XMIT = 0x00000001, /* basic xmit operation */
IWN_DEBUG_RECV = 0x00000002, /* basic recv operation */
IWN_DEBUG_STATE = 0x00000004, /* 802.11 state transitions */
IWN_DEBUG_TXPOW = 0x00000008, /* tx power processing */
IWN_DEBUG_RESET = 0x00000010, /* reset processing */
IWN_DEBUG_OPS = 0x00000020, /* iwn_ops processing */
IWN_DEBUG_BEACON = 0x00000040, /* beacon handling */
IWN_DEBUG_WATCHDOG = 0x00000080, /* watchdog timeout */
IWN_DEBUG_INTR = 0x00000100, /* ISR */
IWN_DEBUG_CALIBRATE = 0x00000200, /* periodic calibration */
IWN_DEBUG_NODE = 0x00000400, /* node management */
IWN_DEBUG_LED = 0x00000800, /* led management */
IWN_DEBUG_CMD = 0x00001000, /* cmd submission */
IWN_DEBUG_TXRATE = 0x00002000, /* TX rate debugging */
IWN_DEBUG_PWRSAVE = 0x00004000, /* Power save operations */
IWN_DEBUG_REGISTER = 0x20000000, /* print chipset register */
IWN_DEBUG_TRACE = 0x40000000, /* Print begin and start driver function */
IWN_DEBUG_FATAL = 0x80000000, /* fatal errors */
IWN_DEBUG_ANY = 0xffffffff
};
#define DPRINTF(sc, m, fmt, ...) do { \
if (sc->sc_debug & (m)) \
printf(fmt, __VA_ARGS__); \
} while (0)
static const char *
iwn_intr_str(uint8_t cmd)
{
switch (cmd) {
/* Notifications */
case IWN_UC_READY: return "UC_READY";
case IWN_ADD_NODE_DONE: return "ADD_NODE_DONE";
case IWN_TX_DONE: return "TX_DONE";
case IWN_START_SCAN: return "START_SCAN";
case IWN_STOP_SCAN: return "STOP_SCAN";
case IWN_RX_STATISTICS: return "RX_STATS";
case IWN_BEACON_STATISTICS: return "BEACON_STATS";
case IWN_STATE_CHANGED: return "STATE_CHANGED";
case IWN_BEACON_MISSED: return "BEACON_MISSED";
case IWN_RX_PHY: return "RX_PHY";
case IWN_MPDU_RX_DONE: return "MPDU_RX_DONE";
case IWN_RX_DONE: return "RX_DONE";
/* Command Notifications */
case IWN_CMD_RXON: return "IWN_CMD_RXON";
case IWN_CMD_RXON_ASSOC: return "IWN_CMD_RXON_ASSOC";
case IWN_CMD_EDCA_PARAMS: return "IWN_CMD_EDCA_PARAMS";
case IWN_CMD_TIMING: return "IWN_CMD_TIMING";
case IWN_CMD_LINK_QUALITY: return "IWN_CMD_LINK_QUALITY";
case IWN_CMD_SET_LED: return "IWN_CMD_SET_LED";
case IWN5000_CMD_WIMAX_COEX: return "IWN5000_CMD_WIMAX_COEX";
case IWN5000_CMD_CALIB_CONFIG: return "IWN5000_CMD_CALIB_CONFIG";
case IWN5000_CMD_CALIB_RESULT: return "IWN5000_CMD_CALIB_RESULT";
case IWN5000_CMD_CALIB_COMPLETE: return "IWN5000_CMD_CALIB_COMPLETE";
case IWN_CMD_SET_POWER_MODE: return "IWN_CMD_SET_POWER_MODE";
case IWN_CMD_SCAN: return "IWN_CMD_SCAN";
case IWN_CMD_SCAN_RESULTS: return "IWN_CMD_SCAN_RESULTS";
case IWN_CMD_TXPOWER: return "IWN_CMD_TXPOWER";
case IWN_CMD_TXPOWER_DBM: return "IWN_CMD_TXPOWER_DBM";
case IWN5000_CMD_TX_ANT_CONFIG: return "IWN5000_CMD_TX_ANT_CONFIG";
case IWN_CMD_BT_COEX: return "IWN_CMD_BT_COEX";
case IWN_CMD_SET_CRITICAL_TEMP: return "IWN_CMD_SET_CRITICAL_TEMP";
case IWN_CMD_SET_SENSITIVITY: return "IWN_CMD_SET_SENSITIVITY";
case IWN_CMD_PHY_CALIB: return "IWN_CMD_PHY_CALIB";
}
return "UNKNOWN INTR NOTIF/CMD";
}
#else
#define DPRINTF(sc, m, fmt, ...) do { (void) sc; } while (0)
#endif
#endif /* __IF_IWN_DEBUG_H__ */

View File

@ -17,6 +17,8 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __IF_IWNREG_H__
#define __IF_IWNREG_H__
#define IWN_CT_KILL_THRESHOLD 114 /* in Celsius */
#define IWN_CT_KILL_EXIT_THRESHOLD 95 /* in Celsius */
@ -2052,3 +2054,5 @@ static const char * const iwn_fw_errmsg[] = {
#define IWN_BARRIER_READ_WRITE(sc) \
bus_space_barrier((sc)->sc_st, (sc)->sc_sh, 0, (sc)->sc_sz, \
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE)
#endif /* __IF_IWNREG_H__ */

View File

@ -38,6 +38,7 @@
/* $FreeBSD$ */
#include "oce_if.h"
static int oce_POST(POCE_SOFTC sc);
@ -203,12 +204,16 @@ void oce_get_pci_capabilities(POCE_SOFTC sc)
{
uint32_t val;
if (pci_find_cap(sc->dev, PCIY_PCIX, &val) == 0) {
#if __FreeBSD_version >= 1000000
#define pci_find_extcap pci_find_cap
#endif
if (pci_find_extcap(sc->dev, PCIY_PCIX, &val) == 0) {
if (val != 0)
sc->flags |= OCE_FLAGS_PCIX;
}
if (pci_find_cap(sc->dev, PCIY_EXPRESS, &val) == 0) {
if (pci_find_extcap(sc->dev, PCIY_EXPRESS, &val) == 0) {
if (val != 0) {
uint16_t link_status =
pci_read_config(sc->dev, val + 0x12, 2);
@ -219,12 +224,12 @@ void oce_get_pci_capabilities(POCE_SOFTC sc)
}
}
if (pci_find_cap(sc->dev, PCIY_MSI, &val) == 0) {
if (pci_find_extcap(sc->dev, PCIY_MSI, &val) == 0) {
if (val != 0)
sc->flags |= OCE_FLAGS_MSI_CAPABLE;
}
if (pci_find_cap(sc->dev, PCIY_MSIX, &val) == 0) {
if (pci_find_extcap(sc->dev, PCIY_MSIX, &val) == 0) {
if (val != 0) {
val = pci_msix_count(sc->dev);
sc->flags |= OCE_FLAGS_MSIX_CAPABLE;
@ -386,6 +391,9 @@ oce_create_nw_interface(POCE_SOFTC sc)
capab_flags &= ~MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR;
}
if (IS_SH(sc) || IS_XE201(sc))
capab_flags |= MBX_RX_IFACE_FLAGS_MULTICAST;
/* enable capabilities controlled via driver startup parameters */
if (is_rss_enabled(sc))
capab_en_flags |= MBX_RX_IFACE_FLAGS_RSS;

View File

@ -59,6 +59,30 @@
#define INTR_EN 0x20000000
#define IMAGE_TRANSFER_SIZE (32 * 1024) /* 32K at a time */
/********* UE Status and Mask Registers ***/
#define PCICFG_UE_STATUS_LOW 0xA0
#define PCICFG_UE_STATUS_HIGH 0xA4
#define PCICFG_UE_STATUS_LOW_MASK 0xA8
/* Lancer SLIPORT registers */
#define SLIPORT_STATUS_OFFSET 0x404
#define SLIPORT_CONTROL_OFFSET 0x408
#define SLIPORT_ERROR1_OFFSET 0x40C
#define SLIPORT_ERROR2_OFFSET 0x410
#define PHYSDEV_CONTROL_OFFSET 0x414
#define SLIPORT_STATUS_ERR_MASK 0x80000000
#define SLIPORT_STATUS_DIP_MASK 0x02000000
#define SLIPORT_STATUS_RN_MASK 0x01000000
#define SLIPORT_STATUS_RDY_MASK 0x00800000
#define SLI_PORT_CONTROL_IP_MASK 0x08000000
#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002
#define PHYSDEV_CONTROL_DD_MASK 0x00000004
#define PHYSDEV_CONTROL_INP_MASK 0x40000000
#define SLIPORT_ERROR_NO_RESOURCE1 0x2
#define SLIPORT_ERROR_NO_RESOURCE2 0x9
/* CSR register offsets */
#define MPU_EP_CONTROL 0
#define MPU_EP_SEMAPHORE_BE3 0xac
@ -2079,7 +2103,8 @@ struct flash_file_hdr {
uint32_t antidote;
uint32_t num_imgs;
uint8_t build[24];
uint8_t rsvd[32];
uint8_t asic_type_rev;
uint8_t rsvd[31];
};
struct image_hdr {
@ -3681,4 +3706,3 @@ enum OCE_QUEUE_RX_STATS {
QUEUE_RX_BUFFER_ERRORS = 8,
QUEUE_RX_N_WORDS = 10
};

View File

@ -36,7 +36,6 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include "opt_inet6.h"
@ -44,6 +43,78 @@
#include "oce_if.h"
/* UE Status Low CSR */
static char *ue_status_low_desc[] = {
"CEV",
"CTX",
"DBUF",
"ERX",
"Host",
"MPU",
"NDMA",
"PTC ",
"RDMA ",
"RXF ",
"RXIPS ",
"RXULP0 ",
"RXULP1 ",
"RXULP2 ",
"TIM ",
"TPOST ",
"TPRE ",
"TXIPS ",
"TXULP0 ",
"TXULP1 ",
"UC ",
"WDMA ",
"TXULP2 ",
"HOST1 ",
"P0_OB_LINK ",
"P1_OB_LINK ",
"HOST_GPIO ",
"MBOX ",
"AXGMAC0",
"AXGMAC1",
"JTAG",
"MPU_INTPEND"
};
/* UE Status High CSR */
static char *ue_status_hi_desc[] = {
"LPCMEMHOST",
"MGMT_MAC",
"PCS0ONLINE",
"MPU_IRAM",
"PCS1ONLINE",
"PCTL0",
"PCTL1",
"PMEM",
"RR",
"TXPB",
"RXPP",
"XAUI",
"TXP",
"ARM",
"IPC",
"HOST2",
"HOST3",
"HOST4",
"HOST5",
"HOST6",
"HOST7",
"HOST8",
"HOST9",
"NETC",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown"
};
/* Driver entry points prototypes */
static int oce_probe(device_t dev);
@ -388,11 +459,11 @@ oce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
}
if ((ifp->if_flags & IFF_PROMISC) && !sc->promisc) {
sc->promisc = TRUE;
oce_rxf_set_promiscuous(sc, sc->promisc);
if (!oce_rxf_set_promiscuous(sc, (1 | (1 << 1))))
sc->promisc = TRUE;
} else if (!(ifp->if_flags & IFF_PROMISC) && sc->promisc) {
sc->promisc = FALSE;
oce_rxf_set_promiscuous(sc, sc->promisc);
if (!oce_rxf_set_promiscuous(sc, 0))
sc->promisc = FALSE;
}
break;
@ -862,10 +933,12 @@ retry:
(m->m_pkthdr.csum_flags & CSUM_TCP) ? 1 : 0;
nichdr->u0.s.num_wqe = num_wqes;
nichdr->u0.s.total_length = m->m_pkthdr.len;
if (m->m_flags & M_VLANTAG) {
nichdr->u0.s.vlan = 1; /*Vlan present*/
nichdr->u0.s.vlan_tag = m->m_pkthdr.ether_vtag;
}
if (m->m_pkthdr.csum_flags & CSUM_TSO) {
if (m->m_pkthdr.tso_segsz) {
nichdr->u0.s.lso = 1;
@ -1156,6 +1229,18 @@ oce_wq_handler(void *arg)
}
#if __FreeBSD_version >= 1000000
static __inline void
drbr_stats_update(struct ifnet *ifp, int len, int mflags)
{
#ifndef NO_SLOW_STATS
ifp->if_obytes += len;
if (mflags & M_MCAST)
ifp->if_omcasts++;
#endif
}
#endif
static int
oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
{
@ -1174,7 +1259,7 @@ oce_multiq_transmit(struct ifnet *ifp, struct mbuf *m, struct oce_wq *wq)
return status;
}
if (m != NULL) {
if (m != NULL) {
if ((status = drbr_enqueue(ifp, br, m)) != 0)
return status;
}
@ -1646,6 +1731,10 @@ oce_attach_ifp(POCE_SOFTC sc)
sc->ifp->if_capenable = sc->ifp->if_capabilities;
if_initbaudrate(sc->ifp, IF_Gbps(10));
#if __FreeBSD_version >= 1000000
sc->ifp->if_hw_tsomax = OCE_MAX_TSO_SIZE;
#endif
ether_ifattach(sc->ifp, sc->macaddr.mac_addr);
return 0;
@ -1664,7 +1753,8 @@ oce_add_vlan(void *arg, struct ifnet *ifp, uint16_t vtag)
sc->vlan_tag[vtag] = 1;
sc->vlans_added++;
oce_vid_config(sc);
if (sc->vlans_added <= (sc->max_vlans + 1))
oce_vid_config(sc);
}
@ -1866,12 +1956,76 @@ done:
}
static void oce_detect_hw_error(POCE_SOFTC sc)
{
uint32_t ue_low = 0, ue_high = 0, ue_low_mask = 0, ue_high_mask = 0;
uint32_t sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
uint32_t i;
if (sc->hw_error)
return;
if (IS_XE201(sc)) {
sliport_status = OCE_READ_REG32(sc, db, SLIPORT_STATUS_OFFSET);
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
sliport_err1 = OCE_READ_REG32(sc, db, SLIPORT_ERROR1_OFFSET);
sliport_err2 = OCE_READ_REG32(sc, db, SLIPORT_ERROR2_OFFSET);
}
} else {
ue_low = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW);
ue_high = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HIGH);
ue_low_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_LOW_MASK);
ue_high_mask = OCE_READ_REG32(sc, devcfg, PCICFG_UE_STATUS_HI_MASK);
ue_low = (ue_low & ~ue_low_mask);
ue_high = (ue_high & ~ue_high_mask);
}
/* On certain platforms BE hardware can indicate spurious UEs.
* Allow the h/w to stop working completely in case of a real UE.
* Hence not setting the hw_error for UE detection.
*/
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
sc->hw_error = TRUE;
device_printf(sc->dev, "Error detected in the card\n");
}
if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
device_printf(sc->dev,
"ERR: sliport status 0x%x\n", sliport_status);
device_printf(sc->dev,
"ERR: sliport error1 0x%x\n", sliport_err1);
device_printf(sc->dev,
"ERR: sliport error2 0x%x\n", sliport_err2);
}
if (ue_low) {
for (i = 0; ue_low; ue_low >>= 1, i++) {
if (ue_low & 1)
device_printf(sc->dev, "UE: %s bit set\n",
ue_status_low_desc[i]);
}
}
if (ue_high) {
for (i = 0; ue_high; ue_high >>= 1, i++) {
if (ue_high & 1)
device_printf(sc->dev, "UE: %s bit set\n",
ue_status_hi_desc[i]);
}
}
}
static void
oce_local_timer(void *arg)
{
POCE_SOFTC sc = arg;
int i = 0;
oce_detect_hw_error(sc);
oce_refresh_nic_stats(sc);
oce_refresh_queue_stats(sc);
oce_mac_addr_set(sc);
@ -1890,7 +2044,7 @@ oce_local_timer(void *arg)
/* NOTE : This should only be called holding
* DEVICE_LOCK.
*/
*/
static void
oce_if_deactivate(POCE_SOFTC sc)
{
@ -2080,6 +2234,9 @@ setup_max_queues_want(POCE_SOFTC sc)
(sc->flags & OCE_FLAGS_BE2)) {
sc->nrqs = 1;
sc->nwqs = 1;
} else {
sc->nrqs = MIN(OCE_NCPUS, sc->nrssqs) + 1;
sc->nwqs = MIN(OCE_NCPUS, sc->nrssqs);
}
}

View File

@ -36,7 +36,6 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include <sys/param.h>
@ -88,7 +87,8 @@
#include "oce_hw.h"
#define COMPONENT_REVISION "4.6.95.0"
/* OCE device driver module component revision informaiton */
#define COMPONENT_REVISION "10.0.664.0"
/* OCE devices supported by this driver */
#define PCI_VENDOR_EMULEX 0x10df /* Emulex */
@ -150,6 +150,7 @@ extern int mp_ncpus; /* system's total active cpu cores */
#define OCE_MAX_TX_ELEMENTS 29
#define OCE_MAX_TX_DESC 1024
#define OCE_MAX_TX_SIZE 65535
#define OCE_MAX_TSO_SIZE (65535 - ETHER_HDR_LEN)
#define OCE_MAX_RX_SIZE 4096
#define OCE_MAX_RQ_POSTS 255
#define OCE_DEFAULT_PROMISCUOUS 0
@ -173,6 +174,7 @@ extern int mp_ncpus; /* system's total active cpu cores */
#define OCE_CAPAB_FLAGS (MBX_RX_IFACE_FLAGS_BROADCAST | \
MBX_RX_IFACE_FLAGS_UNTAGGED | \
MBX_RX_IFACE_FLAGS_PROMISCUOUS | \
MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS | \
MBX_RX_IFACE_FLAGS_MCAST_PROMISCUOUS | \
MBX_RX_IFACE_FLAGS_RSS | \
MBX_RX_IFACE_FLAGS_PASS_L3L4_ERR)
@ -863,7 +865,7 @@ typedef struct oce_softc {
uint32_t if_cap_flags;
uint32_t flow_control;
uint32_t promisc;
uint8_t promisc;
struct oce_aic_obj aic_obj[OCE_MAX_EQ];
@ -877,9 +879,11 @@ typedef struct oce_softc {
struct oce_drv_stats oce_stats_info;
struct callout timer;
int8_t be3_native;
uint8_t hw_error;
uint16_t qnq_debug_event;
uint16_t qnqid;
uint16_t pvid;
uint16_t max_vlans;
} OCE_SOFTC, *POCE_SOFTC;
@ -1010,7 +1014,7 @@ int oce_config_vlan(POCE_SOFTC sc, uint32_t if_id,
uint32_t untagged, uint32_t enable_promisc);
int oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control);
int oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss);
int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable);
int oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable);
int oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl);
int oce_get_link_status(POCE_SOFTC sc, struct link_status *link);
int oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem);

View File

@ -36,11 +36,8 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include "oce_if.h"
extern uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
@ -281,8 +278,10 @@ oce_get_fw_version(POCE_SOFTC sc)
if (!ret)
ret = fwcmd->hdr.u0.rsp.status;
if (ret) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, ret);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, ret,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@ -438,8 +437,10 @@ oce_read_mac_addr(POCE_SOFTC sc, uint32_t if_id,
if (!ret)
ret = fwcmd->hdr.u0.rsp.status;
if (ret) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, ret);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, ret,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@ -481,25 +482,27 @@ oce_get_fw_config(POCE_SOFTC sc)
if (!ret)
ret = fwcmd->hdr.u0.rsp.status;
if (ret) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, ret);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, ret,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
DW_SWAP(u32ptr(fwcmd), sizeof(struct mbx_common_query_fw_config));
sc->config_number = fwcmd->params.rsp.config_number;
sc->asic_revision = fwcmd->params.rsp.asic_revision;
sc->port_id = fwcmd->params.rsp.port_id;
sc->function_mode = fwcmd->params.rsp.function_mode;
sc->function_caps = fwcmd->params.rsp.function_caps;
sc->config_number = HOST_32(fwcmd->params.rsp.config_number);
sc->asic_revision = HOST_32(fwcmd->params.rsp.asic_revision);
sc->port_id = HOST_32(fwcmd->params.rsp.port_id);
sc->function_mode = HOST_32(fwcmd->params.rsp.function_mode);
sc->function_caps = HOST_32(fwcmd->params.rsp.function_caps);
if (fwcmd->params.rsp.ulp[0].ulp_mode & ULP_NIC_MODE) {
sc->max_tx_rings = fwcmd->params.rsp.ulp[0].nic_wq_tot;
sc->max_rx_rings = fwcmd->params.rsp.ulp[0].lro_rqid_tot;
sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[0].nic_wq_tot);
sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[0].lro_rqid_tot);
} else {
sc->max_tx_rings = fwcmd->params.rsp.ulp[1].nic_wq_tot;
sc->max_rx_rings = fwcmd->params.rsp.ulp[1].lro_rqid_tot;
sc->max_tx_rings = HOST_32(fwcmd->params.rsp.ulp[1].nic_wq_tot);
sc->max_rx_rings = HOST_32(fwcmd->params.rsp.ulp[1].lro_rqid_tot);
}
error:
@ -561,15 +564,17 @@ oce_if_create(POCE_SOFTC sc,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
*if_id = LE_32(fwcmd->params.rsp.if_id);
*if_id = HOST_32(fwcmd->params.rsp.if_id);
if (mac_addr != NULL)
sc->pmac_id = LE_32(fwcmd->params.rsp.pmac_id);
sc->pmac_id = HOST_32(fwcmd->params.rsp.pmac_id);
error:
return rc;
}
@ -607,8 +612,10 @@ oce_if_del(POCE_SOFTC sc, uint32_t if_id)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -630,7 +637,10 @@ oce_config_vlan(POCE_SOFTC sc,
{
struct oce_mbx mbx;
struct mbx_common_config_vlan *fwcmd;
int rc;
int rc = 0;
if (sc->vlans_added > sc->max_vlans)
goto vlan_promisc;
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_common_config_vlan *)&mbx.payload;
@ -659,9 +669,19 @@ oce_config_vlan(POCE_SOFTC sc,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
return 0;
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto done;
vlan_promisc:
/* Enable Vlan Promis */
oce_rxf_set_promiscuous(sc, (1 << 1));
device_printf(sc->dev,"Enabling Vlan Promisc Mode\n");
done:
return rc;
}
@ -702,8 +722,10 @@ oce_set_flow_control(POCE_SOFTC sc, uint32_t flow_control)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -802,8 +824,10 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
}
return rc;
}
@ -818,7 +842,7 @@ oce_config_nic_rss(POCE_SOFTC sc, uint32_t if_id, uint16_t enable_rss)
* This function uses the COMMON_SET_IFACE_RX_FILTER command instead.
*/
int
oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable)
oce_rxf_set_promiscuous(POCE_SOFTC sc, uint8_t enable)
{
struct mbx_set_common_iface_rx_filter *fwcmd;
int sz = sizeof(struct mbx_set_common_iface_rx_filter);
@ -836,10 +860,13 @@ oce_rxf_set_promiscuous(POCE_SOFTC sc, uint32_t enable)
req = &fwcmd->params.req;
req->iface_flags_mask = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
if (enable) {
req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS |
MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
}
/* Bit 0 Mac promisc, Bit 1 Vlan promisc */
if (enable & 0x01)
req->iface_flags = MBX_RX_IFACE_FLAGS_PROMISCUOUS;
if (enable & 0x02)
req->iface_flags = MBX_RX_IFACE_FLAGS_VLAN_PROMISCUOUS;
req->if_id = sc->if_id;
rc = oce_set_common_iface_rx_filter(sc, &sgl);
@ -886,9 +913,11 @@ oce_set_common_iface_rx_filter(POCE_SOFTC sc, POCE_DMA_MEM sgl)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
return 0;
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
/**
@ -925,14 +954,16 @@ oce_get_link_status(POCE_SOFTC sc, struct link_status *link)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
/* interpret response */
bcopy(&fwcmd->params.rsp, link, sizeof(struct link_status));
link->logical_link_status = LE_32(link->logical_link_status);
link->qos_link_speed = LE_16(link->qos_link_speed);
link->logical_link_status = HOST_32(link->logical_link_status);
link->qos_link_speed = HOST_16(link->qos_link_speed);
error:
return rc;
}
@ -978,8 +1009,10 @@ oce_mbox_get_nic_stats_v0(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -1028,8 +1061,10 @@ oce_mbox_get_nic_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -1080,8 +1115,10 @@ oce_mbox_get_pport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -1133,8 +1170,10 @@ oce_mbox_get_vport_stats(POCE_SOFTC sc, POCE_DMA_MEM pstats_dma_mem,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -1178,8 +1217,10 @@ oce_update_multicast(POCE_SOFTC sc, POCE_DMA_MEM pdma_mem)
if (!rc)
rc = req->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
req->hdr.u0.rsp.additional_status);
return rc;
}
@ -1243,8 +1284,10 @@ oce_mbox_macaddr_add(POCE_SOFTC sc, uint8_t *mac_addr,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
*pmac_id = fwcmd->params.rsp.pmac_id;
@ -1281,8 +1324,10 @@ oce_mbox_macaddr_del(POCE_SOFTC sc, uint32_t if_id, uint32_t pmac_id)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -1318,11 +1363,13 @@ oce_mbox_check_native_mode(POCE_SOFTC sc)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
sc->be3_native = fwcmd->params.rsp.capability_flags
sc->be3_native = HOST_32(fwcmd->params.rsp.capability_flags)
& CAP_BE3_NATIVE_ERX_API;
error:
@ -1363,8 +1410,10 @@ oce_mbox_cmd_set_loopback(POCE_SOFTC sc, uint8_t port_num,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
@ -1406,8 +1455,10 @@ oce_mbox_cmd_test_loopback(POCE_SOFTC sc, uint32_t port_num,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
}
@ -1433,9 +1484,9 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
payload_len,
OCE_MBX_VER_V0);
fwcmd->flash_op_type = optype;
fwcmd->flash_op_code = opcode;
fwcmd->data_buffer_size = num_bytes;
fwcmd->flash_op_type = LE_32(optype);
fwcmd->flash_op_code = LE_32(opcode);
fwcmd->data_buffer_size = LE_32(num_bytes);
mbx.u0.s.embedded = 0; /*Non embeded*/
mbx.payload_length = payload_len;
@ -1451,8 +1502,10 @@ oce_mbox_write_flashrom(POCE_SOFTC sc, uint32_t optype,uint32_t opcode,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
return rc;
@ -1497,8 +1550,10 @@ oce_mbox_get_flashrom_crc(POCE_SOFTC sc, uint8_t *flash_crc,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
bcopy(fwcmd->data_buffer, flash_crc, 4);
@ -1532,18 +1587,20 @@ oce_mbox_get_phy_info(POCE_SOFTC sc, struct oce_phy_info *phy_info)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
phy_info->phy_type = fwcmd->params.rsp.phy_info.phy_type;
phy_info->phy_type = HOST_16(fwcmd->params.rsp.phy_info.phy_type);
phy_info->interface_type =
fwcmd->params.rsp.phy_info.interface_type;
HOST_16(fwcmd->params.rsp.phy_info.interface_type);
phy_info->auto_speeds_supported =
fwcmd->params.rsp.phy_info.auto_speeds_supported;
HOST_16(fwcmd->params.rsp.phy_info.auto_speeds_supported);
phy_info->fixed_speeds_supported =
fwcmd->params.rsp.phy_info.fixed_speeds_supported;
phy_info->misc_params =fwcmd->params.rsp.phy_info.misc_params;
HOST_16(fwcmd->params.rsp.phy_info.fixed_speeds_supported);
phy_info->misc_params = HOST_32(fwcmd->params.rsp.phy_info.misc_params);
error:
return rc;
@ -1593,11 +1650,13 @@ oce_mbox_lancer_write_flashrom(POCE_SOFTC sc, uint32_t data_size,
if (!rc)
rc = fwcmd->params.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->params.rsp.additional_status);
goto error;
}
*written_data = fwcmd->params.rsp.actual_write_length;
*written_data = HOST_32(fwcmd->params.rsp.actual_write_length);
*additional_status = fwcmd->params.rsp.additional_status;
error:
return rc;
@ -1649,11 +1708,13 @@ oce_mbox_create_rq(struct oce_rq *rq)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
rq->rq_id = fwcmd->params.rsp.rq_id;
rq->rq_id = HOST_16(fwcmd->params.rsp.rq_id);
rq->rss_cpuid = fwcmd->params.rsp.rss_cpuid;
error:
return rc;
@ -1673,15 +1734,17 @@ oce_mbox_create_wq(struct oce_wq *wq)
bzero(&mbx, sizeof(struct oce_mbx));
fwcmd = (struct mbx_create_nic_wq *)&mbx.payload;
if (IS_XE201(sc)) {
if (IS_XE201(sc))
version = OCE_MBX_VER_V1;
fwcmd->params.req.if_id = sc->if_id;
} else if(IS_BE(sc))
else if(IS_BE(sc))
IS_PROFILE_SUPER_NIC(sc) ? (version = OCE_MBX_VER_V2)
: (version = OCE_MBX_VER_V0);
else
version = OCE_MBX_VER_V2;
if (version > OCE_MBX_VER_V0)
fwcmd->params.req.if_id = sc->if_id;
mbx_common_req_hdr_init(&fwcmd->hdr, 0, 0,
MBX_SUBSYSTEM_NIC,
NIC_CREATE_WQ, MBX_TIMEOUT_SEC,
@ -1703,13 +1766,15 @@ oce_mbox_create_wq(struct oce_wq *wq)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
wq->wq_id = LE_16(fwcmd->params.rsp.wq_id);
wq->wq_id = HOST_16(fwcmd->params.rsp.wq_id);
if (version == OCE_MBX_VER_V2)
wq->db_offset = LE_32(fwcmd->params.rsp.db_offset);
wq->db_offset = HOST_32(fwcmd->params.rsp.db_offset);
else
wq->db_offset = PD_TXULP_DB;
error:
@ -1754,11 +1819,13 @@ oce_mbox_create_eq(struct oce_eq *eq)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
eq->eq_id = LE_16(fwcmd->params.rsp.eq_id);
eq->eq_id = HOST_16(fwcmd->params.rsp.eq_id);
error:
return rc;
}
@ -1832,11 +1899,13 @@ oce_mbox_cq_create(struct oce_cq *cq, uint32_t ncoalesce, uint32_t is_eventable)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
cq->cq_id = LE_16(fwcmd->params.rsp.cq_id);
cq->cq_id = HOST_16(fwcmd->params.rsp.cq_id);
error:
return rc;
@ -1885,8 +1954,10 @@ oce_mbox_read_transrecv_data(POCE_SOFTC sc, uint32_t page_num)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
if(fwcmd->params.rsp.page_num == PAGE_NUM_A0)
@ -1947,8 +2018,10 @@ oce_mbox_eqd_modify_periodic(POCE_SOFTC sc, struct oce_set_eqd *set_eqd,
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc)
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
}
int
@ -2006,8 +2079,10 @@ oce_get_profile_config(POCE_SOFTC sc)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@ -2027,6 +2102,7 @@ oce_get_profile_config(POCE_SOFTC sc)
goto error;
}
else {
sc->max_vlans = nic_desc->vlan_count;
sc->nwqs = HOST_32(nic_desc->txq_count);
if (sc->nwqs)
sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);
@ -2096,8 +2172,10 @@ oce_get_func_config(POCE_SOFTC sc)
if (!rc)
rc = fwcmd->hdr.u0.rsp.status;
if (rc) {
device_printf(sc->dev,"%s failed - cmd status: %d\n",
__FUNCTION__, rc);
device_printf(sc->dev,
"%s failed - cmd status: %d addi status: %d\n",
__FUNCTION__, rc,
fwcmd->hdr.u0.rsp.additional_status);
goto error;
}
@ -2117,6 +2195,7 @@ oce_get_func_config(POCE_SOFTC sc)
goto error;
}
else {
sc->max_vlans = nic_desc->vlan_count;
sc->nwqs = HOST_32(nic_desc->txq_count);
if (sc->nwqs)
sc->nwqs = MIN(sc->nwqs, OCE_MAX_WQ);

View File

@ -36,11 +36,8 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include "oce_if.h"
/*****************************************************

View File

@ -38,7 +38,6 @@
/* $FreeBSD$ */
#include "oce_if.h"
static void copy_stats_to_sc_xe201(POCE_SOFTC sc);
@ -46,9 +45,8 @@ static void copy_stats_to_sc_be3(POCE_SOFTC sc);
static void copy_stats_to_sc_be2(POCE_SOFTC sc);
static int oce_sysctl_loopback(SYSCTL_HANDLER_ARGS);
static int oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
static int oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
static int oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS);
static int oce_be3_flashdata(POCE_SOFTC sc, const struct firmware
*fw, int num_imgs);
static int oce_lancer_fwupgrade(POCE_SOFTC sc, const struct firmware *fw);
static int oce_sysctl_sfp_vpd_dump(SYSCTL_HANDLER_ARGS);
static boolean_t oce_phy_flashing_required(POCE_SOFTC sc);
@ -62,9 +60,18 @@ static void oce_add_stats_sysctls_xe201(POCE_SOFTC sc,
struct sysctl_ctx_list *ctx,
struct sysctl_oid *stats_node);
extern char component_revision[32];
uint32_t sfp_vpd_dump_buffer[TRANSCEIVER_DATA_NUM_ELE];
struct flash_img_attri {
int img_offset;
int img_size;
int img_type;
bool skip_image;
int optype;
};
void
oce_add_sysctls(POCE_SOFTC sc)
{
@ -154,10 +161,10 @@ oce_loopback_test(struct oce_softc *sc, uint8_t loopback_type)
{
uint32_t status = 0;
oce_mbox_cmd_set_loopback(sc, sc->if_id, loopback_type, 1);
status = oce_mbox_cmd_test_loopback(sc, sc->if_id, loopback_type,
oce_mbox_cmd_set_loopback(sc, sc->port_id, loopback_type, 1);
status = oce_mbox_cmd_test_loopback(sc, sc->port_id, loopback_type,
1500, 2, 0xabc);
oce_mbox_cmd_set_loopback(sc, sc->if_id, OCE_NO_LOOPBACK, 1);
oce_mbox_cmd_set_loopback(sc, sc->port_id, OCE_NO_LOOPBACK, 1);
return status;
}
@ -223,7 +230,7 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
return ENOENT;
}
if (IS_BE(sc) || IS_SH(sc)) {
if (IS_BE(sc)) {
if ((sc->flags & OCE_FLAGS_BE2)) {
device_printf(sc->dev,
"Flashing not supported for BE2 yet.\n");
@ -231,6 +238,8 @@ oce_sys_fwupgrade(SYSCTL_HANDLER_ARGS)
goto done;
}
status = oce_be3_fwupgrade(sc, fw);
} else if (IS_SH(sc)) {
status = oce_skyhawk_fwupgrade(sc,fw);
} else
status = oce_lancer_fwupgrade(sc, fw);
done:
@ -246,6 +255,277 @@ done:
return status;
}
static void oce_fill_flash_img_data(POCE_SOFTC sc, const struct flash_sec_info * fsec,
struct flash_img_attri *pimg, int i,
const struct firmware *fw, int bin_offset)
{
if (IS_SH(sc)) {
pimg->img_offset = HOST_32(fsec->fsec_entry[i].offset);
pimg->img_size = HOST_32(fsec->fsec_entry[i].pad_size);
}
pimg->img_type = HOST_32(fsec->fsec_entry[i].type);
pimg->skip_image = FALSE;
switch (pimg->img_type) {
case IMG_ISCSI:
pimg->optype = 0;
if (IS_BE3(sc)) {
pimg->img_offset = 2097152;
pimg->img_size = 2097152;
}
break;
case IMG_REDBOOT:
pimg->optype = 1;
if (IS_BE3(sc)) {
pimg->img_offset = 262144;
pimg->img_size = 1048576;
}
if (!oce_img_flashing_required(sc, fw->data,
pimg->optype,
pimg->img_offset,
pimg->img_size,
bin_offset))
pimg->skip_image = TRUE;
break;
case IMG_BIOS:
pimg->optype = 2;
if (IS_BE3(sc)) {
pimg->img_offset = 12582912;
pimg->img_size = 524288;
}
break;
case IMG_PXEBIOS:
pimg->optype = 3;
if (IS_BE3(sc)) {
pimg->img_offset = 13107200;;
pimg->img_size = 524288;
}
break;
case IMG_FCOEBIOS:
pimg->optype = 8;
if (IS_BE3(sc)) {
pimg->img_offset = 13631488;
pimg->img_size = 524288;
}
break;
case IMG_ISCSI_BAK:
pimg->optype = 9;
if (IS_BE3(sc)) {
pimg->img_offset = 4194304;
pimg->img_size = 2097152;
}
break;
case IMG_FCOE:
pimg->optype = 10;
if (IS_BE3(sc)) {
pimg->img_offset = 6291456;
pimg->img_size = 2097152;
}
break;
case IMG_FCOE_BAK:
pimg->optype = 11;
if (IS_BE3(sc)) {
pimg->img_offset = 8388608;
pimg->img_size = 2097152;
}
break;
case IMG_NCSI:
pimg->optype = 13;
if (IS_BE3(sc)) {
pimg->img_offset = 15990784;
pimg->img_size = 262144;
}
break;
case IMG_PHY:
pimg->optype = 99;
if (IS_BE3(sc)) {
pimg->img_offset = 1310720;
pimg->img_size = 262144;
}
if (!oce_phy_flashing_required(sc))
pimg->skip_image = TRUE;
break;
default:
pimg->skip_image = TRUE;
break;
}
}
static int
oce_sh_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int32_t num_imgs)
{
char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
const char *p = (const char *)fw->data;
const struct flash_sec_info *fsec = NULL;
struct mbx_common_read_write_flashrom *req;
int rc = 0, i, bin_offset = 0, opcode, num_bytes;
OCE_DMA_MEM dma_mem;
struct flash_img_attri imgatt;
/* Validate Cookie */
bin_offset = (sizeof(struct flash_file_hdr) +
(num_imgs * sizeof(struct image_hdr)));
p += bin_offset;
while (p < ((const char *)fw->data + fw->datasize)) {
fsec = (const struct flash_sec_info *)p;
if (!memcmp(cookie, fsec->cookie, sizeof(cookie)))
break;
fsec = NULL;
p += 32;
}
if (!fsec) {
device_printf(sc->dev,
"Invalid Cookie. Firmware image corrupted ?\n");
return EINVAL;
}
rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom)
+ 32*1024, &dma_mem, 0);
if (rc) {
device_printf(sc->dev,
"Memory allocation failure while flashing\n");
return ENOMEM;
}
req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom);
if (IS_SH(sc))
num_imgs = HOST_32(fsec->fsec_hdr.num_images);
else if (IS_BE3(sc))
num_imgs = MAX_FLASH_COMP;
for (i = 0; i < num_imgs; i++) {
bzero(&imgatt, sizeof(struct flash_img_attri));
oce_fill_flash_img_data(sc, fsec, &imgatt, i, fw, bin_offset);
if (imgatt.skip_image)
continue;
p = fw->data;
p = p + bin_offset + imgatt.img_offset;
if ((p + imgatt.img_size) > ((const char *)fw->data + fw->datasize)) {
rc = 1;
goto ret;
}
while (imgatt.img_size) {
if (imgatt.img_size > 32*1024)
num_bytes = 32*1024;
else
num_bytes = imgatt.img_size;
imgatt.img_size -= num_bytes;
if (!imgatt.img_size)
opcode = FLASHROM_OPER_FLASH;
else
opcode = FLASHROM_OPER_SAVE;
memcpy(req->data_buffer, p, num_bytes);
p += num_bytes;
rc = oce_mbox_write_flashrom(sc, imgatt.optype, opcode,
&dma_mem, num_bytes);
if (rc) {
device_printf(sc->dev,
"cmd to write to flash rom failed.\n");
rc = EIO;
goto ret;
}
/* Leave the CPU for others for some time */
pause("yield", 10);
}
}
ret:
oce_dma_free(sc, &dma_mem);
return rc;
}
#define UFI_TYPE2 2
#define UFI_TYPE3 3
#define UFI_TYPE3R 10
#define UFI_TYPE4 4
#define UFI_TYPE4R 11
static int oce_get_ufi_type(POCE_SOFTC sc,
const struct flash_file_hdr *fhdr)
{
if (fhdr == NULL)
goto be_get_ufi_exit;
if (IS_SH(sc) && fhdr->build[0] == '4') {
if (fhdr->asic_type_rev >= 0x10)
return UFI_TYPE4R;
else
return UFI_TYPE4;
} else if (IS_BE3(sc) && fhdr->build[0] == '3') {
if (fhdr->asic_type_rev == 0x10)
return UFI_TYPE3R;
else
return UFI_TYPE3;
} else if (IS_BE2(sc) && fhdr->build[0] == '2')
return UFI_TYPE2;
be_get_ufi_exit:
device_printf(sc->dev,
"UFI and Interface are not compatible for flashing\n");
return -1;
}
static int
oce_skyhawk_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
{
int rc = 0, num_imgs = 0, i = 0, ufi_type;
const struct flash_file_hdr *fhdr;
const struct image_hdr *img_ptr;
fhdr = (const struct flash_file_hdr *)fw->data;
ufi_type = oce_get_ufi_type(sc, fhdr);
/* Display flash version */
device_printf(sc->dev, "Flashing Firmware %s\n", &fhdr->build[2]);
num_imgs = fhdr->num_imgs;
for (i = 0; i < num_imgs; i++) {
img_ptr = (const struct image_hdr *)((const char *)fw->data +
sizeof(struct flash_file_hdr) +
(i * sizeof(struct image_hdr)));
if (img_ptr->imageid != 1)
continue;
switch (ufi_type) {
case UFI_TYPE4R:
rc = oce_sh_be3_flashdata(sc, fw,
num_imgs);
break;
case UFI_TYPE4:
if (sc->asic_revision < 0x10)
rc = oce_sh_be3_flashdata(sc, fw,
num_imgs);
else {
rc = -1;
device_printf(sc->dev,
"Cant load SH A0 UFI on B0\n");
}
break;
default:
rc = -1;
break;
}
}
return rc;
}
static int
oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
@ -268,7 +548,8 @@ oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
sizeof(struct flash_file_hdr) +
(i * sizeof(struct image_hdr)));
if (img_ptr->imageid == 1) {
rc = oce_be3_flashdata(sc, fw, num_imgs);
rc = oce_sh_be3_flashdata(sc, fw, num_imgs);
break;
}
}
@ -277,156 +558,6 @@ oce_be3_fwupgrade(POCE_SOFTC sc, const struct firmware *fw)
}
static int
oce_be3_flashdata(POCE_SOFTC sc, const struct firmware *fw, int num_imgs)
{
char cookie[2][16] = {"*** SE FLAS", "H DIRECTORY *** "};
const char *p = (const char *)fw->data;
const struct flash_sec_info *fsec = NULL;
struct mbx_common_read_write_flashrom *req;
int rc = 0, i, img_type, bin_offset = 0;
boolean_t skip_image;
uint32_t optype = 0, size = 0, start = 0, num_bytes = 0;
uint32_t opcode = 0;
OCE_DMA_MEM dma_mem;
/* Validate Cookie */
bin_offset = (sizeof(struct flash_file_hdr) +
(num_imgs * sizeof(struct image_hdr)));
p += bin_offset;
while (p < ((const char *)fw->data + fw->datasize)) {
fsec = (const struct flash_sec_info *)p;
if (!memcmp(cookie, fsec->cookie, sizeof(cookie)))
break;
fsec = NULL;
p += 32;
}
if (!fsec) {
device_printf(sc->dev,
"Invalid Cookie. Firmware image corrupted ?\n");
return EINVAL;
}
rc = oce_dma_alloc(sc, sizeof(struct mbx_common_read_write_flashrom)
+ 32*1024, &dma_mem, 0);
if (rc) {
device_printf(sc->dev,
"Memory allocation failure while flashing\n");
return ENOMEM;
}
req = OCE_DMAPTR(&dma_mem, struct mbx_common_read_write_flashrom);
for (i = 0; i < MAX_FLASH_COMP; i++) {
img_type = fsec->fsec_entry[i].type;
skip_image = FALSE;
switch (img_type) {
case IMG_ISCSI:
optype = 0;
size = 2097152;
start = 2097152;
break;
case IMG_REDBOOT:
optype = 1;
size = 1048576;
start = 262144;
if (!oce_img_flashing_required(sc, fw->data,
optype, start, size, bin_offset))
skip_image = TRUE;
break;
case IMG_BIOS:
optype = 2;
size = 524288;
start = 12582912;
break;
case IMG_PXEBIOS:
optype = 3;
size = 524288;
start = 13107200;
break;
case IMG_FCOEBIOS:
optype = 8;
size = 524288;
start = 13631488;
break;
case IMG_ISCSI_BAK:
optype = 9;
size = 2097152;
start = 4194304;
break;
case IMG_FCOE:
optype = 10;
size = 2097152;
start = 6291456;
break;
case IMG_FCOE_BAK:
optype = 11;
size = 2097152;
start = 8388608;
break;
case IMG_NCSI:
optype = 13;
size = 262144;
start = 15990784;
break;
case IMG_PHY:
optype = 99;
size = 262144;
start = 1310720;
if (!oce_phy_flashing_required(sc))
skip_image = TRUE;
break;
default:
skip_image = TRUE;
break;
}
if (skip_image)
continue;
p = fw->data;
p = p + bin_offset + start;
if ((p + size) > ((const char *)fw->data + fw->datasize)) {
rc = 1;
goto ret;
}
while (size) {
if (size > 32*1024)
num_bytes = 32*1024;
else
num_bytes = size;
size -= num_bytes;
if (!size)
opcode = FLASHROM_OPER_FLASH;
else
opcode = FLASHROM_OPER_SAVE;
memcpy(req->data_buffer, p, num_bytes);
p += num_bytes;
rc = oce_mbox_write_flashrom(sc, optype, opcode,
&dma_mem, num_bytes);
if (rc) {
device_printf(sc->dev,
"cmd to write to flash rom failed.\n");
rc = EIO;
goto ret;
}
/* Leave the CPU for others for some time */
pause("yield", 10);
}
}
ret:
oce_dma_free(sc, &dma_mem);
return rc;
}
static boolean_t
oce_phy_flashing_required(POCE_SOFTC sc)
{

View File

@ -36,10 +36,8 @@
* Costa Mesa, CA 92626
*/
/* $FreeBSD$ */
#include "oce_if.h"
static void oce_dma_map_ring(void *arg,

View File

@ -70,4 +70,16 @@ ofw_bus_get_type(device_t dev)
return (OFW_BUS_GET_TYPE(device_get_parent(dev), dev));
}
static __inline int
ofw_bus_map_intr(device_t dev, phandle_t iparent, int irq)
{
return (OFW_BUS_MAP_INTR(dev, dev, iparent, irq));
}
static __inline int
ofw_bus_config_intr(device_t dev, int irq, int sense)
{
return (OFW_BUS_CONFIG_INTR(dev, dev, irq, sense));
}
#endif /* !_DEV_OFW_OFW_BUS_H_ */

View File

@ -56,6 +56,8 @@ CODE {
static ofw_bus_get_name_t ofw_bus_default_get_name;
static ofw_bus_get_node_t ofw_bus_default_get_node;
static ofw_bus_get_type_t ofw_bus_default_get_type;
static ofw_bus_map_intr_t ofw_bus_default_map_intr;
static ofw_bus_config_intr_t ofw_bus_default_config_intr;
static const struct ofw_bus_devinfo *
ofw_bus_default_get_devinfo(device_t bus, device_t dev)
@ -98,6 +100,31 @@ CODE {
return (NULL);
}
int
ofw_bus_default_map_intr(device_t bus, device_t dev, phandle_t iparent,
int irq)
{
/* Propagate up the bus hierarchy until someone handles it. */
if (device_get_parent(bus) != NULL)
return OFW_BUS_MAP_INTR(device_get_parent(bus), dev,
iparent, irq);
/* If that fails, then assume a one-domain system */
return (irq);
}
int
ofw_bus_default_config_intr(device_t bus, device_t dev, int irq,
int sense)
{
/* Propagate up the bus hierarchy until someone handles it. */
if (device_get_parent(bus) != NULL)
return OFW_BUS_CONFIG_INTR(device_get_parent(bus), dev,
irq, sense);
return (ENXIO);
}
};
# Get the ofw_bus_devinfo struct for the device dev on the bus. Used for bus
@ -143,3 +170,22 @@ METHOD const char * get_type {
device_t bus;
device_t dev;
} DEFAULT ofw_bus_default_get_type;
# Map an (interrupt parent, IRQ) pair to a unique system-wide interrupt number.
METHOD int map_intr {
device_t bus;
device_t dev;
phandle_t iparent;
int irq;
} DEFAULT ofw_bus_default_map_intr;
# Configure an interrupt using the device-tree encoded sense key (the second
# value in the interrupts property if interrupt-cells is 2). IRQ should be
# encoded as from ofw_bus_map_intr().
METHOD int config_intr {
device_t bus;
device_t dev;
int irq;
int sense;
} DEFAULT ofw_bus_default_config_intr;

View File

@ -214,14 +214,14 @@ ofw_bus_setup_iinfo(phandle_t node, struct ofw_bus_iinfo *ii, int intrsz)
pcell_t addrc;
int msksz;
if (OF_getprop(node, "#address-cells", &addrc, sizeof(addrc)) == -1)
if (OF_getencprop(node, "#address-cells", &addrc, sizeof(addrc)) == -1)
addrc = 2;
ii->opi_addrc = addrc * sizeof(pcell_t);
ii->opi_imapsz = OF_getprop_alloc(node, "interrupt-map", 1,
ii->opi_imapsz = OF_getencprop_alloc(node, "interrupt-map", 1,
(void **)&ii->opi_imap);
if (ii->opi_imapsz > 0) {
msksz = OF_getprop_alloc(node, "interrupt-map-mask", 1,
msksz = OF_getencprop_alloc(node, "interrupt-map-mask", 1,
(void **)&ii->opi_imapmsk);
/*
* Failure to get the mask is ignored; a full mask is used
@ -246,7 +246,7 @@ ofw_bus_lookup_imap(phandle_t node, struct ofw_bus_iinfo *ii, void *reg,
("ofw_bus_lookup_imap: register size too small: %d < %d",
regsz, ii->opi_addrc));
if (node != -1) {
rv = OF_getprop(node, "reg", reg, regsz);
rv = OF_getencprop(node, "reg", reg, regsz);
if (rv < regsz)
panic("ofw_bus_lookup_imap: cannot get reg property");
}
@ -301,8 +301,8 @@ ofw_bus_search_intrmap(void *intr, int intrsz, void *regs, int physsz,
i = imapsz;
while (i > 0) {
bcopy(mptr + physsz + intrsz, &parent, sizeof(parent));
if (OF_searchprop(OF_xref_phandle(parent), "#interrupt-cells",
&pintrsz, sizeof(pintrsz)) == -1)
if (OF_searchencprop(OF_xref_phandle(parent),
"#interrupt-cells", &pintrsz, sizeof(pintrsz)) == -1)
pintrsz = 1; /* default */
pintrsz *= sizeof(pcell_t);

View File

@ -106,8 +106,8 @@ cn_drvinit(void *unused)
SYSINIT(cndev, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE, cn_drvinit, NULL);
static int stdin;
static int stdout;
static pcell_t stdin;
static pcell_t stdout;
static int
ofwtty_open(struct tty *tp)
@ -170,12 +170,12 @@ ofw_cnprobe(struct consdev *cp)
return;
}
if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1) {
if (OF_getencprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1) {
cp->cn_pri = CN_DEAD;
return;
}
if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) {
if (OF_getencprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1) {
cp->cn_pri = CN_DEAD;
return;
}

View File

@ -226,20 +226,8 @@ ofw_fdt_parent(ofw_t ofw, phandle_t node)
static phandle_t
ofw_fdt_instance_to_package(ofw_t ofw, ihandle_t instance)
{
int offset;
/*
* Note: FDT does not have the notion of instances, but we somewhat
* abuse the semantics and let treat as 'instance' the internal
* 'phandle' prop, so that ofw I/F consumers have a uniform way of
* translation between internal representation (which appear in some
* contexts as property values) and effective phandles.
*/
offset = fdt_node_offset_by_phandle(fdtp, instance);
if (offset < 0)
return (-1);
return (fdt_offset_phandle(offset));
return (-1);
}
/* Get the length of a property of a package. */

View File

@ -35,7 +35,6 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/mutex.h>
#include <dev/fdt/fdt_common.h>
#include <dev/iicbus/iicbus.h>
#include <dev/iicbus/iiconf.h>
#include <dev/ofw/ofw_bus.h>
@ -104,7 +103,6 @@ ofw_iicbus_attach(device_t dev)
phandle_t child;
pcell_t paddr;
device_t childdev;
uint32_t addr;
sc->dev = dev;
mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF);
@ -123,11 +121,12 @@ ofw_iicbus_attach(device_t dev)
* property, then try the reg property. It moves around
* on different systems.
*/
if (OF_getprop(child, "i2c-address", &paddr, sizeof(paddr)) == -1)
if (OF_getprop(child, "reg", &paddr, sizeof(paddr)) == -1)
if (OF_getencprop(child, "i2c-address", &paddr,
sizeof(paddr)) == -1)
if (OF_getencprop(child, "reg", &paddr,
sizeof(paddr)) == -1)
continue;
addr = fdt32_to_cpu(paddr);
/*
* Now set up the I2C and OFW bus layer devinfo and add it
* to the bus.
@ -136,7 +135,7 @@ ofw_iicbus_attach(device_t dev)
M_NOWAIT | M_ZERO);
if (dinfo == NULL)
continue;
dinfo->opd_dinfo.addr = addr;
dinfo->opd_dinfo.addr = paddr;
if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
0) {
free(dinfo, M_DEVBUF);

503
sys/dev/ofw/ofw_nexus.c Normal file
View File

@ -0,0 +1,503 @@
/*-
* Copyright 1998 Massachusetts Institute of Technology
* Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>.
* Copyright 2006 by Marius Strobl <marius@FreeBSD.org>.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
* granted, provided that both the above copyright notice and this
* permission notice appear in all copies, that both the above
* copyright notice and this permission notice appear in all
* supporting documentation, and that the name of M.I.T. not be used
* in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. M.I.T. makes
* no representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
* SHALL M.I.T. 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.
*
* from: FreeBSD: src/sys/i386/i386/nexus.c,v 1.43 2001/02/09
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/pcpu.h>
#include <sys/rman.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/ofw_nexus.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
#include <machine/resource.h>
/*
* The nexus (which is a pseudo-bus actually) iterates over the nodes that
* hang from the Open Firmware root node and adds them as devices to this bus
* (except some special nodes which are excluded) so that drivers can be
* attached to them.
*
* Additionally, interrupt setup/teardown and some resource management are
* done at this level.
*
*/
struct nexus_devinfo {
struct ofw_bus_devinfo ndi_obdinfo;
struct resource_list ndi_rl;
};
static device_probe_t nexus_probe;
static device_attach_t nexus_attach;
static bus_print_child_t nexus_print_child;
static bus_add_child_t nexus_add_child;
static bus_probe_nomatch_t nexus_probe_nomatch;
static bus_alloc_resource_t nexus_alloc_resource;
static bus_adjust_resource_t nexus_adjust_resource;
static bus_release_resource_t nexus_release_resource;
static bus_get_resource_list_t nexus_get_resource_list;
static ofw_bus_get_devinfo_t nexus_get_devinfo;
static int nexus_inlist(const char *, const char *const *);
static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t);
static void nexus_destroy_dinfo(struct nexus_devinfo *);
static int nexus_print_res(struct nexus_devinfo *);
static device_method_t nexus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_probe),
DEVMETHOD(device_attach, nexus_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch),
DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_adjust_resource, nexus_adjust_resource),
DEVMETHOD(bus_release_resource, nexus_release_resource),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_get_resource_list, nexus_get_resource_list),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_devinfo, nexus_get_devinfo),
DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
DEVMETHOD_END
};
DEFINE_CLASS_0(ofw_nexus, ofw_nexus_driver, nexus_methods,
sizeof(struct ofw_nexus_softc));
MODULE_VERSION(ofw_nexus, 1);
static const char *const nexus_excl_name[] = {
"FJSV,system",
"aliases",
"associations",
"chosen",
"cmp",
"counter-timer", /* No separate device; handled by psycho/sbus */
"failsafe",
"memory",
"openprom",
"options",
"packages",
"physical-memory",
"rsc",
"sgcn",
"todsg",
"virtual-memory",
NULL
};
static const char *const nexus_excl_type[] = {
"core",
"cpu",
NULL
};
static int
nexus_inlist(const char *name, const char *const *list)
{
int i;
if (name == NULL)
return (0);
for (i = 0; list[i] != NULL; i++)
if (strcmp(name, list[i]) == 0)
return (1);
return (0);
}
#define NEXUS_EXCLUDED(name, type) \
(nexus_inlist((name), nexus_excl_name) || \
((type) != NULL && nexus_inlist((type), nexus_excl_type)))
static int
nexus_probe(device_t dev)
{
/* Nexus does always match. */
device_set_desc(dev, "Open Firmware Nexus device");
return (0);
}
static int
nexus_attach(device_t dev)
{
struct nexus_devinfo *ndi;
struct ofw_nexus_softc *sc;
device_t cdev;
phandle_t node;
sc = device_get_softc(dev);
node = OF_peer(0);
sc->sc_intr_rman.rm_type = RMAN_ARRAY;
sc->sc_intr_rman.rm_descr = "Interrupts";
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "Device Memory";
if (rman_init(&sc->sc_intr_rman) != 0 ||
rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0 ||
rman_manage_region(&sc->sc_mem_rman, 0, BUS_SPACE_MAXADDR) != 0)
panic("%s: failed to set up rmans.", __func__);
/*
* Allow devices to identify.
*/
bus_generic_probe(dev);
/*
* If no Open Firmware, bail early
*/
if (node == -1)
return (bus_generic_attach(dev));
/*
* Some important numbers
*/
sc->acells = 2;
OF_getencprop(node, "#address-cells", &sc->acells, sizeof(sc->acells));
sc->scells = 1;
OF_getencprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));
/*
* Now walk the OFW tree and attach top-level devices.
*/
for (node = OF_child(node); node > 0; node = OF_peer(node)) {
if ((ndi = nexus_setup_dinfo(dev, node)) == NULL)
continue;
cdev = device_add_child(dev, NULL, -1);
if (cdev == NULL) {
device_printf(dev, "<%s>: device_add_child failed\n",
ndi->ndi_obdinfo.obd_name);
nexus_destroy_dinfo(ndi);
continue;
}
device_set_ivars(cdev, ndi);
}
return (bus_generic_attach(dev));
}
static device_t
nexus_add_child(device_t dev, u_int order, const char *name, int unit)
{
device_t cdev;
struct nexus_devinfo *ndi;
cdev = device_add_child_ordered(dev, order, name, unit);
if (cdev == NULL)
return (NULL);
ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
ndi->ndi_obdinfo.obd_node = -1;
resource_list_init(&ndi->ndi_rl);
device_set_ivars(cdev, ndi);
return (cdev);
}
static int
nexus_print_child(device_t bus, device_t child)
{
int rv;
rv = bus_print_child_header(bus, child);
rv += nexus_print_res(device_get_ivars(child));
rv += bus_print_child_footer(bus, child);
return (rv);
}
static void
nexus_probe_nomatch(device_t bus, device_t child)
{
const char *name, *type;
if (!bootverbose)
return;
name = ofw_bus_get_name(child);
type = ofw_bus_get_type(child);
device_printf(bus, "<%s>",
name != NULL ? name : "unknown");
nexus_print_res(device_get_ivars(child));
printf(" type %s (no driver attached)\n",
type != NULL ? type : "unknown");
}
static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct ofw_nexus_softc *sc;
struct rman *rm;
struct resource *rv;
struct resource_list_entry *rle;
int isdefault, passthrough;
isdefault = (start == 0UL && end == ~0UL);
passthrough = (device_get_parent(child) != bus);
sc = device_get_softc(bus);
rle = NULL;
if (!passthrough && isdefault) {
rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child),
type, *rid);
if (rle == NULL)
return (NULL);
if (rle->res != NULL)
panic("%s: resource entry is busy", __func__);
start = rle->start;
count = ulmax(count, rle->count);
end = ulmax(rle->end, start + count - 1);
}
switch (type) {
case SYS_RES_IRQ:
rm = &sc->sc_intr_rman;
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
break;
default:
return (NULL);
}
rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
*rid, rv) != 0) {
rman_release_resource(rv);
return (NULL);
}
if (!passthrough && rle != NULL) {
rle->res = rv;
rle->start = rman_get_start(rv);
rle->end = rman_get_end(rv);
rle->count = rle->end - rle->start + 1;
}
return (rv);
}
static int
nexus_adjust_resource(device_t bus, device_t child __unused, int type,
struct resource *r, u_long start, u_long end)
{
struct ofw_nexus_softc *sc;
struct rman *rm;
device_t nexus;
nexus = bus;
while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
nexus = device_get_parent(nexus);
sc = device_get_softc(nexus);
switch (type) {
case SYS_RES_IRQ:
rm = &sc->sc_intr_rman;
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
break;
default:
return (EINVAL);
}
if (rm == NULL)
return (ENXIO);
if (rman_is_region_manager(r, rm) == 0)
return (EINVAL);
return (rman_adjust_resource(r, start, end));
}
static int
nexus_release_resource(device_t bus __unused, device_t child, int type,
int rid, struct resource *r)
{
int error;
if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
error = bus_deactivate_resource(child, type, rid, r);
if (error)
return (error);
}
return (rman_release_resource(r));
}
static struct resource_list *
nexus_get_resource_list(device_t bus __unused, device_t child)
{
struct nexus_devinfo *ndi;
ndi = device_get_ivars(child);
return (&ndi->ndi_rl);
}
static const struct ofw_bus_devinfo *
nexus_get_devinfo(device_t bus __unused, device_t child)
{
struct nexus_devinfo *ndi;
ndi = device_get_ivars(child);
return (&ndi->ndi_obdinfo);
}
static struct nexus_devinfo *
nexus_setup_dinfo(device_t dev, phandle_t node)
{
struct ofw_nexus_softc *sc;
struct nexus_devinfo *ndi;
uint32_t *reg, *intr, icells;
uint64_t phys, size;
phandle_t iparent;
int i, j;
int nintr;
int nreg;
sc = device_get_softc(dev);
ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
if (ofw_bus_gen_setup_devinfo(&ndi->ndi_obdinfo, node) != 0) {
free(ndi, M_DEVBUF);
return (NULL);
}
if (NEXUS_EXCLUDED(ndi->ndi_obdinfo.obd_name,
ndi->ndi_obdinfo.obd_type)) {
ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
free(ndi, M_DEVBUF);
return (NULL);
}
resource_list_init(&ndi->ndi_rl);
nreg = OF_getencprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
if (nreg == -1)
nreg = 0;
if (nreg % (sc->acells + sc->scells) != 0) {
if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
ndi->ndi_obdinfo.obd_name);
nreg = 0;
}
for (i = 0; i < nreg; i += sc->acells + sc->scells) {
phys = size = 0;
for (j = 0; j < sc->acells; j++) {
phys <<= 32;
phys |= reg[i + j];
}
for (j = 0; j < sc->scells; j++) {
size <<= 32;
size |= reg[i + sc->acells + j];
}
/* Skip the dummy reg property of glue devices like ssm(4). */
if (size != 0)
resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i,
phys, phys + size - 1, size);
}
free(reg, M_OFWPROP);
nintr = OF_getencprop_alloc(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
iparent = 0;
OF_searchencprop(node, "interrupt-parent", &iparent,
sizeof(iparent));
OF_searchencprop(iparent, "#interrupt-cells", &icells,
sizeof(icells));
for (i = 0; i < nintr; i+= icells) {
intr[i] = ofw_bus_map_intr(dev, iparent, intr[i]);
resource_list_add(&ndi->ndi_rl, SYS_RES_IRQ, i, intr[i],
intr[i], 1);
if (icells > 1)
ofw_bus_config_intr(dev, intr[i], intr[i+1]);
}
free(intr, M_OFWPROP);
}
return (ndi);
}
static void
nexus_destroy_dinfo(struct nexus_devinfo *ndi)
{
resource_list_free(&ndi->ndi_rl);
ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
free(ndi, M_DEVBUF);
}
static int
nexus_print_res(struct nexus_devinfo *ndi)
{
int rv;
rv = 0;
rv += resource_list_print_type(&ndi->ndi_rl, "mem", SYS_RES_MEMORY,
"%#lx");
rv += resource_list_print_type(&ndi->ndi_rl, "irq", SYS_RES_IRQ,
"%ld");
return (rv);
}

40
sys/dev/ofw/ofw_nexus.h Normal file
View File

@ -0,0 +1,40 @@
/*-
* Copyright (c) 2010 Marius Strobl <marius@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _OFW_NEXUS_H_
#define _OFW_NEXUS_H_
struct ofw_nexus_softc {
uint32_t acells, scells;
struct rman sc_intr_rman;
struct rman sc_mem_rman;
};
DECLARE_CLASS(ofw_nexus_driver);
#endif /* _OFW_NEXUS_H_ */

View File

@ -135,7 +135,8 @@ OF_init(void *cookie)
rv = OFW_INIT(ofw_obj, cookie);
if ((chosen = OF_finddevice("/chosen")) != -1)
if (OF_getprop(chosen, "stdout", &stdout, sizeof(stdout)) == -1)
if (OF_getencprop(chosen, "stdout", &stdout,
sizeof(stdout)) == -1)
stdout = -1;
return (rv);
@ -354,11 +355,9 @@ OF_getencprop_alloc(phandle_t package, const char *name, int elsz, void **buf)
pcell_t *cell;
int i;
KASSERT(elsz % 4 == 0, ("Need a multiple of 4 bytes"));
retval = OF_getprop_alloc(package, name, elsz, buf);
if (retval == -1)
return (retval);
if (retval == -1 || retval*elsz % 4 != 0)
return (-1);
cell = *buf;
for (i = 0; i < retval*elsz/4; i++)
@ -450,9 +449,9 @@ OF_child_xref_phandle(phandle_t parent, phandle_t xref)
if (rxref != -1)
return (rxref);
if (OF_getprop(child, "phandle", &rxref, sizeof(rxref)) == -1 &&
OF_getprop(child, "ibm,phandle", &rxref,
sizeof(rxref)) == -1 && OF_getprop(child,
if (OF_getencprop(child, "phandle", &rxref, sizeof(rxref)) ==
-1 && OF_getencprop(child, "ibm,phandle", &rxref,
sizeof(rxref)) == -1 && OF_getencprop(child,
"linux,phandle", &rxref, sizeof(rxref)) == -1)
continue;

View File

@ -70,10 +70,6 @@ __FBSDID("$FreeBSD$");
#include "pcib_if.h"
#include "pci_if.h"
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
#define PCI_DMA_BOUNDARY 0x100000000
#endif
#define PCIR_IS_BIOS(cfg, reg) \
(((cfg)->hdrtype == PCIM_HDRTYPE_NORMAL && reg == PCIR_BIOS) || \
((cfg)->hdrtype == PCIM_HDRTYPE_BRIDGE && reg == PCIR_BIOS_1))
@ -100,7 +96,6 @@ static void pci_load_vendor_data(void);
static int pci_describe_parse_line(char **ptr, int *vendor,
int *device, char **desc);
static char *pci_describe_device(device_t dev);
static bus_dma_tag_t pci_get_dma_tag(device_t bus, device_t dev);
static int pci_modevent(module_t mod, int what, void *arg);
static void pci_hdrtypedata(device_t pcib, int b, int s, int f,
pcicfgregs *cfg);

View File

@ -116,6 +116,7 @@ int pci_child_pnpinfo_str_method(device_t cbdev, device_t child,
int pci_assign_interrupt_method(device_t dev, device_t child);
int pci_resume(device_t dev);
int pci_suspend(device_t dev);
bus_dma_tag_t pci_get_dma_tag(device_t bus, device_t dev);
/** Restore the config register state. The state must be previously
* saved with pci_cfg_save. However, the pci bus driver takes care of

View File

@ -762,8 +762,17 @@
#define PCIEM_SLOT_STA_EIS 0x0080
#define PCIEM_SLOT_STA_DLLSC 0x0100
#define PCIER_ROOT_CTL 0x1c
#define PCIEM_ROOT_CTL_SERR_CORR 0x0001
#define PCIEM_ROOT_CTL_SERR_NONFATAL 0x0002
#define PCIEM_ROOT_CTL_SERR_FATAL 0x0004
#define PCIEM_ROOT_CTL_PME 0x0008
#define PCIEM_ROOT_CTL_CRS_VIS 0x0010
#define PCIER_ROOT_CAP 0x1e
#define PCIEM_ROOT_CAP_CRS_VIS 0x0001
#define PCIER_ROOT_STA 0x20
#define PCIEM_ROOT_STA_PME_REQID_MASK 0x0000ffff
#define PCIEM_ROOT_STA_PME_STATUS 0x00010000
#define PCIEM_ROOT_STA_PME_PEND 0x00020000
#define PCIER_DEVICE_CAP2 0x24
#define PCIER_DEVICE_CTL2 0x28
#define PCIEM_CTL2_COMP_TIMEOUT_VAL 0x000f

View File

@ -499,6 +499,15 @@ void pci_restore_state(device_t dev);
void pci_save_state(device_t dev);
int pci_set_max_read_req(device_t dev, int size);
#ifdef BUS_SPACE_MAXADDR
#if (BUS_SPACE_MAXADDR > 0xFFFFFFFF)
#define PCI_DMA_BOUNDARY 0x100000000
#else
#define PCI_DMA_BOUNDARY 0
#endif
#endif
#endif /* _SYS_BUS_H_ */
/*

192
sys/dev/spibus/ofw_spibus.c Normal file
View File

@ -0,0 +1,192 @@
/*-
* Copyright (c) 2009, Nathan Whitehorn <nwhitehorn@FreeBSD.org>
* Copyright (c) 2013 The FreeBSD Foundation
* All rights reserved.
*
* Portions of this software were developed by Oleksandr 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
* 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/libkern.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <dev/fdt/fdt_common.h>
#include <dev/spibus/spi.h>
#include <dev/spibus/spibusvar.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
#include "spibus_if.h"
struct ofw_spibus_devinfo {
struct spibus_ivar opd_dinfo;
struct ofw_bus_devinfo opd_obdinfo;
};
/* Methods */
static device_probe_t ofw_spibus_probe;
static device_attach_t ofw_spibus_attach;
static device_t ofw_spibus_add_child(device_t dev, u_int order,
const char *name, int unit);
static const struct ofw_bus_devinfo *ofw_spibus_get_devinfo(device_t bus,
device_t dev);
static int
ofw_spibus_probe(device_t dev)
{
if (ofw_bus_get_node(dev) == -1)
return (ENXIO);
device_set_desc(dev, "OFW SPI bus");
return (0);
}
static int
ofw_spibus_attach(device_t dev)
{
struct spibus_softc *sc = device_get_softc(dev);
struct ofw_spibus_devinfo *dinfo;
phandle_t child;
pcell_t paddr;
device_t childdev;
sc->dev = dev;
bus_generic_probe(dev);
bus_enumerate_hinted_children(dev);
/*
* Attach those children represented in the device tree.
*/
for (child = OF_child(ofw_bus_get_node(dev)); child != 0;
child = OF_peer(child)) {
/*
* Try to get the CS number first from the spi-chipselect
* property, then try the reg property.
*/
if (OF_getencprop(child, "spi-chipselect", &paddr,
sizeof(paddr)) == -1) {
if (OF_getencprop(child, "reg", &paddr,
sizeof(paddr)) == -1)
continue;
}
/*
* Now set up the SPI and OFW bus layer devinfo and add it
* to the bus.
*/
dinfo = malloc(sizeof(struct ofw_spibus_devinfo), M_DEVBUF,
M_NOWAIT | M_ZERO);
if (dinfo == NULL)
continue;
dinfo->opd_dinfo.cs = paddr;
if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
0) {
free(dinfo, M_DEVBUF);
continue;
}
childdev = device_add_child(dev, NULL, -1);
device_set_ivars(childdev, dinfo);
}
return (bus_generic_attach(dev));
}
static device_t
ofw_spibus_add_child(device_t dev, u_int order, const char *name, int unit)
{
device_t child;
struct ofw_spibus_devinfo *devi;
child = device_add_child_ordered(dev, order, name, unit);
if (child == NULL)
return (child);
devi = malloc(sizeof(struct ofw_spibus_devinfo), M_DEVBUF,
M_NOWAIT | M_ZERO);
if (devi == NULL) {
device_delete_child(dev, child);
return (0);
}
/*
* NULL all the OFW-related parts of the ivars for non-OFW
* children.
*/
devi->opd_obdinfo.obd_node = -1;
devi->opd_obdinfo.obd_name = NULL;
devi->opd_obdinfo.obd_compat = NULL;
devi->opd_obdinfo.obd_type = NULL;
devi->opd_obdinfo.obd_model = NULL;
device_set_ivars(child, devi);
return (child);
}
static const struct ofw_bus_devinfo *
ofw_spibus_get_devinfo(device_t bus, device_t dev)
{
struct ofw_spibus_devinfo *dinfo;
dinfo = device_get_ivars(dev);
return (&dinfo->opd_obdinfo);
}
static device_method_t ofw_spibus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ofw_spibus_probe),
DEVMETHOD(device_attach, ofw_spibus_attach),
/* Bus interface */
DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
DEVMETHOD(bus_add_child, ofw_spibus_add_child),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_devinfo, ofw_spibus_get_devinfo),
DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
DEVMETHOD_END
};
static devclass_t ofwspibus_devclass;
DEFINE_CLASS_1(spibus, ofw_spibus_driver, ofw_spibus_methods,
sizeof(struct spibus_softc), spibus_driver);
DRIVER_MODULE(ofw_spibus, spi, ofw_spibus_driver, ofwspibus_devclass, 0, 0);
MODULE_VERSION(ofw_spibus, 1);
MODULE_DEPEND(ofw_spibus, spibus, 1, 1, 1);

View File

@ -23,7 +23,7 @@ static int
spibus_probe(device_t dev)
{
device_set_desc(dev, "spibus bus");
return (0);
return (BUS_PROBE_GENERIC);
}
static int
@ -185,7 +185,7 @@ static device_method_t spibus_methods[] = {
DEVMETHOD_END
};
static driver_t spibus_driver = {
driver_t spibus_driver = {
"spibus",
spibus_methods,
sizeof(struct spibus_softc)

View File

@ -26,3 +26,6 @@ spibus_get_ ## A(device_t dev, T *t) \
}
SPIBUS_ACCESSOR(cs, CS, uint32_t)
extern driver_t spibus_driver;
extern devclass_t spibus_devclass;

View File

@ -189,7 +189,7 @@ imx_uart_bus_attach(struct uart_softc *sc)
(void)imx_uart_bus_getsig(sc);
/* XXX workaround to have working console on manut prompt */
/* 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 {

View File

@ -1689,7 +1689,7 @@ ext2_ind_read(struct vop_read_args *ap)
NOCRED, blkoffset + uio->uio_resid, seqcount,
0, &bp);
} else if (seqcount > 1) {
int nextsize = blksize(fs, ip, nextlbn);
u_int nextsize = blksize(fs, ip, nextlbn);
error = breadn(vp, lbn,
size, &nextlbn, &nextsize, 1, NOCRED, &bp);
} else

View File

@ -1,232 +0,0 @@
/*-
* Copyright (c) 2012 Advanced Computing Technologies LLC
* Written by George Neville-Neil gnn@freebsd.org
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/dtrace.h>
#include "../sys/dtrace_bsd.h"
static int dtio_unload(void);
static void dtio_getargdesc(void *, dtrace_id_t, void *,
dtrace_argdesc_t *);
static void dtio_provide(void *, dtrace_probedesc_t *);
static void dtio_destroy(void *, dtrace_id_t, void *);
static void dtio_enable(void *, dtrace_id_t, void *);
static void dtio_disable(void *, dtrace_id_t, void *);
static void dtio_load(void *);
static dtrace_pattr_t dtio_attr = {
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
};
static char *kernel = "kernel";
/*
* Name strings.
*/
static char *dtio_start_str = "start";
static char *dtio_done_str = "done";
static char *dtio_wait_start_str = "wait-start";
static char *dtio_wait_done_str = "wait-done";
static dtrace_pops_t dtio_pops = {
dtio_provide,
NULL,
dtio_enable,
dtio_disable,
NULL,
NULL,
dtio_getargdesc,
NULL,
NULL,
dtio_destroy
};
static dtrace_provider_id_t dtio_id;
extern uint32_t dtio_start_id;
extern uint32_t dtio_done_id;
extern uint32_t dtio_wait_start_id;
extern uint32_t dtio_wait_done_id;
static void
dtio_getargdesc(void *arg, dtrace_id_t id, void *parg,
dtrace_argdesc_t *desc)
{
const char *p = NULL;
switch (desc->dtargd_ndx) {
case 0:
p = "struct bio *";
break;
case 1:
p = "struct devstat *";
break;
default:
desc->dtargd_ndx = DTRACE_ARGNONE;
}
if (p != NULL)
strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
}
static void
dtio_provide(void *arg, dtrace_probedesc_t *desc)
{
if (desc != NULL)
return;
if (dtrace_probe_lookup(dtio_id, kernel, NULL,
dtio_start_str) == 0) {
dtio_start_id = dtrace_probe_create(dtio_id, kernel, NULL,
dtio_start_str, 0, NULL);
}
if (dtrace_probe_lookup(dtio_id, kernel, NULL, dtio_done_str) == 0) {
dtio_done_id = dtrace_probe_create(dtio_id, kernel, NULL,
dtio_done_str, 0, NULL);
}
if (dtrace_probe_lookup(dtio_id, kernel, NULL,
dtio_wait_start_str) == 0) {
dtio_wait_start_id = dtrace_probe_create(dtio_id, kernel,
NULL,
dtio_wait_start_str,
0, NULL);
}
if (dtrace_probe_lookup(dtio_id, kernel, NULL,
dtio_wait_done_str) == 0) {
dtio_wait_done_id = dtrace_probe_create(dtio_id, kernel, NULL,
dtio_wait_done_str, 0, NULL);
}
}
static void
dtio_destroy(void *arg, dtrace_id_t id, void *parg)
{
}
static void
dtio_enable(void *arg, dtrace_id_t id, void *parg)
{
if (id == dtio_start_id)
dtrace_io_start_probe =
(dtrace_io_start_probe_func_t)dtrace_probe;
else if (id == dtio_done_id)
dtrace_io_done_probe =
(dtrace_io_done_probe_func_t)dtrace_probe;
else if (id == dtio_wait_start_id)
dtrace_io_wait_start_probe =
(dtrace_io_wait_start_probe_func_t)dtrace_probe;
else if (id == dtio_wait_done_id)
dtrace_io_wait_done_probe =
(dtrace_io_wait_done_probe_func_t)dtrace_probe;
else
printf("dtrace io provider: unknown ID\n");
}
static void
dtio_disable(void *arg, dtrace_id_t id, void *parg)
{
if (id == dtio_start_id)
dtrace_io_start_probe = NULL;
else if (id == dtio_done_id)
dtrace_io_done_probe = NULL;
else if (id == dtio_wait_start_id)
dtrace_io_wait_start_probe = NULL;
else if (id == dtio_wait_done_id)
dtrace_io_wait_done_probe = NULL;
else
printf("dtrace io provider: unknown ID\n");
}
static void
dtio_load(void *dummy)
{
if (dtrace_register("io", &dtio_attr, DTRACE_PRIV_USER, NULL,
&dtio_pops, NULL, &dtio_id) != 0)
return;
}
static int
dtio_unload()
{
dtrace_io_start_probe = NULL;
dtrace_io_done_probe = NULL;
dtrace_io_wait_start_probe = NULL;
dtrace_io_wait_done_probe = NULL;
return (dtrace_unregister(dtio_id));
}
static int
dtio_modevent(module_t mod __unused, int type, void *data __unused)
{
int error = 0;
switch (type) {
case MOD_LOAD:
break;
case MOD_UNLOAD:
break;
case MOD_SHUTDOWN:
break;
default:
error = EOPNOTSUPP;
break;
}
return (error);
}
SYSINIT(dtio_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
dtio_load, NULL);
SYSUNINIT(dtio_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
dtio_unload, NULL);
DEV_MODULE(dtio, dtio_modevent, NULL);
MODULE_VERSION(dtio, 1);
MODULE_DEPEND(dtio, dtrace, 1, 1, 1);
MODULE_DEPEND(dtio, opensolaris, 1, 1, 1);

View File

@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bio.h>
#include <sys/devicestat.h>
#include <sys/sdt.h>
#include <sys/sysctl.h>
#include <sys/malloc.h>
#include <sys/lock.h>
@ -46,57 +47,21 @@ __FBSDID("$FreeBSD$");
#include <machine/atomic.h>
#ifdef KDTRACE_HOOKS
#include <sys/dtrace_bsd.h>
SDT_PROVIDER_DEFINE(io);
dtrace_io_start_probe_func_t dtrace_io_start_probe;
dtrace_io_done_probe_func_t dtrace_io_done_probe;
dtrace_io_wait_start_probe_func_t dtrace_io_wait_start_probe;
dtrace_io_wait_done_probe_func_t dtrace_io_wait_done_probe;
SDT_PROBE_DEFINE2(io, , , start, start, "struct bio *", "struct devstat *");
SDT_PROBE_DEFINE2(io, , , done, done, "struct bio *", "struct devstat *");
SDT_PROBE_DEFINE2(io, , , wait_start, wait-start, "struct bio *",
"struct devstat *");
SDT_PROBE_DEFINE2(io, , , wait_done, wait-done, "struct bio *",
"struct devstat *");
uint32_t dtio_start_id;
uint32_t dtio_done_id;
uint32_t dtio_wait_start_id;
uint32_t dtio_wait_done_id;
#define DTRACE_DEVSTAT_START() \
if (dtrace_io_start_probe != NULL) \
(*dtrace_io_start_probe)(dtio_start_id, NULL, ds);
#define DTRACE_DEVSTAT_BIO_START() \
if (dtrace_io_start_probe != NULL) \
(*dtrace_io_start_probe)(dtio_start_id, bp, ds);
#define DTRACE_DEVSTAT_DONE() \
if (dtrace_io_done_probe != NULL) \
(*dtrace_io_done_probe)(dtio_done_id, NULL, ds);
#define DTRACE_DEVSTAT_BIO_DONE() \
if (dtrace_io_done_probe != NULL) \
(*dtrace_io_done_probe)(dtio_done_id, bp, ds);
#define DTRACE_DEVSTAT_WAIT_START() \
if (dtrace_io_wait_start_probe != NULL) \
(*dtrace_io_wait_start_probe)(dtio_wait_start_id, NULL, ds);
#define DTRACE_DEVSTAT_WAIT_DONE() \
if (dtrace_io_wait_done_probe != NULL) \
(*dtrace_io_wait_done_probe)(dtio_wait_done_id, NULL, ds);
#else /* ! KDTRACE_HOOKS */
#define DTRACE_DEVSTAT_START()
#define DTRACE_DEVSTAT_BIO_START()
#define DTRACE_DEVSTAT_DONE()
#define DTRACE_DEVSTAT_BIO_DONE()
#define DTRACE_DEVSTAT_WAIT_START()
#define DTRACE_DEVSTAT_WAIT_DONE()
#endif /* KDTRACE_HOOKS */
#define DTRACE_DEVSTAT_START() SDT_PROBE2(io, , , start, NULL, ds)
#define DTRACE_DEVSTAT_BIO_START() SDT_PROBE2(io, , , start, bp, ds)
#define DTRACE_DEVSTAT_DONE() SDT_PROBE2(io, , , done, NULL, ds)
#define DTRACE_DEVSTAT_BIO_DONE() SDT_PROBE2(io, , , done, bp, ds)
#define DTRACE_DEVSTAT_WAIT_START() SDT_PROBE2(io, , , wait_start, NULL, ds)
#define DTRACE_DEVSTAT_WAIT_DONE() SDT_PROBE2(io, , , wait_done, NULL, ds)
static int devstat_num_devs;
static long devstat_generation = 1;

View File

@ -0,0 +1,57 @@
#
# Alfa Networks Hornet UB - an AR933x based SoC wifi device.
#
# http://www.alfa.com.tw/products_show.php?pc=99&ps=50
#
# This is for the 64MB RAM/16MB flash part. They also
# do various other versions; they have different RAM/flash
# configurations.
#
# * AR9330 SoC
# * 64MB RAM
# * 16MB flash
# * Integrated 1x1 2GHz wifi and 10/100 bridge
#
# $FreeBSD$
#
# Include the default AR933x parameters
include "AR933X_BASE"
ident ALFA_HORNET_UB
# Override hints with board values
hints "ALFA_HORNET_UB.hints"
# Board memory - 64MB
options AR71XX_REALMEM=(64*1024*1024)
# i2c GPIO bus
#device gpioiic
#device iicbb
#device iicbus
#device iic
# Options required for miiproxy and mdiobus
options ARGE_MDIO # Export an MDIO bus separate from arge
device miiproxy # MDIO bus <-> MII PHY rendezvous
device etherswitch
device arswitch
# read MSDOS formatted disks - USB
#options MSDOSFS
# Enable the uboot environment stuff rather then the
# redboot stuff.
options AR71XX_ENV_UBOOT
# uzip - to boot natively from flash
device geom_uncompress
options GEOM_UNCOMPRESS
# Used for the static uboot partition map
device geom_map
# Boot off of the rootfs, as defined in the geom_map setup.
options ROOTDEVNAME=\"ufs:map/rootfs.uncompress\"

View File

@ -0,0 +1,105 @@
#
# This file adds to the values in AR933X_BASE.hints
#
# $FreeBSD$
# mdiobus on arge1
hint.argemdio.0.at="nexus0"
hint.argemdio.0.maddr=0x1a000000
hint.argemdio.0.msize=0x1000
hint.argemdio.0.order=0
# There's no need to set the ar933x GMAC configuration bits.
# This just creates a switch instance and correctly uses it.
# Embedded Atheros Switch
hint.arswitch.0.at="mdio0"
# XXX this should really say it's an AR933x switch, as there
# are some vlan specific differences here!
hint.arswitch.0.is_7240=1
hint.arswitch.0.numphys=4
hint.arswitch.0.phy4cpu=1 # phy 4 is a "CPU" separate PHY
hint.arswitch.0.is_rgmii=0
hint.arswitch.0.is_gmii=1 # arge1 <-> switch PHY is GMII
# arge0 - MII, autoneg, phy(4)
hint.arge.0.phymask=0x10 # PHY4
hint.arge.0.mdio=mdioproxy1 # .. off of the switch mdiobus
# arge1 - GMII, 1000/full
hint.arge.1.phymask=0x0 # No directly mapped PHYs
hint.arge.1.media=1000
hint.arge.1.fduplex=1
# Where the ART is - last 64k in the flash
# 0x9fff1000 ?
hint.ath.0.eepromaddr=0x1fff0000
hint.ath.0.eepromsize=16384
# The board 16MiB flash layout in uboot env:
#
# 256k (uboot), 64k (uboot-env), 14336k (rootfs), 1600k (kernel), 64k (NVRAM), 64k (ART)
# However, it boots from 0x9f050000, which is the front of the flsah!
# Thus the kernel/rootfs are switched around.
# 256KB
hint.map.0.at="flash/spi0"
hint.map.0.start=0x00000000
hint.map.0.end=0x000040000
hint.map.0.name="uboot"
hint.map.0.readonly=1
# 64KB
hint.map.1.at="flash/spi0"
hint.map.1.start=0x00040000
hint.map.1.end=0x00050000
hint.map.1.name="uboot-env"
hint.map.1.readonly=0
# 1600KB
hint.map.2.at="flash/spi0"
hint.map.2.start=0x00050000
hint.map.2.end=0x001e0000
hint.map.2.name="kernel"
hint.map.2.readonly=0
# 14336KB
hint.map.3.at="flash/spi0"
hint.map.3.start=0x001e0000
hint.map.3.end=0x00fe0000
hint.map.3.name="rootfs"
hint.map.3.readonly=0
# NVRAM
hint.map.4.at="flash/spi0"
hint.map.4.start=0x00fe0000
hint.map.4.end=0x00ff0000
hint.map.4.name="cfg"
hint.map.4.readonly=0
# This is radio calibration section. It is (or should be!) unique
# for each board, to take into account thermal and electrical differences
# as well as the regulatory compliance data.
#
hint.map.5.at="flash/spi0"
hint.map.5.start=0x00ff0000
hint.map.5.end=0x01000000
hint.map.5.name="art"
hint.map.5.readonly=1
# GPIO specific configuration block
# Don't flip on anything that isn't already enabled.
# This includes leaving the SPI CS1/CS2 pins as GPIO pins as they're
# not used here.
hint.gpio.0.function_set=0x00000000
hint.gpio.0.function_clear=0x00000000
# These are the GPIO LEDs and buttons which can be software controlled.
#hint.gpio.0.pinmask=0x001c02ae
#hint.gpio.0.pinmask=0x00001803
# XXX TODO: the button and LEDs!

View File

@ -1,26 +0,0 @@
# $FreeBSD$
#
# Altera JTAG UARTs configured for console, debugging, and data putput on the
# BERI simulator.
#
hint.altera_jtag_uart.0.at="nexus0"
hint.altera_jtag_uart.0.maddr=0x7f000000
hint.altera_jtag_uart.0.msize=0x40
hint.altera_jtag_uart.0.irq=0
hint.altera_jtag_uart.1.at="nexus0"
hint.altera_jtag_uart.1.maddr=0x7f001000
hint.altera_jtag_uart.1.msize=0x40
hint.altera_jtag_uart.2.at="nexus0"
hint.altera_jtag_uart.2.maddr=0x7f002000
hint.altera_jtag_uart.2.msize=0x40
#
# On-board DE4 and tPad SD Card IP core -- also present in Bluespec
# simulation.
#
hint.altera_sdcardc.0.at="nexus0"
hint.altera_sdcardc.0.maddr=0x7f008000
hint.altera_sdcardc.0.msize=0x400

View File

@ -56,19 +56,30 @@ typedef pt_entry_t *pd_entry_t;
#define TLBMASK_MASK ((PAGE_MASK >> TLBMASK_SHIFT) << TLBMASK_SHIFT)
/*
* PFN for EntryLo register. Upper bits are 0, which is to say that
* bit 28 is the last hardware bit; Bits 29 and upwards (EntryLo is
* 64 bit though it can be referred to in 32-bits providing 3 software
* bits safely. We use it as 64 bits to get many software bits, and
* god knows what else.) are unacknowledged by hardware. They may be
* written as anything, but otherwise they have as much meaning as
* other 0 fields.
* FreeBSD/mips page-table entries take a near-identical format to MIPS TLB
* entries, each consisting of two 32-bit or 64-bit values ("EntryHi" and
* "EntryLo"). MIPS4k and MIPS64 both define certain bits in TLB entries as
* reserved, and these must be zero-filled by software. We overload these
* bits in PTE entries to hold PTE_ flags such as RO, W, and MANAGED.
* However, we must mask these out when writing to TLB entries to ensure that
* they do not become visible to hardware -- especially on MIPS64r2 which has
* an extended physical memory space.
*
* When using n64 and n32, shift software-defined bits into the MIPS64r2
* reserved range, which runs from bit 55 ... 63. In other configurations
* (32-bit MIPS4k and compatible), shift them out to bits 29 ... 31.
*
* NOTE: This means that for 32-bit use of CP0, we aren't able to set the top
* bit of PFN to a non-zero value, as software is using it! This physical
* memory size limit may not be sufficiently enforced elsewhere.
*/
#if defined(__mips_n64) || defined(__mips_n32) /* PHYSADDR_64_BIT */
#define TLBLO_SWBITS_SHIFT (34)
#define TLBLO_SWBITS_SHIFT (55)
#define TLBLO_SWBITS_CLEAR_SHIFT (9)
#define TLBLO_PFN_MASK 0x3FFFFFFC0ULL
#else
#define TLBLO_SWBITS_SHIFT (29)
#define TLBLO_SWBITS_CLEAR_SHIFT (3)
#define TLBLO_PFN_MASK (0x1FFFFFC0)
#endif
#define TLBLO_PFN_SHIFT (6)
@ -133,6 +144,9 @@ typedef pt_entry_t *pd_entry_t;
* listen to requests to write to it.
* W: Wired. ???
* MANAGED:Managed. This PTE maps a managed page.
*
* These bits should not be written into the TLB, so must first be masked out
* explicitly in C, or using CLEAR_PTE_SWBITS() in assembly.
*/
#define PTE_RO ((pt_entry_t)0x01 << TLBLO_SWBITS_SHIFT)
#define PTE_W ((pt_entry_t)0x02 << TLBLO_SWBITS_SHIFT)
@ -162,7 +176,7 @@ typedef pt_entry_t *pd_entry_t;
#define PTESIZE 4
#define PTE_L lw
#define PTE_MTC0 mtc0
#define CLEAR_PTE_SWBITS(r) sll r, 3; srl r, 3 /* remove 3 high bits */
#define CLEAR_PTE_SWBITS(r) LONG_SLL r, TLBLO_SWBITS_CLEAR_SHIFT; LONG_SRL r, TLBLO_SWBITS_CLEAR_SHIFT /* remove swbits */
#endif /* defined(__mips_n64) || defined(__mips_n32) */
#if defined(__mips_n64)

View File

@ -9,7 +9,6 @@ SUBDIR= dtmalloc \
dtrace \
dtraceall \
dtrace_test \
dtio \
lockstat \
profile \
prototype \

View File

@ -1,15 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../kern
KMOD= dtio
SRCS= dtio_kdtrace.c \
vnode_if.h
CFLAGS+= -I${.CURDIR}/../../../cddl/compat/opensolaris \
-I${.CURDIR}/../../../cddl/contrib/opensolaris/uts/common \
-I${.CURDIR}/../../..
.include <bsd.kmod.mk>
CFLAGS+= -include ${.CURDIR}/../../../cddl/compat/opensolaris/sys/debug_compat.h

View File

@ -66,7 +66,6 @@ MODULE_VERSION(dtraceall, 1);
MODULE_DEPEND(dtraceall, cyclic, 1, 1, 1);
MODULE_DEPEND(dtraceall, opensolaris, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtrace, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtio, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);
MODULE_DEPEND(dtraceall, dtnfscl, 1, 1, 1);
#if defined(NFSCLIENT)

View File

@ -205,7 +205,7 @@ vmnet_clone_create(struct if_clone *ifc, int unit, caddr_t params)
i = clone_create(&tapclones, &tap_cdevsw, &unit, &dev, VMNET_DEV_MASK);
if (i) {
dev = make_dev(&tap_cdevsw, unit | VMNET_DEV_MASK, UID_ROOT,
GID_WHEEL, 0600, "%s%d", tapname, unit);
GID_WHEEL, 0600, "%s%d", vmnetname, unit);
}
tapcreate(dev);

View File

@ -2732,20 +2732,35 @@ ieee80211_alloc_cts(struct ieee80211com *ic,
static void
ieee80211_tx_mgt_timeout(void *arg)
{
struct ieee80211_node *ni = arg;
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211vap *vap = arg;
IEEE80211_LOCK(vap->iv_ic);
if (vap->iv_state != IEEE80211_S_INIT &&
(vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0) {
/*
* NB: it's safe to specify a timeout as the reason here;
* it'll only be used in the right state.
*/
ieee80211_new_state(vap, IEEE80211_S_SCAN,
ieee80211_new_state_locked(vap, IEEE80211_S_SCAN,
IEEE80211_SCAN_FAIL_TIMEOUT);
}
IEEE80211_UNLOCK(vap->iv_ic);
}
/*
* This is the callback set on net80211-sourced transmitted
* authentication request frames.
*
* This does a couple of things:
*
* + If the frame transmitted was a success, it schedules a future
* event which will transition the interface to scan.
* If a state transition _then_ occurs before that event occurs,
* said state transition will cancel this callout.
*
* + If the frame transmit was a failure, it immediately schedules
* the transition back to scan.
*/
static void
ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status)
{
@ -2763,10 +2778,11 @@ ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status)
*
* XXX what happens if !acked but response shows up before callback?
*/
if (vap->iv_state == ostate)
if (vap->iv_state == ostate) {
callout_reset(&vap->iv_mgtsend,
status == 0 ? IEEE80211_TRANS_WAIT*hz : 0,
ieee80211_tx_mgt_timeout, ni);
ieee80211_tx_mgt_timeout, vap);
}
}
static void

View File

@ -107,8 +107,6 @@ static void update_promisc(void *, int);
static void update_channel(void *, int);
static void update_chw(void *, int);
static void ieee80211_newstate_cb(void *, int);
static int ieee80211_new_state_locked(struct ieee80211vap *,
enum ieee80211_state, int);
static int
null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
@ -1834,7 +1832,7 @@ done:
* is usually a mistake and indicates lack of proper integration
* with the net80211 layer.
*/
static int
int
ieee80211_new_state_locked(struct ieee80211vap *vap,
enum ieee80211_state nstate, int arg)
{

View File

@ -332,6 +332,8 @@ void ieee80211_dturbo_switch(struct ieee80211vap *, int newflags);
void ieee80211_swbmiss(void *arg);
void ieee80211_beacon_miss(struct ieee80211com *);
int ieee80211_new_state(struct ieee80211vap *, enum ieee80211_state, int);
int ieee80211_new_state_locked(struct ieee80211vap *, enum ieee80211_state,
int);
void ieee80211_print_essid(const uint8_t *, int);
void ieee80211_dump_pkt(struct ieee80211com *,
const uint8_t *, int, int, int);

View File

@ -1227,6 +1227,7 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated)
mtu = IPV6_MMTU - 8;
bzero(&inc, sizeof(inc));
inc.inc_fibnum = M_GETFIB(m);
inc.inc_flags |= INC_ISIPV6;
inc.inc6_faddr = *dst;
if (in6_setscope(&inc.inc6_faddr, m->m_pkthdr.rcvif, NULL))

View File

@ -188,6 +188,25 @@ bare_timebase_freq(platform_t plat, struct cpuref *cpuref)
if ((child = OF_child(cpus)) == 0)
goto out;
switch (OF_getproplen(child, "timebase-frequency")) {
case 4:
{
uint32_t tbase;
OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
ticks = tbase;
return (ticks);
}
case 8:
{
uint64_t tbase;
OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
ticks = tbase;
return (ticks);
}
default:
break;
}
freq = 0;
if (OF_getprop(child, "bus-frequency", (void *)&freq,
sizeof(freq)) <= 0)

View File

@ -56,5 +56,6 @@ int powerpc_setup_intr(const char *, u_int, driver_filter_t, driver_intr_t,
int powerpc_teardown_intr(void *);
int powerpc_bind_intr(u_int irq, u_char cpu);
int powerpc_config_intr(int, enum intr_trigger, enum intr_polarity);
int powerpc_fw_config_intr(int irq, int sense_code);
#endif /* _MACHINE_INTR_MACHDEP_H_ */

View File

@ -79,6 +79,9 @@ static void atpic_ipi(device_t, u_int);
static void atpic_mask(device_t, u_int);
static void atpic_unmask(device_t, u_int);
static void atpic_ofw_translate_code(device_t, u_int irq, int code,
enum intr_trigger *trig, enum intr_polarity *pol);
static device_method_t atpic_isa_methods[] = {
/* Device interface */
DEVMETHOD(device_identify, atpic_isa_identify),
@ -94,6 +97,8 @@ static device_method_t atpic_isa_methods[] = {
DEVMETHOD(pic_mask, atpic_mask),
DEVMETHOD(pic_unmask, atpic_unmask),
DEVMETHOD(pic_translate_code, atpic_ofw_translate_code),
{ 0, 0 },
};
@ -325,3 +330,35 @@ atpic_unmask(device_t dev, u_int irq)
atpic_write(sc, ATPIC_MASTER, 1, sc->sc_mask[ATPIC_MASTER]);
}
}
static void
atpic_ofw_translate_code(device_t dev, u_int irq, int code,
enum intr_trigger *trig, enum intr_polarity *pol)
{
switch (code) {
case 0:
/* Active L level */
*trig = INTR_TRIGGER_LEVEL;
*pol = INTR_POLARITY_LOW;
break;
case 1:
/* Active H level */
*trig = INTR_TRIGGER_LEVEL;
*pol = INTR_POLARITY_HIGH;
break;
case 2:
/* H to L edge */
*trig = INTR_TRIGGER_EDGE;
*pol = INTR_POLARITY_LOW;
break;
case 3:
/* L to H edge */
*trig = INTR_TRIGGER_EDGE;
*pol = INTR_POLARITY_HIGH;
break;
default:
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
}
}

View File

@ -272,7 +272,7 @@ ofw_pci_route_interrupt(device_t bus, device_t dev, int pin)
if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, &reg,
sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr),
&iparent, maskbuf))
return (MAP_IRQ(iparent, mintr));
return (ofw_bus_map_intr(dev, iparent, mintr));
/* Maybe it's a real interrupt, not an intpin */
if (pin > 4)

View File

@ -157,7 +157,7 @@ ofw_pcib_pci_route_interrupt(device_t bridge, device_t dev, int intpin)
* it again on higher levels - that causes problems
* in some cases, and never seems to be required.
*/
return (MAP_IRQ(iparent, mintr));
return (ofw_bus_map_intr(dev, iparent, mintr));
}
} else if (intpin >= 1 && intpin <= 4) {
/*

View File

@ -218,15 +218,13 @@ ofw_pcibus_enum_devtree(device_t dev, u_int domain, u_int busno)
OF_getprop(OF_xref_phandle(iparent),
"#interrupt-cells", &icells,
sizeof(icells));
intr[0] = MAP_IRQ(iparent, intr[0]);
intr[0] = ofw_bus_map_intr(dev, iparent,
intr[0]);
}
if (iparent != 0 && icells > 1) {
powerpc_config_intr(intr[0],
(intr[1] & 1) ? INTR_TRIGGER_LEVEL :
INTR_TRIGGER_EDGE,
INTR_POLARITY_LOW);
}
if (iparent != 0 && icells > 1)
ofw_bus_config_intr(dev, intr[0],
intr[1]);
resource_list_add(&dinfo->opd_dinfo.resources,
SYS_RES_IRQ, 0, intr[0], intr[0], 1);
@ -343,12 +341,13 @@ ofw_pcibus_assign_interrupt(device_t dev, device_t child)
isz = OF_getprop(node, "AAPL,interrupts", &intr, sizeof(intr));
if (isz == sizeof(intr))
return ((iparent == -1) ? intr : MAP_IRQ(iparent, intr));
return ((iparent == -1) ? intr : ofw_bus_map_intr(dev, iparent,
intr));
isz = OF_getprop(node, "interrupts", &intr, sizeof(intr));
if (isz == sizeof(intr)) {
if (iparent != -1)
intr = MAP_IRQ(iparent, intr);
intr = ofw_bus_map_intr(dev, iparent, intr);
} else {
/* No property: our best guess is the intpin. */
intr = pci_get_intpin(child);

View File

@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
static int openpic_ofw_probe(device_t);
static int openpic_ofw_attach(device_t);
static void openpic_ofw_translate_code(device_t, u_int irq, int code,
enum intr_trigger *trig, enum intr_polarity *pol);
static device_method_t openpic_ofw_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, openpic_ofw_probe),
@ -76,6 +79,8 @@ static device_method_t openpic_ofw_methods[] = {
DEVMETHOD(pic_mask, openpic_mask),
DEVMETHOD(pic_unmask, openpic_unmask),
DEVMETHOD(pic_translate_code, openpic_ofw_translate_code),
DEVMETHOD_END
};
@ -127,3 +132,34 @@ openpic_ofw_attach(device_t dev)
return (openpic_common_attach(dev, xref));
}
static void
openpic_ofw_translate_code(device_t dev, u_int irq, int code,
enum intr_trigger *trig, enum intr_polarity *pol)
{
switch (code) {
case 0:
/* L to H edge */
*trig = INTR_TRIGGER_EDGE;
*pol = INTR_POLARITY_HIGH;
break;
case 1:
/* Active L level */
*trig = INTR_TRIGGER_LEVEL;
*pol = INTR_POLARITY_LOW;
break;
case 2:
/* Active H level */
*trig = INTR_TRIGGER_LEVEL;
*pol = INTR_POLARITY_HIGH;
break;
case 3:
/* H to L edge */
*trig = INTR_TRIGGER_EDGE;
*pol = INTR_POLARITY_LOW;
break;
default:
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
}
}

View File

@ -68,6 +68,8 @@ struct pmac_fan_le {
struct pmac_sens_le {
struct pmac_therm *sensor;
int last_val;
#define MAX_CRITICAL_COUNT 6
int critical_count;
SLIST_ENTRY(pmac_sens_le) entries;
};
static SLIST_HEAD(pmac_fans, pmac_fan_le) fans = SLIST_HEAD_INITIALIZER(fans);
@ -106,14 +108,27 @@ pmac_therm_manage_fans(void)
sensor->last_val = temp;
if (sensor->last_val > sensor->sensor->max_temp) {
sensor->critical_count++;
printf("WARNING: Current temperature (%s: %d.%d C) "
"exceeds critical temperature (%d.%d C)! "
"Shutting down!\n", sensor->sensor->name,
(sensor->last_val - ZERO_C_TO_K) / 10,
(sensor->last_val - ZERO_C_TO_K) % 10,
(sensor->sensor->max_temp - ZERO_C_TO_K) / 10,
(sensor->sensor->max_temp - ZERO_C_TO_K) % 10);
shutdown_nice(RB_POWEROFF);
"exceeds critical temperature (%d.%d C); "
"count=%d\n",
sensor->sensor->name,
(sensor->last_val - ZERO_C_TO_K) / 10,
(sensor->last_val - ZERO_C_TO_K) % 10,
(sensor->sensor->max_temp - ZERO_C_TO_K) / 10,
(sensor->sensor->max_temp - ZERO_C_TO_K) % 10,
sensor->critical_count);
if (sensor->critical_count >= MAX_CRITICAL_COUNT) {
printf("WARNING: %s temperature exceeded "
"critical temperature %d times in a row; "
"shutting down!\n",
sensor->sensor->name,
sensor->critical_count);
shutdown_nice(RB_POWEROFF);
}
} else {
if (sensor->critical_count > 0)
sensor->critical_count--;
}
}
@ -177,6 +192,8 @@ pmac_thermal_sensor_register(struct pmac_therm *sensor)
list_entry = malloc(sizeof(struct pmac_sens_le), M_PMACTHERM,
M_ZERO | M_WAITOK);
list_entry->sensor = sensor;
list_entry->last_val = 0;
list_entry->critical_count = 0;
SLIST_INSERT_HEAD(&sensors, list_entry, entries);
}

View File

@ -102,6 +102,7 @@ struct powerpc_intr {
cpuset_t cpu;
enum intr_trigger trig;
enum intr_polarity pol;
int fwcode;
};
struct pic {
@ -427,6 +428,9 @@ powerpc_enable_intr(void)
if (error)
continue;
if (i->trig == -1)
PIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode,
&i->trig, &i->pol);
if (i->trig != INTR_TRIGGER_CONFORM ||
i->pol != INTR_POLARITY_CONFORM)
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
@ -469,15 +473,21 @@ powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
if (!cold) {
error = powerpc_map_irq(i);
if (!error && (i->trig != INTR_TRIGGER_CONFORM ||
i->pol != INTR_POLARITY_CONFORM))
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
if (!error) {
if (i->trig == -1)
PIC_TRANSLATE_CODE(i->pic, i->intline,
i->fwcode, &i->trig, &i->pol);
if (!error && i->pic == root_pic)
PIC_BIND(i->pic, i->intline, i->cpu);
if (i->trig != INTR_TRIGGER_CONFORM ||
i->pol != INTR_POLARITY_CONFORM)
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
if (!error && enable)
PIC_ENABLE(i->pic, i->intline, i->vector);
if (i->pic == root_pic)
PIC_BIND(i->pic, i->intline, i->cpu);
if (enable)
PIC_ENABLE(i->pic, i->intline, i->vector);
}
}
return (error);
}
@ -503,6 +513,28 @@ powerpc_bind_intr(u_int irq, u_char cpu)
}
#endif
int
powerpc_fw_config_intr(int irq, int sense_code)
{
struct powerpc_intr *i;
i = intr_lookup(irq);
if (i == NULL)
return (ENOMEM);
i->trig = -1;
i->pol = INTR_POLARITY_CONFORM;
i->fwcode = sense_code;
if (!cold && i->pic != NULL) {
PIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode, &i->trig,
&i->pol);
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol);
}
return (0);
}
int
powerpc_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol)
{

View File

@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/ofw_nexus.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
@ -63,260 +64,45 @@ __FBSDID("$FreeBSD$");
*
* Additionally, interrupt setup/teardown and some resource management are
* done at this level.
*
* Maybe this code should get into dev/ofw to some extent, as some of it should
* work for all Open Firmware based machines...
*/
struct nexus_devinfo {
struct ofw_bus_devinfo ndi_obdinfo;
struct resource_list ndi_rl;
};
struct nexus_softc {
uint32_t acells, scells;
struct rman sc_intr_rman;
struct rman sc_mem_rman;
};
static device_probe_t nexus_probe;
static device_attach_t nexus_attach;
static bus_print_child_t nexus_print_child;
static bus_add_child_t nexus_add_child;
static bus_probe_nomatch_t nexus_probe_nomatch;
static bus_setup_intr_t nexus_setup_intr;
static bus_teardown_intr_t nexus_teardown_intr;
static bus_alloc_resource_t nexus_alloc_resource;
static bus_activate_resource_t nexus_activate_resource;
static bus_deactivate_resource_t nexus_deactivate_resource;
static bus_adjust_resource_t nexus_adjust_resource;
static bus_release_resource_t nexus_release_resource;
static bus_get_resource_list_t nexus_get_resource_list;
#ifdef SMP
static bus_bind_intr_t nexus_bind_intr;
#endif
static bus_config_intr_t nexus_config_intr;
static ofw_bus_get_devinfo_t nexus_get_devinfo;
static int nexus_inlist(const char *, const char *const *);
static struct nexus_devinfo * nexus_setup_dinfo(device_t, phandle_t);
static void nexus_destroy_dinfo(struct nexus_devinfo *);
static int nexus_print_res(struct nexus_devinfo *);
static ofw_bus_map_intr_t nexus_ofw_map_intr;
static ofw_bus_config_intr_t nexus_ofw_config_intr;
static device_method_t nexus_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, nexus_probe),
DEVMETHOD(device_attach, nexus_attach),
DEVMETHOD(device_detach, bus_generic_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
/* Bus interface */
DEVMETHOD(bus_print_child, nexus_print_child),
DEVMETHOD(bus_probe_nomatch, nexus_probe_nomatch),
DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
DEVMETHOD(bus_add_child, nexus_add_child),
DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str),
DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
DEVMETHOD(bus_adjust_resource, nexus_adjust_resource),
DEVMETHOD(bus_release_resource, nexus_release_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
DEVMETHOD(bus_get_resource_list, nexus_get_resource_list),
#ifdef SMP
DEVMETHOD(bus_bind_intr, nexus_bind_intr),
#endif
DEVMETHOD(bus_config_intr, nexus_config_intr),
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_devinfo, nexus_get_devinfo),
DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
DEVMETHOD(ofw_bus_map_intr, nexus_ofw_map_intr),
DEVMETHOD(ofw_bus_config_intr, nexus_ofw_config_intr),
DEVMETHOD_END
};
static devclass_t nexus_devclass;
DEFINE_CLASS_0(nexus, nexus_driver, nexus_methods, sizeof(struct nexus_softc));
DEFINE_CLASS_1(nexus, nexus_driver, nexus_methods,
sizeof(struct ofw_nexus_softc), ofw_nexus_driver);
EARLY_DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0,
BUS_PASS_BUS);
MODULE_VERSION(nexus, 1);
static const char *const nexus_excl_name[] = {
"FJSV,system",
"aliases",
"associations",
"chosen",
"cmp",
"counter-timer", /* No separate device; handled by psycho/sbus */
"failsafe",
"memory",
"openprom",
"options",
"packages",
"physical-memory",
"rsc",
"sgcn",
"todsg",
"virtual-memory",
NULL
};
static const char *const nexus_excl_type[] = {
"core",
"cpu",
NULL
};
extern struct bus_space_tag nexus_bustag;
extern struct bus_dma_tag nexus_dmatag;
static int
nexus_inlist(const char *name, const char *const *list)
{
int i;
if (name == NULL)
return (0);
for (i = 0; list[i] != NULL; i++)
if (strcmp(name, list[i]) == 0)
return (1);
return (0);
}
#define NEXUS_EXCLUDED(name, type) \
(nexus_inlist((name), nexus_excl_name) || \
((type) != NULL && nexus_inlist((type), nexus_excl_type)))
static int
nexus_probe(device_t dev)
{
/* Nexus does always match. */
device_set_desc(dev, "Open Firmware Nexus device");
return (0);
}
static int
nexus_attach(device_t dev)
{
struct nexus_devinfo *ndi;
struct nexus_softc *sc;
device_t cdev;
phandle_t node;
sc = device_get_softc(dev);
if (strcmp(device_get_name(device_get_parent(dev)), "root") == 0) {
node = OF_peer(0);
sc->sc_intr_rman.rm_type = RMAN_ARRAY;
sc->sc_intr_rman.rm_descr = "Interrupts";
sc->sc_mem_rman.rm_type = RMAN_ARRAY;
sc->sc_mem_rman.rm_descr = "Device Memory";
if (rman_init(&sc->sc_intr_rman) != 0 ||
rman_init(&sc->sc_mem_rman) != 0 ||
rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0 ||
rman_manage_region(&sc->sc_mem_rman, 0, BUS_SPACE_MAXADDR)
!= 0)
panic("%s: failed to set up rmans.", __func__);
} else
node = ofw_bus_get_node(dev);
/*
* Allow devices to identify.
*/
bus_generic_probe(dev);
/*
* If no Open Firmware, bail early
*/
if (node == -1)
return (bus_generic_attach(dev));
/*
* Some important numbers
*/
sc->acells = 2;
OF_getprop(node, "#address-cells", &sc->acells, sizeof(sc->acells));
sc->scells = 1;
OF_getprop(node, "#size-cells", &sc->scells, sizeof(sc->scells));
/*
* Now walk the OFW tree and attach top-level devices.
*/
for (node = OF_child(node); node > 0; node = OF_peer(node)) {
if ((ndi = nexus_setup_dinfo(dev, node)) == NULL)
continue;
cdev = device_add_child(dev, NULL, -1);
if (cdev == NULL) {
device_printf(dev, "<%s>: device_add_child failed\n",
ndi->ndi_obdinfo.obd_name);
nexus_destroy_dinfo(ndi);
continue;
}
device_set_ivars(cdev, ndi);
}
return (bus_generic_attach(dev));
}
static device_t
nexus_add_child(device_t dev, u_int order, const char *name, int unit)
{
device_t cdev;
struct nexus_devinfo *ndi;
cdev = device_add_child_ordered(dev, order, name, unit);
if (cdev == NULL)
return (NULL);
ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
ndi->ndi_obdinfo.obd_node = -1;
resource_list_init(&ndi->ndi_rl);
device_set_ivars(cdev, ndi);
return (cdev);
}
static int
nexus_print_child(device_t bus, device_t child)
{
int rv;
rv = bus_print_child_header(bus, child);
rv += nexus_print_res(device_get_ivars(child));
rv += bus_print_child_footer(bus, child);
return (rv);
}
static void
nexus_probe_nomatch(device_t bus, device_t child)
{
const char *name, *type;
if (!bootverbose)
return;
name = ofw_bus_get_name(child);
type = ofw_bus_get_type(child);
device_printf(bus, "<%s>",
name != NULL ? name : "unknown");
nexus_print_res(device_get_ivars(child));
printf(" type %s (no driver attached)\n",
type != NULL ? type : "unknown");
}
static int
nexus_setup_intr(device_t bus __unused, device_t child, struct resource *r,
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
@ -370,68 +156,17 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
return (powerpc_config_intr(irq, trig, pol));
}
static struct resource *
nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int irq)
{
struct nexus_softc *sc;
struct rman *rm;
struct resource *rv;
struct resource_list_entry *rle;
device_t nexus;
int isdefault, passthrough;
return (MAP_IRQ(iparent, irq));
}
isdefault = (start == 0UL && end == ~0UL);
passthrough = (device_get_parent(child) != bus);
nexus = bus;
while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
nexus = device_get_parent(nexus);
sc = device_get_softc(nexus);
rle = NULL;
static int
nexus_ofw_config_intr(device_t dev, device_t child, int irq, int sense)
{
if (!passthrough && isdefault) {
rle = resource_list_find(BUS_GET_RESOURCE_LIST(bus, child),
type, *rid);
if (rle == NULL)
return (NULL);
if (rle->res != NULL)
panic("%s: resource entry is busy", __func__);
start = rle->start;
count = ulmax(count, rle->count);
end = ulmax(rle->end, start + count - 1);
}
switch (type) {
case SYS_RES_IRQ:
rm = &sc->sc_intr_rman;
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
break;
default:
return (NULL);
}
rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
child);
if (rv == NULL)
return (NULL);
rman_set_rid(rv, *rid);
if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type,
*rid, rv) != 0) {
rman_release_resource(rv);
return (NULL);
}
if (!passthrough && rle != NULL) {
rle->res = rv;
rle->start = rman_get_start(rv);
rle->end = rman_get_end(rv);
rle->count = rle->end - rle->start + 1;
}
return (rv);
return (powerpc_fw_config_intr(irq, sense));
}
static int
@ -476,164 +211,3 @@ nexus_deactivate_resource(device_t bus __unused, device_t child __unused,
return (rman_deactivate_resource(r));
}
static int
nexus_adjust_resource(device_t bus, device_t child __unused, int type,
struct resource *r, u_long start, u_long end)
{
struct nexus_softc *sc;
struct rman *rm;
device_t nexus;
nexus = bus;
while (strcmp(device_get_name(device_get_parent(nexus)), "root") != 0)
nexus = device_get_parent(nexus);
sc = device_get_softc(nexus);
switch (type) {
case SYS_RES_IRQ:
rm = &sc->sc_intr_rman;
break;
case SYS_RES_MEMORY:
rm = &sc->sc_mem_rman;
break;
default:
return (EINVAL);
}
if (rm == NULL)
return (ENXIO);
if (rman_is_region_manager(r, rm) == 0)
return (EINVAL);
return (rman_adjust_resource(r, start, end));
}
static int
nexus_release_resource(device_t bus __unused, device_t child, int type,
int rid, struct resource *r)
{
int error;
if ((rman_get_flags(r) & RF_ACTIVE) != 0) {
error = bus_deactivate_resource(child, type, rid, r);
if (error)
return (error);
}
return (rman_release_resource(r));
}
static struct resource_list *
nexus_get_resource_list(device_t bus __unused, device_t child)
{
struct nexus_devinfo *ndi;
ndi = device_get_ivars(child);
return (&ndi->ndi_rl);
}
static const struct ofw_bus_devinfo *
nexus_get_devinfo(device_t bus __unused, device_t child)
{
struct nexus_devinfo *ndi;
ndi = device_get_ivars(child);
return (&ndi->ndi_obdinfo);
}
static struct nexus_devinfo *
nexus_setup_dinfo(device_t dev, phandle_t node)
{
struct nexus_softc *sc;
struct nexus_devinfo *ndi;
uint32_t *reg, *intr, icells;
uint64_t phys, size;
phandle_t iparent;
int i, j;
int nintr;
int nreg;
sc = device_get_softc(dev);
ndi = malloc(sizeof(*ndi), M_DEVBUF, M_WAITOK | M_ZERO);
if (ofw_bus_gen_setup_devinfo(&ndi->ndi_obdinfo, node) != 0) {
free(ndi, M_DEVBUF);
return (NULL);
}
if (NEXUS_EXCLUDED(ndi->ndi_obdinfo.obd_name,
ndi->ndi_obdinfo.obd_type)) {
ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
free(ndi, M_DEVBUF);
return (NULL);
}
resource_list_init(&ndi->ndi_rl);
nreg = OF_getprop_alloc(node, "reg", sizeof(*reg), (void **)&reg);
if (nreg == -1)
nreg = 0;
if (nreg % (sc->acells + sc->scells) != 0) {
if (bootverbose)
device_printf(dev, "Malformed reg property on <%s>\n",
ndi->ndi_obdinfo.obd_name);
nreg = 0;
}
for (i = 0; i < nreg; i += sc->acells + sc->scells) {
phys = size = 0;
for (j = 0; j < sc->acells; j++) {
phys <<= 32;
phys |= reg[i + j];
}
for (j = 0; j < sc->scells; j++) {
size <<= 32;
size |= reg[i + sc->acells + j];
}
/* Skip the dummy reg property of glue devices like ssm(4). */
if (size != 0)
resource_list_add(&ndi->ndi_rl, SYS_RES_MEMORY, i,
phys, phys + size - 1, size);
}
free(reg, M_OFWPROP);
nintr = OF_getprop_alloc(node, "interrupts", sizeof(*intr),
(void **)&intr);
if (nintr > 0) {
iparent = 0;
OF_searchprop(node, "interrupt-parent", &iparent,
sizeof(iparent));
OF_searchprop(iparent, "#interrupt-cells", &icells,
sizeof(icells));
for (i = 0; i < nintr; i+= icells) {
intr[i] = MAP_IRQ(iparent, intr[i]);
resource_list_add(&ndi->ndi_rl, SYS_RES_IRQ, i, intr[i],
intr[i], 1);
if (icells > 1) {
powerpc_config_intr(intr[i], (intr[i+1] & 1) ?
INTR_TRIGGER_LEVEL : INTR_TRIGGER_EDGE,
INTR_POLARITY_LOW);
}
}
free(intr, M_OFWPROP);
}
return (ndi);
}
static void
nexus_destroy_dinfo(struct nexus_devinfo *ndi)
{
resource_list_free(&ndi->ndi_rl);
ofw_bus_gen_destroy_devinfo(&ndi->ndi_obdinfo);
free(ndi, M_DEVBUF);
}
static int
nexus_print_res(struct nexus_devinfo *ndi)
{
int rv;
rv = 0;
rv += resource_list_print_type(&ndi->ndi_rl, "mem", SYS_RES_MEMORY,
"%#lx");
rv += resource_list_print_type(&ndi->ndi_rl, "irq", SYS_RES_IRQ,
"%ld");
return (rv);
}

View File

@ -33,12 +33,31 @@
INTERFACE pic;
CODE {
static pic_translate_code_t pic_translate_code_default;
static void pic_translate_code_default(device_t dev, u_int irq,
int code, enum intr_trigger *trig, enum intr_polarity *pol)
{
*trig = INTR_TRIGGER_CONFORM;
*pol = INTR_POLARITY_CONFORM;
}
};
METHOD void bind {
device_t dev;
u_int irq;
cpuset_t cpumask;
};
METHOD void translate_code {
device_t dev;
u_int irq;
int code;
enum intr_trigger *trig;
enum intr_polarity *pol;
} DEFAULT pic_translate_code_default;
METHOD void config {
device_t dev;
u_int irq;

View File

@ -156,7 +156,8 @@ vdevice_attach(device_t dev)
for (i = 0; i < nintr; i += icells) {
u_int irq = intr[i];
if (iparent != -1)
irq = MAP_IRQ(iparent, intr[i]);
irq = ofw_bus_map_intr(dev, iparent,
intr[i]);
resource_list_add(&dinfo->mdi_resources,
SYS_RES_IRQ, i, irq, irq, i);

View File

@ -58,7 +58,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* from: NetBSD: bus.h,v 1.58 2008/04/28 20:23:36 martin Exp
* from: NetBSD: bus.h,v 1.58 2008/04/28 20:23:36 martin Exp
* and
* from: FreeBSD: src/sys/alpha/include/bus.h,v 1.9 2001/01/09
*
@ -104,11 +104,7 @@ extern const int bus_stream_asi[];
struct bus_space_tag {
void *bst_cookie;
bus_space_tag_t bst_parent;
int bst_type;
void (*bst_bus_barrier)(bus_space_tag_t, bus_space_handle_t,
bus_size_t, bus_size_t, int);
};
/*
@ -131,23 +127,23 @@ int bus_space_map(bus_space_tag_t tag, bus_addr_t address, bus_size_t size,
void bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t size);
/* This macro finds the first "upstream" implementation of method `f' */
#define _BS_CALL(t,f) \
while (t->f == NULL) \
t = t->bst_parent; \
return (*(t)->f)
static __inline void
bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
bus_size_t s, int f)
bus_space_barrier(bus_space_tag_t t __unused, bus_space_handle_t h __unused,
bus_size_t o __unused, bus_size_t s __unused, int f __unused)
{
_BS_CALL(t, bst_bus_barrier)(t, h, o, s, f);
/*
* We have lots of alternatives depending on whether we're
* synchronizing loads with loads, loads with stores, stores
* with loads, or stores with stores. The only ones that seem
* generic are #Sync and #MemIssue. We use #Sync for safety.
*/
membar(Sync);
}
static __inline int
bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
bus_size_t s, bus_space_handle_t *hp)
bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t h,
bus_size_t o __unused, bus_size_t s __unused, bus_space_handle_t *hp)
{
*hp = h + o;

View File

@ -40,8 +40,7 @@ int sparc64_bus_mem_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size,
int flags, vm_offset_t vaddr, bus_space_handle_t *hp);
int sparc64_bus_mem_unmap(bus_space_tag_t tag, bus_space_handle_t handle,
bus_size_t size);
bus_space_tag_t sparc64_alloc_bus_tag(void *cookie,
struct bus_space_tag *ptag, int type, void *barrier);
bus_space_tag_t sparc64_alloc_bus_tag(void *cookie, int type);
bus_space_handle_t sparc64_fake_bustag(int space, bus_addr_t addr,
struct bus_space_tag *ptag);

View File

@ -756,12 +756,10 @@ fire_attach(device_t dev)
free(range, M_OFWPROP);
/* Allocate our tags. */
sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
sc->sc_mem_res[FIRE_PCI]), PCI_IO_BUS_SPACE, NULL);
sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, PCI_IO_BUS_SPACE);
if (sc->sc_pci_iot == NULL)
panic("%s: could not allocate PCI I/O tag", __func__);
sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
sc->sc_mem_res[FIRE_PCI]), PCI_CONFIG_BUS_SPACE, NULL);
sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, PCI_CONFIG_BUS_SPACE);
if (sc->sc_pci_cfgt == NULL)
panic("%s: could not allocate PCI configuration space tag",
__func__);
@ -2072,8 +2070,7 @@ fire_activate_resource(device_t bus, device_t child, int type, int rid,
return (bus_generic_activate_resource(bus, child, type, rid,
r));
case SYS_RES_MEMORY:
tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
sc->sc_mem_res[FIRE_PCI]), PCI_MEMORY_BUS_SPACE, NULL);
tag = sparc64_alloc_bus_tag(r, PCI_MEMORY_BUS_SPACE);
if (tag == NULL)
return (ENOMEM);
rman_set_bustag(r, tag);

View File

@ -573,12 +573,10 @@ psycho_attach(device_t dev)
}
/* Allocate our tags. */
sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
sc->sc_mem_res), PCI_IO_BUS_SPACE, NULL);
sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, PCI_IO_BUS_SPACE);
if (sc->sc_pci_iot == NULL)
panic("%s: could not allocate PCI I/O tag", __func__);
sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag(
sc->sc_mem_res), PCI_CONFIG_BUS_SPACE, NULL);
sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, PCI_CONFIG_BUS_SPACE);
if (sc->sc_pci_cfgt == NULL)
panic("%s: could not allocate PCI configuration space tag",
__func__);
@ -1236,8 +1234,7 @@ psycho_activate_resource(device_t bus, device_t child, int type, int rid,
return (bus_generic_activate_resource(bus, child, type, rid,
r));
case SYS_RES_MEMORY:
tag = sparc64_alloc_bus_tag(r, rman_get_bustag(
sc->sc_mem_res), PCI_MEMORY_BUS_SPACE, NULL);
tag = sparc64_alloc_bus_tag(r, PCI_MEMORY_BUS_SPACE);
if (tag == NULL)
return (ENOMEM);
rman_set_bustag(r, tag);

Some files were not shown because too many files have changed in this diff Show More