This commit is contained in:
attilio 2013-03-02 14:28:31 +00:00
commit 17028bb6ae
201 changed files with 6642 additions and 2274 deletions

View File

@ -26,6 +26,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
20130301:
The ctl device has been disabled in GENERIC for i386 and amd64.
This was done due to the extra memory being allocated at system
initialisation time by the ctl driver which was only used if
a CAM target device was created. This makes a FreeBSD system
unusable on 128MB or less of RAM.
20130208:
A new compression method (lz4) has been merged to -HEAD. Please
refer to zpool-features(7) for more information.
@ -46,8 +53,8 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
unlikely event that -M was the last option on the command line
and the command line contained at least two files and a target
directory the first file will have logs appended to it. The -M
option served little practical purpose in the last decade so it's
used expected to be extremely rare.
option served little practical purpose in the last decade so its
use is expected to be extremely rare.
20121223:
After switching to Clang as the default compiler some users of ZFS

View File

@ -526,6 +526,39 @@ if the snapshot has been marked for deferred destroy by using the
.Qq Nm Cm destroy -d
command. Otherwise, the property is
.Cm off .
.It Sy logicalreferenced
The amount of space that is
.Qq logically
accessible by this dataset.
See the
.Sy referenced
property.
The logical space ignores the effect of the
.Sy compression
and
.Sy copies
properties, giving a quantity closer to the amount of data that applications
see.
However, it does include space consumed by metadata.
.Pp
This property can also be referred to by its shortened column name,
.Sy lrefer .
.It Sy logicalused
The amount of space that is
.Qq logically
consumed by this dataset and all its descendents.
See the
.Sy used
property.
The logical space ignores the effect of the
.Sy compression
and
.Sy copies
properties, giving a quantity closer to the amount of data that applications
see.
.Pp
This property can also be referred to by its shortened column name,
.Sy lused .
.It Sy mounted
For file systems, indicates whether the file system is currently mounted. This
property can be either

View File

@ -24,6 +24,7 @@
* Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
*/
#ifndef _LIBFS_IMPL_H
@ -216,6 +217,7 @@ extern void libzfs_fru_clear(libzfs_handle_t *, boolean_t);
#ifndef sun
static int zfs_kernel_version = 0;
static int zfs_ioctl_version = 0;
/*
* This is FreeBSD version of ioctl, because Solaris' ioctl() updates
@ -225,19 +227,34 @@ static int zfs_kernel_version = 0;
static __inline int
zcmd_ioctl(int fd, unsigned long cmd, zfs_cmd_t *zc)
{
size_t oldsize, zfs_kernel_version_size;
size_t oldsize, zfs_kernel_version_size, zfs_ioctl_version_size;
int version, ret, cflag = ZFS_CMD_COMPAT_NONE;
zfs_kernel_version_size = sizeof(zfs_kernel_version);
if (zfs_kernel_version == 0) {
sysctlbyname("vfs.zfs.version.spa", &zfs_kernel_version,
&zfs_kernel_version_size, NULL, 0);
zfs_ioctl_version_size = sizeof(zfs_ioctl_version);
if (zfs_ioctl_version == 0) {
sysctlbyname("vfs.zfs.version.ioctl", &zfs_ioctl_version,
&zfs_ioctl_version_size, NULL, 0);
}
if (zfs_kernel_version == SPA_VERSION_15 ||
zfs_kernel_version == SPA_VERSION_14 ||
zfs_kernel_version == SPA_VERSION_13)
cflag = ZFS_CMD_COMPAT_V15;
/*
* If vfs.zfs.version.ioctl is not defined, assume we have v28
* compatible binaries and use vfs.zfs.version.spa to test for v15
*/
if (zfs_ioctl_version < ZFS_IOCVER_DEADMAN) {
cflag = ZFS_CMD_COMPAT_V28;
zfs_kernel_version_size = sizeof(zfs_kernel_version);
if (zfs_kernel_version == 0) {
sysctlbyname("vfs.zfs.version.spa",
&zfs_kernel_version,
&zfs_kernel_version_size, NULL, 0);
}
if (zfs_kernel_version == SPA_VERSION_15 ||
zfs_kernel_version == SPA_VERSION_14 ||
zfs_kernel_version == SPA_VERSION_13)
cflag = ZFS_CMD_COMPAT_V15;
}
oldsize = zc->zc_nvlist_dst_size;
ret = zcmd_ioctl_compat(fd, cmd, zc, cflag);

View File

@ -394,6 +394,7 @@ read_thread_wait(void)
mtx_lock(&adist_remote_mtx);
if (adhost->adh_reset) {
reset:
adhost->adh_reset = false;
if (trail_filefd(adist_trail) != -1)
trail_close(adist_trail);
@ -408,6 +409,14 @@ read_thread_wait(void)
while (trail_filefd(adist_trail) == -1) {
newfile = true;
wait_for_dir();
/*
* We may have been disconnected and reconnected in the
* meantime, check if reset is set.
*/
mtx_lock(&adist_remote_mtx);
if (adhost->adh_reset)
goto reset;
mtx_unlock(&adist_remote_mtx);
if (trail_filefd(adist_trail) == -1)
trail_next(adist_trail);
}

View File

@ -548,7 +548,7 @@
43184:AUE_OPENAT:openat(2) - attr only:fa
43185:AUE_POSIX_OPENPT:posix_openpt(2):ip
43186:AUE_CAP_NEW:cap_new(2):fm
43187:AUE_CAP_GETRIGHTS:cap_getrights(2):fm
43187:AUE_CAP_RIGHTS_GET:cap_rights_get(2):fm
43188:AUE_CAP_ENTER:cap_enter(2):pc
43189:AUE_CAP_GETMODE:cap_getmode(2):pc
43190:AUE_POSIX_SPAWN:posix_spawn(2):pc
@ -563,6 +563,11 @@
43199:AUE_PDGETPID:pdgetpid(2):pc
43200:AUE_PDWAIT:pdwait(2):pc
43201:AUE_WAIT6:wait6(2):pc
43202:AUE_CAP_RIGHTS_LIMIT:cap_rights_limit(2):fm
43203:AUE_CAP_IOCTLS_LIMIT:cap_ioctls_limit(2):fm
43204:AUE_CAP_IOCTLS_GET:cap_ioctls_get(2):fm
43205:AUE_CAP_FCNTLS_LIMIT:cap_fcntls_limit(2):fm
43206:AUE_CAP_FCNTLS_GET:cap_fcntls_get(2):fm
#
# Solaris userspace events.
#

View File

@ -16,6 +16,7 @@ SRCS+= __getosreldate.c \
assert.c \
auxv.c \
basename.c \
cap_sandboxed.c \
check_utility_compat.c \
clock.c \
clock_getcpuclockid.c \
@ -168,6 +169,7 @@ SYM_MAPS+=${.CURDIR}/gen/Symbol.map
MAN+= alarm.3 \
arc4random.3 \
basename.3 \
cap_sandboxed.3 \
check_utility_compat.3 \
clock.3 \
clock_getcpuclockid.3 \

View File

@ -0,0 +1,70 @@
.\" Copyright (c) 2012 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This documentation was written by Pawel Jakub Dawidek 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, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd September 18, 2012
.Dt CAP_SANDBOXED 3
.Os
.Sh NAME
.Nm cap_sandboxed
.Nd Check if in a capability mode sandbox
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/capability.h
.In stdbool.h
.Ft bool
.Fn cap_sandboxed "void"
.Sh DESCRIPTION
.Fn cap_sandboxed
returns
.Va true
if the process is in a capability mode sandbox or
.Va false
if it is not.
This function is a more handy alternative to the
.Xr cap_getmode 2
system call as it always succeeds, so there is no need for error checking.
If the support for capability mode is not compiled into the kernel,
.Fn cap_sandboxed
will always return
.Va false .
.Sh RETURN VALUES
Function
.Fn cap_sandboxed
is always successful and will return either
.Va true
or
.Va false .
.Sh SEE ALSO
.Xr cap_enter 2 ,
.Xr capsicum 4
.Sh AUTHORS
This function was implemented and manual page was written by
.An Pawel Jakub Dawidek Aq pawel@dawidek.net
under sponsorship of the FreeBSD Foundation.

View File

@ -0,0 +1,50 @@
/*-
* Copyright (c) 2012 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek 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, 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 AUTHORS 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 AUTHORS 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/capability.h>
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
bool
cap_sandboxed(void)
{
u_int mode;
if (cap_getmode(&mode) != 0) {
assert(errno == ENOSYS);
return (false);
}
assert(mode == 0 || mode == 1);
return (mode == 1);
}

View File

@ -42,6 +42,8 @@ __sym_compat(__semctl, freebsd7___semctl, FBSD_1.0);
__sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0);
__sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0);
__sym_compat(cap_getrights, cap_rights_get, FBSD_1.2);
#undef __sym_compat
#endif /* __LIBC_COMPAT_H__ */

View File

@ -1212,7 +1212,7 @@ CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max)
}
cs->ranges = newranges;
cs->ranges[cs->nranges].min = min;
cs->ranges[cs->nranges].min = max;
cs->ranges[cs->nranges].max = max;
cs->nranges++;
}

View File

