Merge ^/head r286697 through r286857.

This commit is contained in:
Dimitry Andric 2015-08-17 19:02:23 +00:00
commit 6fdf637e23
283 changed files with 18048 additions and 7962 deletions

View File

@ -220,7 +220,7 @@ INSTALLTMP!= /usr/bin/mktemp -d -u -t install
# This stage is responsible for creating the object
# tree and building any tools that are needed during
# the build process. Some programs are listed during
# this phase because they build binaires to generate
# this phase because they build binaries to generate
# files needed to build these programs. This stage also
# builds the 'build-tools' target rather than 'all'.
# 3. cross-tools stage [XMAKE]
@ -1494,7 +1494,7 @@ _btxld= usr.sbin/btxld
.if ${MK_BINUTILS_BOOTSTRAP} != "no"
_binutils= gnu/usr.bin/binutils
.endif
.if ${MK_ELFTOOLCHAIN_TOOLS} != "no"
.if ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no"
_elftctools= lib/libelftc \
usr.bin/elfcopy \
usr.bin/nm \
@ -1504,7 +1504,7 @@ _elftctools= lib/libelftc \
# cross-build on a FreeBSD 10 host:
_elftctools+= usr.bin/addr2line
.endif
.elif ${TARGET_ARCH} != ${MACHINE_ARCH} && ${MK_ELFTOOLCHAIN_TOOLS} != "no"
.elif ${TARGET_ARCH} != ${MACHINE_ARCH} && ${MK_ELFTOOLCHAIN_BOOTSTRAP} != "no"
# If cross-building with an external binutils we still need to build strip for
# the target (for at least crunchide).
_elftctools= lib/libelftc \

View File

@ -36,6 +36,26 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW:
20141231 entry below for information about prerequisites and upgrading,
if you are not already using 3.5.0 or higher.
20150817:
Kernel-loadable modules for the random(4) device are back. To use
them, the kernel must have
device random
options RANDOM_LOADABLE
kldload(8) can then be used to load random_fortuna.ko
or random_yarrow.ko. Please note that due to the indirect
function calls that the loadable modules need to provide,
the build-in variants will be slightly more efficient.
The random(4) kernel option RANDOM_DUMMY has been retired due to
unpopularity. It was not all that useful anyway.
20150813:
The WITHOUT_ELFTOOLCHAIN_TOOLS src.conf(5) knob has been retired.
Control over building the ELF Tool Chain tools is now provided by
the WITHOUT_TOOLCHAIN knob.
20150810:
The polarity of Pulse Per Second (PPS) capture events with the
uart(4) driver has been corrected. Prior to this change the PPS

View File