@ -260,7 +260,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
if (ct->ct_addr.buf == NULL)
goto err;
memcpy(ct->ct_addr.buf, raddr->buf, raddr->len);
ct->ct_addr.len = raddr->maxlen;
ct->ct_addr.len = raddr->len;
ct->ct_addr.maxlen = raddr->maxlen;
/*

View File

@ -93,7 +93,9 @@ MAN+= abort2.2 \
bind.2 \
brk.2 \
cap_enter.2 \
cap_new.2 \
cap_fcntls_limit.2 \
cap_ioctls_limit.2 \
cap_rights_limit.2 \
chdir.2 \
chflags.2 \
chmod.2 \
@ -270,7 +272,9 @@ MLINKS+=access.2 eaccess.2 \
access.2 faccessat.2
MLINKS+=brk.2 sbrk.2
MLINKS+=cap_enter.2 cap_getmode.2
MLINKS+=cap_new.2 cap_getrights.2
MLINKS+=cap_fcntls_limit.2 cap_fcntls_get.2
MLINKS+=cap_ioctls_limit.2 cap_ioctls_get.2
MLINKS+=cap_rights_limit.2 cap_rights_get.2
MLINKS+=chdir.2 fchdir.2
MLINKS+=chflags.2 fchflags.2 \
chflags.2 lchflags.2

View File

@ -364,7 +364,6 @@ FBSD_1.2 {
cap_enter;
cap_getmode;
cap_new;
cap_getrights;
getloginclass;
pdfork;
pdgetpid;
@ -379,6 +378,13 @@ FBSD_1.2 {
};
FBSD_1.3 {
cap_fcntls_get;
cap_fcntls_limit;
cap_ioctls_get;
cap_ioctls_limit;
cap_rights_get;
cap_rights_limit;
cap_sandboxed;
clock_getcpuclockid2;
ffclock_getcounter;
ffclock_getestimate;

View File

@ -58,8 +58,10 @@ or
.Xr pdfork 2
will be placed in capability mode from inception.
.Pp
When combined with capabilities created with
.Xr cap_new 2 ,
When combined with
.Xr cap_rights_limit 2 ,
.Xr cap_ioctls_limit 2 ,
.Xr cap_fcntls_limit 2 ,
.Fn cap_enter
may be used to create kernel-enforced sandboxes in which
appropriately-crafted applications or application components may be run.
@ -71,11 +73,6 @@ sandbox.
Creating effective process sandboxes is a tricky process that involves
identifying the least possible rights required by the process and then
passing those rights into the process in a safe manner.
See the CAVEAT
section of
.Xr cap_new 2
for why this is particularly tricky with UNIX file descriptors as the
canonical representation of a right.
Consumers of
.Fn cap_enter
should also be aware of other inherited rights, such as access to VM
@ -87,9 +84,35 @@ to create a runtime environment inside the sandbox that has as few implicitly
acquired rights as possible.
.Sh RETURN VALUES
.Rv -std cap_enter cap_getmode
.Sh ERRORS
The
.Fn cap_enter
and
.Fn cap_getmode
system calls
will fail if:
.Bl -tag -width Er
.It Bq Er ENOSYS
The kernel is compiled without:
.Pp
.Cd "options CAPABILITY_MODE"
.El
.Pp
The
.Fn cap_getmode
system call may also return the following error:
.Bl -tag -width Er
.It Bq Er EFAULT
Pointer
.Fa modep
points outside the process's allocated address space.
.El
.Sh SEE ALSO
.Xr cap_new 2 ,
.Xr cap_fcntls_limit 2 ,
.Xr cap_ioctls_limit 2 ,
.Xr cap_rights_limit 2 ,
.Xr fexecve 2 ,
.Xr cap_sandboxed 3 ,
.Xr capsicum 4
.Sh HISTORY
Support for capabilities and capabilities mode was developed as part of the

View File

@ -0,0 +1,126 @@
.\"
.\" Copyright (c) 2012 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
.\" 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, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd September 20, 2012
.Dt CAP_FCNTLS_LIMIT 2
.Os
.Sh NAME
.Nm cap_fcntls_limit ,
.Nm cap_fcntls_get
.Nd manage allowed fcntl commands
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/capability.h
.Ft int
.Fn cap_fcntls_limit "int fd" "uint32_t fcntlrights"
.Ft int
.Fn cap_fcntls_get "int fd" "uint32_t *fcntlrightsp"
.Sh DESCRIPTION
If a file descriptor is granted the
.Dv CAP_FCNTL
capability right, the list of allowed
.Xr fcntl 2
commands can be selectively reduced (but never expanded) with the
.Fn cap_fcntls_limit
system call.
.Pp
A bitmask of allowed fcntls commands for a given file descriptor can be obtained
with the
.Fn cap_fcntls_get
system call.
.Sh FLAGS
The following flags may be specified in the
.Fa fcntlrights
argument or returned in the
.Fa fcntlrightsp
argument:
.Bl -tag -width CAP_FCNTL_GETOWN
.It Dv CAP_FCNTL_GETFL
Permit
.Dv F_GETFL
command.
.It Dv CAP_FCNTL_SETFL
Permit
.Dv F_SETFL
command.
.It Dv CAP_FCNTL_GETOWN
Permit
.Dv F_GETOWN
command.
.It Dv CAP_FCNTL_SETOWN
Permit
.Dv F_SETOWN
command.
.El
.Sh RETURN VALUES
.Rv -std
.Sh ERRORS
.Fn cap_fcntls_limit
succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
.Fa fd
argument is not a valid descriptor.
.It Bq Er EINVAL
An invalid flag has been passed in
.Fa fcntlrights .
.It Bq Er ENOTCAPABLE
.Fa fcntlrights
would expand the list of allowed
.Xr fcntl 2
commands.
.El
.Pp
.Fn cap_fcntls_get
succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
.Fa fd
argument is not a valid descriptor.
.It Bq Er EFAULT
The
.Fa fcntlrightsp
argument points at an invalid address.
.El
.Sh SEE ALSO
.Xr cap_ioctls_limit 2 ,
.Xr cap_rights_limit 2 ,
.Xr fcntl 2
.Sh HISTORY
Support for capabilities and capabilities mode was developed as part of the
.Tn TrustedBSD
Project.
.Sh AUTHORS
This function was created by
.An Pawel Jakub Dawidek Aq pawel@dawidek.net
under sponsorship of the FreeBSD Foundation.

View File

@ -0,0 +1,157 @@
.\"
.\" Copyright (c) 2012 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
.\" 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, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd September 20, 2012
.Dt CAP_IOCTLS_LIMIT 2
.Os
.Sh NAME
.Nm cap_ioctls_limit ,
.Nm cap_ioctls_get
.Nd manage allowed ioctl commands
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/capability.h
.Ft int
.Fn cap_ioctls_limit "int fd" "const unsigned long *cmds" "size_t ncmds"
.Ft ssize_t
.Fn cap_ioctls_get "int fd" "unsigned long *cmds" "size_t maxcmds"
.Sh DESCRIPTION
If a file descriptor is granted the
.Dv CAP_IOCTL
capability right, the list of allowed
.Xr ioctl 2
commands can be selectively reduced (but never expanded) with the
.Fn cap_ioctls_limit
system call.
The
.Fa cmds
argument is an array of
.Xr ioctl 2
commands and the
.Fa ncmds
argument specifies the number of elements in the array.
There might be up to
.Va 256
elements in the array.
.Pp
The list of allowed ioctl commands for a given file descriptor can be obtained
with the
.Fn cap_ioctls_get
system call.
The
.Fa cmds
argument points at memory that can hold up to
.Fa maxcmds
values.
The function populates the provided buffer with up to
.Fa maxcmds
elements, but always returns the total number of ioctl commands allowed for the
given file descriptor.
The total number of ioctls commands for the given file descriptor can be
obtained by passing
.Dv NULL as the
.Fa cmds
argument and
.Va 0
as the
.Fa maxcmds
argument.
If all ioctl commands are allowed
.Dv ( CAP_IOCTL
capability right is assigned to the file descriptor and the
.Fn cap_ioctls_limit
system call was never called for this file descriptor), the
.Fn cap_ioctls_get
system call will return
.Dv CAP_IOCTLS_ALL
and won't modify the buffer pointed out by the
.Fa cmds
argument.
.Sh RETURN VALUES
.Rv -std cap_ioctls_limit
.Pp
The
.Fn cap_ioctls_limit
function, if successfull, returns the total number of allowed ioctl commands or
the value
.Dv INT_MAX
if all ioctls commands are allowed.
On failure the value
.Va -1
is returned and the global variable errno is set to indicate the error.
.Sh ERRORS
.Fn cap_ioctls_limit
succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
.Fa fd
argument is not a valid descriptor.
.It Bq Er EFAULT
The
.Fa cmds
argument points at an invalid address.
.It Bq Er EINVAL
The
.Fa ncmds
argument is greater than
.Va 256 .
.It Bq Er ENOTCAPABLE
.Fa cmds
would expand the list of allowed
.Xr ioctl 2
commands.
.El
.Pp
.Fn cap_ioctls_get
succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
.Fa fd
argument is not a valid descriptor.
.It Bq Er EFAULT
The
.Fa cmds
argument points at invalid address.
.El
.Sh SEE ALSO
.Xr cap_fcntls_limit 2 ,
.Xr cap_rights_limit 2 ,
.Xr ioctl 2
.Sh HISTORY
Support for capabilities and capabilities mode was developed as part of the
.Tn TrustedBSD
Project.
.Sh AUTHORS
This function was created by
.An Pawel Jakub Dawidek Aq pawel@dawidek.net
under sponsorship of the FreeBSD Foundation.

View File

@ -1,10 +1,14 @@
.\"
.\" Copyright (c) 2008-2010 Robert N. M. Watson
.\" Copyright (c) 2012-2013 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This software was developed at the University of Cambridge Computer
.\" Laboratory with support from a grant from Google, Inc.
.\"
.\" Portions of this documentation were written by Pawel Jakub Dawidek
.\" 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:
@ -28,76 +32,48 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 20, 2011
.Dt CAP_NEW 2
.Dd February 23, 2013
.Dt CAP_RIGHTS_LIMIT 2
.Os
.Sh NAME
.Nm cap_new ,
.Nm cap_getrights
.Nd System calls to manipulate capabilities
.Nm cap_rights_limit ,
.Nm cap_rights_get
.Nd manage capability rights
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/capability.h
.Ft int
.Fn cap_new "int fd" "cap_rights_t rights"
.Fn cap_rights_limit "int fd" "cap_rights_t rights"
.Ft int
.Fn cap_getrights "int fd" "cap_rights_t *rightsp"
.Fn cap_rights_get "int fd" "cap_rights_t *rightsp"
.Sh DESCRIPTION
Capabilities are special file descriptors derived from an existing file
descriptor, such as one returned by
When a file descriptor is created by a function such as
.Xr fhopen 2 ,
.Xr kqueue 2 ,
.Xr mq_open 2 ,
.Xr open 2 ,
.Xr openat 2 ,
.Xr pdfork 2 ,
.Xr pipe 2 ,
.Xr shm_open 2 ,
.Xr socket 2 ,
or
.Xr socketpair 2 ,
but with a restricted set of permitted operations determined by a rights
mask set when the capability is created.
These restricted rights cannot be changed after the capability is created,
although further capabilities with yet more restricted rights may be created
from an existing capability.
In every other sense, a capability behaves in the same way as the file
descriptor it was created from.
it is assigned all capability rights.
Those rights can be reduced (but never expanded) by using the
.Fn cap_rights_limit
system call.
Once capability rights are reduced, operations on the file descriptor will be
limited to those permitted by
.Fa rights .
.Pp
.Fn cap_new
creates a new capability for the existing file descriptor
.Fa fd ,
and returns a file descriptor for it.
Operations on the capability will be limited to those permitted by
.Fa rights ,
which is static for the lifetime of the capability.
If
.Fa fd
refers to an existing capability, then
.Fa rights
must be equal to or a subset of the rights on that capability.
As with
.Xr dup 2
and
.Xr dup2 2 ,
many properties are shared between the new capability and the existing file
descriptor, including open file flags, blocking disposition, and file offset.
Many applications will prefer to use the
.Xr cap_limitfd 3
library call, part of
.Xr libcapsicum 3 ,
as it offers a more convenient interface.
.Pp
.Fn cap_getrights
queries the rights associated with the capability referred to by file
descriptor
.Fa fd .
.Pp
These system calls, when combined with
.Xr cap_enter 2 ,
may be used to construct process sandboxes with highly granular rights
assignment.
A bitmask of capability rights assigned to a file descriptor can be obtained with
the
.Fn cap_rights_get
system call.
.Sh RIGHTS
The following rights may be specified in a new capability rights mask:
The following rights may be specified in a rights mask:
.Bl -tag -width CAP_EXTATTR_DELETE
.It Dv CAP_ACCEPT
Permit
@ -134,6 +110,13 @@ Permit
also required for
.Xr sendto 2
with a non-NULL destination address.
.It Dv CAP_CREATE
Permit
.Xr openat 2
with the
.Dv O_CREAT
flag.
.\" XXXPJD: Doesn't exist anymore.
.It Dv CAP_EVENT
Permit
.Xr select 2 ,
@ -143,7 +126,12 @@ and
to be used in monitoring the file descriptor for events.
.It Dv CAP_FEXECVE
Permit
.Xr fexecve 2 ;
.Xr fexecve 2
and
.Xr openat 2
with the
.Dv O_EXEC
flag;
.Dv CAP_READ
will also be required.
.It Dv CAP_EXTATTR_DELETE
@ -166,19 +154,49 @@ Permit
.Xr fchflags 2 .
.It Dv CAP_FCHMOD
Permit
.Xr fchmod 2 .
.Xr fchmod 2
and
.Xr fchmodat 2 .
.It Dv CAP_FCHMODAT
An alias to
.Dv CAP_FCHMOD .
.It Dv CAP_FCHOWN
Permit
.Xr fchown 2 .
.Xr fchown 2
and
.Xr fchownat 2 .
.It Dv CAP_FCHOWNAT
An alias to
.Dv CAP_FCHOWN .
.It Dv CAP_FCNTL
Permit
.Xr fcntl 2 ;
be aware that this call provides indirect access to other operations, such as
.Xr flock 2 .
.Xr fcntl 2 .
Note that only the
.Dv F_GETFL ,
.Dv F_SETFL ,
.Dv F_GETOWN
and
.Dv F_SETOWN
commands require this capability right.
Also note that the list of permitted commands can be further limited with the
.Xr cap_fcntls_limit 2
system call.
.It Dv CAP_FLOCK
Permit
.Xr flock 2
and related calls.
.Xr flock 2 ,
.Xr fcntl 2
(with
.Dv F_GETLK ,
.Dv F_SETLK
or
.Dv F_SETLKW
flag) and
.Xr openat 2
(with
.Dv O_EXLOCK
or
.Dv O_SHLOCK
flag).
.It Dv CAP_FPATHCONF
Permit
.Xr fpathconf 2 .
@ -186,22 +204,42 @@ Permit
Permit UFS background-fsck operations on the descriptor.
.It Dv CAP_FSTAT
Permit
.Xr fstat 2 .
.Xr fstat 2
and
.Xr fstatat 2 .
.It Dv CAP_FSTATAT
An alias to
.Dv CAP_FSTAT .
.It Dv CAP_FSTATFS
Permit
.Xr fstatfs 2 .
.It Dv CAP_FSYNC
Permit
.Xr aio_fsync 2
.Xr aio_fsync 2 ,
.Xr fsync 2
and
.Xr fsync 2 .
.Pp
.Xr openat 2
with
.Dv O_FSYNC
or
.Dv O_SYNC
flag.
.It Dv CAP_FTRUNCATE
Permit
.Xr ftruncate 2 .
.Xr ftruncate 2
and
.Xr openat 2
with the
.Dv O_TRUNC
flag.
.It Dv CAP_FUTIMES
Permit
.Xr futimes 2 .
.Xr futimes 2
and
.Xr futimesat 2 .
.It Dv CAP_FUTIMESAT
An alias to
.Dv CAP_FUTIMES .
.It Dv CAP_GETPEERNAME
Permit
.Xr getpeername 2 .
@ -216,42 +254,106 @@ Permit
.Xr ioctl 2 .
Be aware that this system call has enormous scope, including potentially
global scope for some objects.
The list of permitted ioctl commands can be further limited with the
.Xr cap_ioctls_limit 2
system call.
.\" XXXPJD: Doesn't exist anymore.
.It Dv CAP_KEVENT
Permit
.Xr kevent 2 ;
.Dv CAP_EVENT
is also required on file descriptors that will be monitored using
.Xr kevent 2 .
.It Dv CAP_LINKAT
Permit
.Xr linkat 2
and
.Xr renameat 2 .
This right is required for the destination directory descriptor.
.It Dv CAP_LISTEN
Permit
.Xr listen 2 ;
not much use (generally) without
.Dv CAP_BIND .
.It Dv CAP_LOOKUP
Permit the file descriptor to be used as a starting directory for calls such
as
Permit the file descriptor to be used as a starting directory for calls such as
.Xr linkat 2 ,
.Xr openat 2 ,
and
.Xr unlinkat 2 .
Note that these calls are not available in capability mode as they manipulate
a global name space; see
.Xr cap_enter 2
for details.
.It Dv CAP_MAC_GET
Permit
.Xr mac_get_fd 3 .
.It Dv CAP_MAC_SET
Permit
.Xr mac_set_fd 3 .
.It Dv CAP_MKDIRAT
Permit
.Xr mkdirat 2 .
.It Dv CAP_MKFIFOAT
Permit
.Xr mkfifoat 2 .
.It Dv CAP_MKNODAT
Permit
.Xr mknodat 2 .
.It Dv CAP_MMAP
Permit
.Xr mmap 2 ;
specific invocations may also require
.Xr mmap 2
with the
.Dv PROT_NONE
protection.
.It Dv CAP_MMAP_R
Permit
.Xr mmap 2
with the
.Dv PROT_READ
protection.
This also implies
.Dv CAP_READ
or
.Dv CAP_WRITE .
.Pp
and
.Dv CAP_SEEK
rights.
.It Dv CAP_MMAP_W
Permit
.Xr mmap 2
with the
.Dv PROT_WRITE
protection.
This also implies
.Dv CAP_WRITE
and
.Dv CAP_SEEK
rights.
.It Dv CAP_MMAP_X
Permit
.Xr mmap 2
with the
.Dv PROT_EXEC
protection.
This also implies
.Dv CAP_SEEK
right.
.It Dv CAP_MMAP_RW
Implies
.Dv CAP_MMAP_R
and
.Dv CAP_MMAP_W .
.It Dv CAP_MMAP_RX
Implies
.Dv CAP_MMAP_R
and
.Dv CAP_MMAP_X .
.It Dv CAP_MMAP_WX
Implies
.Dv CAP_MMAP_W
and
.Dv CAP_MMAP_X .
.It Dv CAP_MMAP_RWX
Implies
.Dv CAP_MMAP_R ,
.Dv CAP_MMAP_W
and
.Dv CAP_MMAP_X .
.It Dv CAP_PDGETPID
Permit
.Xr pdgetpid 2 .
@ -264,30 +366,46 @@ Permit
.It Dv CAP_PEELOFF
Permit
.Xr sctp_peeloff 2 .
.\" XXXPJD: Not documented.
.It Dv CAP_POLL_EVENT
.\" XXXPJD: Not documented.
.It Dv CAP_POST_EVENT
.It Dv CAP_PREAD
Implies
.Dv CAP_SEEK
and
.Dv CAP_READ .
.It Dv CAP_PWRITE
Implies
.Dv CAP_SEEK
and
.Dv CAP_WRITE .
.It Dv CAP_READ
Allow
.Xr aio_read 2 ,
.Xr pread 2 ,
.Xr openat
with the
.Dv O_RDONLY flag,
.Xr read 2 ,
.Xr recv 2 ,
.Xr recvfrom 2 ,
.Xr recvmsg 2 ,
.Xr recvmsg 2
and related system calls.
.Pp
For files and other seekable objects,
.Dv CAP_SEEK
may also be required.
.It Dv CAP_REVOKE
.It Dv CAP_RECV
An alias to
.Dv CAP_READ .
.It Dv CAP_RENAMEAT
Permit
.Xr frevoke 2
in certain ABI compatibility modes that support this system call.
.Xr renameat 2 .
This right is required for the source directory descriptor.
.It Dv CAP_SEEK
Permit operations that seek on the file descriptor, such as
.Xr lseek 2 ,
but also required for I/O system calls that modify the file offset, such as
.Xr read 2
but also required for I/O system calls that can read or write at any position
in the file, such as
.Xr pread 2
and
.Xr write 2 .
.Xr pwrite 2 .
.It Dv CAP_SEM_GETVALUE
Permit
.Xr sem_getvalue 3 .
@ -299,6 +417,9 @@ Permit
.Xr sem_wait 3
and
.Xr sem_trywait 3 .
.It Dv CAP_SEND
An alias to
.Dv CAP_WRITE .
.It Dv CAP_SETSOCKOPT
Permit
.Xr setsockopt 2 ;
@ -308,49 +429,56 @@ connecting, and other behaviors with global scope.
Permit explicit
.Xr shutdown 2 ;
closing the socket will also generally shut down any connections on it.
.It Dv CAP_SYMLINKAT
Permit
.Xr symlinkat 2 .
.It Dv CAP_TTYHOOK
Allow configuration of TTY hooks, such as
.Xr snp 4 ,
on the file descriptor.
.It Dv CAP_UNLINKAT
Permit
.Xr unlinkat 2
and
.Xr renameat 2 .
This right is only required for
.Xr renameat 2
on the destination directory descriptor if the destination object already
exists and will be removed by the rename.
.It Dv CAP_WRITE
Allow
.Xr aio_write 2 ,
.Xr pwrite 2 ,
.Xr openat 2
with
.Dv O_WRONLY
and
.Dv O_APPEND
flags,
.Xr send 2 ,
.Xr sendmsg 2 ,
.Xr sendto 2 ,
.Xr write 2 ,
and related system calls.
.Pp
For files and other seekable objects,
.Dv CAP_SEEK
may also be required.
.Pp
For
.Xr sendto 2
with a non-NULL connection address,
.Dv CAP_CONNECT
is also required.
For
.Xr openat 2
with the
.Dv O_WRONLY
flag, but without the
.Dv O_APPEND
flag,
.Dv CAP_SEEK
is also required.
.El
.Sh CAVEAT
The
.Fn cap_new
system call and the capabilities it creates may be used to assign
fine-grained rights to sandboxed processes running in capability mode.
However, the semantics of objects accessed via file descriptors are complex,
so caution should be exercised in passing object capabilities into sandboxes.
.Sh RETURN VALUES
If successful,
.Fn cap_new
returns a non-negative integer, termed a file descriptor.
It returns -1 on failure, and sets
.Va errno
to indicate the error.
.Pp
.Rv -std cap_getrights
.Rv -std
.Sh ERRORS
.Fn cap_new
may return the following errors:
.Fn cap_rights_limit
succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
@ -359,29 +487,23 @@ argument is not a valid active descriptor.
.It Bq Er EINVAL
An invalid right has been requested in
.Fa rights .
.It Bq Er EMFILE
The process has already reached its limit for open file descriptors.
.It Bq Er ENFILE
The system file table is full.
.It Bq Er EPERM
.It Bq Er ENOTCAPABLE
.Fa rights
contains requested rights not present in the current rights mask associated
with the capability referenced by
.Fa fd ,
if any.
with the given file descriptor.
.El
.Pp
.Fn cap_getrights
may return the following errors:
.Fn cap_rights_get
succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
.Fa fd
argument is not a valid active descriptor.
.It Bq Er EINVAL
.It Bq Er EFAULT
The
.Fa fd
argument is not a capability.
.Fa rightsp
argument points at an invalid address.
.El
.Sh SEE ALSO
.Xr accept 2 ,
@ -390,6 +512,9 @@ argument is not a capability.
.Xr aio_write 2 ,
.Xr bind 2 ,
.Xr cap_enter 2 ,
.Xr cap_fcntls_limit 2 ,
.Xr cap_ioctls_limit 2 ,
.Xr cap_rights_limit 2 ,
.Xr connect 2 ,
.Xr dup 2 ,
.Xr dup2 2 ,
@ -421,6 +546,7 @@ argument is not a capability.
.Xr mq_open 2 ,
.Xr open 2 ,
.Xr openat 2 ,
.Xr pdfork 2 ,
.Xr pdgetpid 2 ,
.Xr pdkill 2 ,
.Xr pdwait4 2 ,
@ -432,6 +558,7 @@ argument is not a capability.
.Xr recv 2 ,
.Xr recvfrom 2 ,
.Xr recvmsg 2 ,
.Xr renameat 2 ,
.Xr sctp_peeloff 2 ,
.Xr select 2 ,
.Xr send 2 ,
@ -442,6 +569,7 @@ argument is not a capability.
.Xr shutdown 2 ,
.Xr socket 2 ,
.Xr socketpair 2 ,
.Xr symlinkat 2 ,
.Xr unlinkat 2 ,
.Xr write 2 ,
.Xr acl_delete_fd_np 3 ,
@ -463,10 +591,9 @@ Support for capabilities and capabilities mode was developed as part of the
.Tn TrustedBSD
Project.
.Sh AUTHORS
These functions and the capability facility were created by
.An "Robert N. M. Watson"
at the University of Cambridge Computer Laboratory with support from a grant
from Google, Inc.
This function was created by
.An Pawel Jakub Dawidek Aq pawel@dawidek.net
under sponsorship of the FreeBSD Foundation.
.Sh BUGS
This man page should list the set of permitted system calls more specifically
for each capability right.

View File

@ -115,11 +115,6 @@ and
is a valid descriptor, then
.Fn dup2
is successful, and does nothing.
.Pp
The related
.Xr cap_new 2
system call allows file descriptors to be duplicated with restrictions on
their use.
.Sh RETURN VALUES
The value -1 is returned if an error occurs in either call.
The external variable
@ -152,7 +147,6 @@ argument is negative or exceeds the maximum allowable descriptor number
.El
.Sh SEE ALSO
.Xr accept 2 ,
.Xr cap_new 2 ,
.Xr close 2 ,
.Xr fcntl 2 ,
.Xr getdtablesize 2 ,

View File

@ -600,7 +600,6 @@ kinfo_fflags2fst(int kfflags)
} kfflags2fst[] = {
{ KF_FLAG_APPEND, PS_FST_FFLAG_APPEND },
{ KF_FLAG_ASYNC, PS_FST_FFLAG_ASYNC },
{ KF_FLAG_CAPABILITY, PS_FST_FFLAG_CAPABILITY },
{ KF_FLAG_CREAT, PS_FST_FFLAG_CREAT },
{ KF_FLAG_DIRECT, PS_FST_FFLAG_DIRECT },
{ KF_FLAG_EXCL, PS_FST_FFLAG_EXCL },

View File

@ -88,7 +88,6 @@
#define PS_FST_FFLAG_DIRECT 0x1000
#define PS_FST_FFLAG_EXEC 0x2000
#define PS_FST_FFLAG_HASLOCK 0x4000
#define PS_FST_FFLAG_CAPABILITY 0x8000
struct procstat;
struct filestat {

View File

@ -95,8 +95,7 @@ static off_t nandfs_seek(struct open_file *, off_t, int);
static int nandfs_stat(struct open_file *, struct stat *);
static int nandfs_readdir(struct open_file *, struct dirent *);
static int nandfs_buf_read(struct nandfs *, char **, size_t *);
static struct nandfs_node *nandfs_lookup_inode(struct nandfs *, nandfs_daddr_t);
static int nandfs_buf_read(struct nandfs *, void **, size_t *);
static struct nandfs_node *nandfs_lookup_path(struct nandfs *, const char *);
static int nandfs_read_inode(struct nandfs *, struct nandfs_node *,
nandfs_lbn_t, u_int, void *, int);
@ -125,6 +124,27 @@ struct fs_ops nandfs_fsops = {
#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t))
/* from NetBSD's src/sys/net/if_ethersubr.c */
static uint32_t
nandfs_crc32(uint32_t crc, const uint8_t *buf, size_t len)
{
static const uint32_t crctab[] = {
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
};
size_t i;
crc = crc ^ ~0U;
for (i = 0; i < len; i++) {
crc ^= buf[i];
crc = (crc >> 4) ^ crctab[crc & 0xf];
crc = (crc >> 4) ^ crctab[crc & 0xf];
}
return (crc ^ ~0U);
}
static int
nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
{
@ -138,7 +158,7 @@ nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata)
/* Calculate */
fsdata->f_sum = (0);
comp_crc = crc32(0, (uint8_t *)fsdata, fsdata->f_bytes);
comp_crc = nandfs_crc32(0, (uint8_t *)fsdata, fsdata->f_bytes);
/* Restore */
fsdata->f_sum = fsdata_crc;
@ -162,7 +182,7 @@ nandfs_check_superblock_crc(struct nandfs_fsdata *fsdata,
/* Calculate */
super->s_sum = (0);
comp_crc = crc32(0, (uint8_t *)super, fsdata->f_sbbytes);
comp_crc = nandfs_crc32(0, (uint8_t *)super, fsdata->f_sbbytes);
/* Restore */
super->s_sum = super_crc;
@ -397,7 +417,7 @@ nandfs_open(const char *path, struct open_file *f)
return (0);
}
static int
static void
nandfs_free_node(struct nandfs_node *node)
{
struct bmap_buf *bmap, *tmp;
@ -424,6 +444,7 @@ nandfs_close(struct open_file *f)
nandfs_free_node(fs->nf_opened_node);
free(fs->nf_sb);
free(fs);
return (0);
}
static int
@ -431,7 +452,7 @@ nandfs_read(struct open_file *f, void *addr, size_t size, size_t *resid)
{
struct nandfs *fs = (struct nandfs *)f->f_fsdata;
size_t csize, buf_size;
uint8_t *buf;
void *buf;
int error = 0;
NANDFS_DEBUG("nandfs_read(file=%p, addr=%p, size=%d)\n", f, addr, size);
@ -440,7 +461,7 @@ nandfs_read(struct open_file *f, void *addr, size_t size, size_t *resid)
if (fs->nf_offset >= fs->nf_opened_node->inode->i_size)
break;
error = nandfs_buf_read(fs, (void *)&buf, &buf_size);
error = nandfs_buf_read(fs, &buf, &buf_size);
if (error)
break;
@ -517,7 +538,7 @@ nandfs_readdir(struct open_file *f, struct dirent *d)
{
struct nandfs *fs = f->f_fsdata;
struct nandfs_dir_entry *dirent;
uint8_t *buf;
void *buf;
size_t buf_size;
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)\n", f, d);
@ -528,7 +549,7 @@ nandfs_readdir(struct open_file *f, struct dirent *d)
return (ENOENT);
}
if (nandfs_buf_read(fs, (void *)&buf, &buf_size)) {
if (nandfs_buf_read(fs, &buf, &buf_size)) {
NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)"
"buf_read failed\n", f, d);
return (EIO);
@ -546,7 +567,7 @@ nandfs_readdir(struct open_file *f, struct dirent *d)
}
static int
nandfs_buf_read(struct nandfs *fs, char **buf_p, size_t *size_p)
nandfs_buf_read(struct nandfs *fs, void **buf_p, size_t *size_p)
{
nandfs_daddr_t blknr, blkoff;
@ -612,8 +633,8 @@ nandfs_lookup_path(struct nandfs *fs, const char *path)
struct nandfs_node *node;
struct nandfs_dir_entry *dirent;
char *namebuf;
uint64_t i, j, done, counter, pinode, inode;
int nlinks = 0, len, link_len, nameidx;
uint64_t i, done, pinode, inode;
int nlinks = 0, counter, len, link_len, nameidx;
uint8_t *buffer, *orig;
char *strp, *lpath;
@ -650,7 +671,8 @@ nandfs_lookup_path(struct nandfs *fs, const char *path)
buffer = orig;
done = counter = 0;
while (1) {
dirent = (struct nandfs_dir_entry *)buffer;
dirent =
(struct nandfs_dir_entry *)(void *)buffer;
NANDFS_DEBUG("%s: dirent.name = %s\n",
__func__, dirent->name);
NANDFS_DEBUG("%s: dirent.rec_len = %d\n",
@ -746,9 +768,9 @@ static int
nandfs_read_inode(struct nandfs *fs, struct nandfs_node *node,
nandfs_daddr_t blknr, u_int nblks, void *buf, int raw)
{
int i;
uint64_t *pblks;
uint64_t *vblks;
u_int i;
int error;
pblks = malloc(nblks * sizeof(uint64_t));
@ -777,7 +799,7 @@ nandfs_read_inode(struct nandfs *fs, struct nandfs_node *node,
return (EIO);
}
buf += fs->nf_blocksize;
buf = (void *)((uintptr_t)buf + fs->nf_blocksize);
}
free(pblks);
@ -859,8 +881,7 @@ nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node,
{
struct nandfs_inode *ino;
nandfs_daddr_t ind_block_num;
uint64_t *map, *indir;
uint64_t idx0, idx1, vblk, tmp;
uint64_t *map;
int idx;
int level;
@ -1006,7 +1027,7 @@ ioread(struct open_file *f, off_t pos, void *buf, u_int length)
err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, pos,
nsec * bsize, buffer, NULL);
memcpy(buf, buffer + off, length);
memcpy(buf, (void *)((uintptr_t)buffer + off), length);
free(buffer);
return (err);

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd February 25, 2012
.Dd March 1, 2013
.Dt KINFO_GETPROC 3
.Os
.Sh NAME
@ -37,7 +37,7 @@
.In sys/types.h
.In libutil.h
.Ft struct kinfo_proc *
.Fn kinfo_getproc "pid_t pid" "int *cntp"
.Fn kinfo_getproc "pid_t pid"
.Sh DESCRIPTION
This function is used for obtaining process information from the kernel.
.Pp

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd December 18, 2012
.Dd February 27, 2013
.Dt ARCMSR 4
.Os
.Sh NAME
@ -108,6 +108,8 @@ ARC-1222
.It
ARC-1223
.It
ARC-1224
.It
ARC-1230
.It
ARC-1231

View File

@ -1,5 +1,5 @@
.\"
.\" Copyright (c) 2011 Alexander Motin <mav@FreeBSD.org>
.\" Copyright (c) 2011-2013 Alexander Motin <mav@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd December 14, 2011
.Dd February 25, 2013
.Dt EVENTTIMERS 9
.Os
.Sh NAME
@ -36,7 +36,7 @@
struct eventtimer;
typedef int et_start_t(struct eventtimer *et,
struct bintime *first, struct bintime *period);
sbintime_t first, sbintime_t period);
typedef int et_stop_t(struct eventtimer *et);
typedef void et_event_cb_t(struct eventtimer *et, void *arg);
typedef int et_deregister_cb_t(struct eventtimer *et, void *arg);
@ -53,8 +53,8 @@ struct eventtimer {
int et_quality;
int et_active;
uint64_t et_frequency;
struct bintime et_min_period;
struct bintime et_max_period;
sbintime_t et_min_period;
sbintime_t et_max_period;
et_start_t *et_start;
et_stop_t *et_stop;
et_event_cb_t *et_event_cb;
@ -75,7 +75,7 @@ struct eventtimer {
.Ft int
.Fn et_init "struct eventtimer *et" "et_event_cb_t *event" "et_deregister_cb_t *deregister" "void *arg"
.Ft int
.Fn et_start "struct eventtimer *et" "struct bintime *first" "struct bintime *period"
.Fn et_start "struct eventtimer *et" "sbintime_t first" "sbintime_t period"
.Ft int
.Fn et_stop "struct eventtimer *et"
.Ft int

View File

@ -14,7 +14,7 @@ COMPILER_TYPE:= gcc
. elif ${_COMPILER_VERSION:Mclang}
COMPILER_TYPE:= clang
. else
.error Unable to determine compiler type for ${CC}
.error Unable to determine compiler type for ${CC}. Consider setting COMPILER_TYPE.
. endif
. undef _COMPILER_VERSION
. endif

View File

@ -658,7 +658,7 @@ cpu_halt(void)
halt();
}
void (*cpu_idle_hook)(void) = NULL; /* ACPI idle hook. */
void (*cpu_idle_hook)(sbintime_t) = NULL; /* ACPI idle hook. */
static int cpu_ident_amdc1e = 0; /* AMD C1E supported. */
static int idle_mwait = 1; /* Use MONITOR/MWAIT for short idle. */
TUNABLE_INT("machdep.idle_mwait", &idle_mwait);
@ -670,7 +670,7 @@ SYSCTL_INT(_machdep, OID_AUTO, idle_mwait, CTLFLAG_RW, &idle_mwait,
#define STATE_SLEEPING 0x2
static void
cpu_idle_acpi(int busy)
cpu_idle_acpi(sbintime_t sbt)
{
int *state;
@ -682,14 +682,14 @@ cpu_idle_acpi(int busy)
if (sched_runnable())
enable_intr();
else if (cpu_idle_hook)
cpu_idle_hook();
cpu_idle_hook(sbt);
else
__asm __volatile("sti; hlt");
*state = STATE_RUNNING;
}
static void
cpu_idle_hlt(int busy)
cpu_idle_hlt(sbintime_t sbt)
{
int *state;
@ -730,7 +730,7 @@ cpu_idle_hlt(int busy)
#define MWAIT_C4 0x30
static void
cpu_idle_mwait(int busy)
cpu_idle_mwait(sbintime_t sbt)
{
int *state;
@ -753,7 +753,7 @@ cpu_idle_mwait(int busy)
}
static void
cpu_idle_spin(int busy)
cpu_idle_spin(sbintime_t sbt)
{
int *state;
int i;
@ -802,12 +802,13 @@ cpu_probe_amdc1e(void)
}
}
void (*cpu_idle_fn)(int) = cpu_idle_acpi;
void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi;
void
cpu_idle(int busy)
{
uint64_t msr;
sbintime_t sbt = -1;
CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
busy, curcpu);
@ -825,7 +826,7 @@ cpu_idle(int busy)
/* If we have time - switch timers into idle mode. */
if (!busy) {
critical_enter();
cpu_idleclock();
sbt = cpu_idleclock();
}
/* Apply AMD APIC timer C1E workaround. */
@ -836,7 +837,7 @@ cpu_idle(int busy)
}
/* Call main idle method. */
cpu_idle_fn(busy);
cpu_idle_fn(sbt);
/* Switch timers mack into active mode. */
if (!busy) {

View File

@ -3665,7 +3665,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
pv = get_pv_entry(pmap, &lock);
pv->pv_va = va;
CHANGE_PV_LIST_LOCK_TO_PHYS(&lock, pa);
TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_next);
if ((newpte & PG_RW) != 0)
vm_page_aflag_set(m, PGA_WRITEABLE);
}

View File

@ -138,7 +138,7 @@ device sa # Sequential Access (tape etc)
device cd # CD
device pass # Passthrough device (direct ATA/SCSI access)
device ses # Enclosure Services (SES and SAF-TE)
device ctl # CAM Target Layer
#device ctl # CAM Target Layer
# RAID controllers interfaced to the SCSI subsystem
device amr # AMI MegaRAID

View File

@ -17,5 +17,5 @@ arm/allwinner/timer.c standard
arm/allwinner/aintc.c standard
arm/allwinner/bus_space.c standard
arm/allwinner/common.c standard
arm/allwinner/console.c standard
#arm/allwinner/console.c standard
arm/allwinner/a10_machdep.c standard

View File

@ -95,7 +95,7 @@ int a10_timer_get_timerfreq(struct a10_timer_softc *);
static u_int a10_timer_get_timecount(struct timecounter *);
static int a10_timer_timer_start(struct eventtimer *,
struct bintime *, struct bintime *);
sbintime_t first, sbintime_t period);
static int a10_timer_timer_stop(struct eventtimer *);
static uint64_t timer_read_counter64(void);
@ -193,12 +193,8 @@ a10_timer_attach(device_t dev)
sc->et.et_name = "a10_timer Eventtimer";
sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
sc->et.et_quality = 1000;
sc->et.et_min_period.sec = 0;
sc->et.et_min_period.frac =
((0x00000005LLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
sc->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_min_period = (0x00000005LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = a10_timer_timer_start;
sc->et.et_stop = a10_timer_timer_stop;
sc->et.et_priv = sc;
@ -225,8 +221,8 @@ a10_timer_attach(device_t dev)
}
static int
a10_timer_timer_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
a10_timer_timer_start(struct eventtimer *et, sbintime_t first,
sbintime_t period)
{
struct a10_timer_softc *sc;
uint32_t count;
@ -234,26 +230,21 @@ a10_timer_timer_start(struct eventtimer *et, struct bintime *first,
sc = (struct a10_timer_softc *)et->et_priv;
sc->sc_period = 0;
if (period != NULL) {
sc->sc_period = (sc->et.et_frequency * (period->frac >> 32)) >> 32;
sc->sc_period += sc->et.et_frequency * period->sec;
}
if (first == NULL)
if (period != 0)
sc->sc_period = ((uint32_t)et->et_frequency * period) >> 32;
else
sc->sc_period = 0;
if (first != 0)
count = ((uint32_t)et->et_frequency * first) >> 32;
else
count = sc->sc_period;
else {
count = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
count += sc->et.et_frequency * first->sec;
}
/* Update timer values */
timer_write_4(sc, SW_TIMER0_INT_VALUE_REG, sc->sc_period);
timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, count);
val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
if (first == NULL) {
if (period != 0) {
/* periodic */
val |= TIMER_AUTORELOAD;
} else {

View File

@ -204,6 +204,7 @@ mmu_done:
virt_done:
mov r1, #20 /* loader info size is 20 bytes also second arg */
subs sp, sp, r1 /* allocate arm_boot_params struct on stack */
bic sp, sp, #7 /* align stack to 8 bytes */
mov r0, sp /* loader info pointer is first arg */
str r1, [r0] /* Store length of loader info */
str r9, [r0, #4] /* Store r0 from boot loader */

View File

@ -167,31 +167,23 @@ arm_tmr_get_timecount(struct timecounter *tc)
* Always returns 0
*/
static int
arm_tmr_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
arm_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct arm_tmr_softc *sc = (struct arm_tmr_softc *)et->et_priv;
uint32_t load, count;
uint32_t ctrl;
ctrl = PRV_TIMER_CTRL_IRQ_ENABLE | PRV_TIMER_CTRL_TIMER_ENABLE;
if (period != NULL) {
load = (et->et_frequency * (period->frac >> 32)) >> 32;
if (period->sec > 0)
load += et->et_frequency * period->sec;
if (period != 0) {
load = ((uint32_t)et->et_frequency * period) >> 32;
ctrl |= PRV_TIMER_CTRL_AUTO_RELOAD;
} else {
} else
load = 0;
}
if (first != NULL) {
count = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
count += sc->et.et_frequency * first->sec;
} else {
if (first != 0)
count = ((uint32_t)et->et_frequency * first) >> 32;
else
count = load;
}
tmr_prv_write_4(PRV_TIMER_LOAD, load);
tmr_prv_write_4(PRV_TIMER_COUNT, count);
@ -330,12 +322,8 @@ arm_tmr_attach(device_t dev)
sc->et.et_quality = 1000;
sc->et.et_frequency = sc->clkfreq;
sc->et.et_min_period.sec = 0;
sc->et.et_min_period.frac =
((0x00000002LLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
sc->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = arm_tmr_start;
sc->et.et_stop = arm_tmr_stop;
sc->et.et_priv = sc;

View File

@ -0,0 +1,727 @@
/*
* Copyright (c) 2013 Daisuke Aoyama <aoyama@peach.ne.jp>
* Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@bluezbox.com>
*
* 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/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/resource.h>
#include <sys/rman.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/pmap.h>
#include "bcm2835_dma.h"
#include "bcm2835_vcbus.h"
#define MAX_REG 9
/* private flags */
#define BCM_DMA_CH_USED 0x00000001
#define BCM_DMA_CH_FREE 0x40000000
#define BCM_DMA_CH_UNMAP 0x80000000
/* Register Map (4.2.1.2) */
#define BCM_DMA_CS(n) (0x100*(n) + 0x00)
#define CS_ACTIVE (1 << 0)
#define CS_END (1 << 1)
#define CS_INT (1 << 2)
#define CS_DREQ (1 << 3)
#define CS_ISPAUSED (1 << 4)
#define CS_ISHELD (1 << 5)
#define CS_ISWAIT (1 << 6)
#define CS_ERR (1 << 8)
#define CS_WAITWRT (1 << 28)
#define CS_DISDBG (1 << 29)
#define CS_ABORT (1 << 30)
#define CS_RESET (1 << 31)
#define BCM_DMA_CBADDR(n) (0x100*(n) + 0x04)
#define BCM_DMA_INFO(n) (0x100*(n) + 0x08)
#define INFO_INT_EN (1 << 0)
#define INFO_TDMODE (1 << 1)
#define INFO_WAIT_RESP (1 << 3)
#define INFO_D_INC (1 << 4)
#define INFO_D_WIDTH (1 << 5)
#define INFO_D_DREQ (1 << 6)
#define INFO_S_INC (1 << 8)
#define INFO_S_WIDTH (1 << 9)
#define INFO_S_DREQ (1 << 10)
#define INFO_WAITS_SHIFT (21)
#define INFO_PERMAP_SHIFT (16)
#define INFO_PERMAP_MASK (0x1f << INFO_PERMAP_SHIFT)
#define BCM_DMA_SRC(n) (0x100*(n) + 0x0C)
#define BCM_DMA_DST(n) (0x100*(n) + 0x10)
#define BCM_DMA_LEN(n) (0x100*(n) + 0x14)
#define BCM_DMA_STRIDE(n) (0x100*(n) + 0x18)
#define BCM_DMA_CBNEXT(n) (0x100*(n) + 0x1C)
#define BCM_DMA_DEBUG(n) (0x100*(n) + 0x20)
#define DEBUG_ERROR_MASK (7)
#define BCM_DMA_INT_STATUS 0xfe0
#define BCM_DMA_ENABLE 0xff0
/* relative offset from BCM_VC_DMA0_BASE (p.39) */
#define BCM_DMA_CH(n) (0x100*(n))
/* DMA Control Block - 256bit aligned (p.40) */
struct bcm_dma_cb {
uint32_t info; /* Transfer Information */
uint32_t src; /* Source Address */
uint32_t dst; /* Destination Address */
uint32_t len; /* Transfer Length */
uint32_t stride; /* 2D Mode Stride */
uint32_t next; /* Next Control Block Address */
uint32_t rsvd1; /* Reserved */
uint32_t rsvd2; /* Reserved */
};
#ifdef DEBUG
static void bcm_dma_cb_dump(struct bcm_dma_cb *cb);
static void bcm_dma_reg_dump(int ch);
#endif
/* DMA channel private info */
struct bcm_dma_ch {
int ch;
uint32_t flags;
struct bcm_dma_cb * cb;
uint32_t vc_cb;
bus_dmamap_t dma_map;
void (*intr_func)(int, void *);
void * intr_arg;
};
struct bcm_dma_softc {
device_t sc_dev;
struct mtx sc_mtx;
struct resource * sc_mem;
struct resource * sc_irq[BCM_DMA_CH_MAX];
void * sc_intrhand[BCM_DMA_CH_MAX];
struct bcm_dma_ch sc_dma_ch[BCM_DMA_CH_MAX];
bus_dma_tag_t sc_dma_tag;
};
static struct bcm_dma_softc *bcm_dma_sc = NULL;
static void
bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs,
int nseg, int err)
{
bus_addr_t *addr;
if (err)
return;
addr = (bus_addr_t*)arg;
*addr = PHYS_TO_VCBUS(segs[0].ds_addr);
}
static void
bcm_dma_reset(device_t dev, int ch)
{
struct bcm_dma_softc *sc = device_get_softc(dev);
struct bcm_dma_cb *cb;
uint32_t cs;
int count;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return;
cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch));
if (cs & CS_ACTIVE) {
/* pause current task */
bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), 0);
count = 1000;
do {
cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch));
} while (!(cs & CS_ISPAUSED) && (count-- > 0));
if (!(cs & CS_ISPAUSED)) {
device_printf(dev,
"Can't abort DMA transfer at channel %d\n", ch);
}
bus_write_4(sc->sc_mem, BCM_DMA_CBNEXT(ch), 0);
/* Complete everything, clear interrupt */
bus_write_4(sc->sc_mem, BCM_DMA_CS(ch),
CS_ABORT | CS_INT | CS_END| CS_ACTIVE);
}
/* clear control blocks */
bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch), 0);
bus_write_4(sc->sc_mem, BCM_DMA_CBNEXT(ch), 0);
/* Reset control block */
cb = sc->sc_dma_ch[ch].cb;
bzero(cb, sizeof(cb));
}
static int
bcm_dma_init(device_t dev)
{
struct bcm_dma_softc *sc = device_get_softc(dev);
uint32_t mask;
struct bcm_dma_ch *ch;
void *cb_virt;
vm_paddr_t cb_phys;
int err;
int i;
/* disable and clear interrupt status */
bus_write_4(sc->sc_mem, BCM_DMA_ENABLE, 0);
bus_write_4(sc->sc_mem, BCM_DMA_INT_STATUS, 0);
/* Allocate DMA chunks control blocks */
/* p.40 of spec - control block should be 32-bit aligned */
err = bus_dma_tag_create(bus_get_dma_tag(dev),
1, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL,
sizeof(struct bcm_dma_cb), 1,
sizeof(struct bcm_dma_cb),
BUS_DMA_ALLOCNOW, NULL, NULL,
&sc->sc_dma_tag);
if (err) {
device_printf(dev, "failed allocate DMA tag");
return (err);
}
/* setup initial settings */
for (i = 0; i < BCM_DMA_CH_MAX; i++) {
ch = &sc->sc_dma_ch[i];
err = bus_dmamem_alloc(sc->sc_dma_tag, &cb_virt,
BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
&ch->dma_map);
if (err) {
device_printf(dev, "cannot allocate DMA memory\n");
break;
}
/*
* Least alignment for busdma-allocated stuff is cache
* line size, so just make sure nothing stupid happend
* and we got properly aligned address
*/
if ((uintptr_t)cb_virt & 0x1f) {
device_printf(dev,
"DMA address is not 32-bytes aligned: %p\n",
(void*)cb_virt);
break;
}
err = bus_dmamap_load(sc->sc_dma_tag, ch->dma_map, cb_virt,
sizeof(struct bcm_dma_cb), bcm_dmamap_cb, &cb_phys,
BUS_DMA_WAITOK);
if (err) {
device_printf(dev, "cannot load DMA memory\n");
break;
}
bzero(ch, sizeof(struct bcm_dma_ch));
ch->ch = i;
ch->cb = cb_virt;
ch->vc_cb = cb_phys;
ch->intr_func = NULL;
ch->intr_arg = NULL;
ch->flags = BCM_DMA_CH_UNMAP;
ch->cb->info = INFO_WAIT_RESP;
/* reset DMA engine */
bcm_dma_reset(dev, i);
}
/* now use DMA2/DMA3 only */
sc->sc_dma_ch[2].flags = BCM_DMA_CH_FREE;
sc->sc_dma_ch[3].flags = BCM_DMA_CH_FREE;
/* enable DMAs */
mask = 0;
for (i = 0; i < BCM_DMA_CH_MAX; i++)
if (sc->sc_dma_ch[i].flags & BCM_DMA_CH_FREE)
mask |= (1 << i);
bus_write_4(sc->sc_mem, BCM_DMA_ENABLE, mask);
return (0);
}
/*
* Allocate DMA channel for further use, returns channel # or
* BCM_DMA_CH_INVALID
*/
int
bcm_dma_allocate(int req_ch)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
int ch = BCM_DMA_CH_INVALID;
int i;
if (req_ch >= BCM_DMA_CH_MAX)
return (BCM_DMA_CH_INVALID);
/* Auto(req_ch < 0) or CH specified */
mtx_lock(&sc->sc_mtx);
if (req_ch < 0) {
for (i = 0; i < BCM_DMA_CH_MAX; i++) {
if (sc->sc_dma_ch[i].flags & BCM_DMA_CH_FREE) {
ch = i;
sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_FREE;
sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_USED;
break;
}
}
}
else {
if (sc->sc_dma_ch[req_ch].flags & BCM_DMA_CH_FREE) {
ch = req_ch;
sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_FREE;
sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_USED;
}
}
mtx_unlock(&sc->sc_mtx);
return (ch);
}
/*
* Frees allocated channel. Returns 0 on success, -1 otherwise
*/
int
bcm_dma_free(int ch)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return (-1);
mtx_lock(&sc->sc_mtx);
if (sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED) {
sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_FREE;
sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_USED;
sc->sc_dma_ch[ch].intr_func = NULL;
sc->sc_dma_ch[ch].intr_arg = NULL;
/* reset DMA engine */
bcm_dma_reset(sc->sc_dev, ch);
}
mtx_unlock(&sc->sc_mtx);
return (0);
}
/*
* Assign handler function for channel interrupt
* Returns 0 on success, -1 otherwise
*/
int
bcm_dma_setup_intr(int ch, void (*func)(int, void *), void *arg)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
struct bcm_dma_cb *cb;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return (-1);
if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
return (-1);
sc->sc_dma_ch[ch].intr_func = func;
sc->sc_dma_ch[ch].intr_arg = arg;
cb = sc->sc_dma_ch[ch].cb;
cb->info |= INFO_INT_EN;
return (0);
}
/*
* Setup DMA source parameters
* ch - channel number
* dreq - hardware DREQ # or BCM_DMA_DREQ_NONE if
* source is physical memory
* inc_addr - BCM_DMA_INC_ADDR if source address
* should be increased after each access or
* BCM_DMA_SAME_ADDR if address should remain
* the same
* width - size of read operation, BCM_DMA_32BIT
* for 32bit bursts, BCM_DMA_128BIT for 128 bits
*
* Returns 0 on success, -1 otherwise
*/
int
bcm_dma_setup_src(int ch, int dreq, int inc_addr, int width)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
uint32_t info;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return (-1);
if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
return (-1);
info = sc->sc_dma_ch[ch].cb->info;
info &= ~INFO_PERMAP_MASK;
info |= (dreq << INFO_PERMAP_SHIFT) & INFO_PERMAP_MASK;
if (dreq)
info |= INFO_S_DREQ;
else
info &= ~INFO_S_DREQ;
if (width == BCM_DMA_128BIT)
info |= INFO_S_WIDTH;
else
info &= ~INFO_S_WIDTH;
if (inc_addr == BCM_DMA_INC_ADDR)
info |= INFO_S_INC;
else
info &= ~INFO_S_INC;
sc->sc_dma_ch[ch].cb->info = info;
return (0);
}
/*
* Setup DMA destination parameters
* ch - channel number
* dreq - hardware DREQ # or BCM_DMA_DREQ_NONE if
* destination is physical memory
* inc_addr - BCM_DMA_INC_ADDR if source address
* should be increased after each access or
* BCM_DMA_SAME_ADDR if address should remain
* the same
* width - size of write operation, BCM_DMA_32BIT
* for 32bit bursts, BCM_DMA_128BIT for 128 bits
*
* Returns 0 on success, -1 otherwise
*/
int
bcm_dma_setup_dst(int ch, int dreq, int inc_addr, int width)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
uint32_t info;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return (-1);
if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
return (-1);
info = sc->sc_dma_ch[ch].cb->info;
info &= ~INFO_PERMAP_MASK;
info |= (dreq << INFO_PERMAP_SHIFT) & INFO_PERMAP_MASK;
if (dreq)
info |= INFO_D_DREQ;
else
info &= ~INFO_D_DREQ;
if (width == BCM_DMA_128BIT)
info |= INFO_D_WIDTH;
else
info &= ~INFO_D_WIDTH;
if (inc_addr == BCM_DMA_INC_ADDR)
info |= INFO_D_INC;
else
info &= ~INFO_D_INC;
sc->sc_dma_ch[ch].cb->info = info;
return (0);
}
#ifdef DEBUG
void
bcm_dma_cb_dump(struct bcm_dma_cb *cb)
{
printf("DMA CB ");
printf("INFO: %8.8x ", cb->info);
printf("SRC: %8.8x ", cb->src);
printf("DST: %8.8x ", cb->dst);
printf("LEN: %8.8x ", cb->len);
printf("\n");
printf("STRIDE: %8.8x ", cb->stride);
printf("NEXT: %8.8x ", cb->next);
printf("RSVD1: %8.8x ", cb->rsvd1);
printf("RSVD2: %8.8x ", cb->rsvd2);
printf("\n");
}
void
bcm_dma_reg_dump(int ch)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
int i;
uint32_t reg;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return;
printf("DMA%d: ", ch);
for (i = 0; i < MAX_REG; i++) {
reg = bus_read_4(sc->sc_mem, BCM_DMA_CH(ch) + i*4);
printf("%8.8x ", reg);
}
printf("\n");
}
#endif
/*
* Start DMA transaction
* ch - channel number
* src, dst - source and destination address in
* ARM physical memory address space.
* len - amount of bytes to be transfered
*
* Returns 0 on success, -1 otherwise
*/
int
bcm_dma_start(int ch, vm_paddr_t src, vm_paddr_t dst, int len)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
struct bcm_dma_cb *cb;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return (-1);
if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
return (-1);
cb = sc->sc_dma_ch[ch].cb;
if (BCM2835_ARM_IS_IO(src))
cb->src = IO_TO_VCBUS(src);
else
cb->src = PHYS_TO_VCBUS(src);
if (BCM2835_ARM_IS_IO(dst))
cb->dst = IO_TO_VCBUS(dst);
else
cb->dst = PHYS_TO_VCBUS(dst);
cb->len = len;
bus_dmamap_sync(sc->sc_dma_tag,
sc->sc_dma_ch[ch].dma_map, BUS_DMASYNC_PREWRITE);
bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch),
sc->sc_dma_ch[ch].vc_cb);
bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), CS_ACTIVE);
#ifdef DEBUG
bcm_dma_cb_dump(sc->sc_dma_ch[ch].cb);
bcm_dma_reg_dump(ch);
#endif
return (0);
}
/*
* Get length requested for DMA transaction
* ch - channel number
*
* Returns size of transaction, 0 if channel is invalid
*/
uint32_t
bcm_dma_length(int ch)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
struct bcm_dma_cb *cb;
if (ch < 0 || ch >= BCM_DMA_CH_MAX)
return (0);
if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED))
return (0);
cb = sc->sc_dma_ch[ch].cb;
return (cb->len);
}
static void
bcm_dma_intr(void *arg)
{
struct bcm_dma_softc *sc = bcm_dma_sc;
struct bcm_dma_ch *ch = (struct bcm_dma_ch *)arg;
uint32_t cs, debug;
/* my interrupt? */
cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch->ch));
if (!(cs & (CS_INT | CS_ERR)))
return;
/* running? */
if (!(ch->flags & BCM_DMA_CH_USED)) {
device_printf(sc->sc_dev,
"unused DMA intr CH=%d, CS=%x\n", ch->ch, cs);
return;
}
if (cs & CS_ERR) {
debug = bus_read_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch));
device_printf(sc->sc_dev, "DMA error %d on CH%d\n",
debug & DEBUG_ERROR_MASK, ch->ch);
bus_write_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch),
debug & DEBUG_ERROR_MASK);
}
if (cs & CS_INT) {
/* acknowledge interrupt */
bus_write_4(sc->sc_mem, BCM_DMA_CS(ch->ch),
CS_INT | CS_END);
/* Prepare for possible access to len field */
bus_dmamap_sync(sc->sc_dma_tag, ch->dma_map,
BUS_DMASYNC_POSTWRITE);
/* save callback function and argument */
if (ch->intr_func)
ch->intr_func(ch->ch, ch->intr_arg);
}
}
static int
bcm_dma_probe(device_t dev)
{
if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-dma"))
return (ENXIO);
device_set_desc(dev, "BCM2835 DMA Controller");
return (BUS_PROBE_DEFAULT);
}
static int
bcm_dma_attach(device_t dev)
{
struct bcm_dma_softc *sc = device_get_softc(dev);
int rid, err = 0;
int i;
sc->sc_dev = dev;
if (bcm_dma_sc)
return (ENXIO);
for (i = 0; i < BCM_DMA_CH_MAX; i++) {
sc->sc_irq[i] = NULL;
sc->sc_intrhand[i] = NULL;
}
/* DMA0 - DMA14 */
rid = 0;
sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (sc->sc_mem == NULL) {
device_printf(dev, "could not allocate memory resource\n");
return (ENXIO);
}
/* IRQ DMA0 - DMA11 XXX NOT USE DMA12(spurious?) */
for (rid = 0; rid < BCM_DMA_CH_MAX; rid++) {
sc->sc_irq[rid] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_ACTIVE);
if (sc->sc_irq[rid] == NULL) {
device_printf(dev, "cannot allocate interrupt\n");
err = ENXIO;
goto fail;
}
if (bus_setup_intr(dev, sc->sc_irq[rid], INTR_TYPE_MISC | INTR_MPSAFE,
NULL, bcm_dma_intr, &sc->sc_dma_ch[rid],
&sc->sc_intrhand[rid])) {
device_printf(dev, "cannot setup interrupt handler\n");
err = ENXIO;
goto fail;
}
}
mtx_init(&sc->sc_mtx, "bcmdma", "bcmdma", MTX_DEF);
bcm_dma_sc = sc;
err = bcm_dma_init(dev);
if (err)
goto fail;
return (err);
fail:
if (sc->sc_mem)
bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem);
for (i = 0; i < BCM_DMA_CH_MAX; i++) {
if (sc->sc_intrhand[i])
bus_teardown_intr(dev, sc->sc_irq[i], sc->sc_intrhand[i]);
if (sc->sc_irq[i])
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq[i]);
}
return (err);
}
static device_method_t bcm_dma_methods[] = {
DEVMETHOD(device_probe, bcm_dma_probe),
DEVMETHOD(device_attach, bcm_dma_attach),
{ 0, 0 }
};
static driver_t bcm_dma_driver = {
"bcm_dma",
bcm_dma_methods,
sizeof(struct bcm_dma_softc),
};
static devclass_t bcm_dma_devclass;
DRIVER_MODULE(bcm_dma, simplebus, bcm_dma_driver, bcm_dma_devclass, 0, 0);
MODULE_VERSION(bcm_dma, 1);

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2013 Daisuke Aoyama <aoyama@peach.ne.jp>
* Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@bluezbox.com>
*
* 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_DMA_H_
#define _BCM2835_DMA_H_
#define BCM_DMA_BLOCK_SIZE 512
/* DMA0-DMA15 but DMA15 is special */
#define BCM_DMA_CH_MAX 12
/* request CH for any nubmer */
#define BCM_DMA_CH_INVALID (-1)
#define BCM_DMA_CH_ANY (-1)
#define BCM_DMA_CH_FAST1 (2)
#define BCM_DMA_CH_FAST2 (3)
/* Peripheral DREQ Signals (4.2.1.3) */
#define BCM_DMA_DREQ_NONE 0
#define BCM_DMA_DREQ_EMMC 11
#define BCM_DMA_DREQ_SDHOST 13
#define BCM_DMA_SAME_ADDR 0
#define BCM_DMA_INC_ADDR 1
#define BCM_DMA_32BIT 0
#define BCM_DMA_128BIT 1
int bcm_dma_allocate(int req_ch);
int bcm_dma_free(int ch);
int bcm_dma_setup_intr(int ch, void (*func)(int, void *), void *arg);
int bcm_dma_setup_src(int ch, int dreq, int inc_addr, int width);
int bcm_dma_setup_dst(int ch, int dreq, int inc_addr, int width);
int bcm_dma_start(int ch, vm_paddr_t src, vm_paddr_t dst, int len);
uint32_t bcm_dma_length(int ch);
#endif /* _BCM2835_DMA_H_ */