@ -191,9 +191,10 @@ readcmd(int argc __unused, char **argv __unused)
CHECKSTRSPACE(1, p);
if (backslash) {
backslash = 0;
startword = 0;
if (c != '\n')
if (c != '\n') {
startword = 0;
USTPUTC(c, p);
}
continue;
}
if (!rflag && c == '\\') {

View File

@ -73,6 +73,7 @@ char *minusc; /* argument to -c option */
static void options(int);
static void minus_o(char *, int);
static void setoption(int, int);
static void setoptionbyindex(int, int);
static int getopts(char *, char *, char **, char ***, char **);
@ -269,7 +270,7 @@ minus_o(char *name, int val)
} else {
for (i = 0; i < NOPTS; i++)
if (equal(name, optlist[i].name)) {
setoption(optlist[i].letter, val);
setoptionbyindex(i, val);
return;
}
error("Illegal option -o %s", name);
@ -278,26 +279,32 @@ minus_o(char *name, int val)
static void
setoption(int flag, int val)
setoptionbyindex(int idx, int val)
{
int i;
if (flag == 'p' && !val && privileged) {
if (optlist[idx].letter == 'p' && !val && privileged) {
if (setgid(getgid()) == -1)
error("setgid");
if (setuid(getuid()) == -1)
error("setuid");
}
optlist[idx].val = val;
if (val) {
/* #%$ hack for ksh semantics */
if (optlist[idx].letter == 'V')
Eflag = 0;
else if (optlist[idx].letter == 'E')
Vflag = 0;
}
}
static void
setoption(int flag, int val)
{
int i;
for (i = 0; i < NOPTS; i++)
if (optlist[i].letter == flag) {
optlist[i].val = val;
if (val) {
/* #%$ hack for ksh semantics */
if (flag == 'V')
Eflag = 0;
else if (flag == 'E')
Vflag = 0;
}
setoptionbyindex(i, val);
return;
}
error("Illegal option -%c", flag);

View File

@ -121,6 +121,7 @@ FILES+= read4.0 read4.0.stdout
FILES+= read5.0
FILES+= read6.0
FILES+= read7.0
FILES+= read8.0
FILES+= return1.0
FILES+= return2.1
FILES+= return3.1

View File

@ -0,0 +1,17 @@
# $FreeBSD$
read a b c <<\EOF
\
A\
\
\
\
B\
\
\
C\
\
\
\
EOF
[ "$a.$b.$c" = "A.B.C" ]

View File

@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
*/
#include <stdio.h>
@ -2221,7 +2221,7 @@ dump_label(const char *dev)
(void) close(fd);
}
static uint64_t num_large_blocks;
static uint64_t dataset_feature_count[SPA_FEATURES];
/*ARGSUSED*/
static int
@ -2235,8 +2235,15 @@ dump_one_dir(const char *dsname, void *arg)
(void) printf("Could not open %s, error %d\n", dsname, error);
return (0);
}
if (dmu_objset_ds(os)->ds_large_blocks)
num_large_blocks++;
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
if (!dmu_objset_ds(os)->ds_feature_inuse[f])
continue;
ASSERT(spa_feature_table[f].fi_flags &
ZFEATURE_FLAG_PER_DATASET);
dataset_feature_count[f]++;
}
dump_dir(os);
dmu_objset_disown(os, FTAG);
fuid_table_destroy();
@ -2428,6 +2435,9 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
dmu_object_type_t type;
boolean_t is_metadata;
if (bp == NULL)
return (0);
if (dump_opt['b'] >= 5 && bp->blk_birth > 0) {
char blkbuf[BP_SPRINTF_LEN];
snprintf_blkptr(blkbuf, sizeof (blkbuf), bp);
@ -2917,7 +2927,7 @@ zdb_ddt_add_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
avl_index_t where;
zdb_ddt_entry_t *zdde, zdde_search;
if (BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
if (bp == NULL || BP_IS_HOLE(bp) || BP_IS_EMBEDDED(bp))
return (0);
if (dump_opt['S'] > 1 && zb->zb_level == ZB_ROOT_LEVEL) {
@ -3032,7 +3042,6 @@ dump_zpool(spa_t *spa)
dump_metaslab_groups(spa);
if (dump_opt['d'] || dump_opt['i']) {
uint64_t refcount;
dump_dir(dp->dp_meta_objset);
if (dump_opt['d'] >= 3) {
dump_full_bpobj(&spa->spa_deferred_bpobj,
@ -3054,17 +3063,29 @@ dump_zpool(spa_t *spa)
(void) dmu_objset_find(spa_name(spa), dump_one_dir,
NULL, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
(void) feature_get_refcount(spa,
&spa_feature_table[SPA_FEATURE_LARGE_BLOCKS], &refcount);
if (num_large_blocks != refcount) {
(void) printf("large_blocks feature refcount mismatch: "
"expected %lld != actual %lld\n",
(longlong_t)num_large_blocks,
(longlong_t)refcount);
rc = 2;
} else {
(void) printf("Verified large_blocks feature refcount "
"is correct (%llu)\n", (longlong_t)refcount);
for (spa_feature_t f = 0; f < SPA_FEATURES; f++) {
uint64_t refcount;
if (!(spa_feature_table[f].fi_flags &
ZFEATURE_FLAG_PER_DATASET)) {
ASSERT0(dataset_feature_count[f]);
continue;
}
(void) feature_get_refcount(spa,
&spa_feature_table[f], &refcount);
if (dataset_feature_count[f] != refcount) {
(void) printf("%s feature refcount mismatch: "
"%lld datasets != %lld refcount\n",
spa_feature_table[f].fi_uname,
(longlong_t)dataset_feature_count[f],
(longlong_t)refcount);
rc = 2;
} else {
(void) printf("Verified %s feature refcount "
"of %llu is correct\n",
spa_feature_table[f].fi_uname,
(longlong_t)refcount);
}
}
}
if (rc == 0 && (dump_opt['b'] || dump_opt['c']))

View File

@ -191,11 +191,13 @@
.Nm
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl d | e
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem
.Nm
.Cm allow
@ -2705,6 +2707,7 @@ feature.
.Nm
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Xc
.It Xo
@ -2712,6 +2715,7 @@ feature.
.Cm receive Ns | Ns Cm recv
.Op Fl vnFu
.Op Fl d | e
.Op Fl o Sy origin Ns = Ns Ar snapshot
.Ar filesystem
.Xc
.Pp
@ -2796,6 +2800,10 @@ receive operation.
Do not actually receive the stream. This can be useful in conjunction with the
.Fl v
option to verify the name the receive operation would use.
.It Fl o Sy origin Ns = Ns Ar snapshot
Forces the stream to be received as a clone of the given snapshot.
This is only valid if the stream is an incremental stream whose source
is the same as the provided origin.
.It Fl F
Force a rollback of the file system to the most recent snapshot before
performing the receive operation. If receiving an incremental replication

View File

@ -264,8 +264,9 @@ get_usage(zfs_help_t idx)
return (gettext("\tpromote <clone-filesystem>\n"));
case HELP_RECEIVE:
return (gettext("\treceive|recv [-vnFu] <filesystem|volume|"
"snapshot>\n"
"\treceive|recv [-vnFu] [-d | -e] <filesystem>\n"));
"snapshot>\n"
"\treceive|recv [-vnFu] [-o origin=<snapshot>] [-d | -e] "
"<filesystem>\n"));
case HELP_RENAME:
return (gettext("\trename [-f] <filesystem|volume|snapshot> "
"<filesystem|volume|snapshot>\n"
@ -791,7 +792,7 @@ zfs_do_create(int argc, char **argv)
nomem();
break;
case 'o':
if (parseprop(props, optarg))
if (parseprop(props, optarg) != 0)
goto error;
break;
case 's':
@ -3659,7 +3660,7 @@ zfs_do_snapshot(int argc, char **argv)
while ((c = getopt(argc, argv, "ro:")) != -1) {
switch (c) {
case 'o':
if (parseprop(props, optarg))
if (parseprop(props, optarg) != 0)
return (1);
break;
case 'r':
@ -3918,10 +3919,19 @@ zfs_do_receive(int argc, char **argv)
{
int c, err;
recvflags_t flags = { 0 };
nvlist_t *props;
nvpair_t *nvp = NULL;
if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0)
nomem();
/* check options */
while ((c = getopt(argc, argv, ":denuvF")) != -1) {
while ((c = getopt(argc, argv, ":o:denuvF")) != -1) {
switch (c) {
case 'o':
if (parseprop(props, optarg) != 0)
return (1);
break;
case 'd':
flags.isprefix = B_TRUE;
break;
@ -3966,6 +3976,13 @@ zfs_do_receive(int argc, char **argv)
usage(B_FALSE);
}
while ((nvp = nvlist_next_nvpair(props, nvp))) {
if (strcmp(nvpair_name(nvp), "origin") != 0) {
(void) fprintf(stderr, gettext("invalid option"));
usage(B_FALSE);
}
}
if (isatty(STDIN_FILENO)) {
(void) fprintf(stderr,
gettext("Error: Backup stream can not be read "
@ -3974,7 +3991,7 @@ zfs_do_receive(int argc, char **argv)
return (1);
}
err = zfs_receive(g_zfs, argv[0], &flags, STDIN_FILENO, NULL);
err = zfs_receive(g_zfs, argv[0], props, &flags, STDIN_FILENO, NULL);
return (err != 0);
}

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
@ -294,8 +294,8 @@ zhack_feature_enable_sync(void *arg, dmu_tx_t *tx)
feature_enable_sync(spa, feature, tx);
spa_history_log_internal(spa, "zhack enable feature", tx,
"name=%s can_readonly=%u",
feature->fi_guid, feature->fi_can_readonly);
"guid=%s flags=%x",
feature->fi_guid, feature->fi_flags);
}
static void
@ -314,9 +314,7 @@ zhack_do_feature_enable(int argc, char **argv)
*/
desc = NULL;
feature.fi_uname = "zhack";
feature.fi_mos = B_FALSE;
feature.fi_can_readonly = B_FALSE;
feature.fi_activate_on_enable = B_FALSE;
feature.fi_flags = 0;
feature.fi_depends = nodeps;
feature.fi_feature = SPA_FEATURE_NONE;
@ -324,7 +322,7 @@ zhack_do_feature_enable(int argc, char **argv)
while ((c = getopt(argc, argv, "rmd:")) != -1) {
switch (c) {
case 'r':
feature.fi_can_readonly = B_TRUE;
feature.fi_flags |= ZFEATURE_FLAG_READONLY_COMPAT;
break;
case 'd':
desc = strdup(optarg);
@ -413,7 +411,7 @@ zhack_do_feature_ref(int argc, char **argv)
* disk later.
*/
feature.fi_uname = "zhack";
feature.fi_mos = B_FALSE;
feature.fi_flags = 0;
feature.fi_desc = NULL;
feature.fi_depends = nodeps;
feature.fi_feature = SPA_FEATURE_NONE;
@ -422,7 +420,7 @@ zhack_do_feature_ref(int argc, char **argv)
while ((c = getopt(argc, argv, "md")) != -1) {
switch (c) {
case 'm':
feature.fi_mos = B_TRUE;
feature.fi_flags |= ZFEATURE_FLAG_MOS;
break;
case 'd':
decr = B_TRUE;
@ -455,10 +453,10 @@ zhack_do_feature_ref(int argc, char **argv)
if (0 == zap_contains(mos, spa->spa_feat_for_read_obj,
feature.fi_guid)) {
feature.fi_can_readonly = B_FALSE;
feature.fi_flags &= ~ZFEATURE_FLAG_READONLY_COMPAT;
} else if (0 == zap_contains(mos, spa->spa_feat_for_write_obj,
feature.fi_guid)) {
feature.fi_can_readonly = B_TRUE;
feature.fi_flags |= ZFEATURE_FLAG_READONLY_COMPAT;
} else {
fatal(spa, FTAG, "feature is not enabled: %s", feature.fi_guid);
}

View File

@ -22,7 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2012 by Frederik Wessels. All rights reserved.
* Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
* Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved.
@ -4986,7 +4986,8 @@ zpool_do_upgrade(int argc, char **argv)
"---------------\n");
for (i = 0; i < SPA_FEATURES; i++) {
zfeature_info_t *fi = &spa_feature_table[i];
const char *ro = fi->fi_can_readonly ?
const char *ro =
(fi->fi_flags & ZFEATURE_FLAG_READONLY_COMPAT) ?
" (read-only compatible)" : "";
(void) printf("%-37s%s\n", fi->fi_uname, ro);

View File

@ -3586,7 +3586,8 @@ ztest_dmu_read_write(ztest_ds_t *zd, uint64_t id)
*/
n = ztest_random(regions) * stride + ztest_random(width);
s = 1 + ztest_random(2 * width - 1);
dmu_prefetch(os, bigobj, n * chunksize, s * chunksize);
dmu_prefetch(os, bigobj, 0, n * chunksize, s * chunksize,
ZIO_PRIORITY_SYNC_READ);
/*
* Pick a random index and compute the offsets into packobj and bigobj.
@ -5705,8 +5706,10 @@ ztest_run(ztest_shared_t *zs)
* Right before closing the pool, kick off a bunch of async I/O;
* spa_close() should wait for it to complete.
*/
for (uint64_t object = 1; object < 50; object++)
dmu_prefetch(spa->spa_meta_objset, object, 0, 1ULL << 20);
for (uint64_t object = 1; object < 50; object++) {
dmu_prefetch(spa->spa_meta_objset, object, 0, 0, 1ULL << 20,
ZIO_PRIORITY_SYNC_READ);
}
spa_close(spa, FTAG);
@ -5905,6 +5908,7 @@ ztest_init(ztest_shared_t *zs)
}
VERIFY3U(0, ==, spa_create(ztest_opts.zo_pool, nvroot, props, NULL));
nvlist_free(nvroot);
nvlist_free(props);
VERIFY3U(0, ==, spa_open(ztest_opts.zo_pool, &spa, FTAG));
zs->zs_metaslab_sz =

View File

@ -668,8 +668,8 @@ typedef struct recvflags {
boolean_t nomount;
} recvflags_t;
extern int zfs_receive(libzfs_handle_t *, const char *, recvflags_t *,
int, avl_tree_t *);
extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *,
recvflags_t *, int, avl_tree_t *);
typedef enum diff_flags {
ZFS_DIFF_PARSEABLE = 0x1,

View File

@ -3535,7 +3535,7 @@ zpool_vdev_name(libzfs_handle_t *hdl, zpool_handle_t *zhp, nvlist_t *nv,
}
static int
zbookmark_compare(const void *a, const void *b)
zbookmark_mem_compare(const void *a, const void *b)
{
return (memcmp(a, b, sizeof (zbookmark_phys_t)));
}
@ -3598,7 +3598,7 @@ zpool_get_errlog(zpool_handle_t *zhp, nvlist_t **nverrlistp)
zc.zc_nvlist_dst_size;
count -= zc.zc_nvlist_dst_size;
qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_compare);
qsort(zb, count, sizeof (zbookmark_phys_t), zbookmark_mem_compare);
verify(nvlist_alloc(nverrlistp, 0, KM_SLEEP) == 0);

View File

@ -64,8 +64,9 @@ extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
/* We need to use something for ENODATA. */
#define ENODATA EIDRM
static int zfs_receive_impl(libzfs_handle_t *, const char *, recvflags_t *,
int, const char *, nvlist_t *, avl_tree_t *, char **, int, uint64_t *);
static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
uint64_t *);
static const zio_cksum_t zero_cksum = { 0 };
@ -2498,7 +2499,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
* zfs_receive_one() will take care of it (ie,
* recv_skip() and return 0).
*/
error = zfs_receive_impl(hdl, destname, flags, fd,
error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
action_handlep);
if (error == ENODATA) {
@ -2631,9 +2632,9 @@ recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
*/
static int
zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
recvflags_t *flags, dmu_replay_record_t *drr,
dmu_replay_record_t *drr_noswap, const char *sendfs,
nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
uint64_t *action_handlep)
{
zfs_cmd_t zc = { 0 };
@ -2798,10 +2799,15 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
if (flags->verbose)
(void) printf("found clone origin %s\n", zc.zc_string);
} else if (originsnap) {
(void) strncpy(zc.zc_string, originsnap, ZFS_MAXNAMELEN);
if (flags->verbose)
(void) printf("using provided clone origin %s\n",
zc.zc_string);
}
stream_wantsnewfs = (drrb->drr_fromguid == 0 ||
(drrb->drr_flags & DRR_FLAG_CLONE));
(drrb->drr_flags & DRR_FLAG_CLONE) || originsnap);
if (stream_wantsnewfs) {
/*
@ -3179,9 +3185,10 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
}
static int
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
int infd, const char *sendfs, nvlist_t *stream_nv, avl_tree_t *stream_avl,
char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
uint64_t *action_handlep)
{
int err;
dmu_replay_record_t drr, drr_noswap;
@ -3200,6 +3207,12 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
"(%s) does not exist"), tosnap);
return (zfs_error(hdl, EZFS_NOENT, errbuf));
}
if (originsnap &&
!zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
"(%s) does not exist"), originsnap);
return (zfs_error(hdl, EZFS_NOENT, errbuf));
}
/* read in the BEGIN record */
if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
@ -3272,14 +3285,14 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
*cp = '\0';
sendfs = nonpackage_sendfs;
}
return (zfs_receive_one(hdl, infd, tosnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl,
top_zfs, cleanup_fd, action_handlep));
return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
cleanup_fd, action_handlep));
} else {
assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
DMU_COMPOUNDSTREAM);
return (zfs_receive_package(hdl, infd, tosnap, flags,
&drr, &zcksum, top_zfs, cleanup_fd, action_handlep));
return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
&zcksum, top_zfs, cleanup_fd, action_handlep));
}
}
@ -3290,18 +3303,24 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
* (-1 will override -2).
*/
int
zfs_receive(libzfs_handle_t *hdl, const char *tosnap, recvflags_t *flags,
int infd, avl_tree_t *stream_avl)
zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
recvflags_t *flags, int infd, avl_tree_t *stream_avl)
{
char *top_zfs = NULL;
int err;
int cleanup_fd;
uint64_t action_handle = 0;
char *originsnap = NULL;
if (props) {
err = nvlist_lookup_string(props, "origin", &originsnap);
if (err && err != ENOENT)
return (err);
}
cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
VERIFY(cleanup_fd >= 0);
err = zfs_receive_impl(hdl, tosnap, flags, infd, NULL, NULL,
err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
stream_avl, &top_zfs, cleanup_fd, &action_handle);
VERIFY(0 == close(cleanup_fd));

View File

@ -135,8 +135,18 @@ extern int aok;
/*
* DTrace SDT probes have different signatures in userland than they do in
* kernel. If they're being used in kernel code, re-define them out of
* the kernel. If they're being used in kernel code, re-define them out of
* existence for their counterparts in libzpool.
*
* Here's an example of how to use the set-error probes in userland:
* zfs$target:::set-error /arg0 == EBUSY/ {stack();}
*
* Here's an example of how to use DTRACE_PROBE probes in userland:
* If there is a probe declared as follows:
* DTRACE_PROBE2(zfs__probe_name, uint64_t, blkid, dnode_t *, dn);
* Then you can use it as follows:
* zfs$target:::probe2 /copyinstr(arg0) == "zfs__probe_name"/
* {printf("%u %p\n", arg1, arg2);}
*/
#ifdef DTRACE_PROBE

View File

@ -34,7 +34,7 @@ COMPILER_RT_ABI fp_t __floatditf(di_int a) {
}
// Exponent of (fp_t)a is the width of abs(a).
const int exponent = (aWidth - 1) - __builtin_clz(a);
const int exponent = (aWidth - 1) - __builtin_clzll(a);
rep_t result;
// Shift a into the significand field and clear the implicit bit. Extra

View File

@ -25,7 +25,7 @@ COMPILER_RT_ABI fp_t __floatunditf(du_int a) {
if (a == 0) return fromRep(0);
// Exponent of (fp_t)a is the width of abs(a).
const int exponent = (aWidth - 1) - __builtin_clz(a);
const int exponent = (aWidth - 1) - __builtin_clzll(a);
rep_t result;
// Shift a into the significand field and clear the implicit bit.

View File

@ -567,7 +567,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
SSIZE_MAX to be much smaller than the actual range of the
type. Use INTTYPE_MAXIMUM unconditionally to ensure this
does not bite us. */
if (file->st.st_size > INTTYPE_MAXIMUM (ssize_t))
if (file->st.st_size > SSIZE_MAX)
{
cpp_error (pfile, CPP_DL_ERROR, "%s is too large", file->path);
return false;
@ -581,7 +581,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
file->path);
return false;
}
else if (offset > INTTYPE_MAXIMUM (ssize_t) || (ssize_t)offset > size)
else if (offset > SSIZE_MAX || (ssize_t)offset > size)
{
cpp_error (pfile, CPP_DL_ERROR, "current position of %s is too large",
file->path);

View File

@ -538,7 +538,7 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920
# From Alex Krivenyshev (2008-07-11):
# Seems that English language article "The revival of daylight saving
# time: Energy conservation?"-# No. 16578 (07/11/2008) was originally
# time: Energy conservation?"- No. 16578 (07/11/2008) was originally
# published on Monday, June 30, 2008...
#
# I guess that article in French "Le gouvernement avance l'introduction
@ -670,7 +670,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis
# Here is a link to official document from Royaume du Maroc Premier Ministre,
# Ministère de la Modernisation des Secteurs Publics
#
# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 june 1967)
# Under Article 1 of Royal Decree No. 455-67 of Act 23 safar 1387 (2 June 1967)
# concerning the amendment of the legal time, the Ministry of Modernization of
# Public Sectors announced that the official time in the Kingdom will be
# advanced 60 minutes from Sunday 31 May 2009 at midnight.

View File

@ -6,7 +6,7 @@
# tz@iana.org for general use in the future). For more, please see
# the file CONTRIBUTING in the tz distribution.
# From Paul Eggert (2014-10-31):
# From Paul Eggert (2015-08-08):
#
# Unless otherwise specified, the source for data through 1990 is:
# Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition),
@ -43,7 +43,7 @@
# 2:00 EET EEST Eastern European Time
# 2:00 IST IDT Israel
# 3:00 AST ADT Arabia*
# 3:30 IRST IRDT Iran
# 3:30 IRST IRDT Iran*
# 4:00 GST Gulf*
# 5:30 IST India
# 7:00 ICT Indochina, most times and locations*
@ -52,10 +52,11 @@
# 8:00 CST China
# 8:00 IDT Indochina, 1943-45, 1947-55, 1960-75 (some locations)*
# 8:00 JWST Western Standard Time (Japan, 1896/1937)*
# 8:30 KST KDT Korea when at +0830*
# 9:00 JCST Central Standard Time (Japan, 1896/1937)
# 9:00 WIT east Indonesia (Waktu Indonesia Timur)
# 9:00 JST JDT Japan
# 9:00 KST KDT Korea
# 9:00 KST KDT Korea when at +09
# 9:30 ACST Australian Central Standard Time
#
# See the 'europe' file for Russia and Turkey in Asia.
@ -1027,7 +1028,7 @@ Zone Asia/Jayapura 9:22:48 - LMT 1932 Nov
#
# From Roozbeh Pournader (2007-11-05):
# This is quoted from Official Gazette of the Islamic Republic of
# Iran, Volume 63, Number 18242, dated Tuesday 1386/6/24
# Iran, Volume 63, No. 18242, dated Tuesday 1386/6/24
# [2007-10-16]. I am doing the best translation I can:...
# The official time of the country will be moved forward for one hour
# on the 24 hours of the first day of the month of Farvardin and will
@ -1557,7 +1558,7 @@ Zone Asia/Amman 2:23:44 - LMT 1931
# - Qyzylorda switched from +5:00 to +6:00 on 1992-01-19 02:00.
# - Oral switched from +5:00 to +4:00 in spring 1989.
# From Kazakhstan Embassy's News Bulletin #11
# From Kazakhstan Embassy's News Bulletin No. 11
# <http://www.kazsociety.org.uk/news/2005/03/30.htm> (2005-03-21):
# The Government of Kazakhstan passed a resolution March 15 abolishing
# daylight saving time citing lack of economic benefits and health
@ -1711,6 +1712,17 @@ Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S
#
# For Pyongyang we have no information; guess no changes since World War II.
# From Steffen Thorsen (2015-08-07):
# According to many news sources, North Korea is going to change to
# the 8:30 time zone on August 15, one example:
# http://www.bbc.com/news/world-asia-33815049
#
# From Paul Eggert (2015-08-07):
# No transition time is specified; assume 00:00.
# There is no common English-language abbreviation for this time zone.
# Use %z rather than invent one. We can't assume %z works everywhere yet,
# so for now substitute its output manually.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Seoul 8:27:52 - LMT 1908 Apr 1
8:30 - KST 1912 Jan 1
@ -1723,7 +1735,8 @@ Zone Asia/Pyongyang 8:23:00 - LMT 1908 Apr 1
8:30 - KST 1912 Jan 1
9:00 - JCST 1937 Oct 1
9:00 - JST 1945 Aug 24
9:00 - KST
9:00 - KST 2015 Aug 15
8:30 - KST
###############################################################################

View File

@ -193,11 +193,14 @@
# republished in Finest Hour (Spring 2002) 1(114):26
# http://www.winstonchurchill.org/images/finesthour/Vol.01%20No.114.pdf
# From Paul Eggert (1996-09-03):
# From Paul Eggert (2015-08-08):
# The OED Supplement says that the English originally said "Daylight Saving"
# when they were debating the adoption of DST in 1908; but by 1916 this
# term appears only in quotes taken from DST's opponents, whereas the
# proponents (who eventually won the argument) are quoted as using "Summer".
# The term "Summer Time" was introduced by Herbert Samuel, Home Secretary; see:
# Viscount Samuel. Leisure in a Democracy. Cambridge University Press
# ISBN 978-1-107-49471-8 (1949, reissued 2015), p 8.
# From Arthur David Olson (1989-01-19):
# A source at the British Information Office in New York avers that it's
@ -343,7 +346,7 @@
# From an anonymous contributor (1996-06-02):
# The law governing time in Ireland is under Statutory Instrument SI 395/94,
# which gives force to European Union 7th Council Directive # 94/21/EC.
# which gives force to European Union 7th Council Directive No. 94/21/EC.
# Under this directive, the Minister for Justice in Ireland makes appropriate
# regulations. I spoke this morning with the Secretary of the Department of
# Justice (tel +353 1 678 9711) who confirmed to me that the correct name is
@ -592,11 +595,11 @@ Rule Russia 1921 only - Feb 14 23:00 1:00 MSD
Rule Russia 1921 only - Mar 20 23:00 2:00 MSM # Midsummer
Rule Russia 1921 only - Sep 1 0:00 1:00 MSD
Rule Russia 1921 only - Oct 1 0:00 0 -
# Act No.925 of the Council of Ministers of the USSR (1980-10-24):
# Act No. 925 of the Council of Ministers of the USSR (1980-10-24):
Rule Russia 1981 1984 - Apr 1 0:00 1:00 S
Rule Russia 1981 1983 - Oct 1 0:00 0 -
# Act No.967 of the Council of Ministers of the USSR (1984-09-13), repeated in
# Act No.227 of the Council of Ministers of the USSR (1989-03-14):
# Act No. 967 of the Council of Ministers of the USSR (1984-09-13), repeated in
# Act No. 227 of the Council of Ministers of the USSR (1989-03-14):
Rule Russia 1984 1991 - Sep lastSun 2:00s 0 -
Rule Russia 1985 1991 - Mar lastSun 2:00s 1:00 S
#
@ -828,7 +831,7 @@ Zone Europe/Brussels 0:17:30 - LMT 1880
# Bulgaria
#
# From Plamen Simenov via Steffen Thorsen (1999-09-09):
# A document of Government of Bulgaria (No.94/1997) says:
# A document of Government of Bulgaria (No. 94/1997) says:
# EET -> EETDST is in 03:00 Local time in last Sunday of March ...
# EETDST -> EET is in 04:00 Local time in last Sunday of October
#
@ -845,7 +848,7 @@ Zone Europe/Sofia 1:33:16 - LMT 1880
1:00 C-Eur CE%sT 1945
1:00 - CET 1945 Apr 2 3:00
2:00 - EET 1979 Mar 31 23:00
2:00 Bulg EE%sT 1982 Sep 26 2:00
2:00 Bulg EE%sT 1982 Sep 26 3:00
2:00 C-Eur EE%sT 1991
2:00 E-Eur EE%sT 1997
2:00 EU EE%sT
@ -1062,8 +1065,8 @@ Zone America/Thule -4:35:08 - LMT 1916 Jul 28 # Pituffik air base
# after that.
# From Mart Oruaas (2000-01-29):
# Regulation no. 301 (1999-10-12) obsoletes previous regulation
# no. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
# Regulation No. 301 (1999-10-12) obsoletes previous regulation
# No. 206 (1998-09-22) and thus sticks Estonia to +02:00 GMT for all
# the year round. The regulation is effective 1999-11-01.
# From Toomas Soome (2002-02-21):
@ -1084,7 +1087,7 @@ Zone Europe/Tallinn 1:39:00 - LMT 1880
3:00 Russia MSK/MSD 1989 Mar 26 2:00s
2:00 1:00 EEST 1989 Sep 24 2:00s
2:00 C-Eur EE%sT 1998 Sep 22
2:00 EU EE%sT 1999 Nov 1
2:00 EU EE%sT 1999 Oct 31 4:00
2:00 - EET 2002 Feb 21
2:00 EU EE%sT
@ -1527,21 +1530,21 @@ Link Europe/Rome Europe/San_Marino
# correct data in juridical acts and I found some juridical documents about
# changes in the counting of time in Latvia from 1981....
#
# Act No.35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
# according to the Act No.925 of the Council of Ministers of USSR of 1980-10-24
# Act No. 35 of the Council of Ministers of Latvian SSR of 1981-01-22 ...
# according to the Act No. 925 of the Council of Ministers of USSR of 1980-10-24
# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
# the hands of the clock 1 hour forward on 1 April at 00:00 (GMT 31 March 21:00)
# and 1 hour backward on the 1 October at 00:00 (GMT 30 September 20:00).
#
# Act No.592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
# according to the Act No.967 of the Council of Ministers of USSR of 1984-09-13
# Act No. 592 of the Council of Ministers of Latvian SSR of 1984-09-24 ...
# according to the Act No. 967 of the Council of Ministers of USSR of 1984-09-13
# ...: all year round the time of 2nd time zone + 1 hour, in addition turning
# the hands of the clock 1 hour forward on the last Sunday of March at 02:00
# (GMT 23:00 on the previous day) and 1 hour backward on the last Sunday of
# September at 03:00 (GMT 23:00 on the previous day).
#
# Act No.81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
# according to the Act No.227 of the Council of Ministers of USSR of 1989-03-14
# Act No. 81 of the Council of Ministers of Latvian SSR of 1989-03-22 ...
# according to the Act No. 227 of the Council of Ministers of USSR of 1989-03-14
# ...: since the last Sunday of March 1989 in Lithuanian SSR, Latvian SSR,
# Estonian SSR and Kaliningrad region of Russian Federation all year round the
# time of 2nd time zone (Moscow time minus one hour). On the territory of Latvia
@ -1558,7 +1561,7 @@ Link Europe/Rome Europe/San_Marino
# From Andrei Ivanov (2000-03-06):
# This year Latvia will not switch to Daylight Savings Time (as specified in
# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
# 29-Feb-2000 (#79) <http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm>,
# 29-Feb-2000 (No. 79) <http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm>,
# in Latvian for subscribers only).
# From RFE/RL Newsline
@ -1763,6 +1766,18 @@ Zone Europe/Malta 0:58:04 - LMT 1893 Nov 2 0:00s # Valletta
# News from Moldova (in russian):
# http://ru.publika.md/link_317061.html
# From Roman Tudos (2015-07-02):
# http://lex.justice.md/index.php?action=view&view=doc&lang=1&id=355077
# From Paul Eggert (2015-07-01):
# The abovementioned official link to IGO1445-868/2014 states that
# 2014-10-26's fallback transition occurred at 03:00 local time. Also,
# http://www.trm.md/en/social/la-30-martie-vom-trece-la-ora-de-vara
# says the 2014-03-30 spring-forward transition was at 02:00 local time.
# Guess that since 1997 Moldova has switched one hour before the EU.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Moldova 1997 max - Mar lastSun 2:00 1:00 S
Rule Moldova 1997 max - Oct lastSun 3:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Chisinau 1:55:20 - LMT 1880
@ -1777,7 +1792,7 @@ Zone Europe/Chisinau 1:55:20 - LMT 1880
2:00 Russia EE%sT 1992
2:00 E-Eur EE%sT 1997
# See Romania commentary for the guessed 1997 transition to EU rules.
2:00 EU EE%sT
2:00 Moldova EE%sT
# Monaco
# Shanks & Pottenger give 0:09:20 for Paris Mean Time; go with Howse's
@ -2123,7 +2138,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
# Russia
# From Alexander Krivenyshev (2011-09-15):
# Based on last Russian Government Decree # 725 on August 31, 2011
# Based on last Russian Government Decree No. 725 on August 31, 2011
# (Government document
# http://www.government.ru/gov/results/16355/print/
# in Russian)
@ -2133,7 +2148,7 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
# http://www.worldtimezone.com/dst_news/dst_news_russia36.htm
# From Sanjeev Gupta (2011-09-27):
# Scans of [Decree #23 of January 8, 1992] are available at:
# Scans of [Decree No. 23 of January 8, 1992] are available at:
# http://government.consultant.ru/page.aspx?1223966
# They are in Cyrillic letters (presumably Russian).
@ -2144,19 +2159,19 @@ Zone Europe/Bucharest 1:44:24 - LMT 1891 Oct
# One source is
# http://government.ru/gov/results/16355/
# which, according to translate.google.com, begins "Decree of August 31,
# 2011 No 725" and contains no other dates or "effective date" information.
# 2011 No. 725" and contains no other dates or "effective date" information.
#
# Another source is
# http://www.rg.ru/2011/09/06/chas-zona-dok.html
# which, according to translate.google.com, begins "Resolution of the
# Government of the Russian Federation on August 31, 2011 N 725" and also
# contains "Date first official publication: September 6, 2011 Posted on:
# in the 'RG' - Federal Issue number 5573 September 6, 2011" but which
# in the 'RG' - Federal Issue No. 5573 September 6, 2011" but which
# does not contain any "effective date" information.
#
# Another source is
# http://en.wikipedia.org/wiki/Oymyakonsky_District#cite_note-RuTime-7
# which, in note 8, contains "Resolution #725 of August 31, 2011...
# which, in note 8, contains "Resolution No. 725 of August 31, 2011...
# Effective as of after 7 days following the day of the official publication"
# but which does not contain any reference to September 6, 2011.
#
@ -2364,7 +2379,7 @@ Zone Europe/Simferopol 2:16:24 - LMT 1880
# changed in May.
2:00 E-Eur EE%sT 1994 May
# From IATA SSIM (1994/1997), which also says that Kerch is still like Kiev.
3:00 E-Eur MSK/MSD 1996 Mar 31 3:00s
3:00 E-Eur MSK/MSD 1996 Mar 31 0:00s
3:00 1:00 MSD 1996 Oct 27 3:00s
# IATA SSIM (1997-09) says Crimea switched to EET/EEST.
# Assume it happened in March by not changing the clocks.
@ -2499,7 +2514,7 @@ Zone Asia/Novosibirsk 5:31:40 - LMT 1919 Dec 14 6:00
# from current Russia Zone 6 - Krasnoyarsk Time Zone (KRA) UTC +0700
# to Russia Zone 5 - Novosibirsk Time Zone (NOV) UTC +0600
#
# This is according to Government of Russia decree # 740, on September
# This is according to Government of Russia decree No. 740, on September
# 14, 2009 "Application in the territory of the Kemerovo region the Fifth
# time zone." ("Russia Zone 5" or old "USSR Zone 5" is GMT +0600)
#
@ -2922,7 +2937,7 @@ Zone Africa/Ceuta -0:21:16 - LMT 1901
Zone Atlantic/Canary -1:01:36 - LMT 1922 Mar # Las Palmas de Gran C.
-1:00 - CANT 1946 Sep 30 1:00 # Canaries T
0:00 - WET 1980 Apr 6 0:00s
0:00 1:00 WEST 1980 Sep 28 0:00s
0:00 1:00 WEST 1980 Sep 28 1:00u
0:00 EU WE%sT
# IATA SSIM (1996-09) says the Canaries switch at 2:00u, not 1:00u.
# Ignore this for now, as the Canaries are part of the EU.
@ -3212,7 +3227,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# From Igor Karpov, who works for the Ukrainian Ministry of Justice,
# via Garrett Wollman (2003-01-27):
# BTW, I've found the official document on this matter. It's government
# regulations number 509, May 13, 1996. In my poor translation it says:
# regulations No. 509, May 13, 1996. In my poor translation it says:
# "Time in Ukraine is set to second timezone (Kiev time). Each last Sunday
# of March at 3am the time is changing to 4am and each last Sunday of
# October the time at 4am is changing to 3am"
@ -3221,7 +3236,7 @@ Link Europe/Istanbul Asia/Istanbul # Istanbul is in both continents.
# On September 20, 2011 the deputies of the Verkhovna Rada agreed to
# abolish the transfer clock to winter time.
#
# Bill number 8330 of MP from the Party of Regions Oleg Nadoshi got
# Bill No. 8330 of MP from the Party of Regions Oleg Nadoshi got
# approval from 266 deputies.
#
# Ukraine abolishes transfer back to the winter time (in Russian)

View File

@ -199,10 +199,10 @@
# current -- the update time stamp, the data and the name of the file
# will not change.
#
# Updated through IERS Bulletin C49
# File expires on: 28 December 2015
# Updated through IERS Bulletin C50
# File expires on: 28 June 2016
#
#@ 3660249600
#@ 3676060800
#
2272060800 10 # 1 Jan 1972
2287785600 11 # 1 Jul 1972
@ -246,4 +246,4 @@
# the hash line is also ignored in the
# computation.
#
#h 45e70fa7 a9df2033 f4a49ab0 ec648273 7b6c22c
#h 3d037453 3acade76 570bd8f8 be2b8bc9 55ec6fe8

View File

@ -1235,10 +1235,19 @@ Zone America/Goose_Bay -4:01:40 - LMT 1884 # Happy Valley-Goose Bay
# west Labrador, Nova Scotia, Prince Edward I
# From Paul Eggert (2006-03-22):
# From Brian Inglis (2015-07-20):
# From the historical weather station records available at:
# https://weatherspark.com/history/28351/1971/Sydney-Nova-Scotia-Canada
# Sydney shares the same time history as Glace Bay, so was
# likely to be the same across the island....
# Sydney, as the capital and most populous location, or Cape Breton, would
# have been better names for the zone had we known this in 1996.
# From Paul Eggert (2015-07-20):
# Shanks & Pottenger write that since 1970 most of this region has been like
# Halifax. Many locales did not observe peacetime DST until 1972;
# Glace Bay, NS is the largest that we know of.
# the Cape Breton area, represented by Glace Bay, is the largest we know of
# (Glace Bay was perhaps not the best name choice but no point changing now).
# Shanks & Pottenger also write that Liverpool, NS was the only town
# in Canada to observe DST in 1971 but not 1970; for now we'll assume
# this is a typo.
@ -1796,13 +1805,13 @@ Zone America/Edmonton -7:33:52 - LMT 1906 Sep
# Exact date in October unknown; Sunday October 1 is a reasonable guess.
# 3. June 1918: switch to Pacific Daylight Time (GMT-7)
# Exact date in June unknown; Sunday June 2 is a reasonable guess.
# note#1:
# note 1:
# On Oct 27/1918 when daylight saving ended in the rest of Canada,
# Creston did not change its clocks.
# note#2:
# note 2:
# During WWII when the Federal Government legislated a mandatory clock change,
# Creston did not oblige.
# note#3:
# note 3:
# There is no guarantee that Creston will remain on Mountain Standard Time
# (UTC-7) forever.
# The subject was debated at least once this year by the town Council.

View File

@ -131,7 +131,7 @@ Rule Arg 2000 only - Mar 3 0:00 0 -
# Timezone Law (which never was effectively applied) will (would?) be
# in effect.... The article is at
# http://ar.clarin.com/diario/2001-06-06/e-01701.htm
# ... The Law itself is "Ley No 25155", sanctioned on 1999-08-25, enacted
# ... The Law itself is "Ley No. 25155", sanctioned on 1999-08-25, enacted
# 1999-09-17, and published 1999-09-21. The official publication is at:
# http://www.boletin.jus.gov.ar/BON/Primera/1999/09-Septiembre/21/PDF/BO21-09-99LEG.PDF
# Regretfully, you have to subscribe (and pay) for the on-line version....
@ -175,15 +175,11 @@ Rule Arg 2000 only - Mar 3 0:00 0 -
# http://www.worldtimezone.com/dst_news/dst_news_argentina03.html
# http://www.impulsobaires.com.ar/nota.php?id=57832 (in spanish)
# From Rodrigo Severo (2008-10-06):
# Here is some info available at a Gentoo bug related to TZ on Argentina's DST:
# ...
# ------- Comment #1 from [jmdocile] 2008-10-06 16:28 0000 -------
# Hi, there is a problem with timezone-data-2008e and maybe with
# timezone-data-2008f
# Argentinian law [Number] 25.155 is no longer valid.
# From Juan Manuel Docile in https://bugs.gentoo.org/240339 (2008-10-07)
# via Rodrigo Severo:
# Argentinian law No. 25.155 is no longer valid.
# http://www.infoleg.gov.ar/infolegInternet/anexos/60000-64999/60036/norma.htm
# The new one is law [Number] 26.350
# The new one is law No. 26.350
# http://www.infoleg.gov.ar/infolegInternet/anexos/135000-139999/136191/norma.htm
# So there is no summer time in Argentina for now.
@ -771,7 +767,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890
# [ and in a second message (same day): ]
# I found the decree.
#
# DECRETO No- 7.584, DE 13 DE OUTUBRO DE 2011
# DECRETO No. 7.584, DE 13 DE OUTUBRO DE 2011
# Link :
# http://www.in.gov.br/visualiza/index.jsp?data=13/10/2011&jornal=1000&pagina=6&totalArquivos=6
@ -1125,7 +1121,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# Conflicts between [1] and [2] were resolved as follows:
#
# - [1] says the 1910 transition was Jan 1, [2] says Jan 10 and cites
# Boletín Nº 1, Aviso Nº 1 (1910). Go with [2].
# Boletín No. 1, Aviso No. 1 (1910). Go with [2].
#
# - [1] says SMT was -4:42:45, [2] says Chile's official time from
# 1916 to 1919 was -4:42:46.3, the meridian of Chile's National
@ -1133,7 +1129,7 @@ Zone America/Rio_Branco -4:31:12 - LMT 1914
# Quinta Normal in Santiago. Go with [2], rounding it to -4:42:46.
#
# - [1] says the 1918 transition was Sep 1, [2] says Sep 10 and cites
# Boletín Nº 22, Aviso Nº 129/1918 (1918-08-23). Go with [2].
# Boletín No. 22, Aviso No. 129/1918 (1918-08-23). Go with [2].
#
# - [1] does not give times for transitions; assume they occur
# at midnight mainland time, the current common practice. However,
@ -1533,7 +1529,7 @@ Rule Para 1997 only - Feb lastSun 0:00 0 -
# (1999-09) reports no date; go with above sources and Gerd Knops (2001-02-27).
Rule Para 1998 2001 - Mar Sun>=1 0:00 0 -
# From Rives McDow (2002-02-28):
# A decree was issued in Paraguay (no. 16350) on 2002-02-26 that changed the
# A decree was issued in Paraguay (No. 16350) on 2002-02-26 that changed the
# dst method to be from the first Sunday in September to the first Sunday in
# April.
Rule Para 2002 2004 - Apr Sun>=1 0:00 0 -
@ -1713,8 +1709,19 @@ Rule Uruguay 2005 only - Oct 9 2:00 1:00 S
Rule Uruguay 2006 only - Mar 12 2:00 0 -
# From Jesper Nørgaard Welen (2006-09-06):
# http://www.presidencia.gub.uy/_web/decretos/2006/09/CM%20210_08%2006%202006_00001.PDF
Rule Uruguay 2006 max - Oct Sun>=1 2:00 1:00 S
Rule Uruguay 2007 max - Mar Sun>=8 2:00 0 -
#
# From Steffen Thorsen (2015-06-30):
# ... it looks like they will not be using DST the coming summer:
# http://www.elobservador.com.uy/gobierno-resolvio-que-no-habra-cambio-horario-verano-n656787
# http://www.republica.com.uy/este-ano-no-se-modificara-el-huso-horario-en-uruguay/523760/
# From Paul Eggert (2015-06-30):
# Apparently restaurateurs complained that DST caused people to go to the beach
# instead of out to dinner.
# From Pablo Camargo (2015-07-13):
# http://archivo.presidencia.gub.uy/sci/decretos/2015/06/cons_min_201.pdf
# [dated 2015-06-29; repeals Decree 311/006 dated 2006-09-04]
Rule Uruguay 2006 2014 - Oct Sun>=1 2:00 1:00 S
Rule Uruguay 2007 2015 - Mar Sun>=8 2:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28
-3:44:44 - MMT 1920 May 1 # Montevideo MT
@ -1723,6 +1730,10 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28
# Venezuela
#
# From Paul Eggert (2015-07-28):
# For the 1965 transition see Gaceta Oficial No. 27.619 (1964-12-15), p 205.533
# http://www.pgr.gob.ve/dmdocuments/1964/27619.pdf
#
# From John Stainforth (2007-11-28):
# ... the change for Venezuela originally expected for 2007-12-31 has
# been brought forward to 2007-12-09. The official announcement was
@ -1734,6 +1745,6 @@ Zone America/Montevideo -3:44:44 - LMT 1898 Jun 28
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone America/Caracas -4:27:44 - LMT 1890
-4:27:40 - CMT 1912 Feb 12 # Caracas Mean Time?
-4:30 - VET 1965 # Venezuela Time
-4:30 - VET 1965 Jan 1 0:00 # Venezuela T.
-4:00 - VET 2007 Dec 9 3:00
-4:30 - VET

View File

@ -106,8 +106,8 @@ BW -2439+02555 Africa/Gaborone
BY +5354+02734 Europe/Minsk
BZ +1730-08812 America/Belize
CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador
CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (most places), PEI
CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (peninsula), PEI
CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia (Cape Breton)
CA +4606-06447 America/Moncton Atlantic Time - New Brunswick
CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations
CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore

View File

@ -104,8 +104,8 @@ BT +2728+08939 Asia/Thimphu
BY +5354+02734 Europe/Minsk
BZ +1730-08812 America/Belize
CA +4734-05243 America/St_Johns Newfoundland Time, including SE Labrador
CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (most places), PEI
CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia - places that did not observe DST 1966-1971
CA +4439-06336 America/Halifax Atlantic Time - Nova Scotia (peninsula), PEI
CA +4612-05957 America/Glace_Bay Atlantic Time - Nova Scotia (Cape Breton)
CA +4606-06447 America/Moncton Atlantic Time - New Brunswick
CA +5320-06025 America/Goose_Bay Atlantic Time - Labrador - most locations
CA +5125-05707 America/Blanc-Sablon Atlantic Standard Time - Quebec - Lower North Shore

View File

@ -12,7 +12,7 @@ SUBDIR= doc\
${_objcopy} \
objdump \
.if ${MK_ELFTOOLCHAIN_TOOLS} == "no" || ${MK_ELFCOPY_AS_OBJCOPY} == "no"
.if ${MK_ELFCOPY_AS_OBJCOPY} == "no"
_objcopy= objcopy
.endif

View File

@ -182,7 +182,7 @@ _clang= clang
_cuse= libcuse
.endif
.if ${MK_ELFTOOLCHAIN_TOOLS} != "no"
.if ${MK_TOOLCHAIN} != "no"
_libelftc= libelftc
.endif

View File

@ -95,6 +95,7 @@ NOASM=
.include "${LIBC_SRCTOP}/stdtime/Makefile.inc"
.include "${LIBC_SRCTOP}/string/Makefile.inc"
.include "${LIBC_SRCTOP}/sys/Makefile.inc"
.include "${LIBC_SRCTOP}/secure/Makefile.inc"
.include "${LIBC_SRCTOP}/rpc/Makefile.inc"
.include "${LIBC_SRCTOP}/uuid/Makefile.inc"
.include "${LIBC_SRCTOP}/xdr/Makefile.inc"

View File

@ -138,8 +138,7 @@ we_askshell(const char *words, wordexp_t *we, int flags)
}
else if (pid == 0) {
/*
* We are the child; just get /bin/sh to run the wordexp
* builtin on `words'.
* We are the child; make /bin/sh expand `words'.
*/
(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
if ((pdes[1] != STDOUT_FILENO ?
@ -147,7 +146,9 @@ we_askshell(const char *words, wordexp_t *we, int flags)
_fcntl(pdes[1], F_SETFD, 0)) < 0)
_exit(1);
execl(_PATH_BSHELL, "sh", flags & WRDE_UNDEF ? "-u" : "+u",
"-c", "IFS=$1;eval \"$2\";eval \"wordexp $3\"", "",
"-c", "IFS=$1;eval \"$2\";eval \"set -- $3\";IFS=;a=\"$*\";"
"printf '%08x' \"$#\" \"${#a}\";printf '%s\\0' \"$@\"",
"",
ifs != NULL ? ifs : " \t\n",
flags & WRDE_SHOWERR ? "" : "exec 2>/dev/null", words,
(char *)NULL);

View File

@ -0,0 +1,12 @@
# $FreeBSD$
#
# libc sources related to security
.PATH: ${LIBC_SRCTOP}/secure
# Sources common to both syscall interfaces:
SRCS+= \
stack_protector.c \
stack_protector_compat.c
SYM_MAPS+= ${LIBC_SRCTOP}/secure/Symbol.map

View File

@ -0,0 +1,9 @@
/*
* $FreeBSD$
*/
FBSD_1.0 {
__chk_fail;
__stack_chk_fail;
__stack_chk_guard;
};

View File

@ -31,7 +31,7 @@
.\" @(#)bcopy.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd August 11, 2015
.Dd August 14, 2015
.Dt BCOPY 3
.Os
.Sh NAME
@ -57,20 +57,6 @@ The two strings may overlap.
If
.Fa len
is zero, no bytes are copied.
.Pp
This function is deprecated (marked as LEGACY in
POSIX.1-2001): use
.Xr memcpy 3
or
.Xr memmove 3
in new programs.
Note that the first two arguments are
interchanged for
.Xr memcpy 3
and
.Xr memmove 3 .
POSIX.1-2008 removes the specification of
.Fn bcopy .
.Sh SEE ALSO
.Xr memccpy 3 ,
.Xr memcpy 3 ,
@ -89,3 +75,25 @@ before it was moved to
for
.St -p1003.1-2001
compliance.
.Pp
The
.St -p1003.1-2008
removes the specification of
.Fn bcopy
and it is marked as LEGACY in
.St -p1003.1-2004 .
New programs should use
.Xr memmove 3 .
If the input and output buffer do not overlap, then
.Xr memcpy 3
is more efficient.
Note that
.Fn bcopy
takes
.Ar src
and
.Ar dst
in the opposite order from
.Fn memmove
and
.Fn memcpy .

View File

@ -21,8 +21,6 @@ PSEUDO+= _clock_gettime.o _gettimeofday.o
# Sources common to both syscall interfaces:
SRCS+= \
stack_protector.c \
stack_protector_compat.c \
__error.c \
interposing_table.c

View File

@ -3,8 +3,8 @@
*/
/*
* It'd be nice to have this automatically generated, but we don't
* know to what version they will eventually belong, so for now
* It'd be nice to automatically generate the syscall symbols, but we
* don't know to what version they will eventually belong to, so for now
* it has to be manual.
*/
FBSD_1.0 {
@ -56,7 +56,6 @@ FBSD_1.0 {
bind;
chdir;
chflags;
__chk_fail;
chmod;
chown;
chroot;
@ -281,8 +280,6 @@ FBSD_1.0 {
sigwaitinfo;
socket;
socketpair;
__stack_chk_fail;
__stack_chk_guard;
stat;
statfs;
swapoff;

View File

@ -286,7 +286,7 @@ EndElement(void *userData, const char *name)
"element", name);
return;
}
gc->lg_val = p ? p : strdup("1");
gc->lg_val = p;
LIST_INSERT_HEAD(c, gc, lg_config);
return;
}

View File

@ -4,6 +4,7 @@ TESTSDIR= ${TESTSBASE}/lib/libnv
ATF_TESTS_CXX= \
dnv_tests \
nv_array_tests \
nv_tests \
TAP_TESTS_C+= nvlist_add_test

File diff suppressed because it is too large Load Diff

View File

@ -70,8 +70,6 @@ CFLAGS+= -DUSB_GLOBAL_INCLUDE_FILE=\"${LIBUSB_GLOBAL_INCLUDE_FILE}\"
CFLAGS+= -I ../../sys
.endif
.include <bsd.lib.mk>
# LibUSB v1.0
MLINKS += libusb.3 libusb_init.3
MLINKS += libusb.3 libusb_exit.3
@ -259,3 +257,5 @@ MLINKS += libusb20.3 libusb20_me_decode.3
MLINKS += libusb20.3 libusb20_desc_foreach.3
MLINKS += libusb20.3 libusb20_strerror.3
MLINKS += libusb20.3 libusb20_error_name.3
.include <bsd.lib.mk>

View File

@ -28,7 +28,7 @@
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $FreeBSD$
.\"
.Dd May 15, 2015
.Dd Aug 12, 2015
.Dt IFCONFIG 8
.Os
.Sh NAME
@ -2396,6 +2396,10 @@ Disable local hash computation for RSS hash on the interface.
Set a shift parameter for RSS local hash computation.
Hash is calculated by using flowid bits in a packet header mbuf
which are shifted by the number of this parameter.
.It Cm lacp_fast_timeout
Enable lacp fast-timeout on the interface.
.It Cm -lacp_fast_timeout
Disable lacp fast-timeout on the interface.
.El
.Pp
The following parameters are specific to IP tunnel interfaces,

View File

@ -115,6 +115,8 @@ setlaggsetopt(const char *val, int d, int s, const struct afswtch *afp)
case -LAGG_OPT_LACP_TXTEST:
case LAGG_OPT_LACP_RXTEST:
case -LAGG_OPT_LACP_RXTEST:
case LAGG_OPT_LACP_TIMEOUT:
case -LAGG_OPT_LACP_TIMEOUT:
break;
default:
err(1, "Invalid lagg option");
@ -293,6 +295,8 @@ static struct cmd lagg_cmds[] = {
DEF_CMD("-lacp_txtest", -LAGG_OPT_LACP_TXTEST, setlaggsetopt),
DEF_CMD("lacp_rxtest", LAGG_OPT_LACP_RXTEST, setlaggsetopt),
DEF_CMD("-lacp_rxtest", -LAGG_OPT_LACP_RXTEST, setlaggsetopt),
DEF_CMD("lacp_fast_timeout", LAGG_OPT_LACP_TIMEOUT, setlaggsetopt),
DEF_CMD("-lacp_fast_timeout", -LAGG_OPT_LACP_TIMEOUT, setlaggsetopt),
DEF_CMD_ARG("flowid_shift", setlaggflowidshift),
};
static struct afswtch af_lagg = {

View File

@ -2869,14 +2869,14 @@ fill_ip(ipfw_insn_ip *cmd, char *av, int cblen, struct tidx *tstate)
case '/':
masklen = atoi(p);
if (masklen == 0)
d[1] = htonl(0); /* mask */
d[1] = htonl(0U); /* mask */
else if (masklen > 32)
errx(EX_DATAERR, "bad width ``%s''", p);
else
d[1] = htonl(~0 << (32 - masklen));
d[1] = htonl(~0U << (32 - masklen));
break;
case '{': /* no mask, assume /24 and put back the '{' */
d[1] = htonl(~0 << (32 - 24));
d[1] = htonl(~0U << (32 - 24));
*(--p) = md;
break;
@ -2885,7 +2885,7 @@ fill_ip(ipfw_insn_ip *cmd, char *av, int cblen, struct tidx *tstate)
/* FALLTHROUGH */
case 0: /* initialization value */
default:
d[1] = htonl(~0); /* force /32 */
d[1] = htonl(~0U); /* force /32 */
break;
}
d[0] &= d[1]; /* mask base address with mask */

View File

@ -3,8 +3,7 @@
PROG= ping6
MAN= ping6.8
CFLAGS+=-DIPSEC -DKAME_SCOPEID -DUSE_RFC2292BIS \
-DHAVE_ARC4RANDOM
CFLAGS+=-DIPSEC -DKAME_SCOPEID -DUSE_RFC2292BIS
WARNS?= 3
BINOWN= root

View File

@ -288,9 +288,6 @@ main(int argc, char *argv[])
{
struct timeval last, intvl;
struct sockaddr_in6 from, *sin6;
#ifndef HAVE_ARC4RANDOM
struct timeval seed;
#endif
struct addrinfo hints, *res;
struct sigaction si_sa;
int cc, i;
@ -751,17 +748,7 @@ main(int argc, char *argv[])
*datap++ = i;
ident = getpid() & 0xFFFF;
#ifndef HAVE_ARC4RANDOM
gettimeofday(&seed, NULL);
srand((unsigned int)(seed.tv_sec ^ seed.tv_usec ^ (long)ident));
memset(nonce, 0, sizeof(nonce));
for (i = 0; i < sizeof(nonce); i += sizeof(int))
*((int *)&nonce[i]) = rand();
#else
memset(nonce, 0, sizeof(nonce));
for (i = 0; i < (int)sizeof(nonce); i += sizeof(u_int32_t))
*((u_int32_t *)&nonce[i]) = arc4random();
#endif
arc4random_buf(nonce, sizeof(nonce));
optval = 1;
if (options & F_DONTFRAG)
if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,

View File

@ -31,7 +31,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd October 11, 2011
.Dd August 16, 2015
.Dt EM 4
.Os
.Sh NAME
@ -205,6 +205,11 @@ Tunables can be set at the
prompt before booting the kernel or stored in
.Xr loader.conf 5 .
.Bl -tag -width indent
.It Va hw.em.disable_crc_stripping
Disable or enable hardware stripping of CRC field.
This is mostly useful on BMC/IPMI shared interfaces where stripping the CRC
causes remote access over IPMI to fail.
Default 0 (enabled).
.It Va hw.em.eee_setting
Disable or enable Energy Efficient Ethernet.
Default 1 (disabled).

View File

@ -0,0 +1,163 @@
.\"
.\" Copyright (c) 2015 Ian Lepore <ian@freebsd.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\"
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd August 12, 2015
.Dt AM335X_DMTPPS 4
.Os
.Sh NAME
.Nm am335x_dmtpps
.Nd RFC 2783 Pulse Per Second API driver for AM335x systems
.Sh SYNOPSIS
.Cd "device am335x_dmtpps"
.Pp
Optional in
.Pa /boot/loader.conf :
.Cd hw.am335x_dmtpps.input="pin name"
.\"
.Sh DESCRIPTION
The
.Nm
device driver provides a system time counter that includes precise
capture of Pulse Per Second (PPS) signals emitted by GPS receivers
and other timing devices.
The
.Nm
driver may be compiled into the kernel or loaded as a module.
.Pp
The AM335x timer hardware captures the value of the system time counter
on the leading edge of the PPS pulse.
Because the capture is done by the hardware there is no interrupt
latency in the measurement.
The time counter runs at 24Mhz, providing a measurement resolution
of 42 nanoseconds.
.Pp
To use the PPS timing information provided by this driver with
.Xr ntpd 8 ,
symlink the
.Pa /dev/dmtpps
device to
.Pa /dev/pps0
and configure server
.Va 127.127.22.0
in
.Xr ntp.conf 5
to configure a type 22 (ATOM) refclock.
.\"
.Sh DRIVER CONFIGURATION
The AM335x hardware provides four timer devices with a capture input
pin, DMTimer4 through DMTimer7.
Because it also provides the active system time counter,
only one instance of the
.Nm
driver can be active at a time.
The driver uses system pin configuration to determine which hardware
timer device to use.
Configure the timer input pin in the system's FDT data, or by
supplying the pin name using a tunable variable in
.Xr loader.conf 5 .
.Pp
To use a standard kernel and FDT data, use
.Xr loader.conf 5
to load the
.Nm
module and set the
.Va hw.am335x_dmtpps.input
tunable variable to the name of the input pin, one of the following:
.Pp
.Bl -tag -width "GPMC_ADVn_ALE MMMM" -offset MMMM -compact
.It Em Name
.Em Hardware
.It P8-7
DMTimer4; Beaglebone P8 header pin 7.
.It P8-8
DMTimer7; Beaglebone P8 header pin 8.
.It P8-9
DMTimer5; Beaglebone P8 header pin 9.
.It P8-10
DMTimer6; Beaglebone P8 header pin 10.
.It GPMC_ADVn_ALE
DMTimer4.
.It GPMC_BEn0_CLE
DMTimer5.
.It GPMC_WEn
DMTimer6.
.It GPMC_OEn_REn
DMTimer7.
.El
.Pp
To configure the
.Nm
driver using FDT data, create a new pinctrl node by referencing the standard
.Va am33xx_pinmux
driver node (which is defined in am33xx.dtsi) in your dts file.
For example:
.Bd -literal
&am33xx_pinmux {
timer4_pins: timer4_pins {
pinctrl-single,pins = <0x90 (PIN_INPUT | MUX_MODE2)>;
};
};
.Ed
.Pp
Add pinctrl properties referencing
.Va timer4_pins
to the standard
.Va timer4
device node (also defined in am33xx.dtsi) by referencing it in
your dts file as follows:
.Bd -literal
&timer4 {
pinctrl-names = "default";
pinctrl-0 = <&timer4_pins>;
};
.Ed
.\"
.Sh FILES
.Bl -tag -width ".Pa /dev/dmtpps" -compact
.It Pa /dev/dmtpps
The device providing
.Xr ioctl 2
access to the RFC 2783 API.
.El
.\"
.Sh SEE ALSO
.Xr timecounters 4 ,
.Xr loader.conf 5 ,
.Xr ntp.conf 5 ,
.Xr ntpd 8
.\"
.Sh HISTORY
The
.Nm
device driver first appeared in
.Fx 11.0 .
.\"
.Sh AUTHORS
The
.Nm
device driver and this manual page were written by
.An Ian Lepore Aq Mt ian@FreeBSD.org .

View File

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 30, 2015
.Dd August 17, 2015
.Dt RANDOM 4
.Os
.Sh NAME
@ -31,6 +31,7 @@
.Nd the entropy device
.Sh SYNOPSIS
.Cd "device random"
.Cd "options RANDOM_LOADABLE"
.Sh DESCRIPTION
The
.Nm
@ -133,15 +134,49 @@ The
.Va kern.random.harvest.mask_bin
and
.Va kern.random.harvest.mask_symbolic
sysctl
can be used confirm
that your choices are correct.
sysctls
can be used to confirm
that the choices are correct.
Note that disabled items
in the latter item
are listed in square brackets.
See
.Xr random_harvest 9
for more on the harvesting of entropy.
.Pp
When
.Cd "options RANDOM_LOADABLE"
is used,
the
.Pa /dev/random
device is not created
until an "algorithm module"
is loaded.
Two of these modules
are built by default,
.Em random_fortuna
and
.Em random_yarrow .
The
.Em random_yarrow
module is deprecated,
and will be removed in
.Fx 12.
Use of the Yarrow algorithm
is not encouraged,
but while still present
in the kernel source,
it can be selected with the
.Cd "options RANDOM_YARROW"
kernel option.
Note that these loadable modules
are slightly less efficient
than their compiled-in equivalents.
This is because some functions
must be locked against
load and unload events,
and also must be indirect calls
to allow for removal.
.Sh RANDOMNESS
The use of randomness in the field of computing
is a rather subtle issue because randomness means
@ -294,7 +329,7 @@ It replaces the previous
implementation,
introduced in
.Fx 5.0 .
The older
.Em Yarrow
algorithm remains available
as a compile-time fallback.
The Yarrow algorithm
is no longer supported
by its authors,
and is therefore deprecated.

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd April 12, 2014
.Dd August 12, 2015
.Dt TIMECOUNTERS 4
.Os
.Sh NAME
@ -96,10 +96,16 @@ compared to others.
A negative value means this time counter is broken and should not be used.
.El
.Pp
The time management code of the kernel chooses one time counter from that list.
The current choice can be read and affected via the
The time management code of the kernel automatically switches to a
higher-quality time counter when it registers, unless the
.Va kern.timecounter.hardware
tunable/sysctl.
sysctl has been used to choose a specific device.
.Pp
There is no way to unregister a time counter once it has registered
with the kernel.
If a dynamically loaded module contains a time counter you will not
be able to unload that module, even if the time counter it contains
is not the one currently in use.
.Sh SEE ALSO
.Xr attimer 4 ,
.Xr eventtimers 4 ,

View File

@ -1,7 +1,7 @@
.\" DO NOT EDIT-- this file is automatically generated.
.\" from FreeBSD: head/tools/build/options/makeman 284708 2015-06-22 20:21:57Z sjg
.\" $FreeBSD$
.Dd August 1, 2015
.Dd August 16, 2015
.Dt SRC.CONF 5
.Os
.Sh NAME
@ -137,9 +137,8 @@ associated utilities, and examples.
.Pp
This option only affects amd64/amd64.
.It Va WITHOUT_BINUTILS
.\" from FreeBSD: head/tools/build/options/WITHOUT_BINUTILS 286036 2015-07-29 20:02:20Z emaste
Set to not build or install binutils (as, c++-filt,
ld, nm, objcopy, objdump, readelf, size and strip) as part
.\" from FreeBSD: head/tools/build/options/WITHOUT_BINUTILS 286332 2015-08-05 18:30:00Z emaste
Set to not build or install binutils (as, ld, objcopy, and objdump ) as part
of the normal system build.
The resulting system cannot build programs from source.
.Pp
@ -457,18 +456,6 @@ instead of the one from GNU Binutils.
.Pp
It is a default setting on
arm64/aarch64.
.It Va WITHOUT_ELFTOOLCHAIN_TOOLS
.\" from FreeBSD: head/tools/build/options/WITHOUT_ELFTOOLCHAIN_TOOLS 286016 2015-07-29 15:42:22Z emaste
Set to use
.Xr addr2line 1 ,
.Xr c++filt 1 ,
.Xr nm 1 ,
.Xr readelf 1 ,
.Xr size 1 ,
.Xr strings 1 ,
and
.Xr strip 1
from GNU binutils instead of the ELF Tool Chain project.
.It Va WITHOUT_EXAMPLES
.\" from FreeBSD: head/tools/build/options/WITHOUT_EXAMPLES 156938 2006-03-21 09:06:24Z ru
Set to avoid installing examples to
@ -1228,11 +1215,6 @@ Set to disable symbol versioning when building shared libraries.
Set to not build
.Xr syscons 4
support files such as keyboard maps, fonts, and screen output maps.
.It Va WITHOUT_SYSINSTALL
.\" from FreeBSD: head/tools/build/options/WITHOUT_SYSINSTALL 183242 2008-09-21 22:02:26Z sam
Set to not build
.Xr sysinstall 8
and related programs.
.It Va WITH_SYSROOT
.\" from FreeBSD: head/tools/build/options/WITH_SYSROOT 284708 2015-06-22 20:21:57Z sjg
Enable use of sysroot during build.

View File

@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd August 9, 2015
.Dd August 14, 2015
.Dt ATOMIC 9
.Os
.Sh NAME
@ -68,7 +68,7 @@
.Fn atomic_testandset_<type> "volatile <type> *p" "u_int v"
.Sh DESCRIPTION
Each of the atomic operations is guaranteed to be atomic across multiple
processors and in the presence of interrupts.
threads and in the presence of interrupts.
They can be used to implement reference counts or as building blocks for more
advanced synchronization primitives such as mutexes.
.Ss Types
@ -108,59 +108,78 @@ unsigned 16-bit integer
.El
.Pp
These must not be used in MI code because the instructions to implement them
efficiently may not be available.
.Ss Memory Barriers
Memory barriers are used to guarantee the order of data accesses in
two ways.
First, they specify hints to the compiler to not re-order or optimize the
operations.
Second, on architectures that do not guarantee ordered data accesses,
special instructions or special variants of instructions are used to indicate
to the processor that data accesses need to occur in a certain order.
As a result, most of the atomic operations have three variants in order to
include optional memory barriers.
The first form just performs the operation without any explicit barriers.
The second form uses a read memory barrier, and the third variant uses a write
memory barrier.
.Pp
The second variant of each operation includes an
efficiently might not be available.
.Ss Acquire and Release Operations
By default, a thread's accesses to different memory locations might not be
performed in
.Em program order ,
that is, the order in which the accesses appear in the source code.
To optimize the program's execution, both the compiler and processor might
reorder the thread's accesses.
However, both ensure that their reordering of the accesses is not visible to
the thread.
Otherwise, the traditional memory model that is expected by single-threaded
programs would be violated.
Nonetheless, other threads in a multithreaded program, such as the
.Fx
kernel, might observe the reordering.
Moreover, in some cases, such as the implementation of synchronization between
threads, arbitrary reordering might result in the incorrect execution of the
program.
To constrain the reordering that both the compiler and processor might perform
on a thread's accesses, the thread should use atomic operations with
.Em acquire
memory barrier.
This barrier ensures that the effects of this operation are completed before the
effects of any later data accesses.
As a result, the operation is said to have acquire semantics as it acquires a
pseudo-lock requiring further operations to wait until it has completed.
To denote this, the suffix
and
.Em release
semantics.
.Pp
Most of the atomic operations on memory have three variants.
The first variant performs the operation without imposing any ordering
constraints on memory accesses to other locations.
The second variant has acquire semantics, and the third variant has release
semantics.
In effect, operations with acquire and release semantics establish one-way
barriers to reordering.
.Pp
When an atomic operation has acquire semantics, the effects of the operation
must have completed before any subsequent load or store (by program order) is
performed.
Conversely, acquire semantics do not require that prior loads or stores have
completed before the atomic operation is performed.
To denote acquire semantics, the suffix
.Dq Li _acq
is inserted into the function name immediately prior to the
.Dq Li _ Ns Aq Fa type
suffix.
For example, to subtract two integers ensuring that any later writes will
happen after the subtraction is performed, use
For example, to subtract two integers ensuring that subsequent loads and
stores happen after the subtraction is performed, use
.Fn atomic_subtract_acq_int .
.Pp
The third variant of each operation includes a
.Em release
memory barrier.
This ensures that all effects of all previous data accesses are completed
before this operation takes place.
As a result, the operation is said to have release semantics as it releases
any pending data accesses to be completed before its operation is performed.
To denote this, the suffix
When an atomic operation has release semantics, the effects of all prior
loads or stores (by program order) must have completed before the operation
is performed.
Conversely, release semantics do not require that the effects of the
atomic operation must have completed before any subsequent load or store is
performed.
To denote release semantics, the suffix
.Dq Li _rel
is inserted into the function name immediately prior to the
.Dq Li _ Ns Aq Fa type
suffix.
For example, to add two long integers ensuring that all previous
writes will happen first, use
For example, to add two long integers ensuring that all prior loads and
stores happen before the addition, use
.Fn atomic_add_rel_long .
.Pp
A practical example of using memory barriers is to ensure that data accesses
that are protected by a lock are all performed while the lock is held.
To achieve this, one would use a read barrier when acquiring the lock to
guarantee that the lock is held before any protected operations are performed.
Finally, one would use a write barrier when releasing the lock to ensure that
all of the protected operations are completed before the lock is released.
The one-way barriers provided by acquire and release operations allow the
implementations of common synchronization primitives to express their
ordering requirements without also imposing unnecessary ordering.
For example, for a critical section guarded by a mutex, an acquire operation
when the mutex is locked and a release operation when the mutex is unlocked
will prevent any loads or stores from moving outside of the critical
section.
However, they will not prevent the compiler or processor from moving loads
or stores into the critical section, which does not violate the semantics of
a mutex.
.Ss Multiple Processors
In multiprocessor systems, the atomicity of the atomic operations on memory
depends on support for cache coherence in the underlying architecture.
@ -173,7 +192,7 @@ For example, cache coherence is guaranteed on write-back memory by the
and
.Tn i386
architectures.
However, on some architectures, cache coherence may not be enabled on all
However, on some architectures, cache coherence might not be enabled on all
memory types.
To determine if cache coherence is enabled for a non-default memory type,
consult the architecture's documentation.

View File

@ -1,5 +1,6 @@
.\"
.\" Copyright (c) 2013 The FreeBSD Foundation
.\" Copyright (c) 2013-2015 Mariusz Zaborski <oshogbo@FreeBSD.org>
.\" All rights reserved.
.\"
.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
@ -28,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd Aug 11, 2015
.Dd August 15, 2015
.Dt NV 9
.Os
.Sh NAME
@ -49,6 +50,7 @@
.Nm nvlist_send ,
.Nm nvlist_recv ,
.Nm nvlist_xfer ,
.Nm nvlist_in_array ,
.Nm nvlist_next ,
.Nm nvlist_add ,
.Nm nvlist_move ,
@ -71,6 +73,8 @@
.Fn nvlist_empty "const nvlist_t *nvl"
.Ft int
.Fn nvlist_flags "const nvlist_t *nvl"
.Ft bool
.Fn nvlist_in_array "const nvlist_t *nvl"
.\"
.Ft "nvlist_t *"
.Fn nvlist_clone "const nvlist_t *nvl"
@ -115,6 +119,16 @@
.Fn nvlist_exists_descriptor "const nvlist_t *nvl" "const char *name"
.Ft bool
.Fn nvlist_exists_binary "const nvlist_t *nvl" "const char *name"
.Ft bool
.Fn nvlist_exists_bool_array "const nvlist_t *nvl" "const char *name"
.Ft bool
.Fn nvlist_exists_number_array "const nvlist_t *nvl" "const char *name"
.Ft bool
.Fn nvlist_exists_string_array "const nvlist_t *nvl" "const char *name"
.Ft bool
.Fn nvlist_exists_nvlist_array "const nvlist_t *nvl" "const char *name"
.Ft bool
.Fn nvlist_exists_descriptor_array "const nvlist_t *nvl" "const char *name"
.\"
.Ft void
.Fn nvlist_add_null "nvlist_t *nvl" "const char *name"
@ -134,6 +148,20 @@
.Fn nvlist_add_descriptor "nvlist_t *nvl" "const char *name" "int value"
.Ft void
.Fn nvlist_add_binary "nvlist_t *nvl" "const char *name" "const void *value" "size_t size"
.Ft void
.Fn nvlist_add_bool_array "nvlist_t *nvl" "const char *name" "const bool *value" "size_t nitems"
.
.Ft void
.Fn nvlist_add_number_array "nvlist_t *nvl" "const char *name" "const uint64_t *value" "size_t nitems"
.
.Ft void
.Fn nvlist_add_string_array "nvlist_t *nvl" "const char *name" "const char * const * value" "size_t nitems"
.
.Ft void
.Fn nvlist_add_nvlist_array "nvlist_t *nvl" "const char *name" "const nvlist_t * const * value" "size_t nitems"
.
.Ft void
.Fn nvlist_add_descriptor_array "nvlist_t *nvl" "const char *name" "const int *value" "size_t nitems"
.\"
.Ft void
.Fn nvlist_move_string "nvlist_t *nvl" "const char *name" "char *value"
@ -143,6 +171,20 @@
.Fn nvlist_move_descriptor "nvlist_t *nvl" "const char *name" "int value"
.Ft void
.Fn nvlist_move_binary "nvlist_t *nvl" "const char *name" "void *value" "size_t size"
.Ft void
.Fn nvlist_move_bool_array "nvlist_t *nvl" "const char *name" "bool *value" "size_t nitems"
.
.Ft void
.Fn nvlist_move_number_array "nvlist_t *nvl" "const char *name" "uint64_t *value" "size_t nitems"
.
.Ft void
.Fn nvlist_move_string_array "nvlist_t *nvl" "const char *name" "char **value" "size_t nitems"
.
.Ft void
.Fn nvlist_move_nvlist_array "nvlist_t *nvl" "const char *name" "nvlist_t **value" "size_t nitems"
.
.Ft void
.Fn nvlist_move_descriptor_array "nvlist_t *nvl" "const char *name" "int *value" "size_t nitems"
.\"
.Ft bool
.Fn nvlist_get_bool "const nvlist_t *nvl" "const char *name"
@ -156,8 +198,22 @@
.Fn nvlist_get_descriptor "const nvlist_t *nvl" "const char *name"
.Ft "const void *"
.Fn nvlist_get_binary "const nvlist_t *nvl" "const char *name" "size_t *sizep"
.Ft "const bool *"
.Fn nvlist_get_bool_array "const nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "const uint64_t *"
.Fn nvlist_get_number "const nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "const char * const *"
.Fn nvlist_get_string "const nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "const nvlist_t * const *"
.Fn nvlist_get_nvlist "const nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "const int *"
.Fn nvlist_get_descriptor_array "const nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "const nvlist_t *"
.Fn nvlist_get_parent "const nvlist_t *nvl" "void **cookiep"
.Ft "const nvlist_t *"
.Fn nvlist_get_array_next "const nvlist_t *nvl"
.Ft "const nvlist_t *"
.Fn nvlist_get_pararr "const nvlist_t *nvl" "void **cookiep"
.\"
.Ft bool
.Fn nvlist_take_bool "nvlist_t *nvl" "const char *name"
@ -171,6 +227,16 @@
.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name"
.Ft "void *"
.Fn nvlist_take_binary "nvlist_t *nvl" "const char *name" "size_t *sizep"
.Ft "bool *"
.Fn nvlist_take_bool_array "nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "uint64_t **"
.Fn nvlist_take_number "nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "char **"
.Fn nvlist_take_string "nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "nvlist_t **"
.Fn nvlist_take_nvlist "nvlist_t *nvl" "const char *name" "size_t *nitems"
.Ft "int *"
.Fn nvlist_take_descriptor "nvlist_t *nvl" "const char *name" "size_t *nitems"
.\"
.Ft void
.Fn nvlist_free "nvlist_t *nvl" "const char *name"
@ -191,6 +257,16 @@
.Fn nvlist_free_descriptor "nvlist_t *nvl" "const char *name"
.Ft void
.Fn nvlist_free_binary "nvlist_t *nvl" "const char *name"
.Ft void
.Fn nvlist_free_bool_array "nvlist_t *nvl" "const char *name"
.Ft void
.Fn nvlist_free_number_array "nvlist_t *nvl" "const char *name"
.Ft void
.Fn nvlist_free_string_array "nvlist_t *nvl" "const char *name"
.Ft void
.Fn nvlist_free_nvlist_array "nvlist_t *nvl" "const char *name"
.Ft void
.Fn nvlist_free_descriptor_array "nvlist_t *nvl" "const char *name"
.Sh DESCRIPTION
The
.Nm libnv
@ -221,6 +297,23 @@ Note that file descriptors can be sent only over
domain sockets.
.It Sy binary ( NV_TYPE_BINARY )
The value is a binary buffer.
.It Sy bool array ( NV_TYPE_BOOL_ARRAY )
The value is an array of boolean values.
.It Sy number array ( NV_TYPE_NUMBER_ARRAY )
The value is an array of numbers, each stored as
.Vt uint64_t .
.It Sy string array ( NV_TYPE_STRING_ARRAY )
The value is an array of C strings.
.It Sy nvlist array ( NV_TYPE_NVLIST_ARRAY )
The value is an array of nvlists.
When an nvlist is added to an array, it becomes part of the primary nvlist.
Traversing these arrays can be done using the
.Fn nvlist_get_array_next
and
.Fn nvlist_get_pararr
functions.
.It Sy descriptor array ( NV_TYPE_DESCRIPTOR_ARRAY )
The value is an array of files descriptors.
.El
.Pp
The
@ -280,6 +373,14 @@ function returns flags used to create the nvlist with the
function.
.Pp
The
.Fn nvlist_in_array
function returns
.Dv true
if
.Fa nvl
is part of an array that is a member of another nvlist.
.Pp
The
.Fn nvlist_clone
functions clones the given nvlist.
The clone shares no resources with its origin.
@ -446,7 +547,12 @@ The
.Fn nvlist_exists_string ,
.Fn nvlist_exists_nvlist ,
.Fn nvlist_exists_descriptor ,
.Fn nvlist_exists_binary
.Fn nvlist_exists_binary ,
.Fn nvlist_exists_bool_array ,
.Fn nvlist_exists_number_array ,
.Fn nvlist_exists_string_array ,
.Fn nvlist_exists_nvlist_array ,
.Fn nvlist_exists_descriptor_array
functions return
.Dv true
if element of the given name and the given type determined by the function name
@ -464,7 +570,12 @@ The
.Fn nvlist_add_stringv ,
.Fn nvlist_add_nvlist ,
.Fn nvlist_add_descriptor ,
.Fn nvlist_add_binary
.Fn nvlist_add_binary ,
.Fn nvlist_add_bool_array ,
.Fn nvlist_add_number_array ,
.Fn nvlist_add_string_array ,
.Fn nvlist_add_nvlist_array ,
.Fn nvlist_add_descriptor_array
functions add element to the given nvlist.
When adding string or binary buffor the functions will allocate memory
and copy the data over.
@ -472,6 +583,10 @@ When adding nvlist, the nvlist will be cloned and clone will be added.
When adding descriptor, the descriptor will be duplicated using the
.Xr dup 2
system call and the new descriptor will be added.
The array functions will fail if there are any
.Dv NULL
elements in the array, or if the array pointer is
.Dv NULL .
If an error occurs while adding new element, internal error is set which can be
examined using the
.Fn nvlist_error
@ -481,10 +596,21 @@ The
.Fn nvlist_move_string ,
.Fn nvlist_move_nvlist ,
.Fn nvlist_move_descriptor ,
.Fn nvlist_move_binary
.Fn nvlist_move_binary ,
.Fn nvlist_move_bool_array ,
.Fn nvlist_move_number_array ,
.Fn nvlist_move_string_array ,
.Fn nvlist_move_nvlist_array ,
.Fn nvlist_move_descriptor_array
functions add new element to the given nvlist, but unlike
.Fn nvlist_add_<type>
functions they will consume the given resource.
In the case of strings, descriptors, or nvlists every elements must be
unique, or it could cause a double free.
The array functions will fail if there are any
.Dv NULL
elements, or if the array pointer is
.Dv NULL .
If an error occurs while adding new element, the resource is destroyed and
internal error is set which can be examined using the
.Fn nvlist_error
@ -496,20 +622,43 @@ The
.Fn nvlist_get_string ,
.Fn nvlist_get_nvlist ,
.Fn nvlist_get_descriptor ,
.Fn nvlist_get_binary
functions allow to obtain value of the given name.
In case of string, nvlist, descriptor or binary, returned resource should
not be modified - it still belongs to the nvlist.
If element of the given name does not exist, the program will be aborted.
To avoid that the caller should check for existence before trying to obtain
the value or use
.Fn nvlist_get_binary ,
.Fn nvlist_get_bool_array ,
.Fn nvlist_get_number_array ,
.Fn nvlist_get_string_array ,
.Fn nvlist_get_nvlist_array ,
.Fn nvlist_get_descriptor_array
functions return the value that corresponds to the given key name.
In the case of strings, nvlists, descriptors, binary, or arrays, the returned
resource should not be modified - they still belong to the nvlist.
If an element of the given name does not exist, the program will be aborted.
To avoid this, the caller should check for the existence of the name before
trying to obtain the value, or use the
.Xr dnvlist 3
extension, which allows to provide default value for a missing element.
extension, which can provide a default value in the case of a missing element.
The nvlist must not be in error state.
.Pp
The
.Fn nvlist_get_parent
function allows to obtain the parent nvlist from the nested nvlist.
function returns the parent nvlist of the nested nvlist.
.Pp
The
.Fn nvlist_get_array_next
function returns the next element from the array or
.Dv NULL
if the nvlist is not in array or it is the last element.
Note that
.Fn nvlist_get_array_next
only works if you added the nvlist array using the
.Fn nvlist_move_nvlist_array
or
.Fn nvlist_add_nvlist_array
functions.
.Pp
The
.Fn nvlist_get_pararr
function returns the next element in the array, or if not available
the parent of the nested nvlist.
.Pp
The
.Fn nvlist_take_bool ,
@ -517,7 +666,12 @@ The
.Fn nvlist_take_string ,
.Fn nvlist_take_nvlist ,
.Fn nvlist_take_descriptor ,
.Fn nvlist_take_binary
.Fn nvlist_take_binary ,
.Fn nvlist_take_bool_array ,
.Fn nvlist_take_number_array ,
.Fn nvlist_take_string_array ,
.Fn nvlist_take_nvlist_array ,
.Fn nvlist_take_descriptor_array
functions return value associated with the given name and remove the element
from the nvlist.
In case of string and binary values, the caller is responsible for free returned
@ -532,11 +686,27 @@ In case of descriptor, the caller is responsible for closing returned descriptor
using the
.Fn close 2
system call.
If element of the given name does not exist, the program will be aborted.
To avoid that the caller should check for existence before trying to obtain
the value or use
If an element of the given name does not exist, the program will be aborted.
To avoid that the caller should check for the existence of the given name
before trying to obtain the value, or use the
.Xr dnvlist 3
extension, which allows to provide default value for a missing element.
extension, which can provide a default value in the case of a missing element.
In the case of an array of strings or binary values, the caller is responsible
for freeing every element of the array using the
.Xr free 3
function.
In the case of an array of nvlists, the caller is responsible for destroying
every element of array using the
.Fn nvlist_destroy
function.
In the case of descriptors, the caller is responsible for closing every
element of array using the
.Fn close 2
system call.
In every case involving an array, the caller must also free the pointer to
the array using the
.Xr free 3
function.
The nvlist must not be in error state.
.Pp
The
@ -561,7 +731,12 @@ The
.Fn nvlist_free_string ,
.Fn nvlist_free_nvlist ,
.Fn nvlist_free_descriptor ,
.Fn nvlist_free_binary
.Fn nvlist_free_binary ,
.Fn nvlist_free_bool_array ,
.Fn nvlist_free_number_array ,
.Fn nvlist_free_string_array ,
.Fn nvlist_free_nvlist_array ,
.Fn nvlist_free_descriptor_array
functions remove element of the given name and the given type determined by the
function name from the nvlist and free all resources associated with it.
If element of the given name and the given type does not exist, the program
@ -679,6 +854,65 @@ do {
}
} while ((nvl = nvlist_get_parent(nvl, &cookie)) != NULL);
.Ed
.Pp
Iterating over every nested nvlist and every nvlist element:
.Bd -literal
nvlist_t *nvl;
const nvlist_t * const *array;
const char *name;
void *cookie;
int type;
nvl = nvlist_recv(sock, 0);
if (nvl == null)
err(1, "nvlist_recv() failed");
cookie = null;
do {
while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
if (type == NV_TYPE_NVLIST) {
nvl = nvlist_get_nvlist(nvl, name);
cookie = NULL;
} else if (type == NV_TYPE_NVLIST_ARRAY) {
nvl = nvlist_get_nvlist_array(nvl, name, NULL)[0];
cookie = NULL;
}
}
} while ((nvl = nvlist_get_pararr(nvl, &cookie)) != NULL);
.Ed
.Pp
Or alternatively:
.Bd -literal
nvlist_t *nvl, *tmp;
const nvlist_t * const *array;
const char *name;
void *cookie;
int type;
nvl = nvlist_recv(sock, 0);
if (nvl == null)
err(1, "nvlist_recv() failed");
cooke = NULL;
tmp = nvl;
do {
do {
nvl = tmp;
while ((name = nvlist_next(nvl, &type, &cookie)) != NULL) {
if (type == NV_TYPE_NVLIST) {
nvl = nvlist_get_nvlist(nvl,
name);
cookie = NULL;
} else if (type == NV_TYPE_NVLIST_ARRAY) {
nvl = nvlist_get_nvlist_array(nvl, name,
NULL)[0];
cookie = NULL;
}
}
cookie = NULL;
} while ((tmp = nvlist_get_array_next(nvl)) != NULL);
} while ((tmp = nvlist_get_parent(nvl, &cookie)) != NULL);
.Ed
.Sh SEE ALSO
.Xr close 2 ,
.Xr dup 2 ,

File diff suppressed because it is too large Load Diff

View File

@ -171,7 +171,7 @@ _LIBS= lib${LIB_PRIVATE}${LIB}.a
lib${LIB_PRIVATE}${LIB}.a: ${OBJS} ${STATICOBJS}
@${ECHO} building static ${LIB} library
@rm -f ${.TARGET}
${AR} ${ARFLAGS} ${.TARGET} `NM='${NM}' lorder ${OBJS} ${STATICOBJS} | tsort -q` ${ARADD}
${AR} ${ARFLAGS} ${.TARGET} `NM='${NM}' NMFLAGS='${NMFLAGS}' lorder ${OBJS} ${STATICOBJS} | tsort -q` ${ARADD}
${RANLIB} ${RANLIBFLAGS} ${.TARGET}
.endif
@ -185,7 +185,7 @@ NOPATH_FILES+= ${POBJS}
lib${LIB_PRIVATE}${LIB}_p.a: ${POBJS}
@${ECHO} building profiled ${LIB} library
@rm -f ${.TARGET}
${AR} ${ARFLAGS} ${.TARGET} `NM='${NM}' lorder ${POBJS} | tsort -q` ${ARADD}
${AR} ${ARFLAGS} ${.TARGET} `NM='${NM}' NMFLAGS='${NMFLAGS}' lorder ${POBJS} | tsort -q` ${ARADD}
${RANLIB} ${RANLIBFLAGS} ${.TARGET}
.endif
@ -250,7 +250,7 @@ ${SHLIB_NAME_FULL}: ${SOBJS}
.endif
${_LD} ${LDFLAGS} ${SSP_CFLAGS} ${SOLINKOPTS} \
-o ${.TARGET} -Wl,-soname,${SONAME} \
`NM='${NM}' lorder ${SOBJS} | tsort -q` ${LDADD}
`NM='${NM}' NMFLAGS='${NMFLAGS}' lorder ${SOBJS} | tsort -q` ${LDADD}
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SOBJS}
.endif

View File

@ -80,7 +80,7 @@ __DEFAULT_YES_OPTIONS = \
DYNAMICROOT \
ED_CRYPTO \
EE \
ELFTOOLCHAIN_TOOLS \
ELFTOOLCHAIN_BOOTSTRAP \
EXAMPLES \
FDT \
FILE \
@ -156,7 +156,6 @@ __DEFAULT_YES_OPTIONS = \
SOURCELESS_UCODE \
SVNLITE \
SYSCONS \
SYSINSTALL \
TALK \
TCP_WRAPPERS \
TCSH \
@ -330,6 +329,7 @@ MK_GROFF:= no
.if ${MK_CROSS_COMPILER} == "no"
MK_BINUTILS_BOOTSTRAP:= no
MK_CLANG_BOOTSTRAP:= no
MK_ELFTOOLCHAIN_BOOTSTRAP:= no
MK_GCC_BOOTSTRAP:= no
.endif

View File

@ -167,6 +167,7 @@ MAKE ?= make
.if !defined(%POSIX)
NM ?= nm
NMFLAGS ?=
OBJC ?= cc
OBJCFLAGS ?= ${OBJCINCLUDES} ${CFLAGS} -Wno-import

View File

@ -390,6 +390,8 @@ static struct md_page *pv_table;
*/
pt_entry_t *CMAP1 = 0;
caddr_t CADDR1 = 0;
static vm_offset_t qframe = 0;
static struct mtx qframe_mtx;
static int pmap_flags = PMAP_PDE_SUPERPAGE; /* flags for x86 pmaps */
@ -1031,7 +1033,7 @@ pmap_init(void)
struct pmap_preinit_mapping *ppim;
vm_page_t mpte;
vm_size_t s;
int i, pv_npg;
int error, i, pv_npg;
/*
* Initialize the vm page array entries for the kernel pmap's
@ -1112,6 +1114,12 @@ pmap_init(void)
printf("PPIM %u: PA=%#lx, VA=%#lx, size=%#lx, mode=%#x\n", i,
ppim->pa, ppim->va, ppim->sz, ppim->mode);
}
mtx_init(&qframe_mtx, "qfrmlk", NULL, MTX_SPIN);
error = vmem_alloc(kernel_arena, PAGE_SIZE, M_BESTFIT | M_WAITOK,
(vmem_addr_t *)&qframe);
if (error != 0)
panic("qframe allocation failed");
}
static SYSCTL_NODE(_vm_pmap, OID_AUTO, pde, CTLFLAG_RD, 0,
@ -7019,13 +7027,27 @@ pmap_unmap_io_transient(vm_page_t page[], vm_offset_t vaddr[], int count,
vm_offset_t
pmap_quick_enter_page(vm_page_t m)
{
vm_paddr_t paddr;
return (PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m)));
paddr = VM_PAGE_TO_PHYS(m);
if (paddr < dmaplimit)
return (PHYS_TO_DMAP(paddr));
mtx_lock_spin(&qframe_mtx);
KASSERT(*vtopte(qframe) == 0, ("qframe busy"));
pte_store(vtopte(qframe), paddr | X86_PG_RW | X86_PG_V | X86_PG_A |
X86_PG_M | pmap_cache_bits(kernel_pmap, m->md.pat_mode, 0));
return (qframe);
}
void
pmap_quick_remove_page(vm_offset_t addr)
{
if (addr != qframe)
return;
pte_store(vtopte(qframe), 0);
invlpg(qframe);
mtx_unlock_spin(&qframe_mtx);
}
#include "opt_ddb.h"

View File

@ -904,6 +904,7 @@ set_cpufuncs()
cputype == CPU_ID_CORTEXA9R1 ||
cputype == CPU_ID_CORTEXA9R2 ||
cputype == CPU_ID_CORTEXA9R3 ||
cputype == CPU_ID_CORTEXA9R4 ||
cputype == CPU_ID_CORTEXA12R0 ||
cputype == CPU_ID_CORTEXA15R0 ||
cputype == CPU_ID_CORTEXA15R1 ||

View File

@ -185,6 +185,8 @@ const struct cpuidtab cpuids[] = {
generic_steppings },
{ CPU_ID_CORTEXA9R3, CPU_CLASS_CORTEXA, "Cortex A9-r3",
generic_steppings },
{ CPU_ID_CORTEXA9R4, CPU_CLASS_CORTEXA, "Cortex A9-r4",
generic_steppings },
{ CPU_ID_CORTEXA12R0, CPU_CLASS_CORTEXA, "Cortex A12-r0",
generic_steppings },
{ CPU_ID_CORTEXA15R0, CPU_CLASS_CORTEXA, "Cortex A15-r0",

View File

@ -1166,10 +1166,9 @@ pmap_init_qpages(void)
pc = pcpu_find(i);
pc->pc_qmap_addr = kva_alloc(PAGE_SIZE);
if (pc->pc_qmap_addr == 0)
panic("pmap_init_qpages: unable to allocate KVA");
panic("%s: unable to allocate KVA", __func__);
}
}
SYSINIT(qpages_init, SI_SUB_CPU, SI_ORDER_ANY, pmap_init_qpages, NULL);
/*
@ -5728,18 +5727,17 @@ pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
vm_offset_t
pmap_quick_enter_page(vm_page_t m)
{
pt2_entry_t *pte;
vm_offset_t qmap_addr;
pt2_entry_t *pte2p;
vm_offset_t qmap_addr;
critical_enter();
qmap_addr = PCPU_GET(qmap_addr);
pte = pt2map_entry(qmap_addr);
pte2p = pt2map_entry(qmap_addr);
KASSERT(*pte == 0, ("pmap_quick_enter_page: PTE busy"));
KASSERT(pte2_load(pte2p) == 0, ("%s: PTE2 busy", __func__));
pte2_store(pte, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m),
PTE2_AP_KRW, pmap_page_get_memattr(m)));
pte2_store(pte2p, PTE2_KERN_NG(VM_PAGE_TO_PHYS(m), PTE2_AP_KRW,
pmap_page_get_memattr(m)));
tlb_flush_local(qmap_addr);
return (qmap_addr);
@ -5748,16 +5746,16 @@ pmap_quick_enter_page(vm_page_t m)
void
pmap_quick_remove_page(vm_offset_t addr)
{
pt2_entry_t *pte;
pt2_entry_t *pte2p;
vm_offset_t qmap_addr;
qmap_addr = PCPU_GET(qmap_addr);
pte = pt2map_entry(qmap_addr);
pte2p = pt2map_entry(qmap_addr);
KASSERT(addr == qmap_addr, ("pmap_quick_remove_page: invalid address"));
KASSERT(*pte != 0, ("pmap_quick_remove_page: PTE not in use"));
KASSERT(addr == qmap_addr, ("%s: invalid address", __func__));
KASSERT(pte2_load(pte2p) != 0, ("%s: PTE2 not in use", __func__));
pte2_clear(pte);
pte2_clear(pte2p);
critical_exit();
}

View File

@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <machine/acle-compat.h>
#include <machine/atomic.h>
#include <machine/cpufunc.h>
#include <machine/sysarch.h>
@ -67,19 +68,12 @@ do_sync(void)
__asm volatile ("" : : : "memory");
}
#elif __ARM_ARCH >= 7
static inline void
do_sync(void)
{
__asm volatile ("dmb" : : : "memory");
}
#elif __ARM_ARCH >= 6
static inline void
do_sync(void)
{
__asm volatile ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory");
dmb();
}
#endif

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#define BCM2835_NUM_TIMERS 4
#define DEFAULT_TIMER 3
#define DEFAULT_TIMER_NAME "BCM2835-3"
#define DEFAULT_FREQUENCY 1000000
#define MIN_PERIOD 5LLU
@ -101,7 +102,7 @@ static struct bcm_systimer_softc *bcm_systimer_sc = NULL;
static unsigned bcm_systimer_tc_get_timecount(struct timecounter *);
static struct timecounter bcm_systimer_tc = {
.tc_name = "BCM2835 Timecounter",
.tc_name = DEFAULT_TIMER_NAME,
.tc_get_timecount = bcm_systimer_tc_get_timecount,
.tc_poll_pps = NULL,
.tc_counter_mask = ~0u,
@ -238,8 +239,7 @@ bcm_systimer_attach(device_t dev)
sc->st[DEFAULT_TIMER].index = DEFAULT_TIMER;
sc->st[DEFAULT_TIMER].enabled = 0;
sc->st[DEFAULT_TIMER].et.et_name = malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
sprintf(sc->st[DEFAULT_TIMER].et.et_name, "BCM2835 Event Timer %d", DEFAULT_TIMER);
sc->st[DEFAULT_TIMER].et.et_name = DEFAULT_TIMER_NAME;
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;

View File

@ -26,7 +26,7 @@ ident BEAGLEBONE
include "std.armv6"
include "../ti/am335x/std.am335x"
makeoptions MODULES_EXTRA="dtb/am335x"
makeoptions MODULES_EXTRA="dtb/am335x am335x_dmtpps"
# DTrace support
options KDTRACE_HOOKS # Kernel DTrace hooks
@ -77,6 +77,7 @@ device ti_i2c
device am335x_pmic # AM335x Power Management IC (TPC65217)
device am335x_rtc # RTC support (power management only)
#define am335x_dmtpps # Pulse Per Second capture driver
# Console and misc
device uart

View File

@ -133,6 +133,7 @@
#define CPU_ID_CORTEXA9R1 0x411fc090
#define CPU_ID_CORTEXA9R2 0x412fc090
#define CPU_ID_CORTEXA9R3 0x413fc090
#define CPU_ID_CORTEXA9R4 0x414fc090
#define CPU_ID_CORTEXA12R0 0x410fc0d0
#define CPU_ID_CORTEXA15R0 0x410fc0f0
#define CPU_ID_CORTEXA15R1 0x411fc0f0

View File

@ -0,0 +1,549 @@
/*-
* Copyright (c) 2015 Ian lepore <ian@freebsd.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* AM335x PPS driver using DMTimer capture.
*
* Note that this PPS driver does not use an interrupt. Instead it uses the
* hardware's ability to latch the timer's count register in response to a
* signal on an IO pin. Each of timers 4-7 have an associated pin, and this
* code allows any one of those to be used.
*
* The timecounter routines in kern_tc.c call the pps poll routine periodically
* to see if a new counter value has been latched. When a new value has been
* latched, the only processing done in the poll routine is to capture the
* current set of timecounter timehands (done with pps_capture()) and the
* latched value from the timer. The remaining work (done by pps_event() while
* holding a mutex) is scheduled to be done later in a non-interrupt context.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <sys/taskqueue.h>
#include <sys/timepps.h>
#include <sys/timetc.h>
#include <machine/bus.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/ti/ti_prcm.h>
#include <arm/ti/ti_hwmods.h>
#include <arm/ti/ti_pinmux.h>
#include <arm/ti/am335x/am335x_scm_padconf.h>
#include "am335x_dmtreg.h"
#define PPS_CDEV_NAME "dmtpps"
struct dmtpps_softc {
device_t dev;
int mem_rid;
struct resource * mem_res;
int tmr_num; /* N from hwmod str "timerN" */
char tmr_name[12]; /* "DMTimerN" */
uint32_t tclr; /* Cached TCLR register. */
struct timecounter tc;
int pps_curmode; /* Edge mode now set in hw. */
struct task pps_task; /* For pps_event handling. */
struct cdev * pps_cdev;
struct pps_state pps_state;
struct mtx pps_mtx;
};
static int dmtpps_tmr_num; /* Set by probe() */
/* List of compatible strings for FDT tree */
static struct ofw_compat_data compat_data[] = {
{"ti,am335x-timer", 1},
{"ti,am335x-timer-1ms", 1},
{NULL, 0},
};
/*
* A table relating pad names to the hardware timer number they can be mux'd to.
*/
struct padinfo {
char * ballname;
int tmr_num;
};
static struct padinfo dmtpps_padinfo[] = {
{"GPMC_ADVn_ALE", 4},
{"I2C0_SDA", 4},
{"MII1_TX_EN", 4},
{"XDMA_EVENT_INTR0", 4},
{"GPMC_BEn0_CLE", 5},
{"MDC", 5},
{"MMC0_DAT3", 5},
{"UART1_RTSn", 5},
{"GPMC_WEn", 6},
{"MDIO", 6},
{"MMC0_DAT2", 6},
{"UART1_CTSn", 6},
{"GPMC_OEn_REn", 7},
{"I2C0_SCL", 7},
{"UART0_CTSn", 7},
{"XDMA_EVENT_INTR1", 7},
{NULL, 0}
};
/*
* This is either brilliantly user-friendly, or utterly lame...
*
* The am335x chip is used on the popular Beaglebone boards. Those boards have
* pins for all four capture-capable timers available on the P8 header. Allow
* users to configure the input pin by giving the name of the header pin.
*/
struct nicknames {
const char * nick;
const char * name;
};
static struct nicknames dmtpps_pin_nicks[] = {
{"P8-7", "GPMC_ADVn_ALE"},
{"P8-9", "GPMC_BEn0_CLE"},
{"P8-10", "GPMC_WEn"},
{"P8-8", "GPMC_OEn_REn",},
{NULL, NULL}
};
#define DMTIMER_READ4(sc, reg) bus_read_4((sc)->mem_res, (reg))
#define DMTIMER_WRITE4(sc, reg, val) bus_write_4((sc)->mem_res, (reg), (val))
/*
* Translate a short friendly case-insensitive name to its canonical name.
*/
static const char *
dmtpps_translate_nickname(const char *nick)
{
struct nicknames *nn;
for (nn = dmtpps_pin_nicks; nn->nick != NULL; nn++)
if (strcasecmp(nick, nn->nick) == 0)
return nn->name;
return (nick);
}
/*
* See if our tunable is set to the name of the input pin. If not, that's NOT
* an error, return 0. If so, try to configure that pin as a timer capture
* input pin, and if that works, then we have our timer unit number and if it
* fails that IS an error, return -1.
*/
static int
dmtpps_find_tmr_num_by_tunable()
{
struct padinfo *pi;
char iname[20];
char muxmode[12];
const char * ballname;
int err;
if (!TUNABLE_STR_FETCH("hw.am335x_dmtpps.input", iname, sizeof(iname)))
return (0);
ballname = dmtpps_translate_nickname(iname);
for (pi = dmtpps_padinfo; pi->ballname != NULL; pi++) {
if (strcmp(ballname, pi->ballname) != 0)
continue;
snprintf(muxmode, sizeof(muxmode), "timer%d", pi->tmr_num);
err = ti_pinmux_padconf_set(pi->ballname, muxmode,
PADCONF_INPUT);
if (err != 0) {
printf("am335x_dmtpps: unable to configure capture pin "
"for %s to input mode\n", muxmode);
return (-1);
} else if (bootverbose) {
printf("am335x_dmtpps: configured pin %s as input "
"for %s\n", iname, muxmode);
}
return (pi->tmr_num);
}
/* Invalid name in the tunable, that's an error. */
printf("am335x_dmtpps: unknown pin name '%s'\n", iname);
return (-1);
}
/*
* Ask the pinmux driver whether any pin has been configured as a TIMER4..TIMER7
* input pin. If so, return the timer number, if not return 0.
*/
static int
dmtpps_find_tmr_num_by_padconf()
{
int err;
unsigned int padstate;
const char * padmux;
struct padinfo *pi;
char muxmode[12];
for (pi = dmtpps_padinfo; pi->ballname != NULL; pi++) {
err = ti_pinmux_padconf_get(pi->ballname, &padmux, &padstate);
snprintf(muxmode, sizeof(muxmode), "timer%d", pi->tmr_num);
if (err == 0 && (padstate & RXACTIVE) != 0 &&
strcmp(muxmode, padmux) == 0)
return (pi->tmr_num);
}
/* Nothing found, not an error. */
return (0);
}
/*
* Figure out which hardware timer number to use based on input pin
* configuration. This is done just once, the first time probe() runs.
*/
static int
dmtpps_find_tmr_num()
{
int tmr_num;
if ((tmr_num = dmtpps_find_tmr_num_by_tunable()) == 0)
tmr_num = dmtpps_find_tmr_num_by_padconf();
if (tmr_num <= 0) {
printf("am335x_dmtpps: PPS driver not enabled: unable to find "
"or configure a capture input pin\n");
tmr_num = -1; /* Must return non-zero to prevent re-probing. */
}
return (tmr_num);
}
static void
dmtpps_set_hw_capture(struct dmtpps_softc *sc, bool force_off)
{
int newmode;
if (force_off)
newmode = 0;
else
newmode = sc->pps_state.ppsparam.mode & PPS_CAPTUREASSERT;
if (newmode == sc->pps_curmode)
return;
sc->pps_curmode = newmode;
if (newmode == PPS_CAPTUREASSERT)
sc->tclr |= DMT_TCLR_CAPTRAN_LOHI;
else
sc->tclr &= ~DMT_TCLR_CAPTRAN_MASK;
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
}
static unsigned
dmtpps_get_timecount(struct timecounter *tc)
{
struct dmtpps_softc *sc;
sc = tc->tc_priv;
return (DMTIMER_READ4(sc, DMT_TCRR));
}
static void
dmtpps_poll(struct timecounter *tc)
{
struct dmtpps_softc *sc;
sc = tc->tc_priv;
/*
* If a new value has been latched we've got a PPS event. Capture the
* timecounter data, then override the capcount field (pps_capture()
* populates it from the current DMT_TCRR register) with the latched
* value from the TCAR1 register.
*
* There is no locking here, by design. pps_capture() writes into an
* area of struct pps_state which is read only by pps_event(). The
* synchronization of access to that area is temporal rather than
* interlock based... we write in this routine and trigger the task that
* will read the data, so no simultaneous access can occur.
*
* Note that we don't have the TCAR interrupt enabled, but the hardware
* still provides the status bits in the "RAW" status register even when
* they're masked from generating an irq. However, when clearing the
* TCAR status to re-arm the capture for the next second, we have to
* write to the IRQ status register, not the RAW register. Quirky.
*/
if (DMTIMER_READ4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
pps_capture(&sc->pps_state);
sc->pps_state.capcount = DMTIMER_READ4(sc, DMT_TCAR1);
DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
taskqueue_enqueue_fast(taskqueue_fast, &sc->pps_task);
}
}
static void
dmtpps_event(void *arg, int pending)
{
struct dmtpps_softc *sc;
sc = arg;
/* This is the task function that gets enqueued by poll_pps. Once the
* time has been captured by the timecounter polling code which runs in
* primary interrupt context, the remaining (more expensive) work to
* process the event is done later in a threaded context.
*
* Here there is an interlock that protects the event data in struct
* pps_state. That data can be accessed at any time from userland via
* ioctl() calls so we must ensure that there is no read access to
* partially updated data while pps_event() does its work.
*/
mtx_lock(&sc->pps_mtx);
pps_event(&sc->pps_state, PPS_CAPTUREASSERT);
mtx_unlock(&sc->pps_mtx);
}
static int
dmtpps_open(struct cdev *dev, int flags, int fmt,
struct thread *td)
{
struct dmtpps_softc *sc;
sc = dev->si_drv1;
/*
* Begin polling for pps and enable capture in the hardware whenever the
* device is open. Doing this stuff again is harmless if this isn't the
* first open.
*/
sc->tc.tc_poll_pps = dmtpps_poll;
dmtpps_set_hw_capture(sc, false);
return 0;
}
static int
dmtpps_close(struct cdev *dev, int flags, int fmt,
struct thread *td)
{
struct dmtpps_softc *sc;
sc = dev->si_drv1;
/*
* Stop polling and disable capture on last close. Use the force-off
* flag to override the configured mode and turn off the hardware.
*/
sc->tc.tc_poll_pps = NULL;
dmtpps_set_hw_capture(sc, true);
return 0;
}
static int
dmtpps_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
int flags, struct thread *td)
{
struct dmtpps_softc *sc;
int err;
sc = dev->si_drv1;
/* Let the kernel do the heavy lifting for ioctl. */
mtx_lock(&sc->pps_mtx);
err = pps_ioctl(cmd, data, &sc->pps_state);
mtx_unlock(&sc->pps_mtx);
if (err != 0)
return (err);
/*
* The capture mode could have changed, set the hardware to whatever
* mode is now current. Effectively a no-op if nothing changed.
*/
dmtpps_set_hw_capture(sc, false);
return (err);
}
static struct cdevsw dmtpps_cdevsw = {
.d_version = D_VERSION,
.d_open = dmtpps_open,
.d_close = dmtpps_close,
.d_ioctl = dmtpps_ioctl,
.d_name = PPS_CDEV_NAME,
};
static int
dmtpps_probe(device_t dev)
{
char strbuf[64];
int tmr_num;
if (!ofw_bus_status_okay(dev))
return (ENXIO);
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
/*
* If we haven't chosen which hardware timer to use yet, go do that now.
* We need to know that to decide whether to return success for this
* hardware timer instance or not.
*/
if (dmtpps_tmr_num == 0)
dmtpps_tmr_num = dmtpps_find_tmr_num();
/*
* Figure out which hardware timer is being probed and see if it matches
* the configured timer number determined earlier.
*/
tmr_num = ti_hwmods_get_unit(dev, "timer");
if (dmtpps_tmr_num != tmr_num)
return (ENXIO);
snprintf(strbuf, sizeof(strbuf), "AM335x PPS-Capture DMTimer%d",
tmr_num);
device_set_desc_copy(dev, strbuf);
return(BUS_PROBE_DEFAULT);
}
static int
dmtpps_attach(device_t dev)
{
struct dmtpps_softc *sc;
clk_ident_t timer_id;
int err, sysclk_freq;
sc = device_get_softc(dev);
sc->dev = dev;
/* Get the base clock frequency. */
err = ti_prcm_clk_get_source_freq(SYS_CLK, &sysclk_freq);
/* Enable clocks and power on the device. */
if ((timer_id = ti_hwmods_get_clock(dev)) == INVALID_CLK_IDENT)
return (ENXIO);
if ((err = ti_prcm_clk_set_source(timer_id, SYSCLK_CLK)) != 0)
return (err);
if ((err = ti_prcm_clk_enable(timer_id)) != 0)
return (err);
/* Request the memory resources. */
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->mem_rid, RF_ACTIVE);
if (sc->mem_res == NULL) {
return (ENXIO);
}
/* Figure out which hardware timer this is and set the name string. */
sc->tmr_num = ti_hwmods_get_unit(dev, "timer");
snprintf(sc->tmr_name, sizeof(sc->tmr_name), "DMTimer%d", sc->tmr_num);
/* Set up timecounter hardware, start it. */
DMTIMER_WRITE4(sc, DMT_TSICR, DMT_TSICR_RESET);
while (DMTIMER_READ4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
continue;
sc->tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
DMTIMER_WRITE4(sc, DMT_TLDR, 0);
DMTIMER_WRITE4(sc, DMT_TCRR, 0);
DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
/* Register the timecounter. */
sc->tc.tc_name = sc->tmr_name;
sc->tc.tc_get_timecount = dmtpps_get_timecount;
sc->tc.tc_counter_mask = ~0u;
sc->tc.tc_frequency = sysclk_freq;
sc->tc.tc_quality = 1000;
sc->tc.tc_priv = sc;
tc_init(&sc->tc);
/*
* Indicate our PPS capabilities. Have the kernel init its part of the
* pps_state struct and add its capabilities.
*
* While the hardware has a mode to capture each edge, it's not clear we
* can use it that way, because there's only a single interrupt/status
* bit to say something was captured, but not which edge it was. For
* now, just say we can only capture assert events (the positive-going
* edge of the pulse).
*/
mtx_init(&sc->pps_mtx, "dmtpps", NULL, MTX_DEF);
sc->pps_state.ppscap = PPS_CAPTUREASSERT;
sc->pps_state.driver_abi = PPS_ABI_VERSION;
sc->pps_state.driver_mtx = &sc->pps_mtx;
pps_init_abi(&sc->pps_state);
/*
* Init the task that does deferred pps_event() processing after
* the polling routine has captured a pps pulse time.
*/
TASK_INIT(&sc->pps_task, 0, dmtpps_event, sc);
/* Create the PPS cdev. */
sc->pps_cdev = make_dev(&dmtpps_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600,
PPS_CDEV_NAME);
sc->pps_cdev->si_drv1 = sc;
if (bootverbose)
device_printf(sc->dev, "Using %s for PPS device /dev/%s\n",
sc->tmr_name, PPS_CDEV_NAME);
return (0);
}
static int
dmtpps_detach(device_t dev)
{
/*
* There is no way to remove a timecounter once it has been registered,
* even if it's not in use, so we can never detach. If we were
* dynamically loaded as a module this will prevent unloading.
*/
return (EBUSY);
}
static device_method_t dmtpps_methods[] = {
DEVMETHOD(device_probe, dmtpps_probe),
DEVMETHOD(device_attach, dmtpps_attach),
DEVMETHOD(device_detach, dmtpps_detach),
{ 0, 0 }
};
static driver_t dmtpps_driver = {
"am335x_dmtpps",
dmtpps_methods,
sizeof(struct dmtpps_softc),
};
static devclass_t dmtpps_devclass;
DRIVER_MODULE(am335x_dmtpps, simplebus, dmtpps_driver, dmtpps_devclass, 0, 0);
MODULE_DEPEND(am335x_dmtpps, am335x_prcm, 1, 1, 1);

View File

@ -3,6 +3,7 @@
arm/ti/aintc.c standard
arm/ti/am335x/am335x_dmtimer.c standard
arm/ti/am335x/am335x_dmtpps.c optional am335x_dmtpps
arm/ti/am335x/am335x_gpio.c optional gpio
arm/ti/am335x/am335x_lcd.c optional sc | vt
arm/ti/am335x/am335x_lcd_syscons.c optional sc

View File

@ -244,7 +244,7 @@ sp804_timer_attach(device_t dev)
* Timer 1, timecounter
*/
sc->tc.tc_frequency = sc->sysclk_freq;
sc->tc.tc_name = "SP804 Time Counter";
sc->tc.tc_name = "SP804-1";
sc->tc.tc_get_timecount = sp804_timer_tc_get_timecount;
sc->tc.tc_poll_pps = NULL;
sc->tc.tc_counter_mask = ~0u;
@ -263,9 +263,7 @@ sp804_timer_attach(device_t dev)
* Timer 2, event timer
*/
sc->et_enabled = 0;
sc->et.et_name = malloc(64, M_DEVBUF, M_NOWAIT | M_ZERO);
sprintf(sc->et.et_name, "SP804 Event Timer %d",
device_get_unit(dev));
sc->et.et_name = "SP804-2";
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
sc->et.et_quality = 1000;
sc->et.et_frequency = sc->sysclk_freq / DEFAULT_DIVISOR;

View File

@ -49,6 +49,15 @@ void generic_bs_rm_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
void generic_bs_rm_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
bus_size_t);
void generic_bs_rr_1(void *, bus_space_handle_t, bus_size_t, uint8_t *,
bus_size_t);
void generic_bs_rr_2(void *, bus_space_handle_t, bus_size_t, uint16_t *,
bus_size_t);
void generic_bs_rr_4(void *, bus_space_handle_t, bus_size_t, uint32_t *,
bus_size_t);
void generic_bs_rr_8(void *, bus_space_handle_t, bus_size_t, uint64_t *,
bus_size_t);
void generic_bs_w_1(void *, bus_space_handle_t, bus_size_t, uint8_t);
void generic_bs_w_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
void generic_bs_w_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
@ -63,6 +72,15 @@ void generic_bs_wm_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
void generic_bs_wm_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
bus_size_t);
void generic_bs_wr_1(void *, bus_space_handle_t, bus_size_t, const uint8_t *,
bus_size_t);
void generic_bs_wr_2(void *, bus_space_handle_t, bus_size_t, const uint16_t *,
bus_size_t);
void generic_bs_wr_4(void *, bus_space_handle_t, bus_size_t, const uint32_t *,
bus_size_t);
void generic_bs_wr_8(void *, bus_space_handle_t, bus_size_t, const uint64_t *,
bus_size_t);
static int
generic_bs_map(void *t, bus_addr_t bpa, bus_size_t size, int flags,
bus_space_handle_t *bshp)
@ -126,6 +144,12 @@ struct bus_space memmap_bus = {
.bs_rm_4 = generic_bs_rm_4,
.bs_rm_8 = generic_bs_rm_8,
/* read region */
.bs_rr_1 = generic_bs_rr_1,
.bs_rr_2 = generic_bs_rr_2,
.bs_rr_4 = generic_bs_rr_4,
.bs_rr_8 = generic_bs_rr_8,
/* write single */
.bs_w_1 = generic_bs_w_1,
.bs_w_2 = generic_bs_w_2,
@ -139,10 +163,10 @@ struct bus_space memmap_bus = {
.bs_wm_8 = generic_bs_wm_8,
/* write region */
.bs_wr_1 = NULL,
.bs_wr_2 = NULL,
.bs_wr_4 = NULL,
.bs_wr_8 = NULL,
.bs_wr_1 = generic_bs_wr_1,
.bs_wr_2 = generic_bs_wr_2,
.bs_wr_4 = generic_bs_wr_4,
.bs_wr_8 = generic_bs_wr_8,
/* set multiple */
.bs_sm_1 = NULL,

View File

@ -133,6 +133,90 @@ ENTRY(generic_bs_rm_8)
2: ret
END(generic_bs_rm_8)
ENTRY(generic_bs_rr_1)
/* Is there is anything to read. */
cbz x4, 2f
/* Calculate the device address. */
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Read the data. */
1: ldrb w1, [x0], #1
strb w1, [x3], #1
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_rr_1)
ENTRY(generic_bs_rr_2)
/* Is there is anything to read. */
cbz x4, 2f
/* Calculate the device address. */
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Read the data. */
1: ldrh w1, [x0], #2
strh w1, [x3], #2
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_rr_2)
ENTRY(generic_bs_rr_4)
/* Is there is anything to read. */
cbz x4, 2f
/* Calculate the device address. */
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Read the data. */
1: ldr w1, [x0], #4
str w1, [x3], #4
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_rr_4)
ENTRY(generic_bs_rr_8)
/* Is there is anything to read. */
cbz x4, 2f
/* Calculate the device address. */
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Read the data. */
1: ldr x1, [x0], #8
str x1, [x3], #8
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_rr_8)
ENTRY(generic_bs_w_1)
strb w3, [x1, x2]
@ -233,3 +317,83 @@ ENTRY(generic_bs_wm_8)
2: ret
END(generic_bs_wm_8)
ENTRY(generic_bs_wr_1)
/* Is there is anything to write. */
cbz x4, 2f
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Write the data */
1: ldrb w1, [x3], #1
strb w1, [x0], #1
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_wr_1)
ENTRY(generic_bs_wr_2)
/* Is there is anything to write. */
cbz x4, 2f
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Write the data */
1: ldrh w1, [x3], #2
strh w1, [x0], #2
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_wr_2)
ENTRY(generic_bs_wr_4)
/* Is there is anything to write. */
cbz x4, 2f
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Write the data */
1: ldr w1, [x3], #4
str w1, [x0], #4
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_wr_4)
ENTRY(generic_bs_wr_8)
/* Is there is anything to write. */
cbz x4, 2f
add x0, x1, x2
/*
* x0 = The device address.
* x3 = The kernel address.
* x4 = Count
*/
/* Write the data */
1: ldr x1, [x3], #8
str x1, [x0], #8
subs x4, x4, #1
b.ne 1b
2: ret
END(generic_bs_wr_8)

View File

@ -104,7 +104,7 @@ __FBSDID("$FreeBSD$");
/* Read the current thread flags */
1: ldr x1, [x18, #PC_CURTHREAD] /* Load curthread */
ldr x2, [x1, #TD_FLAGS]! /* TODO: No need for the ! but clang fails without it */
ldr x2, [x1, #TD_FLAGS]
/* Check if we have either bits set */
mov x3, #((TDF_ASTPENDING|TDF_NEEDRESCHED) >> 8)

View File

@ -229,6 +229,21 @@ data_abort(struct trapframe *frame, uint64_t esr, int lower)
userret(td, frame);
}
static void
print_registers(struct trapframe *frame)
{
u_int reg;
for (reg = 0; reg < 31; reg++) {
printf(" %sx%d: %16lx\n", (reg < 10) ? " " : "", reg,
frame->tf_x[reg]);
}
printf(" sp: %16lx\n", frame->tf_sp);
printf(" lr: %16lx\n", frame->tf_lr);
printf(" elr: %16lx\n", frame->tf_elr);
printf("spsr: %16lx\n", frame->tf_spsr);
}
void
do_el1h_sync(struct trapframe *frame)
{
@ -265,6 +280,7 @@ do_el1h_sync(struct trapframe *frame)
switch(exception) {
case EXCP_FP_SIMD:
case EXCP_TRAP_FP:
print_registers(frame);
panic("VFP exception in the kernel");
case EXCP_DATA_ABORT:
data_abort(frame, esr, 0);
@ -286,11 +302,30 @@ do_el1h_sync(struct trapframe *frame)
#endif
break;
default:
print_registers(frame);
panic("Unknown kernel exception %x esr_el1 %lx\n", exception,
esr);
}
}
/*
* We get EXCP_UNKNOWN from QEMU when executing zeroed memory. For now turn
* this into a SIGILL.
*/
static void
el0_excp_unknown(struct trapframe *frame)
{
struct thread *td;
uint64_t far;
td = curthread;
far = READ_SPECIALREG(far_el1);
printf("el0 EXCP_UNKNOWN exception\n");
print_registers(frame);
call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far);
userret(td, frame);
}
void
do_el0_sync(struct trapframe *frame)
{
@ -332,7 +367,11 @@ do_el0_sync(struct trapframe *frame)
case EXCP_DATA_ABORT:
data_abort(frame, esr, 1);
break;
case EXCP_UNKNOWN:
el0_excp_unknown(frame);
break;
default:
print_registers(frame);
panic("Unknown userland exception %x esr_el1 %lx\n", exception,
esr);
}

View File

@ -43,7 +43,8 @@
#define M_USBDEV 0
#define USB_PROC_MAX 3
#define USB_BUS_GIANT_PROC(bus) (usb_process + 2)
#define USB_BUS_NON_GIANT_PROC(bus) (usb_process + 2)
#define USB_BUS_NON_GIANT_BULK_PROC(bus) (usb_process + 2)
#define USB_BUS_NON_GIANT_ISOC_PROC(bus) (usb_process + 2)
#define USB_BUS_EXPLORE_PROC(bus) (usb_process + 0)
#define USB_BUS_CONTROL_XFER_PROC(bus) (usb_process + 1)
#define SYSCTL_DECL(...)

View File

@ -69,10 +69,11 @@ fdt_platform_load_dtb(void)
}
/*
* If the U-boot environment contains a variable giving the name of a
* file, use it if we can load and validate it.
* Try to get FDT filename first from loader env and then from u-boot env
*/
s = ub_env_get("fdtfile");
s = getenv("fdt_file");
if (s == NULL)
s = ub_env_get("fdtfile");
if (s == NULL)
s = ub_env_get("fdt_file");
if (s != NULL && *s != '\0') {

View File

@ -366,16 +366,6 @@ This is a CTL frontend port that is also a CAM SIM. The idea is that this
frontend allows for using CTL without any target-capable hardware. So any
LUNs you create in CTL are visible via this port.
ctl_frontend_internal.c
ctl_frontend_internal.h:
-----------------------
This is a frontend port written for Copan to do some system-specific tasks
that required sending commands into CTL from inside the kernel. This isn't
entirely relevant to FreeBSD in general, but can perhaps be repurposed or
removed later.
ctl_ha.h:
--------

View File

@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_ioctl.h>
@ -383,18 +382,7 @@ static int ctl_init(void);
void ctl_shutdown(void);
static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td);
static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td);
static void ctl_ioctl_online(void *arg);
static void ctl_ioctl_offline(void *arg);
static int ctl_ioctl_lun_enable(void *arg, int lun_id);
static int ctl_ioctl_lun_disable(void *arg, int lun_id);
static int ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio);
static int ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio);
static int ctl_ioctl_submit_wait(union ctl_io *io);
static void ctl_ioctl_datamove(union ctl_io *io);
static void ctl_ioctl_done(union ctl_io *io);
static void ctl_ioctl_hard_startstop_callback(void *arg,
struct cfi_metatask *metatask);
static void ctl_ioctl_bbrread_callback(void *arg,struct cfi_metatask *metatask);
static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num,
struct ctl_ooa *ooa_hdr,
struct ctl_ooa_entry *kern_entries);
@ -529,11 +517,6 @@ static moduledata_t ctl_moduledata = {
DECLARE_MODULE(ctl, ctl_moduledata, SI_SUB_CONFIGURE, SI_ORDER_THIRD);
MODULE_VERSION(ctl, 1);
static struct ctl_frontend ioctl_frontend =
{
.name = "ioctl",
};
#ifdef notyet
static void
ctl_isc_handler_finish_xfer(struct ctl_softc *ctl_softc,
@ -1064,7 +1047,6 @@ ctl_init(void)
{
struct ctl_softc *softc;
void *other_pool;
struct ctl_port *port;
int i, error, retval;
//int isc_retval;
@ -1189,32 +1171,6 @@ ctl_init(void)
return (error);
}
/*
* Initialize the ioctl front end.
*/
ctl_frontend_register(&ioctl_frontend);
port = &softc->ioctl_info.port;
port->frontend = &ioctl_frontend;
sprintf(softc->ioctl_info.port_name, "ioctl");
port->port_type = CTL_PORT_IOCTL;
port->num_requested_ctl_io = 100;
port->port_name = softc->ioctl_info.port_name;
port->port_online = ctl_ioctl_online;
port->port_offline = ctl_ioctl_offline;
port->onoff_arg = &softc->ioctl_info;
port->lun_enable = ctl_ioctl_lun_enable;
port->lun_disable = ctl_ioctl_lun_disable;
port->targ_lun_arg = &softc->ioctl_info;
port->fe_datamove = ctl_ioctl_datamove;
port->fe_done = ctl_ioctl_done;
port->max_targets = 15;
port->max_target_id = 15;
if (ctl_port_register(&softc->ioctl_info.port) != 0) {
printf("ctl: ioctl front end registration failed, will "
"continue anyway\n");
}
SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree),
OID_AUTO, "ha_state", CTLTYPE_INT | CTLFLAG_RWTUN,
softc, 0, ctl_ha_state_sysctl, "I", "HA state for this head");
@ -1238,9 +1194,6 @@ ctl_shutdown(void)
softc = (struct ctl_softc *)control_softc;
if (ctl_port_deregister(&softc->ioctl_info.port) != 0)
printf("ctl: ioctl front end deregistration failed\n");
mtx_lock(&softc->ctl_lock);
/*
@ -1253,8 +1206,6 @@ ctl_shutdown(void)
mtx_unlock(&softc->ctl_lock);
ctl_frontend_deregister(&ioctl_frontend);
#if 0
ctl_shutdown_thread(softc->work_thread);
mtx_destroy(&softc->queue_lock);
@ -1426,26 +1377,6 @@ ctl_port_list(struct ctl_port_entry *entries, int num_entries_alloced,
return (retval);
}
static void
ctl_ioctl_online(void *arg)
{
struct ctl_ioctl_info *ioctl_info;
ioctl_info = (struct ctl_ioctl_info *)arg;
ioctl_info->flags |= CTL_IOCTL_FLAG_ENABLED;
}
static void
ctl_ioctl_offline(void *arg)
{
struct ctl_ioctl_info *ioctl_info;
ioctl_info = (struct ctl_ioctl_info *)arg;
ioctl_info->flags &= ~CTL_IOCTL_FLAG_ENABLED;
}
/*
* Remove an initiator by port number and initiator ID.
* Returns 0 for success, -1 for failure.
@ -1641,181 +1572,6 @@ ctl_create_iid(struct ctl_port *port, int iid, uint8_t *buf)
}
}
static int
ctl_ioctl_lun_enable(void *arg, int lun_id)
{
return (0);
}
static int
ctl_ioctl_lun_disable(void *arg, int lun_id)
{
return (0);
}
/*
* Data movement routine for the CTL ioctl frontend port.
*/
static int
ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
{
struct ctl_sg_entry *ext_sglist, *kern_sglist;
struct ctl_sg_entry ext_entry, kern_entry;
int ext_sglen, ext_sg_entries, kern_sg_entries;
int ext_sg_start, ext_offset;
int len_to_copy, len_copied;
int kern_watermark, ext_watermark;
int ext_sglist_malloced;
int i, j;
ext_sglist_malloced = 0;
ext_sg_start = 0;
ext_offset = 0;
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove\n"));
/*
* If this flag is set, fake the data transfer.
*/
if (ctsio->io_hdr.flags & CTL_FLAG_NO_DATAMOVE) {
ctsio->ext_data_filled = ctsio->ext_data_len;
goto bailout;
}
/*
* To simplify things here, if we have a single buffer, stick it in
* a S/G entry and just make it a single entry S/G list.
*/
if (ctsio->io_hdr.flags & CTL_FLAG_EDPTR_SGLIST) {
int len_seen;
ext_sglen = ctsio->ext_sg_entries * sizeof(*ext_sglist);
ext_sglist = (struct ctl_sg_entry *)malloc(ext_sglen, M_CTL,
M_WAITOK);
ext_sglist_malloced = 1;
if (copyin(ctsio->ext_data_ptr, ext_sglist,
ext_sglen) != 0) {
ctl_set_internal_failure(ctsio,
/*sks_valid*/ 0,
/*retry_count*/ 0);
goto bailout;
}
ext_sg_entries = ctsio->ext_sg_entries;
len_seen = 0;
for (i = 0; i < ext_sg_entries; i++) {
if ((len_seen + ext_sglist[i].len) >=
ctsio->ext_data_filled) {
ext_sg_start = i;
ext_offset = ctsio->ext_data_filled - len_seen;
break;
}
len_seen += ext_sglist[i].len;
}
} else {
ext_sglist = &ext_entry;
ext_sglist->addr = ctsio->ext_data_ptr;
ext_sglist->len = ctsio->ext_data_len;
ext_sg_entries = 1;
ext_sg_start = 0;
ext_offset = ctsio->ext_data_filled;
}
if (ctsio->kern_sg_entries > 0) {
kern_sglist = (struct ctl_sg_entry *)ctsio->kern_data_ptr;
kern_sg_entries = ctsio->kern_sg_entries;
} else {
kern_sglist = &kern_entry;
kern_sglist->addr = ctsio->kern_data_ptr;
kern_sglist->len = ctsio->kern_data_len;
kern_sg_entries = 1;
}
kern_watermark = 0;
ext_watermark = ext_offset;
len_copied = 0;
for (i = ext_sg_start, j = 0;
i < ext_sg_entries && j < kern_sg_entries;) {
uint8_t *ext_ptr, *kern_ptr;
len_to_copy = MIN(ext_sglist[i].len - ext_watermark,
kern_sglist[j].len - kern_watermark);
ext_ptr = (uint8_t *)ext_sglist[i].addr;
ext_ptr = ext_ptr + ext_watermark;
if (ctsio->io_hdr.flags & CTL_FLAG_BUS_ADDR) {
/*
* XXX KDM fix this!
*/
panic("need to implement bus address support");
#if 0
kern_ptr = bus_to_virt(kern_sglist[j].addr);
#endif
} else
kern_ptr = (uint8_t *)kern_sglist[j].addr;
kern_ptr = kern_ptr + kern_watermark;
kern_watermark += len_to_copy;
ext_watermark += len_to_copy;
if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) ==
CTL_FLAG_DATA_IN) {
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: copying %d "
"bytes to user\n", len_to_copy));
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: from %p "
"to %p\n", kern_ptr, ext_ptr));
if (copyout(kern_ptr, ext_ptr, len_to_copy) != 0) {
ctl_set_internal_failure(ctsio,
/*sks_valid*/ 0,
/*retry_count*/ 0);
goto bailout;
}
} else {
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: copying %d "
"bytes from user\n", len_to_copy));
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: from %p "
"to %p\n", ext_ptr, kern_ptr));
if (copyin(ext_ptr, kern_ptr, len_to_copy)!= 0){
ctl_set_internal_failure(ctsio,
/*sks_valid*/ 0,
/*retry_count*/0);
goto bailout;
}
}
len_copied += len_to_copy;
if (ext_sglist[i].len == ext_watermark) {
i++;
ext_watermark = 0;
}
if (kern_sglist[j].len == kern_watermark) {
j++;
kern_watermark = 0;
}
}
ctsio->ext_data_filled += len_copied;
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: ext_sg_entries: %d, "
"kern_sg_entries: %d\n", ext_sg_entries,
kern_sg_entries));
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: ext_data_len = %d, "
"kern_data_len = %d\n", ctsio->ext_data_len,
ctsio->kern_data_len));
/* XXX KDM set residual?? */
bailout:
if (ext_sglist_malloced != 0)
free(ext_sglist, M_CTL);
return (CTL_RETVAL_COMPLETE);
}
/*
* Serialize a command that went down the "wrong" side, and so was sent to
* this controller for execution. The logic is a little different than the
@ -1982,149 +1738,6 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
return (retval);
}
static int
ctl_ioctl_submit_wait(union ctl_io *io)
{
struct ctl_fe_ioctl_params params;
ctl_fe_ioctl_state last_state;
int done, retval;
retval = 0;
bzero(&params, sizeof(params));
mtx_init(&params.ioctl_mtx, "ctliocmtx", NULL, MTX_DEF);
cv_init(&params.sem, "ctlioccv");
params.state = CTL_IOCTL_INPROG;
last_state = params.state;
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = &params;
CTL_DEBUG_PRINT(("ctl_ioctl_submit_wait\n"));
/* This shouldn't happen */
if ((retval = ctl_queue(io)) != CTL_RETVAL_COMPLETE)
return (retval);
done = 0;
do {
mtx_lock(&params.ioctl_mtx);
/*
* Check the state here, and don't sleep if the state has
* already changed (i.e. wakeup has already occured, but we
* weren't waiting yet).
*/
if (params.state == last_state) {
/* XXX KDM cv_wait_sig instead? */
cv_wait(&params.sem, &params.ioctl_mtx);
}
last_state = params.state;
switch (params.state) {
case CTL_IOCTL_INPROG:
/* Why did we wake up? */
/* XXX KDM error here? */
mtx_unlock(&params.ioctl_mtx);
break;
case CTL_IOCTL_DATAMOVE:
CTL_DEBUG_PRINT(("got CTL_IOCTL_DATAMOVE\n"));
/*
* change last_state back to INPROG to avoid
* deadlock on subsequent data moves.
*/
params.state = last_state = CTL_IOCTL_INPROG;
mtx_unlock(&params.ioctl_mtx);
ctl_ioctl_do_datamove(&io->scsiio);
/*
* Note that in some cases, most notably writes,
* this will queue the I/O and call us back later.
* In other cases, generally reads, this routine
* will immediately call back and wake us up,
* probably using our own context.
*/
io->scsiio.be_move_done(io);
break;
case CTL_IOCTL_DONE:
mtx_unlock(&params.ioctl_mtx);
CTL_DEBUG_PRINT(("got CTL_IOCTL_DONE\n"));
done = 1;
break;
default:
mtx_unlock(&params.ioctl_mtx);
/* XXX KDM error here? */
break;
}
} while (done == 0);
mtx_destroy(&params.ioctl_mtx);
cv_destroy(&params.sem);
return (CTL_RETVAL_COMPLETE);
}
static void
ctl_ioctl_datamove(union ctl_io *io)
{
struct ctl_fe_ioctl_params *params;
params = (struct ctl_fe_ioctl_params *)
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
mtx_lock(&params->ioctl_mtx);
params->state = CTL_IOCTL_DATAMOVE;
cv_broadcast(&params->sem);
mtx_unlock(&params->ioctl_mtx);
}
static void
ctl_ioctl_done(union ctl_io *io)
{
struct ctl_fe_ioctl_params *params;
params = (struct ctl_fe_ioctl_params *)
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
mtx_lock(&params->ioctl_mtx);
params->state = CTL_IOCTL_DONE;
cv_broadcast(&params->sem);
mtx_unlock(&params->ioctl_mtx);
}
static void
ctl_ioctl_hard_startstop_callback(void *arg, struct cfi_metatask *metatask)
{
struct ctl_fe_ioctl_startstop_info *sd_info;
sd_info = (struct ctl_fe_ioctl_startstop_info *)arg;
sd_info->hs_info.status = metatask->status;
sd_info->hs_info.total_luns = metatask->taskinfo.startstop.total_luns;
sd_info->hs_info.luns_complete =
metatask->taskinfo.startstop.luns_complete;
sd_info->hs_info.luns_failed = metatask->taskinfo.startstop.luns_failed;
cv_broadcast(&sd_info->sem);
}
static void
ctl_ioctl_bbrread_callback(void *arg, struct cfi_metatask *metatask)
{
struct ctl_fe_ioctl_bbrread_info *fe_bbr_info;
fe_bbr_info = (struct ctl_fe_ioctl_bbrread_info *)arg;
mtx_lock(fe_bbr_info->lock);
fe_bbr_info->bbr_info->status = metatask->status;
fe_bbr_info->bbr_info->bbr_status = metatask->taskinfo.bbrread.status;
fe_bbr_info->wakeup_done = 1;
mtx_unlock(fe_bbr_info->lock);
cv_broadcast(&fe_bbr_info->sem);
}
/*
* Returns 0 for success, errno for failure.
*/
@ -2367,57 +1980,9 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
retval = 0;
switch (cmd) {
case CTL_IO: {
union ctl_io *io;
void *pool_tmp;
/*
* If we haven't been "enabled", don't allow any SCSI I/O
* to this FETD.
*/
if ((softc->ioctl_info.flags & CTL_IOCTL_FLAG_ENABLED) == 0) {
retval = EPERM;
break;
}
io = ctl_alloc_io(softc->ioctl_info.port.ctl_pool_ref);
/*
* Need to save the pool reference so it doesn't get
* spammed by the user's ctl_io.
*/
pool_tmp = io->io_hdr.pool;
memcpy(io, (void *)addr, sizeof(*io));
io->io_hdr.pool = pool_tmp;
/*
* No status yet, so make sure the status is set properly.
*/
io->io_hdr.status = CTL_STATUS_NONE;
/*
* The user sets the initiator ID, target and LUN IDs.
*/
io->io_hdr.nexus.targ_port = softc->ioctl_info.port.targ_port;
io->io_hdr.flags |= CTL_FLAG_USER_REQ;
if ((io->io_hdr.io_type == CTL_IO_SCSI)
&& (io->scsiio.tag_type != CTL_TAG_UNTAGGED))
io->scsiio.tag_num = softc->ioctl_info.cur_tag_num++;
retval = ctl_ioctl_submit_wait(io);
if (retval != 0) {
ctl_free_io(io);
break;
}
memcpy((void *)addr, io, sizeof(*io));
/* return this to our pool */
ctl_free_io(io);
case CTL_IO:
retval = ctl_ioctl_io(dev, cmd, addr, flag, td);
break;
}
case CTL_ENABLE_PORT:
case CTL_DISABLE_PORT:
case CTL_SET_PORT_WWNS: {
@ -2724,103 +2289,6 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
break;
}
case CTL_HARD_START:
case CTL_HARD_STOP: {
struct ctl_fe_ioctl_startstop_info ss_info;
struct cfi_metatask *metatask;
struct mtx hs_mtx;
mtx_init(&hs_mtx, "HS Mutex", NULL, MTX_DEF);
cv_init(&ss_info.sem, "hard start/stop cv" );
metatask = cfi_alloc_metatask(/*can_wait*/ 1);
if (metatask == NULL) {
retval = ENOMEM;
mtx_destroy(&hs_mtx);
break;
}
if (cmd == CTL_HARD_START)
metatask->tasktype = CFI_TASK_STARTUP;
else
metatask->tasktype = CFI_TASK_SHUTDOWN;
metatask->callback = ctl_ioctl_hard_startstop_callback;
metatask->callback_arg = &ss_info;
cfi_action(metatask);
/* Wait for the callback */
mtx_lock(&hs_mtx);
cv_wait_sig(&ss_info.sem, &hs_mtx);
mtx_unlock(&hs_mtx);
/*
* All information has been copied from the metatask by the
* time cv_broadcast() is called, so we free the metatask here.
*/
cfi_free_metatask(metatask);
memcpy((void *)addr, &ss_info.hs_info, sizeof(ss_info.hs_info));
mtx_destroy(&hs_mtx);
break;
}
case CTL_BBRREAD: {
struct ctl_bbrread_info *bbr_info;
struct ctl_fe_ioctl_bbrread_info fe_bbr_info;
struct mtx bbr_mtx;
struct cfi_metatask *metatask;
bbr_info = (struct ctl_bbrread_info *)addr;
bzero(&fe_bbr_info, sizeof(fe_bbr_info));
bzero(&bbr_mtx, sizeof(bbr_mtx));
mtx_init(&bbr_mtx, "BBR Mutex", NULL, MTX_DEF);
fe_bbr_info.bbr_info = bbr_info;
fe_bbr_info.lock = &bbr_mtx;
cv_init(&fe_bbr_info.sem, "BBR read cv");
metatask = cfi_alloc_metatask(/*can_wait*/ 1);
if (metatask == NULL) {
mtx_destroy(&bbr_mtx);
cv_destroy(&fe_bbr_info.sem);
retval = ENOMEM;
break;
}
metatask->tasktype = CFI_TASK_BBRREAD;
metatask->callback = ctl_ioctl_bbrread_callback;
metatask->callback_arg = &fe_bbr_info;
metatask->taskinfo.bbrread.lun_num = bbr_info->lun_num;
metatask->taskinfo.bbrread.lba = bbr_info->lba;
metatask->taskinfo.bbrread.len = bbr_info->len;
cfi_action(metatask);
mtx_lock(&bbr_mtx);
while (fe_bbr_info.wakeup_done == 0)
cv_wait_sig(&fe_bbr_info.sem, &bbr_mtx);
mtx_unlock(&bbr_mtx);
bbr_info->status = metatask->status;
bbr_info->bbr_status = metatask->taskinfo.bbrread.status;
bbr_info->scsi_status = metatask->taskinfo.bbrread.scsi_status;
memcpy(&bbr_info->sense_data,
&metatask->taskinfo.bbrread.sense_data,
MIN(sizeof(bbr_info->sense_data),
sizeof(metatask->taskinfo.bbrread.sense_data)));
cfi_free_metatask(metatask);
mtx_destroy(&bbr_mtx);
cv_destroy(&fe_bbr_info.sem);
break;
}
case CTL_DELAY_IO: {
struct ctl_io_delay_info *delay_info;
#ifdef CTL_IO_DELAY

View File

@ -194,6 +194,8 @@ void ctl_portDB_changed(int portnum);
#ifdef notyet
void ctl_init_isc_msg(void);
#endif
int ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
/*
* KPI to manipulate LUN/port options

View File

@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_ioctl.h>
#include <cam/ctl/ctl_ha.h>
#include <cam/ctl/ctl_private.h>

View File

@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_ioctl.h>
#include <cam/ctl/ctl_scsi_all.h>
#include <cam/ctl/ctl_error.h>
@ -170,7 +169,6 @@ struct ctl_be_block_lun {
uint64_t size_blocks;
uint64_t size_bytes;
uint32_t blocksize;
int blocksize_shift;
uint16_t pblockexp;
uint16_t pblockoff;
uint16_t ublockexp;
@ -773,7 +771,7 @@ ctl_be_block_gls_file(struct ctl_be_block_lun *be_lun,
DPRINTF("entered\n");
off = roff = ((off_t)lbalen->lba) << be_lun->blocksize_shift;
off = roff = ((off_t)lbalen->lba) * be_lun->blocksize;
vn_lock(be_lun->vn, LK_SHARED | LK_RETRY);
error = VOP_IOCTL(be_lun->vn, FIOSEEKHOLE, &off,
0, curthread->td_ucred, curthread);
@ -791,10 +789,9 @@ ctl_be_block_gls_file(struct ctl_be_block_lun *be_lun,
}
VOP_UNLOCK(be_lun->vn, 0);
off >>= be_lun->blocksize_shift;
data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr;
scsi_u64to8b(lbalen->lba, data->descr[0].addr);
scsi_ulto4b(MIN(UINT32_MAX, off - lbalen->lba),
scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->blocksize - lbalen->lba),
data->descr[0].length);
data->descr[0].status = status;
@ -816,14 +813,14 @@ ctl_be_block_getattr_file(struct ctl_be_block_lun *be_lun, const char *attrname)
if (strcmp(attrname, "blocksused") == 0) {
error = VOP_GETATTR(be_lun->vn, &vattr, curthread->td_ucred);
if (error == 0)
val = vattr.va_bytes >> be_lun->blocksize_shift;
val = vattr.va_bytes / be_lun->blocksize;
}
if (strcmp(attrname, "blocksavail") == 0 &&
(be_lun->vn->v_iflag & VI_DOOMED) == 0) {
error = VFS_STATFS(be_lun->vn->v_mount, &statfs);
if (error == 0)
val = (statfs.f_bavail * statfs.f_bsize) >>
be_lun->blocksize_shift;
val = statfs.f_bavail * statfs.f_bsize /
be_lun->blocksize;
}
VOP_UNLOCK(be_lun->vn, 0);
return (val);
@ -934,7 +931,7 @@ ctl_be_block_gls_zvol(struct ctl_be_block_lun *be_lun,
DPRINTF("entered\n");
off = roff = ((off_t)lbalen->lba) << be_lun->blocksize_shift;
off = roff = ((off_t)lbalen->lba) * be_lun->blocksize;
error = (*dev_data->csw->d_ioctl)(dev_data->cdev, FIOSEEKHOLE,
(caddr_t)&off, FREAD, curthread);
if (error == 0 && off > roff)
@ -950,10 +947,9 @@ ctl_be_block_gls_zvol(struct ctl_be_block_lun *be_lun,
}
}
off >>= be_lun->blocksize_shift;
data = (struct scsi_get_lba_status_data *)io->scsiio.kern_data_ptr;
scsi_u64to8b(lbalen->lba, data->descr[0].addr);
scsi_ulto4b(MIN(UINT32_MAX, off - lbalen->lba),
scsi_ulto4b(MIN(UINT32_MAX, off / be_lun->blocksize - lbalen->lba),
data->descr[0].length);
data->descr[0].status = status;
@ -1866,7 +1862,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
struct cdevsw *devsw;
char *value;
int error, atomic, maxio, unmap;
off_t ps, pss, po, pos, us, uss, uo, uos;
off_t ps, pss, po, pos, us, uss, uo, uos, tmp;
params = &be_lun->params;
@ -1909,8 +1905,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
return (ENODEV);
}
error = devsw->d_ioctl(dev, DIOCGSECTORSIZE,
(caddr_t)&be_lun->blocksize, FREAD,
error = devsw->d_ioctl(dev, DIOCGSECTORSIZE, (caddr_t)&tmp, FREAD,
curthread);
if (error) {
snprintf(req->error_str, sizeof(req->error_str),
@ -1925,15 +1920,9 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
* the user is asking for is an even multiple of the underlying
* device's blocksize.
*/
if ((params->blocksize_bytes != 0)
&& (params->blocksize_bytes > be_lun->blocksize)) {
uint32_t bs_multiple, tmp_blocksize;
bs_multiple = params->blocksize_bytes / be_lun->blocksize;
tmp_blocksize = bs_multiple * be_lun->blocksize;
if (tmp_blocksize == params->blocksize_bytes) {
if ((params->blocksize_bytes != 0) &&
(params->blocksize_bytes >= tmp)) {
if (params->blocksize_bytes % tmp == 0) {
be_lun->blocksize = params->blocksize_bytes;
} else {
snprintf(req->error_str, sizeof(req->error_str),
@ -1944,17 +1933,16 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
return (EINVAL);
}
} else if ((params->blocksize_bytes != 0)
&& (params->blocksize_bytes != be_lun->blocksize)) {
} else if (params->blocksize_bytes != 0) {
snprintf(req->error_str, sizeof(req->error_str),
"requested blocksize %u < backing device "
"blocksize %u", params->blocksize_bytes,
be_lun->blocksize);
return (EINVAL);
}
} else
be_lun->blocksize = tmp;
error = devsw->d_ioctl(dev, DIOCGMEDIASIZE,
(caddr_t)&be_lun->size_bytes, FREAD,
error = devsw->d_ioctl(dev, DIOCGMEDIASIZE, (caddr_t)&tmp, FREAD,
curthread);
if (error) {
snprintf(req->error_str, sizeof(req->error_str),
@ -1965,7 +1953,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
}
if (params->lun_size_bytes != 0) {
if (params->lun_size_bytes > be_lun->size_bytes) {
if (params->lun_size_bytes > tmp) {
snprintf(req->error_str, sizeof(req->error_str),
"requested LUN size %ju > backing device "
"size %ju",
@ -1975,7 +1963,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
}
be_lun->size_bytes = params->lun_size_bytes;
}
} else
be_lun->size_bytes = tmp;
error = devsw->d_ioctl(dev, DIOCGSTRIPESIZE,
(caddr_t)&ps, FREAD, curthread);
@ -2160,14 +2149,8 @@ ctl_be_block_open(struct ctl_be_block_softc *softc,
}
VOP_UNLOCK(be_lun->vn, 0);
if (error != 0) {
if (error != 0)
ctl_be_block_close(be_lun);
return (error);
}
be_lun->blocksize_shift = fls(be_lun->blocksize) - 1;
be_lun->size_blocks = be_lun->size_bytes >> be_lun->blocksize_shift;
return (0);
}
@ -2224,10 +2207,14 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
goto bailout_error;
}
be_lun->dev_path = strdup(value, M_CTLBLK);
be_lun->blocksize = 512;
be_lun->blocksize_shift = fls(be_lun->blocksize) - 1;
be_lun->size_bytes = params->lun_size_bytes;
if (params->blocksize_bytes != 0)
be_lun->blocksize = params->blocksize_bytes;
else
be_lun->blocksize = 512;
retval = ctl_be_block_open(softc, be_lun, req);
be_lun->size_blocks = be_lun->size_bytes / be_lun->blocksize;
if (retval != 0) {
retval = 0;
req->status = CTL_LUN_WARNING;
@ -2652,10 +2639,9 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
error = ctl_be_block_modify_file(be_lun, req);
else
error = EINVAL;
be_lun->size_blocks = be_lun->size_bytes / be_lun->blocksize;
if (error == 0 && be_lun->size_bytes != oldsize) {
be_lun->size_blocks = be_lun->size_bytes >>
be_lun->blocksize_shift;
/*
* The maximum LBA is the size - 1.

View File

@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_debug.h>
#include <cam/ctl/ctl_ioctl.h>
#include <cam/ctl/ctl_error.h>

View File

@ -52,7 +52,6 @@
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_ioctl.h>
#include <cam/ctl/ctl_ha.h>
#include <cam/ctl/ctl_private.h>

View File

@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_ioctl.h>
#include <cam/ctl/ctl_error.h>

View File

@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_backend.h>
/* XXX KDM move defines from ctl_ioctl.h to somewhere else */
#include <cam/ctl/ctl_ioctl.h>

View File

@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_debug.h>
#define io_ptr spriv_ptr1

File diff suppressed because it is too large Load Diff

View File

@ -1,154 +0,0 @@
/*-
* Copyright (c) 2004 Silicon Graphics International Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions, and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* substantially similar to the "NO WARRANTY" disclaimer below
* ("Disclaimer") and any redistribution must be conditioned upon
* including a substantially similar Disclaimer requirement for further
* binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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 DAMAGES.
*
* $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_frontend_internal.h#1 $
* $FreeBSD$
*/
/*
* CTL kernel internal frontend target driver. This allows kernel-level
* clients to send commands into CTL.
*
* Author: Ken Merry <ken@FreeBSD.org>
*/
#ifndef _CTL_FRONTEND_INTERNAL_H_
#define _CTL_FRONTEND_INTERNAL_H_
/*
* These are general metatask error codes. If the error code is CFI_MT_ERROR,
* check any metatask-specific status codes for more detail on the problem.
*/
typedef enum {
CFI_MT_NONE,
CFI_MT_PORT_OFFLINE,
CFI_MT_ERROR,
CFI_MT_SUCCESS
} cfi_mt_status;
typedef enum {
CFI_TASK_NONE,
CFI_TASK_SHUTDOWN,
CFI_TASK_STARTUP,
CFI_TASK_BBRREAD
} cfi_tasktype;
struct cfi_task_startstop {
int total_luns;
int luns_complete;
int luns_failed;
};
/*
* Error code description:
* CFI_BBR_SUCCESS - the read was successful
* CFI_BBR_LUN_UNCONFIG - CFI probe for this lun hasn't completed
* CFI_BBR_NO_LUN - this lun doesn't exist, as far as CFI knows
* CFI_BBR_NO_MEM - memory allocation error
* CFI_BBR_BAD_LEN - data length isn't a multiple of the blocksize
* CFI_BBR_RESERV_CONFLICT - another initiator has this lun reserved, so
* we can't issue I/O at all.
* CFI_BBR_LUN_STOPPED - the lun is powered off.
* CFI_BBR_LUN_OFFLINE_CTL - the lun is offline from a CTL standpoint
* CFI_BBR_LUN_OFFLINE_RC - the lun is offline from a RAIDCore standpoint.
* This is bad, because it basically means we've
* had a double failure on the LUN.
* CFI_BBR_SCSI_ERROR - generic SCSI error, see status byte and sense
* data for more resolution if you want it.
* CFI_BBR_ERROR - the catch-all error code.
*/
typedef enum {
CFI_BBR_SUCCESS,
CFI_BBR_LUN_UNCONFIG,
CFI_BBR_NO_LUN,
CFI_BBR_NO_MEM,
CFI_BBR_BAD_LEN,
CFI_BBR_RESERV_CONFLICT,
CFI_BBR_LUN_STOPPED,
CFI_BBR_LUN_OFFLINE_CTL,
CFI_BBR_LUN_OFFLINE_RC,
CFI_BBR_SCSI_ERROR,
CFI_BBR_ERROR,
} cfi_bbrread_status;
struct cfi_task_bbrread {
int lun_num; /* lun number */
uint64_t lba; /* logical block address */
int len; /* length in bytes */
cfi_bbrread_status status; /* BBR status */
uint8_t scsi_status; /* SCSI status */
struct scsi_sense_data sense_data; /* SCSI sense data */
};
union cfi_taskinfo {
struct cfi_task_startstop startstop;
struct cfi_task_bbrread bbrread;
};
struct cfi_metatask;
typedef void (*cfi_cb_t)(void *arg, struct cfi_metatask *metatask);
struct cfi_metatask {
cfi_tasktype tasktype; /* passed to CFI */
cfi_mt_status status; /* returned from CFI */
union cfi_taskinfo taskinfo; /* returned from CFI */
struct ctl_mem_element *element; /* used by CFI, don't touch*/
cfi_cb_t callback; /* passed to CFI */
void *callback_arg; /* passed to CFI */
STAILQ_ENTRY(cfi_metatask) links; /* used by CFI, don't touch*/
};
#ifdef _KERNEL
MALLOC_DECLARE(M_CTL_CFI);
/*
* This is the API for sending meta commands (commands that are sent to more
* than one LUN) to the internal frontend:
* - Allocate a metatask using cfi_alloc_metatask(). can_wait == 0 means
* that you're calling from an interrupt context. can_wait == 1 means
* that you're calling from a thread context and don't mind waiting to
* allocate memory.
* - Setup the task type, callback and callback argument.
* - Call cfi_action().
* - When the callback comes, note the status and any per-command status
* (see the taskinfo union) and then free the metatask with
* cfi_free_metatask().
*/
struct cfi_metatask *cfi_alloc_metatask(int can_wait);
void cfi_free_metatask(struct cfi_metatask *metatask);
void cfi_action(struct cfi_metatask *metatask);
#endif /* _KERNEL */
#endif /* _CTL_FRONTEND_INTERNAL_H_ */
/*
* vim: ts=8
*/

View File

@ -0,0 +1,470 @@
/*-
* Copyright (c) 2003-2009 Silicon Graphics International Corp.
* Copyright (c) 2012 The FreeBSD Foundation
* Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification, immediately at the beginning of the file.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/types.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/condvar.h>
#include <sys/malloc.h>
#include <sys/conf.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <cam/cam.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_da.h>
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_ioctl.h>
#include <cam/ctl/ctl_ha.h>
#include <cam/ctl/ctl_private.h>
#include <cam/ctl/ctl_debug.h>
#include <cam/ctl/ctl_error.h>
struct cfi_softc {
uint32_t cur_tag_num;
struct ctl_port port;
};
static struct cfi_softc cfi_softc;
static int cfi_init(void);
static void cfi_shutdown(void);
static void cfi_online(void *arg);
static void cfi_offline(void *arg);
static int cfi_lun_enable(void *arg, int lun_id);
static int cfi_lun_disable(void *arg, int lun_id);
static void cfi_datamove(union ctl_io *io);
static void cfi_done(union ctl_io *io);
static struct ctl_frontend cfi_frontend =
{
.name = "ioctl",
.init = cfi_init,
.shutdown = cfi_shutdown,
};
CTL_FRONTEND_DECLARE(ctlioctl, cfi_frontend);
static int
cfi_init(void)
{
struct cfi_softc *isoftc = &cfi_softc;
struct ctl_port *port;
memset(isoftc, 0, sizeof(*isoftc));
port = &isoftc->port;
port->frontend = &cfi_frontend;
port->port_type = CTL_PORT_IOCTL;
port->num_requested_ctl_io = 100;
port->port_name = "ioctl";
port->port_online = cfi_online;
port->port_offline = cfi_offline;
port->onoff_arg = &isoftc;
port->lun_enable = cfi_lun_enable;
port->lun_disable = cfi_lun_disable;
port->targ_lun_arg = &isoftc;
port->fe_datamove = cfi_datamove;
port->fe_done = cfi_done;
port->max_targets = 1;
port->max_target_id = 0;
port->max_initiators = 1;
if (ctl_port_register(port) != 0) {
printf("%s: ioctl port registration failed\n", __func__);
return (0);
}
ctl_port_online(port);
return (0);
}
void
cfi_shutdown(void)
{
struct cfi_softc *isoftc = &cfi_softc;
struct ctl_port *port;
port = &isoftc->port;
ctl_port_offline(port);
if (ctl_port_deregister(&isoftc->port) != 0)
printf("%s: ctl_frontend_deregister() failed\n", __func__);
}
static void
cfi_online(void *arg)
{
}
static void
cfi_offline(void *arg)
{
}
static int
cfi_lun_enable(void *arg, int lun_id)
{
return (0);
}
static int
cfi_lun_disable(void *arg, int lun_id)
{
return (0);
}
/*
* Data movement routine for the CTL ioctl frontend port.
*/
static int
ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
{
struct ctl_sg_entry *ext_sglist, *kern_sglist;
struct ctl_sg_entry ext_entry, kern_entry;
int ext_sglen, ext_sg_entries, kern_sg_entries;
int ext_sg_start, ext_offset;
int len_to_copy, len_copied;
int kern_watermark, ext_watermark;
int ext_sglist_malloced;
int i, j;
ext_sglist_malloced = 0;
ext_sg_start = 0;
ext_offset = 0;
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove\n"));
/*
* If this flag is set, fake the data transfer.
*/
if (ctsio->io_hdr.flags & CTL_FLAG_NO_DATAMOVE) {
ctsio->ext_data_filled = ctsio->ext_data_len;
goto bailout;
}
/*
* To simplify things here, if we have a single buffer, stick it in
* a S/G entry and just make it a single entry S/G list.
*/
if (ctsio->io_hdr.flags & CTL_FLAG_EDPTR_SGLIST) {
int len_seen;
ext_sglen = ctsio->ext_sg_entries * sizeof(*ext_sglist);
ext_sglist = (struct ctl_sg_entry *)malloc(ext_sglen, M_CTL,
M_WAITOK);
ext_sglist_malloced = 1;
if (copyin(ctsio->ext_data_ptr, ext_sglist,
ext_sglen) != 0) {
ctl_set_internal_failure(ctsio,
/*sks_valid*/ 0,
/*retry_count*/ 0);
goto bailout;
}
ext_sg_entries = ctsio->ext_sg_entries;
len_seen = 0;
for (i = 0; i < ext_sg_entries; i++) {
if ((len_seen + ext_sglist[i].len) >=
ctsio->ext_data_filled) {
ext_sg_start = i;
ext_offset = ctsio->ext_data_filled - len_seen;
break;
}
len_seen += ext_sglist[i].len;
}
} else {
ext_sglist = &ext_entry;
ext_sglist->addr = ctsio->ext_data_ptr;
ext_sglist->len = ctsio->ext_data_len;
ext_sg_entries = 1;
ext_sg_start = 0;
ext_offset = ctsio->ext_data_filled;
}
if (ctsio->kern_sg_entries > 0) {
kern_sglist = (struct ctl_sg_entry *)ctsio->kern_data_ptr;
kern_sg_entries = ctsio->kern_sg_entries;
} else {
kern_sglist = &kern_entry;
kern_sglist->addr = ctsio->kern_data_ptr;
kern_sglist->len = ctsio->kern_data_len;
kern_sg_entries = 1;
}
kern_watermark = 0;
ext_watermark = ext_offset;
len_copied = 0;
for (i = ext_sg_start, j = 0;
i < ext_sg_entries && j < kern_sg_entries;) {
uint8_t *ext_ptr, *kern_ptr;
len_to_copy = MIN(ext_sglist[i].len - ext_watermark,
kern_sglist[j].len - kern_watermark);
ext_ptr = (uint8_t *)ext_sglist[i].addr;
ext_ptr = ext_ptr + ext_watermark;
if (ctsio->io_hdr.flags & CTL_FLAG_BUS_ADDR) {
/*
* XXX KDM fix this!
*/
panic("need to implement bus address support");
#if 0
kern_ptr = bus_to_virt(kern_sglist[j].addr);
#endif
} else
kern_ptr = (uint8_t *)kern_sglist[j].addr;
kern_ptr = kern_ptr + kern_watermark;
kern_watermark += len_to_copy;
ext_watermark += len_to_copy;
if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) ==
CTL_FLAG_DATA_IN) {
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: copying %d "
"bytes to user\n", len_to_copy));
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: from %p "
"to %p\n", kern_ptr, ext_ptr));
if (copyout(kern_ptr, ext_ptr, len_to_copy) != 0) {
ctl_set_internal_failure(ctsio,
/*sks_valid*/ 0,
/*retry_count*/ 0);
goto bailout;
}
} else {
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: copying %d "
"bytes from user\n", len_to_copy));
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: from %p "
"to %p\n", ext_ptr, kern_ptr));
if (copyin(ext_ptr, kern_ptr, len_to_copy)!= 0){
ctl_set_internal_failure(ctsio,
/*sks_valid*/ 0,
/*retry_count*/0);
goto bailout;
}
}
len_copied += len_to_copy;
if (ext_sglist[i].len == ext_watermark) {
i++;
ext_watermark = 0;
}
if (kern_sglist[j].len == kern_watermark) {
j++;
kern_watermark = 0;
}
}
ctsio->ext_data_filled += len_copied;
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: ext_sg_entries: %d, "
"kern_sg_entries: %d\n", ext_sg_entries,
kern_sg_entries));
CTL_DEBUG_PRINT(("ctl_ioctl_do_datamove: ext_data_len = %d, "
"kern_data_len = %d\n", ctsio->ext_data_len,
ctsio->kern_data_len));
/* XXX KDM set residual?? */
bailout:
if (ext_sglist_malloced != 0)
free(ext_sglist, M_CTL);
return (CTL_RETVAL_COMPLETE);
}
static void
cfi_datamove(union ctl_io *io)
{
struct ctl_fe_ioctl_params *params;
params = (struct ctl_fe_ioctl_params *)
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
mtx_lock(&params->ioctl_mtx);
params->state = CTL_IOCTL_DATAMOVE;
cv_broadcast(&params->sem);
mtx_unlock(&params->ioctl_mtx);
}
static void
cfi_done(union ctl_io *io)
{
struct ctl_fe_ioctl_params *params;
params = (struct ctl_fe_ioctl_params *)
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
mtx_lock(&params->ioctl_mtx);
params->state = CTL_IOCTL_DONE;
cv_broadcast(&params->sem);
mtx_unlock(&params->ioctl_mtx);
}
static int
cfi_submit_wait(union ctl_io *io)
{
struct ctl_fe_ioctl_params params;
ctl_fe_ioctl_state last_state;
int done, retval;
retval = 0;
bzero(&params, sizeof(params));
mtx_init(&params.ioctl_mtx, "ctliocmtx", NULL, MTX_DEF);
cv_init(&params.sem, "ctlioccv");
params.state = CTL_IOCTL_INPROG;
last_state = params.state;
io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = &params;
CTL_DEBUG_PRINT(("cfi_submit_wait\n"));
/* This shouldn't happen */
if ((retval = ctl_queue(io)) != CTL_RETVAL_COMPLETE)
return (retval);
done = 0;
do {
mtx_lock(&params.ioctl_mtx);
/*
* Check the state here, and don't sleep if the state has
* already changed (i.e. wakeup has already occured, but we
* weren't waiting yet).
*/
if (params.state == last_state) {
/* XXX KDM cv_wait_sig instead? */
cv_wait(&params.sem, &params.ioctl_mtx);
}
last_state = params.state;
switch (params.state) {
case CTL_IOCTL_INPROG:
/* Why did we wake up? */
/* XXX KDM error here? */
mtx_unlock(&params.ioctl_mtx);
break;
case CTL_IOCTL_DATAMOVE:
CTL_DEBUG_PRINT(("got CTL_IOCTL_DATAMOVE\n"));
/*
* change last_state back to INPROG to avoid
* deadlock on subsequent data moves.
*/
params.state = last_state = CTL_IOCTL_INPROG;
mtx_unlock(&params.ioctl_mtx);
ctl_ioctl_do_datamove(&io->scsiio);
/*
* Note that in some cases, most notably writes,
* this will queue the I/O and call us back later.
* In other cases, generally reads, this routine
* will immediately call back and wake us up,
* probably using our own context.
*/
io->scsiio.be_move_done(io);
break;
case CTL_IOCTL_DONE:
mtx_unlock(&params.ioctl_mtx);
CTL_DEBUG_PRINT(("got CTL_IOCTL_DONE\n"));
done = 1;
break;
default:
mtx_unlock(&params.ioctl_mtx);
/* XXX KDM error here? */
break;
}
} while (done == 0);
mtx_destroy(&params.ioctl_mtx);
cv_destroy(&params.sem);
return (CTL_RETVAL_COMPLETE);
}
int
ctl_ioctl_io(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td)
{
union ctl_io *io;
void *pool_tmp;
int retval = 0;
/*
* If we haven't been "enabled", don't allow any SCSI I/O
* to this FETD.
*/
if ((cfi_softc.port.status & CTL_PORT_STATUS_ONLINE) == 0)
return (EPERM);
io = ctl_alloc_io(cfi_softc.port.ctl_pool_ref);
/*
* Need to save the pool reference so it doesn't get
* spammed by the user's ctl_io.
*/
pool_tmp = io->io_hdr.pool;
memcpy(io, (void *)addr, sizeof(*io));
io->io_hdr.pool = pool_tmp;
/*
* No status yet, so make sure the status is set properly.
*/
io->io_hdr.status = CTL_STATUS_NONE;
/*
* The user sets the initiator ID, target and LUN IDs.
*/
io->io_hdr.nexus.targ_port = cfi_softc.port.targ_port;
io->io_hdr.flags |= CTL_FLAG_USER_REQ;
if ((io->io_hdr.io_type == CTL_IO_SCSI) &&
(io->scsiio.tag_type != CTL_TAG_UNTAGGED))
io->scsiio.tag_num = cfi_softc.cur_tag_num++;
retval = cfi_submit_wait(io);
if (retval == 0)
memcpy((void *)addr, io, sizeof(*io));
ctl_free_io(io);
return (retval);
}