View File

@ -67,8 +67,13 @@ __FBSDID("$FreeBSD$");
#include <dev/sdhci/sdhci.h>
#include "sdhci_if.h"
#include "bcm2835_dma.h"
#include "bcm2835_vcbus.h"
#define BCM2835_DEFAULT_SDHCI_FREQ 50
#define BCM_SDHCI_BUFFER_SIZE 512
#define DEBUG
#ifdef DEBUG
@ -85,9 +90,11 @@ __FBSDID("$FreeBSD$");
*/
static int bcm2835_sdhci_min_freq = 400000;
static int bcm2835_sdhci_hs = 1;
static int bcm2835_sdhci_pio_mode = 0;
TUNABLE_INT("hw.bcm2835.sdhci.min_freq", &bcm2835_sdhci_min_freq);
TUNABLE_INT("hw.bcm2835.sdhci.hs", &bcm2835_sdhci_hs);
TUNABLE_INT("hw.bcm2835.sdhci.pio_mode", &bcm2835_sdhci_pio_mode);
struct bcm_sdhci_dmamap_arg {
bus_addr_t sc_dma_busaddr;
@ -111,23 +118,41 @@ struct bcm_sdhci_softc {
int sc_xfer_done;
int sc_bus_busy;
struct sdhci_slot sc_slot;
int sc_dma_inuse;
int sc_dma_ch;
bus_dma_tag_t sc_dma_tag;
bus_dmamap_t sc_dma_map;
void *sc_dma_buffer;
vm_paddr_t sc_dma_buffer_phys;
vm_paddr_t sc_sdhci_buffer_phys;;
};
#define SD_MAX_BLOCKSIZE 1024
/* XXX */
static int bcm_sdhci_probe(device_t);
static int bcm_sdhci_attach(device_t);
static int bcm_sdhci_detach(device_t);
static void bcm_sdhci_intr(void *);
static int bcm_sdhci_get_ro(device_t, device_t);
static void bcm_sdhci_dma_intr(int ch, void *arg);
#define bcm_sdhci_lock(_sc) \
mtx_lock(&_sc->sc_mtx);
#define bcm_sdhci_unlock(_sc) \
mtx_unlock(&_sc->sc_mtx);
static void
bcm_dmamap_cb(void *arg, bus_dma_segment_t *segs,
int nseg, int err)
{
bus_addr_t *addr;
if (err)
return;
addr = (bus_addr_t*)arg;
*addr = segs[0].ds_addr;
}
static int
bcm_sdhci_probe(device_t dev)
{
@ -146,9 +171,13 @@ bcm_sdhci_attach(device_t dev)
phandle_t node;
pcell_t cell;
int default_freq;
void *buffer;
vm_paddr_t buffer_phys;
void *va;
sc->sc_dev = dev;
sc->sc_req = NULL;
err = 0;
default_freq = BCM2835_DEFAULT_SDHCI_FREQ;
node = ofw_bus_get_node(sc->sc_dev);
@ -191,6 +220,9 @@ bcm_sdhci_attach(device_t dev)
goto fail;
}
if (!bcm2835_sdhci_pio_mode)
sc->sc_slot.opt = SDHCI_PLATFORM_TRANSFER;
sc->sc_slot.caps = SDHCI_CAN_VDD_330 | SDHCI_CAN_VDD_180;
if (bcm2835_sdhci_hs)
sc->sc_slot.caps |= SDHCI_CAN_DO_HISPD;
@ -201,6 +233,61 @@ bcm_sdhci_attach(device_t dev)
sdhci_init_slot(dev, &sc->sc_slot, 0);
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST1);
if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_FAST2);
if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
sc->sc_dma_ch = bcm_dma_allocate(BCM_DMA_CH_ANY);
if (sc->sc_dma_ch == BCM_DMA_CH_INVALID)
goto fail;
bcm_dma_setup_intr(sc->sc_dma_ch, bcm_sdhci_dma_intr, sc);
/* Allocate DMA buffers */
err = bus_dma_tag_create(bus_get_dma_tag(dev),
1, 0, BUS_SPACE_MAXADDR_32BIT,
BUS_SPACE_MAXADDR, NULL, NULL,
BCM_SDHCI_BUFFER_SIZE, 1, BCM_SDHCI_BUFFER_SIZE,
BUS_DMA_ALLOCNOW, NULL, NULL,
&sc->sc_dma_tag);
if (err) {
device_printf(dev, "failed allocate DMA tag");
goto fail;
}
err = bus_dmamem_alloc(sc->sc_dma_tag, &buffer,
BUS_DMA_WAITOK | BUS_DMA_COHERENT| BUS_DMA_ZERO,
&sc->sc_dma_map);
if (err) {
device_printf(dev, "cannot allocate DMA memory\n");
goto fail;
}
err = bus_dmamap_load(sc->sc_dma_tag, sc->sc_dma_map, buffer,
BCM_SDHCI_BUFFER_SIZE, bcm_dmamap_cb, &buffer_phys,
BUS_DMA_WAITOK);
if (err) {
device_printf(dev, "cannot load DMA memory\n");
goto fail;
}
/*
* Sanity check: two least bits of address should be zero
*/
if ((uintptr_t)buffer & 3) {
device_printf(dev,
"DMA address is not word-aligned\n");
goto fail;
}
sc->sc_dma_buffer = buffer;
sc->sc_dma_buffer_phys = buffer_phys;
va = (void*)rman_get_start(sc->sc_mem_res);
sc->sc_sdhci_buffer_phys =
pmap_kextract((vm_offset_t)va) + SDHCI_BUFFER;
bus_generic_probe(dev);
bus_generic_attach(dev);
@ -354,6 +441,211 @@ bcm_sdhci_min_freq(device_t dev, struct sdhci_slot *slot)
return bcm2835_sdhci_min_freq;
}
static void
bcm_sdhci_dma_intr(int ch, void *arg)
{
struct bcm_sdhci_softc *sc = (struct bcm_sdhci_softc *)arg;
struct sdhci_slot *slot = &sc->sc_slot;
uint32_t reg, mask;
void *buffer;
size_t len;
int left;
mtx_lock(&slot->mtx);
/* copy DMA buffer to VA if READ */
len = bcm_dma_length(sc->sc_dma_ch);
if (slot->curcmd->data->flags & MMC_DATA_READ) {
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
BUS_DMASYNC_POSTREAD);
mask = SDHCI_INT_DATA_AVAIL;
/* all dma data in single or contiguous page */
buffer = (uint8_t*)(slot->curcmd->data->data) + slot->offset;
memcpy(buffer, sc->sc_dma_buffer, len);
} else {
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
BUS_DMASYNC_POSTWRITE);
mask = SDHCI_INT_SPACE_AVAIL;
}
slot->offset += len;
sc->sc_dma_inuse = 0;
left = min(BCM_SDHCI_BUFFER_SIZE,
slot->curcmd->data->len - slot->offset);
/* DATA END? */
reg = bcm_sdhci_read_4(slot->bus, slot, SDHCI_INT_STATUS);
if (reg & SDHCI_INT_DATA_END) {
/* ACK for all outstanding interrupts */
bcm_sdhci_write_4(slot->bus, slot, SDHCI_INT_STATUS, reg);
/* enable INT */
slot->intmask |= SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL
| SDHCI_INT_DATA_END;
bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
slot->intmask);
/* finish this data */
sdhci_finish_data(slot);
}
else {
/* already available? */
if (reg & mask) {
sc->sc_dma_inuse = 1;
/* ACK for DATA_AVAIL or SPACE_AVAIL */
bcm_sdhci_write_4(slot->bus, slot,
SDHCI_INT_STATUS, mask);
/* continue next DMA transfer */
if (slot->curcmd->data->flags & MMC_DATA_READ) {
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
BUS_DMASYNC_PREREAD);
/* DMA start */
if (bcm_dma_start(sc->sc_dma_ch,
sc->sc_sdhci_buffer_phys,
sc->sc_dma_buffer_phys, left) != 0)
device_printf(sc->sc_dev, "failed DMA start\n");
} else {
buffer = (char*)slot->curcmd->data->data + slot->offset;
memcpy(sc->sc_dma_buffer, buffer, left);
bus_dmamap_sync(sc->sc_dma_tag,
sc->sc_dma_map, BUS_DMASYNC_PREWRITE);
/* DMA start */
if (bcm_dma_start(sc->sc_dma_ch,
sc->sc_dma_buffer_phys,
sc->sc_sdhci_buffer_phys, left) != 0)
device_printf(sc->sc_dev, "failed DMA start\n");
}
} else {
/* wait for next data by INT */
/* enable INT */
slot->intmask |= SDHCI_INT_DATA_AVAIL |
SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END;
bcm_sdhci_write_4(slot->bus, slot, SDHCI_SIGNAL_ENABLE,
slot->intmask);
}
}
mtx_unlock(&slot->mtx);
}
static void
bcm_sdhci_read_dma(struct sdhci_slot *slot)
{
struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
size_t left;
if (sc->sc_dma_inuse) {
device_printf(sc->sc_dev, "DMA in use\n");
return;
}
sc->sc_dma_inuse = 1;
left = min(BCM_SDHCI_BUFFER_SIZE,
slot->curcmd->data->len - slot->offset);
KASSERT((left & 3) == 0,
("%s: len = %d, not word-aligned", __func__, left));
bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
BCM_DMA_INC_ADDR,
(left & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
BUS_DMASYNC_PREREAD);
/* DMA start */
if (bcm_dma_start(sc->sc_dma_ch, sc->sc_sdhci_buffer_phys,
sc->sc_dma_buffer_phys, left) != 0)
device_printf(sc->sc_dev, "failed DMA start\n");
}
static void
bcm_sdhci_write_dma(struct sdhci_slot *slot)
{
struct bcm_sdhci_softc *sc = device_get_softc(slot->bus);
char *buffer;
size_t left;
if (sc->sc_dma_inuse) {
device_printf(sc->sc_dev, "DMA in use\n");
return;
}
sc->sc_dma_inuse = 1;
left = min(BCM_SDHCI_BUFFER_SIZE,
slot->curcmd->data->len - slot->offset);
KASSERT((left & 3) == 0,
("%s: len = %d, not word-aligned", __func__, left));
buffer = (char*)slot->curcmd->data->data + slot->offset;
memcpy(sc->sc_dma_buffer, buffer, left);
bcm_dma_setup_src(sc->sc_dma_ch, BCM_DMA_DREQ_NONE,
BCM_DMA_INC_ADDR,
(left & 0xf) ? BCM_DMA_32BIT : BCM_DMA_128BIT);
bcm_dma_setup_dst(sc->sc_dma_ch, BCM_DMA_DREQ_EMMC,
BCM_DMA_SAME_ADDR, BCM_DMA_32BIT);
bus_dmamap_sync(sc->sc_dma_tag, sc->sc_dma_map,
BUS_DMASYNC_PREWRITE);
/* DMA start */
if (bcm_dma_start(sc->sc_dma_ch, sc->sc_dma_buffer_phys,
sc->sc_sdhci_buffer_phys, left) != 0)
device_printf(sc->sc_dev, "failed DMA start\n");
}
static int
bcm_sdhci_will_handle_transfer(device_t dev, struct sdhci_slot *slot)
{
size_t left;
/* Do not use DMA for transfers less then block size */
left = min(BCM_DMA_BLOCK_SIZE,
slot->curcmd->data->len - slot->offset);
if (left < BCM_DMA_BLOCK_SIZE)
return (0);
return (1);
}
static void
bcm_sdhci_start_transfer(device_t dev, struct sdhci_slot *slot,
uint32_t *intmask)
{
/* Disable INT */
slot->intmask &= ~(SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_END);
bcm_sdhci_write_4(dev, slot, SDHCI_SIGNAL_ENABLE, slot->intmask);
/* DMA transfer FIFO 1KB */
if (slot->curcmd->data->flags & MMC_DATA_READ)
bcm_sdhci_read_dma(slot);
else
bcm_sdhci_write_dma(slot);
}
static void
bcm_sdhci_finish_transfer(device_t dev, struct sdhci_slot *slot)
{
sdhci_finish_data(slot);
}
static device_method_t bcm_sdhci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, bcm_sdhci_probe),
@ -372,8 +664,12 @@ static device_method_t bcm_sdhci_methods[] = {
DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host),
DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host),
/* SDHCI registers accessors */
DEVMETHOD(sdhci_min_freq, bcm_sdhci_min_freq),
/* Platform transfer methods */
DEVMETHOD(sdhci_platform_will_handle, bcm_sdhci_will_handle_transfer),
DEVMETHOD(sdhci_platform_start_transfer, bcm_sdhci_start_transfer),
DEVMETHOD(sdhci_platform_finish_transfer, bcm_sdhci_finish_transfer),
/* SDHCI registers accessors */
DEVMETHOD(sdhci_read_1, bcm_sdhci_read_1),
DEVMETHOD(sdhci_read_2, bcm_sdhci_read_2),
DEVMETHOD(sdhci_read_4, bcm_sdhci_read_4),

View File

@ -118,19 +118,16 @@ bcm_systimer_tc_get_timecount(struct timecounter *tc)
}
static int
bcm_systimer_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
bcm_systimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct systimer *st = et->et_priv;
uint32_t clo;
uint32_t count;
register_t s;
if (first != NULL) {
if (first != 0) {
count = (st->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
count += st->et.et_frequency * first->sec;
count = ((uint32_t)et->et_frequency * first) >> 32;
s = intr_disable();
clo = bcm_systimer_tc_read_4(SYSTIMER_CLO);
@ -238,12 +235,10 @@ bcm_systimer_attach(device_t dev)
sc->st[DEFAULT_TIMER].et.et_flags = ET_FLAGS_ONESHOT;
sc->st[DEFAULT_TIMER].et.et_quality = 1000;
sc->st[DEFAULT_TIMER].et.et_frequency = sc->sysclk_freq;
sc->st[DEFAULT_TIMER].et.et_min_period.sec = 0;
sc->st[DEFAULT_TIMER].et.et_min_period.frac =
((MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) << 32;
sc->st[DEFAULT_TIMER].et.et_max_period.sec = 0xfffffff0U / sc->st[DEFAULT_TIMER].et.et_frequency;
sc->st[DEFAULT_TIMER].et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) << 32;
sc->st[DEFAULT_TIMER].et.et_min_period =
(MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
sc->st[DEFAULT_TIMER].et.et_max_period =
(0xfffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
sc->st[DEFAULT_TIMER].et.et_start = bcm_systimer_start;
sc->st[DEFAULT_TIMER].et.et_stop = bcm_systimer_stop;
sc->st[DEFAULT_TIMER].et.et_priv = &sc->st[DEFAULT_TIMER];

View File

@ -1,5 +1,6 @@
# $FreeBSD$
arm/broadcom/bcm2835/bcm2835_dma.c standard
arm/broadcom/bcm2835/bcm2835_fb.c optional sc
arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio
arm/broadcom/bcm2835/bcm2835_intr.c standard

View File

@ -87,8 +87,8 @@ options ROOTDEVNAME=\"ufs:/dev/da0s2\"
#options ATA_STATIC_ID # Static device numbering
# Console and misc
#device uart
#device uart_ns8250
device uart
device uart_ns8250
device pty
device snp
device md

View File

@ -117,4 +117,4 @@ options FDT
# Note: DTB is normally loaded and modified by RPi boot loader, then
# handed to kernel via U-Boot and ubldr.
#options FDT_DTB_STATIC
#makeoptions FDT_DTS_FILE=bcm2835-rpi-b.dts
makeoptions FDT_DTS_FILE=bcm2835-rpi-b.dts

View File

@ -68,7 +68,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -34,9 +34,32 @@
#ifndef _MACHINE_VMPARAM_H_
#define _MACHINE_VMPARAM_H_
/*
* Machine dependent constants for ARM.
*/
/*
* Virtual memory related constants, all in bytes
*/
#ifndef MAXTSIZ
#define MAXTSIZ (64UL*1024*1024) /* max text size */
#endif
#ifndef DFLDSIZ
#define DFLDSIZ (128UL*1024*1024) /* initial data size limit */
#endif
#ifndef MAXDSIZ
#define MAXDSIZ (512UL*1024*1024) /* max data size */
#endif
#ifndef DFLSSIZ
#define DFLSSIZ (2UL*1024*1024) /* initial stack size limit */
#endif
#ifndef MAXSSIZ
#define MAXSSIZ (8UL*1024*1024) /* max stack size */
#endif
#ifndef SGROWSIZ
#define SGROWSIZ (128UL*1024) /* amount to grow stack */
#endif
/*#include <arm/arm32/vmparam.h>
*/
/*
* Address space constants
*/
@ -153,23 +176,6 @@
VM_MIN_KERNEL_ADDRESS + 1) * 2 / 5)
#endif
#define MAXTSIZ (16*1024*1024)
#ifndef DFLDSIZ
#define DFLDSIZ (128*1024*1024)
#endif
#ifndef MAXDSIZ
#define MAXDSIZ (512*1024*1024)
#endif
#ifndef DFLSSIZ
#define DFLSSIZ (2*1024*1024)
#endif
#ifndef MAXSSIZ
#define MAXSSIZ (8*1024*1024)
#endif
#ifndef SGROWSIZ
#define SGROWSIZ (128*1024)
#endif
#ifdef ARM_USE_SMALL_ALLOC
#define UMA_MD_SMALL_ALLOC
#endif /* ARM_USE_SMALL_ALLOC */
@ -178,4 +184,8 @@ extern vm_offset_t vm_max_kernel_address;
#define ZERO_REGION_SIZE (64 * 1024) /* 64KB */
#ifndef VM_MAX_AUTOTUNE_MAXUSERS
#define VM_MAX_AUTOTUNE_MAXUSERS 384
#endif
#endif /* _MACHINE_VMPARAM_H_ */

View File

@ -72,8 +72,8 @@ static struct lpc_timer_softc *timer_softc = NULL;
static int lpc_timer_initialized = 0;
static int lpc_timer_probe(device_t);
static int lpc_timer_attach(device_t);
static int lpc_timer_start(struct eventtimer *, struct bintime *first,
struct bintime *);
static int lpc_timer_start(struct eventtimer *,
sbintime_t first, sbintime_t period);
static int lpc_timer_stop(struct eventtimer *et);
static unsigned lpc_get_timecount(struct timecounter *);
static int lpc_hardclock(void *);
@ -173,12 +173,8 @@ lpc_timer_attach(device_t dev)
sc->lt_et.et_name = "LPC32x0 Timer0";
sc->lt_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->lt_et.et_quality = 1000;
sc->lt_et.et_min_period.sec = 0;
sc->lt_et.et_min_period.frac =
((0x00000002LLU << 32) / sc->lt_et.et_frequency) << 32;
sc->lt_et.et_max_period.sec = 0xfffffff0U / sc->lt_et.et_frequency;
sc->lt_et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->lt_et.et_frequency) << 32;
sc->lt_et.et_min_period = (0x00000002LLU << 32) / sc->lt_et.et_frequency;
sc->lt_et.et_max_period = (0xfffffffeLLU << 32) / sc->lt_et.et_frequency;
sc->lt_et.et_start = lpc_timer_start;
sc->lt_et.et_stop = lpc_timer_stop;
sc->lt_et.et_priv = sc;
@ -199,27 +195,23 @@ lpc_timer_attach(device_t dev)
}
static int
lpc_timer_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
lpc_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct lpc_timer_softc *sc = (struct lpc_timer_softc *)et->et_priv;
uint32_t ticks;
if (period == NULL)
if (period == 0) {
sc->lt_oneshot = 1;
else {
sc->lt_period = 0;
} else {
sc->lt_oneshot = 0;
sc->lt_period = (sc->lt_et.et_frequency * (first->frac >> 32)) >> 32;
sc->lt_period += sc->lt_et.et_frequency * first->sec;
sc->lt_period = ((uint32_t)et->et_frequency * period) >> 32;
}
if (first == NULL)
if (first == 0)
ticks = sc->lt_period;
else {
ticks = (sc->lt_et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
ticks += sc->lt_et.et_frequency * first->sec;
}
else
ticks = ((uint32_t)et->et_frequency * first) >> 32;
/* Reset timer */
timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_RESET);

View File

@ -93,7 +93,7 @@ static void mv_watchdog_enable(void);
static void mv_watchdog_disable(void);
static void mv_watchdog_event(void *, unsigned int, int *);
static int mv_timer_start(struct eventtimer *et,
struct bintime *first, struct bintime *period);
sbintime_t first, sbintime_t period);
static int mv_timer_stop(struct eventtimer *et);
static void mv_setup_timers(void);
@ -168,12 +168,8 @@ mv_timer_attach(device_t dev)
sc->et.et_quality = 1000;
sc->et.et_frequency = MV_CLOCK_SRC;
sc->et.et_min_period.sec = 0;
sc->et.et_min_period.frac =
((0x00000002LLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
sc->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = mv_timer_start;
sc->et.et_stop = mv_timer_stop;
sc->et.et_priv = sc;
@ -394,25 +390,20 @@ mv_watchdog_event(void *arg, unsigned int cmd, int *error)
}
static int
mv_timer_start(struct eventtimer *et,
struct bintime *first, struct bintime *period)
mv_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct mv_timer_softc *sc;
uint32_t val, val1;
/* Calculate dividers. */
sc = (struct mv_timer_softc *)et->et_priv;
if (period != NULL) {
val = (sc->et.et_frequency * (period->frac >> 32)) >> 32;
if (period->sec != 0)
val += sc->et.et_frequency * period->sec;
} else
if (period != 0)
val = ((uint32_t)sc->et.et_frequency * period) >> 32;
else
val = 0;
if (first != NULL) {
val1 = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
val1 += sc->et.et_frequency * first->sec;
} else
if (first != 0)
val1 = ((uint32_t)sc->et.et_frequency * first) >> 32;
else
val1 = val;
/* Apply configuration. */
@ -420,7 +411,7 @@ mv_timer_start(struct eventtimer *et,
mv_set_timer(0, val1);
val = mv_get_timer_control();
val |= CPU_TIMER0_EN;
if (period != NULL)
if (period != 0)
val |= CPU_TIMER0_AUTO;
else
val &= ~CPU_TIMER0_AUTO;

View File

@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -143,30 +143,24 @@ am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
}
static int
am335x_dmtimer_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
am335x_dmtimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)et->et_priv;
uint32_t load, count;
uint32_t tclr = 0;
if (period != NULL) {
load = (et->et_frequency * (period->frac >> 32)) >> 32;
if (period->sec > 0)
load += et->et_frequency * period->sec;
if (period != 0) {
load = ((uint32_t)et->et_frequency * period) >> 32;
tclr |= 2; /* autoreload bit */
panic("periodic timer not implemented\n");
} else {
load = 0;
}
if (first != NULL) {
count = (tmr->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
count += tmr->et.et_frequency * first->sec;
} else {
if (first != 0)
count = ((uint32_t)et->et_frequency * first) >> 32;
else
count = load;
}
/* Reset Timer */
am335x_dmtimer_et_write_4(DMTIMER_TSICR, 2);
@ -316,12 +310,10 @@ am335x_dmtimer_attach(device_t dev)
sc->t[3].et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->t[3].et.et_quality = 1000;
sc->t[3].et.et_frequency = sc->sysclk_freq;
sc->t[3].et.et_min_period.sec = 0;
sc->t[3].et.et_min_period.frac =
((0x00000002LLU << 32) / sc->t[3].et.et_frequency) << 32;
sc->t[3].et.et_max_period.sec = 0xfffffff0U / sc->t[3].et.et_frequency;
sc->t[3].et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->t[3].et.et_frequency) << 32;
sc->t[3].et.et_min_period =
(0x00000002LLU << 32) / sc->t[3].et.et_frequency;
sc->t[3].et.et_max_period =
(0xfffffffeLLU << 32) / sc->t[3].et.et_frequency;
sc->t[3].et.et_start = am335x_dmtimer_start;
sc->t[3].et.et_stop = am335x_dmtimer_stop;
sc->t[3].et.et_priv = &sc->t[3];

View File

@ -120,18 +120,15 @@ sp804_timer_tc_get_timecount(struct timecounter *tc)
}
static int
sp804_timer_start(struct eventtimer *et, struct bintime *first,
struct bintime *period)
sp804_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct sp804_timer_softc *sc = et->et_priv;
uint32_t count, reg;
if (first != NULL) {
if (first != 0) {
sc->et_enabled = 1;
count = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
if (first->sec != 0)
count += sc->et.et_frequency * first->sec;
count = ((uint32_t)et->et_frequency * first) >> 32;
sp804_timer_tc_write_4(SP804_TIMER2_LOAD, count);
reg = TIMER_CONTROL_32BIT | TIMER_CONTROL_INTREN |
@ -142,7 +139,7 @@ sp804_timer_start(struct eventtimer *et, struct bintime *first,
return (0);
}
if (period != NULL) {
if (period != 0) {
panic("period");
}
@ -264,12 +261,8 @@ sp804_timer_attach(device_t dev)
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->et.et_quality = 1000;
sc->et.et_frequency = sc->sysclk_freq / DEFAULT_DIVISOR;
sc->et.et_min_period.sec = 0;
sc->et.et_min_period.frac =
((0x00000002LLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
sc->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = sp804_timer_start;
sc->et.et_stop = sp804_timer_stop;
sc->et.et_priv = sc;

View File

@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -78,7 +78,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -80,7 +80,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <machine/pmap.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/undefined.h>

View File

@ -121,6 +121,8 @@
interrupt-parent = <&AINTC>;
current-speed = <115200>;
clock-frequency = < 24000000 >;
busy-detect = <1>;
broken-txfifo = <1>;
};
};

View File

@ -588,7 +588,7 @@
#define AUE_OPENAT 43184 /* FreeBSD. */
#define AUE_POSIX_OPENPT 43185 /* FreeBSD. */
#define AUE_CAP_NEW 43186 /* TrustedBSD. */
#define AUE_CAP_GETRIGHTS 43187 /* TrustedBSD. */
#define AUE_CAP_RIGHTS_GET 43187 /* TrustedBSD. */
#define AUE_CAP_ENTER 43188 /* TrustedBSD. */
#define AUE_CAP_GETMODE 43189 /* TrustedBSD. */
#define AUE_POSIX_SPAWN 43190 /* Darwin. */
@ -603,6 +603,11 @@
#define AUE_PDGETPID 43199 /* FreeBSD. */
#define AUE_PDWAIT 43200 /* FreeBSD. */
#define AUE_WAIT6 43201 /* FreeBSD. */
#define AUE_CAP_RIGHTS_LIMIT 43202 /* TrustedBSD. */
#define AUE_CAP_IOCTLS_LIMIT 43203 /* TrustedBSD. */
#define AUE_CAP_IOCTLS_GET 43204 /* TrustedBSD. */
#define AUE_CAP_FCNTLS_LIMIT 43205 /* TrustedBSD. */
#define AUE_CAP_FCNTLS_GET 43206 /* TrustedBSD. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the

View File

@ -39,15 +39,11 @@ typedef struct file file_t;
#include <sys/capability.h>
static __inline file_t *
getf(int fd)
getf(int fd, cap_rights_t rights)
{
struct file *fp;
/*
* We wouldn't need all of these rights on every invocation
* if we had more information about intent.
*/
if (fget(curthread, fd, CAP_READ | CAP_WRITE | CAP_SEEK, &fp) == 0)
if (fget(curthread, fd, rights, &fp) == 0)
return (fp);
return (NULL);
}

View File

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2010 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Portions Copyright 2005, 2010, Oracle and/or its affiliates.
* All rights reserved.
* Use is subject to license terms.
@ -35,22 +35,100 @@
#include <sys/zfs_ioctl.h>
#include "zfs_ioctl_compat.h"
static int zfs_version_ioctl = ZFS_IOCVER_CURRENT;
SYSCTL_DECL(_vfs_zfs_version);
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl,
0, "ZFS_IOCTL_VERSION");
/*
* FreeBSD zfs_cmd compatibility with v15 and older binaries
* FreeBSD zfs_cmd compatibility with older binaries
* appropriately remap/extend the zfs_cmd_t structure
*/
void
zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
{
zfs_cmd_v15_t *zc_c;
zfs_cmd_v28_t *zc28_c;
if (cflag == ZFS_CMD_COMPAT_V15) {
switch (cflag) {
case ZFS_CMD_COMPAT_V28:
zc28_c = (void *)addr;
/* zc */
strlcpy(zc->zc_name, zc28_c->zc_name, MAXPATHLEN);
strlcpy(zc->zc_value, zc28_c->zc_value, MAXPATHLEN * 2);
strlcpy(zc->zc_string, zc28_c->zc_string, MAXPATHLEN);
strlcpy(zc->zc_top_ds, zc28_c->zc_top_ds, MAXPATHLEN);
zc->zc_guid = zc28_c->zc_guid;
zc->zc_nvlist_conf = zc28_c->zc_nvlist_conf;
zc->zc_nvlist_conf_size = zc28_c->zc_nvlist_conf_size;
zc->zc_nvlist_src = zc28_c->zc_nvlist_src;
zc->zc_nvlist_src_size = zc28_c->zc_nvlist_src_size;
zc->zc_nvlist_dst = zc28_c->zc_nvlist_dst;
zc->zc_nvlist_dst_size = zc28_c->zc_nvlist_dst_size;
zc->zc_cookie = zc28_c->zc_cookie;
zc->zc_objset_type = zc28_c->zc_objset_type;
zc->zc_perm_action = zc28_c->zc_perm_action;
zc->zc_history = zc28_c->zc_history;
zc->zc_history_len = zc28_c->zc_history_len;
zc->zc_history_offset = zc28_c->zc_history_offset;
zc->zc_obj = zc28_c->zc_obj;
zc->zc_iflags = zc28_c->zc_iflags;
zc->zc_share = zc28_c->zc_share;
zc->zc_jailid = zc28_c->zc_jailid;
zc->zc_objset_stats = zc28_c->zc_objset_stats;
zc->zc_begin_record = zc28_c->zc_begin_record;
zc->zc_defer_destroy = zc28_c->zc_defer_destroy;
zc->zc_temphold = zc28_c->zc_temphold;
zc->zc_action_handle = zc28_c->zc_action_handle;
zc->zc_cleanup_fd = zc28_c->zc_cleanup_fd;
zc->zc_simple = zc28_c->zc_simple;
bcopy(zc28_c->zc_pad, zc->zc_pad, sizeof(zc->zc_pad));
zc->zc_sendobj = zc28_c->zc_sendobj;
zc->zc_fromobj = zc28_c->zc_fromobj;
zc->zc_createtxg = zc28_c->zc_createtxg;
zc->zc_stat = zc28_c->zc_stat;
/* zc->zc_inject_record */
zc->zc_inject_record.zi_objset =
zc28_c->zc_inject_record.zi_objset;
zc->zc_inject_record.zi_object =
zc28_c->zc_inject_record.zi_object;
zc->zc_inject_record.zi_start =
zc28_c->zc_inject_record.zi_start;
zc->zc_inject_record.zi_end =
zc28_c->zc_inject_record.zi_end;
zc->zc_inject_record.zi_guid =
zc28_c->zc_inject_record.zi_guid;
zc->zc_inject_record.zi_level =
zc28_c->zc_inject_record.zi_level;
zc->zc_inject_record.zi_error =
zc28_c->zc_inject_record.zi_error;
zc->zc_inject_record.zi_type =
zc28_c->zc_inject_record.zi_type;
zc->zc_inject_record.zi_freq =
zc28_c->zc_inject_record.zi_freq;
zc->zc_inject_record.zi_failfast =
zc28_c->zc_inject_record.zi_failfast;
strlcpy(zc->zc_inject_record.zi_func,
zc28_c->zc_inject_record.zi_func, MAXNAMELEN);
zc->zc_inject_record.zi_iotype =
zc28_c->zc_inject_record.zi_iotype;
zc->zc_inject_record.zi_duration =
zc28_c->zc_inject_record.zi_duration;
zc->zc_inject_record.zi_timer =
zc28_c->zc_inject_record.zi_timer;
zc->zc_inject_record.zi_cmd = ZINJECT_UNINITIALIZED;
zc->zc_inject_record.zi_pad = 0;
break;
case ZFS_CMD_COMPAT_V15:
zc_c = (void *)addr;
/* zc */
strlcpy(zc->zc_name,zc_c->zc_name,MAXPATHLEN);
strlcpy(zc->zc_value,zc_c->zc_value,MAXPATHLEN);
strlcpy(zc->zc_string,zc_c->zc_string,MAXPATHLEN);
strlcpy(zc->zc_name, zc_c->zc_name, MAXPATHLEN);
strlcpy(zc->zc_value, zc_c->zc_value, MAXPATHLEN);
strlcpy(zc->zc_string, zc_c->zc_string, MAXPATHLEN);
zc->zc_guid = zc_c->zc_guid;
zc->zc_nvlist_conf = zc_c->zc_nvlist_conf;
zc->zc_nvlist_conf_size = zc_c->zc_nvlist_conf_size;
@ -91,6 +169,7 @@ zfs_cmd_compat_get(zfs_cmd_t *zc, caddr_t addr, const int cflag)
zc_c->zc_inject_record.zi_freq;
zc->zc_inject_record.zi_failfast =
zc_c->zc_inject_record.zi_failfast;
break;
}
}
@ -98,15 +177,84 @@ void
zfs_cmd_compat_put(zfs_cmd_t *zc, caddr_t addr, const int cflag)
{
zfs_cmd_v15_t *zc_c;
zfs_cmd_v28_t *zc28_c;
switch (cflag) {
case ZFS_CMD_COMPAT_V28:
zc28_c = (void *)addr;
strlcpy(zc28_c->zc_name, zc->zc_name, MAXPATHLEN);
strlcpy(zc28_c->zc_value, zc->zc_value, MAXPATHLEN * 2);
strlcpy(zc28_c->zc_string, zc->zc_string, MAXPATHLEN);
strlcpy(zc28_c->zc_top_ds, zc->zc_top_ds, MAXPATHLEN);
zc28_c->zc_guid = zc->zc_guid;
zc28_c->zc_nvlist_conf = zc->zc_nvlist_conf;
zc28_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
zc28_c->zc_nvlist_src = zc->zc_nvlist_src;
zc28_c->zc_nvlist_src_size = zc->zc_nvlist_src_size;
zc28_c->zc_nvlist_dst = zc->zc_nvlist_dst;
zc28_c->zc_nvlist_dst_size = zc->zc_nvlist_dst_size;
zc28_c->zc_cookie = zc->zc_cookie;
zc28_c->zc_objset_type = zc->zc_objset_type;
zc28_c->zc_perm_action = zc->zc_perm_action;
zc28_c->zc_history = zc->zc_history;
zc28_c->zc_history_len = zc->zc_history_len;
zc28_c->zc_history_offset = zc->zc_history_offset;
zc28_c->zc_obj = zc->zc_obj;
zc28_c->zc_iflags = zc->zc_iflags;
zc28_c->zc_share = zc->zc_share;
zc28_c->zc_jailid = zc->zc_jailid;
zc28_c->zc_objset_stats = zc->zc_objset_stats;
zc28_c->zc_begin_record = zc->zc_begin_record;
zc28_c->zc_defer_destroy = zc->zc_defer_destroy;
zc28_c->zc_temphold = zc->zc_temphold;
zc28_c->zc_action_handle = zc->zc_action_handle;
zc28_c->zc_cleanup_fd = zc->zc_cleanup_fd;
zc28_c->zc_simple = zc->zc_simple;
bcopy(zc->zc_pad, zc28_c->zc_pad, sizeof(zc28_c->zc_pad));
zc28_c->zc_sendobj = zc->zc_sendobj;
zc28_c->zc_fromobj = zc->zc_fromobj;
zc28_c->zc_createtxg = zc->zc_createtxg;
zc28_c->zc_stat = zc->zc_stat;
/* zc_inject_record */
zc28_c->zc_inject_record.zi_objset =
zc->zc_inject_record.zi_objset;
zc28_c->zc_inject_record.zi_object =
zc->zc_inject_record.zi_object;
zc28_c->zc_inject_record.zi_start =
zc->zc_inject_record.zi_start;
zc28_c->zc_inject_record.zi_end =
zc->zc_inject_record.zi_end;
zc28_c->zc_inject_record.zi_guid =
zc->zc_inject_record.zi_guid;
zc28_c->zc_inject_record.zi_level =
zc->zc_inject_record.zi_level;
zc28_c->zc_inject_record.zi_error =
zc->zc_inject_record.zi_error;
zc28_c->zc_inject_record.zi_type =
zc->zc_inject_record.zi_type;
zc28_c->zc_inject_record.zi_freq =
zc->zc_inject_record.zi_freq;
zc28_c->zc_inject_record.zi_failfast =
zc->zc_inject_record.zi_failfast;
strlcpy(zc28_c->zc_inject_record.zi_func,
zc->zc_inject_record.zi_func, MAXNAMELEN);
zc28_c->zc_inject_record.zi_iotype =
zc->zc_inject_record.zi_iotype;
zc28_c->zc_inject_record.zi_duration =
zc->zc_inject_record.zi_duration;
zc28_c->zc_inject_record.zi_timer =
zc->zc_inject_record.zi_timer;
break;
case ZFS_CMD_COMPAT_V15:
zc_c = (void *)addr;
/* zc */
strlcpy(zc_c->zc_name,zc->zc_name,MAXPATHLEN);
strlcpy(zc_c->zc_value,zc->zc_value,MAXPATHLEN);
strlcpy(zc_c->zc_string,zc->zc_string,MAXPATHLEN);
strlcpy(zc_c->zc_name, zc->zc_name, MAXPATHLEN);
strlcpy(zc_c->zc_value, zc->zc_value, MAXPATHLEN);
strlcpy(zc_c->zc_string, zc->zc_string, MAXPATHLEN);
zc_c->zc_guid = zc->zc_guid;
zc_c->zc_nvlist_conf = zc->zc_nvlist_conf;
zc_c->zc_nvlist_conf_size = zc->zc_nvlist_conf_size;
@ -260,7 +408,7 @@ zfs_ioctl_compat_fix_stats_nvlist(nvlist_t *nvl)
}
static int
zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int cflag)
zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int nc)
{
nvlist_t *nv, *nvp = NULL;
nvpair_t *elem;
@ -270,7 +418,7 @@ zfs_ioctl_compat_fix_stats(zfs_cmd_t *zc, const int cflag)
zc->zc_nvlist_dst_size, zc->zc_iflags, &nv)) != 0)
return (error);
if (cflag == 5) { /* ZFS_IOC_POOL_STATS */
if (nc == 5) { /* ZFS_IOC_POOL_STATS */
elem = NULL;
while ((elem = nvlist_next_nvpair(nv, elem)) != NULL) {
if (nvpair_value_nvlist(elem, &nvp) == 0)
@ -334,17 +482,22 @@ zcmd_ioctl_compat(int fd, unsigned long cmd, zfs_cmd_t *zc, const int cflag)
void *zc_c;
unsigned long ncmd;
if (cflag == ZFS_CMD_COMPAT_NONE) {
switch (cflag) {
case ZFS_CMD_COMPAT_NONE:
ret = ioctl(fd, cmd, zc);
return (ret);
}
if (cflag == ZFS_CMD_COMPAT_V15) {
case ZFS_CMD_COMPAT_V28:
zc_c = malloc(sizeof(zfs_cmd_v28_t));
ncmd = _IOWR('Z', ZFS_IOC(cmd), struct zfs_cmd_v28);
break;
case ZFS_CMD_COMPAT_V15:
nc = zfs_ioctl_v28_to_v15[ZFS_IOC(cmd)];
zc_c = malloc(sizeof(zfs_cmd_v15_t));
ncmd = _IOWR('Z', nc, struct zfs_cmd_v15);
} else
break;
default:
return (EINVAL);
}
if (ZFS_IOC(ncmd) == ZFS_IOC_COMPAT_FAIL)
return (ENOTSUP);
@ -358,16 +511,18 @@ zcmd_ioctl_compat(int fd, unsigned long cmd, zfs_cmd_t *zc, const int cflag)
zfs_cmd_compat_get(zc, (caddr_t)zc_c, cflag);
free(zc_c);
switch (nc) {
case 2: /* ZFS_IOC_POOL_IMPORT */
case 4: /* ZFS_IOC_POOL_CONFIGS */
case 5: /* ZFS_IOC_POOL_STATS */
case 6: /* ZFS_IOC_POOL_TRYIMPORT */
zfs_ioctl_compat_fix_stats(zc, nc);
break;
case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
zfs_ioctl_compat_pool_get_props(zc);
break;
if (cflag == ZFS_CMD_COMPAT_V15) {
switch (nc) {
case 2: /* ZFS_IOC_POOL_IMPORT */
case 4: /* ZFS_IOC_POOL_CONFIGS */
case 5: /* ZFS_IOC_POOL_STATS */
case 6: /* ZFS_IOC_POOL_TRYIMPORT */
zfs_ioctl_compat_fix_stats(zc, nc);
break;
case 41: /* ZFS_IOC_POOL_GET_PROPS (v15) */
zfs_ioctl_compat_pool_get_props(zc);
break;
}
}
return (ret);

View File

@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2010 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Use is subject to license terms.
*/
@ -40,11 +40,21 @@
extern "C" {
#endif
#define ZFS_CMD_COMPAT_NONE 0
#define ZFS_CMD_COMPAT_V15 1
/*
* Backwards ioctl compatibility
*/
#define ZFS_IOC_COMPAT_PASS 254
#define ZFS_IOC_COMPAT_FAIL 255
/* ioctl versions for vfs.zfs.version.ioctl */
#define ZFS_IOCVER_DEADMAN 1
#define ZFS_IOCVER_CURRENT ZFS_IOCVER_DEADMAN
/* compatibility conversion flag */
#define ZFS_CMD_COMPAT_NONE 0
#define ZFS_CMD_COMPAT_V15 1
#define ZFS_CMD_COMPAT_V28 2
#define ZFS_IOC_COMPAT_PASS 254
#define ZFS_IOC_COMPAT_FAIL 255
typedef struct zinject_record_v15 {
uint64_t zi_objset;
@ -84,6 +94,60 @@ typedef struct zfs_cmd_v15 {
zinject_record_v15_t zc_inject_record;
} zfs_cmd_v15_t;
typedef struct zinject_record_v28 {
uint64_t zi_objset;
uint64_t zi_object;
uint64_t zi_start;
uint64_t zi_end;
uint64_t zi_guid;
uint32_t zi_level;
uint32_t zi_error;
uint64_t zi_type;
uint32_t zi_freq;
uint32_t zi_failfast;
char zi_func[MAXNAMELEN];
uint32_t zi_iotype;
int32_t zi_duration;
uint64_t zi_timer;
} zinject_record_v28_t;
typedef struct zfs_cmd_v28 {
char zc_name[MAXPATHLEN];
char zc_value[MAXPATHLEN * 2];
char zc_string[MAXNAMELEN];
char zc_top_ds[MAXPATHLEN];
uint64_t zc_guid;
uint64_t zc_nvlist_conf; /* really (char *) */
uint64_t zc_nvlist_conf_size;
uint64_t zc_nvlist_src; /* really (char *) */
uint64_t zc_nvlist_src_size;
uint64_t zc_nvlist_dst; /* really (char *) */
uint64_t zc_nvlist_dst_size;
uint64_t zc_cookie;
uint64_t zc_objset_type;
uint64_t zc_perm_action;
uint64_t zc_history; /* really (char *) */
uint64_t zc_history_len;
uint64_t zc_history_offset;
uint64_t zc_obj;
uint64_t zc_iflags; /* internal to zfs(7fs) */
zfs_share_t zc_share;
uint64_t zc_jailid;
dmu_objset_stats_t zc_objset_stats;
struct drr_begin zc_begin_record;
zinject_record_v28_t zc_inject_record;
boolean_t zc_defer_destroy;
boolean_t zc_temphold;
uint64_t zc_action_handle;
int zc_cleanup_fd;
uint8_t zc_simple;
uint8_t zc_pad[3]; /* alignment */
uint64_t zc_sendobj;
uint64_t zc_fromobj;
uint64_t zc_createtxg;
zfs_stat_t zc_stat;
} zfs_cmd_v28_t;
#ifdef _KERNEL
unsigned static long zfs_ioctl_v15_to_v28[] = {
0, /* 0 ZFS_IOC_POOL_CREATE */

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
*/
@ -350,6 +350,10 @@ zfs_prop_init(void)
ZFS_TYPE_SNAPSHOT, "<count>", "USERREFS");
zprop_register_number(ZFS_PROP_WRITTEN, "written", 0, PROP_READONLY,
ZFS_TYPE_DATASET, "<size>", "WRITTEN");
zprop_register_number(ZFS_PROP_LOGICALUSED, "logicalused", 0,
PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LUSED");
zprop_register_number(ZFS_PROP_LOGICALREFERENCED, "logicalreferenced",
0, PROP_READONLY, ZFS_TYPE_DATASET, "<size>", "LREFER");
/* default number properties */
zprop_register_number(ZFS_PROP_QUOTA, "quota", 0, PROP_DEFAULT,

View File

@ -2344,6 +2344,8 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
(ds->ds_phys->ds_uncompressed_bytes * 100 /
ds->ds_phys->ds_compressed_bytes);
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio);
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALREFERENCED,
ds->ds_phys->ds_uncompressed_bytes);
if (ds->ds_phys->ds_next_snap_obj) {
/*

View File

@ -541,6 +541,8 @@ dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv)
dd->dd_phys->dd_compressed_bytes == 0 ? 100 :
(dd->dd_phys->dd_uncompressed_bytes * 100 /
dd->dd_phys->dd_compressed_bytes));
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_LOGICALUSED,
dd->dd_phys->dd_uncompressed_bytes);
if (dd->dd_phys->dd_flags & DD_FLAG_USED_BREAKDOWN) {
dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USEDSNAP,
dd->dd_phys->dd_used_breakdown[DD_USED_SNAP]);

View File

@ -6018,7 +6018,7 @@ spa_sync_version(void *arg1, void *arg2, dmu_tx_t *tx)
*/
ASSERT(tx->tx_txg != TXG_INITIAL);
ASSERT(version <= SPA_VERSION);
ASSERT(SPA_VERSION_IS_SUPPORTED(version));
ASSERT(version >= spa_version(spa));
spa->spa_uberblock.ub_version = version;
@ -6559,7 +6559,7 @@ spa_upgrade(spa_t *spa, uint64_t version)
* future version would result in an unopenable pool, this shouldn't be
* possible.
*/
ASSERT(spa->spa_uberblock.ub_version <= SPA_VERSION);
ASSERT(SPA_VERSION_IS_SUPPORTED(spa->spa_uberblock.ub_version));
ASSERT(version >= spa->spa_uberblock.ub_version);
spa->spa_uberblock.ub_version = version;

View File

@ -23,7 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011-2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* All rights reserved.
* Portions Copyright 2011 Martin Matuska <mm@FreeBSD.org>
* Copyright 2013 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
@ -3822,7 +3822,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
return (error);
fd = zc->zc_cookie;
fp = getf(fd);
fp = getf(fd, CAP_PREAD);
if (fp == NULL) {
nvlist_free(props);
return (EBADF);
@ -4079,7 +4079,7 @@ zfs_ioc_send(zfs_cmd_t *zc)
error = dmu_send_estimate(tosnap, fromsnap, zc->zc_obj,
&zc->zc_objset_type);
} else {
file_t *fp = getf(zc->zc_cookie);
file_t *fp = getf(zc->zc_cookie, CAP_WRITE);
if (fp == NULL) {
dsl_dataset_rele(ds, FTAG);
if (dsfrom)
@ -4675,7 +4675,7 @@ zfs_ioc_diff(zfs_cmd_t *zc)
return (error);
}
fp = getf(zc->zc_cookie);
fp = getf(zc->zc_cookie, CAP_WRITE);
if (fp == NULL) {
dmu_objset_rele(fromsnap, FTAG);
dmu_objset_rele(tosnap, FTAG);
@ -5331,12 +5331,14 @@ zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
len = IOCPARM_LEN(cmd);
/*
* Check if we have sufficient kernel memory allocated
* for the zfs_cmd_t request. Bail out if not so we
* will not access undefined memory region.
* Check if we are talking to supported older binaries
* and translate zfs_cmd if necessary
*/
if (len < sizeof(zfs_cmd_t))
if (len == sizeof(zfs_cmd_v15_t)) {
if (len == sizeof(zfs_cmd_v28_t)) {
cflag = ZFS_CMD_COMPAT_V28;
vec = ZFS_IOC(cmd);
} else if (len == sizeof(zfs_cmd_v15_t)) {
cflag = ZFS_CMD_COMPAT_V15;
vec = zfs_ioctl_v15_to_v28[ZFS_IOC(cmd)];
} else
@ -5351,6 +5353,11 @@ zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
return (ENOTSUP);
}
/*
* Check if we have sufficient kernel memory allocated
* for the zfs_cmd_t request. Bail out if not so we
* will not access undefined memory region.
*/
if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
return (EINVAL);

View File

@ -124,7 +124,7 @@ zfs_onexit_fd_hold(int fd, minor_t *minorp)
void *data;
int error;
fp = getf(fd);
fp = getf(fd, CAP_NONE);
if (fp == NULL)
return (EBADF);

View File

@ -131,6 +131,8 @@ typedef enum {
ZFS_PROP_REFRATIO,
ZFS_PROP_WRITTEN,
ZFS_PROP_CLONES,
ZFS_PROP_LOGICALUSED,
ZFS_PROP_LOGICALREFERENCED,
ZFS_NUM_PROPS
} zfs_prop_t;

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 242958 2012-11-13 12:52:31Z kib
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
*/
#ifndef _FREEBSD32_SYSPROTO_H_

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 242958 2012-11-13 12:52:31Z kib
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
*/
#define FREEBSD32_SYS_syscall 0
@ -416,7 +416,7 @@
#define FREEBSD32_SYS_freebsd32_shmctl 512
#define FREEBSD32_SYS_lpathconf 513
#define FREEBSD32_SYS_cap_new 514
#define FREEBSD32_SYS_cap_getrights 515
#define FREEBSD32_SYS_cap_rights_get 515
#define FREEBSD32_SYS_cap_enter 516
#define FREEBSD32_SYS_cap_getmode 517
#define FREEBSD32_SYS_freebsd32_pselect 522
@ -430,4 +430,9 @@
#define FREEBSD32_SYS_freebsd32_posix_fallocate 530
#define FREEBSD32_SYS_freebsd32_posix_fadvise 531
#define FREEBSD32_SYS_freebsd32_wait6 532
#define FREEBSD32_SYS_MAXSYSCALL 533
#define FREEBSD32_SYS_cap_rights_limit 533
#define FREEBSD32_SYS_cap_ioctls_limit 534
#define FREEBSD32_SYS_cap_ioctls_get 535
#define FREEBSD32_SYS_cap_fcntls_limit 536
#define FREEBSD32_SYS_cap_fcntls_get 537
#define FREEBSD32_SYS_MAXSYSCALL 538

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 242958 2012-11-13 12:52:31Z kib
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
*/
const char *freebsd32_syscallnames[] = {
@ -538,7 +538,7 @@ const char *freebsd32_syscallnames[] = {
"freebsd32_shmctl", /* 512 = freebsd32_shmctl */
"lpathconf", /* 513 = lpathconf */
"cap_new", /* 514 = cap_new */
"cap_getrights", /* 515 = cap_getrights */
"cap_rights_get", /* 515 = cap_rights_get */
"cap_enter", /* 516 = cap_enter */
"cap_getmode", /* 517 = cap_getmode */
"#518", /* 518 = pdfork */
@ -556,4 +556,9 @@ const char *freebsd32_syscallnames[] = {
"freebsd32_posix_fallocate", /* 530 = freebsd32_posix_fallocate */
"freebsd32_posix_fadvise", /* 531 = freebsd32_posix_fadvise */
"freebsd32_wait6", /* 532 = freebsd32_wait6 */
"cap_rights_limit", /* 533 = cap_rights_limit */
"cap_ioctls_limit", /* 534 = cap_ioctls_limit */
"cap_ioctls_get", /* 535 = cap_ioctls_get */
"cap_fcntls_limit", /* 536 = cap_fcntls_limit */
"cap_fcntls_get", /* 537 = cap_fcntls_get */
};

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 242958 2012-11-13 12:52:31Z kib
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 247602 2013-03-02 00:53:12Z pjd
*/
#include "opt_compat.h"
@ -575,7 +575,7 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_shmctl_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 512 = freebsd32_shmctl */
{ AS(lpathconf_args), (sy_call_t *)sys_lpathconf, AUE_LPATHCONF, NULL, 0, 0, 0, SY_THR_STATIC }, /* 513 = lpathconf */
{ AS(cap_new_args), (sy_call_t *)sys_cap_new, AUE_CAP_NEW, NULL, 0, 0, 0, SY_THR_STATIC }, /* 514 = cap_new */
{ AS(cap_getrights_args), (sy_call_t *)sys_cap_getrights, AUE_CAP_GETRIGHTS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 515 = cap_getrights */
{ AS(cap_rights_get_args), (sy_call_t *)sys_cap_rights_get, AUE_CAP_RIGHTS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 515 = cap_rights_get */
{ 0, (sy_call_t *)sys_cap_enter, AUE_CAP_ENTER, NULL, 0, 0, 0, SY_THR_STATIC }, /* 516 = cap_enter */
{ AS(cap_getmode_args), (sy_call_t *)sys_cap_getmode, AUE_CAP_GETMODE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 517 = cap_getmode */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 518 = pdfork */
@ -593,4 +593,9 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_posix_fallocate_args), (sy_call_t *)freebsd32_posix_fallocate, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 530 = freebsd32_posix_fallocate */
{ AS(freebsd32_posix_fadvise_args), (sy_call_t *)freebsd32_posix_fadvise, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 531 = freebsd32_posix_fadvise */
{ AS(freebsd32_wait6_args), (sy_call_t *)freebsd32_wait6, AUE_WAIT6, NULL, 0, 0, 0, SY_THR_STATIC }, /* 532 = freebsd32_wait6 */
{ AS(cap_rights_limit_args), (sy_call_t *)sys_cap_rights_limit, AUE_CAP_RIGHTS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 533 = cap_rights_limit */
{ AS(cap_ioctls_limit_args), (sy_call_t *)sys_cap_ioctls_limit, AUE_CAP_IOCTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 534 = cap_ioctls_limit */
{ AS(cap_ioctls_get_args), (sy_call_t *)sys_cap_ioctls_get, AUE_CAP_IOCTLS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 535 = cap_ioctls_get */
{ AS(cap_fcntls_limit_args), (sy_call_t *)sys_cap_fcntls_limit, AUE_CAP_FCNTLS_LIMIT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 536 = cap_fcntls_limit */
{ AS(cap_fcntls_get_args), (sy_call_t *)sys_cap_fcntls_get, AUE_CAP_FCNTLS_GET, NULL, 0, 0, 0, SY_THR_STATIC }, /* 537 = cap_fcntls_get */
};

View File

@ -2956,9 +2956,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 2;
break;
}
/* cap_getrights */
/* cap_rights_get */
case 515: {
struct cap_getrights_args *p = params;
struct cap_rights_get_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->rightsp; /* uint64_t * */
*n_args = 2;
@ -3088,6 +3088,48 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 6;
break;
}
/* cap_rights_limit */
case 533: {
struct cap_rights_limit_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = p->rights; /* uint64_t */
*n_args = 2;
break;
}
/* cap_ioctls_limit */
case 534: {
struct cap_ioctls_limit_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->cmds; /* const u_long * */
uarg[2] = p->ncmds; /* size_t */
*n_args = 3;
break;
}
/* cap_ioctls_get */
case 535: {
struct cap_ioctls_get_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->cmds; /* u_long * */
uarg[2] = p->maxcmds; /* size_t */
*n_args = 3;
break;
}
/* cap_fcntls_limit */
case 536: {
struct cap_fcntls_limit_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = p->fcntlrights; /* uint32_t */
*n_args = 2;
break;
}
/* cap_fcntls_get */
case 537: {
struct cap_fcntls_get_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->fcntlrightsp; /* uint32_t * */
*n_args = 2;
break;
}
default:
*n_args = 0;
break;
@ -8002,7 +8044,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
/* cap_getrights */
/* cap_rights_get */
case 515:
switch(ndx) {
case 0:
@ -8243,6 +8285,77 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
/* cap_rights_limit */
case 533:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "uint64_t";
break;
default:
break;
};
break;
/* cap_ioctls_limit */
case 534:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "const u_long *";
break;
case 2:
p = "size_t";
break;
default:
break;
};
break;
/* cap_ioctls_get */
case 535:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "u_long *";
break;
case 2:
p = "size_t";
break;
default:
break;
};
break;
/* cap_fcntls_limit */
case 536:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "uint32_t";
break;
default:
break;
};
break;
/* cap_fcntls_get */
case 537:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "uint32_t *";
break;
default:
break;
};
break;
default:
break;
};
@ -9938,7 +10051,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* cap_getrights */
/* cap_rights_get */
case 515:
if (ndx == 0 || ndx == 1)
p = "int";
@ -10005,6 +10118,31 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* cap_rights_limit */
case 533:
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* cap_ioctls_limit */
case 534:
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* cap_ioctls_get */
case 535:
if (ndx == 0 || ndx == 1)
p = "ssize_t";
break;
/* cap_fcntls_limit */
case 536:
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* cap_fcntls_get */
case 537:
if (ndx == 0 || ndx == 1)
p = "int";
break;
default:
break;
};

View File

@ -963,7 +963,7 @@
struct shmid_ds32 *buf); }
513 AUE_LPATHCONF NOPROTO { int lpathconf(char *path, int name); }
514 AUE_CAP_NEW NOPROTO { int cap_new(int fd, uint64_t rights); }
515 AUE_CAP_GETRIGHTS NOPROTO { int cap_getrights(int fd, \
515 AUE_CAP_RIGHTS_GET NOPROTO { int cap_rights_get(int fd, \
uint64_t *rightsp); }
516 AUE_CAP_ENTER NOPROTO { int cap_enter(void); }
517 AUE_CAP_GETMODE NOPROTO { int cap_getmode(u_int *modep); }
@ -1005,3 +1005,13 @@
struct wrusage32 *wrusage, \
siginfo_t *info); }
533 AUE_CAP_RIGHTS_LIMIT NOPROTO { int cap_rights_limit(int fd, \
uint64_t rights); }
534 AUE_CAP_IOCTLS_LIMIT NOPROTO { int cap_ioctls_limit(int fd, \
const u_long *cmds, size_t ncmds); }
535 AUE_CAP_IOCTLS_GET NOPROTO { ssize_t cap_ioctls_get(int fd, \
u_long *cmds, size_t maxcmds); }
536 AUE_CAP_FCNTLS_LIMIT NOPROTO { int cap_fcntls_limit(int fd, \
uint32_t fcntlrights); }
537 AUE_CAP_FCNTLS_GET NOPROTO { int cap_fcntls_get(int fd, \
uint32_t *fcntlrightsp); }

View File

@ -154,6 +154,7 @@ linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mod
SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
PROC_UNLOCK(p);
sx_unlock(&proctree_lock);
/* XXXPJD: Verify if TIOCSCTTY is allowed. */
if (fp->f_type == DTYPE_VNODE)
(void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0,
td->td_ucred, td);
@ -1038,11 +1039,11 @@ linux_pread(td, uap)
error = sys_pread(td, &bsd);
if (error == 0) {
/* This seems to violate POSIX but linux does it */
if ((error = fgetvp(td, uap->fd, CAP_READ, &vp)) != 0)
return (error);
/* This seems to violate POSIX but linux does it */
if ((error = fgetvp(td, uap->fd, CAP_PREAD, &vp)) != 0)
return (error);
if (vp->v_type == VDIR) {
vrele(vp);
vrele(vp);
return (EISDIR);
}
vrele(vp);

View File

@ -566,7 +566,7 @@ ndis_convert_res(arg)
return (ENOMEM);
rl->cprl_version = 5;
rl->cprl_version = 1;
rl->cprl_revision = 1;
rl->cprl_count = sc->ndis_rescnt;
prd = rl->cprl_partial_descs;

View File

@ -265,14 +265,14 @@ fd_revoke(td, fd)
/*
* If we ever want to support Capsicum on SVR4 processes (unlikely)
* or FreeBSD grows a native frevoke() (more likely), we will need a
* CAP_REVOKE here.
* CAP_FREVOKE here.
*
* In the meantime, use CAP_MASK_VALID: if a SVR4 process wants to
* In the meantime, use CAP_ALL: if a SVR4 process wants to
* do an frevoke(), it needs to do it on either a regular file
* descriptor or a fully-privileged capability (which is effectively
* the same as a non-capability-restricted file descriptor).
*/
if ((error = fgetvp(td, fd, CAP_MASK_VALID, &vp)) != 0)
if ((error = fgetvp(td, fd, CAP_ALL, &vp)) != 0)
return (error);
if (vp->v_type != VCHR && vp->v_type != VBLK) {

View File

@ -197,22 +197,24 @@ svr4_fil_ioctl(fp, td, retval, fd, cmd, data)
u_long cmd;
caddr_t data;
{
int error;
int num;
struct filedesc *fdp = td->td_proc->p_fd;
struct filedescent *fde;
int error, num;
*retval = 0;
switch (cmd) {
case SVR4_FIOCLEX:
FILEDESC_XLOCK(fdp);
fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
fde = &fdp->fd_ofiles[fd];
fde->fde_flags |= UF_EXCLOSE;
FILEDESC_XUNLOCK(fdp);
return 0;
case SVR4_FIONCLEX:
FILEDESC_XLOCK(fdp);
fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
fde = &fdp->fd_ofiles[fd];
fde->fde_flags &= ~UF_EXCLOSE;
FILEDESC_XUNLOCK(fdp);
return 0;

View File

@ -247,10 +247,8 @@ svr4_sys_getdents64(td, uap)
DPRINTF(("svr4_sys_getdents64(%d, *, %d)\n",
uap->fd, uap->nbytes));
if ((error = getvnode(td->td_proc->p_fd, uap->fd,
CAP_READ | CAP_SEEK, &fp)) != 0) {
if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0)
return (error);
}
if ((fp->f_flag & FREAD) == 0) {
fdrop(fp, td);
@ -426,8 +424,7 @@ svr4_sys_getdents(td, uap)
if (uap->nbytes < 0)
return (EINVAL);
if ((error = getvnode(td->td_proc->p_fd, uap->fd,
CAP_READ | CAP_SEEK, &fp)) != 0)
if ((error = getvnode(td->td_proc->p_fd, uap->fd, CAP_READ, &fp)) != 0)
return (error);
if ((fp->f_flag & FREAD) == 0) {

View File

@ -1449,7 +1449,7 @@ svr4_sys_putmsg(td, uap)
struct file *fp;
int error;
if ((error = fget(td, uap->fd, CAP_WRITE, &fp)) != 0) {
if ((error = fget(td, uap->fd, CAP_SEND, &fp)) != 0) {
#ifdef DEBUG_SVR4
uprintf("putmsg: bad fp\n");
#endif
@ -1621,7 +1621,7 @@ svr4_sys_getmsg(td, uap)
struct file *fp;
int error;
if ((error = fget(td, uap->fd, CAP_READ, &fp)) != 0) {
if ((error = fget(td, uap->fd, CAP_RECV, &fp)) != 0) {
#ifdef DEBUG_SVR4
uprintf("getmsg: bad fp\n");
#endif

View File

@ -23,7 +23,6 @@ PSM_DEBUG opt_psm.h
PSM_HOOKRESUME opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
DEBUGGER_ON_POWERFAIL opt_psycho.h
PSYCHO_DEBUG opt_psycho.h
SCHIZO_DEBUG opt_schizo.h

View File

@ -117,7 +117,7 @@ static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
static int aac_sa_get_mailbox(struct aac_softc *sc, int mb);
static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
struct aac_interface aac_sa_interface = {
const struct aac_interface aac_sa_interface = {
aac_sa_get_fwstatus,
aac_sa_qnotify,
aac_sa_get_istatus,
@ -142,7 +142,7 @@ static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
static int aac_rx_get_outb_queue(struct aac_softc *sc);
static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
struct aac_interface aac_rx_interface = {
const struct aac_interface aac_rx_interface = {
aac_rx_get_fwstatus,
aac_rx_qnotify,
aac_rx_get_istatus,
@ -169,7 +169,7 @@ static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
static int aac_rkt_get_outb_queue(struct aac_softc *sc);
static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
struct aac_interface aac_rkt_interface = {
const struct aac_interface aac_rkt_interface = {
aac_rkt_get_fwstatus,
aac_rkt_qnotify,
aac_rkt_get_istatus,
@ -183,8 +183,8 @@ struct aac_interface aac_rkt_interface = {
};
/* Debugging and Diagnostics */
static void aac_describe_controller(struct aac_softc *sc);
static char *aac_describe_code(struct aac_code_lookup *table,
static void aac_describe_controller(struct aac_softc *sc);
static const char *aac_describe_code(const struct aac_code_lookup *table,
u_int32_t code);
/* Management Interface */
@ -222,7 +222,7 @@ static struct cdevsw aac_cdevsw = {
static MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
/* sysctl node */
static SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
/*
* Device Interface
@ -634,8 +634,8 @@ aac_free(struct aac_softc *sc)
if (sc->aac_intr)
bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
if (sc->aac_irq != NULL)
bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
sc->aac_irq);
bus_release_resource(sc->aac_dev, SYS_RES_IRQ,
rman_get_rid(sc->aac_irq), sc->aac_irq);
/* destroy data-transfer DMA tag */
if (sc->aac_buffer_dmat)
@ -648,10 +648,10 @@ aac_free(struct aac_softc *sc)
/* release the register window mapping */
if (sc->aac_regs_res0 != NULL)
bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
sc->aac_regs_rid0, sc->aac_regs_res0);
rman_get_rid(sc->aac_regs_res0), sc->aac_regs_res0);
if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
sc->aac_regs_rid1, sc->aac_regs_res1);
rman_get_rid(sc->aac_regs_res1), sc->aac_regs_res1);
}
/*
@ -1333,9 +1333,6 @@ aac_bio_complete(struct aac_command *cm)
} else {
bp->bio_error = EIO;
bp->bio_flags |= BIO_ERROR;
/* pass an error string out to the disk layer */
bp->bio_driver1 = aac_describe_code(aac_command_status_table,
status);
}
aac_biodone(bp);
}
@ -1687,7 +1684,7 @@ static int
aac_check_firmware(struct aac_softc *sc)
{
u_int32_t code, major, minor, options = 0, atu_size = 0;
int status;
int rid, status;
time_t then;
fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
@ -1765,7 +1762,7 @@ aac_check_firmware(struct aac_softc *sc)
sc->flags |= AAC_FLAGS_SG_64BIT;
}
if ((options & AAC_SUPPORTED_NEW_COMM)
&& sc->aac_if.aif_send_command)
&& sc->aac_if->aif_send_command)
sc->flags |= AAC_FLAGS_NEW_COMM;
if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
sc->flags |= AAC_FLAGS_ARRAY_64BIT;
@ -1776,17 +1773,15 @@ aac_check_firmware(struct aac_softc *sc)
/* Remap mem. resource, if required */
if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
atu_size > rman_get_size(sc->aac_regs_res1)) {
bus_release_resource(
sc->aac_dev, SYS_RES_MEMORY,
sc->aac_regs_rid1, sc->aac_regs_res1);
sc->aac_regs_res1 = bus_alloc_resource(
sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid1,
0ul, ~0ul, atu_size, RF_ACTIVE);
atu_size > rman_get_size(sc->aac_regs_res1)) {
rid = rman_get_rid(sc->aac_regs_res1);
bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, rid,
sc->aac_regs_res1);
sc->aac_regs_res1 = bus_alloc_resource(sc->aac_dev,
SYS_RES_MEMORY, &rid, 0ul, ~0ul, atu_size, RF_ACTIVE);
if (sc->aac_regs_res1 == NULL) {
sc->aac_regs_res1 = bus_alloc_resource_any(
sc->aac_dev, SYS_RES_MEMORY,
&sc->aac_regs_rid1, RF_ACTIVE);
sc->aac_dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
if (sc->aac_regs_res1 == NULL) {
device_printf(sc->aac_dev,
"couldn't allocate register window\n");
@ -1799,7 +1794,6 @@ aac_check_firmware(struct aac_softc *sc)
if (sc->aac_hwif == AAC_HWIF_NARK) {
sc->aac_regs_res0 = sc->aac_regs_res1;
sc->aac_regs_rid0 = sc->aac_regs_rid1;
sc->aac_btag0 = sc->aac_btag1;
sc->aac_bhandle0 = sc->aac_bhandle1;
}
@ -2003,14 +1997,7 @@ aac_init(struct aac_softc *sc)
static int
aac_setup_intr(struct aac_softc *sc)
{
sc->aac_irq_rid = 0;
if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
&sc->aac_irq_rid,
RF_SHAREABLE |
RF_ACTIVE)) == NULL) {
device_printf(sc->aac_dev, "can't allocate interrupt\n");
return (EINVAL);
}
if (sc->flags & AAC_FLAGS_NEW_COMM) {
if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
INTR_MPSAFE|INTR_TYPE_BIO, NULL,
@ -2119,7 +2106,7 @@ aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
* Note that the queue implementation here is a little funky; neither the PI or
* CI will ever be zero. This behaviour is a controller feature.
*/
static struct {
static const struct {
int size;
int notify;
} aac_qinfo[] = {
@ -2786,8 +2773,8 @@ aac_describe_controller(struct aac_softc *sc)
* Look up a text description of a numeric error code and return a pointer to
* same.
*/
static char *
aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
static const char *
aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
{
int i;

View File

@ -92,7 +92,7 @@ static device_method_t aac_pass_methods[] = {
DEVMETHOD(device_probe, aac_cam_probe),
DEVMETHOD(device_attach, aac_cam_attach),
DEVMETHOD(device_detach, aac_cam_detach),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t aac_pass_driver = {
@ -101,7 +101,7 @@ static driver_t aac_pass_driver = {
sizeof(struct aac_cam)
};
DRIVER_MODULE(aacp, aac, aac_pass_driver, aac_pass_devclass, 0, 0);
DRIVER_MODULE(aacp, aac, aac_pass_driver, aac_pass_devclass, NULL, NULL);
MODULE_DEPEND(aacp, cam, 1, 1, 1);
static MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
@ -685,4 +685,3 @@ aac_cam_term_io(struct cam_sim *sim, union ccb *ccb)
{
return (CAM_UA_TERMIO);
}

View File

@ -73,7 +73,7 @@ static device_method_t aac_disk_methods[] = {
DEVMETHOD(device_probe, aac_disk_probe),
DEVMETHOD(device_attach, aac_disk_attach),
DEVMETHOD(device_detach, aac_disk_detach),
{ 0, 0 }
DEVMETHOD_END
};
static driver_t aac_disk_driver = {
@ -82,7 +82,7 @@ static driver_t aac_disk_driver = {
sizeof(struct aac_disk)
};
DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, NULL, NULL);
/*
* Handle open from generic layer.

View File

@ -60,6 +60,11 @@ __FBSDID("$FreeBSD$");
static int aac_pci_probe(device_t dev);
static int aac_pci_attach(device_t dev);
static int aac_enable_msi = 1;
TUNABLE_INT("hw.aac.enable_msi", &aac_enable_msi);
SYSCTL_INT(_hw_aac, OID_AUTO, enable_msi, CTLFLAG_RDTUN, &aac_enable_msi, 0,
"Enable MSI interrupts");
static device_method_t aac_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, aac_pci_probe),
@ -79,11 +84,10 @@ static driver_t aac_pci_driver = {
static devclass_t aac_devclass;
DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, NULL, NULL);
MODULE_DEPEND(aac, pci, 1, 1, 1);
struct aac_ident
static const struct aac_ident
{
u_int16_t vendor;
u_int16_t device;
@ -91,7 +95,7 @@ struct aac_ident
u_int16_t subdevice;
int hwif;
int quirks;
char *desc;
const char *desc;
} aac_identifiers[] = {
{0x1028, 0x0001, 0x1028, 0x0001, AAC_HWIF_I960RX, 0,
"Dell PERC 2/Si"},
@ -139,7 +143,6 @@ struct aac_ident
"Adaptec SCSI RAID 2230S"},
{0x9005, 0x0286, 0x9005, 0x028d, AAC_HWIF_RKT, 0,
"Adaptec SCSI RAID 2130S"},
{0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
{0x9005, 0x0285, 0x17aa, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
@ -276,7 +279,8 @@ struct aac_ident
"AOC-USAS-S8iR-LP"},
{0, 0, 0, 0, 0, 0, 0}
};
struct aac_ident
static const struct aac_ident
aac_family_identifiers[] = {
{0x9005, 0x0285, 0, 0, AAC_HWIF_I960RX, 0,
"Adaptec RAID Controller"},
@ -285,10 +289,10 @@ aac_family_identifiers[] = {
{0, 0, 0, 0, 0, 0, 0}
};
static struct aac_ident *
static const struct aac_ident *
aac_find_ident(device_t dev)
{
struct aac_ident *m;
const struct aac_ident *m;
u_int16_t vendid, devid, sub_vendid, sub_devid;
vendid = pci_get_vendor(dev);
@ -317,7 +321,7 @@ aac_find_ident(device_t dev)
static int
aac_pci_probe(device_t dev)
{
struct aac_ident *id;
const struct aac_ident *id;
fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
@ -335,9 +339,8 @@ static int
aac_pci_attach(device_t dev)
{
struct aac_softc *sc;
struct aac_ident *id;
int error;
u_int32_t command;
const struct aac_ident *id;
int count, error, reg, rid;
fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
@ -345,7 +348,6 @@ aac_pci_attach(device_t dev)
* Initialise softc.
*/
sc = device_get_softc(dev);
bzero(sc, sizeof(*sc));
sc->aac_dev = dev;
/* assume failure is 'not configured' */
@ -354,55 +356,66 @@ aac_pci_attach(device_t dev)
/*
* Verify that the adapter is correctly set up in PCI space.
*/
command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
command |= PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, command, 2);
command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
if (!(command & PCIM_CMD_BUSMASTEREN)) {
device_printf(sc->aac_dev, "can't enable bus-master feature\n");
goto out;
}
if ((command & PCIM_CMD_MEMEN) == 0) {
device_printf(sc->aac_dev, "memory window not available\n");
pci_enable_busmaster(dev);
if (!(pci_read_config(dev, PCIR_COMMAND, 2) & PCIM_CMD_BUSMASTEREN)) {
device_printf(dev, "can't enable bus-master feature\n");
goto out;
}
/*
* Allocate the PCI register window.
* Allocate the PCI register window(s).
*/
sc->aac_regs_rid0 = PCIR_BAR(0);
if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev,
SYS_RES_MEMORY, &sc->aac_regs_rid0, RF_ACTIVE)) == NULL) {
device_printf(sc->aac_dev,
"couldn't allocate register window 0\n");
rid = PCIR_BAR(0);
if ((sc->aac_regs_res0 = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) {
device_printf(dev, "can't allocate register window 0\n");
goto out;
}
sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
if (sc->aac_hwif == AAC_HWIF_NARK) {
sc->aac_regs_rid1 = PCIR_BAR(1);
if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev,
SYS_RES_MEMORY, &sc->aac_regs_rid1, RF_ACTIVE)) == NULL) {
device_printf(sc->aac_dev,
"couldn't allocate register window 1\n");
rid = PCIR_BAR(1);
if ((sc->aac_regs_res1 = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE)) == NULL) {
device_printf(dev,
"can't allocate register window 1\n");
goto out;
}
sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
} else {
sc->aac_regs_res1 = sc->aac_regs_res0;
sc->aac_regs_rid1 = sc->aac_regs_rid0;
sc->aac_btag1 = sc->aac_btag0;
sc->aac_bhandle1 = sc->aac_bhandle0;
}
/*
* Allocate the interrupt.
*/
rid = 0;
count = 0;
if (aac_enable_msi != 0 && pci_find_cap(dev, PCIY_MSI, &reg) == 0) {
count = pci_msi_count(dev);
if (count > 1)
count = 1;
else
count = 0;
if (count == 1 && pci_alloc_msi(dev, &count) == 0)
rid = 1;
}
if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
&rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE))) == NULL) {
device_printf(dev, "can't allocate interrupt\n");
goto out;
}
/*
* Allocate the parent bus DMA tag appropriate for our PCI interface.
*
* Note that some of these controllers are 64-bit capable.
*/
if (bus_dma_tag_create(bus_get_dma_tag(sc->aac_dev), /* parent */
if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */
PAGE_SIZE, 0, /* algnmnt, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@ -413,7 +426,7 @@ aac_pci_attach(device_t dev)
0, /* flags */
NULL, NULL, /* No locking needed */
&sc->aac_parent_dmat)) {
device_printf(sc->aac_dev, "can't allocate parent DMA tag\n");
device_printf(dev, "can't allocate parent DMA tag\n");
goto out;
}
@ -427,19 +440,19 @@ aac_pci_attach(device_t dev)
case AAC_HWIF_I960RX:
case AAC_HWIF_NARK:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK");
sc->aac_if = aac_rx_interface;
sc->aac_if = &aac_rx_interface;
break;
case AAC_HWIF_STRONGARM:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
sc->aac_if = aac_sa_interface;
sc->aac_if = &aac_sa_interface;
break;
case AAC_HWIF_RKT:
fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
sc->aac_if = aac_rkt_interface;
sc->aac_if = &aac_rkt_interface;
break;
default:
sc->aac_hwif = AAC_HWIF_UNKNOWN;
device_printf(sc->aac_dev, "unknown hardware type\n");
device_printf(dev, "unknown hardware type\n");
error = ENXIO;
goto out;
}
@ -472,7 +485,7 @@ static device_method_t aacch_methods[] = {
DEVMETHOD(device_probe, aacch_probe),
DEVMETHOD(device_attach, aacch_attach),
DEVMETHOD(device_detach, aacch_detach),
{ 0, 0 }
DEVMETHOD_END
};
struct aacch_softc {
@ -486,7 +499,7 @@ static driver_t aacch_driver = {
};
static devclass_t aacch_devclass;
DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, 0, 0);
DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, NULL, NULL);
static int
aacch_probe(device_t dev)

View File

@ -27,13 +27,14 @@
* $FreeBSD$
*/
#if 0
/*
* Status codes for block read/write commands, etc.
*
* XXX many of these would not normally be returned, as they are
* relevant only to FSA operations.
*/
static struct aac_code_lookup aac_command_status_table[] = {
static const struct aac_code_lookup aac_command_status_table[] = {
{"OK", ST_OK},
{"operation not permitted", ST_PERM},
{"not found", ST_NOENT},
@ -75,8 +76,9 @@ static struct aac_code_lookup aac_command_status_table[] = {
};
#define AAC_COMMAND_STATUS(x) aac_describe_code(aac_command_status_table, x)
#endif
static struct aac_code_lookup aac_cpu_variant[] = {
static const struct aac_code_lookup aac_cpu_variant[] = {
{"i960JX", CPUI960_JX},
{"i960CX", CPUI960_CX},
{"i960HX", CPUI960_HX},
@ -93,7 +95,7 @@ static struct aac_code_lookup aac_cpu_variant[] = {
{"Unknown processor", 0}
};
static struct aac_code_lookup aac_battery_platform[] = {
static const struct aac_code_lookup aac_battery_platform[] = {
{"required battery present", PLATFORM_BAT_REQ_PRESENT},
{"REQUIRED BATTERY NOT PRESENT", PLATFORM_BAT_REQ_NOTPRESENT},
{"optional battery present", PLATFORM_BAT_OPT_PRESENT},
@ -103,7 +105,7 @@ static struct aac_code_lookup aac_battery_platform[] = {
{"unknown battery platform", 0}
};
static struct aac_code_lookup aac_container_types[] = {
static const struct aac_code_lookup aac_container_types[] = {
{"Volume", CT_VOLUME},
{"RAID 1 (Mirror)", CT_MIRROR},
{"RAID 0 (Stripe)", CT_STRIPE},
@ -126,4 +128,3 @@ static struct aac_code_lookup aac_container_types[] = {
{NULL, 0},
{"unknown", 0}
};

View File

@ -33,10 +33,13 @@
#include <sys/callout.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/taskqueue.h>
#include <sys/selinfo.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <geom/geom_disk.h>
SYSCTL_DECL(_hw_aac);
#define AAC_TYPE_DEVO 1
#define AAC_TYPE_ALPHA 2
#define AAC_TYPE_BETA 3
@ -242,28 +245,28 @@ struct aac_interface
int (*aif_get_outb_queue)(struct aac_softc *sc);
void (*aif_set_outb_queue)(struct aac_softc *sc, int index);
};
extern struct aac_interface aac_rx_interface;
extern struct aac_interface aac_sa_interface;
extern struct aac_interface aac_fa_interface;
extern struct aac_interface aac_rkt_interface;
extern const struct aac_interface aac_rx_interface;
extern const struct aac_interface aac_sa_interface;
extern const struct aac_interface aac_fa_interface;
extern const struct aac_interface aac_rkt_interface;
#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if.aif_get_fwstatus((sc)))
#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if.aif_qnotify((sc), (qbit)))
#define AAC_GET_ISTATUS(sc) ((sc)->aac_if.aif_get_istatus((sc)))
#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if.aif_clr_istatus((sc), \
#define AAC_GET_FWSTATUS(sc) ((sc)->aac_if->aif_get_fwstatus((sc)))
#define AAC_QNOTIFY(sc, qbit) ((sc)->aac_if->aif_qnotify((sc), (qbit)))
#define AAC_GET_ISTATUS(sc) ((sc)->aac_if->aif_get_istatus((sc)))
#define AAC_CLEAR_ISTATUS(sc, mask) ((sc)->aac_if->aif_clr_istatus((sc), \
(mask)))
#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), \
((sc)->aac_if->aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), \
(arg3)))
#define AAC_GET_MAILBOX(sc, mb) ((sc)->aac_if.aif_get_mailbox((sc), \
#define AAC_GET_MAILBOX(sc, mb) ((sc)->aac_if->aif_get_mailbox((sc), \
(mb)))
#define AAC_MASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), \
#define AAC_MASK_INTERRUPTS(sc) ((sc)->aac_if->aif_set_interrupts((sc), \
0))
#define AAC_UNMASK_INTERRUPTS(sc) ((sc)->aac_if.aif_set_interrupts((sc), \
#define AAC_UNMASK_INTERRUPTS(sc) ((sc)->aac_if->aif_set_interrupts((sc), \
1))
#define AAC_SEND_COMMAND(sc, cm) ((sc)->aac_if.aif_send_command((sc), (cm)))
#define AAC_GET_OUTB_QUEUE(sc) ((sc)->aac_if.aif_get_outb_queue((sc)))
#define AAC_SET_OUTB_QUEUE(sc, idx) ((sc)->aac_if.aif_set_outb_queue((sc), (idx)))
#define AAC_SEND_COMMAND(sc, cm) ((sc)->aac_if->aif_send_command((sc), (cm)))
#define AAC_GET_OUTB_QUEUE(sc) ((sc)->aac_if->aif_get_outb_queue((sc)))
#define AAC_SET_OUTB_QUEUE(sc, idx) ((sc)->aac_if->aif_set_outb_queue((sc), (idx)))
#define AAC_MEM0_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag0, \
sc->aac_bhandle0, reg, val)
@ -307,14 +310,12 @@ struct aac_softc
/* bus connections */
device_t aac_dev;
struct resource *aac_regs_res0, *aac_regs_res1; /* reg. if. window */
int aac_regs_rid0, aac_regs_rid1; /* resource ID */
bus_space_handle_t aac_bhandle0, aac_bhandle1; /* bus space handle */
bus_space_tag_t aac_btag0, aac_btag1; /* bus space tag */
bus_dma_tag_t aac_parent_dmat; /* parent DMA tag */
bus_dma_tag_t aac_buffer_dmat; /* data buffer/command
* DMA tag */
struct resource *aac_irq; /* interrupt */
int aac_irq_rid;
void *aac_intr; /* interrupt handle */
eventhandler_tag eh;
@ -339,7 +340,7 @@ struct aac_softc
* DMA map */
struct aac_common *aac_common;
u_int32_t aac_common_busaddr;
struct aac_interface aac_if;
const struct aac_interface *aac_if;
/* command/fib resources */
bus_dma_tag_t aac_fib_dmat; /* DMA tag for allocing FIBs */
@ -499,7 +500,7 @@ extern void aac_print_aif(struct aac_softc *sc,
#endif
struct aac_code_lookup {
char *string;
const char *string;
u_int32_t code;
};
@ -581,7 +582,6 @@ aac_remove_ ## name (struct aac_command *cm) \
cm->cm_flags &= ~AAC_ON_ ## index; \
AACQ_REMOVE(cm->cm_sc, index); \
} \
struct hack
AACQ_COMMAND_QUEUE(free, AACQ_FREE);
AACQ_COMMAND_QUEUE(ready, AACQ_READY);
@ -644,4 +644,3 @@ aac_release_sync_fib(struct aac_softc *sc)
mtx_assert(&sc->aac_io_lock, MA_OWNED);
}

View File

@ -168,7 +168,7 @@ static int acpi_cpu_cx_cst(struct acpi_cpu_softc *sc);
static void acpi_cpu_startup(void *arg);
static void acpi_cpu_startup_cx(struct acpi_cpu_softc *sc);
static void acpi_cpu_cx_list(struct acpi_cpu_softc *sc);
static void acpi_cpu_idle(void);
static void acpi_cpu_idle(sbintime_t sbt);
static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context);
static int acpi_cpu_quirks(void);
static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS);
@ -954,13 +954,13 @@ acpi_cpu_startup_cx(struct acpi_cpu_softc *sc)
* interrupts are re-enabled.
*/
static void
acpi_cpu_idle()
acpi_cpu_idle(sbintime_t sbt)
{
struct acpi_cpu_softc *sc;
struct acpi_cx *cx_next;
uint64_t cputicks;
uint32_t start_time, end_time;
int bm_active, cx_next_idx, i;
int bm_active, cx_next_idx, i, us;
/*
* Look up our CPU id to get our softc. If it's NULL, we'll use C1
@ -980,13 +980,16 @@ acpi_cpu_idle()
}
/* Find the lowest state that has small enough latency. */
us = sc->cpu_prev_sleep;
if (sbt >= 0 && us > (sbt >> 12))
us = (sbt >> 12);
cx_next_idx = 0;
if (cpu_disable_deep_sleep)
i = min(sc->cpu_cx_lowest, sc->cpu_non_c3);
else
i = sc->cpu_cx_lowest;
for (; i >= 0; i--) {
if (sc->cpu_cx_states[i].trans_lat * 3 <= sc->cpu_prev_sleep) {
if (sc->cpu_cx_states[i].trans_lat * 3 <= us) {
cx_next_idx = i;
break;
}

View File

@ -147,8 +147,7 @@ hpet_disable(struct hpet_softc *sc)
}
static int
hpet_start(struct eventtimer *et,
struct bintime *first, struct bintime *period)
hpet_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
{
struct hpet_timer *mt = (struct hpet_timer *)et->et_priv;
struct hpet_timer *t;
@ -156,20 +155,16 @@ hpet_start(struct eventtimer *et,
uint32_t fdiv, now;
t = (mt->pcpu_master < 0) ? mt : &sc->t[mt->pcpu_slaves[curcpu]];
if (period != NULL) {
if (period != 0) {
t->mode = 1;
t->div = (sc->freq * (period->frac >> 32)) >> 32;
if (period->sec != 0)
t->div += sc->freq * period->sec;
t->div = (sc->freq * period) >> 32;
} else {
t->mode = 2;
t->div = 0;
}
if (first != NULL) {
fdiv = (sc->freq * (first->frac >> 32)) >> 32;
if (first->sec != 0)
fdiv += sc->freq * first->sec;
} else
if (first != 0)
fdiv = (sc->freq * first) >> 32;
else
fdiv = t->div;
if (t->irq < 0)
bus_write_4(sc->mem_res, HPET_ISR, 1 << t->num);
@ -684,12 +679,9 @@ hpet_attach(device_t dev)
if ((t->caps & HPET_TCAP_PER_INT) == 0)
t->et.et_quality -= 10;
t->et.et_frequency = sc->freq;
t->et.et_min_period.sec = 0;
t->et.et_min_period.frac =
(((uint64_t)(HPET_MIN_CYCLES * 2) << 32) / sc->freq) << 32;
t->et.et_max_period.sec = 0xfffffffeLLU / sc->freq;
t->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->freq) << 32;
t->et.et_min_period =
((uint64_t)(HPET_MIN_CYCLES * 2) << 32) / sc->freq;
t->et.et_max_period = (0xfffffffeLLU << 32) / sc->freq;
t->et.et_start = hpet_start;
t->et.et_stop = hpet_stop;
t->et.et_priv = &sc->t[i];

View File

@ -1,16 +1,15 @@
/*
*****************************************************************************************
** O.S : FreeBSD
********************************************************************************
** OS : FreeBSD
** FILE NAME : arcmsr.c
** BY : Erich Chen, Ching Huang
** Description: SCSI RAID Device Driver for
** ARECA (ARC11XX/ARC12XX/ARC13XX/ARC16XX/ARC188x) SATA/SAS RAID HOST Adapter
** ARCMSR RAID Host adapter
** [RAID controller:INTEL 331(PCI-X) 341(PCI-EXPRESS) chip set]
******************************************************************************************
************************************************************************
** ARECA (ARC11XX/ARC12XX/ARC13XX/ARC16XX/ARC188x)
** SATA/SAS RAID HOST Adapter
********************************************************************************
********************************************************************************
**
** Copyright (C) 2002 - 2010, Areca Technology Corporation All rights reserved.
** Copyright (C) 2002 - 2012, Areca Technology Corporation All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
@ -33,7 +32,7 @@
** 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.
**************************************************************************
********************************************************************************
** History
**
** REV# DATE NAME DESCRIPTION
@ -73,7 +72,7 @@
** 1.20.00.23 01/30/2012 Ching Huang Fixed Request requeued and Retrying command
** 1.20.00.24 06/11/2012 Ching Huang Fixed return sense data condition
** 1.20.00.25 08/17/2012 Ching Huang Fixed hotplug device no function on type A adapter
** 1.20.00.26 12/14/2012 Ching Huang Added support ARC1214
** 1.20.00.26 12/14/2012 Ching Huang Added support ARC1214,1224
******************************************************************************************
*/
@ -145,7 +144,7 @@ __FBSDID("$FreeBSD$");
#define arcmsr_callout_init(a) callout_init(a);
#endif
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.26 2012-12-14"
#define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.26 2013-01-08"
#include <dev/arcmsr/arcmsr.h>
/*
**************************************************************************
@ -168,7 +167,7 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
static void arcmsr_iop_init(struct AdapterControlBlock *acb);
static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb);
static void arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer);
static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb, struct QBUFFER *prbuffer);
static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb);
static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb);
static void arcmsr_srb_complete(struct CommandControlBlock *srb, int stand_flag);
@ -212,7 +211,11 @@ static device_method_t arcmsr_methods[]={
DEVMETHOD(device_suspend, arcmsr_suspend),
DEVMETHOD(device_resume, arcmsr_resume),
#if __FreeBSD_version >= 803000
DEVMETHOD_END
#else
{ 0, 0 }
#endif
};
static driver_t arcmsr_driver={
@ -1381,13 +1384,61 @@ static void arcmsr_poll(struct cam_sim *psim)
**************************************************************************
**************************************************************************
*/
static void arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
static u_int32_t arcmsr_Read_iop_rqbuffer_data_D(struct AdapterControlBlock *acb,
struct QBUFFER *prbuffer) {
u_int8_t *pQbuffer;
u_int8_t *buf1 = 0;
u_int32_t *iop_data, *buf2 = 0;
u_int32_t iop_len, data_len;
iop_data = (u_int32_t *)prbuffer->data;
iop_len = (u_int32_t)prbuffer->data_len;
if ( iop_len > 0 )
{
buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
buf2 = (u_int32_t *)buf1;
if( buf1 == NULL)
return (0);
data_len = iop_len;
while(data_len >= 4)
{
*buf2++ = *iop_data++;
data_len -= 4;
}
if(data_len)
*buf2 = *iop_data;
buf2 = (u_int32_t *)buf1;
}
while (iop_len > 0) {
pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
*pQbuffer = *buf1;
acb->rqbuf_lastindex++;
/* if last, index number set it to 0 */
acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
buf1++;
iop_len--;
}
if(buf2)
free( (u_int8_t *)buf2, M_DEVBUF);
/* let IOP know data has been read */
arcmsr_iop_message_read(acb);
return (1);
}
/*
**************************************************************************
**************************************************************************
*/
static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
struct QBUFFER *prbuffer) {
u_int8_t *pQbuffer;
u_int8_t *iop_data;
u_int32_t iop_len;
if(acb->adapter_type == ACB_ADAPTER_TYPE_D) {
return(arcmsr_Read_iop_rqbuffer_data_D(acb, prbuffer));
}
iop_data = (u_int8_t *)prbuffer->data;
iop_len = (u_int32_t)prbuffer->data_len;
while (iop_len > 0) {
@ -1401,6 +1452,7 @@ static void arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
}
/* let IOP know data has been read */
arcmsr_iop_message_read(acb);
return (1);
}
/*
**************************************************************************
@ -1417,7 +1469,8 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
my_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) &
(ARCMSR_MAX_QBUFFER-1);
if(my_empty_len >= prbuffer->data_len) {
arcmsr_Read_iop_rqbuffer_data(acb, prbuffer);
if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
} else {
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
}
@ -1427,6 +1480,50 @@ static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
**********************************************************************
**********************************************************************
*/
static void arcmsr_Write_data_2iop_wqbuffer_D(struct AdapterControlBlock *acb)
{
u_int8_t *pQbuffer;
struct QBUFFER *pwbuffer;
u_int8_t *buf1 = 0;
u_int32_t *iop_data, *buf2 = 0;
u_int32_t allxfer_len = 0, data_len;
if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
buf1 = malloc(128, M_DEVBUF, M_NOWAIT | M_ZERO);
buf2 = (u_int32_t *)buf1;
if( buf1 == NULL)
return;
acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
pwbuffer = arcmsr_get_iop_wqbuffer(acb);
iop_data = (u_int32_t *)pwbuffer->data;
while((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
&& (allxfer_len < 124)) {
pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
*buf1 = *pQbuffer;
acb->wqbuf_firstindex++;
acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
buf1++;
allxfer_len++;
}
pwbuffer->data_len = allxfer_len;
data_len = allxfer_len;
buf1 = (u_int8_t *)buf2;
while(data_len >= 4)
{
*iop_data++ = *buf2++;
data_len -= 4;
}
if(data_len)
*iop_data = *buf2;
free( buf1, M_DEVBUF);
arcmsr_iop_message_wrote(acb);
}
}
/*
**********************************************************************
**********************************************************************
*/
static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
{
u_int8_t *pQbuffer;
@ -1434,6 +1531,10 @@ static void arcmsr_Write_data_2iop_wqbuffer(struct AdapterControlBlock *acb)
u_int8_t *iop_data;
int32_t allxfer_len=0;
if(acb->adapter_type == ACB_ADAPTER_TYPE_D) {
arcmsr_Write_data_2iop_wqbuffer_D(acb);
return;
}
if(acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READ) {
acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READ);
pwbuffer = arcmsr_get_iop_wqbuffer(acb);
@ -2153,7 +2254,8 @@ u_int32_t arcmsr_iop_ioctlcmd(struct AdapterControlBlock *acb, u_int32_t ioctl_c
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
arcmsr_Read_iop_rqbuffer_data(acb, prbuffer);
if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
}
pcmdmessagefld->cmdmessage.Length = allxfer_len;
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
@ -2374,7 +2476,8 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, union ccb *p
acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
prbuffer = arcmsr_get_iop_rqbuffer(acb);
arcmsr_Read_iop_rqbuffer_data(acb, prbuffer);
if(arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
}
pcmdmessagefld->cmdmessage.Length = allxfer_len;
pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;

View File

@ -1,17 +1,14 @@
/*
***********************************************************************************************
** O.S : FreeBSD
********************************************************************************
** OS : FreeBSD
** FILE NAME : arcmsr.h
** BY : Erich Chen, Ching Huang
** Description: SCSI RAID Device Driver for
** ARECA SATA/SAS RAID HOST Adapter
** [RAID controller:INTEL 331(PCI-X) 341(PCI-EXPRESS) chip set]
***********************************************************************************************
************************************************************************
** Copyright (C) 2002 - 2010, Areca Technology Corporation All rights reserved.
**
** Web site: www.areca.com.tw
** E-mail: erich@areca.com.tw; ching2048@areca.com.tw
** ARECA (ARC11XX/ARC12XX/ARC13XX/ARC16XX/ARC188x)
** SATA/SAS RAID HOST Adapter
********************************************************************************
********************************************************************************
** Copyright (C) 2002 - 2012, Areca Technology Corporation All rights reserved.
**
** Redistribution and use in source and binary forms,with or without
** modification,are permitted provided that the following conditions

View File

@ -236,9 +236,9 @@ ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
rate = rt->info[rc[i].rix].rateCode;
/*
* XXX only do this for legacy rates?
* Only enable short preamble for legacy rates
*/
if (bf->bf_state.bfs_shpream)
if ((! IS_HT_RATE(rate)) && bf->bf_state.bfs_shpream)
rate |= rt->info[rc[i].rix].shortPreamble;
/*
@ -267,6 +267,19 @@ ath_tx_rate_fill_rcflags(struct ath_softc *sc, struct ath_buf *bf)
ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20)
rc[i].flags |= ATH_RC_SGI_FLAG;
/*
* If we have STBC TX enabled and the receiver
* can receive (at least) 1 stream STBC, AND it's
* MCS 0-7, AND we have at least two chains enabled,
* enable STBC.
*/
if (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC &&
ni->ni_htcap & IEEE80211_HTCAP_RXSTBC_1STREAM &&
(sc->sc_cur_txchainmask > 1) &&
HT_RC_2_STREAMS(rate) == 1) {
rc[i].flags |= ATH_RC_STBC_FLAG;
}
/* XXX dual stream? and 3-stream? */
}
@ -459,6 +472,9 @@ ath_get_aggr_limit(struct ath_softc *sc, struct ath_buf *bf)
*
* It, along with ath_buf_set_rate, must be called -after- a burst
* or aggregate is setup.
*
* XXX TODO: it should use the rate series information from the
* ath_buf, rather than recalculating it here!
*/
static void
ath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni,
@ -507,34 +523,6 @@ ath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni,
*/
series[i].ChSel = sc->sc_cur_txchainmask;
if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA))
series[i].RateFlags |= HAL_RATESERIES_RTS_CTS;
/*
* Transmit 40MHz frames only if the node has negotiated
* it rather than whether the node is capable of it or not.
* It's subtly different in the hostap case.
*/
if (ni->ni_chw == 40)
series[i].RateFlags |= HAL_RATESERIES_2040;
/*
* Set short-GI only if the node has advertised it
* the channel width is suitable, and we support it.
* We don't currently have a "negotiated" set of bits -
* ni_htcap is what the remote end sends, not what this
* node is capable of.
*/
if (ni->ni_chw == 40 &&
ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40 &&
ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40)
series[i].RateFlags |= HAL_RATESERIES_HALFGI;
if (ni->ni_chw == 20 &&
ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20 &&
ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20)
series[i].RateFlags |= HAL_RATESERIES_HALFGI;
/*
* Setup rate and TX power cap for this series.
*/
@ -542,24 +530,56 @@ ath_rateseries_setup(struct ath_softc *sc, struct ieee80211_node *ni,
series[i].RateIndex = rc[i].rix;
series[i].tx_power_cap = 0x3f; /* XXX for now */
/*
* If we have STBC TX enabled and the receiver
* can receive (at least) 1 stream STBC, AND it's
* MCS 0-7, AND we have at least two chains enabled,
* enable STBC.
* Enable RTS/CTS as appropriate.
*/
if (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC &&
ni->ni_htcap & IEEE80211_HTCAP_RXSTBC_1STREAM &&
(sc->sc_cur_txchainmask > 1) &&
HT_RC_2_STREAMS(series[i].Rate) == 1) {
series[i].RateFlags |= HAL_RATESERIES_STBC;
if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA))
series[i].RateFlags |= HAL_RATESERIES_RTS_CTS;
if (IS_HT_RATE(rt->info[rc[i].rix].rateCode)) {
/*
* Transmit 40MHz frames only if the node has negotiated
* it rather than whether the node is capable of it or not.
* It's subtly different in the hostap case.
*/
if (ni->ni_chw == 40)
series[i].RateFlags |= HAL_RATESERIES_2040;
/*
* Set short-GI only if the node has advertised it
* the channel width is suitable, and we support it.
* We don't currently have a "negotiated" set of bits -
* ni_htcap is what the remote end sends, not what this
* node is capable of.
*/
if (ni->ni_chw == 40 &&
ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40 &&
ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40)
series[i].RateFlags |= HAL_RATESERIES_HALFGI;
if (ni->ni_chw == 20 &&
ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20 &&
ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20)
series[i].RateFlags |= HAL_RATESERIES_HALFGI;
/*
* If we have STBC TX enabled and the receiver
* can receive (at least) 1 stream STBC, AND it's
* MCS 0-7, AND we have at least two chains enabled,
* enable STBC.
*/
if (ic->ic_htcaps & IEEE80211_HTCAP_TXSTBC &&
ni->ni_htcap & IEEE80211_HTCAP_RXSTBC_1STREAM &&
(sc->sc_cur_txchainmask > 1) &&
HT_RC_2_STREAMS(series[i].Rate) == 1) {
series[i].RateFlags |= HAL_RATESERIES_STBC;
}
/*
* XXX TODO: LDPC if it's possible
*/
}
/*
* XXX TODO: LDPC if it's possible
*/
/*
* PktDuration doesn't include slot, ACK, RTS, etc timing -
* it's just the packet duration

View File

@ -84,6 +84,8 @@ void ath_rate_detach(struct ath_ratectrl *);
#define ATH_RC_SGI_FLAG 0x04 /* use short-GI */
#define ATH_RC_HT_FLAG 0x08 /* use HT */
#define ATH_RC_RTSCTS_FLAG 0x10 /* enable RTS/CTS protection */
#define ATH_RC_STBC_FLAG 0x20 /* enable STBC */
#define ATH_RC_LDPC_FLAG 0x40 /* enable STBC */
struct ath_rc_series {
uint8_t rix; /* ratetable index, not rate code */

View File

@ -95,7 +95,7 @@ __FBSDID("$FreeBSD$");
/****************************************************************************/
#define BCE_DEVDESC_MAX 64
static struct bce_type bce_devs[] = {
static const struct bce_type bce_devs[] = {
/* BCM5706C Controllers and OEM boards. */
{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3101,
"HP NC370T Multifunction Gigabit Server Adapter" },
@ -161,7 +161,7 @@ static struct bce_type bce_devs[] = {
/****************************************************************************/
/* Supported Flash NVRAM device data. */
/****************************************************************************/
static struct flash_spec flash_table[] =
static const struct flash_spec flash_table[] =
{
#define BUFFERED_FLAGS (BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
#define NONBUFFERED_FLAGS (BCE_NV_WREN)
@ -258,7 +258,7 @@ static struct flash_spec flash_table[] =
* logical-to-physical mapping is required in the
* driver.
*/
static struct flash_spec flash_5709 = {
static const struct flash_spec flash_5709 = {
.flags = BCE_NV_BUFFERED,
.page_bits = BCM5709_FLASH_PAGE_BITS,
.page_size = BCM5709_FLASH_PAGE_SIZE,
@ -481,8 +481,8 @@ MODULE_DEPEND(bce, pci, 1, 1, 1);
MODULE_DEPEND(bce, ether, 1, 1, 1);
MODULE_DEPEND(bce, miibus, 1, 1, 1);
DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL);
DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL);
/****************************************************************************/
@ -647,7 +647,7 @@ SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
static int
bce_probe(device_t dev)
{
struct bce_type *t;
const struct bce_type *t;
struct bce_softc *sc;
char *descbuf;
u16 vid = 0, did = 0, svid = 0, sdid = 0;
@ -655,7 +655,6 @@ bce_probe(device_t dev)
t = bce_devs;
sc = device_get_softc(dev);
bzero(sc, sizeof(struct bce_softc));
sc->bce_unit = device_get_unit(dev);
sc->bce_dev = dev;
@ -1040,7 +1039,7 @@ bce_attach(device_t dev)
struct bce_softc *sc;
struct ifnet *ifp;
u32 val;
int error, rid, rc = 0;
int count, error, rc = 0, rid;
sc = device_get_softc(dev);
sc->bce_dev = dev;
@ -1077,6 +1076,7 @@ bce_attach(device_t dev)
bce_probe_pci_caps(dev, sc);
rid = 1;
count = 0;
#if 0
/* Try allocating MSI-X interrupts. */
if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
@ -1084,14 +1084,14 @@ bce_attach(device_t dev)
((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE)) != NULL)) {
msi_needed = sc->bce_msi_count = 1;
msi_needed = count = 1;
if (((error = pci_alloc_msix(dev, &sc->bce_msi_count)) != 0) ||
(sc->bce_msi_count != msi_needed)) {
if (((error = pci_alloc_msix(dev, &count)) != 0) ||
(count != msi_needed)) {
BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
"Received = %d, error = %d\n", __FILE__, __LINE__,
msi_needed, sc->bce_msi_count, error);
sc->bce_msi_count = 0;
msi_needed, count, error);
count = 0;
pci_release_msi(dev);
bus_release_resource(dev, SYS_RES_MEMORY, rid,
sc->bce_res_irq);
@ -1100,19 +1100,18 @@ bce_attach(device_t dev)
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
__FUNCTION__);
sc->bce_flags |= BCE_USING_MSIX_FLAG;
sc->bce_intr = bce_intr;
}
}
#endif
/* Try allocating a MSI interrupt. */
if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
(bce_msi_enable >= 1) && (sc->bce_msi_count == 0)) {
sc->bce_msi_count = 1;
if ((error = pci_alloc_msi(dev, &sc->bce_msi_count)) != 0) {
(bce_msi_enable >= 1) && (count == 0)) {
count = 1;
if ((error = pci_alloc_msi(dev, &count)) != 0) {
BCE_PRINTF("%s(%d): MSI allocation failed! "
"error = %d\n", __FILE__, __LINE__, error);
sc->bce_msi_count = 0;
count = 0;
pci_release_msi(dev);
} else {
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI "
@ -1120,23 +1119,19 @@ bce_attach(device_t dev)
sc->bce_flags |= BCE_USING_MSI_FLAG;
if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
sc->bce_irq_rid = 1;
sc->bce_intr = bce_intr;
rid = 1;
}
}
/* Try allocating a legacy interrupt. */
if (sc->bce_msi_count == 0) {
if (count == 0) {
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
__FUNCTION__);
rid = 0;
sc->bce_intr = bce_intr;
}
sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&rid, RF_SHAREABLE | RF_ACTIVE);
sc->bce_irq_rid = rid;
&rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE));
/* Report any IRQ allocation errors. */
if (sc->bce_res_irq == NULL) {
@ -1635,7 +1630,7 @@ bce_shutdown(device_t dev)
static u32
bce_reg_rd(struct bce_softc *sc, u32 offset)
{
u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
u32 val = REG_RD(sc, offset);
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
__FUNCTION__, offset, val);
return val;
@ -1653,7 +1648,7 @@ bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
{
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
__FUNCTION__, offset, val);
bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
REG_WR16(sc, offset, val);
}
@ -1668,7 +1663,7 @@ bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
{
DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
__FUNCTION__, offset, val);
bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
REG_WR(sc, offset, val);
}
#endif
@ -1879,13 +1874,6 @@ bce_miibus_read_reg(device_t dev, int phy, int reg)
sc = device_get_softc(dev);
/* Make sure we are accessing the correct PHY address. */
if (phy != sc->bce_phy_addr) {
DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
"for PHY read!\n", phy);
return(0);
}
/*
* The 5709S PHY is an IEEE Clause 45 PHY
* with special mappings to work with IEEE
@ -1968,13 +1956,6 @@ bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
sc = device_get_softc(dev);
/* Make sure we are accessing the correct PHY address. */
if (phy != sc->bce_phy_addr) {
DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
"for PHY write!\n", phy);
return(0);
}
DB_PRINT_PHY_REG(reg, val);
/*
@ -2535,7 +2516,7 @@ bce_init_nvram(struct bce_softc *sc)
{
u32 val;
int j, entry_count, rc = 0;
struct flash_spec *flash;
const struct flash_spec *flash;
DBENTER(BCE_VERBOSE_NVRAM);
@ -3949,8 +3930,8 @@ bce_release_resources(struct bce_softc *sc)
if (sc->bce_res_irq != NULL) {
DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
sc->bce_res_irq);
bus_release_resource(dev, SYS_RES_IRQ,
rman_get_rid(sc->bce_res_irq), sc->bce_res_irq);
}
if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
@ -11650,4 +11631,3 @@ bce_breakpoint(struct bce_softc *sc)
return;
}
#endif

View File

@ -622,7 +622,7 @@ struct bce_type {
u_int16_t bce_did;
u_int16_t bce_svid;
u_int16_t bce_sdid;
char *bce_name;
const char *bce_name;
};
/****************************************************************************/
@ -716,7 +716,7 @@ struct flash_spec {
u32 page_size;
u32 addr_mask;
u32 total_size;
u8 *name;
const u8 *name;
};
@ -2001,7 +2001,7 @@ struct l2_fhdr {
#define BCE_MISC_ENABLE_CLR_BITS_UMP_ENABLE (1L<<27)
#define BCE_MISC_ENABLE_CLR_BITS_RV2P_CMD_SCHEDULER_ENABLE (1L<<28)
#define BCE_MISC_ENABLE_CLR_BITS_RSVD_FUTURE_ENABLE (0x7L<<29)
#define BCE_MISC_ENABLE_CLR_DEFAULT 0x17ffffff
#define BCE_MISC_CLOCK_CONTROL_BITS 0x00000818
@ -6318,19 +6318,19 @@ struct fw_info {
u32 text_addr;
u32 text_len;
u32 text_index;
u32 *text;
const u32 *text;
/* Data section. */
u32 data_addr;
u32 data_len;
u32 data_index;
u32 *data;
const u32 *data;
/* SBSS section. */
u32 sbss_addr;
u32 sbss_len;
u32 sbss_index;
u32 *sbss;
const u32 *sbss;
/* BSS section. */
u32 bss_addr;
@ -6421,7 +6421,7 @@ struct fw_info {
struct bce_softc
{
/* Interface info. Must be first!! */
/* Interface info */
struct ifnet *bce_ifp;
/* Parent device handle */
@ -6451,10 +6451,7 @@ struct bce_softc
struct mtx bce_mtx;
/* Interrupt handler. */
driver_intr_t *bce_intr;
void *bce_intrhand;
int bce_irq_rid;
int bce_msi_count;
/* ASIC Chip ID. */
u32 bce_chipid;
@ -6509,7 +6506,7 @@ struct bce_softc
u16 link_speed;
/* Flash NVRAM settings */
struct flash_spec *bce_flash_info;
const struct flash_spec *bce_flash_info;
/* Flash NVRAM size */
u32 bce_flash_size;
@ -6518,7 +6515,7 @@ struct bce_softc
u32 bce_shmem_base;
/* Name string */
char *bce_name;
const char *bce_name;
/* Tracks the version of bootcode firmware. */
char bce_bc_ver[32];
@ -6834,4 +6831,3 @@ struct bce_softc
};
#endif /* __BCEREG_H_DEFINED */

View File

@ -824,7 +824,8 @@ cas_disable_rx(struct cas_softc *sc)
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
if (cas_bitwait(sc, CAS_MAC_RX_CONF, CAS_MAC_RX_CONF_EN, 0))
return (1);
device_printf(sc->sc_dev, "cannot disable RX MAC\n");
if (bootverbose)
device_printf(sc->sc_dev, "cannot disable RX MAC\n");
return (0);
}
@ -838,7 +839,8 @@ cas_disable_tx(struct cas_softc *sc)
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
if (cas_bitwait(sc, CAS_MAC_TX_CONF, CAS_MAC_TX_CONF_EN, 0))
return (1);
device_printf(sc->sc_dev, "cannot disable TX MAC\n");
if (bootverbose)
device_printf(sc->sc_dev, "cannot disable TX MAC\n");
return (0);
}
@ -1041,7 +1043,8 @@ cas_init_locked(struct cas_softc *sc)
/*
* Enable infinite bursts for revisions without PCI issues if
* applicable. Doing so greatly improves the TX performance on
* !__sparc64__.
* !__sparc64__ (on sparc64, setting CAS_INF_BURST improves TX
* performance only marginally but hurts RX throughput quite a bit).
*/
CAS_WRITE_4(sc, CAS_INF_BURST,
#if !defined(__sparc64__)
@ -2691,7 +2694,10 @@ cas_pci_attach(device_t dev)
return (ENXIO);
}
pci_enable_busmaster(dev);
/* PCI configuration */
pci_write_config(dev, PCIR_COMMAND,
pci_read_config(dev, PCIR_COMMAND, 2) | PCIM_CMD_BUSMASTEREN |
PCIM_CMD_MWRICEN | PCIM_CMD_PERRESPEN | PCIM_CMD_SERRESPEN, 2);
sc->sc_dev = dev;
if (sc->sc_variant == CAS_CAS && pci_get_devid(dev) < 0x02)

View File

@ -182,6 +182,7 @@
#define com_xoff1 6 /* XOFF 1 character (R/W) */
#define com_xoff2 7 /* XOFF 2 character (R/W) */
#define DW_REG_USR 31 /* DesignWare derived Uart Status Reg */
#define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */
#define REG_USR com_usr
#define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */

View File

@ -387,11 +387,11 @@ i_setsoc(isc_session_t *sp, int fd, struct thread *td)
if(sp->soc != NULL)
isc_stop_receiver(sp);
error = fget(td, fd, CAP_SOCK_ALL, &sp->fp);
error = fget(td, fd, CAP_SOCK_CLIENT, &sp->fp);
if(error)
return error;
if((error = fgetsock(td, fd, CAP_SOCK_ALL, &sp->soc, 0)) == 0) {
if((error = fgetsock(td, fd, CAP_SOCK_CLIENT, &sp->soc, 0)) == 0) {
sp->td = td;
isc_start_receiver(sp);
}

View File

@ -2997,7 +2997,7 @@ mfi_stp_cmd(struct mfi_softc *sc, struct mfi_command *cm,caddr_t arg)
cm->cm_frame->stp.sgl.sg64[i].len =
ioc->mfi_sgl[i].iov_len;
} else {
cm->cm_frame->stp.sgl.sg32[i].len =
cm->cm_frame->stp.sgl.sg32[i].addr =
kern_sge[i].phys_addr;
cm->cm_frame->stp.sgl.sg32[i].len =
ioc->mfi_sgl[i].iov_len;

View File

@ -136,8 +136,8 @@ mps_diag_reset(struct mps_softc *sc,int sleep_flag)
/*Force NO_SLEEP for threads prohibited to sleep
* e.a Thread from interrupt handler are prohibited to sleep.
*/
if(curthread->td_pflags & TDP_NOSLEEPING)
*/
if (curthread->td_no_sleeping != 0)
sleep_flag = NO_SLEEP;
/* Push the magic sequence */
@ -469,8 +469,8 @@ mps_request_sync(struct mps_softc *sc, void *req, MPI2_DEFAULT_REPLY *reply,
uint16_t *data16;
int i, count, ioc_sz, residual;
int sleep_flags = CAN_SLEEP;
if(curthread->td_pflags & TDP_NOSLEEPING)
if (curthread->td_no_sleeping != 0)
sleep_flags = NO_SLEEP;
/* Step 1 */

View File

@ -244,7 +244,6 @@ static const struct pci_quirk pci_quirks[] = {
* but support MSI just fine. QEMU uses the Intel 82440.
*/
{ 0x12378086, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 },
{ 0x12751275, PCI_QUIRK_ENABLE_MSI_VM, 0, 0 }, /* bhyve */
/*
* HPET MMIO base address may appear in Bar1 for AMD SB600 SMBus

View File

@ -769,7 +769,7 @@ const struct puc_cfg puc_pci_devices[] = {
{ 0x1415, 0x9538, 0xffff, 0,
"Oxford Semiconductor OX16PCI958 UARTs",
DEFAULT_RCLK * 10,
DEFAULT_RCLK,
PUC_PORT_8S, 0x18, 0, 8,
},
@ -918,6 +918,7 @@ const struct puc_cfg puc_pci_devices[] = {
DEFAULT_RCLK * 8,
PUC_PORT_4S, 0x10, 0, 8,
},
{ 0x14d2, 0xa004, 0xffff, 0,
"Titan PCI-800H",
DEFAULT_RCLK * 8,
@ -1060,7 +1061,7 @@ const struct puc_cfg puc_pci_devices[] = {
{ 0x9710, 0x9865, 0xa000, 0x3004,
"NetMos NM9865 Quad UART",
DEFAULT_RCLK,
PUC_PORT_4S, 0x10, 4, 0,0
PUC_PORT_4S, 0x10, 4, 0,
},
{ 0x9710, 0x9865, 0xa000, 0x3011,
@ -1420,26 +1421,26 @@ static int
puc_config_timedia(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port,
intptr_t *res)
{
static uint16_t dual[] = {
static const uint16_t dual[] = {
0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
0xD079, 0
};
static uint16_t quad[] = {
static const uint16_t quad[] = {
0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
0xB157, 0
};
static uint16_t octa[] = {
static const uint16_t octa[] = {
0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0
};
static struct {
static const struct {
int ports;
uint16_t *ids;
const uint16_t *ids;
} subdevs[] = {
{ 2, dual },
{ 4, quad },

View File

@ -573,6 +573,13 @@ sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num)
if (slot->quirks & SDHCI_QUIRK_FORCE_DMA)
slot->opt |= SDHCI_HAVE_DMA;
/*
* Use platform-provided transfer backend
* with PIO as a fallback mechanism
*/
if (slot->opt & SDHCI_PLATFORM_TRANSFER)
slot->opt &= ~SDHCI_HAVE_DMA;
if (bootverbose || sdhci_debug) {
slot_printf(slot, "%uMHz%s 4bits%s%s%s %s\n",
slot->max_clk / 1000000,
@ -909,7 +916,7 @@ sdhci_start_data(struct sdhci_slot *slot, struct mmc_data *data)
WR2(slot, SDHCI_BLOCK_COUNT, (data->len + 511) / 512);
}
static void
void
sdhci_finish_data(struct sdhci_slot *slot)
{
struct mmc_data *data = slot->curcmd->data;
@ -1102,13 +1109,23 @@ sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask)
}
if (slot->curcmd->error) {
/* No need to continue after any error. */
sdhci_finish_data(slot);
if (slot->flags & PLATFORM_DATA_STARTED) {
slot->flags &= ~PLATFORM_DATA_STARTED;
SDHCI_PLATFORM_FINISH_TRANSFER(slot->bus, slot);
} else
sdhci_finish_data(slot);
return;
}
/* Handle PIO interrupt. */
if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL))
sdhci_transfer_pio(slot);
if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) {
if ((slot->opt & SDHCI_PLATFORM_TRANSFER) &&
SDHCI_PLATFORM_WILL_HANDLE(slot->bus, slot)) {
SDHCI_PLATFORM_START_TRANSFER(slot->bus, slot, &intmask);
slot->flags |= PLATFORM_DATA_STARTED;
} else
sdhci_transfer_pio(slot);
}
/* Handle DMA border. */
if (intmask & SDHCI_INT_DMA_END) {
struct mmc_data *data = slot->curcmd->data;
@ -1147,8 +1164,13 @@ sdhci_data_irq(struct sdhci_slot *slot, uint32_t intmask)
WR4(slot, SDHCI_DMA_ADDRESS, slot->paddr);
}
/* We have got all data. */
if (intmask & SDHCI_INT_DATA_END)
sdhci_finish_data(slot);
if (intmask & SDHCI_INT_DATA_END) {
if (slot->flags & PLATFORM_DATA_STARTED) {
slot->flags &= ~PLATFORM_DATA_STARTED;
SDHCI_PLATFORM_FINISH_TRANSFER(slot->bus, slot);
} else
sdhci_finish_data(slot);
}
}
static void

View File

@ -224,8 +224,9 @@ struct sdhci_slot {
device_t dev; /* Slot device */
u_char num; /* Slot number */
u_char opt; /* Slot options */
#define SDHCI_HAVE_DMA 1
#define SDHCI_PLATFORM_TRANSFER 2
u_char version;
#define SDHCI_HAVE_DMA 1
uint32_t max_clk; /* Max possible freq */
uint32_t timeout_clk; /* Timeout freq */
bus_dma_tag_t dmatag;
@ -250,6 +251,7 @@ struct sdhci_slot {
#define CMD_STARTED 1
#define STOP_STARTED 2
#define SDHCI_USE_DMA 4 /* Use DMA for this req. */
#define PLATFORM_DATA_STARTED 8 /* Data transfer is handled by platform */
struct mtx mtx; /* Slot mutex */
};
@ -257,6 +259,8 @@ int sdhci_generic_read_ivar(device_t bus, device_t child, int which, uintptr_t *
int sdhci_generic_write_ivar(device_t bus, device_t child, int which, uintptr_t value);
int sdhci_init_slot(device_t dev, struct sdhci_slot *slot, int num);
void sdhci_start_slot(struct sdhci_slot *slot);
/* performs generic clean-up for platform transfers */
void sdhci_finish_data(struct sdhci_slot *slot);
int sdhci_cleanup_slot(struct sdhci_slot *slot);
int sdhci_generic_suspend(struct sdhci_slot *slot);
int sdhci_generic_resume(struct sdhci_slot *slot);

View File

@ -131,6 +131,22 @@ METHOD void write_multi_4 {
bus_size_t count;
}
METHOD int platform_will_handle {
device_t brdev;
struct sdhci_slot *slot;
}
METHOD void platform_start_transfer {
device_t brdev;
struct sdhci_slot *slot;
uint32_t *intmask;
}
METHOD void platform_finish_transfer {
device_t brdev;
struct sdhci_slot *slot;
}
METHOD uint32_t min_freq {
device_t brdev;
struct sdhci_slot *slot;

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