View File

@ -61,7 +61,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_error.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_debug.h>
#include <cam/ctl/ctl_ha.h>
#include <cam/ctl/ctl_ioctl.h>

View File

@ -92,23 +92,6 @@ struct ctl_ooa_info {
ctl_ooa_status status; /* Returned from CTL */
};
struct ctl_hard_startstop_info {
cfi_mt_status status;
int total_luns;
int luns_complete;
int luns_failed;
};
struct ctl_bbrread_info {
int lun_num; /* Passed in to CTL */
uint64_t lba; /* Passed in to CTL */
int len; /* Passed in to CTL */
cfi_mt_status status; /* Returned from CTL */
cfi_bbrread_status bbr_status; /* Returned from CTL */
uint8_t scsi_status; /* Returned from CTL */
struct scsi_sense_data sense_data; /* Returned from CTL */
};
typedef enum {
CTL_DELAY_TYPE_NONE,
CTL_DELAY_TYPE_CONT,
@ -828,10 +811,6 @@ struct ctl_lun_map {
#define CTL_DISABLE_PORT _IOW(CTL_MINOR, 0x05, struct ctl_port_entry)
#define CTL_DUMP_OOA _IO(CTL_MINOR, 0x06)
#define CTL_CHECK_OOA _IOWR(CTL_MINOR, 0x07, struct ctl_ooa_info)
#define CTL_HARD_STOP _IOR(CTL_MINOR, 0x08, \
struct ctl_hard_startstop_info)
#define CTL_HARD_START _IOR(CTL_MINOR, 0x09, \
struct ctl_hard_startstop_info)
#define CTL_DELAY_IO _IOWR(CTL_MINOR, 0x10, struct ctl_io_delay_info)
#define CTL_REALSYNC_GET _IOR(CTL_MINOR, 0x11, int)
#define CTL_REALSYNC_SET _IOW(CTL_MINOR, 0x12, int)
@ -839,7 +818,6 @@ struct ctl_lun_map {
#define CTL_GETSYNC _IOWR(CTL_MINOR, 0x14, struct ctl_sync_info)
#define CTL_GETSTATS _IOWR(CTL_MINOR, 0x15, struct ctl_stats)
#define CTL_ERROR_INJECT _IOWR(CTL_MINOR, 0x16, struct ctl_error_desc)
#define CTL_BBRREAD _IOWR(CTL_MINOR, 0x17, struct ctl_bbrread_info)
#define CTL_GET_OOA _IOWR(CTL_MINOR, 0x18, struct ctl_ooa)
#define CTL_DUMP_STRUCTS _IO(CTL_MINOR, 0x19)
#define CTL_GET_PORT_LIST _IOWR(CTL_MINOR, 0x20, struct ctl_port_list)

View File

@ -47,18 +47,6 @@
#define CTL_PROCESSOR_PRODUCT "CTLPROCESSOR "
#define CTL_UNKNOWN_PRODUCT "CTLDEVICE "
struct ctl_fe_ioctl_startstop_info {
struct cv sem;
struct ctl_hard_startstop_info hs_info;
};
struct ctl_fe_ioctl_bbrread_info {
struct cv sem;
struct ctl_bbrread_info *bbr_info;
int wakeup_done;
struct mtx *lock;
};
typedef enum {
CTL_IOCTL_INPROG,
CTL_IOCTL_DATAMOVE,
@ -80,18 +68,6 @@ struct ctl_io_pool {
struct uma_zone *zone;
};
typedef enum {
CTL_IOCTL_FLAG_NONE = 0x00,
CTL_IOCTL_FLAG_ENABLED = 0x01
} ctl_ioctl_flags;
struct ctl_ioctl_info {
ctl_ioctl_flags flags;
uint32_t cur_tag_num;
struct ctl_port port;
char port_name[24];
};
typedef enum {
CTL_SER_BLOCK,
CTL_SER_BLOCKOPT,
@ -472,7 +448,6 @@ struct ctl_softc {
int inquiry_pq_no_lun;
struct sysctl_ctx_list sysctl_ctx;
struct sysctl_oid *sysctl_tree;
struct ctl_ioctl_info ioctl_info;
void *othersc_pool;
struct proc *ctl_proc;
int targ_online;

View File

@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_ioctl.h>

View File

@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <cam/ctl/ctl_io.h>
#include <cam/ctl/ctl.h>
#include <cam/ctl/ctl_frontend.h>
#include <cam/ctl/ctl_frontend_internal.h>
#include <cam/ctl/ctl_util.h>
#include <cam/ctl/ctl_backend.h>
#include <cam/ctl/ctl_ioctl.h>

View File

@ -42,29 +42,19 @@
*/
#define nvlist_add_binary illumos_nvlist_add_binary
#define nvlist_add_bool illumos_nvlist_add_bool
#define nvlist_add_bool_array illumos_nvlist_add_bool_array
#define nvlist_add_descriptor illumos_nvlist_add_descriptor
#define nvlist_add_descriptor_array illumos_nvlist_add_descriptor_array
#define nvlist_add_null illumos_nvlist_add_null
#define nvlist_add_number illumos_nvlist_add_number
#define nvlist_add_number_array illumos_nvlist_add_number_array
#define nvlist_add_nvlist illumos_nvlist_add_nvlist
#define nvlist_add_nvlist_array illumos_nvlist_add_nvlist_array
#define nvlist_add_nvpair illumos_nvlist_add_nvpair
#define nvlist_add_string illumos_nvlist_add_string
#define nvlist_add_string_array illumos_nvlist_add_string_array
#define nvlist_add_stringf illumos_nvlist_add_stringf
#define nvlist_add_stringv illumos_nvlist_add_stringv
#define nvlist_addf_binary illumos_nvlist_addf_binary
#define nvlist_addf_bool illumos_nvlist_addf_bool
#define nvlist_addf_descriptor illumos_nvlist_addf_descriptor
#define nvlist_addf_null illumos_nvlist_addf_null
#define nvlist_addf_number illumos_nvlist_addf_number
#define nvlist_addf_nvlist illumos_nvlist_addf_nvlist
#define nvlist_addf_string illumos_nvlist_addf_string
#define nvlist_addv_binary illumos_nvlist_addv_binary
#define nvlist_addv_bool illumos_nvlist_addv_bool
#define nvlist_addv_descriptor illumos_nvlist_addv_descriptor
#define nvlist_addv_null illumos_nvlist_addv_null
#define nvlist_addv_number illumos_nvlist_addv_number
#define nvlist_addv_nvlist illumos_nvlist_addv_nvlist
#define nvlist_addv_string illumos_nvlist_addv_string
#define nvlist_check_header illumos_nvlist_check_header
#define nvlist_clone illumos_nvlist_clone
#define nvlist_create illumos_nvlist_create
#define nvlist_descriptors illumos_nvlist_descriptors
@ -75,92 +65,61 @@
#define nvlist_exists illumos_nvlist_exists
#define nvlist_exists_binary illumos_nvlist_exists_binary
#define nvlist_exists_bool illumos_nvlist_exists_bool
#define nvlist_exists_bool_array illumos_nvlist_exists_bool_array
#define nvlist_exists_descriptor illumos_nvlist_exists_descriptor
#define nvlist_exists_descriptor_array illumos_nvlist_exists_descriptor_array
#define nvlist_exists_null illumos_nvlist_exists_null
#define nvlist_exists_number illumos_nvlist_exists_number
#define nvlist_exists_number_array illumos_nvlist_exists_number_array
#define nvlist_exists_nvlist illumos_nvlist_exists_nvlist
#define nvlist_exists_nvlist_array illumos_nvlist_exists_nvlist_array
#define nvlist_exists_string illumos_nvlist_exists_string
#define nvlist_exists_string_array illumos_nvlist_exists_string_array
#define nvlist_exists_type illumos_nvlist_exists_type
#define nvlist_existsf illumos_nvlist_existsf
#define nvlist_existsf_binary illumos_nvlist_existsf_binary
#define nvlist_existsf_bool illumos_nvlist_existsf_bool
#define nvlist_existsf_descriptor illumos_nvlist_existsf_descriptor
#define nvlist_existsf_null illumos_nvlist_existsf_null
#define nvlist_existsf_number illumos_nvlist_existsf_number
#define nvlist_existsf_nvlist illumos_nvlist_existsf_nvlist
#define nvlist_existsf_string illumos_nvlist_existsf_string
#define nvlist_existsf_type illumos_nvlist_existsf_type
#define nvlist_existsv illumos_nvlist_existsv
#define nvlist_existsv_binary illumos_nvlist_existsv_binary
#define nvlist_existsv_bool illumos_nvlist_existsv_bool
#define nvlist_existsv_descriptor illumos_nvlist_existsv_descriptor
#define nvlist_existsv_null illumos_nvlist_existsv_null
#define nvlist_existsv_number illumos_nvlist_existsv_number
#define nvlist_existsv_nvlist illumos_nvlist_existsv_nvlist
#define nvlist_existsv_string illumos_nvlist_existsv_string
#define nvlist_existsv_type illumos_nvlist_existsv_type
#define nvlist_fdump illumos_nvlist_fdump
#define nvlist_first_nvpair illumos_nvlist_first_nvpair
#define nvlist_flags illumos_nvlist_flags
#define nvlist_free illumos_nvlist_free
#define nvlist_free_binary illumos_nvlist_free_binary
#define nvlist_free_binary_array illumos_nvlist_free_binary_array
#define nvlist_free_bool illumos_nvlist_free_bool
#define nvlist_free_bool_array illumos_nvlist_free_bool_array
#define nvlist_free_descriptor illumos_nvlist_free_descriptor
#define nvlist_free_descriptor_array illumos_nvlist_free_descriptor_array
#define nvlist_free_null illumos_nvlist_free_null
#define nvlist_free_number illumos_nvlist_free_number
#define nvlist_free_number_array illumos_nvlist_free_number_array
#define nvlist_free_nvlist illumos_nvlist_free_nvlist
#define nvlist_free_nvlist_array illumos_nvlist_free_nvlist_array
#define nvlist_free_nvpair illumos_nvlist_free_nvpair
#define nvlist_free_string illumos_nvlist_free_string
#define nvlist_free_string_array illumos_nvlist_free_string_array
#define nvlist_free_type illumos_nvlist_free_type
#define nvlist_freef illumos_nvlist_freef
#define nvlist_freef_binary illumos_nvlist_freef_binary
#define nvlist_freef_bool illumos_nvlist_freef_bool
#define nvlist_freef_descriptor illumos_nvlist_freef_descriptor
#define nvlist_freef_null illumos_nvlist_freef_null
#define nvlist_freef_number illumos_nvlist_freef_number
#define nvlist_freef_nvlist illumos_nvlist_freef_nvlist
#define nvlist_freef_string illumos_nvlist_freef_string
#define nvlist_freef_type illumos_nvlist_freef_type
#define nvlist_freev illumos_nvlist_freev
#define nvlist_freev_binary illumos_nvlist_freev_binary
#define nvlist_freev_bool illumos_nvlist_freev_bool
#define nvlist_freev_descriptor illumos_nvlist_freev_descriptor
#define nvlist_freev_null illumos_nvlist_freev_null
#define nvlist_freev_number illumos_nvlist_freev_number
#define nvlist_freev_nvlist illumos_nvlist_freev_nvlist
#define nvlist_freev_string illumos_nvlist_freev_string
#define nvlist_freev_type illumos_nvlist_freev_type
#define nvlist_get_array_next illumos_nvlist_get_array_next
#define nvlist_get_binary illumos_nvlist_get_binary
#define nvlist_get_bool illumos_nvlist_get_bool
#define nvlist_get_bool_array illumos_nvlist_get_bool_array
#define nvlist_get_descriptor illumos_nvlist_get_descriptor
#define nvlist_get_descriptor_array illumos_nvlist_get_descriptor_array
#define nvlist_get_number illumos_nvlist_get_number
#define nvlist_get_number_array illumos_nvlist_get_number_array
#define nvlist_get_nvlist illumos_nvlist_get_nvlist
#define nvlist_get_nvpair illumos_nvlist_get_nvpair
#define nvlist_get_nvpair_parent illumos_nvlist_get_nvpair_parent
#define nvlist_get_pararr illumos_nvlist_get_pararr
#define nvlist_get_parent illumos_nvlist_get_parent
#define nvlist_get_string illumos_nvlist_get_string
#define nvlist_getf_binary illumos_nvlist_getf_binary
#define nvlist_getf_bool illumos_nvlist_getf_bool
#define nvlist_getf_descriptor illumos_nvlist_getf_descriptor
#define nvlist_getf_number illumos_nvlist_getf_number
#define nvlist_getf_nvlist illumos_nvlist_getf_nvlist
#define nvlist_getf_string illumos_nvlist_getf_string
#define nvlist_getv_binary illumos_nvlist_getv_binary
#define nvlist_getv_bool illumos_nvlist_getv_bool
#define nvlist_getv_descriptor illumos_nvlist_getv_descriptor
#define nvlist_getv_number illumos_nvlist_getv_number
#define nvlist_getv_nvlist illumos_nvlist_getv_nvlist
#define nvlist_getv_string illumos_nvlist_getv_string
#define nvlist_in_array illumos_nvlist_in_array
#define nvlist_move_binary illumos_nvlist_move_binary
#define nvlist_move_bool_array illumos_nvlist_move_bool_array
#define nvlist_move_descriptor illumos_nvlist_move_descriptor
#define nvlist_move_descriptor_array illumos_nvlist_move_descriptor_array
#define nvlist_move_number_array illumos_nvlist_move_number_array
#define nvlist_move_nvlist illumos_nvlist_move_nvlist
#define nvlist_move_nvlist_array illumos_nvlist_move_nvlist_array
#define nvlist_move_nvpair illumos_nvlist_move_nvpair
#define nvlist_move_string illumos_nvlist_move_string
#define nvlist_movef_binary illumos_nvlist_movef_binary
#define nvlist_movef_descriptor illumos_nvlist_movef_descriptor
#define nvlist_movef_nvlist illumos_nvlist_movef_nvlist
#define nvlist_movef_string illumos_nvlist_movef_string
#define nvlist_movev_binary illumos_nvlist_movev_binary
#define nvlist_movev_descriptor illumos_nvlist_movev_descriptor
#define nvlist_movev_nvlist illumos_nvlist_movev_nvlist
#define nvlist_movev_string illumos_nvlist_movev_string
#define nvlist_move_string_array illumos_nvlist_move_string_array
#define nvlist_ndescriptors illumos_nvlist_ndescriptors
#define nvlist_next illumos_nvlist_next
#define nvlist_next_nvpair illumos_nvlist_next_nvpair
@ -168,93 +127,101 @@
#define nvlist_prev_nvpair illumos_nvlist_prev_nvpair
#define nvlist_recv illumos_nvlist_recv
#define nvlist_remove_nvpair illumos_nvlist_remove_nvpair
#define nvlist_report_missing illumos_nvlist_report_missing
#define nvlist_send illumos_nvlist_send
#define nvlist_set_array_next illumos_nvlist_set_array_next
#define nvlist_set_error illumos_nvlist_set_error
#define nvlist_set_flags illumos_nvlist_set_flags
#define nvlist_set_parent illumos_nvlist_set_parent
#define nvlist_size illumos_nvlist_size
#define nvlist_take_binary illumos_nvlist_take_binary
#define nvlist_take_bool illumos_nvlist_take_bool
#define nvlist_take_bool_array illumos_nvlist_take_bool_array
#define nvlist_take_descriptor illumos_nvlist_take_descriptor
#define nvlist_take_descriptor_array illumos_nvlist_take_descriptor_array
#define nvlist_take_number illumos_nvlist_take_number
#define nvlist_take_number_array illumos_nvlist_take_number_array
#define nvlist_take_nvlist illumos_nvlist_take_nvlist
#define nvlist_take_nvlist_array illumos_nvlist_take_nvlist_array
#define nvlist_take_nvpair illumos_nvlist_take_nvpair
#define nvlist_take_string illumos_nvlist_take_string
#define nvlist_takef_binary illumos_nvlist_takef_binary
#define nvlist_takef_bool illumos_nvlist_takef_bool
#define nvlist_takef_descriptor illumos_nvlist_takef_descriptor
#define nvlist_takef_number illumos_nvlist_takef_number
#define nvlist_takef_nvlist illumos_nvlist_takef_nvlist
#define nvlist_takef_string illumos_nvlist_takef_string
#define nvlist_takev_binary illumos_nvlist_takev_binary
#define nvlist_takev_bool illumos_nvlist_takev_bool
#define nvlist_takev_descriptor illumos_nvlist_takev_descriptor
#define nvlist_takev_number illumos_nvlist_takev_number
#define nvlist_takev_nvlist illumos_nvlist_takev_nvlist
#define nvlist_takev_string illumos_nvlist_takev_string
#define nvlist_take_string_array illumos_nvlist_take_string_array
#define nvlist_unpack illumos_nvlist_unpack
#define nvlist_unpack_header illumos_nvlist_unpack_header
#define nvlist_xfer illumos_nvlist_xfer
#define nvlist_xpack illumos_nvlist_xpack
#define nvlist_xunpack illumos_nvlist_xunpack
#define nvpair_allocv illumos_nvpair_allocv
#define nvpair_assert illumos_nvpair_assert
#define nvpair_clone illumos_nvpair_clone
#define nvpair_create_binary illumos_nvpair_create_binary
#define nvpair_create_bool illumos_nvpair_create_bool
#define nvpair_create_bool_array illumos_nvpair_create_bool_array
#define nvpair_create_descriptor illumos_nvpair_create_descriptor
#define nvpair_create_descriptor_array illumos_nvpair_create_descriptor_array
#define nvpair_create_null illumos_nvpair_create_null
#define nvpair_create_number illumos_nvpair_create_number
#define nvpair_create_number_array illumos_nvpair_create_number_array
#define nvpair_create_nvlist illumos_nvpair_create_nvlist
#define nvpair_create_nvlist_array illumos_nvpair_create_nvlist_array
#define nvpair_create_string illumos_nvpair_create_string
#define nvpair_create_string_array illumos_nvpair_create_string_array
#define nvpair_create_stringf illumos_nvpair_create_stringf
#define nvpair_create_stringv illumos_nvpair_create_stringv
#define nvpair_createf_binary illumos_nvpair_createf_binary
#define nvpair_createf_bool illumos_nvpair_createf_bool
#define nvpair_createf_descriptor illumos_nvpair_createf_descriptor
#define nvpair_createf_null illumos_nvpair_createf_null
#define nvpair_createf_number illumos_nvpair_createf_number
#define nvpair_createf_nvlist illumos_nvpair_createf_nvlist
#define nvpair_createf_string illumos_nvpair_createf_string
#define nvpair_createv_binary illumos_nvpair_createv_binary
#define nvpair_createv_bool illumos_nvpair_createv_bool
#define nvpair_createv_descriptor illumos_nvpair_createv_descriptor
#define nvpair_createv_null illumos_nvpair_createv_null
#define nvpair_createv_number illumos_nvpair_createv_number
#define nvpair_createv_nvlist illumos_nvpair_createv_nvlist
#define nvpair_createv_string illumos_nvpair_createv_string
#define nvpair_free illumos_nvpair_free
#define nvpair_free_structure illumos_nvpair_free_structure
#define nvpair_get_binary illumos_nvpair_get_binary
#define nvpair_get_bool illumos_nvpair_get_bool
#define nvpair_get_bool_array illumos_nvpair_get_bool_array
#define nvpair_get_descriptor illumos_nvpair_get_descriptor
#define nvpair_get_descriptor_array illumos_nvpair_get_descriptor_array
#define nvpair_get_number illumos_nvpair_get_number
#define nvpair_get_number_array illumos_nvpair_get_number_array
#define nvpair_get_nvlist illumos_nvpair_get_nvlist
#define nvpair_get_string illumos_nvpair_get_string
#define nvpair_header_size illumos_nvpair_header_size
#define nvpair_init_datasize illumos_nvpair_init_datasize
#define nvpair_insert illumos_nvpair_insert
#define nvpair_move_binary illumos_nvpair_move_binary
#define nvpair_move_bool_array illumos_nvpair_move_bool_array
#define nvpair_move_descriptor illumos_nvpair_move_descriptor
#define nvpair_move_descriptor_array illumos_nvpair_move_descriptor_array
#define nvpair_move_number_array illumos_nvpair_move_number_array
#define nvpair_move_nvlist illumos_nvpair_move_nvlist
#define nvpair_move_nvlist_array illumos_nvpair_move_nvlist_array
#define nvpair_move_string illumos_nvpair_move_string
#define nvpair_movef_binary illumos_nvpair_movef_binary
#define nvpair_movef_descriptor illumos_nvpair_movef_descriptor
#define nvpair_movef_nvlist illumos_nvpair_movef_nvlist
#define nvpair_movef_string illumos_nvpair_movef_string
#define nvpair_movev_binary illumos_nvpair_movev_binary
#define nvpair_movev_descriptor illumos_nvpair_movev_descriptor
#define nvpair_movev_nvlist illumos_nvpair_movev_nvlist
#define nvpair_movev_string illumos_nvpair_movev_string
#define nvpair_move_string_array illumos_nvpair_move_string_array
#define nvpair_name illumos_nvpair_name
#define nvpair_next illumos_nvpair_next
#define nvpair_nvlist illumos_nvpair_nvlist
#define nvpair_pack illumos_nvpair_pack
#define nvpair_pack_binary illumos_nvpair_pack_binary
#define nvpair_pack_bool illumos_nvpair_pack_bool
#define nvpair_pack_bool_array illumos_nvpair_pack_bool_array
#define nvpair_pack_descriptor illumos_nvpair_pack_descriptor
#define nvpair_pack_descriptor_array illumos_nvpair_pack_descriptor_array
#define nvpair_pack_header illumos_nvpair_pack_header
#define nvpair_pack_null illumos_nvpair_pack_null
#define nvpair_pack_number illumos_nvpair_pack_number
#define nvpair_pack_number_array illumos_nvpair_pack_number_array
#define nvpair_pack_nvlist_array_next illumos_nvpair_pack_nvlist_array_next
#define nvpair_pack_nvlist_up illumos_nvpair_pack_nvlist_up
#define nvpair_pack_string illumos_nvpair_pack_string
#define nvpair_pack_string_array illumos_nvpair_pack_string_array
#define nvpair_prev illumos_nvpair_prev
#define nvpair_remove illumos_nvpair_remove
#define nvpair_size illumos_nvpair_size
#define nvpair_type illumos_nvpair_type
#define nvpair_type_string illumos_nvpair_type_string
#define nvpair_unpack illumos_nvpair_unpack
#define nvpair_unpack_binary illumos_nvpair_unpack_binary
#define nvpair_unpack_bool illumos_nvpair_unpack_bool
#define nvpair_unpack_bool_array illumos_nvpair_unpack_bool_array
#define nvpair_unpack_descriptor illumos_nvpair_unpack_descriptor
#define nvpair_unpack_descriptor_array illumos_nvpair_unpack_descriptor_array
#define nvpair_unpack_header illumos_nvpair_unpack_header
#define nvpair_unpack_null illumos_nvpair_unpack_null
#define nvpair_unpack_number illumos_nvpair_unpack_number
#define nvpair_unpack_number_array illumos_nvpair_unpack_number_array
#define nvpair_unpack_nvlist illumos_nvpair_unpack_nvlist
#define nvpair_unpack_nvlist_array illumos_nvpair_unpack_nvlist_array
#define nvpair_unpack_string illumos_nvpair_unpack_string
#define nvpair_unpack_string_array illumos_nvpair_unpack_string_array
#endif /* _KERNEL */

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved.
@ -129,15 +129,15 @@ zfeature_depends_on(spa_feature_t fid, spa_feature_t check) {
static void
zfeature_register(spa_feature_t fid, const char *guid, const char *name,
const char *desc, boolean_t readonly, boolean_t mos,
boolean_t activate_on_enable, const spa_feature_t *deps)
const char *desc, zfeature_flags_t flags, const spa_feature_t *deps)
{
zfeature_info_t *feature = &spa_feature_table[fid];
static spa_feature_t nodeps[] = { SPA_FEATURE_NONE };
ASSERT(name != NULL);
ASSERT(desc != NULL);
ASSERT(!readonly || !mos);
ASSERT((flags & ZFEATURE_FLAG_READONLY_COMPAT) == 0 ||
(flags & ZFEATURE_FLAG_MOS) == 0);
ASSERT3U(fid, <, SPA_FEATURES);
ASSERT(zfeature_is_valid_guid(guid));
@ -148,9 +148,7 @@ zfeature_register(spa_feature_t fid, const char *guid, const char *name,
feature->fi_guid = guid;
feature->fi_uname = name;
feature->fi_desc = desc;
feature->fi_can_readonly = readonly;
feature->fi_mos = mos;
feature->fi_activate_on_enable = activate_on_enable;
feature->fi_flags = flags;
feature->fi_depends = deps;
}
@ -159,45 +157,46 @@ zpool_feature_init(void)
{
zfeature_register(SPA_FEATURE_ASYNC_DESTROY,
"com.delphix:async_destroy", "async_destroy",
"Destroy filesystems asynchronously.", B_TRUE, B_FALSE,
B_FALSE, NULL);
"Destroy filesystems asynchronously.",
ZFEATURE_FLAG_READONLY_COMPAT, NULL);
zfeature_register(SPA_FEATURE_EMPTY_BPOBJ,
"com.delphix:empty_bpobj", "empty_bpobj",
"Snapshots use less space.", B_TRUE, B_FALSE,
B_FALSE, NULL);
"Snapshots use less space.",
ZFEATURE_FLAG_READONLY_COMPAT, NULL);
zfeature_register(SPA_FEATURE_LZ4_COMPRESS,
"org.illumos:lz4_compress", "lz4_compress",
"LZ4 compression algorithm support.", B_FALSE, B_FALSE,
B_TRUE, NULL);
"LZ4 compression algorithm support.",
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE, NULL);
zfeature_register(SPA_FEATURE_MULTI_VDEV_CRASH_DUMP,
"com.joyent:multi_vdev_crash_dump", "multi_vdev_crash_dump",
"Crash dumps to multiple vdev pools.", B_FALSE, B_FALSE,
B_FALSE, NULL);
"Crash dumps to multiple vdev pools.",
0, NULL);
zfeature_register(SPA_FEATURE_SPACEMAP_HISTOGRAM,
"com.delphix:spacemap_histogram", "spacemap_histogram",
"Spacemaps maintain space histograms.", B_TRUE, B_FALSE,
B_FALSE, NULL);
"Spacemaps maintain space histograms.",
ZFEATURE_FLAG_READONLY_COMPAT, NULL);
zfeature_register(SPA_FEATURE_ENABLED_TXG,
"com.delphix:enabled_txg", "enabled_txg",
"Record txg at which a feature is enabled", B_TRUE, B_FALSE,
B_FALSE, NULL);
"Record txg at which a feature is enabled",
ZFEATURE_FLAG_READONLY_COMPAT, NULL);
static spa_feature_t hole_birth_deps[] = { SPA_FEATURE_ENABLED_TXG,
SPA_FEATURE_NONE };
zfeature_register(SPA_FEATURE_HOLE_BIRTH,
"com.delphix:hole_birth", "hole_birth",
"Retain hole birth txg for more precise zfs send",
B_FALSE, B_TRUE, B_TRUE, hole_birth_deps);
ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE,
hole_birth_deps);
zfeature_register(SPA_FEATURE_EXTENSIBLE_DATASET,
"com.delphix:extensible_dataset", "extensible_dataset",
"Enhanced dataset functionality, used by other features.",
B_FALSE, B_FALSE, B_FALSE, NULL);
0, NULL);
static const spa_feature_t bookmarks_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
@ -206,7 +205,7 @@ zpool_feature_init(void)
zfeature_register(SPA_FEATURE_BOOKMARKS,
"com.delphix:bookmarks", "bookmarks",
"\"zfs bookmark\" command",
B_TRUE, B_FALSE, B_FALSE, bookmarks_deps);
ZFEATURE_FLAG_READONLY_COMPAT, bookmarks_deps);
static const spa_feature_t filesystem_limits_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
@ -214,13 +213,14 @@ zpool_feature_init(void)
};
zfeature_register(SPA_FEATURE_FS_SS_LIMIT,
"com.joyent:filesystem_limits", "filesystem_limits",
"Filesystem and snapshot limits.", B_TRUE, B_FALSE, B_FALSE,
filesystem_limits_deps);
"Filesystem and snapshot limits.",
ZFEATURE_FLAG_READONLY_COMPAT, filesystem_limits_deps);
zfeature_register(SPA_FEATURE_EMBEDDED_DATA,
"com.delphix:embedded_data", "embedded_data",
"Blocks which compress very well use even less space.",
B_FALSE, B_TRUE, B_TRUE, NULL);
ZFEATURE_FLAG_MOS | ZFEATURE_FLAG_ACTIVATE_ON_ENABLE,
NULL);
static const spa_feature_t large_blocks_deps[] = {
SPA_FEATURE_EXTENSIBLE_DATASET,
@ -228,6 +228,6 @@ zpool_feature_init(void)
};
zfeature_register(SPA_FEATURE_LARGE_BLOCKS,
"org.open-zfs:large_blocks", "large_blocks",
"Support for blocks larger than 128KB.", B_FALSE, B_FALSE, B_FALSE,
large_blocks_deps);
"Support for blocks larger than 128KB.",
ZFEATURE_FLAG_PER_DATASET, large_blocks_deps);
}

View File

@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
@ -56,15 +56,23 @@ typedef enum spa_feature {
#define SPA_FEATURE_DISABLED (-1ULL)
typedef enum zfeature_flags {
/* Can open pool readonly even if this feature is not supported. */
ZFEATURE_FLAG_READONLY_COMPAT = (1 << 0),
/* Is this feature necessary to read the MOS? */
ZFEATURE_FLAG_MOS = (1 << 1),
/* Activate this feature at the same time it is enabled. */
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE = (1 << 2),
/* Each dataset has a field set if it has ever used this feature. */
ZFEATURE_FLAG_PER_DATASET = (1 << 3)
} zfeature_flags_t;
typedef struct zfeature_info {
spa_feature_t fi_feature;
const char *fi_uname; /* User-facing feature name */
const char *fi_guid; /* On-disk feature identifier */
const char *fi_desc; /* Feature description */
boolean_t fi_can_readonly; /* Can open pool readonly w/o support? */
boolean_t fi_mos; /* Is the feature necessary to read the MOS? */
/* Activate this feature at the same time it is enabled */
boolean_t fi_activate_on_enable;
zfeature_flags_t fi_flags;
/* array of dependencies, terminated by SPA_FEATURE_NONE */
const spa_feature_t *fi_depends;
} zfeature_info_t;

View File

@ -22,7 +22,9 @@
#
# Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2013 by Delphix. All rights reserved.
# Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
# Copyright (c) 2012 Joyent, Inc. All rights reserved.
# Copyright (c) 2011, 2014 by Delphix. All rights reserved.
# Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
#
#
@ -36,6 +38,7 @@ ZFS_COMMON_OBJS += \
blkptr.o \
bpobj.o \
bptree.o \
bqueue.o \
dbuf.o \
ddt.o \
ddt_zap.o \
@ -65,6 +68,7 @@ ZFS_COMMON_OBJS += \
lz4.o \
lzjb.o \
metaslab.o \
multilist.o \
range_tree.o \
refcount.o \
rrwlock.o \

File diff suppressed because it is too large Load Diff

View File

@ -154,7 +154,7 @@ bptree_visit_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
int err;
struct bptree_args *ba = arg;
if (BP_IS_HOLE(bp))
if (bp == NULL || BP_IS_HOLE(bp))
return (0);
err = ba->ba_func(ba->ba_arg, bp, ba->ba_tx);

View File

@ -0,0 +1,111 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014 by Delphix. All rights reserved.
*/
#include <sys/bqueue.h>
#include <sys/zfs_context.h>
static inline bqueue_node_t *
obj2node(bqueue_t *q, void *data)
{
return ((bqueue_node_t *)((char *)data + q->bq_node_offset));
}
/*
* Initialize a blocking queue The maximum capacity of the queue is set to
* size. Types that want to be stored in a bqueue must contain a bqueue_node_t,
* and offset should give its offset from the start of the struct. Return 0 on
* success, or -1 on failure.
*/
int
bqueue_init(bqueue_t *q, uint64_t size, size_t node_offset)
{
list_create(&q->bq_list, node_offset + sizeof (bqueue_node_t),
node_offset + offsetof(bqueue_node_t, bqn_node));
cv_init(&q->bq_add_cv, NULL, CV_DEFAULT, NULL);
cv_init(&q->bq_pop_cv, NULL, CV_DEFAULT, NULL);
mutex_init(&q->bq_lock, NULL, MUTEX_DEFAULT, NULL);
q->bq_node_offset = node_offset;
q->bq_size = 0;
q->bq_maxsize = size;
return (0);
}
/*
* Destroy a blocking queue. This function asserts that there are no
* elements in the queue, and no one is blocked on the condition
* variables.
*/
void
bqueue_destroy(bqueue_t *q)
{
ASSERT0(q->bq_size);
cv_destroy(&q->bq_add_cv);
cv_destroy(&q->bq_pop_cv);
mutex_destroy(&q->bq_lock);
list_destroy(&q->bq_list);
}
/*
* Add data to q, consuming size units of capacity. If there is insufficient
* capacity to consume size units, block until capacity exists. Asserts size is
* > 0.
*/
void
bqueue_enqueue(bqueue_t *q, void *data, uint64_t item_size)
{
ASSERT3U(item_size, >, 0);
ASSERT3U(item_size, <, q->bq_maxsize);
mutex_enter(&q->bq_lock);
obj2node(q, data)->bqn_size = item_size;
while (q->bq_size + item_size > q->bq_maxsize) {
cv_wait(&q->bq_add_cv, &q->bq_lock);
}
q->bq_size += item_size;
list_insert_tail(&q->bq_list, data);
cv_signal(&q->bq_pop_cv);
mutex_exit(&q->bq_lock);
}
/*
* Take the first element off of q. If there are no elements on the queue, wait
* until one is put there. Return the removed element.
*/
void *
bqueue_dequeue(bqueue_t *q)
{
void *ret;
uint64_t item_size;
mutex_enter(&q->bq_lock);
while (q->bq_size == 0) {
cv_wait(&q->bq_pop_cv, &q->bq_lock);
}
ret = list_remove_head(&q->bq_list);
item_size = obj2node(q, ret)->bqn_size;
q->bq_size -= item_size;
mutex_exit(&q->bq_lock);
cv_signal(&q->bq_add_cv);
return (ret);
}
/*
* Returns true if the space used is 0.
*/
boolean_t
bqueue_empty(bqueue_t *q)
{
return (q->bq_size == 0);
}

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