diff --git a/MAINTAINERS b/MAINTAINERS index 98fa63d98f9..29236caf6b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -48,7 +48,6 @@ cd(4) ken Pre-commit review requested. pass(4) ken Pre-commit review requested. ch(4) ken Pre-commit review requested. em(4) jfv Pre-commit review requested. -bxe(4) davidch Pre-commit review requested. tdfx(4) cokane Just keep me informed of changes, try not to break it. sendmail gshapiro Pre-commit review requested. etc/mail gshapiro Pre-commit review requested. @@ -81,6 +80,8 @@ contrib/pf glebius Pre-commit review recommended. file obrien Insists to keep file blocked from other's unapproved commits contrib/bzip2 obrien Pre-commit review required. +contrib/netbsd-tests freebsd-testing,ngie Pre-commit review requested. +contrib/pjdfstest freebsd-testing,ngie Pre-commit review requested. geom_concat pjd Pre-commit review preferred. geom_eli pjd Pre-commit review preferred. geom_gate pjd Pre-commit review preferred. diff --git a/Makefile.inc1 b/Makefile.inc1 index 07050ef0c56..8cbd58f5afc 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -1447,12 +1447,31 @@ NXBMAKE= ${NXBENV} ${MAKE} \ MK_CLANG_FULL=no MK_LLDB=no native-xtools: .MAKE + mkdir -p ${OBJTREE}/nxb-bin/bin + mkdir -p ${OBJTREE}/nxb-bin/sbin mkdir -p ${OBJTREE}/nxb-bin/usr mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ -p ${OBJTREE}/nxb-bin/usr >/dev/null mtree -deU -f ${.CURDIR}/etc/mtree/BSD.include.dist \ -p ${OBJTREE}/nxb-bin/usr/include >/dev/null .for _tool in \ + bin/cat \ + bin/chmod \ + bin/cp \ + bin/csh \ + bin/echo \ + bin/expr \ + bin/hostname \ + bin/ln \ + bin/ls \ + bin/mkdir \ + bin/mv \ + bin/ps \ + bin/realpath \ + bin/rm \ + bin/rmdir \ + bin/sh \ + bin/sleep \ ${_clang_tblgen} \ usr.bin/ar \ ${_binutils} \ @@ -1460,12 +1479,39 @@ native-xtools: .MAKE ${_gcc_tools} \ ${_clang_libs} \ ${_clang} \ + sbin/md5 \ + sbin/sysctl \ + gnu/usr.bin/diff \ usr.bin/awk \ + usr.bin/basename \ usr.bin/bmake \ + usr.bin/bzip2 \ + usr.bin/cmp \ + usr.bin/dirname \ + usr.bin/env \ + usr.bin/fetch \ + usr.bin/find \ + usr.bin/grep \ + usr.bin/gzip \ + usr.bin/id \ usr.bin/lex \ usr.bin/lorder \ + usr.bin/mktemp \ + usr.bin/mt \ + usr.bin/patch \ usr.bin/sed \ - usr.bin/yacc + usr.bin/sort \ + usr.bin/tar \ + usr.bin/touch \ + usr.bin/tr \ + usr.bin/true \ + usr.bin/uniq \ + usr.bin/unzip \ + usr.bin/xargs \ + usr.bin/xinstall \ + usr.bin/xz \ + usr.bin/yacc \ + usr.sbin/chown ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \ cd ${.CURDIR}/${_tool} && \ ${NXBMAKE} DIRPRFX=${_tool}/ obj && \ diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index c8072d44605..be0b7c90924 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,12 @@ # xargs -n1 | sort | uniq -d; # done +# 20141109: faith/faithd removal +OLD_FILES+=etc/rc.d/faith +OLD_FILES+=usr/share/man/man4/faith.4.gz +OLD_FILES+=usr/share/man/man4/if_faith.4.gz +OLD_FILES+=usr/sbin/faithd +OLD_FILES+=usr/share/man/man8/faithd.8.gz # 20141102: postrandom obsoleted by new /dev/random code OLD_FILES+=etc/rc.d/postrandom # 20141031: initrandom obsoleted by new /dev/random code diff --git a/UPDATING b/UPDATING index 41e036fa8e8..b9a7b3552fb 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20141109: + faith(4) and faithd(8) has been removed from base system. It + has been obsolete for a very long time. + 20141104: vt(4), the new console driver, is enabled by default. It brings support for Unicode and double-width characters, as well as @@ -833,8 +837,8 @@ COMMON ITEMS: 2.) update the ZFS boot block on your boot drive The following example updates the ZFS boot block on the first - partition (freebsd-boot) of a GPT partitioned drive ad0: - "gpart bootcode -p /boot/gptzfsboot -i 1 ad0" + partition (freebsd-boot) of a GPT partitioned drive ada0: + "gpart bootcode -p /boot/gptzfsboot -i 1 ada0" Non-boot pools do not need these updates. diff --git a/bin/sh/sh.1 b/bin/sh/sh.1 index c770aca07d5..fa6872017ca 100644 --- a/bin/sh/sh.1 +++ b/bin/sh/sh.1 @@ -32,7 +32,7 @@ .\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95 .\" $FreeBSD$ .\" -.Dd November 7, 2014 +.Dd November 14, 2014 .Dt SH 1 .Os .Sh NAME @@ -795,10 +795,13 @@ should indicate the various exit codes and what they mean. Additionally, the built-in commands return exit codes, as does an executed shell function. .Pp -If a command is terminated by a signal, its exit status is 128 plus -the signal number. -Signal numbers are defined in the header file -.In sys/signal.h . +If a command is terminated by a signal, its exit status is greater than 128. +The signal name can be found by passing the exit status to +.Li kill -l . +.Pp +If there is no command word, +the exit status is the exit status of the last command substitution executed, +or zero if the command does not contain any command substitutions. .Ss Complex Commands Complex commands are combinations of simple commands with control operators or keywords, together creating a larger complex @@ -818,7 +821,8 @@ function definition .El .Pp Unless otherwise stated, the exit status of a command is -that of the last simple command executed by the command. +that of the last simple command executed by the command, +or zero if no simple command was executed. .Ss Pipelines A pipeline is a sequence of one or more commands separated by the control operator @@ -902,6 +906,8 @@ The format for running a command in background is: If the shell is not interactive, the standard input of an asynchronous command is set to .Pa /dev/null . +.Pp +The exit status is zero. .Ss Lists (Generally Speaking) A list is a sequence of zero or more commands separated by newlines, semicolons, or ampersands, @@ -940,6 +946,13 @@ command is: .Ic fi .Ed .Pp +The exit status is that of selected +.Ic then +or +.Ic else +list, +or zero if no list was selected. +.Pp The syntax of the .Ic while command is: @@ -960,6 +973,9 @@ in place of which causes it to repeat until the exit status of the first list is zero. .Pp +The exit status is that of the last execution of the second list, +or zero if it was never executed. +.Pp The syntax of the .Ic for command is: @@ -1040,10 +1056,6 @@ continuing until a list terminated with or the end of the .Ic case command. -The exit code of the -.Ic case -command is the exit code of the last command executed in the list or -zero if no patterns were matched. .Ss Grouping Commands Together Commands may be grouped by writing either .Pp @@ -1131,6 +1143,8 @@ and the syntax is: The .Ic local command is implemented as a built-in command. +The exit status is zero +unless the command is not in a function or a variable name is invalid. .Pp When a variable is made local, it inherits the initial value and exported and readonly flags from the variable diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c index c2c47d511c0..47ab7bf9a1d 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c @@ -2147,6 +2147,8 @@ dump_label(const char *dev) (void) close(fd); } +static uint64_t num_large_blocks; + /*ARGSUSED*/ static int dump_one_dir(const char *dsname, void *arg) @@ -2159,6 +2161,8 @@ 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++; dump_dir(os); dmu_objset_disown(os, FTAG); fuid_table_destroy(); @@ -2169,7 +2173,7 @@ dump_one_dir(const char *dsname, void *arg) /* * Block statistics. */ -#define PSIZE_HISTO_SIZE (SPA_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1) +#define PSIZE_HISTO_SIZE (SPA_OLD_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 2) typedef struct zdb_blkstats { uint64_t zb_asize; uint64_t zb_lsize; @@ -2234,7 +2238,15 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp, zb->zb_lsize += BP_GET_LSIZE(bp); zb->zb_psize += BP_GET_PSIZE(bp); zb->zb_count++; - zb->zb_psize_histogram[BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT]++; + + /* + * The histogram is only big enough to record blocks up to + * SPA_OLD_MAXBLOCKSIZE; larger blocks go into the last, + * "other", bucket. + */ + int idx = BP_GET_PSIZE(bp) >> SPA_MINBLOCKSHIFT; + idx = MIN(idx, SPA_OLD_MAXBLOCKSIZE / SPA_MINBLOCKSIZE + 1); + zb->zb_psize_histogram[idx]++; zb->zb_gangs += BP_COUNT_GANG(bp); @@ -2946,6 +2958,7 @@ 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_bpobj(&spa->spa_deferred_bpobj, @@ -2965,8 +2978,21 @@ 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); + } } - if (dump_opt['b'] || dump_opt['c']) + if (rc == 0 && (dump_opt['b'] || dump_opt['c'])) rc = dump_block_stats(spa); if (rc == 0) diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 index 2315e056aaf..e37b14868e9 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs.8 +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs.8 @@ -27,10 +27,11 @@ .\" Copyright (c) 2014, Joyent, Inc. All rights reserved. .\" Copyright (c) 2013, Steven Hartland .\" Copyright (c) 2014, Xin LI +.\" Copyright (c) 2014, The FreeBSD Foundation, All Rights Reserved. .\" .\" $FreeBSD$ .\" -.Dd June 30, 2014 +.Dd November 12, 2014 .Dt ZFS 8 .Os .Sh NAME @@ -179,12 +180,12 @@ .Ar bookmark .Nm .Cm send -.Op Fl DnPpRve +.Op Fl DnPpRveL .Op Fl i Ar snapshot | Fl I Ar snapshot .Ar snapshot .Nm .Cm send -.Op Fl e +.Op Fl eL .Op Fl i Ar snapshot Ns | Ns bookmark .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot .Nm @@ -1187,6 +1188,12 @@ systems is strongly discouraged, and may adversely affect performance. .Pp The size specified must be a power of two greater than or equal to 512 and less than or equal to 128 Kbytes. +If the +.Sy large_blocks +feature is enabled on the pool, the size may be up to 1 Mbyte. +See +.Xr zpool-features 7 +for details on ZFS feature flags. .Pp Changing the file system's .Sy recordsize @@ -1785,7 +1792,7 @@ descendent file systems. Recursively destroy all clones of these snapshots, including the clones, snapshots, and children. If this flag is specified, the -.Op fl d +.Fl d flag will have no effect. .It Fl n Do a dry-run ("No-op") deletion. No data will be deleted. This is useful in @@ -2477,7 +2484,7 @@ feature. .It Xo .Nm .Cm send -.Op Fl DnPpRve +.Op Fl DnPpRveL .Op Fl i Ar snapshot | Fl I Ar snapshot .Ar snapshot .Xc @@ -2549,6 +2556,22 @@ be used regardless of the dataset's property, but performance will be much better if the filesystem uses a dedup-capable checksum (eg. .Sy sha256 ) . +.It Fl L +Generate a stream which may contain blocks larger than 128KB. +This flag +has no effect if the +.Sy large_blocks +pool feature is disabled, or if the +.Sy recordsize +property of this filesystem has never been set above 128KB. +The receiving system must have the +.Sy large_blocks +pool feature enabled as well. +See +.Xr zpool-features 7 +for details on ZFS feature flags and the +.Sy large_blocks +feature. .It Fl e Generate a more compact stream by using WRITE_EMBEDDED records for blocks which are stored more compactly on disk by the @@ -2596,7 +2619,7 @@ on future versions of .It Xo .Nm .Cm send -.Op Fl e +.Op Fl eL .Op Fl i Ar snapshot Ns | Ns Ar bookmark .Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot .Xc @@ -2622,6 +2645,22 @@ specified as the last component of the name If the incremental target is a clone, the incremental source can be the origin snapshot, or an earlier snapshot in the origin's filesystem, or the origin's origin, etc. +.It Fl L +Generate a stream which may contain blocks larger than 128KB. +This flag +has no effect if the +.Sy large_blocks +pool feature is disabled, or if the +.Sy recordsize +property of this filesystem has never been set above 128KB. +The receiving system must have the +.Sy large_blocks +pool feature enabled as well. +See +.Xr zpool-features 7 +for details on ZFS feature flags and the +.Sy large_blocks +feature. .It Fl e Generate a more compact stream by using WRITE_EMBEDDED records for blocks which are stored more compactly on disk by the diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c index a3b461e1159..baac993a0df 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_main.c @@ -274,9 +274,9 @@ get_usage(zfs_help_t idx) case HELP_ROLLBACK: return (gettext("\trollback [-rRf] \n")); case HELP_SEND: - return (gettext("\tsend [-DnPpRve] [-[iI] snapshot] " + return (gettext("\tsend [-DnPpRvLe] [-[iI] snapshot] " "\n" - "\tsend [-e] [-i snapshot|bookmark] " + "\tsend [-Le] [-i snapshot|bookmark] " "\n")); case HELP_SET: return (gettext("\tset " @@ -3709,7 +3709,7 @@ zfs_do_send(int argc, char **argv) boolean_t extraverbose = B_FALSE; /* check options */ - while ((c = getopt(argc, argv, ":i:I:RDpvnPe")) != -1) { + while ((c = getopt(argc, argv, ":i:I:RDpvnPLe")) != -1) { switch (c) { case 'i': if (fromname) @@ -3744,6 +3744,9 @@ zfs_do_send(int argc, char **argv) case 'n': flags.dryrun = B_TRUE; break; + case 'L': + flags.largeblock = B_TRUE; + break; case 'e': flags.embed_data = B_TRUE; break; @@ -3800,6 +3803,8 @@ zfs_do_send(int argc, char **argv) if (zhp == NULL) return (1); + if (flags.largeblock) + lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK; if (flags.embed_data) lzc_flags |= LZC_SEND_FLAG_EMBED_DATA; diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 index 27e63a9438f..d855f168cc6 100644 --- a/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 +++ b/cddl/contrib/opensolaris/cmd/zpool/zpool-features.7 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 1, 2014 +.Dd November 10, 2014 .Dt ZPOOL-FEATURES 7 .Os .Sh NAME @@ -427,6 +427,33 @@ This feature becomes as soon as it is enabled and will never return to being .Sy enabled . +.It Sy large_blocks +.Bl -column "READ\-ONLY COMPATIBLE" "org.open-zfs:large_block" +.It GUID Ta org.open-zfs:large_block +.It READ\-ONLY COMPATIBLE Ta no +.It DEPENDENCIES Ta extensible_dataset +.El +.Pp +The +.Sy large_block +feature allows the record size on a dataset to be +set larger than 128KB. +.Pp +This feature becomes +.Sy active +once a +.Sy recordsize +property has been set larger than 128KB, and will return to being +.Sy enabled +once all filesystems that have ever had their recordsize larger than 128KB +are destroyed. +.Pp +Please note that booting from datasets that have recordsize greater than +128KB is +.Em NOT +supported by the +.Fx +boot loader. .El .Sh SEE ALSO .Xr zpool 8 diff --git a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c index dce1cb3d765..d99d8014f04 100644 --- a/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c +++ b/cddl/contrib/opensolaris/cmd/zstreamdump/zstreamdump.c @@ -54,7 +54,6 @@ uint64_t total_stream_len = 0; FILE *send_stream = 0; boolean_t do_byteswap = B_FALSE; boolean_t do_cksum = B_TRUE; -#define INITIAL_BUFLEN (1<<20) static void usage(void) @@ -67,6 +66,18 @@ usage(void) exit(1); } +static void * +safe_malloc(size_t size) +{ + void *rv = malloc(size); + if (rv == NULL) { + (void) fprintf(stderr, "ERROR; failed to allocate %zu bytes\n", + size); + abort(); + } + return (rv); +} + /* * ssread - send stream read. * @@ -158,7 +169,7 @@ print_block(char *buf, int length) int main(int argc, char *argv[]) { - char *buf = malloc(INITIAL_BUFLEN); + char *buf = safe_malloc(SPA_MAXBLOCKSIZE); uint64_t drr_record_count[DRR_NUMTYPES] = { 0 }; uint64_t total_records = 0; dmu_replay_record_t thedrr; @@ -307,9 +318,9 @@ main(int argc, char *argv[]) nvlist_t *nv; int sz = drr->drr_payloadlen; - if (sz > INITIAL_BUFLEN) { + if (sz > SPA_MAXBLOCKSIZE) { free(buf); - buf = malloc(sz); + buf = safe_malloc(sz); } (void) ssread(buf, sz, &zc); if (ferror(send_stream)) diff --git a/cddl/contrib/opensolaris/cmd/ztest/ztest.c b/cddl/contrib/opensolaris/cmd/ztest/ztest.c index 5ed87ce1371..ab69154b8d1 100644 --- a/cddl/contrib/opensolaris/cmd/ztest/ztest.c +++ b/cddl/contrib/opensolaris/cmd/ztest/ztest.c @@ -987,9 +987,15 @@ ztest_spa_get_ashift() { static int ztest_random_blocksize(void) { - // Choose a block size >= the ashift. - uint64_t block_shift = - ztest_random(SPA_MAXBLOCKSHIFT - ztest_spa_get_ashift() + 1); + uint64_t block_shift; + /* + * Choose a block size >= the ashift. + * If the SPA supports new MAXBLOCKSIZE, test up to 1MB blocks. + */ + int maxbs = SPA_OLD_MAXBLOCKSHIFT; + if (spa_maxblocksize(ztest_spa) == SPA_MAXBLOCKSIZE) + maxbs = 20; + block_shift = ztest_random(maxbs - ztest_spa_get_ashift() + 1); return (1 << (SPA_MINBLOCKSHIFT + block_shift)); } @@ -4789,7 +4795,7 @@ ztest_fault_inject(ztest_ds_t *zd, uint64_t id) char path0[MAXPATHLEN]; char pathrand[MAXPATHLEN]; size_t fsize; - int bshift = SPA_MAXBLOCKSHIFT + 2; /* don't scrog all labels */ + int bshift = SPA_OLD_MAXBLOCKSHIFT + 2; /* don't scrog all labels */ int iters = 1000; int maxfaults; int mirror_save; diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c index 54426834d50..0b531c5e688 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_dof.c @@ -469,7 +469,7 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data) * locally so an alternate symbol is added for the purpose * of this relocation. */ - if (pip->pi_rname[0] == '\0') + if (pip->pi_rname == NULL) dofr.dofr_name = dofpr.dofpr_func; else dofr.dofr_name = dof_add_string(ddo, pip->pi_rname); diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c index 0f1bfe07b7b..6acb86b155b 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.c @@ -520,6 +520,8 @@ dt_probe_destroy(dt_probe_t *prp) for (pip = prp->pr_inst; pip != NULL; pip = pip_next) { pip_next = pip->pi_next; + dt_free(dtp, pip->pi_rname); + dt_free(dtp, pip->pi_fname); dt_free(dtp, pip->pi_offs); dt_free(dtp, pip->pi_enoffs); dt_free(dtp, pip); @@ -552,28 +554,18 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp, if ((pip = dt_zalloc(dtp, sizeof (*pip))) == NULL) return (-1); - if ((pip->pi_offs = dt_zalloc(dtp, - sizeof (uint32_t))) == NULL) { - dt_free(dtp, pip); - return (-1); - } + if ((pip->pi_offs = dt_zalloc(dtp, sizeof (uint32_t))) == NULL) + goto nomem; if ((pip->pi_enoffs = dt_zalloc(dtp, - sizeof (uint32_t))) == NULL) { - dt_free(dtp, pip->pi_offs); - dt_free(dtp, pip); - return (-1); - } + sizeof (uint32_t))) == NULL) + goto nomem; - (void) strlcpy(pip->pi_fname, fname, sizeof (pip->pi_fname)); - if (rname != NULL) { - if (strlen(rname) + 1 > sizeof (pip->pi_rname)) { - dt_free(dtp, pip->pi_offs); - dt_free(dtp, pip); - return (dt_set_errno(dtp, EDT_COMPILER)); - } - (void) strcpy(pip->pi_rname, rname); - } + if ((pip->pi_fname = strdup(fname)) == NULL) + goto nomem; + + if (rname != NULL && (pip->pi_rname = strdup(rname)) == NULL) + goto nomem; pip->pi_noffs = 0; pip->pi_maxoffs = 1; @@ -618,6 +610,13 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp, (*offs)[(*noffs)++] = offset; return (0); + +nomem: + dt_free(dtp, pip->pi_fname); + dt_free(dtp, pip->pi_enoffs); + dt_free(dtp, pip->pi_offs); + dt_free(dtp, pip); + return (dt_set_errno(dtp, EDT_NOMEM)); } /* diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h index af4ec33dcb9..2752baae32d 100644 --- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h +++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_provider.h @@ -64,8 +64,8 @@ typedef struct dt_probe_iter { } dt_probe_iter_t; typedef struct dt_probe_instance { - char pi_fname[DTRACE_FUNCNAMELEN]; /* function name */ - char pi_rname[DTRACE_FUNCNAMELEN + 20]; /* mangled relocation name */ + char *pi_fname; /* function name */ + char *pi_rname; /* mangled relocation name */ uint32_t *pi_offs; /* offsets into the function */ uint32_t *pi_enoffs; /* is-enabled offsets */ uint_t pi_noffs; /* number of offsets */ diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h index ef18b457e05..8a707d1f795 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h @@ -609,6 +609,9 @@ typedef struct sendflags { /* show progress (ie. -v) */ boolean_t progress; + /* large blocks (>128K) are permitted */ + boolean_t largeblock; + /* WRITE_EMBEDDED records of type DATA are permitted */ boolean_t embed_data; } sendflags_t; diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index 265038ab1bf..063df4a3c23 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -1080,21 +1080,36 @@ zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl, break; } - case ZFS_PROP_RECORDSIZE: case ZFS_PROP_VOLBLOCKSIZE: - /* must be power of two within SPA_{MIN,MAX}BLOCKSIZE */ + case ZFS_PROP_RECORDSIZE: + { + int maxbs = SPA_MAXBLOCKSIZE; + if (zhp != NULL) { + maxbs = zpool_get_prop_int(zhp->zpool_hdl, + ZPOOL_PROP_MAXBLOCKSIZE, NULL); + } + /* + * Volumes are limited to a volblocksize of 128KB, + * because they typically service workloads with + * small random writes, which incur a large performance + * penalty with large blocks. + */ + if (prop == ZFS_PROP_VOLBLOCKSIZE) + maxbs = SPA_OLD_MAXBLOCKSIZE; + /* + * The value must be a power of two between + * SPA_MINBLOCKSIZE and maxbs. + */ if (intval < SPA_MINBLOCKSIZE || - intval > SPA_MAXBLOCKSIZE || !ISP2(intval)) { + intval > maxbs || !ISP2(intval)) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "'%s' must be power of 2 from %u " - "to %uk"), propname, - (uint_t)SPA_MINBLOCKSIZE, - (uint_t)SPA_MAXBLOCKSIZE >> 10); + "'%s' must be power of 2 from 512B " + "to %uKB"), propname, maxbs >> 10); (void) zfs_error(hdl, EZFS_BADPROP, errbuf); goto error; } break; - + } case ZFS_PROP_MLSLABEL: { #ifdef sun @@ -1471,7 +1486,9 @@ zfs_setprop_error(libzfs_handle_t *hdl, zfs_prop_t prop, int err, break; case ERANGE: - if (prop == ZFS_PROP_COMPRESSION) { + case EDOM: + if (prop == ZFS_PROP_COMPRESSION || + prop == ZFS_PROP_RECORDSIZE) { (void) zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "property setting is not allowed on " "bootable datasets")); @@ -3197,9 +3214,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type, case EDOM: zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "volume block size must be power of 2 from " - "%u to %uk"), - (uint_t)SPA_MINBLOCKSIZE, - (uint_t)SPA_MAXBLOCKSIZE >> 10); + "512B to 128KB")); return (zfs_error(hdl, EZFS_BADPROP, errbuf)); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c index 97f18d7bb22..91857b65a8d 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_sendrecv.c @@ -215,7 +215,7 @@ static void * cksummer(void *arg) { dedup_arg_t *dda = arg; - char *buf = malloc(1<<20); + char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE); dmu_replay_record_t thedrr; dmu_replay_record_t *drr = &thedrr; struct drr_begin *drrb = &thedrr.drr_u.drr_begin; @@ -280,9 +280,9 @@ cksummer(void *arg) DMU_COMPOUNDSTREAM && drr->drr_payloadlen != 0) { int sz = drr->drr_payloadlen; - if (sz > 1<<20) { - free(buf); - buf = malloc(sz); + if (sz > SPA_MAXBLOCKSIZE) { + buf = zfs_realloc(dda->dedup_hdl, buf, + SPA_MAXBLOCKSIZE, sz); } (void) ssread(buf, sz, ofp); if (ferror(stdin)) @@ -815,7 +815,7 @@ typedef struct send_dump_data { char prevsnap[ZFS_MAXNAMELEN]; uint64_t prevsnap_obj; boolean_t seenfrom, seento, replicate, doall, fromorigin; - boolean_t verbose, dryrun, parsable, progress, embed_data; + boolean_t verbose, dryrun, parsable, progress, embed_data, large_block; int outfd; boolean_t err; nvlist_t *fss; @@ -1163,6 +1163,8 @@ dump_snapshot(zfs_handle_t *zhp, void *arg) } enum lzc_send_flags flags = 0; + if (sdd->large_block) + flags |= LZC_SEND_FLAG_LARGE_BLOCK; if (sdd->embed_data) flags |= LZC_SEND_FLAG_EMBED_DATA; @@ -1511,6 +1513,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap, sdd.parsable = flags->parsable; sdd.progress = flags->progress; sdd.dryrun = flags->dryrun; + sdd.large_block = flags->largeblock; sdd.embed_data = flags->embed_data; sdd.filter_cb = filter_func; sdd.filter_cb_arg = cb_arg; @@ -2545,7 +2548,7 @@ static int recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap) { dmu_replay_record_t *drr; - void *buf = malloc(1<<20); + void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE); char errbuf[1024]; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c index cb38dc2d128..52bd580c47d 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.c @@ -502,6 +502,10 @@ lzc_get_holds(const char *snapname, nvlist_t **holdsp) * * "fd" is the file descriptor to write the send stream to. * + * If "flags" contains LZC_SEND_FLAG_LARGE_BLOCK, the stream is permitted + * to contain DRR_WRITE records with drr_length > 128K, and DRR_OBJECT + * records with drr_blksz > 128K. + * * If "flags" contains LZC_SEND_FLAG_EMBED_DATA, the stream is permitted * to contain DRR_WRITE_EMBEDDED records with drr_etype==BP_EMBEDDED_TYPE_DATA, * which the receiving system must support (as indicated by support @@ -518,6 +522,8 @@ lzc_send(const char *snapname, const char *from, int fd, fnvlist_add_int32(args, "fd", fd); if (from != NULL) fnvlist_add_string(args, "fromsnap", from); + if (flags & LZC_SEND_FLAG_LARGE_BLOCK) + fnvlist_add_boolean(args, "largeblockok"); if (flags & LZC_SEND_FLAG_EMBED_DATA) fnvlist_add_boolean(args, "embedok"); err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL); diff --git a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h index 99883fecc13..b6a4c12f250 100644 --- a/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h +++ b/cddl/contrib/opensolaris/lib/libzfs_core/common/libzfs_core.h @@ -54,7 +54,8 @@ int lzc_release(nvlist_t *, nvlist_t **); int lzc_get_holds(const char *, nvlist_t **); enum lzc_send_flags { - LZC_SEND_FLAG_EMBED_DATA = 1 << 0 + LZC_SEND_FLAG_EMBED_DATA = 1 << 0, + LZC_SEND_FLAG_LARGE_BLOCK = 1 << 1 }; int lzc_send(const char *, const char *, int, enum lzc_send_flags); diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c index d4036d03b0c..26d9f364b09 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c @@ -24,6 +24,8 @@ */ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2012 Garrett D'Amore . All rights reserved. + * Copyright (c) 2014 by Delphix. All rights reserved. */ #include @@ -32,8 +34,10 @@ int taskq_now; taskq_t *system_taskq; #define TASKQ_ACTIVE 0x00010000 +#define TASKQ_NAMELEN 31 struct taskq { + char tq_name[TASKQ_NAMELEN + 1]; kmutex_t tq_lock; krwlock_t tq_threadlock; kcondvar_t tq_dispatch_cv; @@ -136,6 +140,7 @@ taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) t->tqent_prev->tqent_next = t; t->tqent_func = func; t->tqent_arg = arg; + t->tqent_flags = 0; cv_signal(&tq->tq_dispatch_cv); mutex_exit(&tq->tq_lock); return (1); @@ -245,6 +250,7 @@ taskq_create(const char *name, int nthreads, pri_t pri, cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL); + (void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1); tq->tq_flags = flags | TASKQ_ACTIVE; tq->tq_active = nthreads; tq->tq_nthreads = nthreads; diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c index 55ce7b2e2de..5dfeab3c0be 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/dwarf.c @@ -766,7 +766,8 @@ die_array_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private) debug(3, "trying to resolve array %d (cont %d)\n", tdp->t_id, tdp->t_ardef->ad_contents->t_id); - if ((sz = tdesc_size(tdp->t_ardef->ad_contents)) == 0) { + if ((sz = tdesc_size(tdp->t_ardef->ad_contents)) == 0 && + (tdp->t_ardef->ad_contents->t_flags & TDESC_F_RESOLVED) == 0) { debug(3, "unable to resolve array %s (%d) contents %d\n", tdesc_name(tdp), tdp->t_id, tdp->t_ardef->ad_contents->t_id); @@ -1138,12 +1139,17 @@ die_sou_resolve(tdesc_t *tdp, tdesc_t **tdpp __unused, void *private) /* * For empty members, or GCC/C99 flexible array - * members, a size of 0 is correct. + * members, a size of 0 is correct. Structs and unions + * consisting of flexible array members will also have + * size 0. */ if (mt->t_members == NULL) continue; if (mt->t_type == ARRAY && mt->t_ardef->ad_nelems == 0) continue; + if ((mt->t_flags & TDESC_F_RESOLVED) != 0 && + (mt->t_type == STRUCT || mt->t_type == UNION)) + continue; dw->dw_nunres++; return (1); diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c index 2ef37d460b3..d366f318273 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/merge.c @@ -287,19 +287,11 @@ equiv_su(tdesc_t *stdp, tdesc_t *ttdp, equiv_data_t *ed) while (ml1 && ml2) { if (ml1->ml_offset != ml2->ml_offset || - strcmp(ml1->ml_name, ml2->ml_name) != 0) + strcmp(ml1->ml_name, ml2->ml_name) != 0 || + ml1->ml_size != ml2->ml_size || + !equiv_node(ml1->ml_type, ml2->ml_type, ed)) return (0); - /* - * Don't do the recursive equivalency checking more than - * we have to. - */ - if (olm1 == NULL || olm1->ml_type->t_id != ml1->ml_type->t_id) { - if (ml1->ml_size != ml2->ml_size || - !equiv_node(ml1->ml_type, ml2->ml_type, ed)) - return (0); - } - olm1 = ml1; ml1 = ml1->ml_next; ml2 = ml2->ml_next; @@ -357,7 +349,7 @@ equiv_node(tdesc_t *ctdp, tdesc_t *mtdp, equiv_data_t *ed) int (*equiv)(tdesc_t *, tdesc_t *, equiv_data_t *); int mapping; - if (ctdp->t_emark > ed->ed_clear_mark || + if (ctdp->t_emark > ed->ed_clear_mark && mtdp->t_emark > ed->ed_clear_mark) return (ctdp->t_emark == mtdp->t_emark); diff --git a/contrib/byacc/test/yacc/calc.tab.c b/contrib/byacc/test/yacc/calc.tab.c index 762dfa182e2..ac7240d3114 100644 --- a/contrib/byacc/test/yacc/calc.tab.c +++ b/contrib/byacc/test/yacc/calc.tab.c @@ -150,7 +150,7 @@ extern int YYPARSE_DECL(); #define LETTER 258 #define UMINUS 259 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT calc_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/calc1.tab.c b/contrib/byacc/test/yacc/calc1.tab.c index 7a5f925f914..22967c81c9e 100644 --- a/contrib/byacc/test/yacc/calc1.tab.c +++ b/contrib/byacc/test/yacc/calc1.tab.c @@ -175,7 +175,7 @@ extern int YYPARSE_DECL(); #define CONST 259 #define UMINUS 260 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT calc1_lhs[] = { -1, 3, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, diff --git a/contrib/byacc/test/yacc/calc2.tab.c b/contrib/byacc/test/yacc/calc2.tab.c index dc82b8e2567..dbd52a186c5 100644 --- a/contrib/byacc/test/yacc/calc2.tab.c +++ b/contrib/byacc/test/yacc/calc2.tab.c @@ -152,7 +152,7 @@ extern int YYPARSE_DECL(); #define LETTER 258 #define UMINUS 259 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT calc2_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/calc3.tab.c b/contrib/byacc/test/yacc/calc3.tab.c index d13bc1afb68..db5d367689d 100644 --- a/contrib/byacc/test/yacc/calc3.tab.c +++ b/contrib/byacc/test/yacc/calc3.tab.c @@ -157,7 +157,7 @@ extern int YYPARSE_DECL(); #define LETTER 258 #define UMINUS 259 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT calc3_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/code_calc.code.c b/contrib/byacc/test/yacc/code_calc.code.c index 43291db28c4..94c86b0b78c 100644 --- a/contrib/byacc/test/yacc/code_calc.code.c +++ b/contrib/byacc/test/yacc/code_calc.code.c @@ -160,7 +160,7 @@ typedef int YYSTYPE; #define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a)) extern int YYPARSE_DECL(); -typedef short YYINT; +typedef int YYINT; extern YYINT yylhs[]; extern YYINT yylen[]; extern YYINT yydefred[]; diff --git a/contrib/byacc/test/yacc/code_calc.tab.c b/contrib/byacc/test/yacc/code_calc.tab.c index e72fa8421c4..428375dbf44 100644 --- a/contrib/byacc/test/yacc/code_calc.tab.c +++ b/contrib/byacc/test/yacc/code_calc.tab.c @@ -1,4 +1,4 @@ -typedef short YYINT; +typedef int YYINT; const YYINT calc_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/code_error.code.c b/contrib/byacc/test/yacc/code_error.code.c index 38d3e5866b3..a52d316a418 100644 --- a/contrib/byacc/test/yacc/code_error.code.c +++ b/contrib/byacc/test/yacc/code_error.code.c @@ -152,7 +152,7 @@ typedef int YYSTYPE; #define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a)) extern int YYPARSE_DECL(); -typedef short YYINT; +typedef int YYINT; extern YYINT yylhs[]; extern YYINT yylen[]; extern YYINT yydefred[]; diff --git a/contrib/byacc/test/yacc/code_error.tab.c b/contrib/byacc/test/yacc/code_error.tab.c index 9296aa5b1e2..d394ad80849 100644 --- a/contrib/byacc/test/yacc/code_error.tab.c +++ b/contrib/byacc/test/yacc/code_error.tab.c @@ -1,4 +1,4 @@ -typedef short YYINT; +typedef int YYINT; const YYINT error_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/empty.tab.c b/contrib/byacc/test/yacc/empty.tab.c index da0c4be7a22..d211255b852 100644 --- a/contrib/byacc/test/yacc/empty.tab.c +++ b/contrib/byacc/test/yacc/empty.tab.c @@ -144,7 +144,7 @@ typedef int YYSTYPE; extern int YYPARSE_DECL(); #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT empty_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/err_syntax10.tab.c b/contrib/byacc/test/yacc/err_syntax10.tab.c index a3b450960ef..ec244c99ea6 100644 --- a/contrib/byacc/test/yacc/err_syntax10.tab.c +++ b/contrib/byacc/test/yacc/err_syntax10.tab.c @@ -134,7 +134,7 @@ static void yyerror(const char *); extern int YYPARSE_DECL(); #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT err_syntax10_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/err_syntax11.tab.c b/contrib/byacc/test/yacc/err_syntax11.tab.c index ebb065f4589..46e5d2e3525 100644 --- a/contrib/byacc/test/yacc/err_syntax11.tab.c +++ b/contrib/byacc/test/yacc/err_syntax11.tab.c @@ -140,7 +140,7 @@ typedef int YYSTYPE; extern int YYPARSE_DECL(); #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT err_syntax11_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/err_syntax12.tab.c b/contrib/byacc/test/yacc/err_syntax12.tab.c index 784a45ffe90..5afd3d135d8 100644 --- a/contrib/byacc/test/yacc/err_syntax12.tab.c +++ b/contrib/byacc/test/yacc/err_syntax12.tab.c @@ -141,7 +141,7 @@ extern int YYPARSE_DECL(); #define text 456 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT err_syntax12_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/err_syntax18.tab.c b/contrib/byacc/test/yacc/err_syntax18.tab.c index fb7b06c40cf..5b7bef787fa 100644 --- a/contrib/byacc/test/yacc/err_syntax18.tab.c +++ b/contrib/byacc/test/yacc/err_syntax18.tab.c @@ -140,7 +140,7 @@ typedef int YYSTYPE; extern int YYPARSE_DECL(); #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT err_syntax18_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/err_syntax20.tab.c b/contrib/byacc/test/yacc/err_syntax20.tab.c index 85ea1ba908e..690daefa3f3 100644 --- a/contrib/byacc/test/yacc/err_syntax20.tab.c +++ b/contrib/byacc/test/yacc/err_syntax20.tab.c @@ -135,7 +135,7 @@ extern int YYPARSE_DECL(); #define recur 257 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT err_syntax20_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/error.tab.c b/contrib/byacc/test/yacc/error.tab.c index e7aa39508c4..df363825fc2 100644 --- a/contrib/byacc/test/yacc/error.tab.c +++ b/contrib/byacc/test/yacc/error.tab.c @@ -140,7 +140,7 @@ typedef int YYSTYPE; extern int YYPARSE_DECL(); #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT error_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/grammar.tab.c b/contrib/byacc/test/yacc/grammar.tab.c index e78f1881512..8dc8cf933b8 100644 --- a/contrib/byacc/test/yacc/grammar.tab.c +++ b/contrib/byacc/test/yacc/grammar.tab.c @@ -453,7 +453,7 @@ extern int YYPARSE_DECL(); #define T_ASMARG 290 #define T_VA_DCL 291 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT grammar_lhs[] = { -1, 0, 0, 26, 26, 27, 27, 27, 27, 27, 27, 27, 31, 30, 30, 28, 28, 34, 28, 32, 32, diff --git a/contrib/byacc/test/yacc/ok_syntax1.tab.c b/contrib/byacc/test/yacc/ok_syntax1.tab.c index 94d67d93bd9..0446ec57c6b 100644 --- a/contrib/byacc/test/yacc/ok_syntax1.tab.c +++ b/contrib/byacc/test/yacc/ok_syntax1.tab.c @@ -178,7 +178,7 @@ extern int YYPARSE_DECL(); #define VT 272 #define UMINUS 273 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT ok_syntax1_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/pure_calc.tab.c b/contrib/byacc/test/yacc/pure_calc.tab.c index 911db408e31..3505bc4ffdc 100644 --- a/contrib/byacc/test/yacc/pure_calc.tab.c +++ b/contrib/byacc/test/yacc/pure_calc.tab.c @@ -160,7 +160,7 @@ extern int YYPARSE_DECL(); #define LETTER 258 #define UMINUS 259 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT calc_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/pure_error.tab.c b/contrib/byacc/test/yacc/pure_error.tab.c index 0184e924fab..41effc1176b 100644 --- a/contrib/byacc/test/yacc/pure_error.tab.c +++ b/contrib/byacc/test/yacc/pure_error.tab.c @@ -152,7 +152,7 @@ typedef int YYSTYPE; extern int YYPARSE_DECL(); #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT error_lhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/quote_calc-s.tab.c b/contrib/byacc/test/yacc/quote_calc-s.tab.c index 9d4d7bd5835..caab2481102 100644 --- a/contrib/byacc/test/yacc/quote_calc-s.tab.c +++ b/contrib/byacc/test/yacc/quote_calc-s.tab.c @@ -156,7 +156,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc.tab.c b/contrib/byacc/test/yacc/quote_calc.tab.c index affdbe56db3..b01685245c1 100644 --- a/contrib/byacc/test/yacc/quote_calc.tab.c +++ b/contrib/byacc/test/yacc/quote_calc.tab.c @@ -162,7 +162,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc2-s.tab.c b/contrib/byacc/test/yacc/quote_calc2-s.tab.c index 47b8fd0d3b1..16de64b6552 100644 --- a/contrib/byacc/test/yacc/quote_calc2-s.tab.c +++ b/contrib/byacc/test/yacc/quote_calc2-s.tab.c @@ -156,7 +156,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc2_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc2.tab.c b/contrib/byacc/test/yacc/quote_calc2.tab.c index cdf8171f02e..f03cfb636c0 100644 --- a/contrib/byacc/test/yacc/quote_calc2.tab.c +++ b/contrib/byacc/test/yacc/quote_calc2.tab.c @@ -162,7 +162,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc2_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc3-s.tab.c b/contrib/byacc/test/yacc/quote_calc3-s.tab.c index b91c1a14a02..f85e6754a4d 100644 --- a/contrib/byacc/test/yacc/quote_calc3-s.tab.c +++ b/contrib/byacc/test/yacc/quote_calc3-s.tab.c @@ -156,7 +156,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc3_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc3.tab.c b/contrib/byacc/test/yacc/quote_calc3.tab.c index ad4fe1ae6bf..59739980ce4 100644 --- a/contrib/byacc/test/yacc/quote_calc3.tab.c +++ b/contrib/byacc/test/yacc/quote_calc3.tab.c @@ -156,7 +156,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc3_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc4-s.tab.c b/contrib/byacc/test/yacc/quote_calc4-s.tab.c index 4d1e3d4376f..643567605ac 100644 --- a/contrib/byacc/test/yacc/quote_calc4-s.tab.c +++ b/contrib/byacc/test/yacc/quote_calc4-s.tab.c @@ -156,7 +156,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc4_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/quote_calc4.tab.c b/contrib/byacc/test/yacc/quote_calc4.tab.c index a5f047ec8d3..b8dff595c91 100644 --- a/contrib/byacc/test/yacc/quote_calc4.tab.c +++ b/contrib/byacc/test/yacc/quote_calc4.tab.c @@ -156,7 +156,7 @@ extern int YYPARSE_DECL(); #define LETTER 270 #define UMINUS 271 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT quote_calc4_lhs[] = { -1, 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, diff --git a/contrib/byacc/test/yacc/rename_debug.c b/contrib/byacc/test/yacc/rename_debug.c index 5202074113c..6bdd4a4b2c6 100644 --- a/contrib/byacc/test/yacc/rename_debug.c +++ b/contrib/byacc/test/yacc/rename_debug.c @@ -16,7 +16,7 @@ #line 17 "rename_debug.c" #include "rename_debug.i" #include "rename_debug.h" -typedef short YYINT; +typedef int YYINT; static const YYINT yylhs[] = { -1, 0, }; diff --git a/contrib/byacc/test/yacc/varsyntax_calc1.tab.c b/contrib/byacc/test/yacc/varsyntax_calc1.tab.c index 49a1527817c..6094f8b28cb 100644 --- a/contrib/byacc/test/yacc/varsyntax_calc1.tab.c +++ b/contrib/byacc/test/yacc/varsyntax_calc1.tab.c @@ -176,7 +176,7 @@ extern int YYPARSE_DECL(); #define CONST 259 #define UMINUS 260 #define YYERRCODE 256 -typedef short YYINT; +typedef int YYINT; static const YYINT varsyntax_calc1_lhs[] = { -1, 3, 3, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, diff --git a/contrib/hyperv/tools/hv_kvp_daemon.c b/contrib/hyperv/tools/hv_kvp_daemon.c index b0a84d41109..1c31d3f9b62 100644 --- a/contrib/hyperv/tools/hv_kvp_daemon.c +++ b/contrib/hyperv/tools/hv_kvp_daemon.c @@ -285,7 +285,7 @@ kvp_file_init(void) int alloc_unit = sizeof(struct kvp_record) * ENTRIES_PER_BLOCK; if (mkdir("/var/db/hyperv/pool", S_IRUSR | S_IWUSR | S_IROTH) < 0 && - errno != EISDIR) { + (errno != EEXIST && errno != EISDIR)) { KVP_LOG(LOG_ERR, " Failed to create /var/db/hyperv/pool\n"); exit(EXIT_FAILURE); } @@ -511,25 +511,25 @@ kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value, static int -kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size, +kvp_pool_enumerate(int pool, int idx, __u8 *key, int key_size, __u8 *value, int value_size) { struct kvp_record *record; KVP_LOG(LOG_DEBUG, "kvp_pool_enumerate: pool = %d, index = %d\n,", - pool, index); + pool, idx); /* First update our in-memory state first. */ kvp_update_mem_state(pool); record = kvp_pools[pool].records; /* Index starts with 0 */ - if (index >= kvp_pools[pool].num_records) { + if (idx >= kvp_pools[pool].num_records) { return (1); } - memcpy(key, record[index].key, key_size); - memcpy(value, record[index].value, value_size); + memcpy(key, record[idx].key, key_size); + memcpy(value, record[idx].value, value_size); return (0); } diff --git a/contrib/libxo/README.md b/contrib/libxo/README.md index 40c162b0875..e9b3b4bd093 100644 --- a/contrib/libxo/README.md +++ b/contrib/libxo/README.md @@ -60,3 +60,5 @@ option: View the beautiful documentation at: http://juniper.github.io/libxo/libxo-manual.html + +[![Analytics](https://ga-beacon.appspot.com/UA-56056421-1/Juniper/libxo/Readme)](https://github.com/Juniper/libxo) diff --git a/contrib/libxo/configure.ac b/contrib/libxo/configure.ac index 2412d12cf0a..904af12bf68 100644 --- a/contrib/libxo/configure.ac +++ b/contrib/libxo/configure.ac @@ -12,7 +12,7 @@ # AC_PREREQ(2.2) -AC_INIT([libxo], [0.1.4], [phil@juniper.net]) +AC_INIT([libxo], [0.1.6], [phil@juniper.net]) AM_INIT_AUTOMAKE([-Wall -Werror foreign -Wno-portability]) # Support silent build rules. Requires at least automake-1.11. diff --git a/contrib/libxo/libxo/libxo.c b/contrib/libxo/libxo/libxo.c index ebe55b9e4fd..89adc03fe2f 100644 --- a/contrib/libxo/libxo/libxo.c +++ b/contrib/libxo/libxo/libxo.c @@ -79,7 +79,7 @@ struct xo_handle_s { unsigned short xo_indent; /* Indent level (if pretty) */ unsigned short xo_indent_by; /* Indent amount (tab stop) */ xo_write_func_t xo_write; /* Write callback */ - xo_close_func_t xo_close; /* Clo;se callback */ + xo_close_func_t xo_close; /* Close callback */ xo_formatter_t xo_formatter; /* Custom formating function */ xo_checkpointer_t xo_checkpointer; /* Custom formating support function */ void *xo_opaque; /* Opaque data for write function */ @@ -317,7 +317,7 @@ xo_init_handle (xo_handle_t *xop) cp = getenv("LC_ALL"); if (cp == NULL) cp = "UTF-8"; /* Optimistic? */ - cp = setlocale(LC_CTYPE, cp); + (void) setlocale(LC_CTYPE, cp); } /* @@ -607,8 +607,10 @@ xo_vsnprintf (xo_handle_t *xop, xo_buffer_t *xbp, const char *fmt, va_list vap) rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); if (rc > xbp->xb_size) { - if (!xo_buf_has_room(xbp, rc)) + if (!xo_buf_has_room(xbp, rc)) { + va_end(va_local); return -1; + } /* * After we call vsnprintf(), the stage of vap is not defined. @@ -648,8 +650,10 @@ xo_printf_v (xo_handle_t *xop, const char *fmt, va_list vap) rc = vsnprintf(xbp->xb_curp, left, fmt, va_local); if (rc > xbp->xb_size) { - if (!xo_buf_has_room(xbp, rc)) + if (!xo_buf_has_room(xbp, rc)) { + va_end(va_local); return -1; + } va_end(va_local); /* Reset vap to the start */ va_copy(va_local, vap); @@ -974,8 +978,10 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn, int left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); int rc = vsnprintf(xbp->xb_curp, left, newfmt, vap); if (rc > xbp->xb_size) { - if (!xo_buf_has_room(xbp, rc)) + if (!xo_buf_has_room(xbp, rc)) { + va_end(va_local); return; + } va_end(vap); /* Reset vap to the start */ va_copy(vap, va_local); @@ -1118,8 +1124,10 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) int left = xbp->xb_size - (xbp->xb_curp - xbp->xb_bufp); rc = vsnprintf(xbp->xb_curp, left, fmt, vap); if (rc > xbp->xb_size) { - if (!xo_buf_has_room(xbp, rc)) + if (!xo_buf_has_room(xbp, rc)) { + va_end(va_local); return; + } va_end(vap); /* Reset vap to the start */ va_copy(vap, va_local); @@ -1154,14 +1162,15 @@ xo_message_hcv (xo_handle_t *xop, int code, const char *fmt, va_list vap) va_copy(va_local, vap); - rc = vsnprintf(buf, bufsiz, fmt, va_local); + rc = vsnprintf(bp, bufsiz, fmt, va_local); if (rc > bufsiz) { bufsiz = rc + BUFSIZ; bp = alloca(bufsiz); va_end(va_local); va_copy(va_local, vap); - rc = vsnprintf(buf, bufsiz, fmt, va_local); + rc = vsnprintf(bp, bufsiz, fmt, va_local); } + va_end(va_local); cp = bp + rc; if (need_nl) { @@ -1302,9 +1311,9 @@ xo_create_to_file (FILE *fp, xo_style_t style, xo_xof_flags_t flags) * @xop XO handle to alter (or NULL for default handle) */ void -xo_destroy (xo_handle_t *xop) +xo_destroy (xo_handle_t *xop_arg) { - xop = xo_default(xop); + xo_handle_t *xop = xo_default(xop_arg); if (xop->xo_close && (xop->xo_flags & XOF_CLOSE_FP)) xop->xo_close(xop->xo_opaque); @@ -1315,7 +1324,7 @@ xo_destroy (xo_handle_t *xop) xo_buf_cleanup(&xop->xo_predicate); xo_buf_cleanup(&xop->xo_attrs); - if (xop == &xo_default_handle) { + if (xop_arg == NULL) { bzero(&xo_default_handle, sizeof(&xo_default_handle)); xo_default_inited = 0; } else @@ -1743,7 +1752,7 @@ xo_format_string_direct (xo_handle_t *xop, xo_buffer_t *xbp, int need_enc, int have_enc) { int cols = 0; - wchar_t wc; + wchar_t wc = 0; int ilen, olen, width; int attr = (flags & XFF_ATTR); const char *sp; @@ -1912,6 +1921,7 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, xo_format_t *xfp) { static char null[] = "(null)"; + char *cp = NULL; wchar_t *wcp = NULL; int len, cols = 0, rc = 0; @@ -1922,16 +1932,33 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, if (xo_check_conversion(xop, xfp->xf_enc, need_enc)) return 0; + len = xfp->xf_width[XF_WIDTH_SIZE]; + if (xfp->xf_enc == XF_ENC_WIDE) { wcp = va_arg(xop->xo_vap, wchar_t *); if (xfp->xf_skip) return 0; + /* + * Dont' deref NULL; use the traditional "(null)" instead + * of the more accurate "who's been a naughty boy, then?". + */ + if (wcp == NULL) { + cp = null; + len = sizeof(null) - 1; + } + } else { cp = va_arg(xop->xo_vap, char *); /* UTF-8 or native */ if (xfp->xf_skip) return 0; + /* Echo "Dont' deref NULL" logic */ + if (cp == NULL) { + cp = null; + len = sizeof(null) - 1; + } + /* * Optimize the most common case, which is "%s". We just * need to copy the complete string to the output buffer. @@ -1957,17 +1984,6 @@ xo_format_string (xo_handle_t *xop, xo_buffer_t *xbp, xo_xff_flags_t flags, } } - len = xfp->xf_width[XF_WIDTH_SIZE]; - - /* - * Dont' deref NULL; use the traditional "(null)" instead - * of the more accurate "who's been a naughty boy, then?". - */ - if (cp == NULL && wcp == NULL) { - cp = null; - len = sizeof(null) - 1; - } - cols = xo_format_string_direct(xop, xbp, flags, wcp, cp, len, xfp->xf_width[XF_WIDTH_MAX], need_enc, xfp->xf_enc); @@ -3859,7 +3875,7 @@ xo_close_list_h (xo_handle_t *xop, const char *name) rc = xo_printf(xop, "%s%*s]", pre_nl, xo_indent(xop), ""); xop->xo_stack[xop->xo_depth].xs_flags |= XSF_NOT_FIRST; - return 0; + return rc; } int diff --git a/contrib/libxo/libxo/xoconfig.h b/contrib/libxo/libxo/xoconfig.h index 7a6dbe8b78b..0870e358720 100644 --- a/contrib/libxo/libxo/xoconfig.h +++ b/contrib/libxo/libxo/xoconfig.h @@ -158,7 +158,7 @@ #define PACKAGE_NAME "libxo" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libxo 0.1.4" +#define PACKAGE_STRING "libxo 0.1.6" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libxo" @@ -167,7 +167,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.1.4" +#define PACKAGE_VERSION "0.1.6" /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be @@ -181,7 +181,7 @@ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "0.1.4" +#define VERSION "0.1.6" /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ diff --git a/contrib/libxo/libxo/xoversion.h b/contrib/libxo/libxo/xoversion.h index 51da744036e..60c6118be93 100644 --- a/contrib/libxo/libxo/xoversion.h +++ b/contrib/libxo/libxo/xoversion.h @@ -18,17 +18,17 @@ /** * The version string */ -#define LIBXO_VERSION "0.1.4" +#define LIBXO_VERSION "0.1.6" /** * The version number */ -#define LIBXO_VERSION_NUMBER 1004 +#define LIBXO_VERSION_NUMBER 1006 /** * The version number as a string */ -#define LIBXO_VERSION_STRING "1004" +#define LIBXO_VERSION_STRING "1006" /** * The version number extra info as a string diff --git a/contrib/libxo/tests/core/Makefile.am b/contrib/libxo/tests/core/Makefile.am index a87fcc55adc..a5470f37547 100644 --- a/contrib/libxo/tests/core/Makefile.am +++ b/contrib/libxo/tests/core/Makefile.am @@ -30,7 +30,7 @@ test_07_test_SOURCES = test_07.c # TEST_CASES := $(shell cd ${srcdir} ; echo *.c ) -bin_PROGRAMS = ${TEST_CASES:.c=.test} +noinst_PROGRAMS = ${TEST_CASES:.c=.test} LDADD = \ ${top_builddir}/libxo/libxo.la @@ -66,7 +66,7 @@ valgrind: TEST_ONE = \ LIBXO_OPTIONS=:W$$fmt \ - ${CHECKER} $$base.test ${TEST_OPTS} \ + ${CHECKER} ./$$base.test ${TEST_OPTS} \ > out/$$base.$$fmt.out 2> out/$$base.$$fmt.err ; \ ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.out out/$$base.$$fmt.out ${S2O} ; \ ${DIFF} -Nu ${srcdir}/saved/$$base.$$fmt.err out/$$base.$$fmt.err ${S2O} diff --git a/contrib/libxo/tests/core/saved/test_07.J.out b/contrib/libxo/tests/core/saved/test_07.J.out index 2c9a9286f20..9285ff5a6c5 100644 --- a/contrib/libxo/tests/core/saved/test_07.J.out +++ b/contrib/libxo/tests/core/saved/test_07.J.out @@ -1,2 +1,2 @@ -{"employees": {"v1":"γιγνώσκειν","v2":"ὦ ἄνδρες ᾿Αθηναῖοι","columns":28,"columns":2,"v1":"ახლავე გაიაროთ რეგისტრაცია","v2":"Unicode-ის მეათე საერთაშორისო","columns":55, "employee": ["columns":0, {"first-name":"Jim","nic-name":"\"რეგტ\"","last-name":"გთხოვთ ახ","department":431,"percent-time":90,"columns":23,"benefits":"full"}, {"first-name":"Terry","nic-name":"\"γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοι282ახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო550Jim"რეგტ"გთხოვთ ახ4319023fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones6609047fullLeslie"Les"Patterson3416025fullAshley"Ash"Meter & Smith144040300123456789"0123456789"01234567890123456789014404049ახლა"გაიარო"საერთაშორისო1239029full \ No newline at end of file +(null)γιγνώσκεινὦ ἄνδρες ᾿Αθηναῖοι282ახლავე გაიაროთ რეგისტრაციაUnicode-ის მეათე საერთაშორისო550Jim"რეგტ"გთხოვთ ახ4319023fullTerry"<one"Οὐχὶ ταὐτὰ παρίσταταί μοι Jones6609047fullLeslie"Les"Patterson3416025fullAshley"Ash"Meter & Smith144040300123456789"0123456789"01234567890123456789014404049ახლა"გაიარო"საერთაშორისო1239029full \ No newline at end of file diff --git a/contrib/libxo/tests/core/saved/test_07.XP.out b/contrib/libxo/tests/core/saved/test_07.XP.out index b502650596d..c13f838c85f 100644 --- a/contrib/libxo/tests/core/saved/test_07.XP.out +++ b/contrib/libxo/tests/core/saved/test_07.XP.out @@ -1,4 +1,7 @@ + + (null) + γιγνώσκειν ὦ ἄνδρες ᾿Αθηναῖοι 28 diff --git a/contrib/libxo/tests/core/test_07.c b/contrib/libxo/tests/core/test_07.c index 3ceba8edf6a..18b7baa146b 100644 --- a/contrib/libxo/tests/core/test_07.c +++ b/contrib/libxo/tests/core/test_07.c @@ -52,6 +52,12 @@ main (int argc, char **argv) xo_open_container("employees"); + xo_open_list("test"); + xo_open_instance("test"); + xo_emit("{ek:filename/%s}", NULL); + xo_close_instance("test"); + xo_close_list("test"); + rc = xo_emit("Οὐχὶ ταὐτὰ παρίσταταί μοι {:v1/%s}, {:v2/%s}\n", "γιγνώσκειν", "ὦ ἄνδρες ᾿Αθηναῖοι"); rc = xo_emit("{:columns/%d}\n", rc); diff --git a/contrib/libxo/xolint/xolint.pl b/contrib/libxo/xolint/xolint.pl index 8693e62bff8..427edf7aa95 100755 --- a/contrib/libxo/xolint/xolint.pl +++ b/contrib/libxo/xolint/xolint.pl @@ -28,6 +28,19 @@ sub main { extract_samples() if /^-X/; } + if ($#ARGV < 0) { + print STDERR "xolint [options] files ...\n"; + print STDERR " -c invoke 'cpp' on input\n"; + print STDERR " -C flags Pass flags to cpp\n"; + print STDERR " -d Show debug output\n"; + print STDERR " -D Extract xolint documentation\n"; + print STDERR " -I Print xo_info_t data\n"; + print STDERR " -p Print input data on errors\n"; + print STDERR " -V Print vocabulary (list of tags)\n"; + print STDERR " -X Print examples of invalid use\n"; + exit(1); + } + for $file (@ARGV) { parse_file($file); } @@ -269,9 +282,9 @@ sub check_format { $last = $prev; next; } + $prev = $ch; } - $prev = $ch; $build[$phase] .= $ch; } @@ -346,18 +359,6 @@ sub check_field { info("potential missing slash after N, L, or T with format") if $field[1] =~ /%/; - #@ Format cannot be given when content is present (roles: DNLT) - #@ xo_emit("{T:Max/%6.6s}", "Max"); - #@ Fields with the D, N, L, or T roles can't have both - #@ static literal content ("{T:Title}") and a - #@ format ("{T:/%s}"). - #@ This error will also occur when the content has a backslash - #@ in it, like "{N:Type of I/O}"; backslashes should be escaped, - #@ like "{N:Type of I\\/O}". Note the double backslash, one for - #@ handling 'C' strings, and one for libxo. - error("format cannot be given when content is present") - if $field[1] && $field[2]; - #@ An encoding format cannot be given (roles: DNLT) #@ xo_emit("{T:Max//%s}", "Max"); #@ Fields with the D, N, L, and T roles are not emitted in @@ -367,6 +368,21 @@ sub check_field { if $field[3]; } + # Field is a decoration, label, or title + if ($field[0] =~ /DLN/) { + #@ Format cannot be given when content is present (roles: DLN) + #@ xo_emit("{N:Max/%6.6s}", "Max"); + #@ Fields with the D, L, or N roles can't have both + #@ static literal content ("{L:Label}") and a + #@ format ("{L:/%s}"). + #@ This error will also occur when the content has a backslash + #@ in it, like "{N:Type of I/O}"; backslashes should be escaped, + #@ like "{N:Type of I\\/O}". Note the double backslash, one for + #@ handling 'C' strings, and one for libxo. + error("format cannot be given when content is present") + if $field[1] && $field[2]; + } + # A value field if (length($field[0]) == 0 || $field[0] =~ /V/) { @@ -527,7 +543,7 @@ sub check_field_format { #@ for non-strings. This error may occur from a typo, #@ like "{:tag/%6..6d}" where only one period should be used. error("max width only valid for strings") - if $#chunks >= 2 && $fc =~ /[sS]/; + if $#chunks >= 2 && $fc !~ /[sS]/; } sub error { diff --git a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h index 82becca315a..9e1115b117c 100644 --- a/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/contrib/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -127,6 +127,10 @@ public: DbgValMap[Node].push_back(V); } + /// \brief Invalidate all DbgValues attached to the node and remove + /// it from the Node-to-DbgValues map. + void erase(const SDNode *Node); + void clear() { DbgValMap.clear(); DbgValues.clear(); diff --git a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 45d5a4fa69e..00ffe00d407 100644 --- a/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/contrib/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -625,6 +625,15 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { DeallocateNode(N); } +void SDDbgInfo::erase(const SDNode *Node) { + DbgValMapType::iterator I = DbgValMap.find(Node); + if (I == DbgValMap.end()) + return; + for (unsigned J = 0, N = I->second.size(); J != N; ++J) + I->second[J]->setIsInvalidated(); + DbgValMap.erase(I); +} + void SelectionDAG::DeallocateNode(SDNode *N) { if (N->OperandsNeedDelete) delete[] N->OperandList; @@ -635,10 +644,9 @@ void SelectionDAG::DeallocateNode(SDNode *N) { NodeAllocator.Deallocate(AllNodes.remove(N)); - // If any of the SDDbgValue nodes refer to this SDNode, invalidate them. - ArrayRef DbgVals = DbgInfo->getSDDbgValues(N); - for (unsigned i = 0, e = DbgVals.size(); i != e; ++i) - DbgVals[i]->setIsInvalidated(); + // If any of the SDDbgValue nodes refer to this SDNode, invalidate + // them and forget about that node. + DbgInfo->erase(N); } /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that diff --git a/contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff b/contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff new file mode 100644 index 00000000000..f70ddcef894 --- /dev/null +++ b/contrib/llvm/patches/patch-r274442-llvm-r221709-debug-oom.diff @@ -0,0 +1,73 @@ +Pull in r221709 from upstream llvm trunk (by Frédéric Riss): + + Totally forget deallocated SDNodes in SDDbgInfo. + + What would happen before that commit is that the SDDbgValues associated with + a deallocated SDNode would be marked Invalidated, but SDDbgInfo would keep + a map entry keyed by the SDNode pointer pointing to this list of invalidated + SDDbgNodes. As the memory gets reused, the list might get wrongly associated + with another new SDNode. As the SDDbgValues are cloned when they are transfered, + this can lead to an exponential number of SDDbgValues being produced during + DAGCombine like in http://llvm.org/bugs/show_bug.cgi?id=20893 + + Note that the previous behavior wasn't really buggy as the invalidation made + sure that the SDDbgValues won't be used. This commit can be considered a + memory optimization and as such is really hard to validate in a unit-test. + +This should fix abnormally large memory usage and resulting OOM crashes +when compiling certain ports with debug information. + +Reported by: Dmitry Marakasov +Upstream PRs: http://llvm.org/PR19031 http://llvm.org/PR20893 + +Introduced here: http://svnweb.freebsd.org/changeset/base/274442 + +Index: include/llvm/CodeGen/SelectionDAG.h +=================================================================== +--- include/llvm/CodeGen/SelectionDAG.h ++++ include/llvm/CodeGen/SelectionDAG.h +@@ -127,6 +127,10 @@ class SDDbgInfo { + DbgValMap[Node].push_back(V); + } + ++ /// \brief Invalidate all DbgValues attached to the node and remove ++ /// it from the Node-to-DbgValues map. ++ void erase(const SDNode *Node); ++ + void clear() { + DbgValMap.clear(); + DbgValues.clear(); +Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp +=================================================================== +--- lib/CodeGen/SelectionDAG/SelectionDAG.cpp ++++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp +@@ -625,6 +625,15 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode * + DeallocateNode(N); + } + ++void SDDbgInfo::erase(const SDNode *Node) { ++ DbgValMapType::iterator I = DbgValMap.find(Node); ++ if (I == DbgValMap.end()) ++ return; ++ for (unsigned J = 0, N = I->second.size(); J != N; ++J) ++ I->second[J]->setIsInvalidated(); ++ DbgValMap.erase(I); ++} ++ + void SelectionDAG::DeallocateNode(SDNode *N) { + if (N->OperandsNeedDelete) + delete[] N->OperandList; +@@ -635,10 +644,9 @@ void SelectionDAG::DeallocateNode(SDNode *N) { + + NodeAllocator.Deallocate(AllNodes.remove(N)); + +- // If any of the SDDbgValue nodes refer to this SDNode, invalidate them. +- ArrayRef DbgVals = DbgInfo->getSDDbgValues(N); +- for (unsigned i = 0, e = DbgVals.size(); i != e; ++i) +- DbgVals[i]->setIsInvalidated(); ++ // If any of the SDDbgValue nodes refer to this SDNode, invalidate ++ // them and forget about that node. ++ DbgInfo->erase(N); + } + + /// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c index e9982495694..5bbf337efd9 100644 --- a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c +++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c @@ -31,7 +31,7 @@ */ -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif #include @@ -251,7 +251,7 @@ ATF_TC_BODY(t_spawn_open_nonexistent, tc) posix_spawn_file_actions_destroy(&fa); } -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TC(t_spawn_open_nonexistent_diag); ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc) @@ -381,7 +381,7 @@ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, t_spawn_fileactions); ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag); #endif ATF_TP_ADD_TC(tp, t_spawn_reopen); diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c index bb3baf01342..1f3998404f3 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c @@ -56,7 +56,7 @@ ATF_TC_BODY(getcwd_err, tc) ATF_REQUIRE(getcwd(buf, 0) == NULL); ATF_REQUIRE(errno == EINVAL); -#if defined(__NetBSD__) +#ifdef __NetBSD__ errno = 0; ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL); diff --git a/contrib/netbsd-tests/lib/libc/gen/t_glob.c b/contrib/netbsd-tests/lib/libc/gen/t_glob.c index 1611bfa0264..198148c6937 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_glob.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c @@ -46,7 +46,7 @@ __RCSID("$NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $"); #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include "h_macros.h" #define __gl_stat_t struct stat #define _S_IFDIR S_IFDIR @@ -138,7 +138,7 @@ gl_readdir(void *v) dir.d_ino = dd->pos; dir.d_type = f->dir ? DT_DIR : DT_REG; DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type)); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ dir.d_reclen = -1; /* Does not have _DIRENT_RECLEN */ #else dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen); @@ -223,7 +223,7 @@ run(const char *p, int flags, const char **res, size_t len) } -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ ATF_TC(glob_star); ATF_TC_HEAD(glob_star, tc) { @@ -272,7 +272,7 @@ ATF_TC_BODY(glob_nocheck, tc) ATF_TP_ADD_TCS(tp) { -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ ATF_TP_ADD_TC(tp, glob_star); #endif ATF_TP_ADD_TC(tp, glob_star_not); diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c index eec2d103332..5836c862916 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c @@ -34,7 +34,7 @@ #include #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #else #include @@ -82,7 +82,7 @@ const struct hnopts { /* * Truncated output. Rev. 1.7 produces "1.0 K". */ -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" }, /* diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c index a0e912be6fb..10b8df7ccb7 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_nice.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c @@ -72,7 +72,7 @@ ATF_TC_BODY(nice_err, tc) { int i; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("nice(incr) with incr < 0 fails with unprivileged " "users and sets errno == EPERM; see PR # 189821 for more details"); #endif @@ -98,7 +98,7 @@ ATF_TC_HEAD(nice_priority, tc) ATF_TC_BODY(nice_priority, tc) { -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ int i, pri, pri2, nic; #else int i, pri, nic; @@ -115,7 +115,7 @@ ATF_TC_BODY(nice_priority, tc) pri = getpriority(PRIO_PROCESS, 0); ATF_REQUIRE(errno == 0); -#if defined(__NetBSD__) +#ifdef __NetBSD__ if (nic != pri) atf_tc_fail("nice(3) and getpriority(2) conflict"); #endif @@ -130,14 +130,14 @@ ATF_TC_BODY(nice_priority, tc) if (pid == 0) { errno = 0; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ pri = getpriority(PRIO_PROCESS, 0); #else pri2 = getpriority(PRIO_PROCESS, 0); #endif ATF_REQUIRE(errno == 0); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ if (pri != pri2) #else if (nic != pri) @@ -180,7 +180,7 @@ ATF_TC_HEAD(nice_thread, tc) ATF_TC_BODY(nice_thread, tc) { pthread_t tid[5]; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ int pri, rv, val; #else int rv, val; @@ -196,7 +196,7 @@ ATF_TC_BODY(nice_thread, tc) val = nice(i); ATF_REQUIRE(val != -1); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ pri = getpriority(PRIO_PROCESS, 0); rv = pthread_create(&tid[i], NULL, threadfunc, &pri); #else diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c index 120981f8466..d6f888fde12 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_raise.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c @@ -43,7 +43,7 @@ static int count; static void handler_err(int); static void handler_ret(int); static void handler_stress(int); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2 }; #else static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR }; diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c index a93083a17f6..f51eb2a9d89 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c @@ -63,7 +63,7 @@ ATF_TC_BODY(setdomainname_basic, tc) (void)memset(name, 0, sizeof(name)); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ /* * Sanity checks to ensure that the wrong invariant isn't being * tested for per PR # 181127 @@ -101,7 +101,7 @@ ATF_TC_BODY(setdomainname_limit, tc) (void)memset(name, 0, sizeof(name)); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0); ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN) == -1); #endif diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c index 6dc79531b6e..9c9a3c743c0 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c @@ -28,7 +28,7 @@ #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif #include @@ -87,7 +87,7 @@ sig_debug(int signo, siginfo_t *info, ucontext_t *ctx) printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp, (unsigned long)ctx->uc_stack.ss_size, ctx->uc_stack.ss_flags); -#if defined(__NetBSD__) +#ifdef __NetBSD__ for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++) printf("uc_mcontext.greg[%d] 0x%lx\n", i, (long)ctx->uc_mcontext.__gregs[i]); @@ -144,7 +144,7 @@ sigchild_action(int signo, siginfo_t *info, void *ptr) printf("si_uid=%d\n", info->si_uid); printf("si_pid=%d\n", info->si_pid); printf("si_status=%d\n", info->si_status); -#if defined(__NetBSD__) +#ifdef __NetBSD__ printf("si_utime=%lu\n", (unsigned long int)info->si_utime); printf("si_stime=%lu\n", (unsigned long int)info->si_stime); #endif diff --git a/contrib/netbsd-tests/lib/libc/gen/t_time.c b/contrib/netbsd-tests/lib/libc/gen/t_time.c index 21e625ffcf2..790f3caada4 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_time.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c @@ -31,7 +31,7 @@ #include __RCSID("$NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $"); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif #include diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c index 80f5c17c1cb..bb9d26420c3 100644 --- a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c +++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c @@ -107,7 +107,7 @@ ATF_TC_BODY(ttyname_r_err, tc) ATF_REQUIRE(rv == ERANGE); } -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("FreeBSD returns ENOTTY instead of EBADF; see bin/191936"); #endif rv = ttyname_r(-1, buf, ttymax); diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c index 7cab9739797..8b3876fa788 100644 --- a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c @@ -132,7 +132,7 @@ h_ctype2(const struct test *t, bool use_mbstate) size_t n; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); #else if (setlocale(LC_CTYPE, t->locale) == NULL) { @@ -245,7 +245,7 @@ ATF_TC_BODY(mbrtowc_internal, tc) { struct test *t; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("ja_* locale fails"); #endif for (t = &tests[0]; t->data != NULL; ++t) diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c index 7395d19bf17..f8c06d394d6 100644 --- a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c @@ -150,7 +150,7 @@ ATF_TC_BODY(mbstowcs_basic, tc) int i; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); #else if (setlocale(LC_CTYPE, t->locale) == NULL) { diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c index bb690607fa0..7816260e928 100644 --- a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c +++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c @@ -76,7 +76,7 @@ h_mbtowc(const char *locale, const char *illegal, const char *legal) char *str; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL); #else if (setlocale(LC_CTYPE, locale) == NULL) { @@ -137,13 +137,13 @@ ATF_TC_BODY(mbtowc, tc) h_mbtowc("ja_JP.ISO2022-JP", "\033$B", "\033$B$\"\033(B"); h_mbtowc("ja_JP.SJIS", "\202", "\202\240"); h_mbtowc("ja_JP.eucJP", "\244", "\244\242"); -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ /* Moved last as it fails */ h_mbtowc("zh_CN.GB18030", "\241", "\241\241"); #endif h_mbtowc("zh_TW.Big5", "\241", "\241@"); h_mbtowc("zh_TW.eucTW", "\241", "\241\241"); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("zh_CN.GB18030"); h_mbtowc("zh_CN.GB18030", "\241", "\241\241"); #endif diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c index fe7b468eb62..8d1ef33a1a2 100644 --- a/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c +++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c @@ -66,7 +66,7 @@ __RCSID("$NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $"); #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c index 06016bf31f6..3405e976101 100644 --- a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c +++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c @@ -109,7 +109,7 @@ h_wctomb(const struct test *t, char tc) size_t sz, ret, i; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); #else if (setlocale(LC_CTYPE, t->locale) == NULL) { diff --git a/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c index 999aa4070e2..2a910607238 100644 --- a/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c +++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c @@ -46,14 +46,14 @@ __RCSID("$NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $"); #include #include -#if !defined(__NetBSD__) -#if defined(__linux__) +#ifndef __NetBSD__ +#ifdef __linux__ #include #endif #include #endif -#if defined(__NetBSD__) +#ifdef __NetBSD__ #define ETHER_ADDR_LEN 6 int ether_aton_r(u_char *dest, size_t len, const char *str); @@ -65,7 +65,7 @@ static const struct { int error; } tests[] = { { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }, "01:23:45:67:89:ab", 0 }, -#if defined(__NetBSD__) +#ifdef __NetBSD__ { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "0:1:22-3:14:05", 0 }, { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "000122031405", 0 }, { { 0x0a, 0x0B, 0xcc, 0xdD, 0xEE, 0x0f }, "0a0BccdDEE0f", 0 }, @@ -86,13 +86,13 @@ ATF_TC_HEAD(tc_ether_aton, tc) ATF_TC_BODY(tc_ether_aton, tc) { -#if defined(__NetBSD__) +#ifdef __NetBSD__ u_char dest[ETHER_ADDR_LEN]; #else struct ether_addr dest; #endif size_t t; -#if defined(__NetBSD__) +#ifdef __NetBSD__ int e, r; #else int e; @@ -103,7 +103,7 @@ ATF_TC_BODY(tc_ether_aton, tc) for (t = 0; tests[t].str; t++) { s = tests[t].str; if ((e = tests[t].error) == 0) { -#if defined(__NetBSD__) +#ifdef __NetBSD__ if (ether_aton_r(dest, sizeof(dest), s) != e) atf_tc_fail("failed on `%s'", s); if (memcmp(dest, tests[t].res, sizeof(dest)) != 0) @@ -115,7 +115,7 @@ ATF_TC_BODY(tc_ether_aton, tc) atf_tc_fail("unexpected result on `%s'", s); #endif } else { -#if defined(__NetBSD__) +#ifdef __NetBSD__ if ((r = ether_aton_r(dest, sizeof(dest), s)) != e) atf_tc_fail("unexpectedly succeeded on `%s' " "(%d != %d)", s, r, e); diff --git a/contrib/netbsd-tests/lib/libc/regex/debug.c b/contrib/netbsd-tests/lib/libc/regex/debug.c index 55655eb8cd9..f1d2b15de63 100644 --- a/contrib/netbsd-tests/lib/libc/regex/debug.c +++ b/contrib/netbsd-tests/lib/libc/regex/debug.c @@ -34,7 +34,7 @@ #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #include #endif @@ -54,7 +54,7 @@ static char *regchar(int); void regprint(regex_t *r, FILE *d) { -#if defined(__NetBSD__) +#ifdef __NetBSD__ struct re_guts *g = r->re_g; int c; int last; @@ -177,7 +177,7 @@ s_print(struct re_guts *g, FILE *d) break; case OANYOF: fprintf(d, "[(%ld)", (long)opnd); -#if defined(__NetBSD__) +#ifdef __NetBSD__ cs = &g->sets[opnd]; last = -1; for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */ @@ -250,7 +250,7 @@ s_print(struct re_guts *g, FILE *d) fprintf(d, ">"); break; default: -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ fprintf(d, "!%ld(%ld)!", OP(*s), opnd); #else fprintf(d, "!%d(%d)!", OP(*s), opnd); diff --git a/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c index bc34441fe4c..0670e514e7e 100644 --- a/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c +++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c @@ -45,7 +45,7 @@ __RCSID("$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $"); #include #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif @@ -179,7 +179,7 @@ ATF_TC_HEAD(regcomp_too_big, tc) " crash, but return a proper error code"); // libtre needs it. atf_tc_set_md_var(tc, "timeout", "600"); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_set_md_var(tc, "require.memory", "64M"); #else atf_tc_set_md_var(tc, "require.memory", "120M"); @@ -189,12 +189,12 @@ ATF_TC_HEAD(regcomp_too_big, tc) ATF_TC_BODY(regcomp_too_big, tc) { regex_t re; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ struct rlimit limit; #endif int e; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ limit.rlim_cur = limit.rlim_max = 64 * 1024 * 1024; ATF_REQUIRE(setrlimit(RLIMIT_VMEM, &limit) != -1); #endif diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c index fb8f2855f98..0ca44b47577 100644 --- a/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c +++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c @@ -48,7 +48,7 @@ __RCSID("$NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $"); #include #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif @@ -377,7 +377,7 @@ checkmatches(const char *matches, size_t nm, const regmatch_t *pm, " cur=%d, max=%zu", res, l, len - off); off += l; } -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ATF_CHECK_STREQ_MSG(res, matches, " at line %zu", lineno); #else ATF_REQUIRE_STREQ_MSG(res, matches, " at line %zu", lineno); @@ -580,7 +580,7 @@ ATF_TC_BODY(leftassoc, tc) * any explation. Mark as broken here, but I don't know why. */ atf_tc_expect_fail("Reason for breakage unknown"); #endif -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("The expected and matched groups are mismatched on FreeBSD"); #endif att_test(tc, "leftassoc"); diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c index d3e1f113aba..c0641dbc6bf 100644 --- a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c @@ -42,7 +42,7 @@ __RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $"); extern int __cxa_atexit(void (*func)(void *), void *, void *); extern void __cxa_finalize(void *); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ /* * On shared object unload, in __cxa_finalize, call and clear all installed * atexit and __cxa_atexit handlers that are either installed by unloaded @@ -191,7 +191,7 @@ main(int argc, char *argv[]) ASSERT(0 == atexit(normal_handler_0)); ASSERT(0 == atexit(normal_handler_1)); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1)); ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1)); ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2)); diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c index 58ecd9639cd..ec2b9bbf3d5 100644 --- a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c @@ -34,7 +34,7 @@ #include #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c index f5ded273de4..2293e2cc957 100644 --- a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c +++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c @@ -36,7 +36,7 @@ #include #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c index 3b0b8850b58..5a8fa282242 100644 --- a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c @@ -40,7 +40,7 @@ __RCSID("$NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $"); #include #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif @@ -155,7 +155,7 @@ ATF_TC_BODY(setenv_basic, tc) ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1); ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1); ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ /* Both FreeBSD and OS/X does not validate the second argument to setenv(3) diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c index 3c869c4f0b9..d66596747f3 100644 --- a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c +++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c @@ -75,7 +75,7 @@ __RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $"); #define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno)) -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TC(hsearch_basic); ATF_TC_HEAD(hsearch_basic, tc) { @@ -231,7 +231,7 @@ ATF_TC_BODY(hsearch_two, tc) hdestroy(); } -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TC(hsearch_r_basic); ATF_TC_HEAD(hsearch_r_basic, tc) { @@ -389,14 +389,14 @@ ATF_TC_BODY(hsearch_r_two, tc) ATF_TP_ADD_TCS(tp) { -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TP_ADD_TC(tp, hsearch_basic); #endif ATF_TP_ADD_TC(tp, hsearch_duplicate); ATF_TP_ADD_TC(tp, hsearch_nonexistent); ATF_TP_ADD_TC(tp, hsearch_two); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TP_ADD_TC(tp, hsearch_r_basic); #endif ATF_TP_ADD_TC(tp, hsearch_r_duplicate); diff --git a/contrib/netbsd-tests/lib/libc/string/t_memcpy.c b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c index c9e52a379a2..192a4e81f7e 100644 --- a/contrib/netbsd-tests/lib/libc/string/t_memcpy.c +++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c @@ -51,7 +51,7 @@ unsigned char *start[BLOCKTYPES] = { }; char result[100]; -#if defined(__NetBSD__) +#ifdef __NetBSD__ const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb"; #else const char goodResult[] = "217b4fbe456916bf62a2f85df752e4ab"; @@ -93,7 +93,7 @@ ATF_TC_BODY(memcpy_basic, tc) start[2] = auto1; start[3] = auto2; -#if defined(__NetBSD__) +#ifdef __NetBSD__ srandom(0L); #else /* diff --git a/contrib/netbsd-tests/lib/libc/string/t_strerror.c b/contrib/netbsd-tests/lib/libc/string/t_strerror.c index cb008d79ce8..888a8261f8d 100644 --- a/contrib/netbsd-tests/lib/libc/string/t_strerror.c +++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c @@ -37,7 +37,7 @@ __RCSID("$NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $"); #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c index 0bd6a262e17..b8b399e7ee2 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_access.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c @@ -40,7 +40,7 @@ __RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $"); #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c index 37a426707a6..229c343c7a8 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c @@ -63,7 +63,7 @@ __RCSID("$NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $"); #include #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif @@ -75,7 +75,7 @@ __RCSID("$NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $"); #include #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include "../../../h_macros.h" #else #include diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c index 12628c23900..7dedca44528 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c @@ -57,7 +57,7 @@ ATF_TC_BODY(getgroups_err, tc) errno = 0; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("Reported as kern/189941"); #endif ATF_REQUIRE(getgroups(-1, gidset) == -1); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c index 669c7042ff0..85eeac6bee0 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c @@ -47,7 +47,7 @@ static void sighandler(int); static const size_t maxiter = 2000; static void -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ sighandler(int signo __unused) #else sighandler(int signo) diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c index 5578adcdd48..fe298c55282 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c @@ -149,11 +149,11 @@ ATF_TC_BODY(kqueue_desc_passing, tc) printf("parent (pid %d): sending kq fd %d\n", getpid(), kq); if (sendmsg(s[0], &m, 0) == -1) { -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno); atf_tc_skip("PR kern/46523"); #endif -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ATF_REQUIRE_EQ_MSG(errno, EOPNOTSUPP, "errno is %d", errno); close(s[0]); #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_listen.c b/contrib/netbsd-tests/lib/libc/sys/t_listen.c index 1de1e874f69..d7c7d9e02d4 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_listen.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c @@ -36,7 +36,7 @@ #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c index ce68336bd32..70f890682a7 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c @@ -47,7 +47,7 @@ __RCSID("$NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $"); #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c index fddf5eb3967..d30cb7b97f2 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c @@ -47,7 +47,7 @@ __RCSID("$NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $"); #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c index 1712d813a5d..b4d9f8a809e 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c @@ -45,7 +45,7 @@ __RCSID("$NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $"); #include static void -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ handler(int signo __unused) #else handler(int signo) diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c index f0922871052..8208cf79231 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c @@ -53,7 +53,7 @@ run(int flags) while ((i = open("/", O_RDONLY)) < 3) ATF_REQUIRE(i != -1); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ closefrom(3); #else ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1); @@ -80,7 +80,7 @@ run(int flags) ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0); } -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ if (flags & O_NOSIGPIPE) { ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0); ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0); @@ -116,7 +116,7 @@ ATF_TC_BODY(pipe2_consume, tc) { struct rlimit rl; int err, filedes[2]; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ int old; closefrom(4); @@ -132,7 +132,7 @@ ATF_TC_BODY(pipe2_consume, tc) * file descriptor limit in the middle of a pipe2() call - i.e. * before the call only a single descriptor may be openend. */ -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ old = rl.rlim_cur; #endif rl.rlim_cur = 4; @@ -141,7 +141,7 @@ ATF_TC_BODY(pipe2_consume, tc) err = pipe2(filedes, O_CLOEXEC); ATF_REQUIRE(err == -1); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ rl.rlim_cur = old; err = setrlimit(RLIMIT_NOFILE, &rl); #endif @@ -169,7 +169,7 @@ ATF_TC_BODY(pipe2_cloexec, tc) run(O_CLOEXEC); } -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TC(pipe2_nosigpipe); ATF_TC_HEAD(pipe2_nosigpipe, tc) { @@ -201,7 +201,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, pipe2_consume); ATF_TP_ADD_TC(tp, pipe2_nonblock); ATF_TP_ADD_TC(tp, pipe2_cloexec); -#if defined(__NetBSD__) +#ifdef __NetBSD__ ATF_TP_ADD_TC(tp, pipe2_nosigpipe); #endif ATF_TP_ADD_TC(tp, pipe2_einval); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_poll.c b/contrib/netbsd-tests/lib/libc/sys/t_poll.c index 805773dc948..62144863837 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_poll.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c @@ -233,7 +233,7 @@ ATF_TC_BODY(poll_err, tc) ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1); } -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ ATF_TC(pollts_basic); ATF_TC_HEAD(pollts_basic, tc) { @@ -386,7 +386,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, poll_3way); ATF_TP_ADD_TC(tp, poll_basic); ATF_TP_ADD_TC(tp, poll_err); -#if !defined(__FreeBSD__) +#ifndef __FreeBSD__ ATF_TP_ADD_TC(tp, pollts_basic); ATF_TP_ADD_TC(tp, pollts_err); ATF_TP_ADD_TC(tp, pollts_sigmask); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_revoke.c b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c index fe59cac0956..926d27406aa 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_revoke.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c @@ -58,7 +58,7 @@ ATF_TC_BODY(revoke_basic, tc) size_t i, n; int *buf; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_skip("revoke(2) is only implemented for devfs(5)."); #endif (void)memset(&res, 0, sizeof(struct rlimit)); @@ -116,7 +116,7 @@ ATF_TC_BODY(revoke_err, tc) errno = 0; ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_skip("revoke(2) is only implemented for devfs(5)."); #endif errno = 0; @@ -139,7 +139,7 @@ ATF_TC_BODY(revoke_perm, tc) int fd, sta; pid_t pid; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_skip("revoke(2) is only implemented for devfs(5)."); #endif pw = getpwnam("nobody"); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c index ac7d3ad1be7..6686f022b13 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c @@ -46,7 +46,7 @@ static void handler(int, siginfo_t *, void *); static int value; static void -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ handler(int signo __unused, siginfo_t *info __unused, void *data __unused) #else handler(int signo, siginfo_t *info, void *data) @@ -76,7 +76,7 @@ ATF_TC_BODY(sigqueue_basic, tc) sv.sival_int = VALUE; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ /* * From kern_sig.c: * Specification says sigqueue can only send signal to single process. diff --git a/contrib/netbsd-tests/lib/libc/sys/t_stat.c b/contrib/netbsd-tests/lib/libc/sys/t_stat.c index e96d7721926..5e1d17e28e7 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_stat.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c @@ -47,7 +47,7 @@ __RCSID("$NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $"); #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c index 168bad72c41..cc853073ff4 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c @@ -38,7 +38,7 @@ static timer_t t; static bool fail = true; static void -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ timer_signal_handler(int signo, siginfo_t *si, void *osi __unused) #else timer_signal_handler(int signo, siginfo_t *si, void *osi) diff --git a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c index e73e2f4ca02..8d9466881cb 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c @@ -85,7 +85,7 @@ ATF_TC_BODY(unlink_err, tc) (void)memset(buf, 'x', sizeof(buf)); errno = 0; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ATF_REQUIRE_ERRNO(EISDIR, unlink("/") == -1); #else ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1); diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c index d7a06e0fe46..a3783cb5dee 100644 --- a/contrib/netbsd-tests/lib/libc/sys/t_write.c +++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c @@ -32,7 +32,7 @@ __COPYRIGHT("@(#) Copyright (c) 2008\ __RCSID("$NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $"); #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif @@ -45,7 +45,7 @@ __RCSID("$NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $"); #include #include -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include #endif @@ -55,7 +55,7 @@ static bool fail = false; static const char *path = "write"; static void -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ sighandler(int signo __unused) #else sighandler(int signo) diff --git a/contrib/netbsd-tests/lib/libc/time/t_strptime.c b/contrib/netbsd-tests/lib/libc/time/t_strptime.c index 7808891b640..99871ffdc4b 100644 --- a/contrib/netbsd-tests/lib/libc/time/t_strptime.c +++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c @@ -49,7 +49,7 @@ h_pass(const char *buf, const char *fmt, int len, exp = buf + len; ret = strptime(buf, fmt, &tm); -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ATF_CHECK_MSG(ret == exp, "strptime(\"%s\", \"%s\", tm): incorrect return code: " "expected: %p, got: %p", buf, fmt, exp, ret); @@ -88,7 +88,7 @@ h_fail(const char *buf, const char *fmt) { struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL }; -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ ATF_CHECK_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", " "\"%s\", &tm) should fail, but it didn't", buf, fmt); #else @@ -108,7 +108,7 @@ ATF_TC_HEAD(common, tc) ATF_TC_BODY(common, tc) { -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ atf_tc_expect_fail("There are various issues with strptime on FreeBSD"); #endif @@ -189,13 +189,13 @@ ATF_TC_BODY(day, tc) h_pass("mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1); h_pass("tueSDay", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1); h_pass("sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1); -#if defined(__NetBSD__) +#ifdef __NetBSD__ h_fail("sunday", "%EA"); #else h_pass("Sunday", "%EA", 6, -1, -1, -1, -1, -1, -1, 0, -1); #endif h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1); -#if defined(__NetBSD__) +#ifdef __NetBSD__ h_fail("SaturDay", "%OA"); #else h_pass("SaturDay", "%OA", 8, -1, -1, -1, -1, -1, -1, 6, -1); diff --git a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c index 373528beef8..6c913a4a4c5 100644 --- a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c +++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c @@ -36,7 +36,7 @@ __RCSID("$NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $"); #include #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c index 1ebbe7dfe21..a268068b72a 100644 --- a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c @@ -39,7 +39,7 @@ __RCSID("$NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); #include #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c index b5d1728b64e..1982a9bcc76 100644 --- a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c @@ -38,7 +38,7 @@ __RCSID("$NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $"); #include #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c index 028f398fdae..db0ff16f504 100644 --- a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c @@ -37,7 +37,7 @@ __RCSID("$NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); #include #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c index a85ce9b7215..841b2bf712e 100644 --- a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c +++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c @@ -34,7 +34,7 @@ #include __RCSID("$NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $"); -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c index 8a82689221b..a5e78ffab97 100644 --- a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c +++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c @@ -35,7 +35,7 @@ __RCSID("$NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $"); #include -#if defined(__NetBSD__) +#ifdef __NetBSD__ #include #endif diff --git a/contrib/netbsd-tests/lib/libm/t_cbrt.c b/contrib/netbsd-tests/lib/libm/t_cbrt.c index a7de9f62981..b19413a0124 100644 --- a/contrib/netbsd-tests/lib/libm/t_cbrt.c +++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c @@ -237,6 +237,7 @@ ATF_TC_BODY(cbrtf_zero_pos, tc) atf_tc_fail_nonfatal("cbrtf(+0.0) != +0.0"); } +#if !defined(__FreeBSD__) || LDBL_PREC != 53 /* * cbrtl(3) */ @@ -270,7 +271,11 @@ ATF_TC_BODY(cbrtl_powl, tc) for (i = 0; i < __arraycount(x); i++) { y = cbrtl(x[i]); +#ifdef __FreeBSD__ + z = powl(x[i], (long double)1.0 / 3.0); +#else z = powl(x[i], 1.0 / 3.0); +#endif if (fabsl(y - z) > eps * fabsl(1 + x[i])) atf_tc_fail_nonfatal("cbrtl(%0.03Lf) != " @@ -337,6 +342,7 @@ ATF_TC_BODY(cbrtl_zero_pos, tc) if (fabsl(y) > 0.0 || signbit(y) != 0) atf_tc_fail_nonfatal("cbrtl(+0.0) != +0.0"); } +#endif ATF_TP_ADD_TCS(tp) { @@ -355,12 +361,14 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, cbrtf_zero_neg); ATF_TP_ADD_TC(tp, cbrtf_zero_pos); +#if !defined(__FreeBSD__) || LDBL_PREC != 53 ATF_TP_ADD_TC(tp, cbrtl_nan); ATF_TP_ADD_TC(tp, cbrtl_powl); ATF_TP_ADD_TC(tp, cbrtl_inf_neg); ATF_TP_ADD_TC(tp, cbrtl_inf_pos); ATF_TP_ADD_TC(tp, cbrtl_zero_neg); ATF_TP_ADD_TC(tp, cbrtl_zero_pos); +#endif return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libm/t_exp.c b/contrib/netbsd-tests/lib/libm/t_exp.c index 6d410972d77..7a8e9f80436 100644 --- a/contrib/netbsd-tests/lib/libm/t_exp.c +++ b/contrib/netbsd-tests/lib/libm/t_exp.c @@ -131,6 +131,10 @@ ATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x") }; unsigned int i; +#if defined(__FreeBSD__) && defined(__i386__) + atf_tc_expect_fail("a number of the assertions fail on i386"); +#endif + for (i = 0; i < __arraycount(v); i++) { T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0); T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0); @@ -173,6 +177,11 @@ ATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x") }; unsigned int i; +#ifdef __FreeBSD__ + atf_tc_expect_fail("Some of the cases produce failures on FreeBSD " + "due to the error epsilon being so small"); +#endif + for (i = 0; i < __arraycount(v); i++) { T_LIBM_CHECK(i, exp2, v[i].x, v[i].y, v[i].d_eps); if (i > 1) diff --git a/contrib/netbsd-tests/lib/libm/t_pow.c b/contrib/netbsd-tests/lib/libm/t_pow.c index 62b7235e764..a8ae6f0f62f 100644 --- a/contrib/netbsd-tests/lib/libm/t_pow.c +++ b/contrib/netbsd-tests/lib/libm/t_pow.c @@ -34,6 +34,10 @@ __RCSID("$NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $"); #include #include +#ifdef __FreeBSD__ +#define isinff isinf +#endif + /* * pow(3) */ diff --git a/contrib/netbsd-tests/lib/libm/t_precision.c b/contrib/netbsd-tests/lib/libm/t_precision.c index 777666f297f..c01debac5d0 100644 --- a/contrib/netbsd-tests/lib/libm/t_precision.c +++ b/contrib/netbsd-tests/lib/libm/t_precision.c @@ -58,6 +58,7 @@ ATF_TC_BODY(t_precision, tc) x += DBL_EPSILON; ATF_CHECK(x == 2.0); +#if !defined(__FreeBSD__) || !defined(__i386__) y += LDBL_EPSILON; ATF_CHECK(y != 1.0L); y -= 1; @@ -65,6 +66,7 @@ ATF_TC_BODY(t_precision, tc) y = 2; y += LDBL_EPSILON; ATF_CHECK(y == 2.0L); +#endif } ATF_TP_ADD_TCS(tp) diff --git a/contrib/netbsd-tests/lib/libm/t_scalbn.c b/contrib/netbsd-tests/lib/libm/t_scalbn.c index 586c2c3bc62..2d186cf1df8 100644 --- a/contrib/netbsd-tests/lib/libm/t_scalbn.c +++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c @@ -81,6 +81,9 @@ ATF_TC_BODY(scalbn_val, tc) double rv; for (i = 0; i < tcnt; i++) { +#ifdef __FreeBSD__ + errno = 0; +#endif rv = scalbn(tests[i].inval, tests[i].exp); ATF_CHECK_EQ_MSG(errno, tests[i].error, "test %zu: errno %d instead of %d", i, errno, diff --git a/contrib/netbsd-tests/lib/libpthread/h_atexit.c b/contrib/netbsd-tests/lib/libpthread/h_atexit.c index 2d4c91c60bd..29b8775681c 100644 --- a/contrib/netbsd-tests/lib/libpthread/h_atexit.c +++ b/contrib/netbsd-tests/lib/libpthread/h_atexit.c @@ -47,9 +47,19 @@ __RCSID("$NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $"); extern int __cxa_atexit(void (*func)(void *), void *, void *); extern void __cxa_finalize(void *); +#ifdef __FreeBSD__ +/* + * See comments in ../../lib/libc/stdlib/h_atexit.c about the deviation + * between FreeBSD and NetBSD with this helper program + */ +static void *dso_handle_1 = (void *)1; +static void *dso_handle_2 = (void *)2; +static void *dso_handle_3 = (void *)3; +#else static int dso_handle_1; static int dso_handle_2; static int dso_handle_3; +#endif static int arg_1; static int arg_2; @@ -170,8 +180,17 @@ main(int argc, char *argv[]) exiting_state = 5; +#ifdef __FreeBSD__ ASSERT(0 == atexit(normal_handler_0)); ASSERT(0 == atexit(normal_handler_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1)); + ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2)); + ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3)); + + __cxa_finalize(dso_handle_1); + __cxa_finalize(dso_handle_2); +#else ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1)); ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1)); ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2)); @@ -179,5 +198,6 @@ main(int argc, char *argv[]) __cxa_finalize(&dso_handle_1); __cxa_finalize(&dso_handle_2); +#endif exit(0); } diff --git a/contrib/netbsd-tests/lib/libpthread/h_cancel.c b/contrib/netbsd-tests/lib/libpthread/h_cancel.c index 1077806c77f..b7a93630bd4 100644 --- a/contrib/netbsd-tests/lib/libpthread/h_cancel.c +++ b/contrib/netbsd-tests/lib/libpthread/h_cancel.c @@ -42,7 +42,9 @@ main(void) char str1[] = "You should see this.\n"; char str2[] = "You should not see this.\n"; +#ifdef __NetBSD__ printf("Cancellation test: Self-cancellation and disabling.\n"); +#endif pthread_cancel(pthread_self()); diff --git a/contrib/netbsd-tests/lib/libpthread/t_condwait.c b/contrib/netbsd-tests/lib/libpthread/t_condwait.c index 9b79587104c..17bbb89df76 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_condwait.c +++ b/contrib/netbsd-tests/lib/libpthread/t_condwait.c @@ -40,6 +40,10 @@ __RCSID("$NetBSD: t_condwait.c,v 1.4 2013/04/12 17:18:11 christos Exp $"); #include "isqemu.h" +#ifdef __FreeBSD__ +#include +#endif + #define WAITTIME 2 /* Timeout wait secound */ static const int debug = 1; diff --git a/contrib/netbsd-tests/lib/libpthread/t_detach.c b/contrib/netbsd-tests/lib/libpthread/t_detach.c index 21db871a70d..8922d5a1e93 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_detach.c +++ b/contrib/netbsd-tests/lib/libpthread/t_detach.c @@ -75,6 +75,10 @@ ATF_TC_BODY(pthread_detach, tc) rv = pthread_join(t, NULL); ATF_REQUIRE(rv == EINVAL); +#ifdef __FreeBSD__ + atf_tc_expect_fail("PR # 191906: fails with EINVAL, not ESRCH"); +#endif + /* * As usual, ESRCH should follow if * we try to detach an invalid thread. diff --git a/contrib/netbsd-tests/lib/libpthread/t_fork.c b/contrib/netbsd-tests/lib/libpthread/t_fork.c index ab8806d2564..a58c1a6be5d 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_fork.c +++ b/contrib/netbsd-tests/lib/libpthread/t_fork.c @@ -61,7 +61,11 @@ print_pid(void *arg) thread_survived = 1; if (parent != getpid()) { +#ifdef __FreeBSD__ + _exit(1); +#else exit(1); +#endif } return NULL; } @@ -95,7 +99,11 @@ ATF_TC_BODY(fork, tc) ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), 0, "thread survived in child"); } else { sleep(5); +#ifdef __FreeBSD__ + _exit(thread_survived ? 1 : 0); +#else exit(thread_survived ? 1 : 0); +#endif } } diff --git a/contrib/netbsd-tests/lib/libpthread/t_join.c b/contrib/netbsd-tests/lib/libpthread/t_join.c index 7f6f8348acf..71b6775c30c 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_join.c +++ b/contrib/netbsd-tests/lib/libpthread/t_join.c @@ -37,6 +37,10 @@ __RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $"); #include +#ifdef __FreeBSD__ +#include +#endif + #include "h_common.h" #ifdef CHECK_STACK_ALIGNMENT @@ -152,6 +156,9 @@ threadfunc2(void *arg) j = (uintptr_t)arg; +#ifdef __FreeBSD__ + pthread_attr_init(&attr); +#endif ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0); ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0); ATF_REQUIRE(stacksize == STACKSIZE * (j + 1)); diff --git a/contrib/netbsd-tests/lib/libpthread/t_mutex.c b/contrib/netbsd-tests/lib/libpthread/t_mutex.c index b5b07b31b4f..eb371fabd88 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_mutex.c +++ b/contrib/netbsd-tests/lib/libpthread/t_mutex.c @@ -117,9 +117,11 @@ ATF_TC(mutex2); ATF_TC_HEAD(mutex2, tc) { atf_tc_set_md_var(tc, "descr", "Checks mutexes"); +#ifdef __NetBSD__ #if defined(__powerpc__) atf_tc_set_md_var(tc, "timeout", "40"); #endif +#endif } ATF_TC_BODY(mutex2, tc) { @@ -129,8 +131,10 @@ ATF_TC_BODY(mutex2, tc) printf("1: Mutex-test 2\n"); +#ifdef __NetBSD__ #if defined(__powerpc__) atf_tc_expect_timeout("PR port-powerpc/44387"); +#endif #endif PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL)); @@ -158,6 +162,7 @@ ATF_TC_BODY(mutex2, tc) global_x, (long)joinval); ATF_REQUIRE_EQ(global_x, 20000000); +#ifdef __NetBSD__ #if defined(__powerpc__) /* XXX force a timeout in ppc case since an un-triggered race otherwise looks like a "failure" */ @@ -165,6 +170,7 @@ ATF_TC_BODY(mutex2, tc) complain about unexpected success */ sleep(41); #endif +#endif } static void * @@ -188,9 +194,11 @@ ATF_TC_HEAD(mutex3, tc) { atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static " "initializer"); +#ifdef __NetBSD__ #if defined(__powerpc__) atf_tc_set_md_var(tc, "timeout", "40"); #endif +#endif } ATF_TC_BODY(mutex3, tc) { @@ -200,8 +208,10 @@ ATF_TC_BODY(mutex3, tc) printf("1: Mutex-test 3\n"); +#ifdef __NetBSD__ #if defined(__powerpc__) atf_tc_expect_timeout("PR port-powerpc/44387"); +#endif #endif global_x = 0; @@ -227,6 +237,7 @@ ATF_TC_BODY(mutex3, tc) global_x, (long)joinval); ATF_REQUIRE_EQ(global_x, 20000000); +#ifdef __NetBSD__ #if defined(__powerpc__) /* XXX force a timeout in ppc case since an un-triggered race otherwise looks like a "failure" */ @@ -234,6 +245,7 @@ ATF_TC_BODY(mutex3, tc) complain about unexpected success */ sleep(41); #endif +#endif } static void * diff --git a/contrib/netbsd-tests/lib/libpthread/t_once.c b/contrib/netbsd-tests/lib/libpthread/t_once.c index 575d5d7ef89..e87907721a6 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_once.c +++ b/contrib/netbsd-tests/lib/libpthread/t_once.c @@ -46,6 +46,10 @@ static int x; #define NTHREADS 25 +#ifdef __FreeBSD__ +#include +#endif + static void ofunc(void) { diff --git a/contrib/netbsd-tests/lib/libpthread/t_sem.c b/contrib/netbsd-tests/lib/libpthread/t_sem.c index a4e03ae9c60..5bb7ae7264d 100644 --- a/contrib/netbsd-tests/lib/libpthread/t_sem.c +++ b/contrib/netbsd-tests/lib/libpthread/t_sem.c @@ -111,6 +111,10 @@ __RCSID("$NetBSD: t_sem.c,v 1.8 2014/11/04 00:20:19 justin Exp $"); static sem_t sem; +#ifdef __FreeBSD__ +#include +#endif + ATF_TC(named); ATF_TC_HEAD(named, tc) { diff --git a/contrib/netbsd-tests/lib/librt/t_sem.c b/contrib/netbsd-tests/lib/librt/t_sem.c index b6fc4dbf197..e76cd521559 100644 --- a/contrib/netbsd-tests/lib/librt/t_sem.c +++ b/contrib/netbsd-tests/lib/librt/t_sem.c @@ -86,6 +86,9 @@ ATF_TC_BODY(basic, tc) if (sysconf(_SC_SEMAPHORES) == -1) atf_tc_skip("POSIX semaphores not supported"); +#ifdef __FreeBSD__ + sem_unlink("/sem_b"); +#endif sem_b = sem_open("/sem_b", O_CREAT | O_EXCL, 0644, 0); ATF_REQUIRE(sem_b != SEM_FAILED); @@ -127,6 +130,9 @@ ATF_TC_BODY(child, tc) if (sysconf(_SC_SEMAPHORES) == -1) atf_tc_skip("POSIX semaphores not supported"); +#ifdef __FreeBSD__ + sem_unlink("/sem_a"); +#endif sem_a = sem_open("/sem_a", O_CREAT | O_EXCL, 0644, 0); ATF_REQUIRE(sem_a != SEM_FAILED); diff --git a/contrib/ofed/librdmacm/examples/rping.c b/contrib/ofed/librdmacm/examples/rping.c index 9bbfab1caa1..44f12327cb9 100644 --- a/contrib/ofed/librdmacm/examples/rping.c +++ b/contrib/ofed/librdmacm/examples/rping.c @@ -1049,19 +1049,20 @@ static int rping_run_client(struct rping_cb *cb) ret = rping_connect_client(cb); if (ret) { fprintf(stderr, "connect error %d\n", ret); - goto err2; + goto err3; } ret = rping_test_client(cb); if (ret) { fprintf(stderr, "rping client failed: %d\n", ret); - goto err3; + goto err4; } ret = 0; -err3: +err4: rdma_disconnect(cb->cm_id); -err2: +err3: pthread_join(cb->cqthread, NULL); +err2: rping_free_buffers(cb); err1: rping_free_qp(cb); diff --git a/contrib/telnet/arpa/telnet.h b/contrib/telnet/arpa/telnet.h index 26f75fb3130..b028a1df794 100644 --- a/contrib/telnet/arpa/telnet.h +++ b/contrib/telnet/arpa/telnet.h @@ -127,6 +127,7 @@ extern char *telcmds[]; #define TELOPT_KERMIT 47 /* RFC2840 - Kermit */ #define TELOPT_EXOPL 255 /* extended-options-list */ +#define COMPORT_SET_BAUDRATE 1 /* RFC2217 - Com Port Set Baud Rate */ #define NTELOPTS (1+TELOPT_KERMIT) #ifdef TELOPTS diff --git a/contrib/telnet/telnet/baud.h b/contrib/telnet/telnet/baud.h new file mode 100644 index 00000000000..c422535cf8a --- /dev/null +++ b/contrib/telnet/telnet/baud.h @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2014 EMC Corporation + * 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 JOHN BIRRELL 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 REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +/* + * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD). + */ +#if B4800 != 4800 +#define DECODE_BAUD +#endif + +#ifdef DECODE_BAUD +#ifndef B7200 +#define B7200 B4800 +#endif + +#ifndef B14400 +#define B14400 B9600 +#endif + +#ifndef B19200 +#define B19200 B14400 +#endif + +#ifndef B28800 +#define B28800 B19200 +#endif + +#ifndef B38400 +#define B38400 B28800 +#endif + +#ifndef B57600 +#define B57600 B38400 +#endif + +#ifndef B76800 +#define B76800 B57600 +#endif + +#ifndef B115200 +#define B115200 B76800 +#endif + +#ifndef B115200 +#define B115200 B76800 +#endif +#endif + +#ifndef B230400 +#define B230400 B115200 +#endif + +/* + * A table of available terminal speeds + */ +struct termspeeds termspeeds[] = { + { 0, B0 }, + { 50, B50 }, + { 75, B75 }, + { 110, B110 }, + { 134, B134 }, + { 150, B150 }, + { 200, B200 }, + { 300, B300 }, + { 600, B600 }, + { 1200, B1200 }, + { 1800, B1800 }, + { 2400, B2400 }, + { 4800, B4800 }, +#ifdef B7200 + { 7200, B7200 }, +#endif + { 9600, B9600 }, +#ifdef B14400 + { 14400, B14400 }, +#endif +#ifdef B19200 + { 19200, B19200 }, +#endif +#ifdef B28800 + { 28800, B28800 }, +#endif +#ifdef B38400 + { 38400, B38400 }, +#endif +#ifdef B57600 + { 57600, B57600 }, +#endif +#ifdef B115200 + { 115200, B115200 }, +#endif +#ifdef B230400 + { 230400, B230400 }, +#endif + { -1, 0 } +}; diff --git a/contrib/telnet/telnet/commands.c b/contrib/telnet/telnet/commands.c index c39b18744ca..74cce6d5ded 100644 --- a/contrib/telnet/telnet/commands.c +++ b/contrib/telnet/telnet/commands.c @@ -896,6 +896,7 @@ static struct setlist Setlist[] = { { "forw1", "alternate end of line character", NULL, termForw1Charp }, { "forw2", "alternate end of line character", NULL, termForw2Charp }, { "ayt", "alternate AYT character", NULL, termAytCharp }, + { "baudrate", "set remote baud rate", DoBaudRate, ComPortBaudRate }, { NULL, NULL, NULL, NULL } }; diff --git a/contrib/telnet/telnet/externs.h b/contrib/telnet/telnet/externs.h index e07aebbdb82..d42bddd4cd0 100644 --- a/contrib/telnet/telnet/externs.h +++ b/contrib/telnet/telnet/externs.h @@ -231,6 +231,10 @@ extern unsigned char NetTraceFile[]; /* Name of file where debugging output goes */ extern void SetNetTrace(char *); /* Function to change where debugging goes */ +extern unsigned char + ComPortBaudRate[]; /* Baud rate of the remote end */ +extern void + DoBaudRate(char *); /* Function to set the baud rate of the remote end */ extern jmp_buf toplevel; /* For error conditions. */ @@ -475,6 +479,16 @@ extern cc_t termAytChar; # endif #endif +typedef struct { + int + system, /* what the current time is */ + echotoggle, /* last time user entered echo character */ + modenegotiated, /* last time operating mode negotiated */ + didnetreceive, /* last time we read data from network */ + gotDM; /* when did we last see a data mark */ +} Clocks; + +extern Clocks clocks; /* Ring buffer structures which are shared */ diff --git a/contrib/telnet/telnet/main.c b/contrib/telnet/telnet/main.c index f6eb1ffb08e..1ddec8256a0 100644 --- a/contrib/telnet/telnet/main.c +++ b/contrib/telnet/telnet/main.c @@ -91,10 +91,10 @@ usage(void) fprintf(stderr, "usage: %s %s%s%s%s\n", prompt, #ifdef AUTHENTICATION - "[-4] [-6] [-8] [-E] [-K] [-L] [-N] [-S tos] [-X atype] [-c] [-d]", - "\n\t[-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ", + "[-4] [-6] [-8] [-B baudrate] [-E] [-K] [-L] [-N] [-S tos] [-X atype]", + "\n\t[-c] [-d] [-e char] [-k realm] [-l user] [-f/-F] [-n tracefile] ", #else - "[-4] [-6] [-8] [-E] [-L] [-N] [-S tos] [-c] [-d]", + "[-4] [-6] [-8] [-B baudrate] [-E] [-L] [-N] [-S tos] [-c] [-d]", "\n\t[-e char] [-l user] [-n tracefile] ", #endif "[-r] [-s src_addr] [-u] ", @@ -154,7 +154,7 @@ main(int argc, char *argv[]) #define IPSECOPT #endif while ((ch = getopt(argc, argv, - "468EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1) + "468B:EKLNS:X:acde:fFk:l:n:rs:uxy" IPSECOPT)) != -1) #undef IPSECOPT { switch(ch) { @@ -169,6 +169,9 @@ main(int argc, char *argv[]) case '8': eight = 3; /* binary output and input */ break; + case 'B': + DoBaudRate(optarg); + break; case 'E': rlogin = escape = _POSIX_VDISABLE; break; diff --git a/contrib/telnet/telnet/sys_bsd.c b/contrib/telnet/telnet/sys_bsd.c index 9fba74feada..32f84bf85e4 100644 --- a/contrib/telnet/telnet/sys_bsd.c +++ b/contrib/telnet/telnet/sys_bsd.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include "defines.h" #include "externs.h" #include "types.h" +#include "baud.h" int tout, /* Output file descriptor */ @@ -682,71 +683,6 @@ TerminalNewMode(int f) } -/* - * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD). - */ -#if B4800 != 4800 -#define DECODE_BAUD -#endif - -#ifdef DECODE_BAUD -#ifndef B7200 -#define B7200 B4800 -#endif - -#ifndef B14400 -#define B14400 B9600 -#endif - -#ifndef B19200 -# define B19200 B14400 -#endif - -#ifndef B28800 -#define B28800 B19200 -#endif - -#ifndef B38400 -# define B38400 B28800 -#endif - -#ifndef B57600 -#define B57600 B38400 -#endif - -#ifndef B76800 -#define B76800 B57600 -#endif - -#ifndef B115200 -#define B115200 B76800 -#endif - -#ifndef B230400 -#define B230400 B115200 -#endif - - -/* - * This code assumes that the values B0, B50, B75... - * are in ascending order. They do not have to be - * contiguous. - */ -struct termspeeds { - long speed; - long value; -} termspeeds[] = { - { 0, B0 }, { 50, B50 }, { 75, B75 }, - { 110, B110 }, { 134, B134 }, { 150, B150 }, - { 200, B200 }, { 300, B300 }, { 600, B600 }, - { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, - { 4800, B4800 }, { 7200, B7200 }, { 9600, B9600 }, - { 14400, B14400 }, { 19200, B19200 }, { 28800, B28800 }, - { 38400, B38400 }, { 57600, B57600 }, { 115200, B115200 }, - { 230400, B230400 }, { -1, B230400 } -}; -#endif /* DECODE_BAUD */ - void TerminalSpeeds(long *ispeed, long *ospeed) { diff --git a/contrib/telnet/telnet/telnet.1 b/contrib/telnet/telnet/telnet.1 index 2dce4c51dd5..f55c62e8729 100644 --- a/contrib/telnet/telnet/telnet.1 +++ b/contrib/telnet/telnet/telnet.1 @@ -43,6 +43,7 @@ protocol .Sh SYNOPSIS .Nm .Op Fl 468EFKLNacdfruxy +.Op Fl B Ar baudrate .Op Fl S Ar tos .Op Fl X Ar authtype .Op Fl e Ar escapechar @@ -89,6 +90,9 @@ This causes an attempt to negotiate the .Dv TELNET BINARY option on both input and output. +.It Fl B Ar baudrate +Sets the baud rate to +.Ar baudrate . .It Fl E Stops any character from being recognized as an escape character. .It Fl F diff --git a/contrib/telnet/telnet/telnet.c b/contrib/telnet/telnet/telnet.c index 8c457cf613d..80f43b2fc0a 100644 --- a/contrib/telnet/telnet/telnet.c +++ b/contrib/telnet/telnet/telnet.c @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "ring.h" @@ -68,7 +69,7 @@ __FBSDID("$FreeBSD$"); #include #endif #include - + #define strip(x) ((my_want_state_is_wont(TELOPT_BINARY)) ? ((x)&0x7f) : (x)) static unsigned char subbuffer[SUBBUFSIZE], @@ -162,7 +163,7 @@ static int is_unique(char *, char **, char **); */ Clocks clocks; - + /* * Initialize telnet environment. */ @@ -196,7 +197,7 @@ init_telnet(void) flushline = 1; telrcv_state = TS_DATA; } - + /* * These routines are in charge of sending option negotiations @@ -206,6 +207,42 @@ init_telnet(void) * is in disagreement as to what the current state should be. */ +unsigned char ComPortBaudRate[256]; + +void +DoBaudRate(char *arg) +{ + char *temp, temp2[10]; + int i; + uint32_t baudrate; + + errno = 0; + baudrate = (uint32_t)strtol(arg, &temp, 10); + if (temp[0] != '\0' || (baudrate == 0 && errno != 0)) + ExitString("Invalid baud rate provided.\n", 1); + + for (i = 1; termspeeds[i].speed != -1; i++) + if (baudrate == termspeeds[i].speed) + break; + if (termspeeds[i].speed == -1) + ExitString("Invalid baud rate provided.\n", 1); + + strlcpy(ComPortBaudRate, arg, sizeof(ComPortBaudRate)); + + if (NETROOM() < sizeof(temp2)) { + ExitString("No room in buffer for baud rate.\n", 1); + /* NOTREACHED */ + } + + snprintf(temp2, sizeof(temp2), "%c%c%c%c....%c%c", IAC, SB, TELOPT_COMPORT, + COMPORT_SET_BAUDRATE, IAC, SE); + + baudrate = htonl(baudrate); + memcpy(&temp2[4], &baudrate, sizeof(baudrate)); + ring_supply_data(&netoring, temp2, sizeof(temp2)); + printsub('>', &temp[2], sizeof(temp2) - 2); +} + void send_do(int c, int init) { @@ -1084,7 +1121,7 @@ lm_mode(unsigned char *cmd, int len, int init) setconnmode(0); /* set changed mode */ } - + /* * slc() @@ -1628,7 +1665,7 @@ env_opt_end(int emptyok) } } - + int telrcv(void) @@ -2013,7 +2050,7 @@ telsnd(void) ring_consumed(&ttyiring, count); return returnValue||count; /* Non-zero if we did anything */ } - + /* * Scheduler() * diff --git a/contrib/telnet/telnet/types.h b/contrib/telnet/telnet/types.h index 191d311fd15..4db5292e49d 100644 --- a/contrib/telnet/telnet/types.h +++ b/contrib/telnet/telnet/types.h @@ -40,13 +40,9 @@ typedef struct { extern Modelist modelist[]; -typedef struct { - int - system, /* what the current time is */ - echotoggle, /* last time user entered echo character */ - modenegotiated, /* last time operating mode negotiated */ - didnetreceive, /* last time we read data from network */ - gotDM; /* when did we last see a data mark */ -} Clocks; +struct termspeeds { + int speed; + int value; +}; -extern Clocks clocks; +extern struct termspeeds termspeeds[]; diff --git a/contrib/telnet/telnetd/sys_term.c b/contrib/telnet/telnetd/sys_term.c index 5a9421b1b15..bdc43f6e1a2 100644 --- a/contrib/telnet/telnetd/sys_term.c +++ b/contrib/telnet/telnetd/sys_term.c @@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$"); #include "telnetd.h" #include "pathnames.h" +#include "types.h" +#include "baud.h" #ifdef AUTHENTICATION #include @@ -743,56 +745,6 @@ tty_iscrnl(void) #endif } -/* - * Try to guess whether speeds are "encoded" (4.2BSD) or just numeric (4.4BSD). - */ -#if B4800 != 4800 -#define DECODE_BAUD -#endif - -#ifdef DECODE_BAUD - -/* - * A table of available terminal speeds - */ -struct termspeeds { - int speed; - int value; -} termspeeds[] = { - { 0, B0 }, { 50, B50 }, { 75, B75 }, - { 110, B110 }, { 134, B134 }, { 150, B150 }, - { 200, B200 }, { 300, B300 }, { 600, B600 }, - { 1200, B1200 }, { 1800, B1800 }, { 2400, B2400 }, - { 4800, B4800 }, -#ifdef B7200 - { 7200, B7200 }, -#endif - { 9600, B9600 }, -#ifdef B14400 - { 14400, B14400 }, -#endif -#ifdef B19200 - { 19200, B19200 }, -#endif -#ifdef B28800 - { 28800, B28800 }, -#endif -#ifdef B38400 - { 38400, B38400 }, -#endif -#ifdef B57600 - { 57600, B57600 }, -#endif -#ifdef B115200 - { 115200, B115200 }, -#endif -#ifdef B230400 - { 230400, B230400 }, -#endif - { -1, 0 } -}; -#endif /* DECODE_BAUD */ - void tty_tspeed(int val) { diff --git a/contrib/tzdata/africa b/contrib/tzdata/africa index b17c62b7e31..1b9bf50da22 100644 --- a/contrib/tzdata/africa +++ b/contrib/tzdata/africa @@ -6,20 +6,19 @@ # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2013-02-21): +# From Paul Eggert (2014-10-31): # -# A good source for time zone historical data outside the U.S. is +# Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), # San Diego: ACS Publications, Inc. (2003). +# Unfortunately this book contains many errors and cites no sources. # # Gwillim Law writes that a good source # for recent time zone data is the International Air Transport # Association's Standard Schedules Information Manual (IATA SSIM), # published semiannually. Law sent in several helpful summaries -# of the IATA's data after 1990. -# -# Except where otherwise noted, Shanks & Pottenger is the source for -# entries through 1990, and IATA SSIM is the source for entries afterwards. +# of the IATA's data after 1990. Except where otherwise noted, +# IATA SSIM is the source for entries after 1990. # # Another source occasionally used is Edward W. Whitman, World Time Differences, # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which @@ -65,7 +64,6 @@ # 3:00 CAST Central Africa Summer Time (no longer used) # 3:00 SAST South Africa Summer Time (no longer used) # 3:00 EAT East Africa Time -# 4:00 EAST East Africa Summer Time (no longer used) # Algeria # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S @@ -146,9 +144,7 @@ Zone Africa/Ndjamena 1:00:12 - LMT 1912 # N'Djamena 1:00 - WAT # Comoros -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Indian/Comoro 2:53:04 - LMT 1911 Jul # Moroni, Gran Comoro - 3:00 - EAT +# See Africa/Nairobi. # Democratic Republic of the Congo # See Africa/Lagos for the western part and Africa/Maputo for the eastern. @@ -172,9 +168,7 @@ Link Africa/Abidjan Africa/Sao_Tome # São Tomé and Príncipe Link Africa/Abidjan Atlantic/St_Helena # St Helena # Djibouti -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Djibouti 2:52:36 - LMT 1911 Jul - 3:00 - EAT +# See Africa/Nairobi. ############################################################################### @@ -387,27 +381,8 @@ Zone Africa/Cairo 2:05:09 - LMT 1900 Oct # See Africa/Lagos. # Eritrea -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Asmara 2:35:32 - LMT 1870 - 2:35:32 - AMT 1890 # Asmara Mean Time - 2:35:20 - ADMT 1936 May 5 # Adis Dera MT - 3:00 - EAT - # Ethiopia -# From Paul Eggert (2014-07-31): -# Like the Swahili of Kenya and Tanzania, many Ethiopians keep a -# 12-hour clock starting at our 06:00, so their "8 o'clock" is our -# 02:00 or 14:00. Keep this in mind when you ask the time in Amharic. -# -# Shanks & Pottenger write that Ethiopia had six narrowly-spaced time -# zones between 1870 and 1890, that they merged to 38E50 (2:35:20) in -# 1890, and that they switched to 3:00 on 1936-05-05. Perhaps 38E50 -# was for Adis Dera. Quite likely the Shanks data entries are wrong -# anyway. -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Addis_Ababa 2:34:48 - LMT 1870 - 2:35:20 - ADMT 1936 May 5 # Adis Dera MT - 3:00 - EAT +# See Africa/Nairobi. # Gabon # See Africa/Lagos. @@ -451,6 +426,15 @@ Zone Africa/Nairobi 2:27:16 - LMT 1928 Jul 2:30 - BEAT 1940 2:45 - BEAUT 1960 3:00 - EAT +Link Africa/Nairobi Africa/Addis_Ababa # Ethiopia +Link Africa/Nairobi Africa/Asmara # Eritrea +Link Africa/Nairobi Africa/Dar_es_Salaam # Tanzania +Link Africa/Nairobi Africa/Djibouti +Link Africa/Nairobi Africa/Kampala # Uganda +Link Africa/Nairobi Africa/Mogadishu # Somalia +Link Africa/Nairobi Indian/Antananarivo # Madagascar +Link Africa/Nairobi Indian/Comoro +Link Africa/Nairobi Indian/Mayotte # Lesotho # See Africa/Johannesburg. @@ -528,11 +512,7 @@ Zone Africa/Tripoli 0:52:44 - LMT 1920 2:00 - EET # Madagascar -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Indian/Antananarivo 3:10:04 - LMT 1911 Jul - 3:00 - EAT 1954 Feb 27 23:00s - 3:00 1:00 EAST 1954 May 29 23:00s - 3:00 - EAT +# See Africa/Nairobi. # Malawi # See Africa/Maputo. @@ -635,9 +615,7 @@ Zone Indian/Mauritius 3:50:00 - LMT 1907 # Port Louis # no information; probably like Indian/Mauritius # Mayotte -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Indian/Mayotte 3:00:56 - LMT 1911 Jul # Mamoutzou - 3:00 - EAT +# See Africa/Nairobi. # Morocco # See the 'europe' file for Spanish Morocco (Africa/Ceuta). @@ -1049,11 +1027,7 @@ Zone Indian/Mahe 3:41:48 - LMT 1906 Jun # Victoria # See Africa/Abidjan. # Somalia -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Mogadishu 3:01:28 - LMT 1893 Nov - 3:00 - EAT 1931 - 2:30 - BEAT 1957 - 3:00 - EAT +# See Africa/Nairobi. # South Africa # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S @@ -1096,11 +1070,7 @@ Link Africa/Khartoum Africa/Juba # See Africa/Johannesburg. # Tanzania -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Dar_es_Salaam 2:37:08 - LMT 1931 - 3:00 - EAT 1948 - 2:45 - BEAUT 1961 - 3:00 - EAT +# See Africa/Nairobi. # Togo # See Africa/Abidjan. @@ -1206,12 +1176,7 @@ Zone Africa/Tunis 0:40:44 - LMT 1881 May 12 1:00 Tunisia CE%sT # Uganda -# Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Africa/Kampala 2:09:40 - LMT 1928 Jul - 3:00 - EAT 1930 - 2:30 - BEAT 1948 - 2:45 - BEAUT 1957 - 3:00 - EAT +# See Africa/Nairobi. # Zambia # Zimbabwe diff --git a/contrib/tzdata/asia b/contrib/tzdata/asia index 37b2c88e0ed..1a2bd12ad2a 100644 --- a/contrib/tzdata/asia +++ b/contrib/tzdata/asia @@ -6,20 +6,19 @@ # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2013-08-11): +# From Paul Eggert (2014-10-31): # -# A good source for time zone historical data outside the U.S. is +# Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), # San Diego: ACS Publications, Inc. (2003). +# Unfortunately this book contains many errors and cites no sources. # # Gwillim Law writes that a good source # for recent time zone data is the International Air Transport # Association's Standard Schedules Information Manual (IATA SSIM), # published semiannually. Law sent in several helpful summaries -# of the IATA's data after 1990. -# -# Except where otherwise noted, Shanks & Pottenger is the source for -# entries through 1990, and IATA SSIM is the source for entries afterwards. +# of the IATA's data after 1990. Except where otherwise noted, +# IATA SSIM is the source for entries after 1990. # # Another source occasionally used is Edward W. Whitman, World Time Differences, # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which @@ -1663,44 +1662,70 @@ Zone Asia/Bishkek 4:58:24 - LMT 1924 May 2 # Korea (North and South) # From Annie I. Bang (2006-07-10): -# http://www.koreaherald.co.kr/SITE/data/html_dir/2006/07/10/200607100012.asp -# The Ministry of Commerce, Industry and Energy has already -# commissioned a research project [to reintroduce DST] and has said -# the system may begin as early as 2008.... Korea ran a daylight -# saving program from 1949-61 but stopped it during the 1950-53 Korean War. +# http://www.koreaherald.com/view.php?ud=200607100012 +# Korea ran a daylight saving program from 1949-61 but stopped it +# during the 1950-53 Korean War. The system was temporarily enforced +# between 1987 and 1988 ... + +# From Sanghyuk Jung (2014-10-29): +# http://mm.icann.org/pipermail/tz/2014-October/021830.html +# According to the Korean Wikipedia +# http://ko.wikipedia.org/wiki/한국_표준시 +# [oldid=12896437 2014-09-04 08:03 UTC] +# DST in Republic of Korea was as follows.... And I checked old +# newspapers in Korean, all articles correspond with data in Wikipedia. +# For example, the article in 1948 (Korean Language) proved that DST +# started at June 1 in that year. For another example, the article in +# 1988 said that DST started at 2:00 AM in that year. -# From Shanks & Pottenger: # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S -Rule ROK 1960 only - May 15 0:00 1:00 D -Rule ROK 1960 only - Sep 13 0:00 0 S -Rule ROK 1987 1988 - May Sun>=8 0:00 1:00 D -Rule ROK 1987 1988 - Oct Sun>=8 0:00 0 S +Rule ROK 1948 only - Jun 1 0:00 1:00 D +Rule ROK 1948 only - Sep 13 0:00 0 S +Rule ROK 1949 only - Apr 3 0:00 1:00 D +Rule ROK 1949 1951 - Sep Sun>=8 0:00 0 S +Rule ROK 1950 only - Apr 1 0:00 1:00 D +Rule ROK 1951 only - May 6 0:00 1:00 D +Rule ROK 1955 only - May 5 0:00 1:00 D +Rule ROK 1955 only - Sep 9 0:00 0 S +Rule ROK 1956 only - May 20 0:00 1:00 D +Rule ROK 1956 only - Sep 30 0:00 0 S +Rule ROK 1957 1960 - May Sun>=1 0:00 1:00 D +Rule ROK 1957 1960 - Sep Sun>=18 0:00 0 S +Rule ROK 1987 1988 - May Sun>=8 2:00 1:00 D +Rule ROK 1987 1988 - Oct Sun>=8 3:00 0 S -# From Paul Eggert (2014-07-01): -# The following entries are from Shanks & Pottenger, except that I -# guessed that time zone abbreviations through 1945 followed the same +# From Paul Eggert (2014-10-30): +# The Korean Wikipedia entry gives the following sources for UT offsets: +# +# 1908: Official Journal Article No. 3994 (Edict No. 5) +# 1912: Governor-General of Korea Official Gazette Issue No. 367 +# (Announcement No. 338) +# 1954: Presidential Decree No. 876 (1954-03-17) +# 1961: Law No. 676 (1961-08-07) +# 1987: Law No. 3919 (1986-12-31) +# +# The Wikipedia entry also has confusing information about a change +# to UT+9 in April 1910, but then what would be the point of the later change +# to UT+9 on 1912-01-01? Omit the 1910 change for now. +# +# I guessed that time zone abbreviations through 1945 followed the same # rules as discussed under Taiwan, with nominal switches from JST to KST # when the respective cities were taken over by the Allies after WWII. +# +# For Pyongyang we have no information; guess no changes since World War II. # Zone NAME GMTOFF RULES FORMAT [UNTIL] -Zone Asia/Seoul 8:27:52 - LMT 1890 - 8:30 - KST 1904 Dec - 9:00 - JCST 1928 - 8:30 - KST 1932 +Zone Asia/Seoul 8:27:52 - LMT 1908 Apr 1 + 8:30 - KST 1912 Jan 1 9:00 - JCST 1937 Oct 1 9:00 - JST 1945 Sep 8 9:00 - KST 1954 Mar 21 - 8:00 ROK K%sT 1961 Aug 10 - 8:30 - KST 1968 Oct + 8:30 ROK K%sT 1961 Aug 10 9:00 ROK K%sT -Zone Asia/Pyongyang 8:23:00 - LMT 1890 - 8:30 - KST 1904 Dec - 9:00 - JCST 1928 - 8:30 - KST 1932 +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 1954 Mar 21 - 8:00 - KST 1961 Aug 10 9:00 - KST ############################################################################### diff --git a/contrib/tzdata/australasia b/contrib/tzdata/australasia index 8efe56fd2a2..911e68176a2 100644 --- a/contrib/tzdata/australasia +++ b/contrib/tzdata/australasia @@ -797,19 +797,19 @@ Zone Pacific/Wallis 12:15:20 - LMT 1901 # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2013-02-21): -# A good source for time zone historical data outside the U.S. is +# From Paul Eggert (2014-10-31): +# +# Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), # San Diego: ACS Publications, Inc. (2003). +# Unfortunately this book contains many errors and cites no sources. # # Gwillim Law writes that a good source # for recent time zone data is the International Air Transport # Association's Standard Schedules Information Manual (IATA SSIM), # published semiannually. Law sent in several helpful summaries -# of the IATA's data after 1990. -# -# Except where otherwise noted, Shanks & Pottenger is the source for -# entries through 1990, and IATA SSIM is the source for entries afterwards. +# of the IATA's data after 1990. Except where otherwise noted, +# IATA SSIM is the source for entries after 1990. # # Another source occasionally used is Edward W. Whitman, World Time Differences, # Whitman Publishing Co, 2 Niagara Av, Ealing, London (undated), which diff --git a/contrib/tzdata/europe b/contrib/tzdata/europe index 27a8b30ea3e..5e78c549981 100644 --- a/contrib/tzdata/europe +++ b/contrib/tzdata/europe @@ -6,16 +6,19 @@ # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2014-05-31): -# A good source for time zone historical data outside the U.S. is +# From Paul Eggert (2014-10-31): +# +# Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), # San Diego: ACS Publications, Inc. (2003). +# Unfortunately this book contains many errors and cites no sources. # # Gwillim Law writes that a good source # for recent time zone data is the International Air Transport # Association's Standard Schedules Information Manual (IATA SSIM), # published semiannually. Law sent in several helpful summaries -# of the IATA's data after 1990. +# of the IATA's data after 1990. Except where otherwise noted, +# IATA SSIM is the source for entries after 1990. # # A reliable and entertaining source about time zones is # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997). @@ -287,6 +290,14 @@ # "Timeball on the ballast office is down. Dunsink time." # -- James Joyce, Ulysses +# "Countess Markievicz ... claimed that the [1916] abolition of Dublin Mean Time +# was among various actions undertaken by the 'English' government that +# would 'put the whole country into the SF (Sinn Féin) camp'. She claimed +# Irish 'public feeling (was) outraged by forcing of English time on us'." +# -- Parsons M. Dublin lost its time zone - and 25 minutes - after 1916 Rising. +# Irish Times 2014-10-27. +# http://www.irishtimes.com/news/politics/dublin-lost-its-time-zone-and-25-minutes-after-1916-rising-1.1977411 + # From Joseph S. Myers (2005-01-26): # Irish laws are available online at . # These include various relating to legal time, for example: @@ -594,6 +605,7 @@ Rule Russia 1992 only - Sep lastSat 23:00 0 - Rule Russia 1993 2010 - Mar lastSun 2:00s 1:00 S Rule Russia 1993 1995 - Sep lastSun 2:00s 0 - Rule Russia 1996 2010 - Oct lastSun 2:00s 0 - +# As described below, Russia's 2014 change affects Zone data, not Rule data. # From Alexander Krivenyshev (2011-06-14): # According to Kremlin press service, Russian President Dmitry Medvedev diff --git a/contrib/tzdata/northamerica b/contrib/tzdata/northamerica index 07f527fe9b7..c91430c0337 100644 --- a/contrib/tzdata/northamerica +++ b/contrib/tzdata/northamerica @@ -991,19 +991,19 @@ Zone America/Menominee -5:50:27 - LMT 1885 Sep 18 12:00 ################################################################################ -# From Paul Eggert (2006-03-22): -# A good source for time zone historical data outside the U.S. is +# From Paul Eggert (2014-10-31): +# +# Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), # San Diego: ACS Publications, Inc. (2003). +# Unfortunately this book contains many errors and cites no sources. # # Gwillim Law writes that a good source # for recent time zone data is the International Air Transport # Association's Standard Schedules Information Manual (IATA SSIM), # published semiannually. Law sent in several helpful summaries -# of the IATA's data after 1990. -# -# Except where otherwise noted, Shanks & Pottenger is the source for -# entries through 1990, and IATA SSIM is the source for entries afterwards. +# of the IATA's data after 1990. Except where otherwise noted, +# IATA SSIM is the source for entries after 1990. # # Other sources occasionally used include: # @@ -3131,13 +3131,17 @@ Zone America/Miquelon -3:44:40 - LMT 1911 May 15 # St Pierre # From Paul Eggert (2014-08-19): # The 2014-08-13 Cabinet meeting decided to stay on UTC-4 year-round. See: # http://tcweeklynews.com/daylight-savings-time-to-be-maintained-p5353-127.htm -# Model this as a switch from EST/EDT to AST on 2014-11-02 at 02:00. +# Model this as a switch from EST/EDT to AST ... +# From Chris Walton (2014-11-04): +# ... the TCI government appears to have delayed the switch to +# "permanent daylight saving time" by one year.... +# http://tcweeklynews.com/time-change-to-go-ahead-this-november-p5437-127.htm # # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone America/Grand_Turk -4:44:32 - LMT 1890 -5:07:11 - KMT 1912 Feb # Kingston Mean Time -5:00 - EST 1979 - -5:00 US E%sT 2014 Nov 2 2:00 + -5:00 US E%sT 2015 Nov Sun>=1 2:00 -4:00 - AST # British Virgin Is diff --git a/contrib/tzdata/southamerica b/contrib/tzdata/southamerica index e2466461dd3..bdc29c214ed 100644 --- a/contrib/tzdata/southamerica +++ b/contrib/tzdata/southamerica @@ -6,23 +6,23 @@ # tz@iana.org for general use in the future). For more, please see # the file CONTRIBUTING in the tz distribution. -# From Paul Eggert (2006-03-22): -# A good source for time zone historical data outside the U.S. is +# From Paul Eggert (2014-10-31): +# +# Unless otherwise specified, the source for data through 1990 is: # Thomas G. Shanks and Rique Pottenger, The International Atlas (6th edition), # San Diego: ACS Publications, Inc. (2003). -# -# For data circa 1899, a common source is: -# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. -# http://www.jstor.org/stable/1774359 +# Unfortunately this book contains many errors and cites no sources. # # Gwillim Law writes that a good source # for recent time zone data is the International Air Transport # Association's Standard Schedules Information Manual (IATA SSIM), # published semiannually. Law sent in several helpful summaries -# of the IATA's data after 1990. +# of the IATA's data after 1990. Except where otherwise noted, +# IATA SSIM is the source for entries after 1990. # -# Except where otherwise noted, Shanks & Pottenger is the source for -# entries through 1990, and IATA SSIM is the source for entries afterwards. +# For data circa 1899, a common source is: +# Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94. +# http://www.jstor.org/stable/1774359 # # Earlier editions of these tables used the North American style (e.g. ARST and # ARDT for Argentine Standard and Daylight Time), but the following quote diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 79799bf9165..1422390e978 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -514,9 +514,6 @@ stf_interface_ipv4plen="0" # Prefix length for 6to4 IPv4 addr, stf_interface_ipv6_ifid="0:0:0:1" # IPv6 interface id for stf0. # If you like, you can set "AUTO" for this. stf_interface_ipv6_slaid="0000" # IPv6 Site Level Aggregator for stf0 -ipv6_faith_prefix="NO" # Set faith prefix to enable a FAITH - # IPv6-to-IPv4 TCP translator. You also need - # faithd(8) setup. ipv6_ipv4mapping="NO" # Set to "YES" to enable IPv4 mapped IPv6 addr # communication. (like ::ffff:a.b.c.d) ipv6_ipfilter_rules="/etc/ipf6.rules" # rules definition file for ipfilter, diff --git a/etc/devd/apple.conf b/etc/devd/apple.conf index 7f066cdf5ad..9a84542d090 100644 --- a/etc/devd/apple.conf +++ b/etc/devd/apple.conf @@ -77,4 +77,4 @@ notify 10 { match "subsystem" "POWER"; match "type" "ACLINE"; action "/etc/rc.d/power_profile $notify"; -} +}; diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index ae377acedc1..8604c55932b 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -149,8 +149,16 @@ .. libproc .. + librt + .. + libthr + dlopen + .. + .. libutil .. + msun + .. .. libexec atf diff --git a/etc/network.subr b/etc/network.subr index 520c9e86a7e..b8e06544ff9 100644 --- a/etc/network.subr +++ b/etc/network.subr @@ -372,7 +372,6 @@ dhcpif() case $1 in lo[0-9]*|\ stf[0-9]*|\ - faith[0-9]*|\ lp[0-9]*|\ sl[0-9]*) return 1 @@ -591,7 +590,6 @@ ipv6_autoconfif() case $_if in lo[0-9]*|\ stf[0-9]*|\ - faith[0-9]*|\ lp[0-9]*|\ sl[0-9]*) return 1 diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index bfa22bfcfd0..f26c190fe9d 100644 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -42,7 +42,6 @@ FILES= DAEMON \ dhclient \ dmesg \ dumpon \ - faith \ fsck \ ftpd \ gbde \ diff --git a/etc/rc.d/NETWORKING b/etc/rc.d/NETWORKING index c86150f85ff..12dd3b0d71b 100755 --- a/etc/rc.d/NETWORKING +++ b/etc/rc.d/NETWORKING @@ -4,7 +4,7 @@ # # PROVIDE: NETWORKING NETWORK -# REQUIRE: netif netoptions routing ppp ipfw stf faith +# REQUIRE: netif netoptions routing ppp ipfw stf # REQUIRE: defaultroute routed mrouted route6d mroute6d resolv bridge # REQUIRE: static_arp static_ndp local_unbound diff --git a/etc/rc.d/bridge b/etc/rc.d/bridge index 4c3b34021d8..93e68a20ab0 100755 --- a/etc/rc.d/bridge +++ b/etc/rc.d/bridge @@ -26,7 +26,7 @@ # # PROVIDE: bridge -# REQUIRE: netif faith ppp stf +# REQUIRE: netif ppp stf # KEYWORD: nojail . /etc/rc.subr diff --git a/etc/rc.d/defaultroute b/etc/rc.d/defaultroute index ea54c83ac0c..8e87775ffb9 100755 --- a/etc/rc.d/defaultroute +++ b/etc/rc.d/defaultroute @@ -6,7 +6,7 @@ # # PROVIDE: defaultroute -# REQUIRE: devd faith netif stf +# REQUIRE: devd netif stf # KEYWORD: nojail . /etc/rc.subr diff --git a/etc/rc.d/faith b/etc/rc.d/faith deleted file mode 100755 index 4790ebd0a57..00000000000 --- a/etc/rc.d/faith +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -# $FreeBSD$ -# - -# PROVIDE: faith -# REQUIRE: netif -# KEYWORD: nojail - -. /etc/rc.subr -. /etc/network.subr - -name="faith" -start_cmd="faith_up" -stop_cmd="faith_down" - -faith_up() -{ - case ${ipv6_faith_prefix} in - [Nn][Oo] | '') - ;; - *) - echo "Configuring IPv6-to-IPv4 TCP relay capturing interface:" \ - " faith0." - ${SYSCTL} net.inet6.ip6.keepfaith=1 - ifconfig faith0 create >/dev/null 2>&1 - ifconfig faith0 up - for prefix in ${ipv6_faith_prefix}; do - prefixlen=`expr "${prefix}" : ".*/\(.*\)"` - case ${prefixlen} in - '') - prefixlen=96 - ;; - *) - prefix=`expr "${prefix}" : \ - "\(.*\)/${prefixlen}"` - ;; - esac - route add -inet6 ${prefix} -prefixlen ${prefixlen} ::1 - route change -inet6 ${prefix} -prefixlen ${prefixlen} \ - -ifp faith0 - done - check_startmsgs && ifconfig faith0 - ;; - esac -} - -faith_down() -{ - echo "Removing IPv6-to-IPv4 TCP relay capturing interface: faith0." - ifconfig faith0 destroy - ${SYSCTL} net.inet6.ip6.keepfaith=0 - - case ${ipv6_faith_prefix} in - [Nn][Oo] | '') - ;; - *) - for prefix in ${ipv6_faith_prefix}; do - prefixlen=`expr "${prefix}" : ".*/\(.*\)"` - case ${prefixlen} in - '') - prefixlen=96 - ;; - *) - prefix=`expr "${prefix}" : \ - "\(.*\)/${prefixlen}"` - ;; - esac - route delete -inet6 ${prefix} -prefixlen ${prefixlen} - done - ;; - esac -} - -load_rc_config $name -run_rc_command "$1" diff --git a/etc/rc.d/routing b/etc/rc.d/routing index 9cb07e57698..b38147153b0 100755 --- a/etc/rc.d/routing +++ b/etc/rc.d/routing @@ -6,7 +6,7 @@ # # PROVIDE: routing -# REQUIRE: faith netif ppp stf +# REQUIRE: netif ppp stf # KEYWORD: nojailvnet . /etc/rc.subr @@ -245,7 +245,7 @@ static_inet6() [Nn][Oo][Nn][Ee]) return ;; - lo0|faith[0-9]*) + lo0) continue ;; esac diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h index 1a32d8a125a..379861b0cad 100644 --- a/gnu/usr.bin/gdb/kgdb/kgdb.h +++ b/gnu/usr.bin/gdb/kgdb/kgdb.h @@ -41,7 +41,7 @@ struct kthr { uintptr_t pcb; int tid; int pid; - u_char cpu; + int cpu; }; extern struct kthr *curkthr; diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c index 02c99182fcf..6d206d5ab1a 100644 --- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c +++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c @@ -139,7 +139,7 @@ kgdb_trgt_fetch_tss(void) uintptr_t addr, cpu0prvpage, tss; kt = kgdb_thr_lookup_tid(ptid_get_pid(inferior_ptid)); - if (kt == NULL || kt->cpu == NOCPU) + if (kt == NULL || kt->cpu == NOCPU || kt->cpu < 0) return (0); addr = kgdb_lookup("gdt"); diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index b4c1a33ddff..c50374e7287 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -30,8 +30,6 @@ */ /* - * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. - * * Issues to be discussed: * - Return values. There are nonstandard return values defined and used * in the source code. This is because RFC2553 is silent about which error @@ -101,10 +99,6 @@ __FBSDID("$FreeBSD$"); #include "nscache.h" #endif -#if defined(__KAME__) && defined(INET6) -# define FAITH -#endif - #define ANY 0 #define YES 1 #define NO 0 @@ -1316,47 +1310,6 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr) { char *p; struct addrinfo *ai; -#ifdef FAITH - struct in6_addr faith_prefix; - char *fp_str; - int translate = 0; -#endif - -#ifdef FAITH - /* - * Transfrom an IPv4 addr into a special IPv6 addr format for - * IPv6->IPv4 translation gateway. (only TCP is supported now) - * - * +-----------------------------------+------------+ - * | faith prefix part (12 bytes) | embedded | - * | | IPv4 addr part (4 bytes) - * +-----------------------------------+------------+ - * - * faith prefix part is specified as ascii IPv6 addr format - * in environmental variable GAI. - * For FAITH to work correctly, routing to faith prefix must be - * setup toward a machine where a FAITH daemon operates. - * Also, the machine must enable some mechanizm - * (e.g. faith interface hack) to divert those packet with - * faith prefixed destination addr to user-land FAITH daemon. - */ - fp_str = getenv("GAI"); - if (fp_str && inet_pton(AF_INET6, fp_str, &faith_prefix) == 1 && - afd->a_af == AF_INET && pai->ai_socktype == SOCK_STREAM) { - u_int32_t v4a; - u_int8_t v4a_top; - - memcpy(&v4a, addr, sizeof v4a); - v4a_top = v4a >> IN_CLASSA_NSHIFT; - if (!IN_MULTICAST(v4a) && !IN_EXPERIMENTAL(v4a) && - v4a_top != 0 && v4a != IN_LOOPBACKNET) { - afd = &afdl[N_INET6]; - memcpy(&faith_prefix.s6_addr[12], addr, - sizeof(struct in_addr)); - translate = 1; - } - } -#endif ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + (afd->a_socklen)); @@ -1370,11 +1323,6 @@ get_ai(const struct addrinfo *pai, const struct afd *afd, const char *addr) ai->ai_addrlen = afd->a_socklen; ai->ai_addr->sa_family = ai->ai_family = afd->a_af; p = (char *)(void *)(ai->ai_addr); -#ifdef FAITH - if (translate == 1) - memcpy(p + afd->a_off, &faith_prefix, (size_t)afd->a_addrlen); - else -#endif memcpy(p + afd->a_off, addr, (size_t)afd->a_addrlen); return ai; } diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index ffd34a137ec..005b8773bfc 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -414,7 +414,6 @@ getnameinfo_link(const struct sockaddr *sa, socklen_t salen, /* * The following have zero-length addresses. * IFT_ATM (net/if_atmsubr.c) - * IFT_FAITH (net/if_faith.c) * IFT_GIF (net/if_gif.c) * IFT_LOOP (net/if_loop.c) * IFT_PPP (net/if_ppp.c, net/if_spppsubr.c) diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 07a45377967..c14b35111e7 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -356,6 +356,7 @@ MLINKS+=pdfork.2 pdgetpid.2\ pdfork.2 pdkill.2 \ pdfork.2 pdwait4.2 MLINKS+=pipe.2 pipe2.2 +MLINKS+=poll.2 ppoll.2 MLINKS+=read.2 pread.2 \ read.2 preadv.2 \ read.2 readv.2 diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index fe887c3ddd5..448bcce2675 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -399,6 +399,10 @@ FBSD_1.3 { wait6; }; +FBSD_1.4 { + ppoll; +}; + FBSDprivate_1.0 { ___acl_aclcheck_fd; __sys___acl_aclcheck_fd; @@ -821,6 +825,8 @@ FBSDprivate_1.0 { __sys_pipe; _poll; __sys_poll; + _ppoll; + __sys_ppoll; _preadv; __sys_preadv; _procctl; diff --git a/lib/libc/sys/poll.2 b/lib/libc/sys/poll.2 index 932186d7fb8..a1c7ada4ff3 100644 --- a/lib/libc/sys/poll.2 +++ b/lib/libc/sys/poll.2 @@ -28,7 +28,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd July 8, 2002 +.Dd November 13, 2014 .Dt POLL 2 .Os .Sh NAME @@ -40,6 +40,13 @@ .In poll.h .Ft int .Fn poll "struct pollfd fds[]" "nfds_t nfds" "int timeout" +.Ft int +.Fo ppoll +.Fa "struct pollfd fds[]" +.Fa "nfds_t nfds" +.Fa "const struct timespec * restrict timeout" +.Fa "const sigset_t * restrict newsigmask" +.Fc .Sh DESCRIPTION The .Fn poll @@ -139,6 +146,47 @@ If is zero, then .Fn poll will return without blocking. +.Pp +The +.Fn ppoll +system call, unlike +.Fn poll , +is used to safely wait until either a set of file descriptors becomes +ready or until a signal is caught. +The +.Fa fds +and +.Fa nfds +arguments are identical to the analogous arguments of +.Fn poll . +The +.Fa timeout +argument in +.Fn ppoll +points to a +.Vt "const struct timespec" +which is defined in +.In sys/timespec.h +(shown below) rather than the +.Vt "int timeout" +used by +.Fn poll . +A null pointer may be passed to indicate that +.Fn ppoll +should wait indefinitely. +Finally, +.Fa newsigmask +specifies a signal mask which is set while waiting for input. +When +.Fn ppoll +returns, the original signal mask is restored. +.Pp +.Bd -literal +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; +.Ed .Sh RETURN VALUES The .Fn poll @@ -185,17 +233,26 @@ points outside the process's allocated address space. A signal was delivered before the time limit expired and before any of the selected events occurred. .It Bq Er EINVAL -The specified time limit is negative. +The specified time limit is invalid. One of its components is negative or too large. .El .Sh SEE ALSO .Xr accept 2 , .Xr connect 2 , .Xr kqueue 2 , +.Xr pselect 2 , .Xr read 2 , .Xr recv 2 , .Xr select 2 , .Xr send 2 , .Xr write 2 +.Sh STANDARDS +The +.Fn poll +function conforms to +.St -p1003.1-2001 . +The +.Fn ppoll +is not specified by POSIX. .Sh HISTORY The .Fn poll @@ -203,6 +260,10 @@ function appeared in .At V . This manual page and the core of the implementation was taken from .Nx . +The +.Fn ppoll +function first appeared in +.Fx 11.0 .Sh BUGS The distinction between some of the fields in the .Fa events diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile index 39e8838942a..f9a0bd42b6d 100644 --- a/lib/libc/tests/gen/Makefile +++ b/lib/libc/tests/gen/Makefile @@ -4,6 +4,9 @@ TESTSDIR= ${TESTSBASE}/lib/libc/gen +ATF_TESTS_C= arc4random_test +ATF_TESTS_C+= fpclassify2_test + # TODO: t_closefrom, t_cpuset, t_fmtcheck, t_randomid, t_sleep # TODO: t_siginfo (fixes require further inspection) # TODO: t_sethostname_test (consistently screws up the hostname) diff --git a/tools/regression/lib/libc/gen/test-arc4random.c b/lib/libc/tests/gen/arc4random_test.c similarity index 88% rename from tools/regression/lib/libc/gen/test-arc4random.c rename to lib/libc/tests/gen/arc4random_test.c index eb3d88c0e8c..ec82c3272d2 100644 --- a/tools/regression/lib/libc/gen/test-arc4random.c +++ b/lib/libc/tests/gen/arc4random_test.c @@ -27,13 +27,14 @@ #include __FBSDID("$FreeBSD$"); -#include #include +#include #include #include #include #include #include +#include /* * BUFSIZE is the number of bytes of rc4 output to compare. The probability @@ -45,7 +46,9 @@ __FBSDID("$FreeBSD$"); * Test whether arc4random_buf() returns the same sequence of bytes in both * parent and child processes. (Hint: It shouldn't.) */ -int main(int argc, char *argv[]) { +ATF_TC_WITHOUT_HEAD(test_arc4random); +ATF_TC_BODY(test_arc4random, tc) +{ struct shared_page { char parentbuf[BUFSIZE]; char childbuf[BUFSIZE]; @@ -65,10 +68,7 @@ int main(int argc, char *argv[]) { arc4random_buf(&c, 1); pid = fork(); - if (pid < 0) { - printf("fail 1 - fork\n"); - exit(1); - } + ATF_REQUIRE(0 <= pid); if (pid == 0) { /* child */ arc4random_buf(page->childbuf, BUFSIZE); @@ -79,11 +79,14 @@ int main(int argc, char *argv[]) { arc4random_buf(page->parentbuf, BUFSIZE); wait(&status); } - if (memcmp(page->parentbuf, page->childbuf, BUFSIZE) == 0) { - printf("fail 1 - sequences are the same\n"); - exit(1); - } - - printf("ok 1 - sequences are different\n"); - exit(0); + ATF_CHECK_MSG(memcmp(page->parentbuf, page->childbuf, BUFSIZE) != 0, + "sequences are the same"); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, test_arc4random); + + return (atf_no_error()); } diff --git a/lib/libc/tests/gen/fpclassify2_test.c b/lib/libc/tests/gen/fpclassify2_test.c new file mode 100644 index 00000000000..a6bb1df3c9f --- /dev/null +++ b/lib/libc/tests/gen/fpclassify2_test.c @@ -0,0 +1,72 @@ +/*- + * Copyright (c) 2003 Mike Barcroft + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include + +ATF_TC_WITHOUT_HEAD(test_fpclassify); +ATF_TC_BODY(test_fpclassify, tc) +{ + + ATF_CHECK(fpclassify((float)0) == FP_ZERO); + ATF_CHECK(fpclassify((float)-0.0) == FP_ZERO); + ATF_CHECK(fpclassify((float)1) == FP_NORMAL); + ATF_CHECK(fpclassify((float)1000) == FP_NORMAL); + ATF_CHECK(fpclassify(HUGE_VALF) == FP_INFINITE); + ATF_CHECK(fpclassify((float)HUGE_VAL) == FP_INFINITE); + ATF_CHECK(fpclassify((float)HUGE_VALL) == FP_INFINITE); + ATF_CHECK(fpclassify(NAN) == FP_NAN); + + ATF_CHECK(fpclassify((double)0) == FP_ZERO); + ATF_CHECK(fpclassify((double)-0) == FP_ZERO); + ATF_CHECK(fpclassify((double)1) == FP_NORMAL); + ATF_CHECK(fpclassify((double)1000) == FP_NORMAL); + ATF_CHECK(fpclassify(HUGE_VAL) == FP_INFINITE); + ATF_CHECK(fpclassify((double)HUGE_VALF) == FP_INFINITE); + ATF_CHECK(fpclassify((double)HUGE_VALL) == FP_INFINITE); + ATF_CHECK(fpclassify((double)NAN) == FP_NAN); + + ATF_CHECK(fpclassify((long double)0) == FP_ZERO); + ATF_CHECK(fpclassify((long double)-0.0) == FP_ZERO); + ATF_CHECK(fpclassify((long double)1) == FP_NORMAL); + ATF_CHECK(fpclassify((long double)1000) == FP_NORMAL); + ATF_CHECK(fpclassify(HUGE_VALL) == FP_INFINITE); + ATF_CHECK(fpclassify((long double)HUGE_VALF) == FP_INFINITE); + ATF_CHECK(fpclassify((long double)HUGE_VAL) == FP_INFINITE); + ATF_CHECK(fpclassify((long double)NAN) == FP_NAN); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, test_fpclassify); + + return (atf_no_error()); +} diff --git a/lib/libc/tests/stdio/Makefile b/lib/libc/tests/stdio/Makefile index 3512dd95408..23d5c1ef866 100644 --- a/lib/libc/tests/stdio/Makefile +++ b/lib/libc/tests/stdio/Makefile @@ -2,6 +2,8 @@ TESTSDIR= ${TESTSBASE}/lib/libc/stdio +ATF_TESTS_C= fmemopen2_test + NETBSD_ATF_TESTS_C= clearerr_test NETBSD_ATF_TESTS_C+= fflush_test NETBSD_ATF_TESTS_C+= fmemopen_test diff --git a/tools/regression/lib/libc/stdio/test-fmemopen.c b/lib/libc/tests/stdio/fmemopen2_test.c similarity index 74% rename from tools/regression/lib/libc/stdio/test-fmemopen.c rename to lib/libc/tests/stdio/fmemopen2_test.c index 9f636640a1a..d137780f1ce 100644 --- a/tools/regression/lib/libc/stdio/test-fmemopen.c +++ b/lib/libc/tests/stdio/fmemopen2_test.c @@ -31,14 +31,14 @@ SUCH DAMAGE. #include __FBSDID("$FreeBSD$"); -#include #include #include #include #include +#include -void -test_preexisting() +ATF_TC_WITHOUT_HEAD(test_preexisting); +ATF_TC_BODY(test_preexisting, tc) { /* * Use a pre-existing buffer. @@ -55,55 +55,55 @@ test_preexisting() /* Open a FILE * using fmemopen. */ fp = fmemopen(buf, sizeof(buf), "w"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* Write to the buffer. */ nofw = fwrite(str, 1, sizeof(str), fp); - assert(nofw == sizeof(str)); + ATF_REQUIRE(nofw == sizeof(str)); /* Close the FILE *. */ rc = fclose(fp); - assert(rc == 0); + ATF_REQUIRE(rc == 0); /* Re-open the FILE * to read back the data. */ fp = fmemopen(buf, sizeof(buf), "r"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* Read from the buffer. */ bzero(buf2, sizeof(buf2)); nofr = fread(buf2, 1, sizeof(buf2), fp); - assert(nofr == sizeof(buf2)); + ATF_REQUIRE(nofr == sizeof(buf2)); /* * Since a write on a FILE * retrieved by fmemopen * will add a '\0' (if there's space), we can check * the strings for equality. */ - assert(strcmp(str, buf2) == 0); + ATF_REQUIRE(strcmp(str, buf2) == 0); /* Close the FILE *. */ rc = fclose(fp); - assert(rc == 0); + ATF_REQUIRE(rc == 0); /* Now open a FILE * on the first 4 bytes of the string. */ fp = fmemopen(str, 4, "w"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* * Try to write more bytes than we shoud, we'll get a short count (4). */ nofw = fwrite(str2, 1, sizeof(str2), fp); - assert(nofw == 4); + ATF_REQUIRE(nofw == 4); /* Close the FILE *. */ rc = fclose(fp); /* Check that the string was not modified after the first 4 bytes. */ - assert(strcmp(str, str3) == 0); + ATF_REQUIRE(strcmp(str, str3) == 0); } -void -test_autoalloc() +ATF_TC_WITHOUT_HEAD(test_autoalloc); +ATF_TC_BODY(test_autoalloc, tc) { /* * Let fmemopen allocate the buffer. @@ -117,38 +117,38 @@ test_autoalloc() /* Open a FILE * using fmemopen. */ fp = fmemopen(NULL, 512, "w+"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* fill the buffer */ for (i = 0; i < 512; i++) { nofw = fwrite("a", 1, 1, fp); - assert(nofw == 1); + ATF_REQUIRE(nofw == 1); } /* Get the current position into the stream. */ pos = ftell(fp); - assert(pos == 512); + ATF_REQUIRE(pos == 512); /* * Try to write past the end, we should get a short object count (0) */ nofw = fwrite("a", 1, 1, fp); - assert(nofw == 0); + ATF_REQUIRE(nofw == 0); /* Close the FILE *. */ rc = fclose(fp); - assert(rc == 0); + ATF_REQUIRE(rc == 0); /* Open a FILE * using a wrong mode */ fp = fmemopen(NULL, 512, "r"); - assert(fp == NULL); + ATF_REQUIRE(fp == NULL); fp = fmemopen(NULL, 512, "w"); - assert(fp == NULL); + ATF_REQUIRE(fp == NULL); } -void -test_data_length() +ATF_TC_WITHOUT_HEAD(test_data_length); +ATF_TC_BODY(test_data_length, tc) { /* * Here we test that a read operation doesn't go past the end of the @@ -166,56 +166,56 @@ test_data_length() /* Open a FILE * for updating our buffer. */ fp = fmemopen(buf, sizeof(buf), "w+"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* Write our string into the buffer. */ nofw = fwrite(str, 1, sizeof(str), fp); - assert(nofw == sizeof(str)); + ATF_REQUIRE(nofw == sizeof(str)); /* * Now seek to the end and check that ftell * gives us sizeof(str). */ rc = fseek(fp, 0, SEEK_END); - assert(rc == 0); + ATF_REQUIRE(rc == 0); pos = ftell(fp); - assert(pos == sizeof(str)); + ATF_REQUIRE(pos == sizeof(str)); /* Close the FILE *. */ rc = fclose(fp); - assert(rc == 0); + ATF_REQUIRE(rc == 0); /* Reopen the buffer for appending. */ fp = fmemopen(buf, sizeof(buf), "a+"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* We should now be writing after the first string. */ nofw = fwrite(str2, 1, sizeof(str2), fp); - assert(nofw == sizeof(str2)); + ATF_REQUIRE(nofw == sizeof(str2)); /* Rewind the FILE *. */ rc = fseek(fp, 0, SEEK_SET); - assert(rc == 0); + ATF_REQUIRE(rc == 0); /* Make sure we're at the beginning. */ pos = ftell(fp); - assert(pos == 0); + ATF_REQUIRE(pos == 0); /* Read the whole buffer. */ nofr = fread(str3, 1, sizeof(buf), fp); - assert(nofr == sizeof(str3)); + ATF_REQUIRE(nofr == sizeof(str3)); /* Make sure the two strings are there. */ - assert(strncmp(str3, str, sizeof(str) - 1) == 0); - assert(strncmp(str3 + sizeof(str) - 1, str2, sizeof(str2)) == 0); + ATF_REQUIRE(strncmp(str3, str, sizeof(str) - 1) == 0); + ATF_REQUIRE(strncmp(str3 + sizeof(str) - 1, str2, sizeof(str2)) == 0); /* Close the FILE *. */ rc = fclose(fp); - assert(rc == 0); + ATF_REQUIRE(rc == 0); } -void -test_binary() +ATF_TC_WITHOUT_HEAD(test_binary); +ATF_TC_BODY(test_binary, tc) { /* * Make sure that NULL bytes are never appended when opening a buffer @@ -233,23 +233,23 @@ test_binary() /* Open a FILE * in binary mode. */ fp = fmemopen(buf, sizeof(buf), "w+b"); - assert(fp != NULL); + ATF_REQUIRE(fp != NULL); /* Write some data into it. */ nofw = fwrite(str, 1, strlen(str), fp); - assert(nofw == strlen(str)); + ATF_REQUIRE(nofw == strlen(str)); /* Make sure that the buffer doesn't contain any NULL bytes. */ for (i = 0; i < sizeof(buf); i++) - assert(buf[i] != '\0'); + ATF_REQUIRE(buf[i] != '\0'); /* Close the FILE *. */ rc = fclose(fp); - assert(rc == 0); + ATF_REQUIRE(rc == 0); } -void -test_append_binary_pos() +ATF_TC_WITHOUT_HEAD(test_append_binary_pos); +ATF_TC_BODY(test_append_binary_pos, tc) { /* * For compatibility with other implementations (glibc), we set the @@ -260,7 +260,7 @@ test_append_binary_pos() FILE *fp; fp = fmemopen(NULL, 16, "ab+"); - assert(ftell(fp) == 0L); + ATF_REQUIRE(ftell(fp) == 0L); fclose(fp); /* @@ -268,12 +268,12 @@ test_append_binary_pos() */ char buf[] = "Hello"; fp = fmemopen(buf, sizeof(buf), "ab+"); - assert(ftell(fp) == strlen(buf)); + ATF_REQUIRE(ftell(fp) == strlen(buf)); fclose(fp); } -void -test_size_0() +ATF_TC_WITHOUT_HEAD(test_size_0); +ATF_TC_BODY(test_size_0, tc) { /* * POSIX mandates that we return EINVAL if size is 0. @@ -282,18 +282,19 @@ test_size_0() FILE *fp; fp = fmemopen(NULL, 0, "r+"); - assert(fp == NULL); - assert(errno == EINVAL); + ATF_REQUIRE(fp == NULL); + ATF_REQUIRE(errno == EINVAL); } -int -main(void) +ATF_TP_ADD_TCS(tp) { - test_autoalloc(); - test_preexisting(); - test_data_length(); - test_binary(); - test_append_binary_pos(); - test_size_0(); - return (0); + + ATF_TP_ADD_TC(tp, test_autoalloc); + ATF_TP_ADD_TC(tp, test_preexisting); + ATF_TP_ADD_TC(tp, test_data_length); + ATF_TP_ADD_TC(tp, test_binary); + ATF_TP_ADD_TC(tp, test_append_binary_pos); + ATF_TP_ADD_TC(tp, test_size_0); + + return (atf_no_error()); } diff --git a/lib/libexpat/Makefile b/lib/libexpat/Makefile index 9b641c1dfc8..523a74eacb8 100644 --- a/lib/libexpat/Makefile +++ b/lib/libexpat/Makefile @@ -16,12 +16,10 @@ CLEANFILES= bsdxml.h bsdxml_external.h WARNS?= 2 -# OK, so it is not entirely unadultered: we ammend the COPYING -# to point people to the right place, get rid of some VMS stuff -# and use FreeBSD style indempotency #ifndefs. We also want to -# point it at the new bsdxml_external.h rather than the old -# expat_external.h file. -# +# OK, so it is not entirely unadulterated: we amend the COPYING to +# point people to the right place, get rid of some VMS stuff and use +# FreeBSD-style include guards. We also want to point it at the new +# bsdxml_external.h rather than the old expat_external.h file. bsdxml.h: expat.h unifdef -U__VMS < ${.ALLSRC} | \ sed -e 's/XmlParse_INCLUDED/_BSD_XML_H_/' \ diff --git a/lib/librt/Makefile b/lib/librt/Makefile index f624cf7b1d5..bd6ec0717d9 100644 --- a/lib/librt/Makefile +++ b/lib/librt/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.include + LIB=rt SHLIB_MAJOR= 1 CFLAGS+=-I${.CURDIR}/../libc/include -I${.CURDIR} @@ -18,4 +20,6 @@ PRECIOUSLIB= VERSION_MAP= ${.CURDIR}/Version.map +.include + .include diff --git a/lib/librt/Makefile.amd64 b/lib/librt/Makefile.amd64 new file mode 100644 index 00000000000..dd0f5b0cfb2 --- /dev/null +++ b/lib/librt/Makefile.amd64 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + diff --git a/lib/librt/Makefile.i386 b/lib/librt/Makefile.i386 new file mode 100644 index 00000000000..dd0f5b0cfb2 --- /dev/null +++ b/lib/librt/Makefile.i386 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + diff --git a/lib/librt/tests/Makefile b/lib/librt/tests/Makefile new file mode 100644 index 00000000000..224f52ea85a --- /dev/null +++ b/lib/librt/tests/Makefile @@ -0,0 +1,17 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR:H:H:H} +SRCTOP= ${.CURDIR:H:H:H} +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/librt + +TESTSDIR= ${TESTSBASE}/lib/librt + +DPADD+= ${LIBRT} +LDADD+= -lrt + +NETBSD_ATF_TESTS_C= sched_test +NETBSD_ATF_TESTS_C+= sem_test + +.include + +.include diff --git a/lib/libthr/Makefile b/lib/libthr/Makefile index cfcc41efb99..5cbd0aa3144 100644 --- a/lib/libthr/Makefile +++ b/lib/libthr/Makefile @@ -64,4 +64,6 @@ SYMLINKS+=lib${LIB}_p.a ${LIBDIR}/libpthread_p.a CFLAGS+=-DSYSCALL_COMPAT .endif +.include + .include diff --git a/lib/libthr/Makefile.amd64 b/lib/libthr/Makefile.amd64 new file mode 100644 index 00000000000..dd0f5b0cfb2 --- /dev/null +++ b/lib/libthr/Makefile.amd64 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + diff --git a/lib/libthr/Makefile.i386 b/lib/libthr/Makefile.i386 new file mode 100644 index 00000000000..dd0f5b0cfb2 --- /dev/null +++ b/lib/libthr/Makefile.i386 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + diff --git a/lib/libthr/tests/Makefile b/lib/libthr/tests/Makefile new file mode 100644 index 00000000000..50f07f07e00 --- /dev/null +++ b/lib/libthr/tests/Makefile @@ -0,0 +1,58 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR:H:H:H} +SRCTOP= ${.CURDIR:H:H:H} +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libpthread + +TESTSDIR= ${TESTSBASE}/lib/libthr + +# TODO: t_name (missing pthread_getname_np support in FreeBSD) +NETBSD_ATF_TESTS_C= barrier_test +NETBSD_ATF_TESTS_C+= cond_test +NETBSD_ATF_TESTS_C+= condwait_test +NETBSD_ATF_TESTS_C+= detach_test +NETBSD_ATF_TESTS_C+= equal_test +NETBSD_ATF_TESTS_C+= fork_test +NETBSD_ATF_TESTS_C+= fpu_test +NETBSD_ATF_TESTS_C+= join_test +NETBSD_ATF_TESTS_C+= kill_test +NETBSD_ATF_TESTS_C+= mutex_test +NETBSD_ATF_TESTS_C+= once_test +NETBSD_ATF_TESTS_C+= preempt_test +NETBSD_ATF_TESTS_C+= rwlock_test +NETBSD_ATF_TESTS_C+= sem_test +NETBSD_ATF_TESTS_C+= sigmask_test +NETBSD_ATF_TESTS_C+= sigsuspend_test +NETBSD_ATF_TESTS_C+= siglongjmp_test +NETBSD_ATF_TESTS_C+= sleep_test +NETBSD_ATF_TESTS_C+= swapcontext_test + +NETBSD_ATF_TESTS_SH= atexit_test +NETBSD_ATF_TESTS_SH+= cancel_test +NETBSD_ATF_TESTS_SH+= exit_test +NETBSD_ATF_TESTS_SH+= resolv_test + +DPADD+= ${LIBPTHREAD} +LDADD+= -lpthread +DPADD.fpu_test+= ${LIBM} +LDADD.fpu_test+= -lm +DPADD.sem_test+= ${LIBRT} +LDADD.sem_test+= -lrt + +BINDIR= ${TESTSDIR} + +PROGS= h_atexit +PROGS+= h_cancel +PROGS+= h_exit +PROGS+= h_resolv + +FILESDIR= ${TESTSDIR} +FILES= d_mach + +TESTS_SUBDIRS= dlopen + +.include + +CFLAGS.condwait_test+= -I${SRCTOP}/contrib/netbsd-tests/lib/libc/gen + +.include diff --git a/lib/libthr/tests/dlopen/Makefile b/lib/libthr/tests/dlopen/Makefile new file mode 100644 index 00000000000..0764bfa1593 --- /dev/null +++ b/lib/libthr/tests/dlopen/Makefile @@ -0,0 +1,30 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR:H:H:H:H} +SRCTOP= ${.CURDIR:H:H:H:H} +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libpthread/dlopen + +.include + +TESTSDIR= ${TESTSBASE}/lib/libthr/dlopen + +CFLAGS+= -DTESTDIR=\"${TESTSDIR:Q}/\" +LDFLAGS+= -L${.OBJDIR}/dso -Wl,-rpath=${TESTDIR} + +.if !defined(NO_PIC) +SUBDIR+= dso + +NETBSD_ATF_TESTS_C= dlopen_test +NETBSD_ATF_TESTS_C+= main_pthread_create_test +# XXX: this blocks running the testcase +#NETBSD_ATF_TESTS_C+= dso_pthread_create_test + +.for t in dlopen_test main_pthread_create_test +DPADD.$t+= ${LIBPTHREAD} +LDADD.$t+= -lpthread +.endfor +.endif + +.include + +.include diff --git a/lib/libthr/tests/dlopen/dso/Makefile b/lib/libthr/tests/dlopen/dso/Makefile new file mode 100644 index 00000000000..080dec941a8 --- /dev/null +++ b/lib/libthr/tests/dlopen/dso/Makefile @@ -0,0 +1,19 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR:H:H:H:H:H} +SRCTOP= ${.CURDIR:H:H:H:H:H} +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libpthread/dlopen/dso + +SHLIB= h_pthread_dlopen +SHLIB_MAJOR= 1 +SHLIB_NAME= h_pthread_dlopen.so.${SHLIB_MAJOR} +SRCS= h_pthread_dlopen.c + +DPADD+= ${LIBPTHREAD} +LDADD+= -lpthread + +LIBDIR= ${TESTSBASE}/lib/libthr/dlopen + +.include + +.include diff --git a/lib/msun/Makefile b/lib/msun/Makefile index e8277676818..aee0f2d0331 100644 --- a/lib/msun/Makefile +++ b/lib/msun/Makefile @@ -219,4 +219,8 @@ MLINKS+=tan.3 tanf.3 tan.3 tanl.3 MLINKS+=tanh.3 tanhf.3 tanh.3 tanhl.3 MLINKS+=trunc.3 truncf.3 trunc.3 truncl.3 +.include + +.include + .include diff --git a/lib/msun/Makefile.amd64 b/lib/msun/Makefile.amd64 new file mode 100644 index 00000000000..dd0f5b0cfb2 --- /dev/null +++ b/lib/msun/Makefile.amd64 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + diff --git a/lib/msun/Makefile.i386 b/lib/msun/Makefile.i386 new file mode 100644 index 00000000000..dd0f5b0cfb2 --- /dev/null +++ b/lib/msun/Makefile.i386 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + diff --git a/lib/msun/tests/Makefile b/lib/msun/tests/Makefile new file mode 100644 index 00000000000..4261e4865b5 --- /dev/null +++ b/lib/msun/tests/Makefile @@ -0,0 +1,63 @@ +# $FreeBSD$ + +OBJTOP= ${.OBJDIR:H:H:H} +SRCTOP= ${.CURDIR:H:H:H} +TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libm + +TESTSDIR= ${TESTSBASE}/lib/msun + +.if ${MACHINE} == "sparc" || ${MACHINE} == "i386" \ + || ${MACHINE} == "amd64" || ${MACHINE_CPU} == "arm" \ + || ${MACHINE} == "sparc64" +CFLAGS+= -DHAVE_FENV_H +.endif + +.if ${MACHINE} == "amd64" || ${MACHINE} == "i386" +CFLAGS+= -D__HAVE_LONG_DOUBLE +.endif + +NETBSD_ATF_TESTS_C= acos_test +NETBSD_ATF_TESTS_C+= asin_test +NETBSD_ATF_TESTS_C+= atan_test +NETBSD_ATF_TESTS_C+= cbrt_test +NETBSD_ATF_TESTS_C+= ceil_test +NETBSD_ATF_TESTS_C+= cos_test +NETBSD_ATF_TESTS_C+= cosh_test +NETBSD_ATF_TESTS_C+= erf_test +NETBSD_ATF_TESTS_C+= exp_test +NETBSD_ATF_TESTS_C+= fmod_test +NETBSD_ATF_TESTS_C+= infinity_test +NETBSD_ATF_TESTS_C+= ldexp_test +NETBSD_ATF_TESTS_C+= log_test +NETBSD_ATF_TESTS_C+= pow_test +NETBSD_ATF_TESTS_C+= precision_test +NETBSD_ATF_TESTS_C+= round_test +NETBSD_ATF_TESTS_C+= scalbn_test +NETBSD_ATF_TESTS_C+= sin_test +NETBSD_ATF_TESTS_C+= sinh_test +NETBSD_ATF_TESTS_C+= sqrt_test +NETBSD_ATF_TESTS_C+= tan_test +NETBSD_ATF_TESTS_C+= tanh_test + +CSTD= c99 + +LDADD+= -lm +DPADD+= ${LIBM} +#COPTS+= -Wfloat-equal + +# Copied from lib/msun/Makefile +.if ${MACHINE_CPUARCH} == "i386" +ARCH_SUBDIR= i387 +.else +ARCH_SUBDIR= ${MACHINE_CPUARCH} +.endif + +.include "../${ARCH_SUBDIR}/Makefile.inc" + +# XXX: for some odd reason float.h doesn't tell the full story about what the +# precision is. +CFLAGS+= -DLDBL_PREC=${LDBL_PREC} + +.include + +.include diff --git a/libexec/fingerd/fingerd.8 b/libexec/fingerd/fingerd.8 index 304479f1caa..ddef1a87251 100644 --- a/libexec/fingerd/fingerd.8 +++ b/libexec/fingerd/fingerd.8 @@ -28,7 +28,7 @@ .\" @(#)fingerd.8 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 1, 2010 +.Dd November 19, 2014 .Dt FINGERD 8 .Os .Sh NAME @@ -86,7 +86,7 @@ returns a report that lists all people logged into the system at that moment. .Pp -If a user name is specified (e.g.\& +If a user name is specified (e.g.,\& .Pf eric Aq Tn CRLF ) then the response lists more extended information for only that particular user, @@ -159,19 +159,3 @@ The .Nm utility appeared in .Bx 4.3 . -.Sh BUGS -Connecting directly to the server from a -.Tn TIP -or an equally narrow-minded -.Tn TELNET Ns \-protocol -user program can result -in meaningless attempts at option negotiation being sent to the -server, which will foul up the command line interpretation. -The -.Nm -utility should be taught to filter out -.Tn IAC Ns \'s -and perhaps even respond -negatively -.Pq Tn IAC WON'T -to all option commands received. diff --git a/libexec/telnetd/Makefile b/libexec/telnetd/Makefile index 690b03c7ff9..07de1970471 100644 --- a/libexec/telnetd/Makefile +++ b/libexec/telnetd/Makefile @@ -25,6 +25,7 @@ CFLAGS+= -DINET6 .endif CFLAGS+= -I${TELNETDIR} +CFLAGS+= -I${TELNETDIR}/telnet LIBTELNET= ${.OBJDIR}/../../lib/libtelnet/libtelnet.a diff --git a/release/picobsd/bridge/PICOBSD b/release/picobsd/bridge/PICOBSD index 47f88963265..bc1185d61c6 100644 --- a/release/picobsd/bridge/PICOBSD +++ b/release/picobsd/bridge/PICOBSD @@ -109,7 +109,6 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" #device gif 4 # IPv6 and IPv4 tunneling -#device faith 1 # IPv6-to-IPv4 relaying (translation) device tap #options DEVICE_POLLING diff --git a/release/picobsd/qemu/PICOBSD b/release/picobsd/qemu/PICOBSD index 2b4cdabec3c..16b175385b0 100644 --- a/release/picobsd/qemu/PICOBSD +++ b/release/picobsd/qemu/PICOBSD @@ -114,7 +114,6 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" #device gif 4 # IPv6 and IPv4 tunneling -#device faith 1 # IPv6-to-IPv4 relaying (translation) device tap #options VIMAGE # soner or later we may want to test this diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index 4129cf4c272..cdb379dc6d2 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -5827,15 +5827,31 @@ scsisanitize(struct cam_device *device, int argc, char **argv, if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; - if (((retval = cam_send_ccb(device, ccb)) < 0) - || ((immediate == 0) - && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { - const char errstr[] = "error sending sanitize command"; + if (cam_send_ccb(device, ccb) < 0) { + warn("error sending sanitize command"); + error = 1; + goto scsisanitize_bailout; + } - if (retval < 0) - warn(errstr); - else - warnx(errstr); + if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { + struct scsi_sense_data *sense; + int error_code, sense_key, asc, ascq; + + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == + CAM_SCSI_STATUS_ERROR) { + sense = &ccb->csio.sense_data; + scsi_extract_sense_len(sense, ccb->csio.sense_len - + ccb->csio.sense_resid, &error_code, &sense_key, + &asc, &ascq, /*show_errors*/ 1); + + if (sense_key == SSD_KEY_ILLEGAL_REQUEST && + asc == 0x20 && ascq == 0x00) + warnx("sanitize is not supported by " + "this device"); + else + warnx("error sanitizing this device"); + } else + warnx("error sanitizing this device"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, diff --git a/sbin/gbde/gbde.8 b/sbin/gbde/gbde.8 index 71937679edf..0578287f025 100644 --- a/sbin/gbde/gbde.8 +++ b/sbin/gbde/gbde.8 @@ -233,9 +233,23 @@ pass-phrase: .Pp .Dl "gbde setkey ada0s1f -n 2 -P foo -L key2.lockfile" .Pp -To destroy all copies of the masterkey: +To invalidate your own masterkey: +.Pp +.Dl "gbde nuke ada0s1f" +.Pp +This will overwrite your masterkey sector with zeros, and results in +a diagnostic if you try to use the key again. +You can also destroy the other three copies of the masterkey with the +-n argument. +.Pp +You can also invalidate your masterkey without leaving a tell-tale sector +full of zeros: .Pp .Dl "gbde destroy ada0s1f" +.Pp +This will overwrite the information fields in your masterkey sector, +encrypt it and write it back. +You get a (different) diagnostic if you try to use it. .Sh SEE ALSO .Xr gbde 4 , .Xr geom 4 diff --git a/sbin/gbde/gbde.c b/sbin/gbde/gbde.c index b6baa95ab8c..3dca2126a7a 100644 --- a/sbin/gbde/gbde.c +++ b/sbin/gbde/gbde.c @@ -300,7 +300,6 @@ cmd_attach(const struct g_bde_softc *sc, const char *dest, const char *lfile) gctl_ro_param(r, "key", 16, buf); close(ffd); } - /* gctl_dump(r, stdout); */ errstr = gctl_issue(r); if (errstr != NULL) errx(1, "Attach to %s failed: %s", dest, errstr); @@ -371,7 +370,7 @@ cmd_open(struct g_bde_softc *sc, int dfd , const char *l_opt, u_int *nkey) if (error != 0) errx(1, "Error %d decrypting lock", error); if (nkey) - printf("Opened with key %u\n", *nkey); + printf("Opened with key %u\n", 1 + *nkey); return; } @@ -392,7 +391,7 @@ cmd_nuke(struct g_bde_key *gl, int dfd , int key) free(sbuf); if (i != (int)gl->sectorsize) err(1, "write"); - printf("Nuked key %d\n", key); + printf("Nuked key %d\n", 1 + key); } static void @@ -493,7 +492,7 @@ cmd_destroy(struct g_bde_key *gl, int nkey) bzero(&gl->sector0, sizeof gl->sector0); bzero(&gl->sectorN, sizeof gl->sectorN); bzero(&gl->keyoffset, sizeof gl->keyoffset); - bzero(&gl->flags, sizeof gl->flags); + gl->flags &= GBDE_F_SECT0; bzero(gl->mkey, sizeof gl->mkey); for (i = 0; i < G_BDE_MAXKEYS; i++) if (i != nkey) diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c index 8c15c2143e1..5d23d933ec9 100644 --- a/sbin/geom/core/geom.c +++ b/sbin/geom/core/geom.c @@ -640,6 +640,11 @@ get_class(int *argc, char ***argv) #endif /* !STATIC_GEOM_CLASSES */ set_class_name(); + + /* If we can't load or list, it's not a class. */ + if (!std_available("load") && !std_available("list")) + errx(EXIT_FAILURE, "Invalid class name."); + if (*argc < 1) usage(); } diff --git a/sbin/growfs/growfs.8 b/sbin/growfs/growfs.8 index 0dab89f3594..42dc530a197 100644 --- a/sbin/growfs/growfs.8 +++ b/sbin/growfs/growfs.8 @@ -37,7 +37,7 @@ .\" $TSHeader: src/sbin/growfs/growfs.8,v 1.3 2000/12/12 19:31:00 tomsoft Exp $ .\" $FreeBSD$ .\" -.Dd November 26, 2013 +.Dd November 20, 2014 .Dt GROWFS 8 .Os .Sh NAME @@ -96,12 +96,14 @@ This value defaults to the size of the raw partition specified in will enlarge the file system to the size of the entire partition). .El .Sh EXAMPLES -.Dl growfs -s 2G /dev/ada0p1 +Expand root file system to fill up available space: +.Dl growfs / .Pp -will enlarge +Resize .Pa /dev/ada0p1 -up to 2GB if there is enough space in -.Pa /dev/ada0p1 . +partition to 2GB and expand the file system: +.Dl gpart resize -i 1 -s 2G ada0 +.Dl growfs -s 2G /dev/ada0p1 .Sh SEE ALSO .Xr dumpfs 8 , .Xr ffsinfo 8 , @@ -115,7 +117,7 @@ The .Nm utility first appeared in .Fx 4.4 . -The ability to resize mounted filesystems was added in +The ability to resize mounted file systems was added in .Fx 10.0 . .Sh AUTHORS .An Christoph Herrmann Aq Mt chm@FreeBSD.org diff --git a/sbin/ifconfig/ifgroup.c b/sbin/ifconfig/ifgroup.c index f8b18b4a983..e3f271d4429 100644 --- a/sbin/ifconfig/ifgroup.c +++ b/sbin/ifconfig/ifgroup.c @@ -86,9 +86,6 @@ getifgroups(int s) struct ifgroupreq ifgr; struct ifg_req *ifg; - if (!verbose) - return; - memset(&ifgr, 0, sizeof(ifgr)); strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); @@ -121,6 +118,8 @@ getifgroups(int s) } if (cnt) printf("\n"); + + free(ifgr.ifgr_groups); } static void diff --git a/sbin/reboot/boot_i386.8 b/sbin/reboot/boot_i386.8 index d860423f471..690dfcd436e 100644 --- a/sbin/reboot/boot_i386.8 +++ b/sbin/reboot/boot_i386.8 @@ -36,7 +36,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 1, 2013 +.Dd November 14, 2014 .Dt BOOT 8 i386 .Os .Sh NAME @@ -56,6 +56,11 @@ Some BIOSes allow you to change this default sequence, and may also include a CD-ROM drive as a boot device. .Pp +Some newer PCs boot using UEFI firmware, not BIOS. +That process is described +in +.Xr uefi 8 . +.Pp By default, a three-stage bootstrap is employed, and control is automatically passed from the boot blocks (bootstrap stages one and two) to a separate third-stage bootstrap program, @@ -355,7 +360,8 @@ requirement has not been adhered to. .Xr loader 8 , .Xr nextboot 8 , .Xr reboot 8 , -.Xr shutdown 8 +.Xr shutdown 8 , +.Xr uefi 8 .Sh BUGS The bsdlabel format used by this version of .Bx diff --git a/sbin/route/keywords b/sbin/route/keywords index 8b64be28d38..82edc46690d 100644 --- a/sbin/route/keywords +++ b/sbin/route/keywords @@ -40,7 +40,6 @@ osi prefixlen proto1 proto2 -proto3 proxy recvpipe reject diff --git a/sbin/route/route.8 b/sbin/route/route.8 index 000fbe9c187..5e6f78b4e01 100644 --- a/sbin/route/route.8 +++ b/sbin/route/route.8 @@ -28,7 +28,7 @@ .\" @(#)route.8 8.3 (Berkeley) 3/19/94 .\" $FreeBSD$ .\" -.Dd January 11, 2014 +.Dd November 11, 2014 .Dt ROUTE 8 .Os .Sh NAME @@ -315,7 +315,6 @@ by indicating the following corresponding modifiers: -blackhole RTF_BLACKHOLE - silently discard pkts (during updates) -proto1 RTF_PROTO1 - set protocol specific routing flag #1 -proto2 RTF_PROTO2 - set protocol specific routing flag #2 --proto3 RTF_PROTO3 - set protocol specific routing flag #3 .Ed .Pp The optional modifiers diff --git a/sbin/route/route.c b/sbin/route/route.c index 604057d147d..53ec2986341 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -847,9 +847,6 @@ newroute(int argc, char **argv) case K_PROTO2: flags |= RTF_PROTO2; break; - case K_PROTO3: - flags |= RTF_PROTO3; - break; case K_PROXY: nrflags |= F_PROXY; break; @@ -1590,7 +1587,7 @@ static const char routeflags[] = "\1UP\2GATEWAY\3HOST\4REJECT\5DYNAMIC\6MODIFIED\7DONE" "\012XRESOLVE\013LLINFO\014STATIC\015BLACKHOLE" "\017PROTO2\020PROTO1\021PRCLONING\022WASCLONED\023PROTO3" - "\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY"; + "\024FIXEDMTU\025PINNED\026LOCAL\027BROADCAST\030MULTICAST\035STICKY"; static const char ifnetflags[] = "\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5PTP\6b6\7RUNNING\010NOARP" "\011PPROMISC\012ALLMULTI\013OACTIVE\014SIMPLEX\015LINK0\016LINK1" diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 346f2972e73..76b3d55c2c6 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -132,7 +132,6 @@ MAN= aac.4 \ et.4 \ eventtimers.4 \ exca.4 \ - faith.4 \ fatm.4 \ fd.4 \ fdc.4 \ @@ -637,7 +636,6 @@ MLINKS+=en.4 if_en.4 MLINKS+=enc.4 if_enc.4 MLINKS+=epair.4 if_epair.4 MLINKS+=et.4 if_et.4 -MLINKS+=faith.4 if_faith.4 MLINKS+=fatm.4 if_fatm.4 MLINKS+=fd.4 stderr.4 \ fd.4 stdin.4 \ diff --git a/share/man/man4/acpi.4 b/share/man/man4/acpi.4 index 8196c43b584..17cf1cbab65 100644 --- a/share/man/man4/acpi.4 +++ b/share/man/man4/acpi.4 @@ -238,7 +238,8 @@ Override the assumed memory starting address for PCI host bridges. .It Va hw.acpi.install_interface , hw.acpi.remove_interface Install or remove OS interface(s) to control return value of .Ql _OSI -query method. When an OS interface is specified in +query method. +When an OS interface is specified in .Va hw.acpi.install_interface , .Li _OSI query for the interface returns it is @@ -249,7 +250,8 @@ Conversely, when an OS interface is specified in query returns it is .Em not supported . Multiple interfaces can be specified in a comma-separated list and -any leading white spaces will be ignored. For example, +any leading white spaces will be ignored. +For example, .Qq Li FreeBSD, Linux is a valid list of two interfaces .Qq Li FreeBSD @@ -626,13 +628,3 @@ IRQ routing problems. Upgrade your BIOS to the latest version available from the vendor before deciding it is a problem with .Nm . -.Pp -The -.Nm -CPU idle power management drive conflicts with the local APIC (LAPIC) -timer. -Disable the local APIC timer with -.Va hint.apic.0.clock=0 -or do not use the -.Li C3 -and deeper states if the local APIC timer is enabled. diff --git a/share/man/man4/dpt.4 b/share/man/man4/dpt.4 index fecb7a54583..eddba6cc4e7 100644 --- a/share/man/man4/dpt.4 +++ b/share/man/man4/dpt.4 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 18, 2006 +.Dd November 13, 2014 .Dt DPT 4 .Os .Sh NAME @@ -40,9 +40,6 @@ kernel configuration file: For one or more EISA cards: .Cd "device eisa" .Pp -For one or more ISA cards: -.Cd "device isa" -.Pp For one or more PCI cards: .Cd "device pci" .Pp diff --git a/share/man/man4/faith.4 b/share/man/man4/faith.4 deleted file mode 100644 index f0a2df6f6c3..00000000000 --- a/share/man/man4/faith.4 +++ /dev/null @@ -1,133 +0,0 @@ -.\" $KAME: faith.4,v 1.9 2001/04/27 17:26:35 itojun Exp $ -.\" -.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. -.\" 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. -.\" 3. Neither the name of the project nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd January 23, 2012 -.Dt FAITH 4 -.Os -.Sh NAME -.Nm faith -.Nd IPv6-to-IPv4 TCP relay capturing interface -.Sh SYNOPSIS -.Cd "device faith" -.Sh DESCRIPTION -The -.Nm -interface captures IPv6 TCP traffic, -for implementing userland IPv6-to-IPv4 TCP relay -like -.Xr faithd 8 . -.Pp -Each -.Nm -interface is created at runtime using interface cloning. -This is -most easily done with the -.Xr ifconfig 8 -.Cm create -command or using the -.Va cloned_interfaces -variable in -.Xr rc.conf 5 . -.Pp -Special action will be taken when IPv6 TCP traffic is seen on a router, -and the default routing table suggests to route it to the -.Nm -interface. -In this case, the packet will be accepted by the router, -regardless of the list of IPv6 interface addresses assigned to the router. -The packet will be captured by an IPv6 TCP socket, if it has the -.Dv IN6P_FAITH -flag turned on and matching address/port pairs. -As a result, -.Nm -will let you capture IPv6 TCP traffic to some specific destination addresses. -Userland programs, such as -.Xr faithd 8 -can use this behavior to relay IPv6 TCP traffic to IPv4 TCP traffic. -The program can accept some specific IPv6 TCP traffic, perform -.Xr getsockname 2 -to get the IPv6 destination address specified by the client, -and perform application-specific address mapping to relay IPv6 TCP to IPv4 TCP. -.Pp -The -.Dv IN6P_FAITH -flag on a IPv6 TCP socket can be set by using -.Xr setsockopt 2 , -with level -.Dv IPPROTO_IPV6 -and optname -.Dv IPv6_FAITH . -.Pp -To handle error reports by ICMPv6, some ICMPv6 packets routed to an -.Nm -interface will be delivered to IPv6 TCP, as well. -.Pp -To understand how -.Nm -can be used, take a look at the source code of -.Xr faithd 8 . -.Pp -As the -.Nm -interface implements potentially dangerous operations, -great care must be taken when configuring it. -To avoid possible misuse, the -.Xr sysctl 8 -variable -.Li net.inet6.ip6.keepfaith -must be set to -.Li 1 -prior to using the interface. -When -.Li net.inet6.ip6.keepfaith -is -.Li 0 , -no packets will be captured by the -.Nm -interface. -.Pp -The -.Nm -interface is intended to be used on routers, not on hosts. -.\" -.Sh SEE ALSO -.Xr inet 4 , -.Xr inet6 4 , -.Xr faithd 8 -.Rs -.%A Jun-ichiro itojun Hagino -.%A Kazu Yamamoto -.%T "An IPv6-to-IPv4 transport relay translator" -.%O RFC3142 -.Re -.Sh HISTORY -The FAITH IPv6-to-IPv4 TCP relay translator first appeared in the -WIDE hydrangea IPv6 stack. diff --git a/share/man/man4/inet.4 b/share/man/man4/inet.4 index 0b7a108db52..b0b5a9ee30e 100644 --- a/share/man/man4/inet.4 +++ b/share/man/man4/inet.4 @@ -211,21 +211,6 @@ Boolean: enable/disable accepting of source-routed IP packets (default false). .It Dv IPCTL_SOURCEROUTE .Pq ip.sourceroute Boolean: enable/disable forwarding of source-routed IP packets (default false). -.It Dv IPCTL_RTEXPIRE -.Pq ip.rtexpire -Integer: lifetime in seconds of protocol-cloned -.Tn IP -routes after the last reference drops (default one hour). -This value varies dynamically as described above. -.It Dv IPCTL_RTMINEXPIRE -.Pq ip.rtminexpire -Integer: minimum value of ip.rtexpire (default ten seconds). -This value has no effect on user modifications, but restricts the dynamic -adaptation described above. -.It Dv IPCTL_RTMAXCACHE -.Pq ip.rtmaxcache -Integer: trigger level of cached, unreferenced, protocol-cloned routes -which initiates dynamic adaptation (default 128). .It Va ip.process_options Integer: control IP options processing. By setting this variable to 0, all IP options in the incoming packets diff --git a/share/man/man4/inet6.4 b/share/man/man4/inet6.4 index 93015e0551b..815dee7c038 100644 --- a/share/man/man4/inet6.4 +++ b/share/man/man4/inet6.4 @@ -241,17 +241,6 @@ Defaults to off. Boolean: the default value of a per-interface flag to enable/disable performing automatic link-local address configuration. Defaults to on. -.It Dv IPV6CTL_KEEPFAITH -.Pq ip6.keepfaith -Boolean: enable/disable -.Dq FAITH -TCP relay IPv6-to-IPv4 translator code in the kernel. -Refer -.Xr faith 4 -and -.Xr faithd 8 -for detail. -Defaults to off. .It Dv IPV6CTL_LOG_INTERVAL .Pq ip6.log_interval Integer: default interval between @@ -323,21 +312,6 @@ mapped address on .Dv AF_INET6 sockets. Defaults to on. -.It Dv IPV6CTL_RTEXPIRE -.Pq ip6.rtexpire -Integer: lifetime in seconds of protocol-cloned -.Tn IP -routes after the last reference drops (default one hour). -.\"This value varies dynamically as described above. -.It Dv IPV6CTL_RTMINEXPIRE -.Pq ip6.rtminexpire -Integer: minimum value of ip.rtexpire (default ten seconds). -.\"This value has no effect on user modifications, but restricts the dynamic -.\"adaptation described above. -.It Dv IPV6CTL_RTMAXCACHE -.Pq ip6.rtmaxcache -Integer: trigger level of cached, unreferenced, protocol-cloned routes -which initiates dynamic adaptation (default 128). .El .Ss Interaction between IPv4/v6 sockets By default, diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index fcd396c1e7d..dba5e8de539 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -393,10 +393,6 @@ For wildcard sockets, this can restrict connections to IPv6 only. .\".Ox .\"IPv6 sockets are always IPv6-only, so the socket option is read-only .\"(not modifiable). -.It Dv IPV6_FAITH Fa "int *" -Get or set the status of whether -.Xr faith 4 -connections can be made to this socket. .It Dv IPV6_USE_MIN_MTU Fa "int *" Get or set whether the minimal IPv6 maximum transmission unit (MTU) size will be used to avoid fragmentation from occurring for subsequent diff --git a/share/man/man4/ipheth.4 b/share/man/man4/ipheth.4 index 50491fb2f27..85801f2cf5e 100644 --- a/share/man/man4/ipheth.4 +++ b/share/man/man4/ipheth.4 @@ -103,4 +103,3 @@ A command similar to may be required if the device is not recognised automatically by .Nm after it is connected. - diff --git a/share/man/man4/iscsi_initiator.4 b/share/man/man4/iscsi_initiator.4 index f710a64eae3..a391e086d6c 100644 --- a/share/man/man4/iscsi_initiator.4 +++ b/share/man/man4/iscsi_initiator.4 @@ -54,7 +54,6 @@ Users are advised to use instead. .Ef .Pp - The .Nm implements the kernel side of the Internet SCSI (iSCSI) network diff --git a/share/man/man4/rsu.4 b/share/man/man4/rsu.4 index be4aad9b9cc..9d2854c9567 100644 --- a/share/man/man4/rsu.4 +++ b/share/man/man4/rsu.4 @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd May 3, 2014 +.Dd November 19, 2014 .Dt RSU 4 .Os .Sh NAME @@ -119,6 +119,7 @@ wireless network adapters, including: .It Sitecom WL-349 v1 .It Sitecom WL-353 .It Sweex LW154 +.It TRENDnet TEW-646UBH .It TRENDnet TEW-648UB .It TRENDnet TEW-649UB .El diff --git a/share/man/man4/splash.4 b/share/man/man4/splash.4 index 6cbccf3d966..5c3d6e62a61 100644 --- a/share/man/man4/splash.4 +++ b/share/man/man4/splash.4 @@ -66,7 +66,7 @@ Currently the following decoder modules are available: .Pp .Bl -tag -width splash_decoder -compact .It Pa splash_bmp.ko -W*ndows BMP file decoder. +Windows BMP file decoder. While the BMP file format allows images of various color depths, this decoder currently only handles 256 color bitmaps. Bitmaps of other color depths will not be displayed. diff --git a/share/man/man4/virtio_console.4 b/share/man/man4/virtio_console.4 index c30ad573e65..b855f1388da 100644 --- a/share/man/man4/virtio_console.4 +++ b/share/man/man4/virtio_console.4 @@ -56,6 +56,7 @@ each port is accessible through .Sh FILES .Bl -tag -width ".Pa /dev/ttyV?.??" -compact .It Pa /dev/ttyV?.?? +.El .Sh SEE ALSO .Xr tty 4 .Xr virtio 4 diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 721fef01c1c..09583ec1042 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -2948,15 +2948,6 @@ This can be set to .Pq Vt str IPv6 Site Level Aggregator for .Xr stf 4 . -.It Va ipv6_faith_prefix -.Pq Vt str -If not set to -.Dq Li NO , -this is the faith prefix to enable a FAITH IPv6-to-IPv4 TCP -translator. -You also need -.Xr faithd 8 -setup. .It Va ipv6_ipv4mapping .Pq Vt bool If set to diff --git a/share/man/man7/hier.7 b/share/man/man7/hier.7 index 9cba8961d16..76d4f62f630 100644 --- a/share/man/man7/hier.7 +++ b/share/man/man7/hier.7 @@ -28,7 +28,7 @@ .\" @(#)hier.7 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd July 25, 2014 +.Dd November 10, 2014 .Dt HIER 7 .Os .Sh NAME @@ -380,6 +380,8 @@ shared libraries for compatibility .It Pa aout/ a.out backward compatibility libraries .El +.It Pa debug/ +standalone debug data for the base system libraries and binaries .It Pa dtrace/ DTrace library scripts .It Pa engines/ diff --git a/share/man/man7/security.7 b/share/man/man7/security.7 index d51eea2dc68..d84e4a23c62 100644 --- a/share/man/man7/security.7 +++ b/share/man/man7/security.7 @@ -894,41 +894,6 @@ A competent sysadmin will turn off all of these .Xr inetd 8 Ns -internal test services. -.Pp -Spoofed packet attacks may also be used to overload the kernel route cache. -Refer to the -.Va net.inet.ip.rtexpire , net.inet.ip.rtminexpire , -and -.Va net.inet.ip.rtmaxcache -.Xr sysctl 8 -variables. -A spoofed packet attack that uses a random source IP will cause -the kernel to generate a temporary cached route in the route table, viewable -with -.Dq Li "netstat -rna | fgrep W3" . -These routes typically timeout in 1600 -seconds or so. -If the kernel detects that the cached route table has gotten -too big it will dynamically reduce the -.Va rtexpire -but will never decrease it to -less than -.Va rtminexpire . -There are two problems: (1) The kernel does not react -quickly enough when a lightly loaded server is suddenly attacked, and (2) The -.Va rtminexpire -is not low enough for the kernel to survive a sustained attack. -If your servers are connected to the internet via a T3 or better it may be -prudent to manually override both -.Va rtexpire -and -.Va rtminexpire -via -.Xr sysctl 8 . -Never set either parameter to zero -(unless you want to crash the machine :-)). -Setting both parameters to 2 seconds should be sufficient to protect the route -table from attack. .Sh ACCESS ISSUES WITH KERBEROS AND SSH There are a few issues with both Kerberos and SSH that need to be addressed if you intend to use them. diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 52181a27877..c4884eb1a8a 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -345,6 +345,7 @@ MAN= accept_filter.9 \ vmem.9 \ vn_fullpath.9 \ vn_isdisk.9 \ + vnet.9 \ vnode.9 \ VOP_ACCESS.9 \ VOP_ACLCHECK.9 \ diff --git a/share/man/man9/vnet.9 b/share/man/man9/vnet.9 new file mode 100644 index 00000000000..68689eeeb84 --- /dev/null +++ b/share/man/man9/vnet.9 @@ -0,0 +1,502 @@ +.\"- +.\" Copyright (c) 2010 The FreeBSD Foundation +.\" All rights reserved. +.\" +.\" This documentation was written by CK Software GmbH under sponsorship from +.\" the FreeBSD Foundation. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 20, 2014 +.Dt VNET 9 +.Os +.Sh NAME +.Nm VNET +.Nd "network subsystem virtualization infrastructure" +.Sh SYNOPSIS +.Cd "options VIMAGE" +.Cd "options VNET_DEBUG" +.Pp +.In sys/vnet.h +.Pp +.\"------------------------------------------------------------ +.Ss "Constants and Global Variables" +.\" +.Dv VNET_SETNAME +.\" "set_vnet" +.Dv VNET_SYMPREFIX +.\" "vnet_entry_" +.Vt extern struct vnet *vnet0; +.\"------------------------------------------------------------ +.Ss "Variable Declaration" +.Fo VNET +.Fa "name" +.Fc +.\" +.Fo VNET_NAME +.Fa "name" +.Fc +.\" +.Fo VNET_DECLARE +.Fa "type" "name" +.Fc +.\" +.Fo VNET_DEFINE +.Fa "type" "name" +.Fc +.\" +.Bd -literal +#define V_name VNET(name) +.Ed +.\" ------------------------------------------------------------ +.Ss "Virtual Instance Selection" +.\" +.Fo CRED_TO_VNET +.Fa "struct ucred *" +.Fc +.\" +.Fo TD_TO_VNET +.Fa "struct thread *" +.Fc +.\" +.Fo P_TO_VNET +.Fa "struct proc *" +.Fc +.\" +.Fo IS_DEFAULT_VNET +.Fa "struct vnet *" +.Fc +.\" +.Fo VNET_ASSERT +.Fa exp msg +.Fc +.\" +.Fo CURVNET_SET +.Fa "struct vnet *" +.Fc +.\" +.Fo CURVNET_SET_QUIET +.Fa "struct vnet *" +.Fc +.\" +.Fo CURVNET_RESTORE +.Fc +.\" +.Fo VNET_ITERATOR_DECL +.Fa "struct vnet *" +.Fc +.\" +.Fo VNET_FOREACH +.Fa "struct vnet *" +.Fc +.\" ------------------------------------------------------------ +.Ss "Locking" +.\" +.Fo VNET_LIST_RLOCK +.Fc +.Fo VNET_LIST_RUNLOCK +.Fc +.Fo VNET_LIST_RLOCK_NOSLEEP +.Fc +.Fo VNET_LIST_RUNLOCK_NOSLEEP +.Fc +.\" ------------------------------------------------------------ +.Ss "Startup and Teardown Functions" +.\" +.Ft "struct vnet *" +.Fo vnet_alloc +.Fa void +.Fc +.\" +.Ft void +.Fo vnet_destroy +.Fa "struct vnet *" +.Fc +.\" +.Fo VNET_SYSINIT +.Fa ident +.Fa "enum sysinit_sub_id subsystem" +.Fa "enum sysinit_elem_order order" +.Fa "sysinit_cfunc_t func" +.Fa "const void *arg" +.Fc +.\" +.Fo VNET_SYSUNINIT +.Fa ident +.Fa "enum sysinit_sub_id subsystem" +.Fa "enum sysinit_elem_order order" +.Fa "sysinit_cfunc_t func" +.Fa "const void *arg" +.Fc +.\" ------------------------------------------------------------ +.Ss "Eventhandlers" +.\" +.Fo VNET_GLOBAL_EVENTHANDLER_REGISTER +.Fa "const char *name" +.Fa "void *func" +.Fa "void *arg" +.Fa "int priority" +.Fc +.\" +.Fo VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG +.Fa "eventhandler_tag tag" +.Fa "const char *name" +.Fa "void *func" +.Fa "void *arg" +.Fa "int priority" +.Fc +.\" ------------------------------------------------------------ +.Ss "Sysctl Handling" +.Fo SYSCTL_VNET_INT +.Fa parent nbr name access ptr val descr +.Fc +.Fo SYSCTL_VNET_PROC +.Fa parent nbr name access ptr arg handler fmt descr +.Fc +.Fo SYSCTL_VNET_STRING +.Fa parent nbr name access arg len descr +.Fc +.Fo SYSCTL_VNET_STRUCT +.Fa parent nbr name access ptr type descr +.Fc +.Fo SYSCTL_VNET_UINT +.Fa parent nbr name access ptr val descr +.Fc +.Fo VNET_SYSCTL_ARG +.Fa req arg1 +.Fc +.\" ------------------------------------------------------------ +.Sh DESCRIPTION +.Nm +is the name of a technique to virtualize the network stack. +The basic idea is to change global resources most notably variables into +per network stack resources and have functions, sysctls, eventhandlers, +etc. access and handle them in the context of the correct instance. +Each (virtual) network stack is attached to a +.Em prison , +with +.Vt vnet0 +being the unrestricted default network stack of the base system. +.Pp +The global defines for +.Dv VNET_SETNAME +and +.Dv VNET_SYMPREFIX +are shared with +.Xr kvm 3 +to access internals for debugging reasons. +.\" ------------------------------------------------------------ +.Ss "Variable Declaration" +.\" +Variables are virtualized by using the +.Fn VNET_DEFINE +macro rather than writing them out as +.Em type name . +One can still use static initialization or storage class specifiers, e.g., +.Pp +.Dl Li static VNET_DEFINE(int, foo) = 1; +or +.Dl Li static VNET_DEFINE(SLIST_HEAD(, bar), bars); +.Pp +Static initialization is not possible when the virtualized variable +would need to be referenced, e.g., with +.Dq TAILQ_HEAD_INITIALIZER() . +In that case a +.Fn VNET_SYSINIT +based initialization function must be used. +.Pp +External variables have to be declared using the +.Fn VNET_DECLARE +macro. +In either case the convention is to define another macro, +that is then used throughout the implementation to access that variable. +The variable name is usually prefixed by +.Em V_ +to express that it is virtualized. +The +.Fn VNET +macro will then translate accesses to that variable to the copy of the +currently selected instance (see the +.Sx "Virtual instance selection" +section): +.Pp +.Dl Li #define V_name VNET(name) +.Pp +.Em NOTE: +Do not confuse this with the convention used by +.Xr VFS 9 . +.Pp +The +.Fn VNET_NAME +macro returns the offset within the memory region of the virtual network +stack instance. +It is usually only used with +.Fn SYSCTL_VNET_* +macros. +.\" ------------------------------------------------------------ +.Ss "Virtual Instance Selection" +.\" +There are three different places where the current virtual +network stack pointer is stored and can be taken from: +.Bl -enum -offset indent +.It +a +.Em prison : +.Dl "(struct prison *)->pr_vnet" +.Pp +For convenience the following macros are provided: +.Bd -literal -compact -offset indent +.Fn CRED_TO_VNET "struct ucred *" +.Fn TD_TO_VNET "struct thread *" +.Fn P_TO_VNET "struct proc *" +.Ed +.It +a +.Em socket : +.Dl "(struct socket *)->so_vnet" +.It +an +.Em interface : +.Dl "(struct ifnet *)->if_vnet" +.El +.Pp +.\" +In addition the currently active instance is cached in +.Dq "curthread->td_vnet" +which is usually only accessed through the +.Dv curvnet +macro. +.Pp +.\" +To set the correct context of the current virtual network instance, use the +.Fn CURVNET_SET +or +.Fn CURVNET_SET_QUIET +macros. +The +.Fn CURVNET_SET_QUIET +version will not record vnet recursions in case the kernel was compiled +with +.Cd "options VNET_DEBUG" +and should thus only be used in well known cases, where recursion is +unavoidable. +Both macros will save the previous state on the stack and it must be restored +with the +.Fn CURVNET_RESTORE +macro. +.Pp +.Em NOTE: +As the previous state is saved on the stack, you cannot have multiple +.Fn CURVNET_SET +calls in the same block. +.Pp +.Em NOTE: +As the previous state is saved on the stack, a +.Fn CURVNET_RESTORE +call has to be in the same block as the +.Fn CURVNET_SET +call or in a subblock with the same idea of the saved instances as the +outer block. +.Pp +.Em NOTE: +As each macro is a set of operations and, as previously explained, cannot +be put into its own block when defined, one cannot conditionally set +the current vnet context. +The following will +.Em not +work: +.Bd -literal -offset indent +if (condition) + CURVNET_SET(vnet); +.Ed +.Pp +nor would this work: +.Bd -literal -offset indent +if (condition) { + CURVNET_SET(vnet); +} +CURVNET_RESTORE(); +.Ed +.Pp +.\" +Sometimes one needs to loop over all virtual instances, for example to update +virtual from global state, to run a function from a +.Xr callout 9 +for each instance, etc. +For those cases the +.Fn VNET_ITERATOR_DECL +and +.Fn VNET_FOREACH +macros are provided. +The former macro defines the variable that iterates over the loop, +and the latter loops over all of the virtual network stack instances. +See +.Sx "Locking" +for how to savely traverse the list of all virtual instances. +.Pp +.\" +The +.Fn IS_DEFAULT_VNET +macro provides a safe way to check whether the currently active instance is the +unrestricted default network stack of the base system +.Pq Vt vnet0 . +.Pp +.\" +The +.Fn VNET_ASSERT +macro provides a way to conditionally add assertions that are only active with +.Cd "options VIMAGE" +compiled in and either +.Cd "options VNET_DEBUG" +or +.Cd "options INVARIANTS" +enabled as well. +It uses the same semantics as +.Xr KASSERT 9 . +.\" ------------------------------------------------------------ +.Ss "Locking" +.\" +For public access to the list of virtual network stack instances +e.g., by the +.Fn VNET_FOREACH +macro, read locks are provided. +Macros are used to abstract from the actual type of the locks. +If a caller may sleep while traversing the list, it must use the +.Fn VNET_LIST_RLOCK +and +.Fn VNET_LIST_RUNLOCK +macros. +Otherwise, the caller can use +.Fn VNET_LIST_RLOCK_NOSLEEP +and +.Fn VNET_LIST_RUNLOCK_NOSLEEP . +.\" ------------------------------------------------------------ +.Ss "Startup and Teardown Functions" +.\" +To start or tear down a virtual network stack instance the internal +functions +.Fn vnet_alloc +and +.Fn vnet_destroy +are provided and called from the jail framework. +They run the publicly provided methods to handle network stack +startup and teardown. +.Pp +For public control, the system startup interface has been enhanced +to not only handle a system boot but to also handle a virtual +network stack startup and teardown. +To the base system the +.Fn VNET_SYSINIT +and +.Fn VNET_SYSUNINIT +macros look exactly as if there were no virtual network stack. +In fact, if +.Cd "options VIMAGE" +is not compiled in they are compiled to the standard +.Fn SYSINIT +macros. +In addition to that they are run for each virtual network stack +when starting or, in reverse order, when shutting down. +.\" ------------------------------------------------------------ +.Ss "Eventhandlers" +.\" +Eventhandlers can be handled in two ways: +.Pp +.Bl -enum -offset indent -compact +.It +save the +.Em tags +returned in each virtual instance and properly free the eventhandlers +on teardown using those, or +.It +use one eventhandler that will iterate over all virtual network +stack instances. +.El +.Pp +For the first case one can just use the normal +.Xr EVENTHANDLER 9 +functions, while for the second case the +.Fn VNET_GLOBAL_EVENTHANDLER_REGISTER +and +.Fn VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG +macros are provided. +These differ in that +.Fn VNET_GLOBAL_EVENTHANDLER_REGISTER_TAG +takes an extra first argument that will carry the +.Fa "tag" +upon return. +Eventhandlers registered with either of these will not run +.Fa func +directly but +.Fa func +will be called from an internal iterator function for each vnet. +Both macros can only be used for eventhandlers that do not take +additional arguments, as the variadic arguments from an +.Xr EVENTHANDLER_INVOKE 9 +call will be ignored. +.\" ------------------------------------------------------------ +.Ss "Sysctl Handling" +.\" +A +.Xr sysctl 9 +can be virtualized by using one of the +.Fn SYSCTL_VNET_* +macros. +.Pp +They take the same arguments as the standard +.Xr sysctl 9 +functions, with the only difference, that the +.Fa ptr +argument has to be passed as +.Ql &VNET_NAME(foo) +instead of +.Ql &foo +so that the variable can be selected from the correct memory +region of the virtual network stack instance of the caller. +.Pp +For the very rare case a sysctl handler function would want to +handle +.Fa arg1 +itself the +.Fn VNET_SYSCTL_ARG req arg1 +is provided that will translate the +.Fa arg1 +argument to the correct memory address in the virtual network stack +context of the caller. +.\" ------------------------------------------------------------ +.Sh SEE ALSO +.Xr jail 2 , +.Xr kvm 3 , +.Xr EVENTHANDLER 9 , +.\" .Xr pcpu 9 , +.Xr KASSERT 9 , +.Xr sysctl 9 +.\" .Xr SYSINIT 9 +.Sh HISTORY +The virtual network stack implementation first appeared in +.Fx 8.0 . +.Sh AUTHORS +This manual page was written by +.An Bjoern A. Zeeb, CK Software GmbH, +under sponsorship from the FreeBSD Foundation. diff --git a/share/mk/bsd.incs.mk b/share/mk/bsd.incs.mk index 51474376319..a7e7683a514 100644 --- a/share/mk/bsd.incs.mk +++ b/share/mk/bsd.incs.mk @@ -4,7 +4,7 @@ .error bsd.incs.mk cannot be included directly. .endif -.if ${MK_TOOLCHAIN} != "no" +.if ${MK_INCLUDES} != "no" INCSGROUPS?= INCS diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk index c6b689d84c6..f0acf16772d 100644 --- a/share/mk/bsd.lib.mk +++ b/share/mk/bsd.lib.mk @@ -36,7 +36,7 @@ NO_WERROR= .if defined(DEBUG_FLAGS) CFLAGS+= ${DEBUG_FLAGS} -.if ${MK_CTF} != "no" +.if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != "" CTFFLAGS+= -g .endif .else diff --git a/share/mk/bsd.opts.mk b/share/mk/bsd.opts.mk index 0dbd26b347e..c696f4c811a 100644 --- a/share/mk/bsd.opts.mk +++ b/share/mk/bsd.opts.mk @@ -51,6 +51,7 @@ ____: __DEFAULT_YES_OPTIONS = \ ASSERT_DEBUG \ DOCCOMPRESS \ + INCLUDES \ INSTALLLIB \ KERBEROS \ MAN \ diff --git a/share/mk/bsd.own.mk b/share/mk/bsd.own.mk index 1e2344f2dd2..486914bc19b 100644 --- a/share/mk/bsd.own.mk +++ b/share/mk/bsd.own.mk @@ -128,7 +128,6 @@ ____: .if ${MK_CTF} != "no" CTFCONVERT_CMD= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET} -DEBUG_FLAGS+= -g .elif defined(.PARSEDIR) || (defined(MAKE_VERSION) && ${MAKE_VERSION} >= 5201111300) CTFCONVERT_CMD= .else diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk index e4f71045ab2..340950a3cdd 100644 --- a/share/mk/bsd.prog.mk +++ b/share/mk/bsd.prog.mk @@ -20,7 +20,7 @@ NO_WERROR= CFLAGS+=${DEBUG_FLAGS} CXXFLAGS+=${DEBUG_FLAGS} -.if ${MK_CTF} != "no" +.if ${MK_CTF} != "no" && ${DEBUG_FLAGS:M-g} != "" CTFFLAGS+= -g .endif .endif diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index cb493c96475..87c0f9998cd 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -306,6 +306,7 @@ MK_BINUTILS:= no MK_CLANG:= no MK_GCC:= no MK_GDB:= no +MK_INCLUDES:= no .endif .if ${MK_CLANG} == "no" diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 4ff4fc804e8..f69182045e6 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -137,6 +137,8 @@ OBJCFLAGS ?= ${OBJCINCLUDES} ${CFLAGS} -Wno-import OBJCOPY ?= objcopy +OBJDUMP ?= objdump + PC ?= pc PFLAGS ?= diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index fceccd21863..aff685b2797 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -61,11 +61,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include -#include -#include #include #include #include diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 29e698006fa..6a4077c59a5 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -833,6 +833,15 @@ pmap_bootstrap(vm_paddr_t *firstaddr) */ create_pagetables(firstaddr); + /* + * Add a physical memory segment (vm_phys_seg) corresponding to the + * preallocated kernel page table pages so that vm_page structures + * representing these pages will be created. The vm_page structures + * are required for promotion of the corresponding kernel virtual + * addresses to superpage mappings. + */ + vm_phys_add_seg(KPTphys, KPTphys + ptoa(nkpt)); + virtual_avail = (vm_offset_t) KERNBASE + *firstaddr; virtual_avail = pmap_kmem_choose(virtual_avail); diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 069cf8c7b17..f8b75ffdc2e 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -47,6 +47,7 @@ /* done */ ENTRY(bzero) + PUSH_FRAME_POINTER movq %rsi,%rcx xorl %eax,%eax shrq $3,%rcx @@ -57,11 +58,13 @@ ENTRY(bzero) andq $7,%rcx rep stosb + POP_FRAME_POINTER ret END(bzero) /* Address: %rdi */ ENTRY(pagezero) + PUSH_FRAME_POINTER movq $-PAGE_SIZE,%rdx subq %rdx,%rdi xorl %eax,%eax @@ -73,10 +76,12 @@ ENTRY(pagezero) addq $32,%rdx jne 1b sfence + POP_FRAME_POINTER ret END(pagezero) ENTRY(bcmp) + PUSH_FRAME_POINTER movq %rdx,%rcx shrq $3,%rcx cld /* compare forwards */ @@ -91,6 +96,7 @@ ENTRY(bcmp) 1: setne %al movsbl %al,%eax + POP_FRAME_POINTER ret END(bcmp) @@ -100,8 +106,7 @@ END(bcmp) * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800 */ ENTRY(bcopy) - pushq %rbp - movq %rsp,%rbp + PUSH_FRAME_POINTER xchgq %rsi,%rdi movq %rdx,%rcx @@ -118,7 +123,7 @@ ENTRY(bcopy) andq $7,%rcx /* any bytes left? */ rep movsb - popq %rbp + POP_FRAME_POINTER ret /* ALIGN_TEXT */ @@ -138,7 +143,7 @@ ENTRY(bcopy) rep movsq cld - popq %rbp + POP_FRAME_POINTER ret END(bcopy) @@ -146,6 +151,7 @@ END(bcopy) * Note: memcpy does not support overlapping copies */ ENTRY(memcpy) + PUSH_FRAME_POINTER movq %rdx,%rcx shrq $3,%rcx /* copy by 64-bit words */ cld /* copy forwards */ @@ -155,6 +161,7 @@ ENTRY(memcpy) andq $7,%rcx /* any bytes left? */ rep movsb + POP_FRAME_POINTER ret END(memcpy) @@ -162,6 +169,7 @@ END(memcpy) * pagecopy(%rdi=from, %rsi=to) */ ENTRY(pagecopy) + PUSH_FRAME_POINTER movq $-PAGE_SIZE,%rax movq %rax,%rdx subq %rax,%rdi @@ -182,18 +190,21 @@ ENTRY(pagecopy) addq $32,%rdx jne 2b sfence + POP_FRAME_POINTER ret END(pagecopy) /* fillw(pat, base, cnt) */ /* %rdi,%rsi, %rdx */ ENTRY(fillw) + PUSH_FRAME_POINTER movq %rdi,%rax movq %rsi,%rdi movq %rdx,%rcx cld rep stosw + POP_FRAME_POINTER ret END(fillw) @@ -214,6 +225,7 @@ END(fillw) * %rdi, %rsi, %rdx */ ENTRY(copyout) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rax movq $copyout_fault,PCB_ONFAULT(%rax) testq %rdx,%rdx /* anything to do? */ @@ -259,6 +271,7 @@ done_copyout: xorl %eax,%eax movq PCPU(CURPCB),%rdx movq %rax,PCB_ONFAULT(%rdx) + POP_FRAME_POINTER ret ALIGN_TEXT @@ -266,6 +279,7 @@ copyout_fault: movq PCPU(CURPCB),%rdx movq $0,PCB_ONFAULT(%rdx) movq $EFAULT,%rax + POP_FRAME_POINTER ret END(copyout) @@ -274,6 +288,7 @@ END(copyout) * %rdi, %rsi, %rdx */ ENTRY(copyin) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rax movq $copyin_fault,PCB_ONFAULT(%rax) testq %rdx,%rdx /* anything to do? */ @@ -305,6 +320,7 @@ done_copyin: xorl %eax,%eax movq PCPU(CURPCB),%rdx movq %rax,PCB_ONFAULT(%rdx) + POP_FRAME_POINTER ret ALIGN_TEXT @@ -312,6 +328,7 @@ copyin_fault: movq PCPU(CURPCB),%rdx movq $0,PCB_ONFAULT(%rdx) movq $EFAULT,%rax + POP_FRAME_POINTER ret END(copyin) @@ -321,6 +338,7 @@ END(copyin) * dst = %rdi, old = %esi, oldp = %rdx, new = %ecx */ ENTRY(casueword32) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%r8 movq $fusufault,PCB_ONFAULT(%r8) @@ -349,6 +367,7 @@ ENTRY(casueword32) * catch corrupted pointer. */ movl %esi,(%rdx) /* oldp = %rdx */ + POP_FRAME_POINTER ret END(casueword32) @@ -358,6 +377,7 @@ END(casueword32) * dst = %rdi, old = %rsi, oldp = %rdx, new = %rcx */ ENTRY(casueword) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%r8 movq $fusufault,PCB_ONFAULT(%r8) @@ -380,6 +400,7 @@ ENTRY(casueword) xorl %eax,%eax movq %rax,PCB_ONFAULT(%r8) movq %rsi,(%rdx) + POP_FRAME_POINTER ret END(casueword) @@ -391,6 +412,7 @@ END(casueword) ALTENTRY(fueword64) ENTRY(fueword) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -402,11 +424,13 @@ ENTRY(fueword) movq (%rdi),%r11 movq %rax,PCB_ONFAULT(%rcx) movq %r11,(%rsi) + POP_FRAME_POINTER ret -END(fuword64) -END(fuword) +END(fueword64) +END(fueword) ENTRY(fueword32) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -418,6 +442,7 @@ ENTRY(fueword32) movl (%rdi),%r11d movq %rax,PCB_ONFAULT(%rcx) movl %r11d,(%rsi) + POP_FRAME_POINTER ret END(fueword32) @@ -436,6 +461,7 @@ END(suswintr) END(fuswintr) ENTRY(fuword16) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -445,10 +471,12 @@ ENTRY(fuword16) movzwl (%rdi),%eax movq $0,PCB_ONFAULT(%rcx) + POP_FRAME_POINTER ret END(fuword16) ENTRY(fubyte) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -458,6 +486,7 @@ ENTRY(fubyte) movzbl (%rdi),%eax movq $0,PCB_ONFAULT(%rcx) + POP_FRAME_POINTER ret END(fubyte) @@ -467,6 +496,7 @@ fusufault: xorl %eax,%eax movq %rax,PCB_ONFAULT(%rcx) decq %rax + POP_FRAME_POINTER ret /* @@ -476,6 +506,7 @@ fusufault: */ ALTENTRY(suword64) ENTRY(suword) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -487,11 +518,13 @@ ENTRY(suword) xorl %eax,%eax movq PCPU(CURPCB),%rcx movq %rax,PCB_ONFAULT(%rcx) + POP_FRAME_POINTER ret END(suword64) END(suword) ENTRY(suword32) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -503,10 +536,12 @@ ENTRY(suword32) xorl %eax,%eax movq PCPU(CURPCB),%rcx movq %rax,PCB_ONFAULT(%rcx) + POP_FRAME_POINTER ret END(suword32) ENTRY(suword16) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -518,10 +553,12 @@ ENTRY(suword16) xorl %eax,%eax movq PCPU(CURPCB),%rcx /* restore trashed register */ movq %rax,PCB_ONFAULT(%rcx) + POP_FRAME_POINTER ret END(suword16) ENTRY(subyte) + PUSH_FRAME_POINTER movq PCPU(CURPCB),%rcx movq $fusufault,PCB_ONFAULT(%rcx) @@ -534,6 +571,7 @@ ENTRY(subyte) xorl %eax,%eax movq PCPU(CURPCB),%rcx /* restore trashed register */ movq %rax,PCB_ONFAULT(%rcx) + POP_FRAME_POINTER ret END(subyte) @@ -547,6 +585,7 @@ END(subyte) * return the actual length in *lencopied. */ ENTRY(copyinstr) + PUSH_FRAME_POINTER movq %rdx,%r8 /* %r8 = maxlen */ movq %rcx,%r9 /* %r9 = *len */ xchgq %rdi,%rsi /* %rdi = from, %rsi = to */ @@ -603,6 +642,7 @@ cpystrflt_x: subq %rdx,%r8 movq %r8,(%r9) 1: + POP_FRAME_POINTER ret END(copyinstr) @@ -611,6 +651,7 @@ END(copyinstr) * %rdi, %rsi, %rdx, %rcx */ ENTRY(copystr) + PUSH_FRAME_POINTER movq %rdx,%r8 /* %r8 = maxlen */ xchgq %rdi,%rsi @@ -640,6 +681,7 @@ ENTRY(copystr) subq %rdx,%r8 movq %r8,(%rcx) 7: + POP_FRAME_POINTER ret END(copystr) @@ -709,6 +751,7 @@ END(longjmp) */ ENTRY(rdmsr_safe) /* int rdmsr_safe(u_int msr, uint64_t *data) */ + PUSH_FRAME_POINTER movq PCPU(CURPCB),%r8 movq $msr_onfault,PCB_ONFAULT(%r8) movl %edi,%ecx @@ -720,6 +763,7 @@ ENTRY(rdmsr_safe) movq %rax,(%rsi) xorq %rax,%rax movq %rax,PCB_ONFAULT(%r8) + POP_FRAME_POINTER ret /* @@ -727,6 +771,7 @@ ENTRY(rdmsr_safe) */ ENTRY(wrmsr_safe) /* int wrmsr_safe(u_int msr, uint64_t data) */ + PUSH_FRAME_POINTER movq PCPU(CURPCB),%r8 movq $msr_onfault,PCB_ONFAULT(%r8) movl %edi,%ecx @@ -737,6 +782,7 @@ ENTRY(wrmsr_safe) hi byte in edx, lo in %eax. */ xorq %rax,%rax movq %rax,PCB_ONFAULT(%r8) + POP_FRAME_POINTER ret /* @@ -746,4 +792,5 @@ ENTRY(wrmsr_safe) msr_onfault: movq $0,PCB_ONFAULT(%r8) movl $EFAULT,%eax + POP_FRAME_POINTER ret diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index f8ccd4cba5b..c8d509849b5 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -310,7 +310,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/amd64/include/asmacros.h b/sys/amd64/include/asmacros.h index ce8dce4d622..d5652c4a704 100644 --- a/sys/amd64/include/asmacros.h +++ b/sys/amd64/include/asmacros.h @@ -132,6 +132,16 @@ #define MEXITCOUNT #endif /* GPROF */ +/* + * Convenience for adding frame pointers to hand-coded ASM. Useful for + * DTrace, HWPMC, and KDB. + */ +#define PUSH_FRAME_POINTER \ + pushq %rbp ; \ + movq %rsp, %rbp ; +#define POP_FRAME_POINTER \ + popq %rbp + #ifdef LOCORE /* * Convenience macro for declaring interrupt entry points. diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index b1b89b98d8f..58cd694d6fd 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -175,8 +175,14 @@ #define VM_MAX_ADDRESS UPT_MAX_ADDRESS #define VM_MIN_ADDRESS (0) +/* + * XXX Allowing dmaplimit == 0 is a temporary workaround for vt(4) efifb's + * early use of PHYS_TO_DMAP before the mapping is actually setup. This works + * because the result is not actually accessed until later, but the early + * vt fb startup needs to be reworked. + */ #define PHYS_TO_DMAP(x) ({ \ - KASSERT((x) < dmaplimit, \ + KASSERT(dmaplimit == 0 || (x) < dmaplimit, \ ("physical address %#jx not covered by the DMAP", \ (uintmax_t)x)); \ (x) | DMAP_MIN_ADDRESS; }) diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c index a5321062cc7..23bf399d3dc 100644 --- a/sys/arm/allwinner/a10_gpio.c +++ b/sys/arm/allwinner/a10_gpio.c @@ -302,20 +302,6 @@ a10_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->sc_gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->sc_gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together. */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - - /* Can't mix pull-up/pull-down together. */ - if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) == - (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) - return (EINVAL); - a10_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); return (0); diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c index 6a08819e4ae..05bc5863cdd 100644 --- a/sys/arm/arm/busdma_machdep-v6.c +++ b/sys/arm/arm/busdma_machdep-v6.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2012 Ian Lepore + * Copyright (c) 2012-2014 Ian Lepore * Copyright (c) 2010 Mark Tinguely * Copyright (c) 2004 Olivier Houchard * Copyright (c) 2002 Peter Grehan @@ -64,8 +64,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define IS_POWER_OF_2(val) (((val) & ((val) - 1)) == 0) - #define MAX_BPAGES 64 #define MAX_DMA_SEGMENTS 4096 #define BUS_DMA_EXCL_BOUNCE BUS_DMA_BUS2 @@ -348,6 +346,7 @@ static __inline int might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr, bus_size_t size) { + return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) || alignment_bounce(dmat, addr) || cacheline_bounce(map, addr, size)); @@ -446,6 +445,7 @@ busdma_lock_mutex(void *arg, bus_dma_lock_op_t op) static void dflt_lock(void *arg, bus_dma_lock_op_t op) { + panic("driver error: busdma dflt_lock called"); } @@ -469,11 +469,11 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, #endif /* Basic sanity checking. */ - KASSERT(boundary == 0 || IS_POWER_OF_2(boundary), + KASSERT(boundary == 0 || powerof2(boundary), ("dma tag boundary %lu, must be a power of 2", boundary)); KASSERT(boundary == 0 || boundary >= maxsegsz, ("dma tag boundary %lu is < maxsegsz %lu\n", boundary, maxsegsz)); - KASSERT(alignment != 0 && IS_POWER_OF_2(alignment), + KASSERT(alignment != 0 && powerof2(alignment), ("dma tag alignment %lu, must be non-zero power of 2", alignment)); KASSERT(maxsegsz != 0, ("dma tag maxsegsz must not be zero")); @@ -627,7 +627,7 @@ out: static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp) { - struct bounce_zone *bz; + struct bounce_zone *bz; int maxpages; int error; @@ -1254,13 +1254,13 @@ _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map) } #ifdef notyetbounceuser - /* If busdma uses user pages, then the interrupt handler could - * be use the kernel vm mapping. Both bounce pages and sync list - * do not cross page boundaries. - * Below is a rough sequence that a person would do to fix the - * user page reference in the kernel vmspace. This would be - * done in the dma post routine. - */ +/* If busdma uses user pages, then the interrupt handler could + * be use the kernel vm mapping. Both bounce pages and sync list + * do not cross page boundaries. + * Below is a rough sequence that a person would do to fix the + * user page reference in the kernel vmspace. This would be + * done in the dma post routine. + */ void _bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len, pmap_t pmap, int op) @@ -1269,10 +1269,10 @@ _bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len, bus_addr_t curaddr; vm_offset_t va; - /* each synclist entry is contained within a single page. - * - * this would be needed if BUS_DMASYNC_POSTxxxx was implemented - */ + /* + * each synclist entry is contained within a single page. + * this would be needed if BUS_DMASYNC_POSTxxxx was implemented + */ curaddr = pmap_extract(pmap, buf); va = pmap_dma_map(curaddr); switch (op) { @@ -1314,17 +1314,20 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) /* * If the buffer was from user space, it is possible that this is not * the same vm map, especially on a POST operation. It's not clear that - * dma on userland buffers can work at all right now, certainly not if a - * partial cacheline flush has to be handled. To be safe, until we're - * able to test direct userland dma, panic on a map mismatch. + * dma on userland buffers can work at all right now. To be safe, until + * we're able to test direct userland dma, panic on a map mismatch. */ if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { if (!pmap_dmap_iscurrent(map->pmap)) panic("_bus_dmamap_sync: wrong user map for bounce sync."); - /* Handle data bouncing. */ + CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x " "performing bounce", __func__, dmat, dmat->flags, op); + /* + * For PREWRITE do a writeback. Clean the caches from the + * innermost to the outermost levels. + */ if (op & BUS_DMASYNC_PREWRITE) { while (bpage != NULL) { if (bpage->datavaddr != 0) @@ -1336,7 +1339,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) (void *)bpage->vaddr, bpage->datacount); cpu_dcache_wb_range((vm_offset_t)bpage->vaddr, - bpage->datacount); + bpage->datacount); l2cache_wb_range((vm_offset_t)bpage->vaddr, (vm_offset_t)bpage->busaddr, bpage->datacount); @@ -1345,7 +1348,18 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) dmat->bounce_zone->total_bounced++; } - if (op & BUS_DMASYNC_PREREAD) { + /* + * Do an invalidate for PREREAD unless a writeback was already + * done above due to PREWRITE also being set. The reason for a + * PREREAD invalidate is to prevent dirty lines currently in the + * cache from being evicted during the DMA. If a writeback was + * done due to PREWRITE also being set there will be no dirty + * lines and the POSTREAD invalidate handles the rest. The + * invalidate is done from the innermost to outermost level. If + * L2 were done first, a dirty cacheline could be automatically + * evicted from L1 before we invalidated it, re-dirtying the L2. + */ + if ((op & BUS_DMASYNC_PREREAD) && !(op & BUS_DMASYNC_PREWRITE)) { bpage = STAILQ_FIRST(&map->bpages); while (bpage != NULL) { cpu_dcache_inv_range((vm_offset_t)bpage->vaddr, @@ -1356,6 +1370,16 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) bpage = STAILQ_NEXT(bpage, links); } } + + /* + * Re-invalidate the caches on a POSTREAD, even though they were + * already invalidated at PREREAD time. Aggressive prefetching + * due to accesses to other data near the dma buffer could have + * brought buffer data into the caches which is now stale. The + * caches are invalidated from the outermost to innermost; the + * prefetches could be happening right now, and if L1 were + * invalidated first, stale L2 data could be prefetched into L1. + */ if (op & BUS_DMASYNC_POSTREAD) { while (bpage != NULL) { vm_offset_t startv; @@ -1372,8 +1396,8 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) len = (len - (len & arm_dcache_align_mask)) + arm_dcache_align; - cpu_dcache_inv_range(startv, len); l2cache_inv_range(startv, startp, len); + cpu_dcache_inv_range(startv, len); if (bpage->datavaddr != 0) bcopy((void *)bpage->vaddr, (void *)bpage->datavaddr, @@ -1387,13 +1411,33 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) dmat->bounce_zone->total_bounced++; } } - if (map->flags & DMAMAP_COHERENT) - return; + /* + * For COHERENT memory no cache maintenance is necessary, but ensure all + * writes have reached memory for the PREWRITE case. No action is + * needed for a PREREAD without PREWRITE also set, because that would + * imply that the cpu had written to the COHERENT buffer and expected + * the dma device to see that change, and by definition a PREWRITE sync + * is required to make that happen. + */ + if (map->flags & DMAMAP_COHERENT) { + if (op & BUS_DMASYNC_PREWRITE) { + dsb(); + cpu_l2cache_drain_writebuf(); + } + return; + } + + /* + * Cache maintenance for normal (non-COHERENT non-bounce) buffers. All + * the comments about the sequences for flushing cache levels in the + * bounce buffer code above apply here as well. In particular, the fact + * that the sequence is inner-to-outer for PREREAD invalidation and + * outer-to-inner for POSTREAD invalidation is not a mistake. + */ if (map->sync_count != 0) { if (!pmap_dmap_iscurrent(map->pmap)) panic("_bus_dmamap_sync: wrong user map for sync."); - /* ARM caches are not self-snooping for dma */ sl = &map->slist[0]; end = &map->slist[map->sync_count]; @@ -1402,11 +1446,12 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) switch (op) { case BUS_DMASYNC_PREWRITE: + case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD: while (sl != end) { - cpu_dcache_wb_range(sl->vaddr, sl->datacount); - l2cache_wb_range(sl->vaddr, sl->busaddr, - sl->datacount); - sl++; + cpu_dcache_wb_range(sl->vaddr, sl->datacount); + l2cache_wb_range(sl->vaddr, sl->busaddr, + sl->datacount); + sl++; } break; @@ -1419,19 +1464,19 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) } break; - case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD: + case BUS_DMASYNC_POSTWRITE: + break; + + case BUS_DMASYNC_POSTREAD: + case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE: while (sl != end) { - cpu_dcache_wbinv_range(sl->vaddr, sl->datacount); - l2cache_wbinv_range(sl->vaddr, - sl->busaddr, sl->datacount); + l2cache_inv_range(sl->vaddr, sl->busaddr, + sl->datacount); + cpu_dcache_inv_range(sl->vaddr, sl->datacount); sl++; } break; - case BUS_DMASYNC_POSTREAD: - case BUS_DMASYNC_POSTWRITE: - case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE: - break; default: panic("unsupported combination of sync operations: 0x%08x\n", op); break; @@ -1454,12 +1499,14 @@ SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL); static struct sysctl_ctx_list * busdma_sysctl_tree(struct bounce_zone *bz) { + return (&bz->sysctl_tree); } static struct sysctl_oid * busdma_sysctl_tree_top(struct bounce_zone *bz) { + return (bz->sysctl_tree_top); } diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index 9e15f8bc285..f1bb014b2ed 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -277,7 +277,7 @@ arm_gic_attach(device_t dev) arm_config_irq = gic_config_irq; icciidr = gic_c_read_4(GICC_IIDR); - device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x sc->nirqs %u\n", + device_printf(dev,"pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n", icciidr>>20, (icciidr>>16) & 0xF, (icciidr>>12) & 0xf, (icciidr & 0xfff), sc->nirqs); diff --git a/sys/arm/arm/stdatomic.c b/sys/arm/arm/stdatomic.c index a2db9f023fe..301e0a63306 100644 --- a/sys/arm/arm/stdatomic.c +++ b/sys/arm/arm/stdatomic.c @@ -34,10 +34,6 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef _KERNEL -#include "opt_global.h" -#endif - /* * Executing statements with interrupts disabled. */ diff --git a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c index 4c6976525ee..58fa09e1acd 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_bsc.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_bsc.c @@ -441,7 +441,7 @@ bcm_bsc_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) err = mtx_sleep(dev, &sc->sc_mtx, 0, "bsciow", hz); /* Check for errors. */ - if (err != 0 && (sc->sc_flags & BCM_I2C_ERROR)) + if (err == 0 && (sc->sc_flags & BCM_I2C_ERROR)) err = EIO; if (err != 0) break; diff --git a/sys/arm/broadcom/bcm2835/bcm2835_common.c b/sys/arm/broadcom/bcm2835/bcm2835_common.c index 5c3c2580cbe..a53495765c8 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_common.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_common.c @@ -29,8 +29,6 @@ * SUCH DAMAGE. */ -#include "opt_global.h" - #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c index a8903ee82ea..0ade78fd53a 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c @@ -238,9 +238,7 @@ bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state) offset = pin - 32 * bank; BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), state); - DELAY(10); BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), (1 << offset)); - DELAY(10); BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), 0); BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0); } @@ -399,20 +397,6 @@ bcm_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (bcm_gpio_pin_is_ro(sc, pin)) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->sc_gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together. */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - - /* Can't mix pull-up/pull-down together. */ - if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) == - (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) - return (EINVAL); - bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); return (0); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_machdep.c b/sys/arm/broadcom/bcm2835/bcm2835_machdep.c index 0571c55208b..051593abb66 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_machdep.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_machdep.c @@ -38,7 +38,6 @@ #include "opt_ddb.h" #include "opt_platform.h" -#include "opt_global.h" #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c index a92ddba11c7..9f3c27b7b62 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -84,10 +84,13 @@ __FBSDID("$FreeBSD$"); /* * Arasan HC seems to have problem with Data CRC on lower frequencies. * Use this tunable to cap initialization sequence frequency at higher - * value. Default is standard 400kHz + * value. Default is standard 400kHz. + * HS mode brings too many problems for most of cards, so disable HS mode + * until a better fix comes up. + * HS mode still can be enabled with the tunable. */ static int bcm2835_sdhci_min_freq = 400000; -static int bcm2835_sdhci_hs = 1; +static int bcm2835_sdhci_hs = 0; static int bcm2835_sdhci_pio_mode = 0; TUNABLE_INT("hw.bcm2835.sdhci.min_freq", &bcm2835_sdhci_min_freq); diff --git a/sys/arm/conf/ATMEL b/sys/arm/conf/ATMEL index 6cc6fb4c8ef..615e06e4af5 100644 --- a/sys/arm/conf/ATMEL +++ b/sys/arm/conf/ATMEL @@ -143,7 +143,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) #device firmware # firmware assist module # SCSI peripherals diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR index c95a5974961..a3c57a12177 100644 --- a/sys/arm/conf/DOCKSTAR +++ b/sys/arm/conf/DOCKSTAR @@ -54,7 +54,6 @@ options FDT_DTB_STATIC # Misc pseudo devices device bpf # Required for DHCP -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware(9) required for USB wlan device gif # IPv6 and IPv4 tunneling device loop # Network loopback diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001 index 3bfdd913ef6..73695929947 100644 --- a/sys/arm/conf/DREAMPLUG-1001 +++ b/sys/arm/conf/DREAMPLUG-1001 @@ -57,7 +57,6 @@ options FDT_DTB_STATIC # Misc pseudo devices device bpf # Required for DHCP -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware(9) required for USB wlan device gif # IPv6 and IPv4 tunneling device loop # Network loopback diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX index df7a9efc7ba..677d73d9edc 100644 --- a/sys/arm/conf/EFIKA_MX +++ b/sys/arm/conf/EFIKA_MX @@ -104,7 +104,6 @@ device ether # Ethernet support #device tun # Packet tunnel. #device md # Memory "disks" #device gif # IPv6 and IPv4 tunneling -#device faith # IPv6-to-IPv4 relaying (translation) #device firmware # firmware assist module # Serial (COM) ports diff --git a/sys/arm/conf/ETHERNUT5 b/sys/arm/conf/ETHERNUT5 index 9df7f9c55aa..88f9949059e 100644 --- a/sys/arm/conf/ETHERNUT5 +++ b/sys/arm/conf/ETHERNUT5 @@ -136,7 +136,6 @@ device ether # Ethernet support #device tun # Packet tunnel. #device md # Memory "disks" #device gif # IPv6 and IPv4 tunneling -#device faith # IPv6-to-IPv4 relaying (translation) #device firmware # firmware assist module # SCSI peripherals diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53 index 1396578e3e5..5fd56979fbf 100644 --- a/sys/arm/conf/IMX53 +++ b/sys/arm/conf/IMX53 @@ -92,7 +92,6 @@ device ether # Ethernet support #device tun # Packet tunnel. device md # Memory "disks" #device gif # IPv6 and IPv4 tunneling -#device faith # IPv6-to-IPv4 relaying (translation) #device firmware # firmware assist module # Ethernet diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6 index 88a6462b617..007862bc6d1 100644 --- a/sys/arm/conf/IMX6 +++ b/sys/arm/conf/IMX6 @@ -75,7 +75,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" #device gif # IPv6 and IPv4 tunneling -#device faith # IPv6-to-IPv4 relaying (translation) #device firmware # firmware assist module device ether # Ethernet support device miibus # Required for ethernet diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK index 34b64afd234..c3cba33f8b7 100644 --- a/sys/arm/conf/SAM9260EK +++ b/sys/arm/conf/SAM9260EK @@ -146,7 +146,6 @@ device ether # Ethernet support #device tun # Packet tunnel. #device md # Memory "disks" #device gif # IPv6 and IPv4 tunneling -#device faith # IPv6-to-IPv4 relaying (translation) #device firmware # firmware assist module # SCSI peripherals diff --git a/sys/arm/freescale/imx/imx_common.c b/sys/arm/freescale/imx/imx_common.c index d8fef824394..3b7139c9dd1 100644 --- a/sys/arm/freescale/imx/imx_common.c +++ b/sys/arm/freescale/imx/imx_common.c @@ -33,8 +33,6 @@ * SUCH DAMAGE. */ -#include "opt_global.h" - #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c index b3654894321..c23f75be3f7 100644 --- a/sys/arm/freescale/imx/imx_gpio.c +++ b/sys/arm/freescale/imx/imx_gpio.c @@ -268,18 +268,8 @@ imx51_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - imx51_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); - return (0); } diff --git a/sys/arm/freescale/imx/imx_i2c.c b/sys/arm/freescale/imx/imx_i2c.c index 3c192ead291..abcb01474dc 100644 --- a/sys/arm/freescale/imx/imx_i2c.c +++ b/sys/arm/freescale/imx/imx_i2c.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -45,6 +46,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include #include #include "iicbus_if.h" @@ -79,6 +82,32 @@ __FBSDID("$FreeBSD$"); #define I2C_BAUD_RATE_DEF 0x3F #define I2C_DFSSR_DIV 0x10 +/* + * A table of available divisors and the associated coded values to put in the + * FDR register to achieve that divisor.. There is no algorithmic relationship I + * can see between divisors and the codes that go into the register. The table + * begins and ends with entries that handle insane configuration values. + */ +struct clkdiv { + u_int divisor; + u_int regcode; +}; +static struct clkdiv clkdiv_table[] = { + { 0, 0x20 }, { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, + { 28, 0x23 }, { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, + { 40, 0x26 }, { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, + { 52, 0x05 }, { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2a }, + { 72, 0x2b }, { 80, 0x2c }, { 88, 0x09 }, { 96, 0x2d }, + { 104, 0x0a }, { 112, 0x2e }, { 128, 0x2f }, { 144, 0x0c }, + { 160, 0x30 }, { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0f }, + { 256, 0x33 }, { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, + { 448, 0x36 }, { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, + { 640, 0x38 }, { 768, 0x39 }, { 896, 0x3a }, { 960, 0x17 }, + { 1024, 0x3b }, { 1152, 0x18 }, { 1280, 0x3c }, { 1536, 0x3d }, + { 1792, 0x3e }, { 1920, 0x1b }, { 2048, 0x3f }, { 2304, 0x1c }, + { 2560, 0x1d }, { 3072, 0x1e }, { 3840, 0x1f }, {UINT_MAX, 0x1f} +}; + #ifdef DEBUG #define debugf(fmt, args...) do { printf("%s(): ", __func__); \ printf(fmt,##args); } while (0) @@ -390,28 +419,29 @@ static int i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr) { struct i2c_softc *sc; - uint8_t baud_rate; + u_int busfreq, div, i, ipgfreq; sc = device_get_softc(dev); - switch (speed) { - case IIC_FAST: - baud_rate = I2C_BAUD_RATE_FAST; - break; - case IIC_SLOW: - case IIC_UNKNOWN: - case IIC_FASTEST: - default: - baud_rate = I2C_BAUD_RATE_DEF; - break; + /* + * Look up the divisor that gives the nearest speed that doesn't exceed + * the configured value for the bus. + */ + ipgfreq = imx_ccm_ipg_hz(); + busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed); + div = (ipgfreq + busfreq - 1) / busfreq; + for (i = 0; i < nitems(clkdiv_table); i++) { + if (clkdiv_table[i].divisor >= div) + break; } + div = clkdiv_table[i].regcode; mtx_lock(&sc->mutex); i2c_write_reg(sc, I2C_CONTROL_REG, 0x0); i2c_write_reg(sc, I2C_STATUS_REG, 0x0); DELAY(1000); - i2c_write_reg(sc, I2C_FDR_REG, 20); + i2c_write_reg(sc, I2C_FDR_REG, (uint8_t)div); i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN); DELAY(1000); i2c_write_reg(sc, I2C_STATUS_REG, 0x0); diff --git a/sys/arm/freescale/imx/imx_iomux.c b/sys/arm/freescale/imx/imx_iomux.c index e5d5085bf0e..7786b76e0a4 100644 --- a/sys/arm/freescale/imx/imx_iomux.c +++ b/sys/arm/freescale/imx/imx_iomux.c @@ -99,6 +99,10 @@ struct pincfg { uint32_t padconf_val; }; +#define PADCONF_NONE (1U << 31) /* Do not configure pad. */ +#define PADCONF_SION (1U << 30) /* Force SION bit in mux register. */ +#define PADMUX_SION (1U << 4) /* The SION bit in the mux register. */ + static inline uint32_t RD4(struct iomux_softc *sc, bus_size_t off) { @@ -120,6 +124,7 @@ iomux_configure_pins(device_t dev, phandle_t cfgxref) struct pincfg *cfgtuples, *cfg; phandle_t cfgnode; int i, ntuples; + uint32_t sion; sc = device_get_softc(dev); cfgnode = OF_node_from_xref(cfgxref); @@ -130,9 +135,22 @@ iomux_configure_pins(device_t dev, phandle_t cfgxref) if (ntuples == 0) return (0); /* Empty property is not an error. */ for (i = 0, cfg = cfgtuples; i < ntuples; i++, cfg++) { - WR4(sc, cfg->mux_reg, cfg->mux_val); - WR4(sc, cfg->input_reg, cfg->input_val); - WR4(sc, cfg->padconf_reg, cfg->padconf_val); + sion = (cfg->padconf_val & PADCONF_SION) ? PADMUX_SION : 0; + WR4(sc, cfg->mux_reg, cfg->mux_val | sion); + if (cfg->input_reg != 0) + WR4(sc, cfg->input_reg, cfg->input_val); + if ((cfg->padconf_val & PADCONF_NONE) == 0) + WR4(sc, cfg->padconf_reg, cfg->padconf_val); + if (bootverbose) { + char name[32]; + OF_getprop(cfgnode, "name", &name, sizeof(name)); + printf("%16s: muxreg 0x%04x muxval 0x%02x " + "inpreg 0x%04x inpval 0x%02x " + "padreg 0x%04x padval 0x%08x\n", + name, cfg->mux_reg, cfg->mux_val | sion, + cfg->input_reg, cfg->input_val, + cfg->padconf_reg, cfg->padconf_val); + } } free(cfgtuples, M_OFWPROP); return (0); diff --git a/sys/arm/freescale/vybrid/vf_gpio.c b/sys/arm/freescale/vybrid/vf_gpio.c index b83a877c56b..a31ff782aac 100644 --- a/sys/arm/freescale/vybrid/vf_gpio.c +++ b/sys/arm/freescale/vybrid/vf_gpio.c @@ -312,15 +312,6 @@ vf_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - vf_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); return (0); diff --git a/sys/arm/include/asmacros.h b/sys/arm/include/asmacros.h index 0767e732495..d7f804fa26d 100644 --- a/sys/arm/include/asmacros.h +++ b/sys/arm/include/asmacros.h @@ -34,7 +34,6 @@ #ifdef _KERNEL #ifdef LOCORE -#include "opt_global.h" #ifdef _ARM_ARCH_6 #define GET_CURTHREAD_PTR(tmp) \ diff --git a/sys/arm/mv/mv_common.c b/sys/arm/mv/mv_common.c index 44c22cb2089..d62efc4ca2f 100644 --- a/sys/arm/mv/mv_common.c +++ b/sys/arm/mv/mv_common.c @@ -29,8 +29,6 @@ * SUCH DAMAGE. */ -#include "opt_global.h" - #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/rockchip/rk30xx_gpio.c b/sys/arm/rockchip/rk30xx_gpio.c index fc24947c656..5c7dc992be0 100644 --- a/sys/arm/rockchip/rk30xx_gpio.c +++ b/sys/arm/rockchip/rk30xx_gpio.c @@ -318,20 +318,6 @@ rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->sc_gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->sc_gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together. */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - - /* Can't mix pull-up/pull-down together. */ - if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) == - (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) - return (EINVAL); - rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); return (0); diff --git a/sys/arm/samsung/exynos/exynos5_pad.c b/sys/arm/samsung/exynos/exynos5_pad.c index d00eddca558..c28ebb1c68e 100644 --- a/sys/arm/samsung/exynos/exynos5_pad.c +++ b/sys/arm/samsung/exynos/exynos5_pad.c @@ -764,15 +764,6 @@ pad_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - pad_pin_configure(sc, &sc->gpio_pins[i], flags); return (0); diff --git a/sys/arm/ti/ti_common.c b/sys/arm/ti/ti_common.c index 983e6f80761..5fb72b7a390 100644 --- a/sys/arm/ti/ti_common.c +++ b/sys/arm/ti/ti_common.c @@ -29,8 +29,6 @@ * SUCH DAMAGE. */ -#include "opt_global.h" - #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c index eb0c880214d..612ceb9a947 100644 --- a/sys/arm/ti/ti_gpio.c +++ b/sys/arm/ti/ti_gpio.c @@ -462,16 +462,6 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) uint32_t mask = (1UL << (pin % PINS_PER_BANK)); uint32_t reg_val; - /* Sanity check the flags supplied are valid, i.e. not input and output */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == 0x0000) - return (EINVAL); - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) == - (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) - return (EINVAL); - TI_GPIO_LOCK(sc); /* Sanity check the pin number is valid */ diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c index b479ee55224..8f9af0c7a05 100644 --- a/sys/arm/ti/ti_i2c.c +++ b/sys/arm/ti/ti_i2c.c @@ -102,8 +102,7 @@ struct ti_i2c_softc struct ti_i2c_clock_config { - int speed; - int bitrate; + u_int frequency; /* Bus frequency in Hz */ uint8_t psc; /* Fast/Standard mode prescale divider */ uint8_t scll; /* Fast/Standard mode SCL low time */ uint8_t sclh; /* Fast/Standard mode SCL high time */ @@ -112,27 +111,30 @@ struct ti_i2c_clock_config }; #if defined(SOC_OMAP4) +/* + * OMAP4 i2c bus clock is 96MHz / ((psc + 1) * (scll + 7 + sclh + 5)). + * The prescaler values for 100KHz and 400KHz modes come from the table in the + * OMAP4 TRM. The table doesn't list 1MHz; these values should give that speed. + */ static struct ti_i2c_clock_config ti_omap4_i2c_clock_configs[] = { - { IIC_UNKNOWN, 100000, 23, 13, 15, 0, 0}, - { IIC_SLOW, 100000, 23, 13, 15, 0, 0}, - { IIC_FAST, 400000, 9, 5, 7, 0, 0}, - { IIC_FASTEST, 1000000, 5, 3, 4, 0, 0}, - /* { IIC_FASTEST, 3200000, 1, 113, 115, 7, 10}, - HS mode */ - { -1, 0 } + { 100000, 23, 13, 15, 0, 0}, + { 400000, 9, 5, 7, 0, 0}, + { 1000000, 5, 1, 3, 0, 0}, +/* { 3200000, 1, 113, 115, 7, 10}, - HS mode */ + { 0 /* Table terminator */ } }; #endif #if defined(SOC_TI_AM335X) /* - * AM335X doesn't support HS mode. For 100kHz I2C clock set the internal - * clock to 12Mhz, for 400kHz I2C clock set the internal clock to 24Mhz. + * AM335x i2c bus clock is 48MHZ / ((psc + 1) * (scll + 7 + sclh + 5)) + * In all cases we prescale the clock to 24MHz as recommended in the manual. */ static struct ti_i2c_clock_config ti_am335x_i2c_clock_configs[] = { - { IIC_UNKNOWN, 100000, 7, 59, 61, 0, 0}, - { IIC_SLOW, 100000, 7, 59, 61, 0, 0}, - { IIC_FAST, 400000, 3, 23, 25, 0, 0}, - { IIC_FASTEST, 400000, 3, 23, 25, 0, 0}, - { -1, 0 } + { 100000, 1, 111, 117, 0, 0}, + { 400000, 1, 23, 25, 0, 0}, + { 1000000, 1, 5, 7, 0, 0}, + { 0 /* Table terminator */ } }; #endif @@ -508,6 +510,7 @@ ti_i2c_reset(struct ti_i2c_softc *sc, u_char speed) { int timeout; struct ti_i2c_clock_config *clkcfg; + u_int busfreq; uint16_t fifo_trsh, reg, scll, sclh; switch (ti_chip()) { @@ -524,13 +527,24 @@ ti_i2c_reset(struct ti_i2c_softc *sc, u_char speed) default: panic("Unknown Ti SoC, unable to reset the i2c"); } - while (clkcfg->speed != -1) { - if (clkcfg->speed == speed) + + /* + * If we haven't attached the bus yet, just init at the default slow + * speed. This lets us get the hardware initialized enough to attach + * the bus which is where the real speed configuration is handled. After + * the bus is attached, get the configured speed from it. Search the + * configuration table for the best speed we can do that doesn't exceed + * the requested speed. + */ + if (sc->sc_iicbus == NULL) + busfreq = 100000; + else + busfreq = IICBUS_GET_FREQUENCY(sc->sc_iicbus, speed); + for (;;) { + if (clkcfg[1].frequency == 0 || clkcfg[1].frequency > busfreq) break; clkcfg++; } - if (clkcfg->speed == -1) - return (EINVAL); /* * 23.1.4.3 - HS I2C Software Reset diff --git a/sys/arm/versatile/versatile_common.c b/sys/arm/versatile/versatile_common.c index 766db9deacc..7a9e42f4f07 100644 --- a/sys/arm/versatile/versatile_common.c +++ b/sys/arm/versatile/versatile_common.c @@ -29,8 +29,6 @@ * SUCH DAMAGE. */ -#include "opt_global.h" - #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/versatile/versatile_machdep.c b/sys/arm/versatile/versatile_machdep.c index ef531e142e5..2869f1b5d66 100644 --- a/sys/arm/versatile/versatile_machdep.c +++ b/sys/arm/versatile/versatile_machdep.c @@ -35,7 +35,6 @@ #include "opt_ddb.h" #include "opt_platform.h" -#include "opt_global.h" #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/xilinx/uart_dev_cdnc.c b/sys/arm/xilinx/uart_dev_cdnc.c index 6224503f754..526c5465f19 100644 --- a/sys/arm/xilinx/uart_dev_cdnc.c +++ b/sys/arm/xilinx/uart_dev_cdnc.c @@ -38,8 +38,6 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_global.h" - #include #include #include diff --git a/sys/arm/xilinx/zy7_machdep.c b/sys/arm/xilinx/zy7_machdep.c index 5fb5788028c..f7080dc93d6 100644 --- a/sys/arm/xilinx/zy7_machdep.c +++ b/sys/arm/xilinx/zy7_machdep.c @@ -33,8 +33,6 @@ * (v1.4) November 16, 2012. Xilinx doc UG585. */ -#include "opt_global.h" - #include __FBSDID("$FreeBSD$"); diff --git a/sys/arm/xscale/ixp425/avila_gpio.c b/sys/arm/xscale/ixp425/avila_gpio.c index 48f970d7f4b..4a2d1e94ff4 100644 --- a/sys/arm/xscale/ixp425/avila_gpio.c +++ b/sys/arm/xscale/ixp425/avila_gpio.c @@ -220,16 +220,8 @@ avila_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (pin >= IXP4XX_GPIO_PINS || !(sc->sc_valid & mask)) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->sc_pins[pin].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - avila_gpio_pin_configure(sc, &sc->sc_pins[pin], flags); + return (0); } diff --git a/sys/arm/xscale/ixp425/cambria_gpio.c b/sys/arm/xscale/ixp425/cambria_gpio.c index baa34838f84..7a773db6563 100644 --- a/sys/arm/xscale/ixp425/cambria_gpio.c +++ b/sys/arm/xscale/ixp425/cambria_gpio.c @@ -317,15 +317,6 @@ cambria_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (pin >= GPIO_PINS) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->sc_pins[pin].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - GPIO_LOCK(sc); sc->sc_pins[pin].gp_flags = flags; diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c index 04a7dbe0c34..62ae7471420 100644 --- a/sys/boot/common/load_elf.c +++ b/sys/boot/common/load_elf.c @@ -640,6 +640,14 @@ struct mod_metadata64 { u_int64_t md_cval; /* common string label */ }; #endif +#if defined(__amd64__) && __ELF_WORD_SIZE == 32 +struct mod_metadata32 { + int md_version; /* structure version MDTV_* */ + int md_type; /* type of entry MDT_* */ + u_int32_t md_data; /* specific data */ + u_int32_t md_cval; /* common string label */ +}; +#endif int __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef) @@ -647,6 +655,8 @@ __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef) struct mod_metadata md; #if (defined(__i386__) || defined(__powerpc__)) && __ELF_WORD_SIZE == 64 struct mod_metadata64 md64; +#elif defined(__amd64__) && __ELF_WORD_SIZE == 32 + struct mod_metadata32 md32; #endif struct mod_depend *mdepend; struct mod_version mver; @@ -682,6 +692,18 @@ __elfN(parse_modmetadata)(struct preloaded_file *fp, elf_file_t ef) md.md_type = md64.md_type; md.md_cval = (const char *)(uintptr_t)md64.md_cval; md.md_data = (void *)(uintptr_t)md64.md_data; +#elif defined(__amd64__) && __ELF_WORD_SIZE == 32 + COPYOUT(v, &md32, sizeof(md32)); + error = __elfN(reloc_ptr)(fp, ef, v, &md32, sizeof(md32)); + if (error == EOPNOTSUPP) { + md32.md_cval += ef->off; + md32.md_data += ef->off; + } else if (error != 0) + return (error); + md.md_version = md32.md_version; + md.md_type = md32.md_type; + md.md_cval = (const char *)(uintptr_t)md32.md_cval; + md.md_data = (void *)(uintptr_t)md32.md_data; #else COPYOUT(v, &md, sizeof(md)); error = __elfN(reloc_ptr)(fp, ef, v, &md, sizeof(md)); diff --git a/sys/boot/efi/include/efiapi.h b/sys/boot/efi/include/efiapi.h index b955338296b..623346d6016 100644 --- a/sys/boot/efi/include/efiapi.h +++ b/sys/boot/efi/include/efiapi.h @@ -842,6 +842,8 @@ typedef struct { #define SAL_SYSTEM_TABLE_GUID \ { 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } +#define FDT_TABLE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } typedef struct _EFI_CONFIGURATION_TABLE { EFI_GUID VendorGuid; diff --git a/sys/boot/ficl/amd64/sysdep.c b/sys/boot/ficl/amd64/sysdep.c index 00b0d4acf0e..ad38660843c 100644 --- a/sys/boot/ficl/amd64/sysdep.c +++ b/sys/boot/ficl/amd64/sysdep.c @@ -97,5 +97,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/ficl/arm/sysdep.c b/sys/boot/ficl/arm/sysdep.c index 00b0d4acf0e..ad38660843c 100644 --- a/sys/boot/ficl/arm/sysdep.c +++ b/sys/boot/ficl/arm/sysdep.c @@ -97,5 +97,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/ficl/i386/sysdep.c b/sys/boot/ficl/i386/sysdep.c index 2a5346aa7b4..39c853b4ec6 100644 --- a/sys/boot/ficl/i386/sysdep.c +++ b/sys/boot/ficl/i386/sysdep.c @@ -133,5 +133,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/ficl/mips/sysdep.c b/sys/boot/ficl/mips/sysdep.c index 00b0d4acf0e..ad38660843c 100644 --- a/sys/boot/ficl/mips/sysdep.c +++ b/sys/boot/ficl/mips/sysdep.c @@ -97,5 +97,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/ficl/mips64/sysdep.c b/sys/boot/ficl/mips64/sysdep.c index 00b0d4acf0e..ad38660843c 100644 --- a/sys/boot/ficl/mips64/sysdep.c +++ b/sys/boot/ficl/mips64/sysdep.c @@ -97,5 +97,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/ficl/powerpc/sysdep.c b/sys/boot/ficl/powerpc/sysdep.c index 00b0d4acf0e..ad38660843c 100644 --- a/sys/boot/ficl/powerpc/sysdep.c +++ b/sys/boot/ficl/powerpc/sysdep.c @@ -97,5 +97,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/ficl/sparc64/sysdep.c b/sys/boot/ficl/sparc64/sysdep.c index 00b0d4acf0e..ad38660843c 100644 --- a/sys/boot/ficl/sparc64/sysdep.c +++ b/sys/boot/ficl/sparc64/sysdep.c @@ -97,5 +97,3 @@ int ficlLockDictionary(short fLock) return 0; } #endif /* FICL_MULTITHREAD */ - - diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 241b14aaf97..bd7d296e984 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -254,7 +254,6 @@ if_disc_load="NO" # Discard device if_ef_load="NO" # pseudo-device providing support for multiple # ethernet frame types if_epair_load="NO" # Virtual b-t-b Ethernet-like interface pair -if_faith_load="NO" # IPv6-to-IPv4 TCP relay capturing interface if_gif_load="NO" # generic tunnel interface if_gre_load="NO" # encapsulating network device if_stf_load="NO" # 6to4 tunnel interface diff --git a/sys/boot/i386/loader/conf.c b/sys/boot/i386/loader/conf.c index ac19751bd7e..fda6fd25a07 100644 --- a/sys/boot/i386/loader/conf.c +++ b/sys/boot/i386/loader/conf.c @@ -80,8 +80,11 @@ struct fs_ops *file_system[] = { #if defined(LOADER_NANDFS_SUPPORT) &nandfs_fsops, #endif -#ifdef LOADER_SPLIT_SUPPORT - &splitfs_fsops, +#ifdef LOADER_NFS_SUPPORT + &nfs_fsops, +#endif +#ifdef LOADER_TFTP_SUPPORT + &tftp_fsops, #endif #ifdef LOADER_GZIP_SUPPORT &gzipfs_fsops, @@ -89,11 +92,8 @@ struct fs_ops *file_system[] = { #ifdef LOADER_BZIP2_SUPPORT &bzipfs_fsops, #endif -#ifdef LOADER_NFS_SUPPORT - &nfs_fsops, -#endif -#ifdef LOADER_TFTP_SUPPORT - &tftp_fsops, +#ifdef LOADER_SPLIT_SUPPORT + &splitfs_fsops, #endif NULL }; diff --git a/sys/boot/pc98/loader/conf.c b/sys/boot/pc98/loader/conf.c index ce80cefd1aa..d05cd13f9b2 100644 --- a/sys/boot/pc98/loader/conf.c +++ b/sys/boot/pc98/loader/conf.c @@ -61,19 +61,19 @@ struct fs_ops *file_system[] = { &ext2fs_fsops, &dosfs_fsops, &cd9660_fsops, - &splitfs_fsops, -#ifdef LOADER_GZIP_SUPPORT - &gzipfs_fsops, -#endif -#ifdef LOADER_BZIP2_SUPPORT - &bzipfs_fsops, -#endif #ifdef LOADER_NFS_SUPPORT &nfs_fsops, #endif #ifdef LOADER_TFTP_SUPPORT &tftp_fsops, #endif +#ifdef LOADER_GZIP_SUPPORT + &gzipfs_fsops, +#endif +#ifdef LOADER_BZIP2_SUPPORT + &bzipfs_fsops, +#endif + &splitfs_fsops, NULL }; diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index 16b57c7a615..8d21c571430 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -57,6 +57,7 @@ static const char *features_for_read[] = { "com.delphix:hole_birth", "com.delphix:extensible_dataset", "com.delphix:embedded_data", + "org.open-zfs:large_blocks", NULL }; @@ -1222,6 +1223,11 @@ dnode_read(const spa_t *spa, const dnode_phys_t *dnode, off_t offset, void *buf, int nlevels = dnode->dn_nlevels; int i, rc; + if (bsize > SPA_MAXBLOCKSIZE) { + printf("ZFS: I/O error - blocks larger than 128K are not supported\n"); + return (EIO); + } + /* * Note: bsize may not be a power of two here so we need to do an * actual divide rather than a bitshift. diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index b50caad470c..cd0111416b9 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -8914,7 +8914,8 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio) } break; - case SPRO_PREEMPT: { + case SPRO_PREEMPT: + case SPRO_PRE_ABO: { int nretval; nretval = ctl_pro_preempt(softc, lun, res_key, sa_res_key, type, diff --git a/sys/cam/ctl/ctl_cmd_table.c b/sys/cam/ctl/ctl_cmd_table.c index 0180cecff26..fedc11001e9 100644 --- a/sys/cam/ctl/ctl_cmd_table.c +++ b/sys/cam/ctl/ctl_cmd_table.c @@ -180,7 +180,16 @@ const struct ctl_cmd_entry ctl_cmd_table_5f[32] = 10, { 0x04, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0x07}}, /* 05 PREEMPT AND ABORT */ -{NULL, CTL_SERIDX_INVLD, CTL_CMD_FLAG_NONE, CTL_LUN_PAT_NONE}, +{ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | + CTL_CMD_FLAG_OK_ON_BOTH | + CTL_CMD_FLAG_OK_ON_STOPPED | + CTL_CMD_FLAG_OK_ON_INOPERABLE | + CTL_CMD_FLAG_OK_ON_OFFLINE | + CTL_CMD_FLAG_OK_ON_SECONDARY | + CTL_FLAG_DATA_OUT | + CTL_CMD_FLAG_ALLOW_ON_PR_RESV, + CTL_LUN_PAT_NONE, + 10, { 0x05, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0x07}}, /* 06 REGISTER AND IGNORE EXISTING KEY */ {ctl_persistent_reserve_out, CTL_SERIDX_RES, CTL_CMD_FLAG_ALLOW_ON_RESV | diff --git a/sys/cam/ctl/ctl_frontend_iscsi.c b/sys/cam/ctl/ctl_frontend_iscsi.c index 297b6c5b7ef..408b86a21fc 100644 --- a/sys/cam/ctl/ctl_frontend_iscsi.c +++ b/sys/cam/ctl/ctl_frontend_iscsi.c @@ -1982,7 +1982,7 @@ cfiscsi_ioctl_port_create(struct ctl_req *req) if (ct->ct_state == CFISCSI_TARGET_STATE_ACTIVE) { req->status = CTL_LUN_ERROR; snprintf(req->error_str, sizeof(req->error_str), - "target \"%s\" already exist", target); + "target \"%s\" already exists", target); cfiscsi_target_release(ct); ctl_free_opts(&opts); return; diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index 959eda9125a..abe7e2ed167 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -1106,13 +1106,13 @@ static struct asc_table_entry asc_table[] = { { SST(0x04, 0x09, SS_RDEF, /* XXX TBD */ "Logical unit not ready, self-test in progress") }, /* DTLPWROMAEBKVF */ - { SST(0x04, 0x0A, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x0A, SS_TUR | SSQ_MANY | SSQ_DECREMENT_COUNT | ENXIO, "Logical unit not accessible, asymmetric access state transition")}, /* DTLPWROMAEBKVF */ - { SST(0x04, 0x0B, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x0B, SS_FATAL | ENXIO, "Logical unit not accessible, target port in standby state") }, /* DTLPWROMAEBKVF */ - { SST(0x04, 0x0C, SS_RDEF, /* XXX TBD */ + { SST(0x04, 0x0C, SS_FATAL | ENXIO, "Logical unit not accessible, target port in unavailable state") }, /* F */ { SST(0x04, 0x0D, SS_RDEF, /* XXX TBD */ diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index ea0cfae2c55..6ee03705c75 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -1817,7 +1817,7 @@ struct scsi_inquiry_data * reserved for this peripheral * qualifier. */ -#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x08) != 0) +#define SID_QUAL_IS_VENDOR_UNIQUE(inq_data) ((SID_QUAL(inq_data) & 0x04) != 0) u_int8_t dev_qual2; #define SID_QUAL2 0x7F #define SID_LU_CONG 0x40 diff --git a/sys/cam/scsi/scsi_low.c b/sys/cam/scsi/scsi_low.c index 8ca669e015e..0c91e515b27 100644 --- a/sys/cam/scsi/scsi_low.c +++ b/sys/cam/scsi/scsi_low.c @@ -150,6 +150,8 @@ int scsi_low_version_major = 2; int scsi_low_version_minor = 17; static struct scsi_low_softc_tab sl_tab = LIST_HEAD_INITIALIZER(sl_tab); +static struct mtx sl_tab_lock; +MTX_SYSINIT(sl_tab_lock, &sl_tab_lock, "scsi low table", MTX_DEF); /************************************************************** * Debug, Run test and Statics @@ -365,21 +367,10 @@ static void scsi_low_poll_cam(struct cam_sim *); void scsi_low_scsi_action_cam(struct cam_sim *, union ccb *); static int scsi_low_attach_cam(struct scsi_low_softc *); -static int scsi_low_world_start_cam(struct scsi_low_softc *); -static int scsi_low_dettach_cam(struct scsi_low_softc *); +static int scsi_low_detach_cam(struct scsi_low_softc *); static int scsi_low_ccb_setup_cam(struct scsi_low_softc *, struct slccb *); static int scsi_low_done_cam(struct scsi_low_softc *, struct slccb *); -static void scsi_low_timeout_cam(struct scsi_low_softc *, int, int); -struct scsi_low_osdep_funcs scsi_low_osdep_funcs_cam = { - scsi_low_attach_cam, - scsi_low_world_start_cam, - scsi_low_dettach_cam, - scsi_low_ccb_setup_cam, - scsi_low_done_cam, - scsi_low_timeout_cam -}; - struct scsi_low_error_code scsi_low_error_code_cam[] = { {0, CAM_REQ_CMP}, {SENSEIO, CAM_AUTOSNS_VALID | CAM_REQ_CMP_ERR}, @@ -409,12 +400,13 @@ scsi_low_poll_cam(sim) { struct scsi_low_softc *slp = SIM2SLP(sim); + SCSI_LOW_ASSERT_LOCKED(slp); (*slp->sl_funcs->scsi_low_poll) (slp); - if (slp->sl_si.si_poll_count ++ >= + if (slp->sl_poll_count ++ >= SCSI_LOW_CAM_POLL_HZ / SCSI_LOW_TIMEOUT_HZ) { - slp->sl_si.si_poll_count = 0; + slp->sl_poll_count = 0; scsi_low_timeout_check(slp); } } @@ -429,8 +421,9 @@ scsi_low_scsi_action_cam(sim, ccb) struct lun_info *li; struct slccb *cb; u_int lun, flags, msg, target; - int s, rv; + int rv; + SCSI_LOW_ASSERT_LOCKED(slp); target = (u_int) (ccb->ccb_h.target_id); lun = (u_int) ccb->ccb_h.target_lun; @@ -469,7 +462,6 @@ scsi_low_scsi_action_cam(sim, ccb) else flags = CCB_SCSIIO; - s = splcam(); li = scsi_low_alloc_li(ti, lun, 1); if (ti->ti_setup_msg != 0) @@ -485,7 +477,6 @@ scsi_low_scsi_action_cam(sim, ccb) scsi_low_test_abort(slp, ti, li); } #endif /* SCSI_LOW_DEBUG */ - splx(s); break; case XPT_EN_LUN: /* Enable LUN as a target */ @@ -508,10 +499,8 @@ scsi_low_scsi_action_cam(sim, ccb) } #endif /* SCSI_LOW_DIAGNOSTIC */ - s = splcam(); cb = scsi_low_find_ccb(slp, target, lun, ccb->cab.abort_ccb); rv = scsi_low_abort_ccb(slp, cb); - splx(s); if (rv == 0) ccb->ccb_h.status = CAM_REQ_CMP; @@ -540,7 +529,6 @@ scsi_low_scsi_action_cam(sim, ccb) if (lun == CAM_LUN_WILDCARD) lun = 0; - s = splcam(); scsi = &cts->proto_specific.scsi; spi = &cts->xport_specific.spi; if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH | @@ -587,7 +575,6 @@ scsi_low_scsi_action_cam(sim, ccb) if ((slp->sl_show_result & SHOW_CALCF_RES) != 0) scsi_low_calcf_show(li); } - splx(s); ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -612,7 +599,6 @@ scsi_low_scsi_action_cam(sim, ccb) if (lun == CAM_LUN_WILDCARD) lun = 0; - s = splcam(); li = scsi_low_alloc_li(ti, lun, 1); if (li != NULL && cts->type == CTS_TYPE_CURRENT_SETTINGS) { struct ccb_trans_settings_scsi *scsi = @@ -658,7 +644,6 @@ scsi_low_scsi_action_cam(sim, ccb) } else ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; settings_out: - splx(s); xpt_done(ccb); break; } @@ -670,9 +655,7 @@ settings_out: } case XPT_RESET_BUS: /* Reset the specified SCSI bus */ - s = splcam(); scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL); - splx(s); ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -711,10 +694,8 @@ settings_out: else flags = CCB_NORETRY | CCB_URGENT; - s = splcam(); li = scsi_low_alloc_li(ti, lun, 1); scsi_low_enqueue(slp, ti, li, cb, flags, msg); - splx(s); break; case XPT_PATH_INQ: { /* Path routing inquiry */ @@ -774,51 +755,47 @@ scsi_low_attach_cam(slp) * ask the adapter what subunits are present */ tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS); - slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam, + slp->sl_sim = cam_sim_alloc(scsi_low_scsi_action_cam, scsi_low_poll_cam, device_get_name(slp->sl_dev), slp, - device_get_unit(slp->sl_dev), &Giant, + device_get_unit(slp->sl_dev), &slp->sl_lock, slp->sl_openings, tagged_openings, devq); - if (slp->sl_si.sim == NULL) { + if (slp->sl_sim == NULL) { cam_simq_free(devq); return ENODEV; } - if (xpt_bus_register(slp->sl_si.sim, NULL, 0) != CAM_SUCCESS) { - free(slp->sl_si.sim, M_SCSILOW); + SCSI_LOW_LOCK(slp); + if (xpt_bus_register(slp->sl_sim, slp->sl_dev, 0) != CAM_SUCCESS) { + cam_sim_free(slp->sl_sim, TRUE); + SCSI_LOW_UNLOCK(slp); return ENODEV; } - if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL, - cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD, + if (xpt_create_path(&slp->sl_path, /*periph*/NULL, + cam_sim_path(slp->sl_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); - cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE); + xpt_bus_deregister(cam_sim_path(slp->sl_sim)); + cam_sim_free(slp->sl_sim, /*free_simq*/TRUE); + SCSI_LOW_UNLOCK(slp); return ENODEV; } slp->sl_show_result = SHOW_CALCF_RES; /* OK ? */ + SCSI_LOW_UNLOCK(slp); return 0; } static int -scsi_low_world_start_cam(slp) +scsi_low_detach_cam(slp) struct scsi_low_softc *slp; { - return 0; -} - -static int -scsi_low_dettach_cam(slp) - struct scsi_low_softc *slp; -{ - - xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL); - xpt_free_path(slp->sl_si.path); - xpt_bus_deregister(cam_sim_path(slp->sl_si.sim)); - cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE); + xpt_async(AC_LOST_DEVICE, slp->sl_path, NULL); + xpt_free_path(slp->sl_path); + xpt_bus_deregister(cam_sim_path(slp->sl_sim)); + cam_sim_free(slp->sl_sim, /* free_devq */ TRUE); return 0; } @@ -906,48 +883,6 @@ scsi_low_done_cam(slp, cb) return 0; } -static void -scsi_low_timeout_cam(slp, ch, action) - struct scsi_low_softc *slp; - int ch; - int action; -{ - - switch (ch) - { - case SCSI_LOW_TIMEOUT_CH_IO: - switch (action) - { - case SCSI_LOW_TIMEOUT_START: - slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp, - hz / SCSI_LOW_TIMEOUT_HZ); - break; - case SCSI_LOW_TIMEOUT_STOP: - untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch); - break; - } - break; - - case SCSI_LOW_TIMEOUT_CH_ENGAGE: - switch (action) - { - case SCSI_LOW_TIMEOUT_START: - slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1); - break; - case SCSI_LOW_TIMEOUT_STOP: - untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch); - break; - } - break; - case SCSI_LOW_TIMEOUT_CH_RECOVER: - break; - } -} - -/*============================================================= - * END OF OS switch (All OS depend fucntions should be above) - =============================================================*/ - /************************************************************** * scsi low deactivate and activate **************************************************************/ @@ -965,15 +900,10 @@ int scsi_low_deactivate(slp) struct scsi_low_softc *slp; { - int s; - s = splcam(); slp->sl_flags |= HW_INACTIVE; - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); - splx(s); + callout_stop(&slp->sl_timeout_timer); + callout_stop(&slp->sl_engage_timer); return 0; } @@ -981,21 +911,18 @@ int scsi_low_activate(slp) struct scsi_low_softc *slp; { - int error, s; + int error; - s = splcam(); slp->sl_flags &= ~HW_INACTIVE; if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0) { slp->sl_flags |= HW_INACTIVE; - splx(s); return error; } slp->sl_timeout_count = 0; - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); - splx(s); + callout_reset(&slp->sl_timeout_timer, hz / SCSI_LOW_TIMEOUT_HZ, + scsi_low_timeout, slp); return 0; } @@ -1063,15 +990,15 @@ scsi_low_engage(arg) void *arg; { struct scsi_low_softc *slp = arg; - int s = splcam(); + SCSI_LOW_ASSERT_LOCKED(slp); switch (slp->sl_rstep) { case 0: slp->sl_rstep ++; (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, - SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START); + callout_reset(&slp->sl_engage_timer, hz / 1000, + scsi_low_engage, slp); break; case 1: @@ -1083,7 +1010,6 @@ scsi_low_engage(arg) case 2: break; } - splx(s); } static int @@ -1098,8 +1024,7 @@ scsi_low_init(slp, flags) /* clear power control timeout */ if ((slp->sl_flags & HW_POWERCTRL) != 0) { - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, - SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP); + callout_stop(&slp->sl_engage_timer); slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME); slp->sl_active = 1; slp->sl_powc = SCSI_LOW_POWDOWN_TC; @@ -1273,13 +1198,10 @@ scsi_low_timeout(arg) void *arg; { struct scsi_low_softc *slp = arg; - int s; - s = splcam(); + SCSI_LOW_ASSERT_LOCKED(slp); (void) scsi_low_timeout_check(slp); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); - splx(s); + callout_schedule(&slp->sl_timeout_timer, hz / SCSI_LOW_TIMEOUT_HZ); } static int @@ -1459,12 +1381,7 @@ scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) { struct targ_info *ti; struct lun_info *li; - int s, i, nccb, rv; - - slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam; - - if (slp->sl_osdep_fp == NULL) - panic("scsi_low: interface not spcified"); + int i, nccb, rv; if (ntargs > SCSI_LOW_NTARGETS) { @@ -1503,31 +1420,32 @@ scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) TAILQ_INIT(&slp->sl_start); /* call os depend attach */ - s = splcam(); - rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp); + rv = scsi_low_attach_cam(slp); if (rv != 0) { - splx(s); device_printf(slp->sl_dev, "scsi_low_attach: osdep attach failed\n"); - return EINVAL; + return (rv); } /* check hardware */ DELAY(1000); /* wait for 1ms */ + SCSI_LOW_LOCK(slp); if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0) { - splx(s); device_printf(slp->sl_dev, "scsi_low_attach: initialization failed\n"); + SCSI_LOW_UNLOCK(slp); return EINVAL; } /* start watch dog */ slp->sl_timeout_count = 0; - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START); + callout_reset(&slp->sl_timeout_timer, hz / SCSI_LOW_TIMEOUT_HZ, + scsi_low_timeout, slp); + mtx_lock(&sl_tab_lock); LIST_INSERT_HEAD(&sl_tab, slp, sl_chain); + mtx_unlock(&sl_tab_lock); /* fake call */ scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL)); @@ -1536,38 +1454,40 @@ scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize) /* probing devices */ scsi_low_start_up(slp); #endif /* SCSI_LOW_START_UP_CHECK */ + SCSI_LOW_UNLOCK(slp); - /* call os depend attach done*/ - (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp); - splx(s); return 0; } int -scsi_low_dettach(slp) +scsi_low_detach(slp) struct scsi_low_softc *slp; { - int s, rv; + int rv; - s = splcam(); + SCSI_LOW_LOCK(slp); if (scsi_low_is_busy(slp) != 0) { - splx(s); + SCSI_LOW_UNLOCK(slp); return EBUSY; } scsi_low_deactivate(slp); - rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp); + rv = scsi_low_detach_cam(slp); if (rv != 0) { - splx(s); + SCSI_LOW_UNLOCK(slp); return EBUSY; } scsi_low_free_ti(slp); + SCSI_LOW_UNLOCK(slp); + callout_drain(&slp->sl_timeout_timer); + callout_drain(&slp->sl_engage_timer); + mtx_lock(&sl_tab_lock); LIST_REMOVE(slp, sl_chain); - splx(s); + mtx_unlock(&sl_tab_lock); return 0; } @@ -1753,9 +1673,8 @@ scsi_low_resume(slp) slp->sl_flags |= HW_RESUME; slp->sl_rstep = 0; (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE); - (*slp->sl_osdep_fp->scsi_low_osdep_timeout) - (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, - SCSI_LOW_TIMEOUT_START); + callout_reset(&slp->sl_engage_timer, hz / 1000, + scsi_low_engage, slp); return EJUSTRETURN; } return 0; @@ -1839,7 +1758,7 @@ scsi_low_cmd_start: else if (li->li_state >= SCSI_LOW_LUN_OK) { cb->ccb_flags &= ~CCB_INTERNAL; - rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb); + rv = scsi_low_ccb_setup_cam(slp, cb); if (cb->ccb_msgoutflag != 0) { scsi_low_ccb_message_exec(slp, cb); @@ -2199,7 +2118,7 @@ scsi_low_done(slp, cb) /* call OS depend done */ if (cb->osdep != NULL) { - rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb); + rv = scsi_low_done_cam(slp, cb); if (rv == EJUSTRETURN) goto retry; } @@ -3140,7 +3059,7 @@ cmd_link_start: scsi_low_init_msgsys(slp, ti); - (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb); + scsi_low_ccb_setup_cam(slp, ncb); if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT) ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT; diff --git a/sys/cam/scsi/scsi_low.h b/sys/cam/scsi/scsi_low.h index 2cca8ae4f34..8d82eff6634 100644 --- a/sys/cam/scsi/scsi_low.h +++ b/sys/cam/scsi/scsi_low.h @@ -44,10 +44,6 @@ #ifndef _SCSI_LOW_H_ #define _SCSI_LOW_H_ -/*================================================ - * Scsi low OSDEP - * (All os depend structures should be here!) - ================================================*/ /******** includes *******************************/ #include @@ -65,51 +61,8 @@ #undef MSG_IDENTIFY -/******** os depend interface structures **********/ -typedef struct scsi_sense_data scsi_low_osdep_sense_data_t; - -struct scsi_low_osdep_interface { - device_t si_dev; - - struct cam_sim *sim; - struct cam_path *path; - - int si_poll_count; - - struct callout_handle engage_ch; - struct callout_handle timeout_ch; -#ifdef SCSI_LOW_POWFUNC - struct callout_handle recover_ch; -#endif -}; - -/******** os depend interface functions *************/ -struct slccb; -struct scsi_low_softc; -#define SCSI_LOW_TIMEOUT_STOP 0 -#define SCSI_LOW_TIMEOUT_START 1 -#define SCSI_LOW_TIMEOUT_CH_IO 0 -#define SCSI_LOW_TIMEOUT_CH_ENGAGE 1 -#define SCSI_LOW_TIMEOUT_CH_RECOVER 2 - -struct scsi_low_osdep_funcs { - int (*scsi_low_osdep_attach) \ - (struct scsi_low_softc *); - int (*scsi_low_osdep_world_start) \ - (struct scsi_low_softc *); - int (*scsi_low_osdep_dettach) \ - (struct scsi_low_softc *); - int (*scsi_low_osdep_ccb_setup) \ - (struct scsi_low_softc *, struct slccb *); - int (*scsi_low_osdep_done) \ - (struct scsi_low_softc *, struct slccb *); - void (*scsi_low_osdep_timeout) \ - (struct scsi_low_softc *, int, int); -}; - /*================================================ * Generic Scsi Low header file - * (All os depend structures should be above!) ================================================*/ /************************************************* * Scsi low definitions @@ -229,7 +182,7 @@ struct slccb { * Sense data buffer *****************************************/ u_int8_t ccb_scsi_cmd[12]; - scsi_low_osdep_sense_data_t ccb_sense; + struct scsi_sense_data ccb_sense; }; /************************************************* @@ -486,10 +439,19 @@ struct scsi_low_funcs { }; struct scsi_low_softc { - /* os depend structure */ - struct scsi_low_osdep_interface sl_si; -#define sl_dev sl_si.si_dev - struct scsi_low_osdep_funcs *sl_osdep_fp; + device_t sl_dev; + + struct cam_sim *sl_sim; + struct cam_path *sl_path; + + int sl_poll_count; + + struct mtx sl_lock; + struct callout sl_engage_timer; + struct callout sl_timeout_timer; +#ifdef SCSI_LOW_POWFUNC + struct callout sl_recover_timer; +#endif /* our chain */ LIST_ENTRY(scsi_low_softc) sl_chain; @@ -596,6 +558,10 @@ struct scsi_low_softc { int sl_targsize; }; +#define SCSI_LOW_LOCK(sl) mtx_lock(&(sl)->sl_lock) +#define SCSI_LOW_UNLOCK(sl) mtx_unlock(&(sl)->sl_lock) +#define SCSI_LOW_ASSERT_LOCKED(sl) mtx_assert(&(sl)->sl_lock, MA_OWNED) + /************************************************* * SCSI LOW service functions *************************************************/ @@ -603,7 +569,7 @@ struct scsi_low_softc { * Scsi low attachment function. */ int scsi_low_attach(struct scsi_low_softc *, int, int, int, int, int); -int scsi_low_dettach(struct scsi_low_softc *); +int scsi_low_detach(struct scsi_low_softc *); /* * Scsi low interface activate or deactivate functions diff --git a/sys/cam/scsi/scsi_xpt.c b/sys/cam/scsi/scsi_xpt.c index 5677cdde125..3c087455bce 100644 --- a/sys/cam/scsi/scsi_xpt.c +++ b/sys/cam/scsi/scsi_xpt.c @@ -2032,23 +2032,7 @@ scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb) scan_info->lunindex[target_id]++; } else { mtx_unlock(&target->luns_mtx); - /* - * We're done with scanning all luns. - * - * Nuke the bogus device for lun 0 if lun 0 - * wasn't on the list. - */ - if (first != 0) { - TAILQ_FOREACH(device, - &target->ed_entries, links) { - if (device->lun_id == 0) { - break; - } - } - if (device) { - xpt_release_device(device); - } - } + /* We're done with scanning all luns. */ } } else { mtx_unlock(&target->luns_mtx); diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h index 5f2e255e770..730cdf49a0d 100644 --- a/sys/cddl/boot/zfs/zfsimpl.h +++ b/sys/cddl/boot/zfs/zfsimpl.h @@ -113,17 +113,14 @@ #define BSWAP_64(x) ((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32)) /* - * We currently support nine block sizes, from 512 bytes to 128K. - * We could go higher, but the benefits are near-zero and the cost - * of COWing a giant block to modify one byte would become excessive. + * Note: the boot loader can't actually read blocks larger than 128KB, + * due to lack of memory. Therefore its SPA_MAXBLOCKSIZE is still 128KB. */ #define SPA_MINBLOCKSHIFT 9 #define SPA_MAXBLOCKSHIFT 17 #define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) #define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) -#define SPA_BLOCKSIZES (SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1) - /* * The DVA size encodings for LSIZE and PSIZE support blocks up to 32MB. * The ASIZE encoding should be at least 64 times larger (6 more bits) diff --git a/sys/cddl/compat/opensolaris/sys/vnode.h b/sys/cddl/compat/opensolaris/sys/vnode.h index 4e5b1c92f44..22256cf1f1e 100644 --- a/sys/cddl/compat/opensolaris/sys/vnode.h +++ b/sys/cddl/compat/opensolaris/sys/vnode.h @@ -282,7 +282,7 @@ vn_rename(char *from, char *to, enum uio_seg seg) ASSERT(seg == UIO_SYSSPACE); - return (kern_rename(curthread, from, to, seg)); + return (kern_renameat(curthread, AT_FDCWD, from, AT_FDCWD, to, seg)); } static __inline int @@ -292,7 +292,7 @@ vn_remove(char *fnamep, enum uio_seg seg, enum rm dirflag) ASSERT(seg == UIO_SYSSPACE); ASSERT(dirflag == RMFILE); - return (kern_unlink(curthread, fnamep, seg)); + return (kern_unlinkat(curthread, AT_FDCWD, fnamep, seg, 0)); } #endif /* _KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c index 65d285893e9..52a355d0a54 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.c @@ -56,7 +56,8 @@ valid_char(char c, boolean_t after_colon) { return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || - c == (after_colon ? '_' : '.')); + (after_colon && c == '_') || + (!after_colon && (c == '.' || c == '-'))); } /* @@ -220,4 +221,13 @@ zpool_feature_init(void) "com.delphix:embedded_data", "embedded_data", "Blocks which compress very well use even less space.", B_FALSE, B_TRUE, B_TRUE, NULL); + + static const spa_feature_t large_blocks_deps[] = { + SPA_FEATURE_EXTENSIBLE_DATASET, + SPA_FEATURE_NONE + }; + 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); } diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h index 65016f1b5e2..4ffe435ab68 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfeature_common.h @@ -50,6 +50,7 @@ typedef enum spa_feature { SPA_FEATURE_EMBEDDED_DATA, SPA_FEATURE_BOOKMARKS, SPA_FEATURE_FS_SS_LIMIT, + SPA_FEATURE_LARGE_BLOCKS, SPA_FEATURES } spa_feature_t; diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c index bd023c70ef4..dda72de8737 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c @@ -409,8 +409,8 @@ zfs_prop_init(void) /* inherit number properties */ zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize", - SPA_MAXBLOCKSIZE, PROP_INHERIT, - ZFS_TYPE_FILESYSTEM, "512 to 128k, power of 2", "RECSIZE"); + SPA_OLD_MAXBLOCKSIZE, PROP_INHERIT, + ZFS_TYPE_FILESYSTEM, "512 to 1M, power of 2", "RECSIZE"); /* hidden properties */ zprop_register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER, diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c index a400f821e2e..4d906b02bc0 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c @@ -127,6 +127,8 @@ zpool_prop_init(void) /* hidden properties */ zprop_register_hidden(ZPOOL_PROP_NAME, "name", PROP_TYPE_STRING, PROP_READONLY, ZFS_TYPE_POOL, "NAME"); + zprop_register_hidden(ZPOOL_PROP_MAXBLOCKSIZE, "maxblocksize", + PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_POOL, "MAXBLOCKSIZE"); } /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index b4ab0aff5a8..3a455d73899 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -5326,12 +5326,6 @@ l2arc_compress_buf(l2arc_buf_hdr_t *l2hdr) csize = zio_compress_data(ZIO_COMPRESS_LZ4, l2hdr->b_tmp_cdata, cdata, l2hdr->b_asize); - rounded = P2ROUNDUP(csize, (size_t)SPA_MINBLOCKSIZE); - if (rounded > csize) { - bzero((char *)cdata + csize, rounded - csize); - csize = rounded; - } - if (csize == 0) { /* zero block, indicate that there's nothing to write */ zio_data_buf_free(cdata, len); @@ -5340,11 +5334,19 @@ l2arc_compress_buf(l2arc_buf_hdr_t *l2hdr) l2hdr->b_tmp_cdata = NULL; ARCSTAT_BUMP(arcstat_l2_compress_zeros); return (B_TRUE); - } else if (csize > 0 && csize < len) { + } + + rounded = P2ROUNDUP(csize, + (size_t)1 << l2hdr->b_dev->l2ad_vdev->vdev_ashift); + if (rounded < len) { /* * Compression succeeded, we'll keep the cdata around for * writing and release it afterwards. */ + if (rounded > csize) { + bzero((char *)cdata + csize, rounded - csize); + csize = rounded; + } l2hdr->b_compress = ZIO_COMPRESS_LZ4; l2hdr->b_asize = csize; l2hdr->b_tmp_cdata = cdata; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c index b19df1af396..05c40e38a74 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c @@ -43,7 +43,7 @@ bpobj_alloc_empty(objset_t *os, int blocksize, dmu_tx_t *tx) if (!spa_feature_is_active(spa, SPA_FEATURE_EMPTY_BPOBJ)) { ASSERT0(dp->dp_empty_bpobj); dp->dp_empty_bpobj = - bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx); + bpobj_alloc(os, SPA_OLD_MAXBLOCKSIZE, tx); VERIFY(zap_add(os, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_EMPTY_BPOBJ, sizeof (uint64_t), 1, @@ -398,7 +398,8 @@ bpobj_enqueue_subobj(bpobj_t *bpo, uint64_t subobj, dmu_tx_t *tx) dmu_buf_will_dirty(bpo->bpo_dbuf, tx); if (bpo->bpo_phys->bpo_subobjs == 0) { bpo->bpo_phys->bpo_subobjs = dmu_object_alloc(bpo->bpo_os, - DMU_OT_BPOBJ_SUBOBJ, SPA_MAXBLOCKSIZE, DMU_OT_NONE, 0, tx); + DMU_OT_BPOBJ_SUBOBJ, SPA_OLD_MAXBLOCKSIZE, + DMU_OT_NONE, 0, tx); } dmu_object_info_t doi; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c index c724ed07410..5f7d76f0e2a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c @@ -65,7 +65,7 @@ bptree_alloc(objset_t *os, dmu_tx_t *tx) bptree_phys_t *bt; obj = dmu_object_alloc(os, DMU_OTN_UINT64_METADATA, - SPA_MAXBLOCKSIZE, DMU_OTN_UINT64_METADATA, + SPA_OLD_MAXBLOCKSIZE, DMU_OTN_UINT64_METADATA, sizeof (bptree_phys_t), tx); /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c index c9ea6c02a13..0b9a0b92434 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c @@ -2022,10 +2022,8 @@ dbuf_spill_set_blksz(dmu_buf_t *db_fake, uint64_t blksz, dmu_tx_t *tx) return (SET_ERROR(ENOTSUP)); if (blksz == 0) blksz = SPA_MINBLOCKSIZE; - if (blksz > SPA_MAXBLOCKSIZE) - blksz = SPA_MAXBLOCKSIZE; - else - blksz = P2ROUNDUP(blksz, SPA_MINBLOCKSIZE); + ASSERT3U(blksz, <=, spa_maxblocksize(dmu_objset_spa(db->db_objset))); + blksz = P2ROUNDUP(blksz, SPA_MINBLOCKSIZE); DB_DNODE_ENTER(db); dn = DB_DNODE(db); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c index 73b8e056cc8..e7aeed17fb9 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c @@ -255,6 +255,14 @@ logbias_changed_cb(void *arg, uint64_t newval) zil_set_logbias(os->os_zil, newval); } +static void +recordsize_changed_cb(void *arg, uint64_t newval) +{ + objset_t *os = arg; + + os->os_recordsize = newval; +} + void dmu_objset_byteswap(void *buf, size_t size) { @@ -384,6 +392,11 @@ dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp, ZFS_PROP_REDUNDANT_METADATA), redundant_metadata_changed_cb, os); } + if (err == 0) { + err = dsl_prop_register(ds, + zfs_prop_to_name(ZFS_PROP_RECORDSIZE), + recordsize_changed_cb, os); + } } if (err != 0) { VERIFY(arc_buf_remove_ref(os->os_phys_buf, @@ -642,6 +655,9 @@ dmu_objset_evict(objset_t *os) VERIFY0(dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_REDUNDANT_METADATA), redundant_metadata_changed_cb, os)); + VERIFY0(dsl_prop_unregister(ds, + zfs_prop_to_name(ZFS_PROP_RECORDSIZE), + recordsize_changed_cb, os)); } VERIFY0(dsl_prop_unregister(ds, zfs_prop_to_name(ZFS_PROP_PRIMARYCACHE), diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c index 1a0cab5d1cd..00d4f3e73e2 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c @@ -227,11 +227,12 @@ dump_write(dmu_sendarg_t *dsp, dmu_object_type_t type, drrw->drr_offset = offset; drrw->drr_length = blksz; drrw->drr_toguid = dsp->dsa_toguid; - if (BP_IS_EMBEDDED(bp)) { + if (bp == NULL || BP_IS_EMBEDDED(bp)) { /* - * There's no pre-computed checksum of embedded BP's, so - * (like fletcher4-checkummed blocks) userland will have - * to compute a dedup-capable checksum itself. + * There's no pre-computed checksum for partial-block + * writes or embedded BP's, so (like + * fletcher4-checkummed blocks) userland will have to + * compute a dedup-capable checksum itself. */ drrw->drr_checksumtype = ZIO_CHECKSUM_OFF; } else { @@ -393,6 +394,10 @@ dump_dnode(dmu_sendarg_t *dsp, uint64_t object, dnode_phys_t *dnp) drro->drr_compress = dnp->dn_compress; drro->drr_toguid = dsp->dsa_toguid; + if (!(dsp->dsa_featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS) && + drro->drr_blksz > SPA_OLD_MAXBLOCKSIZE) + drro->drr_blksz = SPA_OLD_MAXBLOCKSIZE; + if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0) return (SET_ERROR(EINTR)); @@ -512,6 +517,7 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, uint32_t aflags = ARC_WAIT; arc_buf_t *abuf; int blksz = BP_GET_LSIZE(bp); + uint64_t offset; ASSERT3U(blksz, ==, dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT); ASSERT0(zb->zb_level); @@ -532,8 +538,24 @@ backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp, } } - err = dump_write(dsp, type, zb->zb_object, zb->zb_blkid * blksz, - blksz, bp, abuf->b_data); + offset = zb->zb_blkid * blksz; + + if (!(dsp->dsa_featureflags & + DMU_BACKUP_FEATURE_LARGE_BLOCKS) && + blksz > SPA_OLD_MAXBLOCKSIZE) { + char *buf = abuf->b_data; + while (blksz > 0 && err == 0) { + int n = MIN(blksz, SPA_OLD_MAXBLOCKSIZE); + err = dump_write(dsp, type, zb->zb_object, + offset, n, NULL, buf); + offset += n; + buf += n; + blksz -= n; + } + } else { + err = dump_write(dsp, type, zb->zb_object, + offset, blksz, bp, abuf->b_data); + } (void) arc_buf_remove_ref(abuf, &abuf); } @@ -548,9 +570,9 @@ static int dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *ds, zfs_bookmark_phys_t *fromzb, boolean_t is_clone, boolean_t embedok, #ifdef illumos - int outfd, vnode_t *vp, offset_t *off) + boolean_t large_block_ok, int outfd, vnode_t *vp, offset_t *off) #else - int outfd, struct file *fp, offset_t *off) + boolean_t large_block_ok, int outfd, struct file *fp, offset_t *off) #endif { objset_t *os; @@ -586,6 +608,8 @@ dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *ds, } #endif + if (large_block_ok && ds->ds_large_blocks) + featureflags |= DMU_BACKUP_FEATURE_LARGE_BLOCKS; if (embedok && spa_feature_is_active(dp->dp_spa, SPA_FEATURE_EMBEDDED_DATA)) { featureflags |= DMU_BACKUP_FEATURE_EMBED_DATA; @@ -682,10 +706,11 @@ out: int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap, + boolean_t embedok, boolean_t large_block_ok, #ifdef illumos - boolean_t embedok, int outfd, vnode_t *vp, offset_t *off) + int outfd, vnode_t *vp, offset_t *off) #else - boolean_t embedok, int outfd, struct file *fp, offset_t *off) + int outfd, struct file *fp, offset_t *off) #endif { dsl_pool_t *dp; @@ -720,18 +745,19 @@ dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap, zb.zbm_guid = fromds->ds_phys->ds_guid; is_clone = (fromds->ds_dir != ds->ds_dir); dsl_dataset_rele(fromds, FTAG); - err = dmu_send_impl(FTAG, dp, ds, &zb, is_clone, embedok, - outfd, fp, off); + err = dmu_send_impl(FTAG, dp, ds, &zb, is_clone, + embedok, large_block_ok, outfd, fp, off); } else { - err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE, embedok, - outfd, fp, off); + err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE, + embedok, large_block_ok, outfd, fp, off); } dsl_dataset_rele(ds, FTAG); return (err); } int -dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, +dmu_send(const char *tosnap, const char *fromsnap, + boolean_t embedok, boolean_t large_block_ok, #ifdef illumos int outfd, vnode_t *vp, offset_t *off) #else @@ -802,11 +828,11 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, dsl_pool_rele(dp, FTAG); return (err); } - err = dmu_send_impl(FTAG, dp, ds, &zb, is_clone, embedok, - outfd, fp, off); + err = dmu_send_impl(FTAG, dp, ds, &zb, is_clone, + embedok, large_block_ok, outfd, fp, off); } else { - err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE, embedok, - outfd, fp, off); + err = dmu_send_impl(FTAG, dp, ds, NULL, B_FALSE, + embedok, large_block_ok, outfd, fp, off); } if (owned) dsl_dataset_disown(ds, FTAG); @@ -1006,6 +1032,15 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx) !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LZ4_COMPRESS)) return (SET_ERROR(ENOTSUP)); + /* + * The receiving code doesn't know how to translate large blocks + * to smaller ones, so the pool must have the LARGE_BLOCKS + * feature enabled if the stream has LARGE_BLOCKS. + */ + if ((featureflags & DMU_BACKUP_FEATURE_LARGE_BLOCKS) && + !spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS)) + return (SET_ERROR(ENOTSUP)); + error = dsl_dataset_hold(dp, tofs, FTAG, &ds); if (error == 0) { /* target fs already exists; recv into temp clone */ @@ -1131,6 +1166,13 @@ dmu_recv_begin_sync(void *arg, dmu_tx_t *tx) } VERIFY0(dsl_dataset_own_obj(dp, dsobj, dmu_recv_tag, &newds)); + if ((DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) & + DMU_BACKUP_FEATURE_LARGE_BLOCKS) && + !newds->ds_large_blocks) { + dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx); + newds->ds_large_blocks = B_TRUE; + } + dmu_buf_will_dirty(newds->ds_dbuf, tx); newds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT; @@ -1283,6 +1325,7 @@ restore_read(struct restorearg *ra, int len, char *buf) /* some things will require 8-byte alignment, so everything must */ ASSERT0(len % 8); + ASSERT3U(len, <=, ra->bufsize); while (done < len) { ssize_t resid; @@ -1420,7 +1463,7 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro) drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS || P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) || drro->drr_blksz < SPA_MINBLOCKSIZE || - drro->drr_blksz > SPA_MAXBLOCKSIZE || + drro->drr_blksz > spa_maxblocksize(dmu_objset_spa(os)) || drro->drr_bonuslen > DN_MAX_BONUSLEN) { return (SET_ERROR(EINVAL)); } @@ -1693,7 +1736,7 @@ restore_spill(struct restorearg *ra, objset_t *os, struct drr_spill *drrs) int err; if (drrs->drr_length < SPA_MINBLOCKSIZE || - drrs->drr_length > SPA_MAXBLOCKSIZE) + drrs->drr_length > spa_maxblocksize(dmu_objset_spa(os))) return (SET_ERROR(EINVAL)); data = restore_read(ra, drrs->drr_length, NULL); @@ -1781,7 +1824,7 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, struct file *fp, offset_t *voffp, ra.td = curthread; ra.fp = fp; ra.voff = *voffp; - ra.bufsize = 1<<20; + ra.bufsize = SPA_MAXBLOCKSIZE; ra.buf = kmem_alloc(ra.bufsize, KM_SLEEP); /* these were verified in dmu_recv_begin */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c index ed9757ecd45..b97040ae870 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c @@ -224,7 +224,7 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) return; min_bs = SPA_MINBLOCKSHIFT; - max_bs = SPA_MAXBLOCKSHIFT; + max_bs = highbit64(txh->txh_tx->tx_objset->os_recordsize) - 1; min_ibs = DN_MIN_INDBLKSHIFT; max_ibs = DN_MAX_INDBLKSHIFT; @@ -293,6 +293,14 @@ dmu_tx_count_write(dmu_tx_hold_t *txh, uint64_t off, uint64_t len) */ ASSERT(dn->dn_datablkshift != 0); min_bs = max_bs = dn->dn_datablkshift; + } else { + /* + * The blocksize can increase up to the recordsize, + * or if it is already more than the recordsize, + * up to the next power of 2. + */ + min_bs = highbit64(dn->dn_datablksz - 1); + max_bs = MAX(max_bs, highbit64(dn->dn_datablksz - 1)); } /* @@ -751,11 +759,11 @@ dmu_tx_hold_zap(dmu_tx_t *tx, uint64_t object, int add, const char *name) bp = &dn->dn_phys->dn_blkptr[0]; if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset, bp, bp->blk_birth)) - txh->txh_space_tooverwrite += SPA_MAXBLOCKSIZE; + txh->txh_space_tooverwrite += MZAP_MAX_BLKSZ; else - txh->txh_space_towrite += SPA_MAXBLOCKSIZE; + txh->txh_space_towrite += MZAP_MAX_BLKSZ; if (!BP_IS_HOLE(bp)) - txh->txh_space_tounref += SPA_MAXBLOCKSIZE; + txh->txh_space_tounref += MZAP_MAX_BLKSZ; return; } @@ -1549,18 +1557,18 @@ dmu_tx_hold_spill(dmu_tx_t *tx, uint64_t object) /* If blkptr doesn't exist then add space to towrite */ if (!(dn->dn_phys->dn_flags & DNODE_FLAG_SPILL_BLKPTR)) { - txh->txh_space_towrite += SPA_MAXBLOCKSIZE; + txh->txh_space_towrite += SPA_OLD_MAXBLOCKSIZE; } else { blkptr_t *bp; bp = &dn->dn_phys->dn_spill; if (dsl_dataset_block_freeable(dn->dn_objset->os_dsl_dataset, bp, bp->blk_birth)) - txh->txh_space_tooverwrite += SPA_MAXBLOCKSIZE; + txh->txh_space_tooverwrite += SPA_OLD_MAXBLOCKSIZE; else - txh->txh_space_towrite += SPA_MAXBLOCKSIZE; + txh->txh_space_towrite += SPA_OLD_MAXBLOCKSIZE; if (!BP_IS_HOLE(bp)) - txh->txh_space_tounref += SPA_MAXBLOCKSIZE; + txh->txh_space_tounref += SPA_OLD_MAXBLOCKSIZE; } } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c index 0b19e76343f..b39f6b11d26 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c @@ -513,10 +513,10 @@ dnode_allocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int ibs, { int i; + ASSERT3U(blocksize, <=, + spa_maxblocksize(dmu_objset_spa(dn->dn_objset))); if (blocksize == 0) blocksize = 1 << zfs_default_bs; - else if (blocksize > SPA_MAXBLOCKSIZE) - blocksize = SPA_MAXBLOCKSIZE; else blocksize = P2ROUNDUP(blocksize, SPA_MINBLOCKSIZE); @@ -597,7 +597,8 @@ dnode_reallocate(dnode_t *dn, dmu_object_type_t ot, int blocksize, int nblkptr; ASSERT3U(blocksize, >=, SPA_MINBLOCKSIZE); - ASSERT3U(blocksize, <=, SPA_MAXBLOCKSIZE); + ASSERT3U(blocksize, <=, + spa_maxblocksize(dmu_objset_spa(dn->dn_objset))); ASSERT0(blocksize % SPA_MINBLOCKSIZE); ASSERT(dn->dn_object != DMU_META_DNODE_OBJECT || dmu_tx_private_ok(tx)); ASSERT(tx->tx_txg != 0); @@ -1352,10 +1353,9 @@ dnode_set_blksz(dnode_t *dn, uint64_t size, int ibs, dmu_tx_t *tx) dmu_buf_impl_t *db; int err; + ASSERT3U(size, <=, spa_maxblocksize(dmu_objset_spa(dn->dn_objset))); if (size == 0) size = SPA_MINBLOCKSIZE; - if (size > SPA_MAXBLOCKSIZE) - size = SPA_MAXBLOCKSIZE; else size = P2ROUNDUP(size, SPA_MINBLOCKSIZE); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index a3efe9293cb..f11fa65bcf3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -51,6 +51,22 @@ #include #include +SYSCTL_DECL(_vfs_zfs); + +/* + * The SPA supports block sizes up to 16MB. However, very large blocks + * can have an impact on i/o latency (e.g. tying up a spinning disk for + * ~300ms), and also potentially on the memory allocator. Therefore, + * we do not allow the recordsize to be set larger than zfs_max_recordsize + * (default 1MB). Larger blocks can be created by changing this tunable, + * and pools with larger blocks can always be imported and used, regardless + * of this setting. + */ +int zfs_max_recordsize = 1 * 1024 * 1024; +SYSCTL_INT(_vfs_zfs, OID_AUTO, max_recordsize, CTLFLAG_RWTUN, + &zfs_max_recordsize, 0, + "Maximum block size. Expect dragons when tuning this."); + #define SWITCH64(x, y) \ { \ uint64_t __tmp = (x); \ @@ -60,8 +76,6 @@ #define DS_REF_MAX (1ULL << 62) -#define DSL_DEADLIST_BLOCKSIZE SPA_MAXBLOCKSIZE - /* * Figure out how much of this delta should be propogated to the dsl_dir * layer. If there's a refreservation, that space has already been @@ -111,6 +125,8 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx) ds->ds_phys->ds_compressed_bytes += compressed; ds->ds_phys->ds_uncompressed_bytes += uncompressed; ds->ds_phys->ds_unique_bytes += used; + if (BP_GET_LSIZE(bp) > SPA_OLD_MAXBLOCKSIZE) + ds->ds_need_large_blocks = B_TRUE; mutex_exit(&ds->ds_lock); dsl_dir_diduse_space(ds->ds_dir, DD_USED_HEAD, delta, compressed, uncompressed, tx); @@ -392,6 +408,14 @@ dsl_dataset_hold_obj(dsl_pool_t *dp, uint64_t dsobj, void *tag, list_create(&ds->ds_sendstreams, sizeof (dmu_sendarg_t), offsetof(dmu_sendarg_t, dsa_link)); + if (doi.doi_type == DMU_OTN_ZAP_METADATA) { + err = zap_contains(mos, dsobj, DS_FIELD_LARGE_BLOCKS); + if (err == 0) + ds->ds_large_blocks = B_TRUE; + else + ASSERT3U(err, ==, ENOENT); + } + if (err == 0) { err = dsl_dir_hold_obj(dp, ds->ds_phys->ds_dir_obj, NULL, ds, &ds->ds_dir); @@ -707,6 +731,9 @@ dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin, dsphys->ds_flags |= origin->ds_phys->ds_flags & (DS_FLAG_INCONSISTENT | DS_FLAG_CI_DATASET); + if (origin->ds_large_blocks) + dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx); + dmu_buf_will_dirty(origin->ds_dbuf, tx); origin->ds_phys->ds_num_children++; @@ -1262,6 +1289,9 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname, dsphys->ds_bp = ds->ds_phys->ds_bp; dmu_buf_rele(dbuf, FTAG); + if (ds->ds_large_blocks) + dsl_dataset_activate_large_blocks_sync_impl(dsobj, tx); + ASSERT3U(ds->ds_prev != 0, ==, ds->ds_phys->ds_prev_snap_obj != 0); if (ds->ds_prev) { uint64_t next_clones_obj = @@ -1546,6 +1576,11 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx) ds->ds_phys->ds_fsid_guid = ds->ds_fsid_guid; dmu_objset_sync(ds->ds_objset, zio, tx); + + if (ds->ds_need_large_blocks && !ds->ds_large_blocks) { + dsl_dataset_activate_large_blocks_sync_impl(ds->ds_object, tx); + ds->ds_large_blocks = B_TRUE; + } } static void @@ -3231,6 +3266,77 @@ dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, return (err); } +static int +dsl_dataset_activate_large_blocks_check(void *arg, dmu_tx_t *tx) +{ + const char *dsname = arg; + dsl_dataset_t *ds; + dsl_pool_t *dp = dmu_tx_pool(tx); + int error = 0; + + if (!spa_feature_is_enabled(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS)) + return (SET_ERROR(ENOTSUP)); + + ASSERT(spa_feature_is_enabled(dp->dp_spa, + SPA_FEATURE_EXTENSIBLE_DATASET)); + + error = dsl_dataset_hold(dp, dsname, FTAG, &ds); + if (error != 0) + return (error); + + if (ds->ds_large_blocks) + error = EALREADY; + dsl_dataset_rele(ds, FTAG); + + return (error); +} + +void +dsl_dataset_activate_large_blocks_sync_impl(uint64_t dsobj, dmu_tx_t *tx) +{ + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + objset_t *mos = dmu_tx_pool(tx)->dp_meta_objset; + uint64_t zero = 0; + + spa_feature_incr(spa, SPA_FEATURE_LARGE_BLOCKS, tx); + dmu_object_zapify(mos, dsobj, DMU_OT_DSL_DATASET, tx); + + VERIFY0(zap_add(mos, dsobj, DS_FIELD_LARGE_BLOCKS, + sizeof (zero), 1, &zero, tx)); +} + +static void +dsl_dataset_activate_large_blocks_sync(void *arg, dmu_tx_t *tx) +{ + const char *dsname = arg; + dsl_dataset_t *ds; + + VERIFY0(dsl_dataset_hold(dmu_tx_pool(tx), dsname, FTAG, &ds)); + + dsl_dataset_activate_large_blocks_sync_impl(ds->ds_object, tx); + ASSERT(!ds->ds_large_blocks); + ds->ds_large_blocks = B_TRUE; + dsl_dataset_rele(ds, FTAG); +} + +int +dsl_dataset_activate_large_blocks(const char *dsname) +{ + int error; + + error = dsl_sync_task(dsname, + dsl_dataset_activate_large_blocks_check, + dsl_dataset_activate_large_blocks_sync, (void *)dsname, + 1, ZFS_SPACE_CHECK_RESERVED); + + /* + * EALREADY indicates that this dataset already supports large blocks. + */ + if (error == EALREADY) + error = 0; + return (error); +} + /* * Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline. * For example, they could both be snapshots of the same filesystem, and diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c index 4f39c397a06..8c8e3746eec 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c @@ -143,7 +143,7 @@ uint64_t dsl_deadlist_alloc(objset_t *os, dmu_tx_t *tx) { if (spa_version(dmu_objset_spa(os)) < SPA_VERSION_DEADLISTS) - return (bpobj_alloc(os, SPA_MAXBLOCKSIZE, tx)); + return (bpobj_alloc(os, SPA_OLD_MAXBLOCKSIZE, tx)); return (zap_create(os, DMU_OT_DEADLIST, DMU_OT_DEADLIST_HDR, sizeof (dsl_deadlist_phys_t), tx)); } @@ -180,7 +180,7 @@ dle_enqueue(dsl_deadlist_t *dl, dsl_deadlist_entry_t *dle, { if (dle->dle_bpobj.bpo_object == dmu_objset_pool(dl->dl_os)->dp_empty_bpobj) { - uint64_t obj = bpobj_alloc(dl->dl_os, SPA_MAXBLOCKSIZE, tx); + uint64_t obj = bpobj_alloc(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx); bpobj_close(&dle->dle_bpobj); bpobj_decr_empty(dl->dl_os, tx); VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); @@ -254,7 +254,7 @@ dsl_deadlist_add_key(dsl_deadlist_t *dl, uint64_t mintxg, dmu_tx_t *tx) dle = kmem_alloc(sizeof (*dle), KM_SLEEP); dle->dle_mintxg = mintxg; - obj = bpobj_alloc_empty(dl->dl_os, SPA_MAXBLOCKSIZE, tx); + obj = bpobj_alloc_empty(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx); VERIFY3U(0, ==, bpobj_open(&dle->dle_bpobj, dl->dl_os, obj)); avl_add(&dl->dl_tree, dle); @@ -338,7 +338,7 @@ dsl_deadlist_clone(dsl_deadlist_t *dl, uint64_t maxtxg, if (dle->dle_mintxg >= maxtxg) break; - obj = bpobj_alloc_empty(dl->dl_os, SPA_MAXBLOCKSIZE, tx); + obj = bpobj_alloc_empty(dl->dl_os, SPA_OLD_MAXBLOCKSIZE, tx); VERIFY3U(0, ==, zap_add_int_key(dl->dl_os, newobj, dle->dle_mintxg, obj, tx)); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c index f8a4546535e..1237641583a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c @@ -264,6 +264,10 @@ dsl_destroy_snapshot_sync_impl(dsl_dataset_t *ds, boolean_t defer, dmu_tx_t *tx) obj = ds->ds_object; + if (ds->ds_large_blocks) { + ASSERT0(zap_contains(mos, obj, DS_FIELD_LARGE_BLOCKS)); + spa_feature_decr(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS, tx); + } if (ds->ds_phys->ds_prev_snap_obj != 0) { ASSERT3P(ds->ds_prev, ==, NULL); VERIFY0(dsl_dataset_hold_obj(dp, @@ -720,6 +724,9 @@ dsl_destroy_head_sync_impl(dsl_dataset_t *ds, dmu_tx_t *tx) ASSERT0(ds->ds_reserved); } + if (ds->ds_large_blocks) + spa_feature_decr(dp->dp_spa, SPA_FEATURE_LARGE_BLOCKS, tx); + dsl_scan_ds_destroyed(ds, tx); obj = ds->ds_object; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c index 53371e64229..08e79ca5b8a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c @@ -467,7 +467,7 @@ dsl_pool_create(spa_t *spa, nvlist_t *zplprops, uint64_t txg) FREE_DIR_NAME, &dp->dp_free_dir)); /* create and open the free_bplist */ - obj = bpobj_alloc(dp->dp_meta_objset, SPA_MAXBLOCKSIZE, tx); + obj = bpobj_alloc(dp->dp_meta_objset, SPA_OLD_MAXBLOCKSIZE, tx); VERIFY(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx) == 0); VERIFY0(bpobj_open(&dp->dp_free_bpobj, @@ -892,7 +892,7 @@ dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx) * subobj support. So call dmu_object_alloc() directly. */ obj = dmu_object_alloc(dp->dp_meta_objset, DMU_OT_BPOBJ, - SPA_MAXBLOCKSIZE, DMU_OT_BPOBJ_HDR, sizeof (bpobj_phys_t), tx); + SPA_OLD_MAXBLOCKSIZE, DMU_OT_BPOBJ_HDR, sizeof (bpobj_phys_t), tx); VERIFY0(zap_add(dp->dp_meta_objset, DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_FREE_BPOBJ, sizeof (uint64_t), 1, &obj, tx)); VERIFY0(bpobj_open(&dp->dp_free_bpobj, dp->dp_meta_objset, obj)); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c index c2bcbfd0ccc..9e53f08a680 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c @@ -153,7 +153,7 @@ SYSCTL_INT(_vfs_zfs_metaslab, OID_AUTO, debug_unload, CTLFLAG_RWTUN, * an allocation of this size then it switches to using more * aggressive strategy (i.e search by size rather than offset). */ -uint64_t metaslab_df_alloc_threshold = SPA_MAXBLOCKSIZE; +uint64_t metaslab_df_alloc_threshold = SPA_OLD_MAXBLOCKSIZE; SYSCTL_QUAD(_vfs_zfs_metaslab, OID_AUTO, df_alloc_threshold, CTLFLAG_RWTUN, &metaslab_df_alloc_threshold, 0, "Minimum size which forces the dynamic allocator to change it's allocation strategy"); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c index 5d8c731c886..84b39dd0292 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c @@ -500,7 +500,7 @@ sa_resize_spill(sa_handle_t *hdl, uint32_t size, dmu_tx_t *tx) if (size == 0) { blocksize = SPA_MINBLOCKSIZE; - } else if (size > SPA_MAXBLOCKSIZE) { + } else if (size > SPA_OLD_MAXBLOCKSIZE) { ASSERT(0); return (SET_ERROR(EFBIG)); } else { @@ -675,7 +675,7 @@ sa_build_layouts(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc, int attr_count, hdrsize = sa_find_sizes(sa, attr_desc, attr_count, hdl->sa_bonus, SA_BONUS, &i, &used, &spilling); - if (used > SPA_MAXBLOCKSIZE) + if (used > SPA_OLD_MAXBLOCKSIZE) return (SET_ERROR(EFBIG)); VERIFY(0 == dmu_set_bonus(hdl->sa_bonus, spilling ? @@ -699,7 +699,7 @@ sa_build_layouts(sa_handle_t *hdl, sa_bulk_attr_t *attr_desc, int attr_count, attr_count - i, hdl->sa_spill, SA_SPILL, &i, &spill_used, &dummy); - if (spill_used > SPA_MAXBLOCKSIZE) + if (spill_used > SPA_OLD_MAXBLOCKSIZE) return (SET_ERROR(EFBIG)); buf_space = hdl->sa_spill->db_size - spillhdrsize; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index 2cdfeb0f244..9c62669e9b0 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -287,6 +287,14 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp) spa_prop_add_list(*nvp, ZPOOL_PROP_ALTROOT, spa->spa_root, 0, ZPROP_SRC_LOCAL); + if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) { + spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL, + MIN(zfs_max_recordsize, SPA_MAXBLOCKSIZE), ZPROP_SRC_NONE); + } else { + spa_prop_add_list(*nvp, ZPOOL_PROP_MAXBLOCKSIZE, NULL, + SPA_OLD_MAXBLOCKSIZE, ZPROP_SRC_NONE); + } + if ((dp = list_head(&spa->spa_config_list)) != NULL) { if (dp->scd_path == NULL) { spa_prop_add_list(*nvp, ZPOOL_PROP_CACHEFILE, @@ -501,7 +509,7 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) if (!error) { objset_t *os; - uint64_t compress; + uint64_t propval; if (strval == NULL || strval[0] == '\0') { objnum = zpool_prop_default_numeric( @@ -512,15 +520,25 @@ spa_prop_validate(spa_t *spa, nvlist_t *props) if (error = dmu_objset_hold(strval, FTAG, &os)) break; - /* Must be ZPL and not gzip compressed. */ + /* + * Must be ZPL, and its property settings + * must be supported by GRUB (compression + * is not gzip, and large blocks are not used). + */ if (dmu_objset_type(os) != DMU_OST_ZFS) { error = SET_ERROR(ENOTSUP); } else if ((error = dsl_prop_get_int_ds(dmu_objset_ds(os), zfs_prop_to_name(ZFS_PROP_COMPRESSION), - &compress)) == 0 && - !BOOTFS_COMPRESS_VALID(compress)) { + &propval)) == 0 && + !BOOTFS_COMPRESS_VALID(propval)) { + error = SET_ERROR(ENOTSUP); + } else if ((error = + dsl_prop_get_int_ds(dmu_objset_ds(os), + zfs_prop_to_name(ZFS_PROP_RECORDSIZE), + &propval)) == 0 && + propval > SPA_OLD_MAXBLOCKSIZE) { error = SET_ERROR(ENOTSUP); } else { objnum = dmu_objset_id(os); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c index 83e521765ac..9fc7a463c65 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c @@ -90,7 +90,7 @@ spa_history_create_obj(spa_t *spa, dmu_tx_t *tx) ASSERT(spa->spa_history == 0); spa->spa_history = dmu_object_alloc(mos, DMU_OT_SPA_HISTORY, - SPA_MAXBLOCKSIZE, DMU_OT_SPA_HISTORY_OFFSETS, + SPA_OLD_MAXBLOCKSIZE, DMU_OT_SPA_HISTORY_OFFSETS, sizeof (spa_history_phys_t), tx); VERIFY(zap_add(mos, DMU_POOL_DIRECTORY_OBJECT, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c index c3a42d026b6..b51dd9791f3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c @@ -401,6 +401,9 @@ zfs_deadman_init() * See also the comments in zfs_space_check_t. */ int spa_slop_shift = 5; +SYSCTL_INT(_vfs_zfs, OID_AUTO, spa_slop_shift, CTLFLAG_RWTUN, + &spa_slop_shift, 0, + "Shift value of reserved space (1/(2^spa_slop_shift))."); /* * ========================================================================== @@ -2048,3 +2051,12 @@ spa_debug_enabled(spa_t *spa) { return (spa->spa_debug); } + +int +spa_maxblocksize(spa_t *spa) +{ + if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_BLOCKS)) + return (SPA_MAXBLOCKSIZE); + else + return (SPA_OLD_MAXBLOCKSIZE); +} diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h index ad192664687..d85d872f89d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu.h @@ -249,7 +249,7 @@ void zfs_znode_byteswap(void *buf, size_t size); * The maximum number of bytes that can be accessed as part of one * operation, including metadata. */ -#define DMU_MAX_ACCESS (10<<20) /* 10MB */ +#define DMU_MAX_ACCESS (32 * 1024 * 1024) /* 32MB */ #define DMU_MAX_DELETEBLKCNT (20480) /* ~5MB of indirect blocks */ #define DMU_USERUSED_OBJECT (-1ULL) @@ -646,6 +646,7 @@ void xuio_stat_wbuf_copied(); void xuio_stat_wbuf_nocopy(); extern int zfs_prefetch_disable; +extern int zfs_max_recordsize; /* * Asynchronously try to read in the data. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h index 23d88fd048b..804f0c182b6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h @@ -95,6 +95,7 @@ struct objset { zfs_cache_type_t os_secondary_cache; zfs_sync_type_t os_sync; zfs_redundant_metadata_type_t os_redundant_metadata; + int os_recordsize; /* no lock needed: */ struct dmu_tx *os_synctx; /* XXX sketchy */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h index b5d617025bd..b03cb0976e6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_send.h @@ -36,7 +36,8 @@ struct dsl_dataset; struct drr_begin; struct avl_tree; -int dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, +int dmu_send(const char *tosnap, const char *fromsnap, + boolean_t embedok, boolean_t large_block_ok, #ifdef illumos int outfd, struct vnode *vp, offset_t *off); #else @@ -45,10 +46,11 @@ int dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, int dmu_send_estimate(struct dsl_dataset *ds, struct dsl_dataset *fromds, uint64_t *sizep); int dmu_send_obj(const char *pool, uint64_t tosnap, uint64_t fromsnap, + boolean_t embedok, boolean_t large_block_ok, #ifdef illumos - boolean_t embedok, int outfd, vnode_t *vp, offset_t *off); + int outfd, struct vnode *vp, offset_t *off); #else - boolean_t embedok, int outfd, struct file *fp, offset_t *off); + int outfd, struct file *fp, offset_t *off); #endif typedef struct dmu_recv_cookie { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h index d9552b2260a..ff90f8b439c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_dataset.h @@ -82,6 +82,13 @@ struct dsl_pool; */ #define DS_FIELD_BOOKMARK_NAMES "com.delphix:bookmarks" +/* + * This field is present (with value=0) if this dataset may contain large + * blocks (>128KB). If it is present, then this dataset + * is counted in the refcount of the SPA_FEATURE_LARGE_BLOCKS feature. + */ +#define DS_FIELD_LARGE_BLOCKS "org.open-zfs:large_blocks" + /* * DS_FLAG_CI_DATASET is set if the dataset contains a file system whose * name lookups should be performed case-insensitively. @@ -135,6 +142,8 @@ typedef struct dsl_dataset { /* only used in syncing context, only valid for non-snapshots: */ struct dsl_dataset *ds_prev; uint64_t ds_bookmarks; /* DMU_OTN_ZAP_METADATA */ + boolean_t ds_large_blocks; + boolean_t ds_need_large_blocks; /* has internal locking: */ dsl_deadlist_t ds_deadlist; @@ -244,6 +253,8 @@ int dsl_dataset_space_written(dsl_dataset_t *oldsnap, dsl_dataset_t *new, int dsl_dataset_space_wouldfree(dsl_dataset_t *firstsnap, dsl_dataset_t *last, uint64_t *usedp, uint64_t *compp, uint64_t *uncompp); boolean_t dsl_dataset_is_dirty(dsl_dataset_t *ds); +int dsl_dataset_activate_large_blocks(const char *dsname); +void dsl_dataset_activate_large_blocks_sync_impl(uint64_t dsobj, dmu_tx_t *tx); int dsl_dsobj_to_dsname(char *pname, uint64_t obj, char *buf); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h index f62e3151f87..a5f32e837be 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h @@ -94,17 +94,26 @@ _NOTE(CONSTCOND) } while (0) _NOTE(CONSTCOND) } while (0) /* - * We currently support nine block sizes, from 512 bytes to 128K. - * We could go higher, but the benefits are near-zero and the cost - * of COWing a giant block to modify one byte would become excessive. + * We currently support block sizes from 512 bytes to 16MB. + * The benefits of larger blocks, and thus larger IO, need to be weighed + * against the cost of COWing a giant block to modify one byte, and the + * large latency of reading or writing a large block. + * + * Note that although blocks up to 16MB are supported, the recordsize + * property can not be set larger than zfs_max_recordsize (default 1MB). + * See the comment near zfs_max_recordsize in dsl_dataset.c for details. + * + * Note that although the LSIZE field of the blkptr_t can store sizes up + * to 32MB, the dnode's dn_datablkszsec can only store sizes up to + * 32MB - 512 bytes. Therefore, we limit SPA_MAXBLOCKSIZE to 16MB. */ #define SPA_MINBLOCKSHIFT 9 -#define SPA_MAXBLOCKSHIFT 17 +#define SPA_OLD_MAXBLOCKSHIFT 17 +#define SPA_MAXBLOCKSHIFT 24 #define SPA_MINBLOCKSIZE (1ULL << SPA_MINBLOCKSHIFT) +#define SPA_OLD_MAXBLOCKSIZE (1ULL << SPA_OLD_MAXBLOCKSHIFT) #define SPA_MAXBLOCKSIZE (1ULL << SPA_MAXBLOCKSHIFT) -#define SPA_BLOCKSIZES (SPA_MAXBLOCKSHIFT - SPA_MINBLOCKSHIFT + 1) - /* * Default maximum supported logical ashift. * @@ -801,6 +810,7 @@ extern boolean_t spa_has_slogs(spa_t *spa); extern boolean_t spa_is_root(spa_t *spa); extern boolean_t spa_writeable(spa_t *spa); extern boolean_t spa_has_pending_synctask(spa_t *spa); +extern int spa_maxblocksize(spa_t *spa); extern int spa_mode(spa_t *spa); extern uint64_t zfs_strtonum(const char *str, char **nptr); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h index 642a4c05d64..e7515d5ae77 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h @@ -60,7 +60,7 @@ typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size, uint64_t *logical_ashift, uint64_t *physical_ashift); typedef void vdev_close_func_t(vdev_t *vd); typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize); -typedef int vdev_io_start_func_t(zio_t *zio); +typedef void vdev_io_start_func_t(zio_t *zio); typedef void vdev_io_done_func_t(zio_t *zio); typedef void vdev_state_change_func_t(vdev_t *vd, int, int); typedef void vdev_hold_func_t(vdev_t *vd); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h index 1dc322e02f6..29ebae53849 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zap_impl.h @@ -41,8 +41,7 @@ extern int fzap_default_block_shift; #define MZAP_ENT_LEN 64 #define MZAP_NAME_LEN (MZAP_ENT_LEN - 8 - 4 - 2) -#define MZAP_MAX_BLKSHIFT SPA_MAXBLOCKSHIFT -#define MZAP_MAX_BLKSZ (1 << MZAP_MAX_BLKSHIFT) +#define MZAP_MAX_BLKSZ SPA_OLD_MAXBLOCKSIZE #define ZAP_NEED_CD (-1U) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h index 73fbf3c9c0e..71ca0440134 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_ioctl.h @@ -85,13 +85,16 @@ typedef enum drr_headertype { /* flags #3 - #15 are reserved for incompatible closed-source implementations */ #define DMU_BACKUP_FEATURE_EMBED_DATA (1<<16) #define DMU_BACKUP_FEATURE_EMBED_DATA_LZ4 (1<<17) +/* flag #18 is reserved for a Delphix feature */ +#define DMU_BACKUP_FEATURE_LARGE_BLOCKS (1<<19) /* * Mask of all supported backup features */ #define DMU_BACKUP_FEATURE_MASK (DMU_BACKUP_FEATURE_DEDUP | \ DMU_BACKUP_FEATURE_DEDUPPROPS | DMU_BACKUP_FEATURE_SA_SPILL | \ - DMU_BACKUP_FEATURE_EMBED_DATA | DMU_BACKUP_FEATURE_EMBED_DATA_LZ4) + DMU_BACKUP_FEATURE_EMBED_DATA | DMU_BACKUP_FEATURE_EMBED_DATA_LZ4 | \ + DMU_BACKUP_FEATURE_LARGE_BLOCKS) /* Are all features in the given flag word currently supported? */ #define DMU_STREAM_SUPPORTED(x) (!((x) & ~DMU_BACKUP_FEATURE_MASK)) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h index dae099b7915..3fb66c864ee 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h @@ -133,8 +133,6 @@ extern "C" { #define ZFS_SHARES_DIR "SHARES" #define ZFS_SA_ATTRS "SA_ATTRS" -#define ZFS_MAX_BLOCKSIZE (SPA_MAXBLOCKSIZE) - /* * Path component length * diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h index 15ef2aa8bf9..895d632a262 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h @@ -90,7 +90,6 @@ typedef struct zil_chain { } zil_chain_t; #define ZIL_MIN_BLKSZ 4096ULL -#define ZIL_MAX_BLKSZ SPA_MAXBLOCKSIZE /* * The words of a log block checksum. diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h index 58566203b69..b5c666c02b7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zil_impl.h @@ -139,7 +139,7 @@ typedef struct zil_bp_node { avl_node_t zn_node; } zil_bp_node_t; -#define ZIL_MAX_LOG_DATA (SPA_MAXBLOCKSIZE - sizeof (zil_chain_t) - \ +#define ZIL_MAX_LOG_DATA (SPA_OLD_MAXBLOCKSIZE - sizeof (zil_chain_t) - \ sizeof (lr_write_t)) #ifdef __cplusplus diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index df7edf4c1c6..17ca65b7520 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -152,9 +152,6 @@ typedef enum zio_priority { ZIO_PRIORITY_NOW /* non-queued I/Os (e.g. ioctl) */ } zio_priority_t; -#define ZIO_PIPELINE_CONTINUE 0x100 -#define ZIO_PIPELINE_STOP 0x101 - enum zio_flag { /* * Flags inherited by gang, ddt, and vdev children, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c index 5c52042a014..621f47c8c6b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c @@ -146,10 +146,8 @@ trim_map_create(vdev_t *vd) { trim_map_t *tm; - ASSERT(vd->vdev_ops->vdev_op_leaf); - - if (!zfs_trim_enabled) - return; + ASSERT(zfs_trim_enabled && !vd->vdev_notrim && + vd->vdev_ops->vdev_op_leaf); tm = kmem_zalloc(sizeof (*tm), KM_SLEEP); mutex_init(&tm->tm_lock, NULL, MUTEX_DEFAULT, NULL); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c index dea1a8fa7bf..a9cd4f0de19 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -926,9 +926,9 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg) /* * Compute the raidz-deflation ratio. Note, we hard-code - * in 128k (1 << 17) because it is the current "typical" blocksize. - * Even if SPA_MAXBLOCKSIZE changes, this algorithm must never change, - * or we will inconsistently account for existing bp's. + * in 128k (1 << 17) because it is the "typical" blocksize. + * Even though SPA_MAXBLOCKSIZE changed, this algorithm can not change, + * otherwise it would inconsistently account for existing bp's. */ vd->vdev_deflate_ratio = (1 << 17) / (vdev_psize_to_asize(vd, 1 << 17) >> SPA_MINBLOCKSHIFT); @@ -1223,6 +1223,7 @@ vdev_open(vdev_t *vd) vd->vdev_stat.vs_aux = VDEV_AUX_NONE; vd->vdev_cant_read = B_FALSE; vd->vdev_cant_write = B_FALSE; + vd->vdev_notrim = B_FALSE; vd->vdev_min_asize = vdev_get_min_asize(vd); /* @@ -1292,10 +1293,8 @@ vdev_open(vdev_t *vd) if (vd->vdev_ishole || vd->vdev_ops == &vdev_missing_ops) return (0); - if (vd->vdev_ops->vdev_op_leaf) { - vd->vdev_notrim = B_FALSE; + if (zfs_trim_enabled && !vd->vdev_notrim && vd->vdev_ops->vdev_op_leaf) trim_map_create(vd); - } for (int c = 0; c < vd->vdev_children; c++) { if (vd->vdev_child[c]->vdev_state != VDEV_STATE_HEALTHY) { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c index 1caff2c554c..c397891d485 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c @@ -715,7 +715,7 @@ vdev_disk_ioctl_done(void *zio_arg, int error) zio_interrupt(zio); } -static int +static void vdev_disk_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -732,7 +732,7 @@ vdev_disk_io_start(zio_t *zio) if (dvd == NULL || (dvd->vd_ldi_offline && dvd->vd_lh == NULL)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } if (zio->io_type == ZIO_TYPE_IOCTL) { @@ -740,7 +740,7 @@ vdev_disk_io_start(zio_t *zio) if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } switch (zio->io_cmd) { @@ -771,7 +771,7 @@ vdev_disk_io_start(zio_t *zio) * and will call vdev_disk_ioctl_done() * upon completion. */ - return (ZIO_PIPELINE_STOP); + return; } if (error == ENOTSUP || error == ENOTTY) { @@ -792,10 +792,12 @@ vdev_disk_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } + ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + vb = kmem_alloc(sizeof (vdev_buf_t), KM_SLEEP); vb->vb_io = zio; @@ -814,8 +816,6 @@ vdev_disk_io_start(zio_t *zio) /* ldi_strategy() will return non-zero only on programming errors */ VERIFY(ldi_strategy(dvd->vd_lh, bp) == 0); - - return (ZIO_PIPELINE_STOP); } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c index ab492d80640..01ef7563eb2 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2014 by Delphix. All rights reserved. */ #include @@ -129,6 +129,8 @@ skip_open: return (error); } + vd->vdev_notrim = B_TRUE; + *max_psize = *psize = vattr.va_size; *logical_ashift = SPA_MINBLOCKSHIFT; *physical_ashift = SPA_MINBLOCKSHIFT; @@ -154,7 +156,7 @@ vdev_file_close(vdev_t *vd) vd->vdev_tsd = NULL; } -static int +static void vdev_file_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -165,7 +167,7 @@ vdev_file_io_start(zio_t *zio) if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } vf = vd->vdev_tsd; @@ -181,10 +183,12 @@ vdev_file_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } + ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ? UIO_READ : UIO_WRITE, vp, zio->io_data, zio->io_size, zio->io_offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid); @@ -194,7 +198,10 @@ vdev_file_io_start(zio_t *zio) zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); +#ifdef illumos + VERIFY3U(taskq_dispatch(system_taskq, vdev_file_io_strategy, bp, + TQ_SLEEP), !=, 0); +#endif } /* ARGSUSED */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index b28125ef60b..848340ce823 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -788,7 +788,7 @@ vdev_geom_io_intr(struct bio *bp) zio_interrupt(zio); } -static int +static void vdev_geom_io_start(zio_t *zio) { vdev_t *vd; @@ -803,6 +803,8 @@ vdev_geom_io_start(zio_t *zio) /* XXPOLICY */ if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); + zio_interrupt(zio); + return; } else { switch (zio->io_cmd) { case DKIOCFLUSHWRITECACHE: @@ -818,23 +820,28 @@ vdev_geom_io_start(zio_t *zio) } } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; case ZIO_TYPE_FREE: if (vd->vdev_notrim) { zio->io_error = SET_ERROR(ENOTSUP); } else if (!vdev_geom_bio_delete_disable) { goto sendreq; } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } sendreq: + ASSERT(zio->io_type == ZIO_TYPE_READ || + zio->io_type == ZIO_TYPE_WRITE || + zio->io_type == ZIO_TYPE_FREE || + zio->io_type == ZIO_TYPE_IOCTL); + cp = vd->vdev_tsd; if (cp == NULL) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } bp = g_alloc_bio(); bp->bio_caller1 = zio; @@ -863,8 +870,6 @@ sendreq: bp->bio_done = vdev_geom_io_intr; g_io_request(bp, cp); - - return (ZIO_PIPELINE_STOP); } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c index 70c186f8d2a..966f2fa364b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c @@ -713,8 +713,9 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) * Don't TRIM if removing so that we don't interfere with zpool * disaster recovery. */ - if (zfs_trim_enabled && vdev_trim_on_init && (reason == VDEV_LABEL_CREATE || - reason == VDEV_LABEL_SPARE || reason == VDEV_LABEL_L2CACHE)) + if (zfs_trim_enabled && vdev_trim_on_init && !vd->vdev_notrim && + (reason == VDEV_LABEL_CREATE || reason == VDEV_LABEL_SPARE || + reason == VDEV_LABEL_L2CACHE)) zio_wait(zio_trim(NULL, spa, vd, 0, vd->vdev_psize)); /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c index 2fefa609ac0..60d221a08de 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ #include @@ -425,7 +425,7 @@ vdev_mirror_child_select(zio_t *zio) return (-1); } -static int +static void vdev_mirror_io_start(zio_t *zio) { mirror_map_t *mm; @@ -450,8 +450,8 @@ vdev_mirror_io_start(zio_t *zio) zio->io_type, zio->io_priority, 0, vdev_mirror_scrub_done, mc)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } /* * For normal reads just pick one child. @@ -478,8 +478,7 @@ vdev_mirror_io_start(zio_t *zio) c++; } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } static int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c index fec0037b2b1..24a44a69776 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ /* @@ -67,12 +67,11 @@ vdev_missing_close(vdev_t *vd) } /* ARGSUSED */ -static int +static void vdev_missing_io_start(zio_t *zio) { zio->io_error = SET_ERROR(ENOTSUP); - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } /* ARGSUSED */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c index 395ea29ff18..962e01d6ee5 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c @@ -170,7 +170,7 @@ int zfs_vdev_async_write_active_max_dirty_percent = 60; * we include spans of optional I/Os to aid aggregation at the disk even when * they aren't able to help us aggregate at this level. */ -int zfs_vdev_aggregation_limit = SPA_MAXBLOCKSIZE; +int zfs_vdev_aggregation_limit = SPA_OLD_MAXBLOCKSIZE; int zfs_vdev_read_gap_limit = 32 << 10; int zfs_vdev_write_gap_limit = 4 << 10; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c index 925aaea79f3..6b538cf56d6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ @@ -1618,7 +1618,7 @@ vdev_raidz_physio(vdev_t *vd, caddr_t data, size_t size, /* * Don't write past the end of the block */ - VERIFY3U(offset + size, <=, origoffset + SPA_MAXBLOCKSIZE); + VERIFY3U(offset + size, <=, origoffset + SPA_OLD_MAXBLOCKSIZE); start = offset; end = start + size; @@ -1633,8 +1633,8 @@ vdev_raidz_physio(vdev_t *vd, caddr_t data, size_t size, * KB size. */ rm = vdev_raidz_map_alloc(data - (offset - origoffset), - SPA_MAXBLOCKSIZE, origoffset, B_FALSE, tvd->vdev_ashift, vd->vdev_children, - vd->vdev_nparity); + SPA_OLD_MAXBLOCKSIZE, origoffset, B_FALSE, tvd->vdev_ashift, + vd->vdev_children, vd->vdev_nparity); coloffset = origoffset; @@ -1726,7 +1726,7 @@ vdev_raidz_child_done(zio_t *zio) * vdevs have had errors, then create zio read operations to the parity * columns' VDevs as well. */ -static int +static void vdev_raidz_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -1756,8 +1756,8 @@ vdev_raidz_io_start(zio_t *zio) vdev_raidz_child_done, rc)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } if (zio->io_type == ZIO_TYPE_WRITE) { @@ -1789,8 +1789,8 @@ vdev_raidz_io_start(zio_t *zio) ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -1830,8 +1830,7 @@ vdev_raidz_io_start(zio_t *zio) } } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c index 4e88a53fe2f..4ed8aac2985 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c @@ -33,6 +33,7 @@ #include #include #include +#include #ifdef _KERNEL #include @@ -664,9 +665,9 @@ zap_create_flags(objset_t *os, int normflags, zap_flags_t flags, uint64_t obj = dmu_object_alloc(os, ot, 0, bonustype, bonuslen, tx); ASSERT(leaf_blockshift >= SPA_MINBLOCKSHIFT && - leaf_blockshift <= SPA_MAXBLOCKSHIFT && + leaf_blockshift <= SPA_OLD_MAXBLOCKSHIFT && indirect_blockshift >= SPA_MINBLOCKSHIFT && - indirect_blockshift <= SPA_MAXBLOCKSHIFT); + indirect_blockshift <= SPA_OLD_MAXBLOCKSHIFT); VERIFY(dmu_object_set_blocksize(os, obj, 1ULL << leaf_blockshift, indirect_blockshift, tx) == 0); @@ -1396,7 +1397,6 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add, zap_t *zap; int err = 0; - /* * Since, we don't have a name, we cannot figure out which blocks will * be affected in this operation. So, account for the worst case : @@ -1409,7 +1409,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add, * large microzap results in a promotion to fatzap. */ if (name == NULL) { - *towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE; + *towrite += (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE; return (err); } @@ -1433,7 +1433,7 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add, /* * We treat this case as similar to (name == NULL) */ - *towrite += (3 + (add ? 4 : 0)) * SPA_MAXBLOCKSIZE; + *towrite += (3 + (add ? 4 : 0)) * SPA_OLD_MAXBLOCKSIZE; } } else { /* @@ -1452,12 +1452,12 @@ zap_count_write(objset_t *os, uint64_t zapobj, const char *name, int add, * ptrtbl blocks */ if (dmu_buf_freeable(zap->zap_dbuf)) - *tooverwrite += SPA_MAXBLOCKSIZE; + *tooverwrite += MZAP_MAX_BLKSZ; else - *towrite += SPA_MAXBLOCKSIZE; + *towrite += MZAP_MAX_BLKSZ; if (add) { - *towrite += 4 * SPA_MAXBLOCKSIZE; + *towrite += 4 * MZAP_MAX_BLKSZ; } } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 5f42c79223f..5595348e9e1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -2433,7 +2433,7 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source, const char *propname = nvpair_name(pair); zfs_prop_t prop = zfs_name_to_prop(propname); uint64_t intval; - int err; + int err = -1; if (prop == ZPROP_INVAL) { if (zfs_prop_userquota(propname)) @@ -3864,8 +3864,7 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr) * the SPA supports it. We ignore any errors here since * we'll catch them later. */ - if (nvpair_type(pair) == DATA_TYPE_UINT64 && - nvpair_value_uint64(pair, &intval) == 0) { + if (nvpair_value_uint64(pair, &intval) == 0) { if (intval >= ZIO_COMPRESS_GZIP_1 && intval <= ZIO_COMPRESS_GZIP_9 && zfs_earlier_version(dsname, @@ -3916,6 +3915,42 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr) return (SET_ERROR(ENOTSUP)); break; + case ZFS_PROP_RECORDSIZE: + /* Record sizes above 128k need the feature to be enabled */ + if (nvpair_value_uint64(pair, &intval) == 0 && + intval > SPA_OLD_MAXBLOCKSIZE) { + spa_t *spa; + + /* + * If this is a bootable dataset then + * the we don't allow large (>128K) blocks, + * because GRUB doesn't support them. + */ + if (zfs_is_bootfs(dsname) && + intval > SPA_OLD_MAXBLOCKSIZE) { + return (SET_ERROR(EDOM)); + } + + /* + * We don't allow setting the property above 1MB, + * unless the tunable has been changed. + */ + if (intval > zfs_max_recordsize || + intval > SPA_MAXBLOCKSIZE) + return (SET_ERROR(EDOM)); + + if ((err = spa_open(dsname, &spa, FTAG)) != 0) + return (err); + + if (!spa_feature_is_enabled(spa, + SPA_FEATURE_LARGE_BLOCKS)) { + spa_close(spa, FTAG); + return (SET_ERROR(ENOTSUP)); + } + spa_close(spa, FTAG); + } + break; + case ZFS_PROP_SHARESMB: if (zpl_earlier_version(dsname, ZPL_VERSION_FUID)) return (SET_ERROR(ENOTSUP)); @@ -4344,7 +4379,7 @@ out: * zc_fromobj objsetid of incremental fromsnap (may be zero) * zc_guid if set, estimate size of stream only. zc_cookie is ignored. * output size in zc_objset_type. - * zc_flags if =1, WRITE_EMBEDDED records are permitted + * zc_flags lzc_send_flags * * outputs: * zc_objset_type estimated size, if zc_guid is set @@ -4356,6 +4391,7 @@ zfs_ioc_send(zfs_cmd_t *zc) offset_t off; boolean_t estimate = (zc->zc_guid != 0); boolean_t embedok = (zc->zc_flags & 0x1); + boolean_t large_block_ok = (zc->zc_flags & 0x2); if (zc->zc_obj != 0) { dsl_pool_t *dp; @@ -4420,10 +4456,11 @@ zfs_ioc_send(zfs_cmd_t *zc) off = fp->f_offset; error = dmu_send_obj(zc->zc_name, zc->zc_sendobj, + zc->zc_fromobj, embedok, large_block_ok, #ifdef illumos - zc->zc_fromobj, embedok, zc->zc_cookie, fp->f_vnode, &off); + zc->zc_cookie, fp->f_vnode, &off); #else - zc->zc_fromobj, embedok, zc->zc_cookie, fp, &off); + zc->zc_cookie, fp, &off); #endif if (off >= 0 && off <= MAXOFFSET_T) @@ -5361,6 +5398,8 @@ zfs_ioc_unjail(zfs_cmd_t *zc) * innvl: { * "fd" -> file descriptor to write stream to (int32) * (optional) "fromsnap" -> full snap name to send an incremental from + * (optional) "largeblockok" -> (value ignored) + * indicates that blocks > 128KB are permitted * (optional) "embedok" -> (value ignored) * presence indicates DRR_WRITE_EMBEDDED records are permitted * } @@ -5376,6 +5415,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) offset_t off; char *fromname = NULL; int fd; + boolean_t largeblockok; boolean_t embedok; error = nvlist_lookup_int32(innvl, "fd", &fd); @@ -5384,6 +5424,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) (void) nvlist_lookup_string(innvl, "fromsnap", &fromname); + largeblockok = nvlist_exists(innvl, "largeblockok"); embedok = nvlist_exists(innvl, "embedok"); file_t *fp = getf(fd, cap_rights_init(&rights, CAP_READ)); @@ -5391,10 +5432,11 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl) return (SET_ERROR(EBADF)); off = fp->f_offset; + error = dmu_send(snapname, fromname, embedok, largeblockok, #ifdef illumos - error = dmu_send(snapname, fromname, embedok, fd, fp->f_vnode, &off); + fd, fp->f_vnode, &off); #else - error = dmu_send(snapname, fromname, embedok, fd, fp, &off); + fd, fp, &off); #endif #ifdef illumos diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c index 3029f7dc4c7..7432290d218 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c @@ -490,7 +490,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, * If the write would overflow the largest block then split it. */ if (write_state != WR_INDIRECT && resid > ZIL_MAX_LOG_DATA) - len = SPA_MAXBLOCKSIZE >> 1; + len = SPA_OLD_MAXBLOCKSIZE >> 1; else len = resid; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index ea17daf81f9..15d34df9a0b 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -270,10 +270,9 @@ static void blksz_changed_cb(void *arg, uint64_t newval) { zfsvfs_t *zfsvfs = arg; - - if (newval < SPA_MINBLOCKSIZE || - newval > SPA_MAXBLOCKSIZE || !ISP2(newval)) - newval = SPA_MAXBLOCKSIZE; + ASSERT3U(newval, <=, spa_maxblocksize(dmu_objset_spa(zfsvfs->z_os))); + ASSERT3U(newval, >=, SPA_MINBLOCKSIZE); + ASSERT(ISP2(newval)); zfsvfs->z_max_blksz = newval; zfsvfs->z_vfs->mnt_stat.f_iosize = newval; @@ -900,7 +899,7 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp) */ zfsvfs->z_vfs = NULL; zfsvfs->z_parent = zfsvfs; - zfsvfs->z_max_blksz = SPA_MAXBLOCKSIZE; + zfsvfs->z_max_blksz = SPA_OLD_MAXBLOCKSIZE; zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE; zfsvfs->z_os = os; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 5fec709c9bb..46d0b6de9fb 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -1023,8 +1023,14 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct) uint64_t new_blksz; if (zp->z_blksz > max_blksz) { + /* + * File's blocksize is already larger than the + * "recordsize" property. Only let it grow to + * the next power of 2. + */ ASSERT(!ISP2(zp->z_blksz)); - new_blksz = MIN(end_size, SPA_MAXBLOCKSIZE); + new_blksz = MIN(end_size, + 1 << highbit64(zp->z_blksz)); } else { new_blksz = MIN(end_size, max_blksz); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c index d92597e4b0e..f92ddd446b8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c @@ -54,6 +54,7 @@ #endif /* _KERNEL */ #include +#include #include #include #include @@ -1543,8 +1544,13 @@ zfs_extend(znode_t *zp, uint64_t end) * We are growing the file past the current block size. */ if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) { + /* + * File's blocksize is already larger than the + * "recordsize" property. Only let it grow to + * the next power of 2. + */ ASSERT(!ISP2(zp->z_blksz)); - newblksz = MIN(end, SPA_MAXBLOCKSIZE); + newblksz = MIN(end, 1 << highbit64(zp->z_blksz)); } else { newblksz = MIN(end, zp->z_zfsvfs->z_max_blksz); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c index c26e53cea63..2084d88ff68 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c @@ -229,6 +229,7 @@ zil_read_log_block(zilog_t *zilog, const blkptr_t *bp, blkptr_t *nbp, void *dst, sizeof (cksum)) || BP_IS_HOLE(&zilc->zc_next_blk)) { error = SET_ERROR(ECKSUM); } else { + ASSERT3U(len, <=, SPA_OLD_MAXBLOCKSIZE); bcopy(lr, dst, len); *end = (char *)dst + len; *nbp = zilc->zc_next_blk; @@ -243,6 +244,8 @@ zil_read_log_block(zilog_t *zilog, const blkptr_t *bp, blkptr_t *nbp, void *dst, (zilc->zc_nused > (size - sizeof (*zilc)))) { error = SET_ERROR(ECKSUM); } else { + ASSERT3U(zilc->zc_nused, <=, + SPA_OLD_MAXBLOCKSIZE); bcopy(lr, dst, zilc->zc_nused); *end = (char *)dst + zilc->zc_nused; *nbp = zilc->zc_next_blk; @@ -326,7 +329,7 @@ zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func, * If the log has been claimed, stop if we encounter a sequence * number greater than the highest claimed sequence number. */ - lrbuf = zio_buf_alloc(SPA_MAXBLOCKSIZE); + lrbuf = zio_buf_alloc(SPA_OLD_MAXBLOCKSIZE); zil_bp_tree_init(zilog); for (blk = zh->zh_log; !BP_IS_HOLE(&blk); blk = next_blk) { @@ -373,7 +376,7 @@ done: (max_blk_seq == claim_blk_seq && max_lr_seq == claim_lr_seq)); zil_bp_tree_fini(zilog); - zio_buf_free(lrbuf, SPA_MAXBLOCKSIZE); + zio_buf_free(lrbuf, SPA_OLD_MAXBLOCKSIZE); return (error); } @@ -905,7 +908,7 @@ zil_lwb_write_init(zilog_t *zilog, lwb_t *lwb) * * These must be a multiple of 4KB. Note only the amount used (again * aligned to 4KB) actually gets written. However, we can't always just - * allocate SPA_MAXBLOCKSIZE as the slog space could be exhausted. + * allocate SPA_OLD_MAXBLOCKSIZE as the slog space could be exhausted. */ uint64_t zil_block_buckets[] = { 4096, /* non TX_WRITE */ @@ -987,7 +990,7 @@ zil_lwb_write_start(zilog_t *zilog, lwb_t *lwb) continue; zil_blksz = zil_block_buckets[i]; if (zil_blksz == UINT64_MAX) - zil_blksz = SPA_MAXBLOCKSIZE; + zil_blksz = SPA_OLD_MAXBLOCKSIZE; zilog->zl_prev_blks[zilog->zl_prev_rotor] = zil_blksz; for (i = 0; i < ZIL_PREV_BLKS; i++) zil_blksz = MAX(zil_blksz, zilog->zl_prev_blks[i]); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 3586f8723bd..70ee9a6a1cb 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -90,6 +90,9 @@ kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; extern vmem_t *zio_alloc_arena; #endif +#define ZIO_PIPELINE_CONTINUE 0x100 +#define ZIO_PIPELINE_STOP 0x101 + /* * The following actions directly effect the spa's sync-to-convergence logic. * The values below define the sync pass when we start performing the action. @@ -139,9 +142,8 @@ zio_init(void) /* * For small buffers, we want a cache for each multiple of - * SPA_MINBLOCKSIZE. For medium-size buffers, we want a cache - * for each quarter-power of 2. For large buffers, we want - * a cache for each multiple of PAGESIZE. + * SPA_MINBLOCKSIZE. For larger buffers, we want a cache + * for each quarter-power of 2. */ for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) { size_t size = (c + 1) << SPA_MINBLOCKSHIFT; @@ -166,10 +168,8 @@ zio_init(void) #endif /* illumos */ if (size <= 4 * SPA_MINBLOCKSIZE) { align = SPA_MINBLOCKSIZE; - } else if (IS_P2ALIGNED(size, PAGESIZE)) { - align = PAGESIZE; } else if (IS_P2ALIGNED(size, p2 >> 2)) { - align = p2 >> 2; + align = MIN(p2 >> 2, PAGESIZE); } if (align != 0) { @@ -2557,6 +2557,18 @@ zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp) * Read, write and delete to physical devices * ========================================================================== */ + + +/* + * Issue an I/O to the underlying vdev. Typically the issue pipeline + * stops after this stage and will resume upon I/O completion. + * However, there are instances where the vdev layer may need to + * continue the pipeline when an I/O was not issued. Since the I/O + * that was sent to the vdev layer might be different than the one + * currently active in the pipeline (see vdev_queue_io()), we explicitly + * force the underlying vdev layers to call either zio_execute() or + * zio_interrupt() to ensure that the pipeline continues with the correct I/O. + */ static int zio_vdev_io_start(zio_t *zio) { @@ -2575,7 +2587,8 @@ zio_vdev_io_start(zio_t *zio) /* * The mirror_ops handle multiple DVAs in a single BP. */ - return (vdev_mirror_ops.vdev_op_io_start(zio)); + vdev_mirror_ops.vdev_op_io_start(zio); + return (ZIO_PIPELINE_STOP); } if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE && @@ -2589,7 +2602,7 @@ zio_vdev_io_start(zio_t *zio) * can quickly react to certain workloads. In particular, we care * about non-scrubbing, top-level reads and writes with the following * characteristics: - * - synchronous writes of user data to non-slog devices + * - synchronous writes of user data to non-slog devices * - any reads of user data * When these conditions are met, adjust the timestamp of spa_last_io * which allows the scan thread to adjust its workload accordingly. @@ -2606,8 +2619,7 @@ zio_vdev_io_start(zio_t *zio) align = 1ULL << vd->vdev_top->vdev_ashift; - if ((!(zio->io_flags & ZIO_FLAG_PHYSICAL) || - (vd->vdev_top->vdev_physical_ashift > SPA_MINBLOCKSHIFT)) && + if (!(zio->io_flags & ZIO_FLAG_PHYSICAL) && P2PHASE(zio->io_size, align) != 0) { /* Transform logical writes to be a full physical block size. */ uint64_t asize = P2ROUNDUP(zio->io_size, align); @@ -2693,10 +2705,8 @@ zio_vdev_io_start(zio_t *zio) return (ZIO_PIPELINE_STOP); } - ret = vd->vdev_ops->vdev_op_io_start(zio); - ASSERT(ret == ZIO_PIPELINE_STOP); - - return (ret); + vd->vdev_ops->vdev_op_io_start(zio); + return (ZIO_PIPELINE_STOP); } static int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index 23480cc5716..1776ed31114 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -258,7 +258,7 @@ int zvol_check_volblocksize(uint64_t volblocksize) { if (volblocksize < SPA_MINBLOCKSIZE || - volblocksize > SPA_MAXBLOCKSIZE || + volblocksize > SPA_OLD_MAXBLOCKSIZE || !ISP2(volblocksize)) return (SET_ERROR(EDOM)); @@ -828,7 +828,7 @@ zvol_prealloc(zvol_state_t *zv) while (resid != 0) { int error; - uint64_t bytes = MIN(resid, SPA_MAXBLOCKSIZE); + uint64_t bytes = MIN(resid, SPA_OLD_MAXBLOCKSIZE); tx = dmu_tx_create(os); dmu_tx_hold_write(tx, ZVOL_OBJ, off, bytes); @@ -1866,7 +1866,8 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) (void) strcpy(dki.dki_dname, "zvol"); dki.dki_ctype = DKC_UNKNOWN; dki.dki_unit = getminor(dev); - dki.dki_maxtransfer = 1 << (SPA_MAXBLOCKSHIFT - zv->zv_min_bs); + dki.dki_maxtransfer = + 1 << (SPA_OLD_MAXBLOCKSHIFT - zv->zv_min_bs); mutex_exit(&spa_namespace_lock); if (ddi_copyout(&dki, (void *)arg, sizeof (dki), flag)) error = SET_ERROR(EFAULT); @@ -2185,14 +2186,14 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize) zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), 8, 1, &vbs, tx); error = error ? error : dmu_object_set_blocksize( - os, ZVOL_OBJ, SPA_MAXBLOCKSIZE, 0, tx); + os, ZVOL_OBJ, SPA_OLD_MAXBLOCKSIZE, 0, tx); if (version >= SPA_VERSION_DEDUP) { error = error ? error : zap_update(os, ZVOL_ZAP_OBJ, zfs_prop_to_name(ZFS_PROP_DEDUP), 8, 1, &dedup, tx); } if (error == 0) - zv->zv_volblocksize = SPA_MAXBLOCKSIZE; + zv->zv_volblocksize = SPA_OLD_MAXBLOCKSIZE; } dmu_tx_commit(tx); diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h index 87d0650badd..16d528e025d 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -196,6 +196,7 @@ typedef enum { ZPOOL_PROP_FREEING, ZPOOL_PROP_FRAGMENTATION, ZPOOL_PROP_LEAKED, + ZPOOL_PROP_MAXBLOCKSIZE, ZPOOL_NUM_PROPS } zpool_prop_t; diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h index de16611af95..ace71ae7415 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/isa_defs.h @@ -331,7 +331,9 @@ extern "C" { /* * Define the appropriate "implementation choices". */ +#if !defined(_ILP32) #define _ILP32 +#endif #if !defined(_I32LPx) && defined(_KERNEL) #define _I32LPx #endif diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 5ea062ea368..24c57381353 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -83,10 +83,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include -#include #ifdef INET #include @@ -1235,7 +1231,8 @@ freebsd32_utimes(struct thread *td, struct freebsd32_utimes_args *uap) sp = s; } else sp = NULL; - return (kern_utimes(td, uap->path, UIO_USERSPACE, sp, UIO_SYSSPACE)); + return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + sp, UIO_SYSSPACE)); } int @@ -1567,26 +1564,18 @@ struct sf_hdtr32 { int trl_cnt; }; -struct sf_hdtr_kq32 { - int kq_fd; - uint32_t kq_flags; - uint32_t kq_udata; /* 32-bit void ptr */ - uint32_t kq_ident; /* 32-bit uintptr_t */ -}; - static int freebsd32_do_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap, int compat) { struct sf_hdtr32 hdtr32; struct sf_hdtr hdtr; - struct sf_hdtr_kq32 hdtr_kq32; - struct sf_hdtr_kq hdtr_kq; struct uio *hdr_uio, *trl_uio; + struct file *fp; + cap_rights_t rights; struct iovec32 *iov32; - off_t offset; + off_t offset, sbytes; int error; - off_t sbytes; offset = PAIR32TO64(off_t, uap->offset); if (offset < 0) @@ -1617,31 +1606,17 @@ freebsd32_do_sendfile(struct thread *td, if (error) goto out; } - - /* - * If SF_KQUEUE is set, then we need to also copy in - * the kqueue data after the normal hdtr set and set do_kqueue=1. - */ - if (uap->flags & SF_KQUEUE) { - error = copyin(((char *) uap->hdtr) + sizeof(hdtr32), - &hdtr_kq32, - sizeof(hdtr_kq32)); - if (error != 0) - goto out; - - /* 32->64 bit fields */ - CP(hdtr_kq32, hdtr_kq, kq_fd); - CP(hdtr_kq32, hdtr_kq, kq_flags); - PTRIN_CP(hdtr_kq32, hdtr_kq, kq_udata); - CP(hdtr_kq32, hdtr_kq, kq_ident); - } } + AUDIT_ARG_FD(uap->fd); - /* Call sendfile */ - /* XXX stack depth! */ - error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat, - offset, uap->nbytes, &sbytes, hdr_uio, trl_uio, &hdtr_kq); + if ((error = fget_read(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) + goto out; + + error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, + uap->nbytes, &sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); + fdrop(fp, td); if (uap->sbytes != NULL) copyout(&sbytes, uap->sbytes, sizeof(off_t)); @@ -1723,7 +1698,8 @@ freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap) struct stat32 sb32; int error; - error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, + &sb, NULL); if (error) return (error); copy_stat(&sb, &sb32); @@ -1739,7 +1715,8 @@ ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap) struct ostat32 sb32; int error; - error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, + &sb, NULL); if (error) return (error); copy_ostat(&sb, &sb32); @@ -1787,7 +1764,8 @@ freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap) struct stat32 ub32; int error; - error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, &ub); + error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, + &ub, NULL); if (error) return (error); copy_stat(&ub, &ub32); @@ -1802,7 +1780,8 @@ freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap) struct stat32 sb32; int error; - error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, + UIO_USERSPACE, &sb, NULL); if (error) return (error); copy_stat(&sb, &sb32); @@ -1818,7 +1797,8 @@ ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap) struct ostat32 sb32; int error; - error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, + UIO_USERSPACE, &sb, NULL); if (error) return (error); copy_ostat(&sb, &sb32); @@ -3017,3 +2997,31 @@ freebsd32_fcntl(struct thread *td, struct freebsd32_fcntl_args *uap) } return (kern_fcntl_freebsd(td, uap->fd, uap->cmd, tmp)); } + +int +freebsd32_ppoll(struct thread *td, struct freebsd32_ppoll_args *uap) +{ + struct timespec32 ts32; + struct timespec ts, *tsp; + sigset_t set, *ssp; + int error; + + if (uap->ts != NULL) { + error = copyin(uap->ts, &ts32, sizeof(ts32)); + if (error != 0) + return (error); + CP(ts32, ts, tv_sec); + CP(ts32, ts, tv_nsec); + tsp = &ts; + } else + tsp = NULL; + if (uap->set != NULL) { + error = copyin(uap->set, &set, sizeof(set)); + if (error != 0) + return (error); + ssp = &set; + } else + ssp = NULL; + + return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp)); +} diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index d426e19aafa..5fe4872ffec 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ #ifndef _FREEBSD32_SYSPROTO_H_ @@ -687,6 +687,12 @@ struct freebsd32_procctl_args { char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)]; }; #endif +struct freebsd32_ppoll_args { + char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)]; + char nfds_l_[PADL_(u_int)]; u_int nfds; char nfds_r_[PADR_(u_int)]; + char ts_l_[PADL_(const struct timespec32 *)]; const struct timespec32 * ts; char ts_r_[PADR_(const struct timespec32 *)]; + char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)]; +}; #if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) #define PAD64_REQUIRED #endif @@ -818,6 +824,7 @@ int freebsd32_procctl(struct thread *, struct freebsd32_procctl_args *); #else int freebsd32_procctl(struct thread *, struct freebsd32_procctl_args *); #endif +int freebsd32_ppoll(struct thread *, struct freebsd32_ppoll_args *); #ifdef COMPAT_43 @@ -1232,6 +1239,7 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_ #define FREEBSD32_SYS_AUE_freebsd32_aio_mlock AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_procctl AUE_NULL #define FREEBSD32_SYS_AUE_freebsd32_procctl AUE_NULL +#define FREEBSD32_SYS_AUE_freebsd32_ppoll AUE_POLL #undef PAD_ #undef PADL_ diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h index e627ff3d074..069a69b1b88 100644 --- a/sys/compat/freebsd32/freebsd32_syscall.h +++ b/sys/compat/freebsd32/freebsd32_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ #define FREEBSD32_SYS_syscall 0 @@ -452,4 +452,5 @@ #define FREEBSD32_SYS_freebsd32_aio_mlock 543 #define FREEBSD32_SYS_freebsd32_procctl 544 #define FREEBSD32_SYS_freebsd32_procctl 544 -#define FREEBSD32_SYS_MAXSYSCALL 545 +#define FREEBSD32_SYS_freebsd32_ppoll 545 +#define FREEBSD32_SYS_MAXSYSCALL 546 diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index 2bf45ea4c3d..5de34d16333 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ const char *freebsd32_syscallnames[] = { @@ -578,4 +578,5 @@ const char *freebsd32_syscallnames[] = { #else "freebsd32_procctl", /* 544 = freebsd32_procctl */ #endif + "freebsd32_ppoll", /* 545 = freebsd32_ppoll */ }; diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 9735e30973b..a401167ce24 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ #include "opt_compat.h" @@ -615,4 +615,5 @@ struct sysent freebsd32_sysent[] = { #else { AS(freebsd32_procctl_args), (sy_call_t *)freebsd32_procctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 544 = freebsd32_procctl */ #endif + { AS(freebsd32_ppoll_args), (sy_call_t *)freebsd32_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = freebsd32_ppoll */ }; diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index db03855862f..4d4d58d36c1 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -3299,6 +3299,16 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) break; } #endif + /* freebsd32_ppoll */ + case 545: { + struct freebsd32_ppoll_args *p = params; + uarg[0] = (intptr_t) p->fds; /* struct pollfd * */ + uarg[1] = p->nfds; /* u_int */ + uarg[2] = (intptr_t) p->ts; /* const struct timespec32 * */ + uarg[3] = (intptr_t) p->set; /* const sigset_t * */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -8844,6 +8854,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) }; break; #endif + /* freebsd32_ppoll */ + case 545: + switch(ndx) { + case 0: + p = "struct pollfd *"; + break; + case 1: + p = "u_int"; + break; + case 2: + p = "const struct timespec32 *"; + break; + case 3: + p = "const sigset_t *"; + break; + default: + break; + }; + break; default: break; }; @@ -10717,6 +10746,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) p = "int"; break; #endif + /* freebsd32_ppoll */ + case 545: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 2fafc0c4887..5d445a57e31 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -1066,3 +1066,6 @@ uint32_t id1, uint32_t id2, int com, \ void *data); } #endif +545 AUE_POLL STD { int freebsd32_ppoll(struct pollfd *fds, \ + u_int nfds, const struct timespec32 *ts, \ + const sigset_t *set); } diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index e56e61f24b7..88303b92c9b 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -82,8 +82,8 @@ linux_creat(struct thread *td, struct linux_creat_args *args) if (ldebug(creat)) printf(ARGS(creat, "%s, %d"), path, args->mode); #endif - error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, - args->mode); + error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, + O_WRONLY | O_CREAT | O_TRUNC, args->mode); LFREEPATH(path); return (error); } @@ -572,7 +572,8 @@ linux_access(struct thread *td, struct linux_access_args *args) if (ldebug(access)) printf(ARGS(access, "%s, %d"), path, args->amode); #endif - error = kern_access(td, path, UIO_SYSSPACE, args->amode); + error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, + args->amode); LFREEPATH(path); return (error); @@ -619,12 +620,15 @@ linux_unlink(struct thread *td, struct linux_unlink_args *args) printf(ARGS(unlink, "%s"), path); #endif - error = kern_unlink(td, path, UIO_SYSSPACE); - if (error == EPERM) + error = kern_unlinkat(td, AT_FDCWD, path, UIO_SYSSPACE, 0); + if (error == EPERM) { /* Introduce POSIX noncompliant behaviour of Linux */ - if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0) + if (kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, + NULL) == 0) { if (S_ISDIR(st.st_mode)) error = EISDIR; + } + } LFREEPATH(path); return (error); } @@ -654,7 +658,7 @@ linux_unlinkat(struct thread *td, struct linux_unlinkat_args *args) if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, AT_SYMLINK_NOFOLLOW, dfd, path, - UIO_SYSSPACE, &st) == 0 && S_ISDIR(st.st_mode)) + UIO_SYSSPACE, &st, NULL) == 0 && S_ISDIR(st.st_mode)) error = EISDIR; } LFREEPATH(path); @@ -689,7 +693,8 @@ linux_chmod(struct thread *td, struct linux_chmod_args *args) if (ldebug(chmod)) printf(ARGS(chmod, "%s, %d"), path, args->mode); #endif - error = kern_chmod(td, path, UIO_SYSSPACE, args->mode); + error = kern_fchmodat(td, AT_FDCWD, path, UIO_SYSSPACE, + args->mode, 0); LFREEPATH(path); return (error); } @@ -725,7 +730,7 @@ linux_mkdir(struct thread *td, struct linux_mkdir_args *args) if (ldebug(mkdir)) printf(ARGS(mkdir, "%s, %d"), path, args->mode); #endif - error = kern_mkdir(td, path, UIO_SYSSPACE, args->mode); + error = kern_mkdirat(td, AT_FDCWD, path, UIO_SYSSPACE, args->mode); LFREEPATH(path); return (error); } @@ -760,7 +765,7 @@ linux_rmdir(struct thread *td, struct linux_rmdir_args *args) if (ldebug(rmdir)) printf(ARGS(rmdir, "%s"), path); #endif - error = kern_rmdir(td, path, UIO_SYSSPACE); + error = kern_rmdirat(td, AT_FDCWD, path, UIO_SYSSPACE); LFREEPATH(path); return (error); } @@ -783,7 +788,7 @@ linux_rename(struct thread *td, struct linux_rename_args *args) if (ldebug(rename)) printf(ARGS(rename, "%s, %s"), from, to); #endif - error = kern_rename(td, from, to, UIO_SYSSPACE); + error = kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, UIO_SYSSPACE); LFREEPATH(from); LFREEPATH(to); return (error); @@ -833,7 +838,7 @@ linux_symlink(struct thread *td, struct linux_symlink_args *args) if (ldebug(symlink)) printf(ARGS(symlink, "%s, %s"), path, to); #endif - error = kern_symlink(td, path, to, UIO_SYSSPACE); + error = kern_symlinkat(td, path, AT_FDCWD, to, UIO_SYSSPACE); LFREEPATH(path); LFREEPATH(to); return (error); @@ -878,8 +883,8 @@ linux_readlink(struct thread *td, struct linux_readlink_args *args) printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf, args->count); #endif - error = kern_readlink(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE, - args->count); + error = kern_readlinkat(td, AT_FDCWD, name, UIO_SYSSPACE, + args->buf, UIO_USERSPACE, args->count); LFREEPATH(name); return (error); } @@ -972,7 +977,8 @@ linux_link(struct thread *td, struct linux_link_args *args) if (ldebug(link)) printf(ARGS(link, "%s, %s"), path, to); #endif - error = kern_link(td, path, to, UIO_SYSSPACE); + error = kern_linkat(td, AT_FDCWD, AT_FDCWD, path, to, UIO_SYSSPACE, + FOLLOW); LFREEPATH(path); LFREEPATH(to); return (error); @@ -1487,7 +1493,8 @@ linux_chown(struct thread *td, struct linux_chown_args *args) if (ldebug(chown)) printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid); #endif - error = kern_chown(td, path, UIO_SYSSPACE, args->uid, args->gid); + error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, + args->gid, 0); LFREEPATH(path); return (error); } @@ -1529,7 +1536,8 @@ linux_lchown(struct thread *td, struct linux_lchown_args *args) if (ldebug(lchown)) printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid); #endif - error = kern_lchown(td, path, UIO_SYSSPACE, args->uid, args->gid); + error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, + args->gid, AT_SYMLINK_NOFOLLOW); LFREEPATH(path); return (error); } diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index ff5e8a25a48..4433e186afa 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -777,7 +777,8 @@ linux_utime(struct thread *td, struct linux_utime_args *args) } else tvp = NULL; - error = kern_utimes(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE); + error = kern_utimesat(td, AT_FDCWD, fname, UIO_SYSSPACE, tvp, + UIO_SYSSPACE); LFREEPATH(fname); return (error); } @@ -809,7 +810,8 @@ linux_utimes(struct thread *td, struct linux_utimes_args *args) tvp = tv; } - error = kern_utimes(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE); + error = kern_utimesat(td, AT_FDCWD, fname, UIO_SYSSPACE, + tvp, UIO_SYSSPACE); LFREEPATH(fname); return (error); } @@ -914,13 +916,14 @@ linux_mknod(struct thread *td, struct linux_mknod_args *args) switch (args->mode & S_IFMT) { case S_IFIFO: case S_IFSOCK: - error = kern_mkfifo(td, path, UIO_SYSSPACE, args->mode); + error = kern_mkfifoat(td, AT_FDCWD, path, UIO_SYSSPACE, + args->mode); break; case S_IFCHR: case S_IFBLK: - error = kern_mknod(td, path, UIO_SYSSPACE, args->mode, - args->dev); + error = kern_mknodat(td, AT_FDCWD, path, UIO_SYSSPACE, + args->mode, args->dev); break; case S_IFDIR: @@ -931,7 +934,7 @@ linux_mknod(struct thread *td, struct linux_mknod_args *args) args->mode |= S_IFREG; /* FALLTHROUGH */ case S_IFREG: - error = kern_open(td, path, UIO_SYSSPACE, + error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, args->mode); if (error == 0) kern_close(td, td->td_retval[0]); diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 43b255d0dd6..61b786fef9f 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -731,7 +731,7 @@ linux_bind(struct thread *td, struct linux_bind_args *args) if (error) return (error); - error = kern_bind(td, args->s, sa); + error = kern_bindat(td, AT_FDCWD, args->s, sa); free(sa, M_SONAME); if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in)) return (EINVAL); @@ -759,7 +759,7 @@ linux_connect(struct thread *td, struct linux_connect_args *args) if (error) return (error); - error = kern_connect(td, args->s, sa); + error = kern_connectat(td, AT_FDCWD, args->s, sa); free(sa, M_SONAME); if (error != EISCONN) return (error); diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 2e05c8543c3..b6dd86dd6ad 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -77,7 +77,7 @@ linux_kern_statat(struct thread *td, int flag, int fd, char *path, enum uio_seg pathseg, struct stat *sbp) { - return (kern_statat_vnhook(td, flag, fd, path, pathseg, sbp, + return (kern_statat(td, flag, fd, path, pathseg, sbp, translate_vnhook_major_minor)); } diff --git a/sys/compat/linux/linux_uid16.c b/sys/compat/linux/linux_uid16.c index c5bf2ddb4f7..61f3030049e 100644 --- a/sys/compat/linux/linux_uid16.c +++ b/sys/compat/linux/linux_uid16.c @@ -121,8 +121,8 @@ linux_chown16(struct thread *td, struct linux_chown16_args *args) args->gid); LIN_SDT_PROBE1(uid16, linux_chown16, conv_path, path); - error = kern_chown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid), - CAST_NOCHG(args->gid)); + error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, + CAST_NOCHG(args->uid), CAST_NOCHG(args->gid), 0); LFREEPATH(path); LIN_SDT_PROBE1(uid16, linux_chown16, return, error); @@ -146,8 +146,8 @@ linux_lchown16(struct thread *td, struct linux_lchown16_args *args) args->gid); LIN_SDT_PROBE1(uid16, linux_lchown16, conv_path, path); - error = kern_lchown(td, path, UIO_SYSSPACE, CAST_NOCHG(args->uid), - CAST_NOCHG(args->gid)); + error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, + CAST_NOCHG(args->uid), CAST_NOCHG(args->gid), AT_SYMLINK_NOFOLLOW); LFREEPATH(path); LIN_SDT_PROBE1(uid16, linux_lchown16, return, error); diff --git a/sys/compat/svr4/svr4_fcntl.c b/sys/compat/svr4/svr4_fcntl.c index c604675285f..edcfcc1074e 100644 --- a/sys/compat/svr4/svr4_fcntl.c +++ b/sys/compat/svr4/svr4_fcntl.c @@ -390,7 +390,8 @@ svr4_sys_open(td, uap) CHECKALTEXIST(td, uap->path, &newpath); bsd_flags = svr4_to_bsd_flags(uap->flags); - error = kern_open(td, newpath, UIO_SYSSPACE, bsd_flags, uap->mode); + error = kern_openat(td, AT_FDCWD, newpath, UIO_SYSSPACE, bsd_flags, + uap->mode); free(newpath, M_TEMP); if (error) { @@ -450,8 +451,8 @@ svr4_sys_creat(td, uap) CHECKALTEXIST(td, uap->path, &newpath); - error = kern_open(td, newpath, UIO_SYSSPACE, O_WRONLY | O_CREAT | - O_TRUNC, uap->mode); + error = kern_openat(td, AT_FDCWD, newpath, UIO_SYSSPACE, + O_WRONLY | O_CREAT | O_TRUNC, uap->mode); free(newpath, M_TEMP); return (error); } @@ -494,7 +495,8 @@ svr4_sys_access(td, uap) int error; CHECKALTEXIST(td, uap->path, &newpath); - error = kern_access(td, newpath, UIO_SYSSPACE, uap->amode); + error = kern_accessat(td, AT_FDCWD, newpath, UIO_SYSSPACE, + 0, uap->amode); free(newpath, M_TEMP); return (error); } diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index 0db5453165f..9e9b020a832 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -653,10 +653,13 @@ svr4_mknod(td, retval, path, mode, dev) CHECKALTEXIST(td, path, &newpath); - if (S_ISFIFO(mode)) - error = kern_mkfifo(td, newpath, UIO_SYSSPACE, mode); - else - error = kern_mknod(td, newpath, UIO_SYSSPACE, mode, dev); + if (S_ISFIFO(mode)) { + error = kern_mkfifoat(td, AT_FDCWD, newpath, UIO_SYSSPACE, + mode); + } else { + error = kern_mknodat(td, AT_FDCWD, newpath, UIO_SYSSPACE, + mode, dev); + } free(newpath, M_TEMP); return (error); } diff --git a/sys/compat/svr4/svr4_stat.c b/sys/compat/svr4/svr4_stat.c index b6866425d54..6ed9873e775 100644 --- a/sys/compat/svr4/svr4_stat.c +++ b/sys/compat/svr4/svr4_stat.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -170,7 +171,7 @@ svr4_sys_stat(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_stat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -195,7 +196,8 @@ svr4_sys_lstat(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_lstat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, + UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -238,7 +240,7 @@ svr4_sys_xstat(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_stat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -265,7 +267,8 @@ svr4_sys_lxstat(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_lstat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, + UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -309,7 +312,7 @@ svr4_sys_stat64(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_stat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -335,7 +338,8 @@ svr4_sys_lstat64(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_lstat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, + UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -582,7 +586,8 @@ svr4_sys_utime(td, uap) tp = NULL; CHECKALTEXIST(td, uap->path, &path); - error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE); + error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE, + tp, UIO_SYSSPACE); free(path, M_TEMP); return (error); } @@ -597,7 +602,8 @@ svr4_sys_utimes(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_utimes(td, path, UIO_SYSSPACE, uap->tptr, UIO_USERSPACE); + error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE, + uap->tptr, UIO_USERSPACE); free(path, M_TEMP); return (error); } diff --git a/sys/compat/svr4/svr4_stream.c b/sys/compat/svr4/svr4_stream.c index 91c393f71a2..d287d5d3271 100644 --- a/sys/compat/svr4/svr4_stream.c +++ b/sys/compat/svr4/svr4_stream.c @@ -282,7 +282,8 @@ clean_pipe(td, path) struct stat st; int error; - error = kern_lstat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, + UIO_SYSSPACE, &st, NULL); /* * Make sure we are dealing with a mode 0 named pipe. @@ -293,7 +294,7 @@ clean_pipe(td, path) if ((st.st_mode & ALLPERMS) != 0) return (0); - error = kern_unlink(td, path, UIO_SYSSPACE); + error = kern_unlinkat(td, AT_FDCWD, path, UIO_SYSSPACE, 0); if (error) DPRINTF(("clean_pipe: unlink failed %d\n", error)); return (error); @@ -812,7 +813,7 @@ ti_bind(fp, fd, ioc, td) DPRINTF(("TI_BIND: fileno %d\n", fd)); - if ((error = kern_bind(td, fd, skp)) != 0) { + if ((error = kern_bindat(td, AT_FDCWD, fd, skp)) != 0) { DPRINTF(("TI_BIND: bind failed %d\n", error)); return error; } @@ -1586,7 +1587,7 @@ svr4_do_putmsg(td, uap, fp) case SVR4_TI_CONNECT_REQUEST: /* connect */ { - return (kern_connect(td, uap->fd, sa)); + return (kern_connectat(td, AT_FDCWD, uap->fd, sa)); } case SVR4_TI_SENDTO_REQUEST: /* sendto */ diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 45b38d9a69f..1436a3bc166 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -890,10 +890,7 @@ device gre device me options XBONEHACK -# The `faith' device captures packets sent to it and diverts them -# to the IPv4/IPv6 translation daemon. # The `stf' device implements 6to4 encapsulation. -device faith device stf # The pf packet filter consists of three devices: diff --git a/sys/conf/files b/sys/conf/files index adafa9c5907..cf40cf2b1e3 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -555,7 +555,6 @@ ddb/db_textdump.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb -#dev/dpt/dpt_control.c optional dpt dev/aac/aac.c optional aac dev/aac/aac_cam.c optional aacp aac dev/aac/aac_debug.c optional aac @@ -2774,7 +2773,7 @@ geom/eli/pkcs5v2.c optional geom_eli geom/gate/g_gate.c optional geom_gate geom/geom_aes.c optional geom_aes geom/geom_bsd.c optional geom_bsd -geom/geom_bsd_enc.c optional geom_bsd +geom/geom_bsd_enc.c optional geom_bsd | geom_part_bsd geom/geom_ccd.c optional ccd | geom_ccd geom/geom_ctl.c standard geom/geom_dev.c standard @@ -3229,7 +3228,6 @@ net/if_edsc.c optional edsc net/if_enc.c optional enc ipsec inet | enc ipsec inet6 net/if_epair.c optional epair net/if_ethersubr.c optional ether -net/if_faith.c optional faith net/if_fddisubr.c optional fddi net/if_fwsubr.c optional fwip net/if_gif.c optional gif inet | gif inet6 | \ diff --git a/sys/conf/kern.opts.mk b/sys/conf/kern.opts.mk index 8c7a0baac5d..16bb13447a7 100644 --- a/sys/conf/kern.opts.mk +++ b/sys/conf/kern.opts.mk @@ -79,6 +79,18 @@ MK_${var}:= no .if defined(WITHOUT_${var}_SUPPORT) || ${MK_${var}} == "no" MK_${var}_SUPPORT:= no .else +.if defined(KERNBUILDDIR) # See if there's an opt_foo.h +OPT_${var}!= cat ${KERNBUILDDIR}/opt_${var:tl}.h; echo +.if ${OPT_${var}} == "" # nothing -> no +MK_${var}_SUPPORT:= no +.else MK_${var}_SUPPORT:= yes .endif +.else # otherwise, yes +MK_${var}_SUPPORT:= yes +.endif +.endif .endfor + + + diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index f323a0da664..9b3b84b0618 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -52,7 +52,7 @@ else fi b=share/examples/etc/bsd-style-copyright -year=`date '+%Y'` +year=$(sed -Ee '/^Copyright .* The FreeBSD Project/!d;s/^.*1992-([0-9]*) .*$/\1/g' ${SYSDIR}/../COPYRIGHT) # look for copyright template for bsd_copyright in ../$b ../../$b ../../../$b /usr/src/$b /usr/$b do diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c index df6d15079f0..7a5d0d924b8 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c @@ -33,6 +33,9 @@ static const char rcsid[] = "@(#)$Id$"; #include #include # include +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 800000) +#include +#endif # include # include #if !defined(__hpux) @@ -52,6 +55,12 @@ static const char rcsid[] = "@(#)$Id$"; #include #include #include +#if defined(__FreeBSD_version) && (__FreeBSD_version >= 800000) +#include +#else +#define CURVNET_SET(arg) +#define CURVNET_RESTORE() +#endif #if defined(__osf__) # include #endif @@ -324,7 +333,9 @@ ipfioctl(dev, cmd, data, mode SPL_NET(s); + CURVNET_SET(TD_TO_VNET(p)); error = ipf_ioctlswitch(&ipfmain, unit, data, cmd, mode, p->p_uid, p); + CURVNET_RESTORE(); if (error != -1) { SPL_X(s); return error; diff --git a/sys/contrib/ngatm/netnatm/saal/saal_sscop.c b/sys/contrib/ngatm/netnatm/saal/saal_sscop.c index 75ce17db89f..0776eda9e4f 100644 --- a/sys/contrib/ngatm/netnatm/saal/saal_sscop.c +++ b/sys/contrib/ngatm/netnatm/saal/saal_sscop.c @@ -163,18 +163,17 @@ static void sscop_set_state(struct sscop *, u_int); } \ } while(0) - -#define QFIND(Q,RN) \ - ({ \ - struct sscop_msg *_msg = NULL, *_m; \ - MSGQ_FOREACH(_m, (Q)) { \ - if(_m->seqno == (RN)) { \ - _msg = _m; \ - break; \ - } \ - } \ - _msg; \ - }) +static inline struct sscop_msg *QFIND(sscop_msgq_head_t *q, u_int rn) +{ + struct sscop_msg *msg = NULL, *m; + MSGQ_FOREACH(m, q) { + if(m->seqno == rn) { + msg = m; + break; + } + } + return msg; +} #define QINSERT(Q,M) \ do { \ diff --git a/sys/crypto/rijndael/rijndael-api-fst.c b/sys/crypto/rijndael/rijndael-api-fst.c index 187177b39ff..bf7b4d14e6a 100644 --- a/sys/crypto/rijndael/rijndael-api-fst.c +++ b/sys/crypto/rijndael/rijndael-api-fst.c @@ -34,7 +34,8 @@ __FBSDID("$FreeBSD$"); typedef u_int8_t BYTE; -int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { +int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, + const char *keyMaterial) { u_int8_t cipherKey[RIJNDAEL_MAXKB]; if (key == NULL) { @@ -83,7 +84,7 @@ int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { } int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputLen, BYTE *outBuffer) { + const BYTE *input, int inputLen, BYTE *outBuffer) { int i, k, numBlocks; u_int8_t block[16], iv[4][4]; @@ -198,7 +199,7 @@ int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, * @return length in octets (not bits) of the encrypted output buffer. */ int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputOctets, BYTE *outBuffer) { + const BYTE *input, int inputOctets, BYTE *outBuffer) { int i, numBlocks, padLen; u_int8_t block[16], *iv, *cp; @@ -232,10 +233,10 @@ int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, case MODE_CBC: iv = cipher->IV; for (i = numBlocks; i > 0; i--) { - ((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0]; - ((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1]; - ((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2]; - ((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3]; + ((u_int32_t*)block)[0] = ((const u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0]; + ((u_int32_t*)block)[1] = ((const u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1]; + ((u_int32_t*)block)[2] = ((const u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2]; + ((u_int32_t*)block)[3] = ((const u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3]; rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); iv = outBuffer; input += 16; @@ -261,7 +262,7 @@ int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, } int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputLen, BYTE *outBuffer) { + const BYTE *input, int inputLen, BYTE *outBuffer) { int i, k, numBlocks; u_int8_t block[16], iv[4][4]; @@ -360,7 +361,7 @@ int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, } int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, - BYTE *input, int inputOctets, BYTE *outBuffer) { + const BYTE *input, int inputOctets, BYTE *outBuffer) { int i, numBlocks, padLen; u_int8_t block[16]; u_int32_t iv[4]; diff --git a/sys/crypto/rijndael/rijndael-api-fst.h b/sys/crypto/rijndael/rijndael-api-fst.h index 122bf52d6ce..e5f596ac75f 100644 --- a/sys/crypto/rijndael/rijndael-api-fst.h +++ b/sys/crypto/rijndael/rijndael-api-fst.h @@ -56,18 +56,18 @@ typedef struct { /* changed order of the components */ /* Function prototypes */ -int rijndael_makeKey(keyInstance *, u_int8_t, int, char *); +int rijndael_makeKey(keyInstance *, u_int8_t, int, const char *); int rijndael_cipherInit(cipherInstance *, u_int8_t, char *); -int rijndael_blockEncrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); -int rijndael_padEncrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); +int rijndael_blockEncrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); +int rijndael_padEncrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); -int rijndael_blockDecrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); -int rijndael_padDecrypt(cipherInstance *, keyInstance *, u_int8_t *, int, - u_int8_t *); +int rijndael_blockDecrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); +int rijndael_padDecrypt(cipherInstance *, keyInstance *, const u_int8_t *, + int, u_int8_t *); #endif /* __RIJNDAEL_API_FST_H */ diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 71fbe3226b6..0e8998b0949 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -694,7 +694,7 @@ acpi_attach(device_t dev) static void acpi_set_power_children(device_t dev, int state) { - device_t child, parent; + device_t child; device_t *devlist; int dstate, i, numdevs; @@ -705,12 +705,11 @@ acpi_set_power_children(device_t dev, int state) * Retrieve and set D-state for the sleep state if _SxD is present. * Skip children who aren't attached since they are handled separately. */ - parent = device_get_parent(dev); for (i = 0; i < numdevs; i++) { child = devlist[i]; dstate = state; if (device_is_attached(child) && - acpi_device_pwr_for_sleep(parent, dev, &dstate) == 0) + acpi_device_pwr_for_sleep(dev, child, &dstate) == 0) acpi_set_powerstate(child, dstate); } free(devlist, M_TEMP); diff --git a/sys/dev/agp/agp_i810.c b/sys/dev/agp/agp_i810.c index 9afd201d205..0db332bbec9 100644 --- a/sys/dev/agp/agp_i810.c +++ b/sys/dev/agp/agp_i810.c @@ -115,6 +115,8 @@ static int agp_sb_get_gtt_total_entries(device_t dev); static int agp_i810_install_gatt(device_t dev); static int agp_i830_install_gatt(device_t dev); +static int agp_i965_install_gatt(device_t dev); +static int agp_g4x_install_gatt(device_t dev); static void agp_i810_deinstall_gatt(device_t dev); static void agp_i830_deinstall_gatt(device_t dev); @@ -397,7 +399,7 @@ static const struct agp_i810_driver agp_i810_g965_driver = { .get_stolen_size = agp_i915_get_stolen_size, .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, .get_gtt_total_entries = agp_i965_get_gtt_total_entries, - .install_gatt = agp_i830_install_gatt, + .install_gatt = agp_i965_install_gatt, .deinstall_gatt = agp_i830_deinstall_gatt, .write_gtt = agp_i965_write_gtt, .install_gtt_pte = agp_i965_install_gtt_pte, @@ -466,7 +468,7 @@ static const struct agp_i810_driver agp_i810_g4x_driver = { .get_stolen_size = agp_i915_get_stolen_size, .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, .get_gtt_total_entries = agp_gen5_get_gtt_total_entries, - .install_gatt = agp_i830_install_gatt, + .install_gatt = agp_g4x_install_gatt, .deinstall_gatt = agp_i830_deinstall_gatt, .write_gtt = agp_g4x_write_gtt, .install_gtt_pte = agp_g4x_install_gtt_pte, @@ -489,7 +491,30 @@ static const struct agp_i810_driver agp_i810_sb_driver = { .get_stolen_size = agp_sb_get_stolen_size, .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, .get_gtt_total_entries = agp_sb_get_gtt_total_entries, - .install_gatt = agp_i830_install_gatt, + .install_gatt = agp_g4x_install_gatt, + .deinstall_gatt = agp_i830_deinstall_gatt, + .write_gtt = agp_sb_write_gtt, + .install_gtt_pte = agp_sb_install_gtt_pte, + .read_gtt_pte = agp_g4x_read_gtt_pte, + .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr, + .set_aperture = agp_i915_set_aperture, + .chipset_flush_setup = agp_i810_chipset_flush_setup, + .chipset_flush_teardown = agp_i810_chipset_flush_teardown, + .chipset_flush = agp_i810_chipset_flush, +}; + +static const struct agp_i810_driver agp_i810_hsw_driver = { + .chiptype = CHIP_SB, + .gen = 7, + .busdma_addr_mask_sz = 40, + .res_spec = agp_g4x_res_spec, + .check_active = agp_sb_check_active, + .set_desc = agp_i810_set_desc, + .dump_regs = agp_sb_dump_regs, + .get_stolen_size = agp_sb_get_stolen_size, + .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries, + .get_gtt_total_entries = agp_sb_get_gtt_total_entries, + .install_gatt = agp_g4x_install_gatt, .deinstall_gatt = agp_i830_deinstall_gatt, .write_gtt = agp_sb_write_gtt, .install_gtt_pte = agp_sb_install_gtt_pte, @@ -736,6 +761,41 @@ static const struct agp_i810_match { .name = "IvyBridge server GT2 IG", .driver = &agp_i810_sb_driver }, + { + .devid = 0x04028086, + .name = "Haswell desktop GT1", + .driver = &agp_i810_hsw_driver + }, + { + .devid = 0x04128086, + .name = "Haswell desktop GT2", + .driver = &agp_i810_hsw_driver + }, + { + .devid = 0x040a8086, + .name = "Haswell server GT1", + .driver = &agp_i810_hsw_driver + }, + { + .devid = 0x041a8086, + .name = "Haswell server GT2", + .driver = &agp_i810_hsw_driver + }, + { + .devid = 0x04068086, + .name = "Haswell mobile GT1", + .driver = &agp_i810_hsw_driver + }, + { + .devid = 0x04168086, + .name = "Haswell mobile GT2", + .driver = &agp_i810_hsw_driver + }, + { + .devid = 0x0c168086, + .name = "Haswell SDV", + .driver = &agp_i810_hsw_driver + }, { .devid = 0, } @@ -747,7 +807,8 @@ agp_i810_match(device_t dev) int i, devid; if (pci_get_class(dev) != PCIC_DISPLAY - || pci_get_subclass(dev) != PCIS_DISPLAY_VGA) + || (pci_get_subclass(dev) != PCIS_DISPLAY_VGA && + pci_get_subclass(dev) != PCIS_DISPLAY_OTHER)) return (NULL); devid = pci_get_devid(dev); @@ -1406,14 +1467,11 @@ agp_i810_install_gatt(device_t dev) return (0); } -static int -agp_i830_install_gatt(device_t dev) +static void +agp_i830_install_gatt_init(struct agp_i810_softc *sc) { - struct agp_i810_softc *sc; uint32_t pgtblctl; - sc = device_get_softc(dev); - /* * The i830 automatically initializes the 128k gatt on boot. * GATT address is already in there, make sure it's enabled. @@ -1423,9 +1481,45 @@ agp_i830_install_gatt(device_t dev) bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl); sc->gatt->ag_physical = pgtblctl & ~1; +} + +static int +agp_i830_install_gatt(device_t dev) +{ + struct agp_i810_softc *sc; + + sc = device_get_softc(dev); + agp_i830_install_gatt_init(sc); return (0); } +static int +agp_gen4_install_gatt(device_t dev, const vm_size_t gtt_offset) +{ + struct agp_i810_softc *sc; + + sc = device_get_softc(dev); + pmap_change_attr((vm_offset_t)rman_get_virtual(sc->sc_res[0]) + + gtt_offset, rman_get_size(sc->sc_res[0]) - gtt_offset, + VM_MEMATTR_WRITE_COMBINING); + agp_i830_install_gatt_init(sc); + return (0); +} + +static int +agp_i965_install_gatt(device_t dev) +{ + + return (agp_gen4_install_gatt(dev, 512 * 1024)); +} + +static int +agp_g4x_install_gatt(device_t dev) +{ + + return (agp_gen4_install_gatt(dev, 2 * 1024 * 1024)); +} + static int agp_i810_attach(device_t dev) { diff --git a/sys/dev/altera/pio/pio.c b/sys/dev/altera/pio/pio.c new file mode 100644 index 00000000000..af610ef25ea --- /dev/null +++ b/sys/dev/altera/pio/pio.c @@ -0,0 +1,215 @@ +/*- + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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. + */ + +/* + * Altera PIO (Parallel IO) device driver + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include "pio_if.h" + +#define READ4(_sc, _reg) bus_read_4((_sc)->res[0], _reg) +#define READ2(_sc, _reg) bus_read_2((_sc)->res[0], _reg) +#define READ1(_sc, _reg) bus_read_1((_sc)->res[0], _reg) +#define WRITE4(_sc, _reg, _val) bus_write_4((_sc)->res[0], _reg, _val) +#define WRITE2(_sc, _reg, _val) bus_write_2((_sc)->res[0], _reg, _val) +#define WRITE1(_sc, _reg, _val) bus_write_1((_sc)->res[0], _reg, _val) + +struct pio_softc { + struct resource *res[2]; + bus_space_tag_t bst; + bus_space_handle_t bsh; + device_t dev; + void *ih; +}; + +static struct resource_spec pio_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { -1, 0 } +}; + +static int +pio_setup_irq(device_t dev, void *intr_handler, void *ih_user) +{ + struct pio_softc *sc; + + sc = device_get_softc(dev); + + /* Setup interrupt handlers */ + if (bus_setup_intr(sc->dev, sc->res[1], INTR_TYPE_BIO | INTR_MPSAFE, + NULL, intr_handler, ih_user, &sc->ih)) { + device_printf(sc->dev, "Unable to setup intr\n"); + return (1); + } + + return (0); +} + +static int +pio_teardown_irq(device_t dev) +{ + struct pio_softc *sc; + + sc = device_get_softc(dev); + + bus_teardown_intr(sc->dev, sc->res[1], sc->ih); + + return (0); +} + +static int +pio_read(device_t dev) +{ + struct pio_softc *sc; + + sc = device_get_softc(dev); + + return (READ4(sc, PIO_DATA)); +} + +static int +pio_set(device_t dev, int bit, int enable) +{ + struct pio_softc *sc; + + sc = device_get_softc(dev); + + if (enable) + WRITE4(sc, PIO_OUTSET, bit); + else + WRITE4(sc, PIO_OUTCLR, bit); + + return (0); +} + +static int +pio_configure(device_t dev, int dir, int mask) +{ + struct pio_softc *sc; + + sc = device_get_softc(dev); + + WRITE4(sc, PIO_INT_MASK, mask); + WRITE4(sc, PIO_DIR, dir); + + return (0); +} + +static int +pio_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "altr,pio")) + return (ENXIO); + + device_set_desc(dev, "Altera PIO"); + return (BUS_PROBE_DEFAULT); +} + +static int +pio_attach(device_t dev) +{ + struct pio_softc *sc; + struct fdt_ic *fic; + phandle_t node; + + sc = device_get_softc(dev); + sc->dev = dev; + + if (bus_alloc_resources(dev, pio_spec, sc->res)) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + /* Memory interface */ + sc->bst = rman_get_bustag(sc->res[0]); + sc->bsh = rman_get_bushandle(sc->res[0]); + + WRITE4(sc, PIO_DATA, 0); + + if ((node = ofw_bus_get_node(sc->dev)) == -1) + return (ENXIO); + + fic = malloc(sizeof(*fic), M_DEVBUF, M_WAITOK|M_ZERO); + fic->iph = node; + fic->dev = dev; + SLIST_INSERT_HEAD(&fdt_ic_list_head, fic, fdt_ics); + + return (0); +} + +static device_method_t pio_methods[] = { + DEVMETHOD(device_probe, pio_probe), + DEVMETHOD(device_attach, pio_attach), + + /* pio_if.m */ + DEVMETHOD(pio_read, pio_read), + DEVMETHOD(pio_configure, pio_configure), + DEVMETHOD(pio_set, pio_set), + DEVMETHOD(pio_setup_irq, pio_setup_irq), + DEVMETHOD(pio_teardown_irq, pio_teardown_irq), + DEVMETHOD_END +}; + +static driver_t pio_driver = { + "altera_pio", + pio_methods, + sizeof(struct pio_softc), +}; + +static devclass_t pio_devclass; + +DRIVER_MODULE(altera_pio, simplebus, pio_driver, pio_devclass, 0, 0); diff --git a/lib/libc/posix1e/acl_size.c b/sys/dev/altera/pio/pio.h similarity index 66% rename from lib/libc/posix1e/acl_size.c rename to sys/dev/altera/pio/pio.h index 27ad6515c0f..710276fc816 100644 --- a/lib/libc/posix1e/acl_size.c +++ b/sys/dev/altera/pio/pio.h @@ -1,7 +1,11 @@ -/* - * Copyright (c) 2001-2002 Chris D. Faulhaber +/*- + * Copyright (c) 2014 Ruslan Bukin * All rights reserved. * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -14,7 +18,7 @@ * 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 AUTHOR OR CONTRIBUTORS BE LIABLE + * 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) @@ -22,22 +26,18 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. + * + * $FreeBSD$ */ -#include -__FBSDID("$FreeBSD$"); +#define PIO_DATA 0x00 +#define PIO_DIR 0x04 +#define PIO_OUT(n) (1 << n) +#define PIO_OUT_ALL 0xffffffff +#define PIO_INT_MASK 0x08 +#define PIO_UNMASK(n) (1 << n) +#define PIO_UNMASK_ALL 0xffffffff +#define PIO_EDGECAPT 0x0c +#define PIO_OUTSET 0x10 +#define PIO_OUTCLR 0x14 -#include -#include "namespace.h" -#include -#include "un-namespace.h" - -#include - -ssize_t -acl_size(acl_t acl) -{ - - errno = ENOSYS; - return (-1); -} diff --git a/sys/dev/altera/pio/pio_if.m b/sys/dev/altera/pio/pio_if.m new file mode 100644 index 00000000000..644afd622ba --- /dev/null +++ b/sys/dev/altera/pio/pio_if.m @@ -0,0 +1,65 @@ +#- +# Copyright (c) 2014 Ruslan Bukin +# All rights reserved. +# +# This software was developed by SRI International and the University of +# Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) +# ("CTSRD"), as part of the DARPA CRASH research programme. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include + +INTERFACE pio; + +# +# PIO device methods +# + +METHOD int read { + device_t dev; +}; + +METHOD int setup_irq { + device_t dev; + void *handler; + void *ih_user; +}; + +METHOD int teardown_irq { + device_t dev; +}; + +METHOD int set { + device_t dev; + int bit; + int enable; +}; + +METHOD int configure { + device_t dev; + int dir; + int mask; +} diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index af686f038b9..ab4f15e1082 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -1812,7 +1812,10 @@ ath_suspend(struct ath_softc *sc) */ ath_hal_intrset(sc->sc_ah, 0); taskqueue_block(sc->sc_tq); - callout_drain(&sc->sc_cal_ch); + + ATH_LOCK(sc); + callout_stop(&sc->sc_cal_ch); + ATH_UNLOCK(sc); /* * XXX ensure sc_invalid is 1 @@ -5599,6 +5602,8 @@ ath_calibrate(void *arg) HAL_BOOL aniCal, shortCal = AH_FALSE; int nextcal; + ATH_LOCK_ASSERT(sc); + /* * Force the hardware awake for ANI work. */ @@ -5888,12 +5893,17 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) * Now, wake the thing up. */ ath_power_set_power_state(sc, HAL_PM_AWAKE); + + /* + * And stop the calibration callout whilst we have + * ATH_LOCK held. + */ + callout_stop(&sc->sc_cal_ch); ATH_UNLOCK(sc); if (ostate == IEEE80211_S_CSA && nstate == IEEE80211_S_RUN) csa_run_transition = 1; - callout_drain(&sc->sc_cal_ch); ath_hal_setledstate(ah, leds[nstate]); /* set LED */ if (nstate == IEEE80211_S_SCAN) { @@ -6084,7 +6094,6 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) ATH_LOCK(sc); ath_power_setselfgen(sc, HAL_PM_AWAKE); ath_power_setpower(sc, HAL_PM_AWAKE); - ATH_UNLOCK(sc); /* * Finally, start any timers and the task q thread @@ -6097,6 +6106,7 @@ ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) DPRINTF(sc, ATH_DEBUG_CALIBRATE, "%s: calibration disabled\n", __func__); } + ATH_UNLOCK(sc); taskqueue_unblock(sc->sc_tq); } else if (nstate == IEEE80211_S_INIT) { @@ -6457,13 +6467,13 @@ ath_watchdog(void *arg) struct ath_softc *sc = arg; int do_reset = 0; + ATH_LOCK_ASSERT(sc); + if (sc->sc_wd_timer != 0 && --sc->sc_wd_timer == 0) { struct ifnet *ifp = sc->sc_ifp; uint32_t hangs; - ATH_LOCK(sc); ath_power_set_power_state(sc, HAL_PM_AWAKE); - ATH_UNLOCK(sc); if (ath_hal_gethangstate(sc->sc_ah, 0xffff, &hangs) && hangs != 0) { @@ -6475,9 +6485,7 @@ ath_watchdog(void *arg) if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); sc->sc_stats.ast_watchdog++; - ATH_LOCK(sc); ath_power_restore_power_state(sc); - ATH_UNLOCK(sc); } /* diff --git a/sys/dev/beri/virtio/virtio_mmio_platform.c b/sys/dev/beri/virtio/virtio_mmio_platform.c new file mode 100644 index 00000000000..41c50f8f844 --- /dev/null +++ b/sys/dev/beri/virtio/virtio_mmio_platform.c @@ -0,0 +1,227 @@ +/*- + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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. + */ + +/* + * BERI interface for Virtio MMIO bus. + * + * This driver provides interrupt-engine for software-implemented + * Virtio MMIO backend. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "virtio_mmio_if.h" +#include "pio_if.h" + +static void platform_intr(void *arg); + +struct virtio_mmio_platform_softc { + struct resource *res[1]; + bus_space_tag_t bst; + bus_space_handle_t bsh; + device_t dev; + void (*intr_handler)(void *); + void *ih_user; + device_t pio_recv; + device_t pio_send; +}; + +static int +setup_pio(struct virtio_mmio_platform_softc *sc, char *name, device_t *dev) +{ + phandle_t pio_node; + struct fdt_ic *ic; + phandle_t xref; + phandle_t node; + + if ((node = ofw_bus_get_node(sc->dev)) == -1) + return (ENXIO); + + if (OF_searchencprop(node, name, &xref, + sizeof(xref)) == -1) { + return (ENXIO); + } + + pio_node = OF_node_from_xref(xref); + SLIST_FOREACH(ic, &fdt_ic_list_head, fdt_ics) { + if (ic->iph == pio_node) { + *dev = ic->dev; + PIO_CONFIGURE(*dev, PIO_OUT_ALL, + PIO_UNMASK_ALL); + return (0); + } + } + + return (ENXIO); +} + +static int +virtio_mmio_platform_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "beri,virtio_mmio_platform")) + return (ENXIO); + + device_set_desc(dev, "Virtio MMIO platform"); + return (BUS_PROBE_DEFAULT); +} + +static int +virtio_mmio_platform_attach(device_t dev) +{ + struct virtio_mmio_platform_softc *sc; + struct fdt_ic *fic; + phandle_t node; + + sc = device_get_softc(dev); + sc->dev = dev; + + if (setup_pio(sc, "pio-send", &sc->pio_send) != 0) + return (ENXIO); + if (setup_pio(sc, "pio-recv", &sc->pio_recv) != 0) + return (ENXIO); + + if ((node = ofw_bus_get_node(sc->dev)) == -1) + return (ENXIO); + + fic = malloc(sizeof(*fic), M_DEVBUF, M_WAITOK|M_ZERO); + fic->iph = node; + fic->dev = dev; + SLIST_INSERT_HEAD(&fdt_ic_list_head, fic, fdt_ics); + + return (0); +} + +static int +platform_note(device_t dev, size_t offset) +{ + struct virtio_mmio_platform_softc *sc; + + sc = device_get_softc(dev); + + if (offset == VIRTIO_MMIO_QUEUE_NOTIFY) { + mips_dcache_wbinv_all(); + PIO_SET(sc->pio_send, Q_NOTIFY, 1); + } + + if (offset == VIRTIO_MMIO_QUEUE_PFN) { + mips_dcache_wbinv_all(); + PIO_SET(sc->pio_send, Q_PFN, 1); + } + + return (0); +} + +static void +platform_intr(void *arg) +{ + struct virtio_mmio_platform_softc *sc; + int reg; + + sc = arg; + + /* Read pending */ + reg = PIO_READ(sc->pio_recv); + + /* Ack */ + PIO_SET(sc->pio_recv, reg, 0); + + /* Writeback, invalidate cache */ + mips_dcache_wbinv_all(); + + if (sc->intr_handler != NULL) + sc->intr_handler(sc->ih_user); +} + +static int +platform_setup_intr(device_t dev, device_t mmio_dev, + void *intr_handler, void *ih_user) +{ + struct virtio_mmio_platform_softc *sc; + + sc = device_get_softc(dev); + + sc->intr_handler = intr_handler; + sc->ih_user = ih_user; + + PIO_SETUP_IRQ(sc->pio_recv, platform_intr, sc); + + return (0); +} + +static device_method_t virtio_mmio_platform_methods[] = { + DEVMETHOD(device_probe, virtio_mmio_platform_probe), + DEVMETHOD(device_attach, virtio_mmio_platform_attach), + + /* virtio_mmio_if.h */ + DEVMETHOD(virtio_mmio_note, platform_note), + DEVMETHOD(virtio_mmio_setup_intr, platform_setup_intr), + DEVMETHOD_END +}; + +static driver_t virtio_mmio_platform_driver = { + "virtio_mmio_platform", + virtio_mmio_platform_methods, + sizeof(struct virtio_mmio_platform_softc), +}; + +static devclass_t virtio_mmio_platform_devclass; + +DRIVER_MODULE(virtio_mmio_platform, simplebus, virtio_mmio_platform_driver, + virtio_mmio_platform_devclass, 0, 0); diff --git a/sys/sys/sf_base.h b/sys/dev/beri/virtio/virtio_mmio_platform.h similarity index 79% rename from sys/sys/sf_base.h rename to sys/dev/beri/virtio/virtio_mmio_platform.h index 7c8d49cde4f..d996449ef5a 100644 --- a/sys/sys/sf_base.h +++ b/sys/dev/beri/virtio/virtio_mmio_platform.h @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2013 Adrian Chadd + * Copyright (c) 2014 Ruslan Bukin * All rights reserved. * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -26,12 +30,6 @@ * $FreeBSD$ */ -#ifndef _SYS_SF_BASE_H_ -#define _SYS_SF_BASE_H_ - -extern int _do_sendfile(struct thread *, int src_fd, int sock_fd, int flags, - int compat, off_t offset, size_t nbytes, off_t *sbytes, - struct uio *hdr_uio, struct uio *trl_uio, - struct sf_hdtr_kq *hdtr_kq); - -#endif /* _SYS_SF_BASE_H_ */ +#define Q_NOTIFY 0x1 +#define Q_PFN 0x2 +#define Q_INTR 0x4 diff --git a/sys/dev/ct/bshw_machdep.c b/sys/dev/ct/bshw_machdep.c index ba89e559cdb..046aa7d9430 100644 --- a/sys/dev/ct/bshw_machdep.c +++ b/sys/dev/ct/bshw_machdep.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -328,7 +329,7 @@ bshw_smit_xfer_start(struct ct_softc *ct) break; count = (datalen > LC_FSZ ? LC_FSZ : datalen); - bus_space_read_region_4(chp->ch_memt, chp->ch_memh, + bus_read_region_4(chp->ch_mem, LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2); data += count; datalen -= count; @@ -354,7 +355,7 @@ bshw_smit_xfer_start(struct ct_softc *ct) } count = (datalen > LC_SFSZ ? LC_SFSZ : datalen); - bus_space_write_region_4(chp->ch_memt, chp->ch_memh, + bus_write_region_4(chp->ch_mem, LC_SMIT_OFFSET, (u_int32_t *) data, count >> 2); data += count; datalen -= count; @@ -363,7 +364,7 @@ bshw_smit_xfer_start(struct ct_softc *ct) break; count = (datalen > LC_REST ? LC_REST : datalen); - bus_space_write_region_4(chp->ch_memt, chp->ch_memh, + bus_write_region_4(chp->ch_mem, LC_SMIT_OFFSET + LC_SFSZ, (u_int32_t *) data, count >> 2); data += count; diff --git a/sys/dev/ct/ct.c b/sys/dev/ct/ct.c index 1d3f0db1c3a..6a96c9c486e 100644 --- a/sys/dev/ct/ct.c +++ b/sys/dev/ct/ct.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -140,6 +141,7 @@ static int ct_unbusy(struct ct_softc *); static void ct_attention(struct ct_softc *); static struct ct_synch_data *ct_make_synch_table(struct ct_softc *); static int ct_catch_intr(struct ct_softc *); +static int ct_poll(void *); struct scsi_low_funcs ct_funcs = { SC_LOW_INIT_T ct_world_start, @@ -155,7 +157,7 @@ struct scsi_low_funcs ct_funcs = { SC_LOW_MSG_T ct_msg, SC_LOW_TIMEOUT_T NULL, - SC_LOW_POLL_T ctintr, + SC_LOW_POLL_T ct_poll, NULL, /* SC_LOW_POWER_T cthw_power, */ }; @@ -876,8 +878,19 @@ ct_catch_intr(struct ct_softc *ct) return EJUSTRETURN; } -int +void ctintr(void *arg) +{ + struct ct_softc *ct = arg; + struct scsi_low_softc *slp = &ct->sc_sclow; + + SCSI_LOW_LOCK(slp); + ct_poll(ct); + SCSI_LOW_UNLOCK(slp); +} + +static int +ct_poll(void *arg) { struct ct_softc *ct = arg; struct scsi_low_softc *slp = &ct->sc_sclow; diff --git a/sys/dev/ct/ct_isa.c b/sys/dev/ct/ct_isa.c index d17af235846..444d9f75b10 100644 --- a/sys/dev/ct/ct_isa.c +++ b/sys/dev/ct/ct_isa.c @@ -137,8 +137,7 @@ ct_isa_match(device_t dev) return ENXIO; bzero(&ch, sizeof(ch)); - ch.ch_iot = rman_get_bustag(port_res); - ch.ch_ioh = rman_get_bushandle(port_res), + ch.ch_io = port_res; ch.ch_bus_weight = ct_isa_bus_access_weight; rv = ctprobesubr(&ch, 0, BSHW_DEFAULT_HOSTID, @@ -159,7 +158,7 @@ ct_isa_match(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, 0, mem_res); if (rv != 0) - return 0; + return (BUS_PROBE_DEFAULT); return ENXIO; } @@ -175,7 +174,6 @@ ct_isa_attach(device_t dev) int irq_rid, drq_rid, chiprev; u_int8_t *vaddr; bus_addr_t addr; - intrmask_t s; hw = ct_find_hw(dev); if (ct_space_map(dev, hw, &ct->port_res, &ct->mem_res) != 0) { @@ -183,13 +181,8 @@ ct_isa_attach(device_t dev) return ENXIO; } - bzero(chp, sizeof(*chp)); - chp->ch_iot = rman_get_bustag(ct->port_res); - chp->ch_ioh = rman_get_bushandle(ct->port_res); - if (ct->mem_res) { - chp->ch_memt = rman_get_bustag(ct->mem_res); - chp->ch_memh = rman_get_bushandle(ct->mem_res); - } + chp->ch_io = ct->port_res; + chp->ch_mem = ct->mem_res; chp->ch_bus_weight = ct_isa_bus_access_weight; irq_rid = 0; @@ -254,7 +247,7 @@ ct_isa_attach(device_t dev) ct->ct_synch_setup = bshw_synch_setup; ct->sc_xmode = CT_XMODE_DMA; - if (chp->ch_memh != NULL) + if (chp->ch_mem != NULL) ct->sc_xmode |= CT_XMODE_PIO; ct->sc_chiprev = chiprev; @@ -297,13 +290,12 @@ ct_isa_attach(device_t dev) slp->sl_dev = dev; slp->sl_hostid = bs->sc_hostid; slp->sl_cfgflags = device_get_flags(dev); + mtx_init(&slp->sl_lock, "ct", NULL, MTX_DEF); - s = splcam(); ctattachsubr(ct); - splx(s); - if (bus_setup_intr(dev, ct->irq_res, INTR_TYPE_CAM, - NULL, (driver_intr_t *)ctintr, ct, &ct->sc_ih)) { + if (bus_setup_intr(dev, ct->irq_res, INTR_TYPE_CAM | INTR_MPSAFE, + NULL, ctintr, ct, &ct->sc_ih)) { ct_space_unmap(dev, ct); return ENXIO; } @@ -326,7 +318,7 @@ ct_space_map(device_t dev, struct bshw *hw, *memhp = NULL; port_rid = 0; - *iohp = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0, ~0, + *iohp = bus_alloc_resource(dev, SYS_RES_IOPORT, &port_rid, 0ul, ~0ul, BSHW_IOSZ, RF_ACTIVE); if (*iohp == NULL) return ENXIO; @@ -335,7 +327,7 @@ ct_space_map(device_t dev, struct bshw *hw, return 0; mem_rid = 0; - *memhp = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid, 0, ~0, + *memhp = bus_alloc_resource(dev, SYS_RES_MEMORY, &mem_rid, 0ul, ~0ul, BSHW_MEMSZ, RF_ACTIVE); if (*memhp == NULL) { bus_release_resource(dev, SYS_RES_IOPORT, port_rid, *iohp); diff --git a/sys/dev/ct/ct_machdep.h b/sys/dev/ct/ct_machdep.h index a6b8b155198..7d92526125e 100644 --- a/sys/dev/ct/ct_machdep.h +++ b/sys/dev/ct/ct_machdep.h @@ -94,7 +94,7 @@ ct_stat_read_1(struct ct_bus_access_handle *chp) { u_int8_t regv; - regv = bus_space_read_1(chp->ch_iot, chp->ch_ioh, stat_port); + regv = bus_read_1(chp->ch_io, stat_port); CT_BUS_WEIGHT(chp) return regv; } @@ -102,33 +102,29 @@ ct_stat_read_1(struct ct_bus_access_handle *chp) static __inline void cthw_set_count(struct ct_bus_access_handle *chp, u_int count) { - bus_space_tag_t bst = chp->ch_iot; - bus_space_handle_t bsh = chp->ch_ioh; - bus_space_write_1(bst, bsh, addr_port, wd3s_cnt); + bus_write_1(chp->ch_io, addr_port, wd3s_cnt); CT_BUS_WEIGHT(chp) - bus_space_write_1(bst, bsh, ctrl_port, count >> 16); + bus_write_1(chp->ch_io, ctrl_port, count >> 16); CT_BUS_WEIGHT(chp) - bus_space_write_1(bst, bsh, ctrl_port, count >> 8); + bus_write_1(chp->ch_io, ctrl_port, count >> 8); CT_BUS_WEIGHT(chp) - bus_space_write_1(bst, bsh, ctrl_port, count); + bus_write_1(chp->ch_io, ctrl_port, count); CT_BUS_WEIGHT(chp) } static __inline u_int cthw_get_count(struct ct_bus_access_handle *chp) { - bus_space_tag_t bst = chp->ch_iot; - bus_space_handle_t bsh = chp->ch_ioh; u_int count; - bus_space_write_1(bst, bsh, addr_port, wd3s_cnt); + bus_write_1(chp->ch_io, addr_port, wd3s_cnt); CT_BUS_WEIGHT(chp) - count = (((u_int) bus_space_read_1(bst, bsh, ctrl_port)) << 16); + count = (((u_int) bus_read_1(chp->ch_io, ctrl_port)) << 16); CT_BUS_WEIGHT(chp) - count += (((u_int) bus_space_read_1(bst, bsh, ctrl_port)) << 8); + count += (((u_int) bus_read_1(chp->ch_io, ctrl_port)) << 8); CT_BUS_WEIGHT(chp) - count += ((u_int) bus_space_read_1(bst, bsh, ctrl_port)); + count += ((u_int) bus_read_1(chp->ch_io, ctrl_port)); CT_BUS_WEIGHT(chp) return count; } @@ -136,15 +132,13 @@ cthw_get_count(struct ct_bus_access_handle *chp) static __inline void ct_write_cmds(struct ct_bus_access_handle *chp, u_int8_t *cmd, int len) { - bus_space_tag_t bst = chp->ch_iot; - bus_space_handle_t bsh = chp->ch_ioh; int i; - bus_space_write_1(bst, bsh, addr_port, wd3s_cdb); + bus_write_1(chp->ch_io, addr_port, wd3s_cdb); CT_BUS_WEIGHT(chp) for (i = 0; i < len; i ++) { - bus_space_write_1(bst, bsh, ctrl_port, cmd[i]); + bus_write_1(chp->ch_io, ctrl_port, cmd[i]); CT_BUS_WEIGHT(chp) } } @@ -152,13 +146,11 @@ ct_write_cmds(struct ct_bus_access_handle *chp, u_int8_t *cmd, int len) static __inline u_int8_t ct_cr_read_1(struct ct_bus_access_handle *chp, bus_addr_t offs) { - bus_space_tag_t bst = chp->ch_iot; - bus_space_handle_t bsh = chp->ch_ioh; u_int8_t regv; - bus_space_write_1(bst, bsh, addr_port, offs); + bus_write_1(chp->ch_io, addr_port, offs); CT_BUS_WEIGHT(chp) - regv = bus_space_read_1(bst, bsh, ctrl_port); + regv = bus_read_1(chp->ch_io, ctrl_port); CT_BUS_WEIGHT(chp) return regv; } @@ -166,12 +158,10 @@ ct_cr_read_1(struct ct_bus_access_handle *chp, bus_addr_t offs) static __inline void ct_cr_write_1(struct ct_bus_access_handle *chp, bus_addr_t offs, u_int8_t val) { - bus_space_tag_t bst = chp->ch_iot; - bus_space_handle_t bsh = chp->ch_ioh; - bus_space_write_1(bst, bsh, addr_port, offs); + bus_write_1(chp->ch_io, addr_port, offs); CT_BUS_WEIGHT(chp) - bus_space_write_1(bst, bsh, ctrl_port, val); + bus_write_1(chp->ch_io, ctrl_port, val); CT_BUS_WEIGHT(chp) } @@ -180,7 +170,7 @@ ct_cmdp_read_1(struct ct_bus_access_handle *chp) { u_int8_t regv; - regv = bus_space_read_1(chp->ch_iot, chp->ch_ioh, cmd_port); + regv = bus_read_1(chp->ch_io, cmd_port); CT_BUS_WEIGHT(chp) return regv; } @@ -189,7 +179,7 @@ static __inline void ct_cmdp_write_1(struct ct_bus_access_handle *chp, u_int8_t val) { - bus_space_write_1(chp->ch_iot, chp->ch_ioh, cmd_port, val); + bus_write_1(chp->ch_io, cmd_port, val); CT_BUS_WEIGHT(chp) } diff --git a/sys/dev/ct/ctvar.h b/sys/dev/ct/ctvar.h index 052542ea2d2..10ce2d89120 100644 --- a/sys/dev/ct/ctvar.h +++ b/sys/dev/ct/ctvar.h @@ -44,15 +44,8 @@ * Host adapter structure *****************************************************************/ struct ct_bus_access_handle { - bus_space_tag_t ch_iot; /* core chip ctrl port tag */ - bus_space_tag_t ch_delayt; /* delay port tag */ - bus_space_tag_t ch_datat; /* data port tag (pio) */ - bus_space_tag_t ch_memt; /* data port tag (shm) */ - - bus_space_handle_t ch_ioh; - bus_space_handle_t ch_delaybah; - bus_space_handle_t ch_datah; - bus_space_handle_t ch_memh; + struct resource *ch_io; /* core chip ctrl port */ + struct resource *ch_mem; /* data port (shm) */ void (*ch_bus_weight)(struct ct_bus_access_handle *); @@ -132,5 +125,5 @@ struct ct_targ_info { *****************************************************************/ int ctprobesubr(struct ct_bus_access_handle *, u_int, int, u_int, int *); void ctattachsubr(struct ct_softc *); -int ctintr(void *); +void ctintr(void *); #endif /* !_CTVAR_H_ */ diff --git a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c index 4d1a74d0560..fc79aefa4a6 100644 --- a/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c +++ b/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.c @@ -1490,11 +1490,11 @@ process_data(struct iwch_ep *ep) process_mpa_request(ep); break; default: - if (ep->com.so->so_rcv.sb_cc) + if (sbavail(&ep->com.so->so_rcv)) printf("%s Unexpected streaming data." " ep %p state %d so %p so_state %x so_rcv.sb_cc %u so_rcv.sb_mb %p\n", __FUNCTION__, ep, state_read(&ep->com), ep->com.so, ep->com.so->so_state, - ep->com.so->so_rcv.sb_cc, ep->com.so->so_rcv.sb_mb); + sbavail(&ep->com.so->so_rcv), ep->com.so->so_rcv.sb_mb); break; } return; diff --git a/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c b/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c index 6a998dd6673..413da4dbc27 100644 --- a/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c +++ b/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c @@ -446,8 +446,8 @@ t3_push_frames(struct socket *so, int req_completion) * Autosize the send buffer. */ if (snd->sb_flags & SB_AUTOSIZE && VNET(tcp_do_autosndbuf)) { - if (snd->sb_cc >= (snd->sb_hiwat / 8 * 7) && - snd->sb_cc < VNET(tcp_autosndbuf_max)) { + if (sbused(snd) >= (snd->sb_hiwat / 8 * 7) && + sbused(snd) < VNET(tcp_autosndbuf_max)) { if (!sbreserve_locked(snd, min(snd->sb_hiwat + VNET(tcp_autosndbuf_inc), VNET(tcp_autosndbuf_max)), so, curthread)) @@ -598,10 +598,10 @@ t3_rcvd(struct toedev *tod, struct tcpcb *tp) INP_WLOCK_ASSERT(inp); SOCKBUF_LOCK(so_rcv); - KASSERT(toep->tp_enqueued >= so_rcv->sb_cc, - ("%s: so_rcv->sb_cc > enqueued", __func__)); - toep->tp_rx_credits += toep->tp_enqueued - so_rcv->sb_cc; - toep->tp_enqueued = so_rcv->sb_cc; + KASSERT(toep->tp_enqueued >= sbused(so_rcv), + ("%s: sbused(so_rcv) > enqueued", __func__)); + toep->tp_rx_credits += toep->tp_enqueued - sbused(so_rcv); + toep->tp_enqueued = sbused(so_rcv); SOCKBUF_UNLOCK(so_rcv); must_send = toep->tp_rx_credits + 16384 >= tp->rcv_wnd; @@ -1782,7 +1782,7 @@ wr_ack(struct toepcb *toep, struct mbuf *m) so_sowwakeup_locked(so); } - if (snd->sb_sndptroff < snd->sb_cc) + if (snd->sb_sndptroff < sbused(snd)) t3_push_frames(so, 0); out_free: diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index 7a88462a2c5..820354ab696 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -238,6 +238,7 @@ struct vpd_params { struct pci_params { unsigned int vpd_cap_addr; + unsigned int mps; unsigned short speed; unsigned short width; }; diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index d81f45ee8e8..2d5d79d752f 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -5420,6 +5420,10 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) } lc = &pi->link_cfg; + if (mod != pi->mod_type) { + pi->mod_type = mod; + t4_os_portmod_changed(adap, i); + } if (link_ok != lc->link_ok || speed != lc->speed || fc != lc->fc) { /* something changed */ int reason; @@ -5435,10 +5439,6 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) lc->supported = ntohs(p->u.info.pcap); t4_os_link_changed(adap, i, link_ok, reason); } - if (mod != pi->mod_type) { - pi->mod_type = mod; - t4_os_portmod_changed(adap, i); - } } else { CH_WARN_RATELIMIT(adap, "Unknown firmware reply 0x%x (0x%x)\n", opcode, action); diff --git a/sys/dev/cxgbe/firmware/t4fw_cfg.txt b/sys/dev/cxgbe/firmware/t4fw_cfg.txt index 81d7df2466d..f417abb6a7e 100644 --- a/sys/dev/cxgbe/firmware/t4fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t4fw_cfg.txt @@ -28,8 +28,8 @@ tp_ntxch = 0 # TP rx and tx payload memory (% of the total EDRAM + DDR3). - tp_pmrx = 38 - tp_pmtx = 60 + tp_pmrx = 38, 512 + tp_pmtx = 60, 512 tp_pmrx_pagesize = 64K tp_pmtx_pagesize = 64K @@ -160,7 +160,7 @@ [fini] version = 0x1 - checksum = 0x6a1f8858 + checksum = 0xb4168add # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt b/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt index 2690edd1e6f..95fc7b1eae6 100644 --- a/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt +++ b/sys/dev/cxgbe/firmware/t4fw_cfg_uwire.txt @@ -125,7 +125,7 @@ # Percentage of dynamic memory (in either the EDRAM or external MEM) # to use for TP RX payload - tp_pmrx = 34 + tp_pmrx = 34, 512 # TP RX payload page size tp_pmrx_pagesize = 64K @@ -135,7 +135,7 @@ # Percentage of dynamic memory (in either the EDRAM or external MEM) # to use for TP TX payload - tp_pmtx = 32 + tp_pmtx = 32, 512 # TP TX payload page size tp_pmtx_pagesize = 64K @@ -544,7 +544,7 @@ [fini] version = 0x14250012 - checksum = 0xd9ae0325 + checksum = 0x22f592a9 # Total resources used by above allocations: # Virtual Interfaces: 104 diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg.txt b/sys/dev/cxgbe/firmware/t5fw_cfg.txt index 51b9129bbde..59ca453066f 100644 --- a/sys/dev/cxgbe/firmware/t5fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t5fw_cfg.txt @@ -37,8 +37,8 @@ tp_ntxch = 0 # TP rx and tx payload memory (% of the total EDRAM + DDR3). - tp_pmrx = 38 - tp_pmtx = 60 + tp_pmrx = 38, 512 + tp_pmtx = 60, 512 tp_pmrx_pagesize = 64K tp_pmtx_pagesize = 64K @@ -173,7 +173,7 @@ [fini] version = 0x1 - checksum = 0xa0ee1715 + checksum = 0x4f45e608 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt b/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt index eb4ed4b205c..e1c8b000815 100644 --- a/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt +++ b/sys/dev/cxgbe/firmware/t5fw_cfg_fpga.txt @@ -149,7 +149,7 @@ # Percentage of dynamic memory (in either the EDRAM or external MEM) # to use for TP RX payload - tp_pmrx = 30 + tp_pmrx = 30, 512 # TP RX payload page size tp_pmrx_pagesize = 64K @@ -159,7 +159,7 @@ # Percentage of dynamic memory (in either the EDRAM or external MEM) # to use for TP TX payload - tp_pmtx = 50 + tp_pmtx = 50, 512 # TP TX payload page size tp_pmtx_pagesize = 64K @@ -463,7 +463,7 @@ [fini] version = 0x1425000d - checksum = 0xe56cb999 + checksum = 0x22f1530b # Total resources used by above allocations: # Virtual Interfaces: 104 diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt b/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt index 3a3d2a938c0..a3c4482e668 100644 --- a/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt +++ b/sys/dev/cxgbe/firmware/t5fw_cfg_uwire.txt @@ -153,7 +153,7 @@ # Percentage of dynamic memory (in either the EDRAM or external MEM) # to use for TP RX payload - tp_pmrx = 30 + tp_pmrx = 30, 512 # TP RX payload page size tp_pmrx_pagesize = 64K @@ -163,7 +163,7 @@ # Percentage of dynamic memory (in either the EDRAM or external MEM) # to use for TP TX payload - tp_pmtx = 50 + tp_pmtx = 50, 512 # TP TX payload page size tp_pmtx_pagesize = 64K @@ -587,7 +587,7 @@ [fini] version = 0x14250016 - checksum = 0x5d740273 + checksum = 0xafaf8723 # Total resources used by above allocations: # Virtual Interfaces: 104 diff --git a/sys/dev/cxgbe/iw_cxgbe/cm.c b/sys/dev/cxgbe/iw_cxgbe/cm.c index b47f16981b3..a997b824a8f 100644 --- a/sys/dev/cxgbe/iw_cxgbe/cm.c +++ b/sys/dev/cxgbe/iw_cxgbe/cm.c @@ -565,8 +565,8 @@ process_data(struct c4iw_ep *ep) { struct sockaddr_in *local, *remote; - CTR5(KTR_IW_CXGBE, "%s: so %p, ep %p, state %s, sb_cc %d", __func__, - ep->com.so, ep, states[ep->com.state], ep->com.so->so_rcv.sb_cc); + CTR5(KTR_IW_CXGBE, "%s: so %p, ep %p, state %s, sbused %d", __func__, + ep->com.so, ep, states[ep->com.state], sbused(&ep->com.so->so_rcv)); switch (state_read(&ep->com)) { case MPA_REQ_SENT: @@ -582,11 +582,11 @@ process_data(struct c4iw_ep *ep) process_mpa_request(ep); break; default: - if (ep->com.so->so_rcv.sb_cc) - log(LOG_ERR, "%s: Unexpected streaming data. " - "ep %p, state %d, so %p, so_state 0x%x, sb_cc %u\n", + if (sbused(&ep->com.so->so_rcv)) + log(LOG_ERR, "%s: Unexpected streaming data. ep %p, " + "state %d, so %p, so_state 0x%x, sbused %u\n", __func__, ep, state_read(&ep->com), ep->com.so, - ep->com.so->so_state, ep->com.so->so_rcv.sb_cc); + ep->com.so->so_state, sbused(&ep->com.so->so_rcv)); break; } } @@ -2090,9 +2090,11 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) ep->com.thread); if (!err) { - CTR2(KTR_IW_CXGBE, "%s:cca %p", __func__, ep); goto out; + } else { + close_socket(&ep->com, 0); + goto fail2; } fail3: diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 475845b27a9..f9caf2eec1d 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -490,6 +490,7 @@ struct { {0x5411, "Chelsio T520-LL-CR"}, /* 2 x 10G */ {0x5412, "Chelsio T560-CR"}, /* 1 x 40G, 2 x 10G */ {0x5414, "Chelsio T580-LP-SO-CR"}, /* 2 x 40G, nomem */ + {0x5415, "Chelsio T502-BT"}, /* 2 x 1G */ #ifdef notyet {0x5404, "Chelsio T520-BCH"}, {0x5405, "Chelsio T540-BCH"}, @@ -593,6 +594,8 @@ t4_attach(device_t dev) v = pci_read_config(dev, i + PCIER_DEVICE_CTL, 2); v |= PCIEM_CTL_RELAXED_ORD_ENABLE; pci_write_config(dev, i + PCIER_DEVICE_CTL, v, 2); + + sc->params.pci.mps = 128 << ((v & PCIEM_CTL_MAX_PAYLOAD) >> 5); } sc->traceq = -1; @@ -1589,7 +1592,9 @@ cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) struct ifmedia *media = NULL; struct ifmedia_entry *cur; int speed = pi->link_cfg.speed; +#ifdef INVARIANTS int data = (pi->port_type << 8) | pi->mod_type; +#endif if (ifp == pi->ifp) media = &pi->media; @@ -1600,10 +1605,7 @@ cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) MPASS(media != NULL); cur = media->ifm_cur; - if (cur->ifm_data != data) { - build_medialist(pi, media); - cur = media->ifm_cur; - } + MPASS(cur->ifm_data == data); ifmr->ifm_status = IFM_AVALID; if (!pi->link_cfg.link_ok) @@ -8004,6 +8006,11 @@ t4_os_portmod_changed(const struct adapter *sc, int idx) NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM" }; + build_medialist(pi, &pi->media); +#ifdef DEV_NETMAP + build_medialist(pi, &pi->nm_media); +#endif + if (pi->mod_type == FW_PORT_MOD_TYPE_NONE) if_printf(pi->ifp, "transceiver unplugged.\n"); else if (pi->mod_type == FW_PORT_MOD_TYPE_UNKNOWN) diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 9af2248dede..29e5fa243be 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -365,15 +365,15 @@ t4_rcvd(struct toedev *tod, struct tcpcb *tp) INP_WLOCK_ASSERT(inp); SOCKBUF_LOCK(sb); - KASSERT(toep->sb_cc >= sb->sb_cc, + KASSERT(toep->sb_cc >= sbused(sb), ("%s: sb %p has more data (%d) than last time (%d).", - __func__, sb, sb->sb_cc, toep->sb_cc)); + __func__, sb, sbused(sb), toep->sb_cc)); if (toep->ulp_mode == ULP_MODE_ISCSI) { toep->rx_credits += toep->sb_cc; toep->sb_cc = 0; } else { - toep->rx_credits += toep->sb_cc - sb->sb_cc; - toep->sb_cc = sb->sb_cc; + toep->rx_credits += toep->sb_cc - sbused(sb); + toep->sb_cc = sbused(sb); } credits = toep->rx_credits; SOCKBUF_UNLOCK(sb); @@ -1079,15 +1079,15 @@ do_peer_close(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) tp->rcv_nxt = be32toh(cpl->rcv_nxt); toep->ddp_flags &= ~(DDP_BUF0_ACTIVE | DDP_BUF1_ACTIVE); - KASSERT(toep->sb_cc >= sb->sb_cc, + KASSERT(toep->sb_cc >= sbused(sb), ("%s: sb %p has more data (%d) than last time (%d).", - __func__, sb, sb->sb_cc, toep->sb_cc)); - toep->rx_credits += toep->sb_cc - sb->sb_cc; + __func__, sb, sbused(sb), toep->sb_cc)); + toep->rx_credits += toep->sb_cc - sbused(sb); #ifdef USE_DDP_RX_FLOW_CONTROL toep->rx_credits -= m->m_len; /* adjust for F_RX_FC_DDP */ #endif sbappendstream_locked(sb, m); - toep->sb_cc = sb->sb_cc; + toep->sb_cc = sbused(sb); } socantrcvmore_locked(so); /* unlocks the sockbuf */ @@ -1582,12 +1582,12 @@ do_rx_data(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m) } } - KASSERT(toep->sb_cc >= sb->sb_cc, + KASSERT(toep->sb_cc >= sbused(sb), ("%s: sb %p has more data (%d) than last time (%d).", - __func__, sb, sb->sb_cc, toep->sb_cc)); - toep->rx_credits += toep->sb_cc - sb->sb_cc; + __func__, sb, sbused(sb), toep->sb_cc)); + toep->rx_credits += toep->sb_cc - sbused(sb); sbappendstream_locked(sb, m); - toep->sb_cc = sb->sb_cc; + toep->sb_cc = sbused(sb); sorwakeup_locked(so); SOCKBUF_UNLOCK_ASSERT(sb); diff --git a/sys/dev/cxgbe/tom/t4_ddp.c b/sys/dev/cxgbe/tom/t4_ddp.c index 3691a3b516d..89585cf8303 100644 --- a/sys/dev/cxgbe/tom/t4_ddp.c +++ b/sys/dev/cxgbe/tom/t4_ddp.c @@ -224,15 +224,15 @@ insert_ddp_data(struct toepcb *toep, uint32_t n) tp->rcv_wnd -= n; #endif - KASSERT(toep->sb_cc >= sb->sb_cc, + KASSERT(toep->sb_cc >= sbused(sb), ("%s: sb %p has more data (%d) than last time (%d).", - __func__, sb, sb->sb_cc, toep->sb_cc)); - toep->rx_credits += toep->sb_cc - sb->sb_cc; + __func__, sb, sbused(sb), toep->sb_cc)); + toep->rx_credits += toep->sb_cc - sbused(sb); #ifdef USE_DDP_RX_FLOW_CONTROL toep->rx_credits -= n; /* adjust for F_RX_FC_DDP */ #endif sbappendstream_locked(sb, m); - toep->sb_cc = sb->sb_cc; + toep->sb_cc = sbused(sb); } /* SET_TCB_FIELD sent as a ULP command looks like this */ @@ -459,15 +459,15 @@ handle_ddp_data(struct toepcb *toep, __be32 ddp_report, __be32 rcv_nxt, int len) else discourage_ddp(toep); - KASSERT(toep->sb_cc >= sb->sb_cc, + KASSERT(toep->sb_cc >= sbused(sb), ("%s: sb %p has more data (%d) than last time (%d).", - __func__, sb, sb->sb_cc, toep->sb_cc)); - toep->rx_credits += toep->sb_cc - sb->sb_cc; + __func__, sb, sbused(sb), toep->sb_cc)); + toep->rx_credits += toep->sb_cc - sbused(sb); #ifdef USE_DDP_RX_FLOW_CONTROL toep->rx_credits -= len; /* adjust for F_RX_FC_DDP */ #endif sbappendstream_locked(sb, m); - toep->sb_cc = sb->sb_cc; + toep->sb_cc = sbused(sb); wakeup: KASSERT(toep->ddp_flags & db_flag, ("%s: DDP buffer not active. toep %p, ddp_flags 0x%x, report 0x%x", @@ -908,7 +908,7 @@ handle_ddp(struct socket *so, struct uio *uio, int flags, int error) #endif /* XXX: too eager to disable DDP, could handle NBIO better than this. */ - if (sb->sb_cc >= uio->uio_resid || uio->uio_resid < sc->tt.ddp_thres || + if (sbused(sb) >= uio->uio_resid || uio->uio_resid < sc->tt.ddp_thres || uio->uio_resid > MAX_DDP_BUFFER_SIZE || uio->uio_iovcnt > 1 || so->so_state & SS_NBIO || flags & (MSG_DONTWAIT | MSG_NBIO) || error || so->so_error || sb->sb_state & SBS_CANTRCVMORE) @@ -946,7 +946,7 @@ handle_ddp(struct socket *so, struct uio *uio, int flags, int error) * payload. */ ddp_flags = select_ddp_flags(so, flags, db_idx); - wr = mk_update_tcb_for_ddp(sc, toep, db_idx, sb->sb_cc, ddp_flags); + wr = mk_update_tcb_for_ddp(sc, toep, db_idx, sbused(sb), ddp_flags); if (wr == NULL) { /* * Just unhold the pages. The DDP buffer's software state is @@ -1134,8 +1134,8 @@ restart: /* uio should be just as it was at entry */ KASSERT(oresid == uio->uio_resid, - ("%s: oresid = %d, uio_resid = %zd, sb_cc = %d", - __func__, oresid, uio->uio_resid, sb->sb_cc)); + ("%s: oresid = %d, uio_resid = %zd, sbused = %d", + __func__, oresid, uio->uio_resid, sbused(sb))); error = handle_ddp(so, uio, flags, 0); ddp_handled = 1; @@ -1145,7 +1145,7 @@ restart: /* Abort if socket has reported problems. */ if (so->so_error) { - if (sb->sb_cc > 0) + if (sbused(sb)) goto deliver; if (oresid > uio->uio_resid) goto out; @@ -1157,32 +1157,32 @@ restart: /* Door is closed. Deliver what is left, if any. */ if (sb->sb_state & SBS_CANTRCVMORE) { - if (sb->sb_cc > 0) + if (sbused(sb)) goto deliver; else goto out; } /* Socket buffer is empty and we shall not block. */ - if (sb->sb_cc == 0 && + if (sbused(sb) == 0 && ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)))) { error = EAGAIN; goto out; } /* Socket buffer got some data that we shall deliver now. */ - if (sb->sb_cc > 0 && !(flags & MSG_WAITALL) && + if (sbused(sb) && !(flags & MSG_WAITALL) && ((sb->sb_flags & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)) || - sb->sb_cc >= sb->sb_lowat || - sb->sb_cc >= uio->uio_resid || - sb->sb_cc >= sb->sb_hiwat) ) { + sbused(sb) >= sb->sb_lowat || + sbused(sb) >= uio->uio_resid || + sbused(sb) >= sb->sb_hiwat) ) { goto deliver; } /* On MSG_WAITALL we must wait until all data or error arrives. */ if ((flags & MSG_WAITALL) && - (sb->sb_cc >= uio->uio_resid || sb->sb_cc >= sb->sb_lowat)) + (sbused(sb) >= uio->uio_resid || sbused(sb) >= sb->sb_lowat)) goto deliver; /* @@ -1201,7 +1201,7 @@ restart: deliver: SOCKBUF_LOCK_ASSERT(&so->so_rcv); - KASSERT(sb->sb_cc > 0, ("%s: sockbuf empty", __func__)); + KASSERT(sbused(sb) > 0, ("%s: sockbuf empty", __func__)); KASSERT(sb->sb_mb != NULL, ("%s: sb_mb == NULL", __func__)); if (sb->sb_flags & SB_DDP_INDICATE && !ddp_handled) @@ -1212,7 +1212,7 @@ deliver: uio->uio_td->td_ru.ru_msgrcv++; /* Fill uio until full or current end of socket buffer is reached. */ - len = min(uio->uio_resid, sb->sb_cc); + len = min(uio->uio_resid, sbused(sb)); if (mp0 != NULL) { /* Dequeue as many mbufs as possible. */ if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) { diff --git a/sys/dev/dpt/dpt_isa.c b/sys/dev/dpt/dpt_isa.c deleted file mode 100644 index b09feac9471..00000000000 --- a/sys/dev/dpt/dpt_isa.c +++ /dev/null @@ -1,267 +0,0 @@ -/*- - * Copyright (c) 2000 Matthew N. Dodd - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#ifdef notyet -static void dpt_isa_identify (driver_t *, device_t); -#endif -static int dpt_isa_probe (device_t); -static int dpt_isa_attach (device_t); -static int dpt_isa_detach (device_t); - -static int dpt_isa_valid_irq (int); -static int dpt_isa_valid_ioport (int); - -static int -dpt_isa_valid_irq (int irq) -{ - switch (irq) { - case 11: - case 12: - case 14: - case 15: - return (0); - default: - return (1); - }; - return (1); -} - -static int -dpt_isa_valid_ioport (int ioport) -{ - switch (ioport) { - case 0x170: - case 0x1f0: - case 0x230: - case 0x330: - return (0); - default: - return (1); - }; - return (1); -} - -#ifdef notyet -static void -dpt_isa_identify (driver_t *driver, device_t parent) -{ - device_t child; - dpt_conf_t * conf; - int isa_bases[] = { 0x1f0, 0x170, 0x330, 0x230, 0 }; - int i; - - for (i = 0; isa_bases[i]; i++) { - conf = dpt_pio_get_conf(isa_bases[i]); - if (!conf) { - if (bootverbose) - device_printf(parent, "dpt: dpt_pio_get_conf(%x) failed.\n", - isa_bases[i]); - continue; - } - - child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "dpt", -1); - if (child == 0) { - device_printf(parent, "dpt: BUS_ADD_CHILD() failed!\n"); - continue; - } - device_set_driver(child, driver); - bus_set_resource(child, SYS_RES_IOPORT, 0, isa_bases[i], 0x9); - } - return; -} -#endif - -static int -dpt_isa_probe (device_t dev) -{ - dpt_conf_t * conf; - u_int32_t io_base; - - /* No pnp support */ - if (isa_get_vendorid(dev)) - return (ENXIO); - - if ((io_base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0) - return (ENXIO); - - if (dpt_isa_valid_ioport(io_base)) - ; - - conf = dpt_pio_get_conf(io_base); - if (!conf) { - printf("dpt: dpt_pio_get_conf() failed.\n"); - return (ENXIO); - } - - if (dpt_isa_valid_irq(conf->IRQ)) - ; - - device_set_desc(dev, "ISA DPT SCSI controller"); - bus_set_resource(dev, SYS_RES_IRQ, 0, conf->IRQ, 1); - bus_set_resource(dev, SYS_RES_DRQ, 0, ((8 - conf->DMA_channel) & 7), 1); - - return 0; -} - -static int -dpt_isa_attach (device_t dev) -{ - dpt_softc_t * dpt; - int error = 0; - - dpt = device_get_softc(dev); - dpt->dev = dev; - dpt_alloc(dev); - - dpt->io_rid = 0; - dpt->io_type = SYS_RES_IOPORT; - dpt->irq_rid = 0; - - error = dpt_alloc_resources(dev); - if (error) { - goto bad; - } - - dpt->drq_rid = 0; - dpt->drq_res = bus_alloc_resource_any(dev, SYS_RES_DRQ, &dpt->drq_rid, - RF_ACTIVE); - if (!dpt->drq_res) { - device_printf(dev, "No DRQ!\n"); - error = ENOMEM; - goto bad; - } - isa_dma_acquire(rman_get_start(dpt->drq_res)); - isa_dmacascade(rman_get_start(dpt->drq_res)); - - /* Allocate a dmatag representing the capabilities of this attachment */ - if (bus_dma_tag_create( /* parent */ bus_get_dma_tag(dev), - /* alignemnt */ 1, - /* boundary */ 0, - /* lowaddr */ BUS_SPACE_MAXADDR_32BIT, - /* highaddr */ BUS_SPACE_MAXADDR, - /* filter */ NULL, - /* filterarg */ NULL, - /* maxsize */ BUS_SPACE_MAXSIZE_32BIT, - /* nsegments */ ~0, - /* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT, - /* flags */ 0, - /* lockfunc */ NULL, - /* lockarg */ NULL, - &dpt->parent_dmat) != 0) { - error = ENXIO; - goto bad; - } - - if (dpt_init(dpt) != 0) { - error = ENXIO; - goto bad; - } - - /* Register with the XPT */ - dpt_attach(dpt); - - if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | - INTR_MPSAFE, NULL, dpt_intr, dpt, &dpt->ih)) { - device_printf(dev, "Unable to register interrupt handler\n"); - error = ENXIO; - goto bad; - } - - return (error); - - bad: - if (dpt->drq_res) { - isa_dma_release(rman_get_start(dpt->drq_res)); - } - - dpt_release_resources(dev); - - if (dpt) - dpt_free(dpt); - - return (error); -} - -static int -dpt_isa_detach (device_t dev) -{ - dpt_softc_t * dpt; - int dma; - int error; - - dpt = device_get_softc(dev); - - dma = rman_get_start(dpt->drq_res); - error = dpt_detach(dev); - isa_dma_release(dma); - - return (error); -} - - -static device_method_t dpt_isa_methods[] = { - /* Device interface */ -#ifdef notyet - DEVMETHOD(device_identify, dpt_isa_identify), -#endif - DEVMETHOD(device_probe, dpt_isa_probe), - DEVMETHOD(device_attach, dpt_isa_attach), - DEVMETHOD(device_detach, dpt_isa_detach), - - { 0, 0 } -}; - -static driver_t dpt_isa_driver = { - "dpt", - dpt_isa_methods, - sizeof(dpt_softc_t), -}; - -DRIVER_MODULE(dpt, isa, dpt_isa_driver, dpt_devclass, 0, 0); -MODULE_DEPEND(dpt, isa, 1, 1, 1); -MODULE_DEPEND(dpt, cam, 1, 1, 1); diff --git a/sys/dev/drm2/radeon/radeon_connectors.c b/sys/dev/drm2/radeon/radeon_connectors.c index 529bac34f46..d303dfa47bc 100644 --- a/sys/dev/drm2/radeon/radeon_connectors.c +++ b/sys/dev/drm2/radeon/radeon_connectors.c @@ -954,7 +954,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) radeon_connector->edid = drm_get_edid(&radeon_connector->base, radeon_connector->ddc_bus->adapter); if (!radeon_connector->edid) { - DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", + DRM_DEBUG_KMS("%s: probed a monitor but no|invalid EDID\n", drm_get_connector_name(connector)); /* rs690 seems to have a problem with connectors not existing and always * return a block of 0's. If we see this just stop polling on this output */ diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c index 9d0c0f038ba..117e7de7adc 100644 --- a/sys/dev/fdt/fdt_common.c +++ b/sys/dev/fdt/fdt_common.c @@ -1,7 +1,9 @@ /*- - * Copyright (c) 2009-2010 The FreeBSD Foundation + * Copyright (c) 2009-2014 The FreeBSD Foundation * All rights reserved. * + * This software was developed by Andrew Turner under sponsorship from + * the FreeBSD Foundation. * This software was developed by Semihalf under sponsorship from * the FreeBSD Foundation. * @@ -64,12 +66,84 @@ vm_offset_t fdt_immr_size; struct fdt_ic_list fdt_ic_list_head = SLIST_HEAD_INITIALIZER(fdt_ic_list_head); +static int +fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base, + u_long *size) +{ + pcell_t ranges[32], *rangesptr; + pcell_t addr_cells, size_cells, par_addr_cells; + u_long bus_addr, par_bus_addr, pbase, psize; + int err, i, len, tuple_size, tuples; + + if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) + return (ENXIO); + /* + * Process 'ranges' property. + */ + par_addr_cells = fdt_parent_addr_cells(node); + if (par_addr_cells > 2) { + return (ERANGE); + } + + len = OF_getproplen(node, "ranges"); + if (len < 0) + return (-1); + if (len > sizeof(ranges)) + return (ENOMEM); + if (len == 0) { + *base = 0; + *size = ULONG_MAX; + return (0); + } + + if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0) + return (EINVAL); + + tuple_size = addr_cells + par_addr_cells + size_cells; + tuples = len / (tuple_size * sizeof(cell_t)); + + if (fdt_ranges_verify(ranges, tuples, par_addr_cells, + addr_cells, size_cells)) { + return (ERANGE); + } + *base = 0; + *size = 0; + + for (i = 0; i < tuples; i++) { + rangesptr = &ranges[i * tuple_size]; + + bus_addr = fdt_data_get((void *)rangesptr, addr_cells); + if (bus_addr != addr) + continue; + rangesptr += addr_cells; + + par_bus_addr = fdt_data_get((void *)rangesptr, par_addr_cells); + rangesptr += par_addr_cells; + + err = fdt_get_range_by_busaddr(OF_parent(node), par_bus_addr, + &pbase, &psize); + if (err > 0) + return (err); + if (err == 0) + *base = pbase; + else + *base = par_bus_addr; + + *size = fdt_data_get((void *)rangesptr, size_cells); + + return (0); + } + + return (EINVAL); +} + int fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size) { pcell_t ranges[6], *rangesptr; pcell_t addr_cells, size_cells, par_addr_cells; - int len, tuple_size, tuples; + u_long par_bus_addr, pbase, psize; + int err, len, tuple_size, tuples; if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) return (ENXIO); @@ -109,8 +183,17 @@ fdt_get_range(phandle_t node, int range_id, u_long *base, u_long *size) *base = fdt_data_get((void *)rangesptr, addr_cells); rangesptr += addr_cells; - *base += fdt_data_get((void *)rangesptr, par_addr_cells); + + par_bus_addr = fdt_data_get((void *)rangesptr, par_addr_cells); rangesptr += par_addr_cells; + + err = fdt_get_range_by_busaddr(OF_parent(node), par_bus_addr, + &pbase, &psize); + if (err == 0) + *base += pbase; + else + *base += par_bus_addr; + *size = fdt_data_get((void *)rangesptr, size_cells); return (0); } @@ -292,7 +375,7 @@ fdt_parent_addr_cells(phandle_t node) /* Find out #address-cells of the superior bus. */ if (OF_searchprop(OF_parent(node), "#address-cells", &addr_cells, sizeof(addr_cells)) <= 0) - addr_cells = 2; + return (2); return ((int)fdt32_to_cpu(addr_cells)); } diff --git a/sys/dev/fdt/fdt_pinctrl.c b/sys/dev/fdt/fdt_pinctrl.c index 474fb00e22a..0a0dd84989a 100644 --- a/sys/dev/fdt/fdt_pinctrl.c +++ b/sys/dev/fdt/fdt_pinctrl.c @@ -124,15 +124,14 @@ pinctrl_configure_children(device_t pinctrl, phandle_t parent) pinctrl_configure_children(pinctrl, node); nconfigs = OF_getencprop_alloc(node, "pinctrl-0", sizeof(*configs), (void **)&configs); -#ifdef DEBUG - { - char name[32]; - OF_getprop(node, "name", &name, sizeof(name)); - printf("%d items in pinctrl-0 for %s\n", nconfigs, name); - } -#endif if (nconfigs <= 0) continue; + if (bootverbose) { + char name[32]; + OF_getprop(node, "name", &name, sizeof(name)); + printf("Processing %d pin-config node(s) in pinctrl-0 for %s\n", + nconfigs, name); + } for (i = 0; i < nconfigs; i++) { if (OF_device_from_xref(configs[i]) == pinctrl) FDT_PINCTRL_CONFIGURE(pinctrl, configs[i]); diff --git a/sys/dev/gpio/gpio_if.m b/sys/dev/gpio/gpio_if.m index 4d6dfd17a5d..f0ead651ce8 100644 --- a/sys/dev/gpio/gpio_if.m +++ b/sys/dev/gpio/gpio_if.m @@ -32,9 +32,7 @@ INTERFACE gpio; CODE { - static gpio_map_gpios_t gpio_default_map_gpios; - - int + static int gpio_default_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags) diff --git a/sys/dev/gpio/gpiobus.c b/sys/dev/gpio/gpiobus.c index 68adab05d5d..efff2c0b5f5 100644 --- a/sys/dev/gpio/gpiobus.c +++ b/sys/dev/gpio/gpiobus.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -38,6 +39,14 @@ __FBSDID("$FreeBSD$"); #include "gpiobus_if.h" +#undef GPIOBUS_DEBUG +#ifdef GPIOBUS_DEBUG +#define dprintf printf +#else +#define dprintf(x, arg...) +#endif + +static void gpiobus_print_pins(struct gpiobus_ivar *, char *, size_t); static int gpiobus_parse_pins(struct gpiobus_softc *, device_t, int); static int gpiobus_probe(device_t); static int gpiobus_attach(device_t); @@ -62,11 +71,28 @@ static int gpiobus_pin_set(device_t, device_t, uint32_t, unsigned int); static int gpiobus_pin_get(device_t, device_t, uint32_t, unsigned int*); static int gpiobus_pin_toggle(device_t, device_t, uint32_t); -void -gpiobus_print_pins(struct gpiobus_ivar *devi) +int +gpio_check_flags(uint32_t caps, uint32_t flags) { - int range_start, range_stop, need_coma; - int i; + + /* Check for unwanted flags. */ + if ((flags & caps) == 0 || (flags & caps) != flags) + return (EINVAL); + /* Cannot mix input/output together. */ + if (flags & GPIO_PIN_INPUT && flags & GPIO_PIN_OUTPUT) + return (EINVAL); + /* Cannot mix pull-up/pull-down together. */ + if (flags & GPIO_PIN_PULLUP && flags & GPIO_PIN_PULLDOWN) + return (EINVAL); + + return (0); +} + +static void +gpiobus_print_pins(struct gpiobus_ivar *devi, char *buf, size_t buflen) +{ + char tmp[128]; + int i, range_start, range_stop, need_coma; if (devi->npins == 0) return; @@ -76,11 +102,15 @@ gpiobus_print_pins(struct gpiobus_ivar *devi) for (i = 1; i < devi->npins; i++) { if (devi->pins[i] != (range_stop + 1)) { if (need_coma) - printf(","); + strlcat(buf, ",", buflen); + memset(tmp, 0, sizeof(tmp)); if (range_start != range_stop) - printf("%d-%d", range_start, range_stop); + snprintf(tmp, sizeof(tmp) - 1, "%d-%d", + range_start, range_stop); else - printf("%d", range_start); + snprintf(tmp, sizeof(tmp) - 1, "%d", + range_start); + strlcat(buf, tmp, buflen); range_start = range_stop = devi->pins[i]; need_coma = 1; @@ -90,11 +120,15 @@ gpiobus_print_pins(struct gpiobus_ivar *devi) } if (need_coma) - printf(","); + strlcat(buf, ",", buflen); + memset(tmp, 0, sizeof(tmp)); if (range_start != range_stop) - printf("%d-%d", range_start, range_stop); + snprintf(tmp, sizeof(tmp) - 1, "%d-%d", + range_start, range_stop); else - printf("%d", range_start); + snprintf(tmp, sizeof(tmp) - 1, "%d", + range_start); + strlcat(buf, tmp, buflen); } int @@ -105,6 +139,11 @@ gpiobus_init_softc(device_t dev) sc = GPIOBUS_SOFTC(dev); sc->sc_busdev = dev; sc->sc_dev = device_get_parent(dev); + sc->sc_intr_rman.rm_type = RMAN_ARRAY; + sc->sc_intr_rman.rm_descr = "GPIO Interrupts"; + if (rman_init(&sc->sc_intr_rman) != 0 || + rman_manage_region(&sc->sc_intr_rman, 0, ~0) != 0) + panic("%s: failed to set up rman.", __func__); if (GPIO_PIN_MAX(sc->sc_dev, &sc->sc_npins) != 0) return (ENXIO); @@ -261,12 +300,17 @@ gpiobus_resume(device_t dev) static int gpiobus_print_child(device_t dev, device_t child) { - struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); + char pins[128]; int retval = 0; + struct gpiobus_ivar *devi; + devi = GPIOBUS_IVAR(child); + memset(pins, 0, sizeof(pins)); retval += bus_print_child_header(dev, child); retval += printf(" at pin(s) "); - gpiobus_print_pins(devi); + gpiobus_print_pins(devi, pins, sizeof(pins)); + retval += printf("%s", pins); + resource_list_print_type(&devi->rl, "irq", SYS_RES_IRQ, "%ld"); retval += bus_print_child_footer(dev, child); return (retval); @@ -276,8 +320,12 @@ static int gpiobus_child_location_str(device_t bus, device_t child, char *buf, size_t buflen) { + struct gpiobus_ivar *devi; + + devi = GPIOBUS_IVAR(child); + strlcpy(buf, "pin(s)=", buflen); + gpiobus_print_pins(devi, buf, buflen); - snprintf(buf, buflen, "pins=?"); return (0); } @@ -304,7 +352,9 @@ gpiobus_add_child(device_t dev, u_int order, const char *name, int unit) device_delete_child(dev, child); return (0); } + resource_list_init(&devi->rl); device_set_ivars(child, devi); + return (child); } @@ -314,14 +364,103 @@ gpiobus_hinted_child(device_t bus, const char *dname, int dunit) struct gpiobus_softc *sc = GPIOBUS_SOFTC(bus); struct gpiobus_ivar *devi; device_t child; - int pins; - + int irq, pins; child = BUS_ADD_CHILD(bus, 0, dname, dunit); devi = GPIOBUS_IVAR(child); resource_int_value(dname, dunit, "pins", &pins); if (gpiobus_parse_pins(sc, child, pins)) device_delete_child(bus, child); + if (resource_int_value(dname, dunit, "irq", &irq) == 0) { + if (bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1) != 0) + device_printf(bus, + "warning: bus_set_resource() failed\n"); + } +} + +static int +gpiobus_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + struct gpiobus_ivar *devi; + struct resource_list_entry *rle; + + dprintf("%s: entry (%p, %p, %d, %d, %p, %ld)\n", + __func__, dev, child, type, rid, (void *)(intptr_t)start, count); + devi = GPIOBUS_IVAR(child); + rle = resource_list_add(&devi->rl, type, rid, start, + start + count - 1, count); + if (rle == NULL) + return (ENXIO); + + return (0); +} + +static struct resource * +gpiobus_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct gpiobus_softc *sc; + struct resource *rv; + struct resource_list *rl; + struct resource_list_entry *rle; + int isdefault; + + if (type != SYS_RES_IRQ) + return (NULL); + isdefault = (start == 0UL && end == ~0UL && count == 1); + rle = NULL; + if (isdefault) { + rl = BUS_GET_RESOURCE_LIST(bus, child); + if (rl == NULL) + return (NULL); + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) + return (NULL); + if (rle->res != NULL) + panic("%s: resource entry is busy", __func__); + start = rle->start; + count = rle->count; + end = rle->end; + } + sc = device_get_softc(bus); + rv = rman_reserve_resource(&sc->sc_intr_rman, start, end, count, flags, + child); + if (rv == NULL) + return (NULL); + rman_set_rid(rv, *rid); + if ((flags & RF_ACTIVE) != 0 && + bus_activate_resource(child, type, *rid, rv) != 0) { + rman_release_resource(rv); + return (NULL); + } + + return (rv); +} + +static int +gpiobus_release_resource(device_t bus __unused, device_t child, int type, + int rid, struct resource *r) +{ + int error; + + if (rman_get_flags(r) & RF_ACTIVE) { + error = bus_deactivate_resource(child, type, rid, r); + if (error) + return (error); + } + + return (rman_release_resource(r)); +} + +static struct resource_list * +gpiobus_get_resource_list(device_t bus __unused, device_t child) +{ + struct gpiobus_ivar *ivar; + + ivar = GPIOBUS_IVAR(child); + + return (&ivar->rl); } static int @@ -369,11 +508,16 @@ gpiobus_pin_setflags(device_t dev, device_t child, uint32_t pin, { struct gpiobus_softc *sc = GPIOBUS_SOFTC(dev); struct gpiobus_ivar *devi = GPIOBUS_IVAR(child); + uint32_t caps; if (pin >= devi->npins) return (EINVAL); + if (GPIO_PIN_GETCAPS(sc->sc_dev, devi->pins[pin], &caps) != 0) + return (EINVAL); + if (gpio_check_flags(caps, flags) != 0) + return (EINVAL); - return GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags); + return (GPIO_PIN_SETFLAGS(sc->sc_dev, devi->pins[pin], flags)); } static int @@ -450,6 +594,15 @@ static device_method_t gpiobus_methods[] = { DEVMETHOD(device_resume, gpiobus_resume), /* Bus interface */ + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_config_intr, bus_generic_config_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_set_resource, gpiobus_set_resource), + DEVMETHOD(bus_alloc_resource, gpiobus_alloc_resource), + DEVMETHOD(bus_release_resource, gpiobus_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_get_resource_list, gpiobus_get_resource_list), DEVMETHOD(bus_add_child, gpiobus_add_child), DEVMETHOD(bus_print_child, gpiobus_print_child), DEVMETHOD(bus_child_pnpinfo_str, gpiobus_child_pnpinfo_str), diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h index 47c0b6b725a..a1c2be0461b 100644 --- a/sys/dev/gpio/gpiobusvar.h +++ b/sys/dev/gpio/gpiobusvar.h @@ -34,6 +34,7 @@ #include #include +#include #ifdef FDT #include @@ -62,6 +63,7 @@ struct gpiobus_softc { struct mtx sc_mtx; /* bus mutex */ + struct rman sc_intr_rman; /* isr resources */ device_t sc_busdev; /* bus device */ device_t sc_owner; /* bus owner */ device_t sc_dev; /* driver device */ @@ -71,6 +73,7 @@ struct gpiobus_softc struct gpiobus_ivar { + struct resource_list rl; /* isr resource list */ uint32_t npins; /* pins total */ uint32_t *flags; /* pins flags */ uint32_t *pins; /* pins map */ @@ -91,7 +94,7 @@ gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, int gcells, device_t ofw_gpiobus_add_fdt_child(device_t, phandle_t); #endif -void gpiobus_print_pins(struct gpiobus_ivar *); +int gpio_check_flags(uint32_t, uint32_t); int gpiobus_init_softc(device_t); extern driver_t gpiobus_driver; diff --git a/sys/dev/gpio/gpioc.c b/sys/dev/gpio/gpioc.c index 156f05c2b19..2fad4dffb28 100644 --- a/sys/dev/gpio/gpioc.c +++ b/sys/dev/gpio/gpioc.c @@ -29,19 +29,16 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include +#include #include #include #include #include -#include -#include -#include -#include +#include + #include "gpio_if.h" #undef GPIOC_DEBUG @@ -119,6 +116,7 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, struct gpioc_softc *sc = cdev->si_drv1; struct gpio_pin pin; struct gpio_req req; + uint32_t caps; switch (cmd) { case GPIOMAXPIN: @@ -141,8 +139,12 @@ gpioc_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag, case GPIOSETCONFIG: bcopy(arg, &pin, sizeof(pin)); dprintf("set config pin %d\n", pin.gp_pin); - res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin, - pin.gp_flags); + res = GPIO_PIN_GETCAPS(sc->sc_pdev, pin.gp_pin, &caps); + if (res == 0) + res = gpio_check_flags(caps, pin.gp_flags); + if (res == 0) + res = GPIO_PIN_SETFLAGS(sc->sc_pdev, pin.gp_pin, + pin.gp_flags); break; case GPIOGET: bcopy(arg, &req, sizeof(req)); diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c index 1b03e9f1323..225e905855c 100644 --- a/sys/dev/gpio/ofw_gpiobus.c +++ b/sys/dev/gpio/ofw_gpiobus.c @@ -238,6 +238,13 @@ ofw_gpiobus_setup_devinfo(device_t dev, phandle_t node) free(dinfo, M_DEVBUF); return (NULL); } + /* And now the interrupt resources. */ + resource_list_init(&dinfo->opd_dinfo.rl); + if (ofw_bus_intr_to_rl(dev, node, &dinfo->opd_dinfo.rl) != 0) { + ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo); + free(dinfo, M_DEVBUF); + return (NULL); + } return (dinfo); } @@ -246,6 +253,7 @@ static void ofw_gpiobus_destroy_devinfo(struct ofw_gpiobus_devinfo *dinfo) { + resource_list_free(&dinfo->opd_dinfo.rl); ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo); free(dinfo, M_DEVBUF); } @@ -316,21 +324,6 @@ ofw_gpiobus_add_child(device_t dev, u_int order, const char *name, int unit) return (child); } -static int -ofw_gpiobus_print_child(device_t dev, device_t child) -{ - struct ofw_gpiobus_devinfo *devi; - int retval = 0; - - devi = device_get_ivars(child); - retval += bus_print_child_header(dev, child); - retval += printf(" at pin(s) "); - gpiobus_print_pins(&devi->opd_dinfo); - retval += bus_print_child_footer(dev, child); - - return (retval); -} - static const struct ofw_bus_devinfo * ofw_gpiobus_get_devinfo(device_t bus, device_t dev) { @@ -348,7 +341,6 @@ static device_method_t ofw_gpiobus_methods[] = { /* Bus interface */ DEVMETHOD(bus_child_pnpinfo_str, ofw_bus_gen_child_pnpinfo_str), - DEVMETHOD(bus_print_child, ofw_gpiobus_print_child), DEVMETHOD(bus_add_child, ofw_gpiobus_add_child), /* ofw_bus interface */ diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 42dd66cee06..f1506d63093 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -4749,8 +4749,9 @@ pmc_initialize(void) if (pmc_callchaindepth <= 0 || pmc_callchaindepth > PMC_CALLCHAIN_DEPTH_MAX) { (void) printf("hwpmc: tunable \"callchaindepth\"=%d out of " - "range.\n", pmc_callchaindepth); - pmc_callchaindepth = PMC_CALLCHAIN_DEPTH; + "range - using %d.\n", pmc_callchaindepth, + PMC_CALLCHAIN_DEPTH_MAX); + pmc_callchaindepth = PMC_CALLCHAIN_DEPTH_MAX; } md = pmc_md_initialize(); diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c index d919277c12e..dc567604be9 100644 --- a/sys/dev/iicbus/iicbus.c +++ b/sys/dev/iicbus/iicbus.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -96,6 +97,7 @@ iicbus_attach(device_t dev) sc->dev = dev; mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF); + iicbus_init_frequency(dev, 0); iicbus_reset(dev, IIC_FASTEST, 0, NULL); if (resource_int_value(device_get_name(dev), device_get_unit(dev), "strict", &strict) == 0) @@ -243,6 +245,51 @@ iicbus_null_repeated_start(device_t dev, u_char addr) return (IIC_ENOTSUPP); } +void +iicbus_init_frequency(device_t dev, u_int bus_freq) +{ + struct iicbus_softc *sc = IICBUS_SOFTC(dev); + + /* + * If a bus frequency value was passed in, use it. Otherwise initialize + * it first to the standard i2c 100KHz frequency, then override that + * from a hint if one exists. + */ + if (bus_freq > 0) + sc->bus_freq = bus_freq; + else { + sc->bus_freq = 100000; + resource_int_value(device_get_name(dev), device_get_unit(dev), + "frequency", (int *)&sc->bus_freq); + } + /* + * Set up the sysctl that allows the bus frequency to be changed. + * It is flagged as a tunable so that the user can set the value in + * loader(8), and that will override any other setting from any source. + * The sysctl tunable/value is the one most directly controlled by the + * user and thus the one that always takes precedence. + */ + SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), + OID_AUTO, "frequency", CTLFLAG_RW | CTLFLAG_TUN, &sc->bus_freq, + sc->bus_freq, "Bus frequency in Hz"); +} + +static u_int +iicbus_get_frequency(device_t dev, u_char speed) +{ + struct iicbus_softc *sc = IICBUS_SOFTC(dev); + + /* + * If the frequency has not been configured for the bus, or the request + * is specifically for SLOW speed, use the standard 100KHz rate, else + * use the configured bus speed. + */ + if (sc->bus_freq == 0 || speed == IIC_SLOW) + return (100000); + return (sc->bus_freq); +} + static device_method_t iicbus_methods[] = { /* device interface */ DEVMETHOD(device_probe, iicbus_probe), @@ -260,6 +307,7 @@ static device_method_t iicbus_methods[] = { /* iicbus interface */ DEVMETHOD(iicbus_transfer, iicbus_transfer), + DEVMETHOD(iicbus_get_frequency, iicbus_get_frequency), DEVMETHOD_END }; diff --git a/sys/dev/iicbus/iicbus.h b/sys/dev/iicbus/iicbus.h index 54fe9804eb2..b5905ad8bc3 100644 --- a/sys/dev/iicbus/iicbus.h +++ b/sys/dev/iicbus/iicbus.h @@ -44,6 +44,7 @@ struct iicbus_softc u_char strict; /* deny operations that violate the * I2C protocol */ struct mtx lock; + u_int bus_freq; /* Configured bus Hz. */ }; struct iicbus_ivar @@ -67,7 +68,8 @@ IICBUS_ACCESSOR(nostop, NOSTOP, bool) #define IICBUS_UNLOCK(sc) mtx_unlock(&(sc)->lock) #define IICBUS_ASSERT_LOCKED(sc) mtx_assert(&(sc)->lock, MA_OWNED) -extern int iicbus_generic_intr(device_t dev, int event, char *buf); +int iicbus_generic_intr(device_t dev, int event, char *buf); +void iicbus_init_frequency(device_t dev, u_int bus_freq); extern driver_t iicbus_driver; extern devclass_t iicbus_devclass; diff --git a/sys/dev/iicbus/iicbus_if.m b/sys/dev/iicbus/iicbus_if.m index c57fac58421..120b5e702de 100644 --- a/sys/dev/iicbus/iicbus_if.m +++ b/sys/dev/iicbus/iicbus_if.m @@ -31,6 +31,15 @@ INTERFACE iicbus; +CODE { + static u_int + iicbus_default_frequency(device_t bus, u_char speed) + { + + return (100000); + } +}; + # # Interpret interrupt # @@ -115,3 +124,14 @@ METHOD int transfer { struct iic_msg *msgs; uint32_t nmsgs; }; + +# +# Return the frequency in Hz for the bus running at the given +# symbolic speed. Only the IIC_SLOW speed has meaning, it is always +# 100KHz. The UNKNOWN, FAST, and FASTEST rates all map to the +# configured bus frequency, or 100KHz when not otherwise configured. +# +METHOD u_int get_frequency { + device_t dev; + u_char speed; +} DEFAULT iicbus_default_frequency; diff --git a/sys/dev/iir/iir.c b/sys/dev/iir/iir.c index 1090042ff51..b2ebad8dad6 100644 --- a/sys/dev/iir/iir.c +++ b/sys/dev/iir/iir.c @@ -71,9 +71,6 @@ __FBSDID("$FreeBSD$"); static MALLOC_DEFINE(M_GDTBUF, "iirbuf", "iir driver buffer"); -struct gdt_softc *gdt_wait_gdt; -int gdt_wait_index; - #ifdef GDT_DEBUG int gdt_debug = GDT_DEBUG; #ifdef __SERIAL__ @@ -135,13 +132,13 @@ int ser_printf(const char *fmt, ...) #endif #endif -/* The linked list of softc structures */ -struct gdt_softc_list gdt_softcs = TAILQ_HEAD_INITIALIZER(gdt_softcs); /* controller cnt. */ int gdt_cnt = 0; /* event buffer */ static gdt_evt_str ebuffer[GDT_MAX_EVENTS]; static int elastidx, eoldidx; +static struct mtx elock; +MTX_SYSINIT(iir_elock, &elock, "iir events", MTX_DEF); /* statistics */ gdt_statist_t gdt_stat; @@ -150,6 +147,7 @@ gdt_statist_t gdt_stat; #define ccb_priority spriv_field1 static void iir_action(struct cam_sim *sim, union ccb *ccb); +static int iir_intr_locked(struct gdt_softc *gdt); static void iir_poll(struct cam_sim *sim); static void iir_shutdown(void *arg, int howto); static void iir_timeout(void *arg); @@ -168,12 +166,12 @@ static int gdt_sync_event(struct gdt_softc *gdt, int service, u_int8_t index, struct gdt_ccb *gccb); static int gdt_async_event(struct gdt_softc *gdt, int service); static struct gdt_ccb *gdt_raw_cmd(struct gdt_softc *gdt, - union ccb *ccb, int *lock); + union ccb *ccb); static struct gdt_ccb *gdt_cache_cmd(struct gdt_softc *gdt, - union ccb *ccb, int *lock); + union ccb *ccb); static struct gdt_ccb *gdt_ioctl_cmd(struct gdt_softc *gdt, - gdt_ucmd_t *ucmd, int *lock); -static void gdt_internal_cache_cmd(struct gdt_softc *gdt,union ccb *ccb); + gdt_ucmd_t *ucmd); +static void gdt_internal_cache_cmd(struct gdt_softc *gdt, union ccb *ccb); static void gdtmapmem(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error); @@ -197,7 +195,6 @@ iir_init(struct gdt_softc *gdt) SLIST_INIT(&gdt->sc_pending_gccb); TAILQ_INIT(&gdt->sc_ccb_queue); TAILQ_INIT(&gdt->sc_ucmd_queue); - TAILQ_INSERT_TAIL(&gdt_softcs, gdt, links); /* DMA tag for mapping buffers into device visible space. */ if (bus_dma_tag_create(gdt->sc_parent_dmat, /*alignment*/1, /*boundary*/0, @@ -207,10 +204,11 @@ iir_init(struct gdt_softc *gdt) /*maxsize*/MAXBSIZE, /*nsegments*/GDT_MAXSG, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/BUS_DMA_ALLOCNOW, - /*lockfunc*/busdma_lock_mutex, /*lockarg*/&Giant, + /*lockfunc*/busdma_lock_mutex, + /*lockarg*/&gdt->sc_lock, &gdt->sc_buffer_dmat) != 0) { - printf("iir%d: bus_dma_tag_create(...,gdt->sc_buffer_dmat) failed\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, + "bus_dma_tag_create(..., gdt->sc_buffer_dmat) failed\n"); return (1); } gdt->sc_init_level++; @@ -227,9 +225,10 @@ iir_init(struct gdt_softc *gdt) /*nsegments*/1, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, &gdt->sc_gcscratch_dmat) != 0) { - printf("iir%d: bus_dma_tag_create(...,gdt->sc_gcscratch_dmat) failed\n", - gdt->sc_hanum); + /*lockarg*/&gdt->sc_lock, + &gdt->sc_gcscratch_dmat) != 0) { + device_printf(gdt->sc_devnode, + "bus_dma_tag_create(...,gdt->sc_gcscratch_dmat) failed\n"); return (1); } gdt->sc_init_level++; @@ -237,8 +236,8 @@ iir_init(struct gdt_softc *gdt) /* Allocation for our ccb scratch area */ if (bus_dmamem_alloc(gdt->sc_gcscratch_dmat, (void **)&gdt->sc_gcscratch, BUS_DMA_NOWAIT, &gdt->sc_gcscratch_dmamap) != 0) { - printf("iir%d: bus_dmamem_alloc(...,&gdt->sc_gccbs,...) failed\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, + "bus_dmamem_alloc(...,&gdt->sc_gccbs,...) failed\n"); return (1); } gdt->sc_init_level++; @@ -256,7 +255,7 @@ iir_init(struct gdt_softc *gdt) gdt->sc_gccbs = malloc(sizeof(struct gdt_ccb) * GDT_MAXCMDS, M_GDTBUF, M_NOWAIT | M_ZERO); if (gdt->sc_gccbs == NULL) { - printf("iir%d: no memory for gccbs.\n", gdt->sc_hanum); + device_printf(gdt->sc_devnode, "no memory for gccbs.\n"); return (1); } for (i = GDT_MAXCMDS-1; i >= 0; i--) { @@ -270,28 +269,30 @@ iir_init(struct gdt_softc *gdt) gccb->gc_map_flag = TRUE; gccb->gc_scratch = &gdt->sc_gcscratch[GDT_SCRATCH_SZ * i]; gccb->gc_scratch_busbase = gdt->sc_gcscratch_busbase + GDT_SCRATCH_SZ * i; - callout_handle_init(&gccb->gc_timeout_ch); + callout_init_mtx(&gccb->gc_timeout, &gdt->sc_lock, 0); SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle); } gdt->sc_init_level++; /* create the control device */ - gdt->sc_dev = gdt_make_dev(gdt->sc_hanum); + gdt->sc_dev = gdt_make_dev(gdt); /* allocate ccb for gdt_internal_cmd() */ + mtx_lock(&gdt->sc_lock); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + mtx_unlock(&gdt->sc_lock); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } bzero(gccb->gc_cmd, GDT_CMD_SZ); if (!gdt_internal_cmd(gdt, gccb, GDT_SCREENSERVICE, GDT_INIT, 0, 0, 0)) { - printf("iir%d: Screen service initialization error %d\n", - gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, + "Screen service initialization error %d\n", gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } @@ -300,9 +301,10 @@ iir_init(struct gdt_softc *gdt) if (!gdt_internal_cmd(gdt, gccb, GDT_CACHESERVICE, GDT_INIT, GDT_LINUX_OS, 0, 0)) { - printf("iir%d: Cache service initialization error %d\n", - gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, "Cache service initialization error %d\n", + gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } cdev_cnt = (u_int16_t)gdt->sc_info; @@ -332,9 +334,10 @@ iir_init(struct gdt_softc *gdt) GDT_IO_CHANNEL | GDT_INVALID_CHANNEL, GDT_GETCH_SZ)) { if (i == 0) { - printf("iir%d: Cannot get channel count, " - "error %d\n", gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, "Cannot get channel count, " + "error %d\n", gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } break; @@ -351,9 +354,10 @@ iir_init(struct gdt_softc *gdt) if (!gdt_internal_cmd(gdt, gccb, GDT_SCSIRAWSERVICE, GDT_INIT, 0, 0, 0)) { - printf("iir%d: Raw service initialization error %d\n", - gdt->sc_hanum, gdt->sc_status); + device_printf(gdt->sc_devnode, + "Raw service initialization error %d\n", gdt->sc_status); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } @@ -365,9 +369,11 @@ iir_init(struct gdt_softc *gdt) 0, 0, 0)) { gdt->sc_raw_feat = gdt->sc_info; if (!(gdt->sc_info & GDT_SCATTER_GATHER)) { - panic("iir%d: Scatter/Gather Raw Service " - "required but not supported!\n", gdt->sc_hanum); + panic("%s: Scatter/Gather Raw Service " + "required but not supported!\n", + device_get_nameunit(gdt->sc_devnode)); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } } @@ -381,9 +387,11 @@ iir_init(struct gdt_softc *gdt) 0, 0, 0)) { gdt->sc_cache_feat = gdt->sc_info; if (!(gdt->sc_info & GDT_SCATTER_GATHER)) { - panic("iir%d: Scatter/Gather Cache Service " - "required but not supported!\n", gdt->sc_hanum); + panic("%s: Scatter/Gather Cache Service " + "required but not supported!\n", + device_get_nameunit(gdt->sc_devnode)); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); return (1); } } @@ -442,8 +450,9 @@ iir_init(struct gdt_softc *gdt) gdt->sc_bus_cnt, cdev_cnt, cdev_cnt == 1 ? "" : "s")); gdt_free_ccb(gdt, gccb); + mtx_unlock(&gdt->sc_lock); - gdt_cnt++; + atomic_add_int(&gdt_cnt, 1); return (0); } @@ -459,9 +468,11 @@ iir_free(struct gdt_softc *gdt) gdt_destroy_dev(gdt->sc_dev); case 5: for (i = GDT_MAXCMDS-1; i >= 0; i--) - if (gdt->sc_gccbs[i].gc_map_flag) + if (gdt->sc_gccbs[i].gc_map_flag) { + callout_drain(&gdt->sc_gccbs[i].gc_timeout); bus_dmamap_destroy(gdt->sc_buffer_dmat, gdt->sc_gccbs[i].gc_dmamap); + } bus_dmamap_unload(gdt->sc_gcscratch_dmat, gdt->sc_gcscratch_dmamap); free(gdt->sc_gccbs, M_GDTBUF); case 4: @@ -475,7 +486,6 @@ iir_free(struct gdt_softc *gdt) case 0: break; } - TAILQ_REMOVE(&gdt_softcs, gdt, links); } void @@ -499,11 +509,12 @@ iir_attach(struct gdt_softc *gdt) * Construct our SIM entry */ gdt->sims[i] = cam_sim_alloc(iir_action, iir_poll, "iir", - gdt, gdt->sc_hanum, &Giant, - /*untagged*/1, - /*tagged*/GDT_MAXCMDS, devq); + gdt, device_get_unit(gdt->sc_devnode), &gdt->sc_lock, + /*untagged*/1, /*tagged*/GDT_MAXCMDS, devq); + mtx_lock(&gdt->sc_lock); if (xpt_bus_register(gdt->sims[i], gdt->sc_devnode, i) != CAM_SUCCESS) { cam_sim_free(gdt->sims[i], /*free_devq*/i == 0); + mtx_unlock(&gdt->sc_lock); break; } @@ -513,8 +524,10 @@ iir_attach(struct gdt_softc *gdt) CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(gdt->sims[i])); cam_sim_free(gdt->sims[i], /*free_devq*/i == 0); + mtx_unlock(&gdt->sc_lock); break; } + mtx_unlock(&gdt->sc_lock); } if (i > 0) EVENTHANDLER_REGISTER(shutdown_final, iir_shutdown, @@ -556,9 +569,7 @@ gdt_wait(struct gdt_softc *gdt, struct gdt_ccb *gccb, gdt->sc_state |= GDT_POLL_WAIT; do { - iir_intr(gdt); - if (gdt == gdt_wait_gdt && - gccb->gc_cmd_index == gdt_wait_index) { + if (iir_intr_locked(gdt) == gccb->gc_cmd_index) { rv = 1; break; } @@ -642,11 +653,10 @@ static struct gdt_ccb * gdt_get_ccb(struct gdt_softc *gdt) { struct gdt_ccb *gccb; - int lock; GDT_DPRINTF(GDT_D_QUEUE, ("gdt_get_ccb(%p)\n", gdt)); - lock = splcam(); + mtx_assert(&gdt->sc_lock, MA_OWNED); gccb = SLIST_FIRST(&gdt->sc_free_gccb); if (gccb != NULL) { SLIST_REMOVE_HEAD(&gdt->sc_free_gccb, sle); @@ -655,23 +665,20 @@ gdt_get_ccb(struct gdt_softc *gdt) if (gdt_stat.cmd_index_act > gdt_stat.cmd_index_max) gdt_stat.cmd_index_max = gdt_stat.cmd_index_act; } - splx(lock); return (gccb); } void gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb) { - int lock; GDT_DPRINTF(GDT_D_QUEUE, ("gdt_free_ccb(%p, %p)\n", gdt, gccb)); - - lock = splcam(); + + mtx_assert(&gdt->sc_lock, MA_OWNED); gccb->gc_flags = GDT_GCF_UNUSED; SLIST_REMOVE(&gdt->sc_pending_gccb, gccb, gdt_ccb, sle); SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle); --gdt_stat.cmd_index_act; - splx(lock); if (gdt->sc_state & GDT_SHUTDOWN) wakeup(gccb); } @@ -679,7 +686,6 @@ gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb) void gdt_next(struct gdt_softc *gdt) { - int lock; union ccb *ccb; gdt_ucmd_t *ucmd; struct cam_sim *sim; @@ -693,10 +699,9 @@ gdt_next(struct gdt_softc *gdt) GDT_DPRINTF(GDT_D_QUEUE, ("gdt_next(%p)\n", gdt)); - lock = splcam(); + mtx_assert(&gdt->sc_lock, MA_OWNED); if (gdt->sc_test_busy(gdt)) { if (!(gdt->sc_state & GDT_POLLING)) { - splx(lock); return; } while (gdt->sc_test_busy(gdt)) @@ -715,7 +720,7 @@ gdt_next(struct gdt_softc *gdt) ucmd = TAILQ_FIRST(&gdt->sc_ucmd_queue); if (ucmd != NULL) { TAILQ_REMOVE(&gdt->sc_ucmd_queue, ucmd, links); - if ((gccb = gdt_ioctl_cmd(gdt, ucmd, &lock)) == NULL) { + if ((gccb = gdt_ioctl_cmd(gdt, ucmd)) == NULL) { TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links); break; } @@ -746,7 +751,7 @@ gdt_next(struct gdt_softc *gdt) xpt_done(ccb); } else if (bus != gdt->sc_virt_bus) { /* raw service command */ - if ((gccb = gdt_raw_cmd(gdt, ccb, &lock)) == NULL) { + if ((gccb = gdt_raw_cmd(gdt, ccb)) == NULL) { TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe); ++gdt_stat.req_queue_act; @@ -763,7 +768,7 @@ gdt_next(struct gdt_softc *gdt) /* cache service command */ if (cmd == READ_6 || cmd == WRITE_6 || cmd == READ_10 || cmd == WRITE_10) { - if ((gccb = gdt_cache_cmd(gdt, ccb, &lock)) == NULL) { + if ((gccb = gdt_cache_cmd(gdt, ccb)) == NULL) { TAILQ_INSERT_HEAD(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe); ++gdt_stat.req_queue_act; @@ -772,9 +777,7 @@ gdt_next(struct gdt_softc *gdt) next_cmd = FALSE; } } else { - splx(lock); gdt_internal_cache_cmd(gdt, ccb); - lock = splcam(); } } if ((gdt->sc_state & GDT_POLLING) || !next_cmd) @@ -783,15 +786,13 @@ gdt_next(struct gdt_softc *gdt) if (gdt->sc_cmd_cnt > 0) gdt->sc_release_event(gdt); - splx(lock); - if ((gdt->sc_state & GDT_POLLING) && gdt->sc_cmd_cnt > 0) { gdt_wait(gdt, gccb, GDT_POLL_TIMEOUT); } } static struct gdt_ccb * -gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) +gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb) { struct gdt_ccb *gccb; struct cam_sim *sim; @@ -802,15 +803,15 @@ gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) if (roundup(GDT_CMD_UNION + GDT_RAW_SZ, sizeof(u_int32_t)) + gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET > gdt->sc_ic_all_size) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_raw_cmd(): DPMEM overflow\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: gdt_raw_cmd(): DPMEM overflow\n", + device_get_nameunit(gdt->sc_devnode))); return (NULL); } gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: No free command index found\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: No free command index found\n", + device_get_nameunit(gdt->sc_devnode))); return (gccb); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -821,7 +822,6 @@ gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) if (gdt->sc_cmd_cnt == 0) gdt->sc_set_sema0(gdt); - splx(*lock); gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX, gccb->gc_cmd_index); gdt_enc16(gccb->gc_cmd + GDT_CMD_OPCODE, GDT_WRITE); @@ -856,12 +856,11 @@ gdt_raw_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } - *lock = splcam(); return (gccb); } static struct gdt_ccb * -gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) +gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb) { struct gdt_ccb *gccb; struct cam_sim *sim; @@ -875,15 +874,15 @@ gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) if (roundup(GDT_CMD_UNION + GDT_CACHE_SZ, sizeof(u_int32_t)) + gdt->sc_cmd_off + GDT_DPMEM_COMMAND_OFFSET > gdt->sc_ic_all_size) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_cache_cmd(): DPMEM overflow\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: gdt_cache_cmd(): DPMEM overflow\n", + device_get_nameunit(gdt->sc_devnode))); return (NULL); } gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_DEBUG, ("%s: No free command index found\n", + device_get_nameunit(gdt->sc_devnode))); return (gccb); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -894,7 +893,6 @@ gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) if (gdt->sc_cmd_cnt == 0) gdt->sc_set_sema0(gdt); - splx(*lock); gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX, gccb->gc_cmd_index); cmdp = ccb->csio.cdb_io.cdb_bytes; @@ -928,12 +926,11 @@ gdt_cache_cmd(struct gdt_softc *gdt, union ccb *ccb, int *lock) xpt_freeze_simq(sim, 1); gccb->gc_ccb->ccb_h.status |= CAM_RELEASE_SIMQ; } - *lock = splcam(); return (gccb); } static struct gdt_ccb * -gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) +gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd) { struct gdt_ccb *gccb; u_int32_t cnt; @@ -942,8 +939,8 @@ gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - GDT_DPRINTF(GDT_D_DEBUG, ("iir%d: No free command index found\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_DEBUG, ("%s: No free command index found\n", + device_get_nameunit(gdt->sc_devnode))); return (gccb); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -958,8 +955,8 @@ gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) sizeof(u_int32_t)); cnt = ucmd->u.ioctl.param_size; if (cnt > GDT_SCRATCH_SZ) { - printf("iir%d: Scratch buffer too small (%d/%d)\n", - gdt->sc_hanum, GDT_SCRATCH_SZ, cnt); + device_printf(gdt->sc_devnode, + "Scratch buffer too small (%d/%d)\n", GDT_SCRATCH_SZ, cnt); gdt_free_ccb(gdt, gccb); return (NULL); } @@ -968,8 +965,8 @@ gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) GDT_SG_SZ, sizeof(u_int32_t)); cnt = ucmd->u.cache.BlockCnt * GDT_SECTOR_SIZE; if (cnt > GDT_SCRATCH_SZ) { - printf("iir%d: Scratch buffer too small (%d/%d)\n", - gdt->sc_hanum, GDT_SCRATCH_SZ, cnt); + device_printf(gdt->sc_devnode, + "Scratch buffer too small (%d/%d)\n", GDT_SCRATCH_SZ, cnt); gdt_free_ccb(gdt, gccb); return (NULL); } @@ -979,8 +976,8 @@ gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) GDT_SG_SZ, sizeof(u_int32_t)); cnt = ucmd->u.raw.sdlen; if (cnt + ucmd->u.raw.sense_len > GDT_SCRATCH_SZ) { - printf("iir%d: Scratch buffer too small (%d/%d)\n", - gdt->sc_hanum, GDT_SCRATCH_SZ, cnt + ucmd->u.raw.sense_len); + device_printf(gdt->sc_devnode, "Scratch buffer too small (%d/%d)\n", + GDT_SCRATCH_SZ, cnt + ucmd->u.raw.sense_len); gdt_free_ccb(gdt, gccb); return (NULL); } @@ -990,15 +987,14 @@ gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) if (gdt->sc_cmd_off + gccb->gc_cmd_len + GDT_DPMEM_COMMAND_OFFSET > gdt->sc_ic_all_size) { - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: gdt_ioctl_cmd(): DPMEM overflow\n", - gdt->sc_hanum)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: gdt_ioctl_cmd(): DPMEM overflow\n", + device_get_nameunit(gdt->sc_devnode))); gdt_free_ccb(gdt, gccb); return (NULL); } if (gdt->sc_cmd_cnt == 0) gdt->sc_set_sema0(gdt); - splx(*lock); /* fill cmd structure */ gdt_enc32(gccb->gc_cmd + GDT_CMD_COMMANDINDEX, @@ -1064,7 +1060,6 @@ gdt_ioctl_cmd(struct gdt_softc *gdt, gdt_ucmd_t *ucmd, int *lock) GDT_SG_LEN, ucmd->u.raw.sdlen); } - *lock = splcam(); gdt_stat.sg_count_act = 1; gdt->sc_copy_cmd(gdt, gccb); return (gccb); @@ -1181,13 +1176,12 @@ gdtexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) struct gdt_ccb *gccb; union ccb *ccb; struct gdt_softc *gdt; - int i, lock; - - lock = splcam(); + int i; gccb = (struct gdt_ccb *)arg; ccb = gccb->gc_ccb; gdt = cam_sim_softc((struct cam_sim *)ccb->ccb_h.ccb_sim_ptr); + mtx_assert(&gdt->sc_lock, MA_OWNED); GDT_DPRINTF(GDT_D_CMD, ("gdtexecuteccb(%p, %p, %p, %d, %d)\n", gdt, gccb, dm_segs, nseg, error)); @@ -1240,12 +1234,10 @@ gdtexecuteccb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) ccb->ccb_h.status |= CAM_SIM_QUEUED; /* timeout handling */ - gccb->gc_timeout_ch = - timeout(iir_timeout, (caddr_t)gccb, - (ccb->ccb_h.timeout * hz) / 1000); + callout_reset(&gccb->gc_timeout, (ccb->ccb_h.timeout * hz) / 1000, + iir_timeout, gccb); gdt->sc_copy_cmd(gdt, gccb); - splx(lock); } @@ -1253,9 +1245,10 @@ static void iir_action( struct cam_sim *sim, union ccb *ccb ) { struct gdt_softc *gdt; - int lock, bus, target, lun; + int bus, target, lun; gdt = (struct gdt_softc *)cam_sim_softc( sim ); + mtx_assert(&gdt->sc_lock, MA_OWNED); ccb->ccb_h.ccb_sim_ptr = sim; bus = cam_sim_bus(sim); target = ccb->ccb_h.target_id; @@ -1270,12 +1263,10 @@ iir_action( struct cam_sim *sim, union ccb *ccb ) switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: - lock = splcam(); TAILQ_INSERT_TAIL(&gdt->sc_ccb_queue, &ccb->ccb_h, sim_links.tqe); ++gdt_stat.req_queue_act; if (gdt_stat.req_queue_act > gdt_stat.req_queue_max) gdt_stat.req_queue_max = gdt_stat.req_queue_act; - splx(lock); gdt_next(gdt); break; case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ @@ -1406,7 +1397,7 @@ iir_poll( struct cam_sim *sim ) gdt = (struct gdt_softc *)cam_sim_softc( sim ); GDT_DPRINTF(GDT_D_CMD, ("iir_poll sim %p gdt %p\n", sim, gdt)); - iir_intr(gdt); + iir_intr_locked(gdt); } static void @@ -1421,29 +1412,29 @@ iir_shutdown( void *arg, int howto ) struct gdt_softc *gdt; struct gdt_ccb *gccb; gdt_ucmd_t *ucmd; - int lock, i; + int i; gdt = (struct gdt_softc *)arg; GDT_DPRINTF(GDT_D_CMD, ("iir_shutdown(%p, %d)\n", gdt, howto)); - printf("iir%d: Flushing all Host Drives. Please wait ... ", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, + "Flushing all Host Drives. Please wait ... "); /* allocate ucmd buffer */ ucmd = malloc(sizeof(gdt_ucmd_t), M_GDTBUF, M_NOWAIT); if (ucmd == NULL) { - printf("iir%d: iir_shutdown(): Cannot allocate resource\n", - gdt->sc_hanum); + printf("\n"); + device_printf(gdt->sc_devnode, + "iir_shutdown(): Cannot allocate resource\n"); return; } bzero(ucmd, sizeof(gdt_ucmd_t)); /* wait for pending IOs */ - lock = splcam(); + mtx_lock(&gdt->sc_lock); gdt->sc_state = GDT_SHUTDOWN; - splx(lock); if ((gccb = SLIST_FIRST(&gdt->sc_pending_gccb)) != NULL) - (void) tsleep((void *)gccb, PCATCH | PRIBIO, "iirshw", 100 * hz); + mtx_sleep(gccb, &gdt->sc_lock, PCATCH | PRIBIO, "iirshw", 100 * hz); /* flush */ for (i = 0; i < GDT_MAX_HDRIVES; ++i) { @@ -1451,15 +1442,15 @@ iir_shutdown( void *arg, int howto ) ucmd->service = GDT_CACHESERVICE; ucmd->OpCode = GDT_FLUSH; ucmd->u.cache.DeviceNo = i; - lock = splcam(); TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links); ucmd->complete_flag = FALSE; - splx(lock); gdt_next(gdt); if (!ucmd->complete_flag) - (void) tsleep((void *)ucmd, PCATCH|PRIBIO, "iirshw", 10*hz); + mtx_sleep(ucmd, &gdt->sc_lock, PCATCH | PRIBIO, "iirshw", + 10 * hz); } } + mtx_unlock(&gdt->sc_lock); free(ucmd, M_DEVBUF); printf("Done.\n"); @@ -1469,29 +1460,33 @@ void iir_intr(void *arg) { struct gdt_softc *gdt = arg; + + mtx_lock(&gdt->sc_lock); + iir_intr_locked(gdt); + mtx_unlock(&gdt->sc_lock); +} + +int +iir_intr_locked(struct gdt_softc *gdt) +{ struct gdt_intr_ctx ctx; - int lock = 0; struct gdt_ccb *gccb; gdt_ucmd_t *ucmd; u_int32_t cnt; GDT_DPRINTF(GDT_D_INTR, ("gdt_intr(%p)\n", gdt)); + mtx_assert(&gdt->sc_lock, MA_OWNED); + /* If polling and we were not called from gdt_wait, just return */ if ((gdt->sc_state & GDT_POLLING) && !(gdt->sc_state & GDT_POLL_WAIT)) - return; - - if (!(gdt->sc_state & GDT_POLLING)) - lock = splcam(); - gdt_wait_index = 0; + return (0); ctx.istatus = gdt->sc_get_status(gdt); if (ctx.istatus == 0x00) { - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); gdt->sc_status = GDT_S_NO_STATUS; - return; + return (ctx.istatus); } gdt->sc_intr(gdt, &ctx); @@ -1501,27 +1496,18 @@ iir_intr(void *arg) gdt->sc_info = ctx.info; gdt->sc_info2 = ctx.info2; - if (gdt->sc_state & GDT_POLL_WAIT) { - gdt_wait_gdt = gdt; - gdt_wait_index = ctx.istatus; - } - if (ctx.istatus == GDT_ASYNCINDEX) { gdt_async_event(gdt, ctx.service); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); - return; + return (ctx.istatus); } if (ctx.istatus == GDT_SPEZINDEX) { GDT_DPRINTF(GDT_D_INVALID, - ("iir%d: Service unknown or not initialized!\n", - gdt->sc_hanum)); + ("%s: Service unknown or not initialized!\n", + device_get_nameunit(gdt->sc_devnode))); gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver); gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum; gdt_store_event(GDT_ES_DRIVER, 4, &gdt->sc_dvr); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); - return; + return (ctx.istatus); } gccb = &gdt->sc_gccbs[ctx.istatus - 2]; @@ -1529,18 +1515,16 @@ iir_intr(void *arg) switch (gccb->gc_flags) { case GDT_GCF_UNUSED: - GDT_DPRINTF(GDT_D_INVALID, ("iir%d: Index (%d) to unused command!\n", - gdt->sc_hanum, ctx.istatus)); + GDT_DPRINTF(GDT_D_INVALID, ("%s: Index (%d) to unused command!\n", + device_get_nameunit(gdt->sc_devnode), ctx.istatus)); gdt->sc_dvr.size = sizeof(gdt->sc_dvr.eu.driver); gdt->sc_dvr.eu.driver.ionode = gdt->sc_hanum; gdt->sc_dvr.eu.driver.index = ctx.istatus; gdt_store_event(GDT_ES_DRIVER, 1, &gdt->sc_dvr); gdt_free_ccb(gdt, gccb); - /* fallthrough */ + break; case GDT_GCF_INTERNAL: - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); break; case GDT_GCF_IOCTL: @@ -1549,8 +1533,6 @@ iir_intr(void *arg) GDT_DPRINTF(GDT_D_DEBUG, ("iir_intr(%p) ioctl: gccb %p busy\n", gdt, gccb)); TAILQ_INSERT_HEAD(&gdt->sc_ucmd_queue, ucmd, links); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); } else { ucmd->status = gdt->sc_status; ucmd->info = gdt->sc_info; @@ -1573,8 +1555,6 @@ iir_intr(void *arg) bcopy(gccb->gc_scratch, ucmd->data, cnt); } gdt_free_ccb(gdt, gccb); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); /* wakeup */ wakeup(ucmd); } @@ -1584,11 +1564,11 @@ iir_intr(void *arg) default: gdt_free_ccb(gdt, gccb); gdt_sync_event(gdt, ctx.service, ctx.istatus, gccb); - if (!(gdt->sc_state & GDT_POLLING)) - splx(lock); gdt_next(gdt); break; } + + return (ctx.istatus); } int @@ -1604,8 +1584,7 @@ gdt_async_event(struct gdt_softc *gdt, int service) DELAY(1); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } bzero(gccb->gc_cmd, GDT_CMD_SZ); @@ -1624,8 +1603,8 @@ gdt_async_event(struct gdt_softc *gdt, int service) sizeof(u_int32_t)); gdt->sc_cmd_cnt = 0; gdt->sc_copy_cmd(gdt, gccb); - printf("iir%d: [PCI %d/%d] ", - gdt->sc_hanum,gdt->sc_bus,gdt->sc_slot); + device_printf(gdt->sc_devnode, "[PCI %d/%d] ", gdt->sc_bus, + gdt->sc_slot); gdt->sc_release_event(gdt); } @@ -1644,7 +1623,7 @@ gdt_async_event(struct gdt_softc *gdt, int service) *(u_int32_t *)gdt->sc_dvr.eu.async.scsi_coord = gdt->sc_info2; } gdt_store_event(GDT_ES_ASYNC, service, &gdt->sc_dvr); - printf("iir%d: %s\n", gdt->sc_hanum, gdt->sc_dvr.event_string); + device_printf(gdt->sc_devnode, "%s\n", gdt->sc_dvr.event_string); } return (0); @@ -1679,8 +1658,7 @@ gdt_sync_event(struct gdt_softc *gdt, int service, bzero(gccb->gc_cmd, GDT_CMD_SZ); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } gccb->gc_service = service; @@ -1723,8 +1701,7 @@ gdt_sync_event(struct gdt_softc *gdt, int service, bzero(gccb->gc_cmd, GDT_CMD_SZ); gccb = gdt_get_ccb(gdt); if (gccb == NULL) { - printf("iir%d: No free command index found\n", - gdt->sc_hanum); + device_printf(gdt->sc_devnode, "No free command index found\n"); return (1); } gccb->gc_service = service; @@ -1748,7 +1725,7 @@ gdt_sync_event(struct gdt_softc *gdt, int service, printf("\n"); return (0); } else { - untimeout(iir_timeout, gccb, gccb->gc_timeout_ch); + callout_stop(&gccb->gc_timeout); if (gdt->sc_status == GDT_S_BSY) { GDT_DPRINTF(GDT_D_DEBUG, ("gdt_sync_event(%p) gccb %p busy\n", gdt, gccb)); @@ -1816,7 +1793,7 @@ gdt_sync_event(struct gdt_softc *gdt, int service, } /* Controller event handling functions */ -gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx, +void gdt_store_event(u_int16_t source, u_int16_t idx, gdt_evt_data *evt) { gdt_evt_str *e; @@ -1824,8 +1801,9 @@ gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx, GDT_DPRINTF(GDT_D_MISC, ("gdt_store_event(%d, %d)\n", source, idx)); if (source == 0) /* no source -> no event */ - return 0; + return; + mtx_lock(&elock); if (ebuffer[elastidx].event_source == source && ebuffer[elastidx].event_idx == idx && ((evt->size != 0 && ebuffer[elastidx].event_data.size != 0 && @@ -1858,16 +1836,16 @@ gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx, e->event_data = *evt; e->application = 0; } - return e; + mtx_unlock(&elock); } int gdt_read_event(int handle, gdt_evt_str *estr) { gdt_evt_str *e; - int eindex, lock; + int eindex; GDT_DPRINTF(GDT_D_MISC, ("gdt_read_event(%d)\n", handle)); - lock = splcam(); + mtx_lock(&elock); if (handle == -1) eindex = eoldidx; else @@ -1875,7 +1853,7 @@ int gdt_read_event(int handle, gdt_evt_str *estr) estr->event_source = 0; if (eindex >= GDT_MAX_EVENTS) { - splx(lock); + mtx_unlock(&elock); return eindex; } e = &ebuffer[eindex]; @@ -1888,7 +1866,7 @@ int gdt_read_event(int handle, gdt_evt_str *estr) } memcpy(estr, e, sizeof(gdt_evt_str)); } - splx(lock); + mtx_unlock(&elock); return eindex; } @@ -1896,10 +1874,10 @@ void gdt_readapp_event(u_int8_t application, gdt_evt_str *estr) { gdt_evt_str *e; int found = FALSE; - int eindex, lock; + int eindex; GDT_DPRINTF(GDT_D_MISC, ("gdt_readapp_event(%d)\n", application)); - lock = splcam(); + mtx_lock(&elock); eindex = eoldidx; for (;;) { e = &ebuffer[eindex]; @@ -1919,13 +1897,15 @@ void gdt_readapp_event(u_int8_t application, gdt_evt_str *estr) memcpy(estr, e, sizeof(gdt_evt_str)); else estr->event_source = 0; - splx(lock); + mtx_unlock(&elock); } void gdt_clear_events() { GDT_DPRINTF(GDT_D_MISC, ("gdt_clear_events\n")); + mtx_lock(&elock); eoldidx = elastidx = 0; ebuffer[0].event_source = 0; + mtx_unlock(&elock); } diff --git a/sys/dev/iir/iir.h b/sys/dev/iir/iir.h index de7b641257e..40debb518ed 100644 --- a/sys/dev/iir/iir.h +++ b/sys/dev/iir/iir.h @@ -591,6 +591,7 @@ struct gdt_intr_ctx { /* softc structure */ struct gdt_softc { device_t sc_devnode; + struct mtx sc_lock; int sc_hanum; int sc_class; /* Controller class */ #define GDT_MPR 0x05 @@ -608,9 +609,7 @@ struct gdt_softc { #define GDT_SHUTDOWN 0x02 #define GDT_POLL_WAIT 0x80 struct cdev *sc_dev; - bus_space_tag_t sc_dpmemt; - bus_space_handle_t sc_dpmemh; - bus_addr_t sc_dpmembase; + struct resource *sc_dpmem; bus_dma_tag_t sc_parent_dmat; bus_dma_tag_t sc_buffer_dmat; bus_dma_tag_t sc_gcscratch_dmat; @@ -684,9 +683,8 @@ struct gdt_ccb { union ccb *gc_ccb; gdt_ucmd_t *gc_ucmd; bus_dmamap_t gc_dmamap; - struct callout_handle gc_timeout_ch; + struct callout gc_timeout; int gc_map_flag; - int gc_timeout; u_int8_t gc_service; u_int8_t gc_cmd_index; u_int8_t gc_flags; @@ -738,15 +736,14 @@ gdt_dec32(u_int8_t *addr) } #endif -extern TAILQ_HEAD(gdt_softc_list, gdt_softc) gdt_softcs; extern u_int8_t gdt_polling; -struct cdev *gdt_make_dev(int unit); +struct cdev *gdt_make_dev(struct gdt_softc *gdt); void gdt_destroy_dev(struct cdev *dev); void gdt_next(struct gdt_softc *gdt); void gdt_free_ccb(struct gdt_softc *gdt, struct gdt_ccb *gccb); -gdt_evt_str *gdt_store_event(u_int16_t source, u_int16_t idx, +void gdt_store_event(u_int16_t source, u_int16_t idx, gdt_evt_data *evt); int gdt_read_event(int handle, gdt_evt_str *estr); void gdt_readapp_event(u_int8_t app, gdt_evt_str *estr); diff --git a/sys/dev/iir/iir_ctrl.c b/sys/dev/iir/iir_ctrl.c index 94b18ddffae..65088d07de8 100644 --- a/sys/dev/iir/iir_ctrl.c +++ b/sys/dev/iir/iir_ctrl.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -52,12 +53,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include /* Entry points and other prototypes */ -static struct gdt_softc *gdt_minor2softc(int minor_no); +static struct gdt_softc *gdt_minor2softc(struct cdev *dev, int minor_no); static d_open_t iir_open; static d_close_t iir_close; @@ -68,7 +70,6 @@ static d_ioctl_t iir_ioctl; /* Normally, this is a static structure. But we need it in pci/iir_pci.c */ static struct cdevsw iir_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = iir_open, .d_close = iir_close, .d_read = iir_read, @@ -77,11 +78,10 @@ static struct cdevsw iir_cdevsw = { .d_name = "iir", }; -/* -static int iir_devsw_installed = 0; -*/ #ifndef SDEV_PER_HBA static int sdev_made = 0; +static struct sx sdev_lock; +SX_SYSINIT(iir_sdev_lock, &sdev_lock, "iir sdev"); #endif extern int gdt_cnt; extern gdt_statist_t gdt_stat; @@ -91,19 +91,22 @@ extern gdt_statist_t gdt_stat; * make a special device and return the dev_t */ struct cdev * -gdt_make_dev(int unit) +gdt_make_dev(struct gdt_softc *gdt) { struct cdev *dev; #ifdef SDEV_PER_HBA - dev = make_dev(&iir_cdevsw, hba2minor(unit), UID_ROOT, GID_OPERATOR, + dev = make_dev(&iir_cdevsw, 0, UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "iir%d", unit); + dev->si_drv1 = gdt; #else + sx_xlock(&sdev_lock); if (sdev_made) - return (0); + return (NULL); dev = make_dev(&iir_cdevsw, 0, UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR, "iir"); sdev_made = 1; + sx_xunlock(&sdev_lock); #endif return (dev); } @@ -120,22 +123,23 @@ gdt_destroy_dev(struct cdev *dev) * return the pointer to its softc structure */ static struct gdt_softc * -gdt_minor2softc(int minor_no) +gdt_minor2softc(struct cdev *dev, int minor_no) { - struct gdt_softc *gdt; - int hanum; - #ifdef SDEV_PER_HBA - hanum = minor2hba(minor_no); + + return (dev->si_drv1); #else - hanum = minor_no; + devclass_t dc; + device_t child; + + dc = devclass_find("iir"); + if (dc == NULL) + return (NULL); + child = devclass_get_device(dc, minor_no); + if (child == NULL) + return (NULL); + return (device_get_softc(child)); #endif - - for (gdt = TAILQ_FIRST(&gdt_softcs); - gdt != NULL && gdt->sc_hanum != hanum; - gdt = TAILQ_NEXT(gdt, links)); - - return (gdt); } static int @@ -143,16 +147,6 @@ iir_open(struct cdev *dev, int flags, int fmt, struct thread * p) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_open()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -161,16 +155,6 @@ iir_close(struct cdev *dev, int flags, int fmt, struct thread * p) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_close()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -179,16 +163,6 @@ iir_write(struct cdev *dev, struct uio * uio, int ioflag) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_write()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -197,16 +171,6 @@ iir_read(struct cdev *dev, struct uio * uio, int ioflag) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_read()\n")); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif - return (0); } @@ -221,15 +185,6 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread { GDT_DPRINTF(GDT_D_DEBUG, ("iir_ioctl() cmd 0x%lx\n",cmd)); -#ifdef SDEV_PER_HBA - int minor_no; - struct gdt_softc *gdt; - - minor_no = dev2unit(dev); - gdt = gdt_minor2softc(minor_no); - if (gdt == NULL) - return (ENXIO); -#endif ++gdt_stat.io_count_act; if (gdt_stat.io_count_act > gdt_stat.io_count_max) gdt_stat.io_count_max = gdt_stat.io_count_act; @@ -239,19 +194,19 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread { gdt_ucmd_t *ucmd; struct gdt_softc *gdt; - int lock; ucmd = (gdt_ucmd_t *)cmdarg; - gdt = gdt_minor2softc(ucmd->io_node); + gdt = gdt_minor2softc(dev, ucmd->io_node); if (gdt == NULL) return (ENXIO); - lock = splcam(); + mtx_lock(&gdt->sc_lock); TAILQ_INSERT_TAIL(&gdt->sc_ucmd_queue, ucmd, links); ucmd->complete_flag = FALSE; - splx(lock); gdt_next(gdt); if (!ucmd->complete_flag) - (void) tsleep((void *)ucmd, PCATCH | PRIBIO, "iirucw", 0); + (void) mtx_sleep(ucmd, &gdt->sc_lock, PCATCH | PRIBIO, "iirucw", + 0); + mtx_unlock(&gdt->sc_lock); break; } @@ -268,7 +223,7 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread struct gdt_softc *gdt; p = (gdt_ctrt_t *)cmdarg; - gdt = gdt_minor2softc(p->io_node); + gdt = gdt_minor2softc(dev, p->io_node); if (gdt == NULL) return (ENXIO); /* only RP controllers */ @@ -298,15 +253,9 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread p = (gdt_osv_t *)cmdarg; p->oscode = 10; - p->version = osrelease[0] - '0'; - if (osrelease[1] == '.') - p->subversion = osrelease[2] - '0'; - else - p->subversion = 0; - if (osrelease[3] == '.') - p->revision = osrelease[4] - '0'; - else - p->revision = 0; + p->version = osreldate / 100000; + p->subversion = osreldate / 1000 % 100; + p->revision = 0; strcpy(p->name, ostype); break; } @@ -318,7 +267,6 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread case GDT_IOCTL_EVENT: { gdt_event_t *p; - int lock; p = (gdt_event_t *)cmdarg; if (p->erase == 0xff) { @@ -330,14 +278,10 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.sync); else p->dvr.event_data.size = sizeof(p->dvr.event_data.eu.async); - lock = splcam(); gdt_store_event(p->dvr.event_source, p->dvr.event_idx, &p->dvr.event_data); - splx(lock); } else if (p->erase == 0xfe) { - lock = splcam(); gdt_clear_events(); - splx(lock); } else if (p->erase == 0) { p->handle = gdt_read_event(p->handle, &p->dvr); } else { @@ -362,18 +306,3 @@ iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread --gdt_stat.io_count_act; return (0); } - -/* -static void -iir_drvinit(void *unused) -{ - GDT_DPRINTF(GDT_D_DEBUG, ("iir_drvinit()\n")); - - if (!iir_devsw_installed) { - cdevsw_add(&iir_cdevsw); - iir_devsw_installed = 1; - } -} - -SYSINIT(iir_dev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, iir_drvinit, NULL) -*/ diff --git a/sys/dev/iir/iir_pci.c b/sys/dev/iir/iir_pci.c index ec54d49b4cb..42e1c815cc3 100644 --- a/sys/dev/iir/iir_pci.c +++ b/sys/dev/iir/iir_pci.c @@ -183,15 +183,18 @@ static int iir_pci_attach(device_t dev) { struct gdt_softc *gdt; - struct resource *io = NULL, *irq = NULL; + struct resource *irq = NULL; int retries, rid, error = 0; void *ih; u_int8_t protocol; - + + gdt = device_get_softc(dev); + mtx_init(&gdt->sc_lock, "iir", NULL, MTX_DEF); + /* map DPMEM */ rid = PCI_DPMEM; - io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); - if (io == NULL) { + gdt->sc_dpmem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (gdt->sc_dpmem == NULL) { device_printf(dev, "can't allocate register resources\n"); error = ENOMEM; goto err; @@ -207,12 +210,8 @@ iir_pci_attach(device_t dev) goto err; } - gdt = device_get_softc(dev); gdt->sc_devnode = dev; gdt->sc_init_level = 0; - gdt->sc_dpmemt = rman_get_bustag(io); - gdt->sc_dpmemh = rman_get_bushandle(io); - gdt->sc_dpmembase = rman_get_start(io); gdt->sc_hanum = device_get_unit(dev); gdt->sc_bus = pci_get_bus(dev); gdt->sc_slot = pci_get_slot(dev); @@ -227,85 +226,70 @@ iir_pci_attach(device_t dev) /* initialize RP controller */ /* check and reset interface area */ - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC, - htole32(GDT_MPR_MAGIC)); - if (bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC) != - htole32(GDT_MPR_MAGIC)) { - printf("cannot access DPMEM at 0x%jx (shadowed?)\n", - (uintmax_t)gdt->sc_dpmembase); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC, htole32(GDT_MPR_MAGIC)); + if (bus_read_4(gdt->sc_dpmem, GDT_MPR_IC) != htole32(GDT_MPR_MAGIC)) { + device_printf(dev, "cannot access DPMEM at 0x%lx (shadowed?)\n", + rman_get_start(gdt->sc_dpmem)); error = ENXIO; goto err; } - bus_space_set_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_I960_SZ, htole32(0), - GDT_MPR_SZ >> 2); + bus_set_region_4(gdt->sc_dpmem, GDT_I960_SZ, htole32(0), GDT_MPR_SZ >> 2); /* Disable everything */ - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN, - bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_EDOOR_EN) | 4); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, - 0); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_CMD_INDEX, - 0); + bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, + bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) | 4); + bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_CMD_INDEX, 0); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO, - htole32(gdt->sc_dpmembase)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, - 0xff); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, + htole32(rman_get_start(gdt->sc_dpmem))); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; - while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_STATUS) != 0xff) { + while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xff) { if (--retries == 0) { - printf("DEINIT failed\n"); + device_printf(dev, "DEINIT failed\n"); error = ENXIO; goto err; } DELAY(1); } - protocol = (uint8_t)le32toh(bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, - 0); + protocol = (uint8_t)le32toh(bus_read_4(gdt->sc_dpmem, + GDT_MPR_IC + GDT_S_INFO)); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); if (protocol != GDT_PROTOCOL_VERSION) { - printf("unsupported protocol %d\n", protocol); + device_printf(dev, "unsupported protocol %d\n", protocol); error = ENXIO; goto err; } - /* special commnd to controller BIOS */ - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_INFO, - htole32(0)); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), htole32(0)); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), - htole32(1)); - bus_space_write_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), - htole32(0)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX, - 0xfe); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); + /* special command to controller BIOS */ + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO, htole32(0)); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), + htole32(0)); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), + htole32(1)); + bus_write_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), + htole32(0)); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_CMD_INDX, 0xfe); + bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); DELAY(20); retries = GDT_RETRIES; - while (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { + while (bus_read_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS) != 0xfe) { if (--retries == 0) { - printf("initialization error\n"); + device_printf(dev, "initialization error\n"); error = ENXIO; goto err; } DELAY(1); } - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_IC + GDT_S_STATUS, - 0); + bus_write_1(gdt->sc_dpmem, GDT_MPR_IC + GDT_S_STATUS, 0); gdt->sc_ic_all_size = GDT_MPR_SZ; @@ -326,7 +310,7 @@ iir_pci_attach(device_t dev) /*nsegments*/GDT_MAXSG, /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, &gdt->sc_parent_dmat) != 0) { + /*lockarg*/&gdt->sc_lock, &gdt->sc_parent_dmat) != 0) { error = ENXIO; goto err; } @@ -342,7 +326,7 @@ iir_pci_attach(device_t dev) iir_attach(gdt); /* associate interrupt handler */ - if (bus_setup_intr( dev, irq, INTR_TYPE_CAM, + if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_MPSAFE, NULL, iir_intr, gdt, &ih )) { device_printf(dev, "Unable to register interrupt handler\n"); error = ENXIO; @@ -355,10 +339,11 @@ iir_pci_attach(device_t dev) err: if (irq) bus_release_resource( dev, SYS_RES_IRQ, 0, irq ); -/* - if (io) - bus_release_resource( dev, SYS_RES_MEMORY, rid, io ); -*/ + + if (gdt->sc_dpmem) + bus_release_resource( dev, SYS_RES_MEMORY, rid, gdt->sc_dpmem ); + mtx_destroy(&gdt->sc_lock); + return (error); } @@ -371,11 +356,9 @@ gdt_pci_enable_intr(struct gdt_softc *gdt) switch(GDT_CLASS(gdt)) { case GDT_MPR: - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_EDOOR, 0xff); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN, - bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_EDOOR_EN) & ~4); + bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_EDOOR_EN, + bus_read_1(gdt->sc_dpmem, GDT_EDOOR_EN) & ~4); break; } } @@ -396,15 +379,14 @@ gdt_mpr_copy_cmd(struct gdt_softc *gdt, struct gdt_ccb *gccb) gdt->sc_cmd_off += cp_count; - bus_space_write_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_DPR_CMD + dp_offset, - (u_int32_t *)gccb->gc_cmd, cp_count >> 2); - bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET, - htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset)); - bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID, - htole16(gccb->gc_service)); + bus_write_region_4(gdt->sc_dpmem, GDT_MPR_IC + GDT_DPR_CMD + dp_offset, + (u_int32_t *)gccb->gc_cmd, cp_count >> 2); + bus_write_2(gdt->sc_dpmem, + GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET, + htole16(GDT_DPMEM_COMMAND_OFFSET + dp_offset)); + bus_write_2(gdt->sc_dpmem, + GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID, + htole16(gccb->gc_service)); } u_int8_t @@ -412,7 +394,7 @@ gdt_mpr_get_status(struct gdt_softc *gdt) { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_get_status(%p) ", gdt)); - return bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR); + return bus_read_1(gdt->sc_dpmem, GDT_MPR_EDOOR); } void @@ -422,39 +404,32 @@ gdt_mpr_intr(struct gdt_softc *gdt, struct gdt_intr_ctx *ctx) GDT_DPRINTF(GDT_D_INTR, ("gdt_mpr_intr(%p) ", gdt)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff); + bus_write_1(gdt->sc_dpmem, GDT_MPR_EDOOR, 0xff); if (ctx->istatus & 0x80) { /* error flag */ ctx->istatus &= ~0x80; - ctx->cmd_status = bus_space_read_2(gdt->sc_dpmemt, - gdt->sc_dpmemh, GDT_MPR_STATUS); + ctx->cmd_status = bus_read_2(gdt->sc_dpmem, GDT_MPR_STATUS); } else /* no error */ ctx->cmd_status = GDT_S_OK; - ctx->info = - bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_INFO); - ctx->service = - bus_space_read_2(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SERVICE); - ctx->info2 = - bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_INFO + sizeof (u_int32_t)); + ctx->info = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO); + ctx->service = bus_read_2(gdt->sc_dpmem, GDT_MPR_SERVICE); + ctx->info2 = bus_read_4(gdt->sc_dpmem, GDT_MPR_INFO + sizeof (u_int32_t)); /* event string */ if (ctx->istatus == GDT_ASYNCINDEX) { if (ctx->service != GDT_SCREENSERVICE && (gdt->sc_fw_vers & 0xff) >= 0x1a) { - gdt->sc_dvr.severity = - bus_space_read_1(gdt->sc_dpmemt,gdt->sc_dpmemh, GDT_SEVERITY); + gdt->sc_dvr.severity = bus_read_1(gdt->sc_dpmem, GDT_SEVERITY); for (i = 0; i < 256; ++i) { - gdt->sc_dvr.event_string[i] = - bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_EVT_BUF + i); + gdt->sc_dvr.event_string[i] = bus_read_1(gdt->sc_dpmem, + GDT_EVT_BUF + i); if (gdt->sc_dvr.event_string[i] == 0) break; } } } - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA1, 0); + bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA1, 0); } void @@ -462,7 +437,7 @@ gdt_mpr_release_event(struct gdt_softc *gdt) { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_release_event(%p) ", gdt)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1); + bus_write_1(gdt->sc_dpmem, GDT_MPR_LDOOR, 1); } void @@ -470,7 +445,7 @@ gdt_mpr_set_sema0(struct gdt_softc *gdt) { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_set_sema0(%p) ", gdt)); - bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA0, 1); + bus_write_1(gdt->sc_dpmem, GDT_MPR_SEMA0, 1); } int @@ -478,6 +453,5 @@ gdt_mpr_test_busy(struct gdt_softc *gdt) { GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_test_busy(%p) ", gdt)); - return (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, - GDT_MPR_SEMA0) & 1); + return (bus_read_1(gdt->sc_dpmem, GDT_MPR_SEMA0) & 1); } diff --git a/sys/dev/ips/ips.c b/sys/dev/ips/ips.c index 4de98ce7475..7ef3ba7beb4 100644 --- a/sys/dev/ips/ips.c +++ b/sys/dev/ips/ips.c @@ -41,7 +41,6 @@ MALLOC_DEFINE(M_IPSBUF, "ipsbuf","IPS driver buffer"); static struct cdevsw ips_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = ips_open, .d_close = ips_close, .d_ioctl = ips_ioctl, @@ -74,14 +73,19 @@ static const char* ips_adapter_name[] = { static int ips_open(struct cdev *dev, int flags, int fmt, struct thread *td) { ips_softc_t *sc = dev->si_drv1; + mtx_lock(&sc->queue_mtx); sc->state |= IPS_DEV_OPEN; + mtx_unlock(&sc->queue_mtx); return 0; } static int ips_close(struct cdev *dev, int flags, int fmt, struct thread *td) { ips_softc_t *sc = dev->si_drv1; + + mtx_lock(&sc->queue_mtx); sc->state &= ~IPS_DEV_OPEN; + mtx_unlock(&sc->queue_mtx); return 0; } @@ -299,7 +303,7 @@ static void ips_timeout(void *arg) int i, state = 0; ips_command_t *command; - mtx_lock(&sc->queue_mtx); + mtx_assert(&sc->queue_mtx, MA_OWNED); command = &sc->commandarray[0]; for(i = 0; i < sc->max_cmds; i++){ if(!command[i].timeout){ @@ -329,8 +333,7 @@ static void ips_timeout(void *arg) sc->state &= ~IPS_TIMEOUT; } if (sc->state != IPS_OFFLINE) - sc->timer = timeout(ips_timeout, sc, 10*hz); - mtx_unlock(&sc->queue_mtx); + callout_reset(&sc->timer, 10 * hz, ips_timeout, sc); } /* check card and initialize it */ @@ -379,7 +382,6 @@ int ips_adapter_init(ips_softc_t *sc) can handle */ sc->max_cmds = 1; ips_cmdqueue_init(sc); - callout_handle_init(&sc->timer); if(sc->ips_adapter_reinit(sc, 0)) goto error; @@ -417,7 +419,7 @@ int ips_adapter_init(ips_softc_t *sc) S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev)); sc->device_file->si_drv1 = sc; ips_diskdev_init(sc); - sc->timer = timeout(ips_timeout, sc, 10*hz); + callout_reset(&sc->timer, 10 * hz, ips_timeout, sc); return 0; error: @@ -492,7 +494,7 @@ int ips_adapter_free(ips_softc_t *sc) return EBUSY; } DEVICE_PRINTF(1, sc->dev, "free\n"); - untimeout(ips_timeout, sc, sc->timer); + callout_drain(&sc->timer); if(sc->sg_dmatag) bus_dma_tag_destroy(sc->sg_dmatag); diff --git a/sys/dev/ips/ips.h b/sys/dev/ips/ips.h index 1b32164d906..9ae4812b65f 100644 --- a/sys/dev/ips/ips.h +++ b/sys/dev/ips/ips.h @@ -56,13 +56,13 @@ MALLOC_DECLARE(M_IPSBUF); * IPS MACROS */ -#define ips_read_1(sc,offset) bus_space_read_1(sc->bustag, sc->bushandle, offset) -#define ips_read_2(sc,offset) bus_space_read_2(sc->bustag, sc->bushandle, offset) -#define ips_read_4(sc,offset) bus_space_read_4(sc->bustag, sc->bushandle, offset) +#define ips_read_1(sc,offset) bus_read_1(sc->iores, offset) +#define ips_read_2(sc,offset) bus_read_2(sc->iores, offset) +#define ips_read_4(sc,offset) bus_read_4(sc->iores, offset) -#define ips_write_1(sc,offset,value) bus_space_write_1(sc->bustag, sc->bushandle, offset, value) -#define ips_write_2(sc,offset,value) bus_space_write_2(sc->bustag, sc->bushandle, offset, value) -#define ips_write_4(sc,offset,value) bus_space_write_4(sc->bustag, sc->bushandle, offset, value) +#define ips_write_1(sc,offset,value) bus_write_1(sc->iores, offset, value) +#define ips_write_2(sc,offset,value) bus_write_2(sc->iores, offset, value) +#define ips_write_4(sc,offset,value) bus_write_4(sc->iores, offset, value) /* this is ugly. It zeros the end elements in an ips_command_t struct starting with the status element */ #define clear_ips_command(command) bzero(&((command)->status), (unsigned long)(&(command)[1])-(unsigned long)&((command)->status)) @@ -122,14 +122,12 @@ typedef struct ips_softc{ int rid; int irqrid; void * irqcookie; - bus_space_tag_t bustag; - bus_space_handle_t bushandle; bus_dma_tag_t adapter_dmatag; bus_dma_tag_t command_dmatag; bus_dma_tag_t sg_dmatag; device_t dev; struct cdev *device_file; - struct callout_handle timer; + struct callout timer; u_int16_t adapter_type; ips_adapter_info_t adapter_info; device_t diskdev[IPS_MAX_NUM_DRIVES]; diff --git a/sys/dev/ips/ips_pci.c b/sys/dev/ips/ips_pci.c index df917ed3729..efffb32eda5 100644 --- a/sys/dev/ips/ips_pci.c +++ b/sys/dev/ips/ips_pci.c @@ -61,20 +61,12 @@ static int ips_pci_attach(device_t dev) { ips_softc_t *sc; - - if (resource_disabled(device_get_name(dev), device_get_unit(dev))) { - device_printf(dev, "device is disabled\n"); - /* but return 0 so the !$)$)*!$*) unit isn't reused */ - return (0); - } DEVICE_PRINTF(1, dev, "in attach.\n"); sc = (ips_softc_t *)device_get_softc(dev); - if(!sc){ - printf("how is sc NULL?!\n"); - return (ENXIO); - } - bzero(sc, sizeof(ips_softc_t)); sc->dev = dev; + mtx_init(&sc->queue_mtx, "IPS bioqueue lock", NULL, MTX_DEF); + sema_init(&sc->cmd_sema, 0, "IPS Command Semaphore"); + callout_init_mtx(&sc->timer, &sc->queue_mtx, 0); if(pci_get_device(dev) == IPS_MORPHEUS_DEVICE_ID){ sc->ips_adapter_reinit = ips_morpheus_reinit; @@ -95,7 +87,7 @@ static int ips_pci_attach(device_t dev) goto error; /* make sure busmastering is on */ pci_enable_busmaster(dev); - /* seting up io space */ + /* setting up io space */ sc->iores = NULL; PRINTF(10, "trying MEMIO\n"); if(pci_get_device(dev) == IPS_COPPERHEAD_DEVICE_ID) @@ -116,8 +108,6 @@ static int ips_pci_attach(device_t dev) device_printf(dev, "resource allocation failed\n"); return (ENXIO); } - sc->bustag = rman_get_bustag(sc->iores); - sc->bushandle = rman_get_bushandle(sc->iores); /*allocate an interrupt. when does the irq become active? after leaving attach? */ sc->irqrid = 0; if(!(sc->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, @@ -144,13 +134,11 @@ static int ips_pci_attach(device_t dev) /* lockfunc */ NULL, /* lockarg */ NULL, &sc->adapter_dmatag) != 0) { - printf("IPS can't alloc dma tag\n"); + device_printf(dev, "can't alloc dma tag\n"); goto error; } sc->ips_ich.ich_func = ips_intrhook; sc->ips_ich.ich_arg = sc; - mtx_init(&sc->queue_mtx, "IPS bioqueue lock", NULL, MTX_DEF); - sema_init(&sc->cmd_sema, 0, "IPS Command Semaphore"); bioq_init(&sc->queue); if (config_intrhook_establish(&sc->ips_ich) != 0) { printf("IPS can't establish configuration hook\n"); diff --git a/sys/dev/iscsi/icl.c b/sys/dev/iscsi/icl.c index f56e494fea7..6bce1802042 100644 --- a/sys/dev/iscsi/icl.c +++ b/sys/dev/iscsi/icl.c @@ -758,7 +758,7 @@ icl_receive_thread(void *arg) * is enough data received to read the PDU. */ SOCKBUF_LOCK(&so->so_rcv); - available = so->so_rcv.sb_cc; + available = sbavail(&so->so_rcv); if (available < ic->ic_receive_len) { so->so_rcv.sb_lowat = ic->ic_receive_len; cv_wait(&ic->ic_receive_cv, &so->so_rcv.sb_mtx); diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 979426084dd..29960d75936 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -2136,10 +2136,9 @@ static void isp_refire_putback_atio(void *arg) { union ccb *ccb = arg; - ispsoftc_t *isp = XS_ISP(ccb); - ISP_LOCK(isp); + + ISP_ASSERT_LOCKED((ispsoftc_t *)XS_ISP(ccb)); isp_target_putback_atio(ccb); - ISP_UNLOCK(isp); } static void @@ -2147,13 +2146,13 @@ isp_refire_notify_ack(void *arg) { isp_tna_t *tp = arg; ispsoftc_t *isp = tp->isp; - ISP_LOCK(isp); + + ISP_ASSERT_LOCKED(isp); if (isp_notify_ack(isp, tp->not)) { - (void) timeout(isp_refire_notify_ack, tp, 5); + callout_schedule(&tp->timer, 5); } else { free(tp, M_DEVBUF); } - ISP_UNLOCK(isp); } @@ -2170,7 +2169,8 @@ isp_target_putback_atio(union ccb *ccb) if (qe == NULL) { xpt_print(ccb->ccb_h.path, "%s: Request Queue Overflow\n", __func__); - (void) timeout(isp_refire_putback_atio, ccb, 10); + callout_reset(&PISP_PCMD(ccb)->wdog, 10, + isp_refire_putback_atio, ccb); return; } memset(qe, 0, QENTRY_LEN); @@ -5964,7 +5964,9 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) } else { tp->not = NULL; } - (void) timeout(isp_refire_notify_ack, tp, 5); + callout_init_mtx(&tp->timer, &isp->isp_lock, 0); + callout_reset(&tp->timer, 5, + isp_refire_notify_ack, tp); } else { isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire"); } diff --git a/sys/dev/isp/isp_freebsd.h b/sys/dev/isp/isp_freebsd.h index 81dcd8d0919..812385ea2cf 100644 --- a/sys/dev/isp/isp_freebsd.h +++ b/sys/dev/isp/isp_freebsd.h @@ -158,6 +158,7 @@ typedef struct isp_timed_notify_ack { void *isp; void *not; uint8_t data[64]; /* sb QENTRY_LEN, but order of definitions is wrong */ + struct callout timer; } isp_tna_t; TAILQ_HEAD(isp_ccbq, ccb_hdr); @@ -399,8 +400,9 @@ struct isposinfo { /* * Locking macros... */ -#define ISP_LOCK(isp) mtx_lock(&isp->isp_osinfo.lock) -#define ISP_UNLOCK(isp) mtx_unlock(&isp->isp_osinfo.lock) +#define ISP_LOCK(isp) mtx_lock(&(isp)->isp_osinfo.lock) +#define ISP_UNLOCK(isp) mtx_unlock(&(isp)->isp_osinfo.lock) +#define ISP_ASSERT_LOCKED(isp) mtx_assert(&(isp)->isp_osinfo.lock, MA_OWNED) /* * Required Macros/Defines diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index 78fdb36b72b..df47b3db0b0 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -4385,7 +4385,7 @@ ixgbe_initialize_receive_units(struct adapter *adapter) * this code is moved elsewhere. */ if (adapter->num_queues > 1 && - adapter->hw.fc.requested_mode == ixgbe_fc_none) { + adapter->fc == ixgbe_fc_none) { srrctl |= IXGBE_SRRCTL_DROP_EN; } else { srrctl &= ~IXGBE_SRRCTL_DROP_EN; diff --git a/sys/dev/mcd/mcd.c b/sys/dev/mcd/mcd.c index 966acc2e598..4d2acd145ca 100644 --- a/sys/dev/mcd/mcd.c +++ b/sys/dev/mcd/mcd.c @@ -128,7 +128,7 @@ static void hsg2msf(int hsg, bcd_t *msf); static int msf2hsg(bcd_t *msf, int relative); static int mcd_volinfo(struct mcd_softc *); static int mcd_waitrdy(struct mcd_softc *,int dly); -static timeout_t mcd_timeout; +static void mcd_timeout(void *arg); static void mcd_doread(struct mcd_softc *, int state, struct mcd_mbx *mbxin); static void mcd_soft_reset(struct mcd_softc *); static int mcd_hard_reset(struct mcd_softc *); @@ -168,7 +168,7 @@ static struct cdevsw mcd_cdevsw = { .d_ioctl = mcdioctl, .d_strategy = mcdstrategy, .d_name = "mcd", - .d_flags = D_DISK | D_NEEDGIANT, + .d_flags = D_DISK, }; #define MCD_RETRYS 5 @@ -193,6 +193,7 @@ mcd_attach(struct mcd_softc *sc) unit = device_get_unit(sc->dev); + MCD_LOCK(sc); sc->data.flags |= MCDINIT; mcd_soft_reset(sc); bioq_init(&sc->data.head); @@ -201,11 +202,13 @@ mcd_attach(struct mcd_softc *sc) /* wire controller for interrupts and dma */ mcd_configure(sc); #endif + MCD_UNLOCK(sc); /* name filled in probe */ sc->mcd_dev_t = make_dev(&mcd_cdevsw, 8 * unit, UID_ROOT, GID_OPERATOR, 0640, "mcd%d", unit); sc->mcd_dev_t->si_drv1 = (void *)sc; + callout_init_mtx(&sc->timer, &sc->mtx, 0); return (0); } @@ -218,41 +221,49 @@ mcdopen(struct cdev *dev, int flags, int fmt, struct thread *td) sc = (struct mcd_softc *)dev->si_drv1; - /* not initialized*/ - if (!(sc->data.flags & MCDINIT)) - return (ENXIO); - /* invalidated in the meantime? mark all open part's invalid */ - if (!(sc->data.flags & MCDVALID) && sc->data.openflags) + MCD_LOCK(sc); + if (!(sc->data.flags & MCDVALID) && sc->data.openflags) { + MCD_UNLOCK(sc); return (ENXIO); + } - if (mcd_getstat(sc, 1) == -1) + if (mcd_getstat(sc, 1) == -1) { + MCD_UNLOCK(sc); return (EIO); + } if ( (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN)) || !(sc->data.status & MCDDSKIN)) for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) { - (void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdsn1", hz/WAIT_FRAC); - if ((r = mcd_getstat(sc, 1)) == -1) + (void) mtx_sleep(sc, &sc->mtx, PSOCK | PCATCH, + "mcdsn1", hz/WAIT_FRAC); + if ((r = mcd_getstat(sc, 1)) == -1) { + MCD_UNLOCK(sc); return (EIO); + } if (r != -2) break; } if (sc->data.status & MCDDOOROPEN) { + MCD_UNLOCK(sc); device_printf(sc->dev, "door is open\n"); return (ENXIO); } if (!(sc->data.status & MCDDSKIN)) { + MCD_UNLOCK(sc); device_printf(sc->dev, "no CD inside\n"); return (ENXIO); } if (sc->data.status & MCDDSKCHNG) { + MCD_UNLOCK(sc); device_printf(sc->dev, "CD not sensed\n"); return (ENXIO); } if (mcd_size(dev) < 0) { + MCD_UNLOCK(sc); device_printf(sc->dev, "failed to get disk size\n"); return (ENXIO); } @@ -262,10 +273,14 @@ mcdopen(struct cdev *dev, int flags, int fmt, struct thread *td) sc->data.flags |= MCDVALID; (void) mcd_lock_door(sc, MCD_LK_LOCK); - if (!(sc->data.flags & MCDVALID)) + if (!(sc->data.flags & MCDVALID)) { + MCD_UNLOCK(sc); return (ENXIO); + } - return mcd_read_toc(sc); + r = mcd_read_toc(sc); + MCD_UNLOCK(sc); + return (r); } static int @@ -275,12 +290,13 @@ mcdclose(struct cdev *dev, int flags, int fmt, struct thread *td) sc = (struct mcd_softc *)dev->si_drv1; - if (!(sc->data.flags & MCDINIT) || !sc->data.openflags) - return (ENXIO); + MCD_LOCK(sc); + KASSERT(sc->data.openflags, ("device not open")); (void) mcd_lock_door(sc, MCD_LK_UNLOCK); sc->data.openflags = 0; sc->data.partflags &= ~MCDREADRAW; + MCD_UNLOCK(sc); return (0); } @@ -293,6 +309,7 @@ mcdstrategy(struct bio *bp) sc = (struct mcd_softc *)bp->bio_dev->si_drv1; /* if device invalidated (e.g. media change, door open), error */ + MCD_LOCK(sc); if (!(sc->data.flags & MCDVALID)) { device_printf(sc->dev, "media changed\n"); bp->bio_error = EIO; @@ -321,11 +338,13 @@ mcdstrategy(struct bio *bp) /* now check whether we can perform processing */ mcd_start(sc); + MCD_UNLOCK(sc); return; bad: bp->bio_flags |= BIO_ERROR; done: + MCD_UNLOCK(sc); bp->bio_resid = bp->bio_bcount; biodone(bp); return; @@ -336,6 +355,7 @@ mcd_start(struct mcd_softc *sc) { struct bio *bp; + MCD_ASSERT_LOCKED(sc); if (sc->data.flags & MCDMBXBSY) { return; } @@ -365,8 +385,11 @@ mcdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *t sc = (struct mcd_softc *)dev->si_drv1; - if (mcd_getstat(sc, 1) == -1) /* detect disk change too */ + MCD_LOCK(sc); + if (mcd_getstat(sc, 1) == -1) { /* detect disk change too */ + MCD_UNLOCK(sc); return (EIO); + } MCD_TRACE("ioctl called 0x%lx\n", cmd); switch (cmd) { @@ -378,83 +401,114 @@ MCD_TRACE("ioctl called 0x%lx\n", cmd); case CDIOCSETMUTE: case CDIOCSETLEFT: case CDIOCSETRIGHT: + MCD_UNLOCK(sc); return (EINVAL); case CDIOCEJECT: - return mcd_eject(sc); + r = mcd_eject(sc); + MCD_UNLOCK(sc); + return (r); case CDIOCSETDEBUG: sc->data.debug = 1; + MCD_UNLOCK(sc); return (0); case CDIOCCLRDEBUG: sc->data.debug = 0; + MCD_UNLOCK(sc); return (0); case CDIOCRESET: - return mcd_hard_reset(sc); + r = mcd_hard_reset(sc); + MCD_UNLOCK(sc); + return (r); case CDIOCALLOW: - return mcd_lock_door(sc, MCD_LK_UNLOCK); + r = mcd_lock_door(sc, MCD_LK_UNLOCK); + MCD_UNLOCK(sc); + return (r); case CDIOCPREVENT: - return mcd_lock_door(sc, MCD_LK_LOCK); + r = mcd_lock_door(sc, MCD_LK_LOCK); + MCD_UNLOCK(sc); + return (r); case CDIOCCLOSE: - return mcd_inject(sc); + r = mcd_inject(sc); + MCD_UNLOCK(sc); + return (r); } if (!(sc->data.flags & MCDVALID)) { if ( (sc->data.status & (MCDDSKCHNG|MCDDOOROPEN)) || !(sc->data.status & MCDDSKIN)) for (retry = 0; retry < DISK_SENSE_SECS * WAIT_FRAC; retry++) { - (void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdsn2", hz/WAIT_FRAC); - if ((r = mcd_getstat(sc, 1)) == -1) + (void) mtx_sleep(sc, &sc->mtx, PSOCK | PCATCH, + "mcdsn2", hz/WAIT_FRAC); + if ((r = mcd_getstat(sc, 1)) == -1) { + MCD_UNLOCK(sc); return (EIO); + } if (r != -2) break; } if ( (sc->data.status & (MCDDOOROPEN|MCDDSKCHNG)) || !(sc->data.status & MCDDSKIN) || mcd_size(dev) < 0 - ) + ) { + MCD_UNLOCK(sc); return (ENXIO); + } sc->data.flags |= MCDVALID; sc->data.partflags |= MCDREADRAW; (void) mcd_lock_door(sc, MCD_LK_LOCK); - if (!(sc->data.flags & MCDVALID)) + if (!(sc->data.flags & MCDVALID)) { + MCD_UNLOCK(sc); return (ENXIO); + } } switch (cmd) { case DIOCGMEDIASIZE: *(off_t *)addr = (off_t)sc->data.disksize * sc->data.blksize; - return (0); + r = 0; + break; case DIOCGSECTORSIZE: *(u_int *)addr = sc->data.blksize; - return (0); - + r = 0; + break; case CDIOCPLAYTRACKS: - return mcd_playtracks(sc, (struct ioc_play_track *) addr); + r = mcd_playtracks(sc, (struct ioc_play_track *) addr); + break; case CDIOCPLAYBLOCKS: - return mcd_playblocks(sc, (struct ioc_play_blocks *) addr); + r = mcd_playblocks(sc, (struct ioc_play_blocks *) addr); + break; case CDIOCPLAYMSF: - return mcd_playmsf(sc, (struct ioc_play_msf *) addr); + r = mcd_playmsf(sc, (struct ioc_play_msf *) addr); + break; case CDIOCREADSUBCHANNEL_SYSSPACE: return mcd_subchan(sc, (struct ioc_read_subchannel *) addr, 1); case CDIOCREADSUBCHANNEL: return mcd_subchan(sc, (struct ioc_read_subchannel *) addr, 0); case CDIOREADTOCHEADER: - return mcd_toc_header(sc, (struct ioc_toc_header *) addr); + r = mcd_toc_header(sc, (struct ioc_toc_header *) addr); + break; case CDIOREADTOCENTRYS: return mcd_toc_entrys(sc, (struct ioc_read_toc_entry *) addr); case CDIOCRESUME: - return mcd_resume(sc); + r = mcd_resume(sc); + break; case CDIOCPAUSE: - return mcd_pause(sc); + r = mcd_pause(sc); + break; case CDIOCSTART: if (mcd_setmode(sc, MCD_MD_COOKED) != 0) - return (EIO); - return (0); + r = EIO; + else + r = 0; + break; case CDIOCSTOP: - return mcd_stop(sc); + r = mcd_stop(sc); + break; default: - return (ENOTTY); + r = ENOTTY; } - /*NOTREACHED*/ + MCD_UNLOCK(sc); + return (r); } static int @@ -762,6 +816,7 @@ mcd_timeout(void *arg) sc = (struct mcd_softc *)arg; + MCD_ASSERT_LOCKED(sc); mcd_doread(sc, sc->ch_state, sc->ch_mbxsave); } @@ -775,6 +830,7 @@ mcd_doread(struct mcd_softc *sc, int state, struct mcd_mbx *mbxin) int blknum; caddr_t addr; + MCD_ASSERT_LOCKED(sc); mbx = (state!=MCD_S_BEGIN) ? sc->ch_mbxsave : mbxin; bp = mbx->bp; @@ -789,15 +845,16 @@ retry_status: MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDGETSTAT); mbx->count = RDELAY_WAITSTAT; sc->ch_state = MCD_S_WAITSTAT; - sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz/100, mcd_timeout, sc); /* XXX */ return; case MCD_S_WAITSTAT: sc->ch_state = MCD_S_WAITSTAT; - untimeout(mcd_timeout,(caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- >= 0) { if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) { sc->ch_state = MCD_S_WAITSTAT; - timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz/100, + mcd_timeout, sc); /* XXX */ return; } sc->data.status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF; @@ -834,7 +891,7 @@ retry_mode: MCD_WRITE(sc, MCD_REG_COMMAND, rm); sc->ch_state = MCD_S_WAITMODE; - sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, mcd_timeout, sc); /* XXX */ return; } else { device_printf(sc->dev, "timeout getstatus\n"); @@ -843,14 +900,14 @@ retry_mode: case MCD_S_WAITMODE: sc->ch_state = MCD_S_WAITMODE; - untimeout(mcd_timeout, (caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- < 0) { device_printf(sc->dev, "timeout set mode\n"); goto readerr; } if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) { sc->ch_state = MCD_S_WAITMODE; - sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); + callout_reset(&sc->timer, hz / 100, mcd_timeout, sc); return; } sc->data.status = MCD_READ(sc, MCD_REG_STATUS) & 0xFF; @@ -878,7 +935,6 @@ nextblock: hsg2msf(blknum,rbuf.start_msf); retry_read: /* send the read command */ - critical_enter(); MCD_WRITE(sc, MCD_REG_COMMAND, sc->data.read_command); MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[0]); MCD_WRITE(sc, MCD_REG_COMMAND, rbuf.start_msf[1]); @@ -886,7 +942,6 @@ retry_read: MCD_WRITE(sc, MCD_REG_COMMAND, 0); MCD_WRITE(sc, MCD_REG_COMMAND, 0); MCD_WRITE(sc, MCD_REG_COMMAND, 1); - critical_exit(); /* Spin briefly (<= 2ms) to avoid missing next block */ for (i = 0; i < 20; i++) { @@ -898,11 +953,11 @@ retry_read: mbx->count = RDELAY_WAITREAD; sc->ch_state = MCD_S_WAITREAD; - sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, mcd_timeout, sc); /* XXX */ return; case MCD_S_WAITREAD: sc->ch_state = MCD_S_WAITREAD; - untimeout(mcd_timeout, (caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- > 0) { k = MCD_READ(sc, MCD_FLAGS); if (!(k & MFL_DATA_NOT_AVAIL)) { /* XXX */ @@ -947,7 +1002,7 @@ retry_read: goto changed; } sc->ch_state = MCD_S_WAITREAD; - sc->ch = timeout(mcd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, mcd_timeout, sc); /* XXX */ return; } else { device_printf(sc->dev, "timeout read data\n"); @@ -1010,7 +1065,8 @@ mcd_close_tray(struct mcd_softc *sc) MCD_WRITE(sc, MCD_REG_COMMAND, MCD_CMDCLOSETRAY); for (retry = 0; retry < CLOSE_TRAY_SECS * WAIT_FRAC; retry++) { if (MCD_READ(sc, MCD_FLAGS) & MFL_STATUS_NOT_AVAIL) - (void) tsleep((caddr_t)sc, PSOCK | PCATCH, "mcdcls", hz/WAIT_FRAC); + (void) mtx_sleep(sc, &sc->mtx, PSOCK | PCATCH, + "mcdcls", hz/WAIT_FRAC); else { if ((r = mcd_getstat(sc, 0)) == -1) return (EIO); @@ -1303,6 +1359,7 @@ mcd_toc_entrys(struct mcd_softc *sc, struct ioc_read_toc_entry *te) } /* copy the data back */ + MCD_UNLOCK(sc); return copyout(entries, te->data, n * sizeof(struct cd_toc_entry)); } @@ -1418,6 +1475,7 @@ mcd_subchan(struct mcd_softc *sc, struct ioc_read_subchannel *sch, int nocopyout break; } + MCD_UNLOCK(sc); if (nocopyout == 0) return copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len)); bcopy(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len)); diff --git a/sys/dev/mcd/mcd_isa.c b/sys/dev/mcd/mcd_isa.c index 8b71f105977..92e8adb5719 100644 --- a/sys/dev/mcd/mcd_isa.c +++ b/sys/dev/mcd/mcd_isa.c @@ -126,6 +126,7 @@ mcd_alloc_resources (device_t dev) sc = device_get_softc(dev); error = 0; + mtx_init(&sc->mtx, "mcd", NULL, MTX_DEF); if (sc->port_type) { sc->port = bus_alloc_resource_any(dev, sc->port_type, @@ -135,8 +136,6 @@ mcd_alloc_resources (device_t dev) error = ENOMEM; goto bad; } - sc->port_bst = rman_get_bustag(sc->port); - sc->port_bsh = rman_get_bushandle(sc->port); } if (sc->irq_type) { @@ -159,9 +158,6 @@ mcd_alloc_resources (device_t dev) } } - mtx_init(&sc->mtx, device_get_nameunit(dev), - "Interrupt lock", MTX_DEF | MTX_RECURSE); - bad: return (error); } @@ -175,18 +171,14 @@ mcd_release_resources (device_t dev) if (sc->irq_ih) bus_teardown_intr(dev, sc->irq, sc->irq_ih); - if (sc->port) { + if (sc->port) bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port); - sc->port_bst = 0; - sc->port_bsh = 0; - } if (sc->irq) bus_release_resource(dev, sc->irq_type, sc->irq_rid, sc->irq); if (sc->drq) bus_release_resource(dev, sc->drq_type, sc->drq_rid, sc->drq); - if (mtx_initialized(&sc->mtx) != 0) - mtx_destroy(&sc->mtx); + mtx_destroy(&sc->mtx); return; } diff --git a/sys/dev/mcd/mcdvar.h b/sys/dev/mcd/mcdvar.h index adfd4a4f419..71e45d0b0bd 100644 --- a/sys/dev/mcd/mcdvar.h +++ b/sys/dev/mcd/mcdvar.h @@ -41,8 +41,6 @@ struct mcd_softc { struct resource * port; int port_rid; int port_type; - bus_space_tag_t port_bst; - bus_space_handle_t port_bsh; struct resource * irq; int irq_rid; @@ -55,20 +53,19 @@ struct mcd_softc { struct mtx mtx; - struct callout_handle ch; + struct callout timer; int ch_state; struct mcd_mbx * ch_mbxsave; struct mcd_data data; }; -#define MCD_LOCK(_sc) splx(&(_sc)->mtx -#define MCD_UNLOCK(_sc) splx(&(_sc)->mtx +#define MCD_LOCK(_sc) mtx_lock(&_sc->mtx) +#define MCD_UNLOCK(_sc) mtx_unlock(&_sc->mtx) +#define MCD_ASSERT_LOCKED(_sc) mtx_assert(&_sc->mtx, MA_OWNED) -#define MCD_READ(_sc, _reg) \ - bus_space_read_1(_sc->port_bst, _sc->port_bsh, _reg) -#define MCD_WRITE(_sc, _reg, _val) \ - bus_space_write_1(_sc->port_bst, _sc->port_bsh, _reg, _val) +#define MCD_READ(_sc, _reg) bus_read_1(_sc->port, _reg) +#define MCD_WRITE(_sc, _reg, _val) bus_write_1(_sc->port, _reg, _val) int mcd_probe (struct mcd_softc *); int mcd_attach (struct mcd_softc *); diff --git a/sys/dev/mly/mly.c b/sys/dev/mly/mly.c index a58b21b8f08..1ea371a62a9 100644 --- a/sys/dev/mly/mly.c +++ b/sys/dev/mly/mly.c @@ -88,7 +88,8 @@ static void mly_periodic(void *data); static int mly_immediate_command(struct mly_command *mc); static int mly_start(struct mly_command *mc); static void mly_done(struct mly_softc *sc); -static void mly_complete(void *context, int pending); +static void mly_complete(struct mly_softc *sc); +static void mly_complete_handler(void *context, int pending); static int mly_alloc_command(struct mly_softc *sc, struct mly_command **mcp); static void mly_release_command(struct mly_command *mc); @@ -116,7 +117,7 @@ static void mly_printstate(struct mly_softc *sc); static void mly_print_command(struct mly_command *mc); static void mly_print_packet(struct mly_command *mc); static void mly_panic(struct mly_softc *sc, char *reason); -static int mly_timeout(struct mly_softc *sc); +static void mly_timeout(void *arg); #endif void mly_print_controller(int controller); @@ -151,7 +152,6 @@ MODULE_DEPEND(mly, cam, 1, 1, 1); static struct cdevsw mly_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = mly_user_open, .d_close = mly_user_close, .d_ioctl = mly_user_ioctl, @@ -216,8 +216,11 @@ mly_attach(device_t dev) debug_called(1); sc->mly_dev = dev; + mtx_init(&sc->mly_lock, "mly", NULL, MTX_DEF); + callout_init_mtx(&sc->mly_periodic, &sc->mly_lock, 0); #ifdef MLY_DEBUG + callout_init_mtx(&sc->mly_timeout, &sc->mly_lock, 0); if (device_get_unit(sc->mly_dev) == 0) mly_softc0 = sc; #endif @@ -238,7 +241,7 @@ mly_attach(device_t dev) /* * Initialise command-completion task. */ - TASK_INIT(&sc->mly_task_complete, 0, mly_complete, sc); + TASK_INIT(&sc->mly_task_complete, 0, mly_complete_handler, sc); /* disable interrupts before we start talking to the controller */ MLY_MASK_INTERRUPTS(sc); @@ -260,7 +263,10 @@ mly_attach(device_t dev) /* * Obtain controller feature information */ - if ((error = mly_get_controllerinfo(sc))) + MLY_LOCK(sc); + error = mly_get_controllerinfo(sc); + MLY_UNLOCK(sc); + if (error) goto out; /* @@ -274,13 +280,16 @@ mly_attach(device_t dev) * Get the current event counter for health purposes, populate the initial * health status buffer. */ - if ((error = mly_get_eventstatus(sc))) - goto out; + MLY_LOCK(sc); + error = mly_get_eventstatus(sc); /* * Enable memory-mailbox mode. */ - if ((error = mly_enable_mmbox(sc))) + if (error == 0) + error = mly_enable_mmbox(sc); + MLY_UNLOCK(sc); + if (error) goto out; /* @@ -297,6 +306,7 @@ mly_attach(device_t dev) /* * Mark all attached devices for rescan. */ + MLY_LOCK(sc); mly_scan_devices(sc); /* @@ -305,6 +315,7 @@ mly_attach(device_t dev) * the SCSI subsystem gets to us, courtesy of the "SCSI settling delay". */ mly_periodic((void *)sc); + MLY_UNLOCK(sc); /* * Create the control device. @@ -317,7 +328,7 @@ mly_attach(device_t dev) MLY_UNMASK_INTERRUPTS(sc); #ifdef MLY_DEBUG - timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz); + callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc); #endif out: @@ -353,8 +364,6 @@ mly_pci_attach(struct mly_softc *sc) mly_printf(sc, "can't allocate register window\n"); goto fail; } - sc->mly_btag = rman_get_bustag(sc->mly_regs_resource); - sc->mly_bhandle = rman_get_bushandle(sc->mly_regs_resource); /* * Allocate and connect our interrupt. @@ -365,7 +374,7 @@ mly_pci_attach(struct mly_softc *sc) mly_printf(sc, "can't allocate interrupt\n"); goto fail; } - if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY, NULL, mly_intr, sc, &sc->mly_intr)) { + if (bus_setup_intr(sc->mly_dev, sc->mly_irq, INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE, NULL, mly_intr, sc, &sc->mly_intr)) { mly_printf(sc, "can't set up interrupt\n"); goto fail; } @@ -405,7 +414,7 @@ mly_pci_attach(struct mly_softc *sc) BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ 0, /* flags */ busdma_lock_mutex, /* lockfunc */ - &Giant, /* lockarg */ + &sc->mly_lock, /* lockarg */ &sc->mly_buffer_dmat)) { mly_printf(sc, "can't allocate buffer DMA tag\n"); goto fail; @@ -511,18 +520,25 @@ mly_shutdown(device_t dev) struct mly_softc *sc = device_get_softc(dev); debug_called(1); - - if (sc->mly_state & MLY_STATE_OPEN) + + MLY_LOCK(sc); + if (sc->mly_state & MLY_STATE_OPEN) { + MLY_UNLOCK(sc); return(EBUSY); + } /* kill the periodic event */ - untimeout(mly_periodic, sc, sc->mly_periodic); + callout_stop(&sc->mly_periodic); +#ifdef MLY_DEBUG + callout_stop(&sc->mly_timeout); +#endif /* flush controller */ mly_printf(sc, "flushing cache..."); printf("%s\n", mly_flush(sc) ? "failed" : "done"); MLY_MASK_INTERRUPTS(sc); + MLY_UNLOCK(sc); return(0); } @@ -538,7 +554,9 @@ mly_intr(void *arg) debug_called(2); + MLY_LOCK(sc); mly_done(sc); + MLY_UNLOCK(sc); }; /******************************************************************************** @@ -676,6 +694,13 @@ mly_free(struct mly_softc *sc) /* Remove the management device */ destroy_dev(sc->mly_dev_t); + if (sc->mly_intr) + bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr); + callout_drain(&sc->mly_periodic); +#ifdef MLY_DEBUG + callout_drain(&sc->mly_timeout); +#endif + /* detach from CAM */ mly_cam_detach(sc); @@ -711,8 +736,6 @@ mly_free(struct mly_softc *sc) bus_dma_tag_destroy(sc->mly_mmbox_dmat); /* disconnect the interrupt handler */ - if (sc->mly_intr) - bus_teardown_intr(sc->mly_dev, sc->mly_irq, sc->mly_intr); if (sc->mly_irq != NULL) bus_release_resource(sc->mly_dev, SYS_RES_IRQ, sc->mly_irq_rid, sc->mly_irq); @@ -723,6 +746,8 @@ mly_free(struct mly_softc *sc) /* release the register window mapping */ if (sc->mly_regs_resource != NULL) bus_release_resource(sc->mly_dev, SYS_RES_MEMORY, sc->mly_regs_rid, sc->mly_regs_resource); + + mtx_destroy(&sc->mly_lock); } /******************************************************************************** @@ -1086,6 +1111,7 @@ mly_ioctl(struct mly_softc *sc, struct mly_command_ioctl *ioctl, void **data, si int error; debug_called(1); + MLY_ASSERT_LOCKED(sc); mc = NULL; if (mly_alloc_command(sc, &mc)) { @@ -1375,6 +1401,7 @@ mly_periodic(void *data) int bus, target; debug_called(2); + MLY_ASSERT_LOCKED(sc); /* * Scan devices. @@ -1398,7 +1425,7 @@ mly_periodic(void *data) mly_check_event(sc); /* reschedule ourselves */ - sc->mly_periodic = timeout(mly_periodic, sc, MLY_PERIODIC_INTERVAL * hz); + callout_schedule(&sc->mly_periodic, MLY_PERIODIC_INTERVAL * hz); } /******************************************************************************** @@ -1415,21 +1442,19 @@ static int mly_immediate_command(struct mly_command *mc) { struct mly_softc *sc = mc->mc_sc; - int error, s; + int error; debug_called(1); - /* spinning at splcam is ugly, but we're only used during controller init */ - s = splcam(); + MLY_ASSERT_LOCKED(sc); if ((error = mly_start(mc))) { - splx(s); return(error); } if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) { /* sleep on the command */ while(!(mc->mc_flags & MLY_CMD_COMPLETE)) { - tsleep(mc, PRIBIO, "mlywait", 0); + mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlywait", 0); } } else { /* spin and collect status while we do */ @@ -1437,7 +1462,6 @@ mly_immediate_command(struct mly_command *mc) mly_done(mc->mc_sc); } } - splx(s); return(0); } @@ -1453,9 +1477,9 @@ mly_start(struct mly_command *mc) { struct mly_softc *sc = mc->mc_sc; union mly_command_packet *pkt; - int s; debug_called(2); + MLY_ASSERT_LOCKED(sc); /* * Set the command up for delivery to the controller. @@ -1467,8 +1491,6 @@ mly_start(struct mly_command *mc) mc->mc_timestamp = time_second; #endif - s = splcam(); - /* * Do we have to use the hardware mailbox? */ @@ -1477,7 +1499,6 @@ mly_start(struct mly_command *mc) * Check to see if the controller is ready for us. */ if (MLY_IDBR_TRUE(sc, MLY_HM_CMDSENT)) { - splx(s); return(EBUSY); } mc->mc_flags |= MLY_CMD_BUSY; @@ -1494,7 +1515,6 @@ mly_start(struct mly_command *mc) /* check to see if the next index is free yet */ if (pkt->mmbox.flag != 0) { - splx(s); return(EBUSY); } mc->mc_flags |= MLY_CMD_BUSY; @@ -1502,13 +1522,11 @@ mly_start(struct mly_command *mc) /* copy in new command */ bcopy(mc->mc_packet->mmbox.data, pkt->mmbox.data, sizeof(pkt->mmbox.data)); /* barrier to ensure completion of previous write before we write the flag */ - bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0, - BUS_SPACE_BARRIER_WRITE); + bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE); /* copy flag last */ pkt->mmbox.flag = mc->mc_packet->mmbox.flag; /* barrier to ensure completion of previous write before we notify the controller */ - bus_space_barrier(sc->mly_btag, sc->mly_bhandle, 0, 0, - BUS_SPACE_BARRIER_WRITE); + bus_barrier(sc->mly_regs_resource, 0, 0, BUS_SPACE_BARRIER_WRITE); /* signal controller, update index */ MLY_SET_REG(sc, sc->mly_idbr, MLY_AM_CMDSENT); @@ -1516,7 +1534,6 @@ mly_start(struct mly_command *mc) } mly_enqueue_busy(mc); - splx(s); return(0); } @@ -1529,9 +1546,9 @@ mly_done(struct mly_softc *sc) struct mly_command *mc; union mly_status_packet *sp; u_int16_t slot; - int s, worked; + int worked; - s = splcam(); + MLY_ASSERT_LOCKED(sc); worked = 0; /* pick up hardware-mailbox commands */ @@ -1589,12 +1606,11 @@ mly_done(struct mly_softc *sc) MLY_SET_REG(sc, sc->mly_odbr, MLY_AM_STSREADY); } - splx(s); if (worked) { if (sc->mly_state & MLY_STATE_INTERRUPTS_ON) - taskqueue_enqueue(taskqueue_swi_giant, &sc->mly_task_complete); + taskqueue_enqueue(taskqueue_thread, &sc->mly_task_complete); else - mly_complete(sc, 0); + mly_complete(sc); } } @@ -1602,13 +1618,21 @@ mly_done(struct mly_softc *sc) * Process completed commands */ static void -mly_complete(void *context, int pending) +mly_complete_handler(void *context, int pending) { struct mly_softc *sc = (struct mly_softc *)context; + + MLY_LOCK(sc); + mly_complete(sc); + MLY_UNLOCK(sc); +} + +static void +mly_complete(struct mly_softc *sc) +{ struct mly_command *mc; void (* mc_complete)(struct mly_command *mc); - debug_called(2); /* @@ -1935,15 +1959,18 @@ mly_cam_attach(struct mly_softc *sc) if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc, device_get_unit(sc->mly_dev), - &Giant, + &sc->mly_lock, sc->mly_controllerinfo->maximum_parallel_commands, 1, devq)) == NULL) { return(ENOMEM); } + MLY_LOCK(sc); if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) { + MLY_UNLOCK(sc); mly_printf(sc, "CAM XPT phsyical channel registration failed\n"); return(ENXIO); } + MLY_UNLOCK(sc); debug(1, "registered physical channel %d", chn); } } @@ -1955,15 +1982,18 @@ mly_cam_attach(struct mly_softc *sc) for (i = 0; i < sc->mly_controllerinfo->virtual_channels_present; i++, chn++) { if ((sc->mly_cam_sim[chn] = cam_sim_alloc(mly_cam_action, mly_cam_poll, "mly", sc, device_get_unit(sc->mly_dev), - &Giant, + &sc->mly_lock, sc->mly_controllerinfo->maximum_parallel_commands, 0, devq)) == NULL) { return(ENOMEM); } + MLY_LOCK(sc); if (xpt_bus_register(sc->mly_cam_sim[chn], sc->mly_dev, chn)) { + MLY_UNLOCK(sc); mly_printf(sc, "CAM XPT virtual channel registration failed\n"); return(ENXIO); } + MLY_UNLOCK(sc); debug(1, "registered virtual channel %d", chn); } @@ -1987,12 +2017,14 @@ mly_cam_detach(struct mly_softc *sc) debug_called(1); + MLY_LOCK(sc); for (i = 0; i < sc->mly_cam_channels; i++) { if (sc->mly_cam_sim[i] != NULL) { xpt_bus_deregister(cam_sim_path(sc->mly_cam_sim[i])); cam_sim_free(sc->mly_cam_sim[i], 0); } } + MLY_UNLOCK(sc); if (sc->mly_cam_devq != NULL) cam_simq_free(sc->mly_cam_devq); } @@ -2030,6 +2062,7 @@ mly_cam_action(struct cam_sim *sim, union ccb *ccb) struct mly_softc *sc = cam_sim_softc(sim); debug_called(2); + MLY_ASSERT_LOCKED(sc); switch (ccb->ccb_h.func_code) { @@ -2173,7 +2206,6 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio) struct mly_command_scsi_small *ss; int bus, target; int error; - int s; bus = cam_sim_bus(sim); target = csio->ccb_h.target_id; @@ -2220,11 +2252,9 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio) * Get a command, or push the ccb back to CAM and freeze the queue. */ if ((error = mly_alloc_command(sc, &mc))) { - s = splcam(); xpt_freeze_simq(sim, 1); csio->ccb_h.status |= CAM_REQUEUE_REQ; sc->mly_qfrzn_cnt++; - splx(s); return(error); } @@ -2270,11 +2300,9 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio) /* give the command to the controller */ if ((error = mly_start(mc))) { - s = splcam(); xpt_freeze_simq(sim, 1); csio->ccb_h.status |= CAM_REQUEUE_REQ; sc->mly_qfrzn_cnt++; - splx(s); return(error); } @@ -2306,7 +2334,6 @@ mly_cam_complete(struct mly_command *mc) struct mly_btl *btl; u_int8_t cmd; int bus, target; - int s; debug_called(2); @@ -2359,12 +2386,10 @@ mly_cam_complete(struct mly_command *mc) break; } - s = splcam(); if (sc->mly_qfrzn_cnt) { csio->ccb_h.status |= CAM_RELEASE_SIMQ; sc->mly_qfrzn_cnt--; } - splx(s); xpt_done((union ccb *)csio); mly_release_command(mc); @@ -2805,7 +2830,9 @@ mly_user_open(struct cdev *dev, int flags, int fmt, struct thread *td) { struct mly_softc *sc = dev->si_drv1; + MLY_LOCK(sc); sc->mly_state |= MLY_STATE_OPEN; + MLY_UNLOCK(sc); return(0); } @@ -2817,7 +2844,9 @@ mly_user_close(struct cdev *dev, int flags, int fmt, struct thread *td) { struct mly_softc *sc = dev->si_drv1; + MLY_LOCK(sc); sc->mly_state &= ~MLY_STATE_OPEN; + MLY_UNLOCK(sc); return (0); } @@ -2855,13 +2884,16 @@ static int mly_user_command(struct mly_softc *sc, struct mly_user_command *uc) { struct mly_command *mc; - int error, s; + int error; /* allocate a command */ + MLY_LOCK(sc); if (mly_alloc_command(sc, &mc)) { + MLY_UNLOCK(sc); error = ENOMEM; goto out; /* XXX Linux version will wait for a command */ } + MLY_UNLOCK(sc); /* handle data size/direction */ mc->mc_length = (uc->DataTransferLength >= 0) ? uc->DataTransferLength : -uc->DataTransferLength; @@ -2888,12 +2920,14 @@ mly_user_command(struct mly_softc *sc, struct mly_user_command *uc) mc->mc_complete = NULL; /* execute the command */ - if ((error = mly_start(mc)) != 0) + MLY_LOCK(sc); + if ((error = mly_start(mc)) != 0) { + MLY_UNLOCK(sc); goto out; - s = splcam(); + } while (!(mc->mc_flags & MLY_CMD_COMPLETE)) - tsleep(mc, PRIBIO, "mlyioctl", 0); - splx(s); + mtx_sleep(mc, &sc->mly_lock, PRIBIO, "mlyioctl", 0); + MLY_UNLOCK(sc); /* return the data to userspace */ if (uc->DataTransferLength > 0) @@ -2916,8 +2950,11 @@ mly_user_command(struct mly_softc *sc, struct mly_user_command *uc) out: if (mc->mc_data != NULL) free(mc->mc_data, M_DEVBUF); - if (mc != NULL) + if (mc != NULL) { + MLY_LOCK(sc); mly_release_command(mc); + MLY_UNLOCK(sc); + } return(error); } @@ -2931,32 +2968,36 @@ static int mly_user_health(struct mly_softc *sc, struct mly_user_health *uh) { struct mly_health_status mh; - int error, s; + int error; /* fetch the current health status from userspace */ if ((error = copyin(uh->HealthStatusBuffer, &mh, sizeof(mh))) != 0) return(error); /* spin waiting for a status update */ - s = splcam(); + MLY_LOCK(sc); error = EWOULDBLOCK; while ((error != 0) && (sc->mly_event_change == mh.change_counter)) - error = tsleep(&sc->mly_event_change, PRIBIO | PCATCH, "mlyhealth", 0); - splx(s); + error = mtx_sleep(&sc->mly_event_change, &sc->mly_lock, PRIBIO | PCATCH, + "mlyhealth", 0); + mh = sc->mly_mmbox->mmm_health.status; + MLY_UNLOCK(sc); - /* copy the controller's health status buffer out (there is a race here if it changes again) */ - error = copyout(&sc->mly_mmbox->mmm_health.status, uh->HealthStatusBuffer, - sizeof(uh->HealthStatusBuffer)); + /* copy the controller's health status buffer out */ + error = copyout(&mh, uh->HealthStatusBuffer, sizeof(mh)); return(error); } #ifdef MLY_DEBUG -static int -mly_timeout(struct mly_softc *sc) +static void +mly_timeout(void *arg) { + struct mly_softc *sc; struct mly_command *mc; int deadline; + sc = arg; + MLY_ASSERT_LOCKED(sc); deadline = time_second - MLY_CMD_TIMEOUT; TAILQ_FOREACH(mc, &sc->mly_busy, mc_link) { if ((mc->mc_timestamp < deadline)) { @@ -2966,8 +3007,6 @@ mly_timeout(struct mly_softc *sc) } } - timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz); - - return (0); + callout_reset(&sc->mly_timeout, MLY_CMD_TIMEOUT * hz, mly_timeout, sc); } #endif diff --git a/sys/dev/mly/mlyvar.h b/sys/dev/mly/mlyvar.h index 7413fa40e9e..6bec8ebe6a4 100644 --- a/sys/dev/mly/mlyvar.h +++ b/sys/dev/mly/mlyvar.h @@ -59,10 +59,6 @@ # include -#ifndef INTR_ENTROPY -# define INTR_ENTROPY 0 -#endif - /******************************************************************************** ******************************************************************************** Driver Variable Definitions @@ -161,8 +157,6 @@ struct mly_softc { struct cdev *mly_dev_t; struct resource *mly_regs_resource; /* register interface window */ int mly_regs_rid; /* resource ID */ - bus_space_handle_t mly_bhandle; /* bus space handle */ - bus_space_tag_t mly_btag; /* bus space tag */ bus_dma_tag_t mly_parent_dmat; /* parent DMA tag */ bus_dma_tag_t mly_buffer_dmat; /* data buffer/command DMA tag */ struct resource *mly_irq; /* interrupt */ @@ -195,6 +189,7 @@ struct mly_softc { u_int32_t mly_mmbox_status_index; /* index we next expect status at */ /* controller features, limits and status */ + struct mtx mly_lock; int mly_state; #define MLY_STATE_OPEN (1<<1) #define MLY_STATE_INTERRUPTS_ON (1<<2) @@ -219,7 +214,7 @@ struct mly_softc { u_int32_t mly_event_change; /* event status change indicator */ u_int32_t mly_event_counter; /* next event for which we anticpiate status */ u_int32_t mly_event_waiting; /* next event the controller will post status for */ - struct callout_handle mly_periodic; /* periodic event handling */ + struct callout mly_periodic; /* periodic event handling */ /* CAM connection */ struct cam_devq *mly_cam_devq; /* CAM device queue */ @@ -230,29 +225,37 @@ struct mly_softc { /* command-completion task */ struct task mly_task_complete; /* deferred-completion task */ int mly_qfrzn_cnt; /* Track simq freezes */ + +#ifdef MLY_DEBUG + struct callout mly_timeout; +#endif }; +#define MLY_LOCK(sc) mtx_lock(&(sc)->mly_lock) +#define MLY_UNLOCK(sc) mtx_unlock(&(sc)->mly_lock) +#define MLY_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mly_lock, MA_OWNED) + /* * Register access helpers. */ -#define MLY_SET_REG(sc, reg, val) bus_space_write_1(sc->mly_btag, sc->mly_bhandle, reg, val) -#define MLY_GET_REG(sc, reg) bus_space_read_1 (sc->mly_btag, sc->mly_bhandle, reg) -#define MLY_GET_REG2(sc, reg) bus_space_read_2 (sc->mly_btag, sc->mly_bhandle, reg) -#define MLY_GET_REG4(sc, reg) bus_space_read_4 (sc->mly_btag, sc->mly_bhandle, reg) +#define MLY_SET_REG(sc, reg, val) bus_write_1(sc->mly_regs_resource, reg, val) +#define MLY_GET_REG(sc, reg) bus_read_1 (sc->mly_regs_resource, reg) +#define MLY_GET_REG2(sc, reg) bus_read_2 (sc->mly_regs_resource, reg) +#define MLY_GET_REG4(sc, reg) bus_read_4 (sc->mly_regs_resource, reg) #define MLY_SET_MBOX(sc, mbox, ptr) \ do { \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox, *((u_int32_t *)ptr)); \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 4, *((u_int32_t *)ptr + 1)); \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 8, *((u_int32_t *)ptr + 2)); \ - bus_space_write_4(sc->mly_btag, sc->mly_bhandle, mbox + 12, *((u_int32_t *)ptr + 3)); \ + bus_write_4(sc->mly_regs_resource, mbox, *((u_int32_t *)ptr)); \ + bus_write_4(sc->mly_regs_resource, mbox + 4, *((u_int32_t *)ptr + 1)); \ + bus_write_4(sc->mly_regs_resource, mbox + 8, *((u_int32_t *)ptr + 2)); \ + bus_write_4(sc->mly_regs_resource, mbox + 12, *((u_int32_t *)ptr + 3)); \ } while(0); #define MLY_GET_MBOX(sc, mbox, ptr) \ do { \ - *((u_int32_t *)ptr) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox); \ - *((u_int32_t *)ptr + 1) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 4); \ - *((u_int32_t *)ptr + 2) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 8); \ - *((u_int32_t *)ptr + 3) = bus_space_read_4(sc->mly_btag, sc->mly_bhandle, mbox + 12); \ + *((u_int32_t *)ptr) = bus_read_4(sc->mly_regs_resource, mbox); \ + *((u_int32_t *)ptr + 1) = bus_read_4(sc->mly_regs_resource, mbox + 4); \ + *((u_int32_t *)ptr + 2) = bus_read_4(sc->mly_regs_resource, mbox + 8); \ + *((u_int32_t *)ptr + 3) = bus_read_4(sc->mly_regs_resource, mbox + 12); \ } while(0); #define MLY_IDBR_TRUE(sc, mask) \ @@ -315,46 +318,34 @@ mly_initq_ ## name (struct mly_softc *sc) \ static __inline void \ mly_enqueue_ ## name (struct mly_command *mc) \ { \ - int s; \ \ - s = splcam(); \ TAILQ_INSERT_TAIL(&mc->mc_sc->mly_ ## name, mc, mc_link); \ MLYQ_ADD(mc->mc_sc, index); \ - splx(s); \ } \ static __inline void \ mly_requeue_ ## name (struct mly_command *mc) \ { \ - int s; \ \ - s = splcam(); \ TAILQ_INSERT_HEAD(&mc->mc_sc->mly_ ## name, mc, mc_link); \ MLYQ_ADD(mc->mc_sc, index); \ - splx(s); \ } \ static __inline struct mly_command * \ mly_dequeue_ ## name (struct mly_softc *sc) \ { \ struct mly_command *mc; \ - int s; \ \ - s = splcam(); \ if ((mc = TAILQ_FIRST(&sc->mly_ ## name)) != NULL) { \ TAILQ_REMOVE(&sc->mly_ ## name, mc, mc_link); \ MLYQ_REMOVE(sc, index); \ } \ - splx(s); \ return(mc); \ } \ static __inline void \ mly_remove_ ## name (struct mly_command *mc) \ { \ - int s; \ \ - s = splcam(); \ TAILQ_REMOVE(&mc->mc_sc->mly_ ## name, mc, mc_link); \ MLYQ_REMOVE(mc->mc_sc, index); \ - splx(s); \ } \ struct hack diff --git a/sys/dev/ncv/ncr53c500.c b/sys/dev/ncv/ncr53c500.c index 3bbded42083..836268281e4 100644 --- a/sys/dev/ncv/ncr53c500.c +++ b/sys/dev/ncv/ncr53c500.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -107,18 +108,18 @@ static int ncv_msg(struct ncv_softc *, struct targ_info *, u_int); static int ncv_reselected(struct ncv_softc *); static int ncv_disconnected(struct ncv_softc *, struct targ_info *); -static __inline void ncvhw_set_count(bus_space_tag_t, bus_space_handle_t, int); -static __inline u_int ncvhw_get_count(bus_space_tag_t, bus_space_handle_t); -static __inline void ncvhw_select_register_0(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static __inline void ncvhw_select_register_1(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static __inline void ncvhw_fpush(bus_space_tag_t, bus_space_handle_t, u_int8_t *, int); +static __inline void ncvhw_set_count(struct resource *, int); +static __inline u_int ncvhw_get_count(struct resource *); +static __inline void ncvhw_select_register_0(struct resource *, struct ncv_hw *); +static __inline void ncvhw_select_register_1(struct resource *, struct ncv_hw *); +static __inline void ncvhw_fpush(struct resource *, u_int8_t *, int); static void ncv_pdma_end(struct ncv_softc *sc, struct targ_info *); static int ncv_world_start(struct ncv_softc *, int); static void ncvhw_bus_reset(struct ncv_softc *); -static void ncvhw_reset(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static int ncvhw_check(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); -static void ncvhw_init(bus_space_tag_t, bus_space_handle_t, struct ncv_hw *); +static void ncvhw_reset(struct resource *, struct ncv_hw *); +static int ncvhw_check(struct resource *, struct ncv_hw *); +static void ncvhw_init(struct resource *, struct ncv_hw *); static int ncvhw_start_selection(struct ncv_softc *sc, struct slccb *); static void ncvhw_attention(struct ncv_softc *); static int ncv_ccb_nexus_establish(struct ncv_softc *); @@ -154,74 +155,56 @@ struct scsi_low_funcs ncv_funcs = { * hwfuncs **************************************************************/ static __inline void -ncvhw_select_register_0(iot, ioh, hw) - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct ncv_hw *hw; +ncvhw_select_register_0(struct resource *res, struct ncv_hw *hw) { - bus_space_write_1(iot, ioh, cr0_cfg4, hw->hw_cfg4); + bus_write_1(res, cr0_cfg4, hw->hw_cfg4); } static __inline void -ncvhw_select_register_1(iot, ioh, hw) - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct ncv_hw *hw; +ncvhw_select_register_1(struct resource *res, struct ncv_hw *hw) { - bus_space_write_1(iot, ioh, cr1_cfg5, hw->hw_cfg5); + bus_write_1(res, cr1_cfg5, hw->hw_cfg5); } static __inline void -ncvhw_fpush(iot, ioh, buf, len) - bus_space_tag_t iot; - bus_space_handle_t ioh; - u_int8_t *buf; - int len; +ncvhw_fpush(struct resource *res, u_int8_t *buf, int len) { int ptr; for (ptr = 0; ptr < len; ptr ++) - bus_space_write_1(iot, ioh, cr0_sfifo, buf[ptr]); + bus_write_1(res, cr0_sfifo, buf[ptr]); } static __inline void -ncvhw_set_count(iot, ioh, count) - bus_space_tag_t iot; - bus_space_handle_t ioh; - int count; +ncvhw_set_count(struct resource *res, int count) { - bus_space_write_1(iot, ioh, cr0_tclsb, (u_int8_t) count); - bus_space_write_1(iot, ioh, cr0_tcmsb, (u_int8_t) (count >> NBBY)); - bus_space_write_1(iot, ioh, cr0_tchsb, (u_int8_t) (count >> (NBBY * 2))); + bus_write_1(res, cr0_tclsb, (u_int8_t) count); + bus_write_1(res, cr0_tcmsb, (u_int8_t) (count >> NBBY)); + bus_write_1(res, cr0_tchsb, (u_int8_t) (count >> (NBBY * 2))); } static __inline u_int -ncvhw_get_count(iot, ioh) - bus_space_tag_t iot; - bus_space_handle_t ioh; +ncvhw_get_count(struct resource *res) { u_int count; - count = (u_int) bus_space_read_1(iot, ioh, cr0_tclsb); - count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tcmsb)) << NBBY; - count |= ((u_int) bus_space_read_1(iot, ioh, cr0_tchsb)) << (NBBY * 2); + count = (u_int) bus_read_1(res, cr0_tclsb); + count |= ((u_int) bus_read_1(res, cr0_tcmsb)) << NBBY; + count |= ((u_int) bus_read_1(res, cr0_tchsb)) << (NBBY * 2); return count; } static int -ncvhw_check(iot, ioh, hw) - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct ncv_hw *hw; +ncvhw_check(struct resource *res, struct ncv_hw *hw) { u_int8_t stat; - ncvhw_select_register_0(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA); - if (bus_space_read_1(iot, ioh, cr0_cmd) != (CMD_NOP | CMD_DMA)) + ncvhw_select_register_0(res, hw); + bus_write_1(res, cr0_cmd, CMD_NOP | CMD_DMA); + if (bus_read_1(res, cr0_cmd) != (CMD_NOP | CMD_DMA)) { #ifdef NCV_DEBUG printf("ncv: cr0_cmd CMD_NOP|CMD_DMA failed\n"); @@ -229,8 +212,8 @@ ncvhw_check(iot, ioh, hw) return ENODEV; } - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - if (bus_space_read_1(iot, ioh, cr0_cmd) != CMD_NOP) + bus_write_1(res, cr0_cmd, CMD_NOP); + if (bus_read_1(res, cr0_cmd) != CMD_NOP) { #ifdef NCV_DEBUG printf("ncv: cr0_cmd CMD_NOP failed\n"); @@ -239,23 +222,23 @@ ncvhw_check(iot, ioh, hw) } /* hardware reset */ - ncvhw_reset(iot, ioh, hw); - ncvhw_init(iot, ioh, hw); + ncvhw_reset(res, hw); + ncvhw_init(res, hw); /* bus reset */ - ncvhw_select_register_0(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA); + ncvhw_select_register_0(res, hw); + bus_write_1(res, cr0_cmd, CMD_FLUSH); + bus_write_1(res, cr0_cmd, CMD_RSTSCSI); + bus_write_1(res, cr0_cmd, CMD_NOP | CMD_DMA); DELAY(100 * 1000); /* check response */ - bus_space_read_1(iot, ioh, cr0_stat); - stat = bus_space_read_1(iot, ioh, cr0_istat); + bus_read_1(res, cr0_stat); + stat = bus_read_1(res, cr0_istat); DELAY(1000); if (((stat & INTR_SBR) == 0) || - (bus_space_read_1(iot, ioh, cr0_istat) & INTR_SBR)) + (bus_read_1(res, cr0_istat) & INTR_SBR)) { #ifdef NCV_DEBUG printf("ncv: cr0_istat SCSI BUS RESET failed\n"); @@ -267,50 +250,44 @@ ncvhw_check(iot, ioh, hw) } static void -ncvhw_reset(iot, ioh, hw) - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct ncv_hw *hw; +ncvhw_reset(struct resource *res, struct ncv_hw *hw) { - ncvhw_select_register_0(iot, ioh, hw); + ncvhw_select_register_0(res, hw); /* dummy cmd twice */ - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); + bus_write_1(res, cr0_cmd, CMD_NOP); + bus_write_1(res, cr0_cmd, CMD_NOP); /* chip reset */ - bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTCHIP); + bus_write_1(res, cr0_cmd, CMD_RSTCHIP); /* again dummy cmd twice */ - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP); + bus_write_1(res, cr0_cmd, CMD_NOP); + bus_write_1(res, cr0_cmd, CMD_NOP); } static void -ncvhw_init(iot, ioh, hw) - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct ncv_hw *hw; +ncvhw_init(struct resource *res, struct ncv_hw *hw) { - ncvhw_select_register_0(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr0_clk, hw->hw_clk); - bus_space_write_1(iot, ioh, cr0_srtout, SEL_TOUT); - bus_space_write_1(iot, ioh, cr0_period, 0); - bus_space_write_1(iot, ioh, cr0_offs, 0); + ncvhw_select_register_0(res, hw); + bus_write_1(res, cr0_clk, hw->hw_clk); + bus_write_1(res, cr0_srtout, SEL_TOUT); + bus_write_1(res, cr0_period, 0); + bus_write_1(res, cr0_offs, 0); - bus_space_write_1(iot, ioh, cr0_cfg1, hw->hw_cfg1); - bus_space_write_1(iot, ioh, cr0_cfg2, hw->hw_cfg2); - bus_space_write_1(iot, ioh, cr0_cfg3, hw->hw_cfg3); - bus_space_write_1(iot, ioh, cr0_tchsb, 0); + bus_write_1(res, cr0_cfg1, hw->hw_cfg1); + bus_write_1(res, cr0_cfg2, hw->hw_cfg2); + bus_write_1(res, cr0_cfg3, hw->hw_cfg3); + bus_write_1(res, cr0_tchsb, 0); - ncvhw_select_register_1(iot, ioh, hw); - bus_space_write_1(iot, ioh, cr1_fstat, 0x0); - bus_space_write_1(iot, ioh, cr1_pflag, 0x0); - bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE); + ncvhw_select_register_1(res, hw); + bus_write_1(res, cr1_fstat, 0x0); + bus_write_1(res, cr1_pflag, 0x0); + bus_write_1(res, cr1_atacmd, ATACMD_ENGAGE); - ncvhw_select_register_0(iot, ioh, hw); + ncvhw_select_register_0(res, hw); } #ifdef NCV_POWER_CONTROL @@ -320,14 +297,13 @@ ncvhw_power(sc, flags) u_int flags; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; if (flags == SCSI_LOW_POWDOWN) { device_printf(slp->sl_dev, "power down\n"); - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_POWDOWN); + ncvhw_select_register_1(res, &sc->sc_hw); + bus_write_1(res, cr1_atacmd, ATACMD_POWDOWN); } else { @@ -335,14 +311,14 @@ ncvhw_power(sc, flags) { case 0: device_printf(slp->sl_dev, "resume step O\n"); - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_atacmd, ATACMD_ENGAGE); + ncvhw_select_register_1(res, &sc->sc_hw); + bus_write_1(res, cr1_atacmd, ATACMD_ENGAGE); break; case 1: device_printf(slp->sl_dev, "resume step I\n"); - ncvhw_reset(iot, ioh, &sc->sc_hw); - ncvhw_init(iot, ioh, &sc->sc_hw); + ncvhw_reset(res, &sc->sc_hw); + ncvhw_init(res, &sc->sc_hw); break; } } @@ -359,7 +335,7 @@ ncvhw_attention(sc) struct ncv_softc *sc; { - bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, CMD_SETATN); + bus_write_1(sc->port_res, cr0_cmd, CMD_SETATN); DELAY(10); } @@ -367,13 +343,11 @@ static void ncvhw_bus_reset(sc) struct ncv_softc *sc; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_RSTSCSI); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_NOP | CMD_DMA); + ncvhw_select_register_0(sc->port_res, &sc->sc_hw); + bus_write_1(sc->port_res, cr0_cmd, CMD_FLUSH); + bus_write_1(sc->port_res, cr0_cmd, CMD_RSTSCSI); + bus_write_1(sc->port_res, cr0_cmd, CMD_NOP | CMD_DMA); } static int @@ -382,10 +356,9 @@ ncvhw_start_selection(sc, cb) struct slccb *cb; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; struct targ_info *ti = cb->ti; - int s, len; + int len; u_int flags; u_int8_t cmd; @@ -411,8 +384,8 @@ ncvhw_start_selection(sc, cb) flags = SCSI_LOW_MSGOUT_INIT; } - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0) + ncvhw_select_register_0(res, &sc->sc_hw); + if ((bus_read_1(res, cr0_stat) & STAT_INT) != 0) return SCSI_LOW_START_FAIL; ncv_target_nexus_establish(sc); @@ -421,23 +394,18 @@ ncvhw_start_selection(sc, cb) if (sc->sc_selstop == 0) scsi_low_cmd(slp, ti); - s = splhigh(); - if ((bus_space_read_1(iot, ioh, cr0_stat) & STAT_INT) != 0) - { - splx(s); + if ((bus_read_1(res, cr0_stat) & STAT_INT) != 0) return SCSI_LOW_START_FAIL; - } - bus_space_write_1(iot, ioh, cr0_dstid, ti->ti_id); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len); + bus_write_1(res, cr0_dstid, ti->ti_id); + bus_write_1(res, cr0_cmd, CMD_FLUSH); + ncvhw_fpush(res, ti->ti_msgoutstr, len); if (sc->sc_selstop == 0) { - ncvhw_fpush(iot, ioh, + ncvhw_fpush(res, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen); } - bus_space_write_1(iot, ioh, cr0_cmd, cmd); - splx(s); + bus_write_1(res, cr0_cmd, cmd); SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); return SCSI_LOW_START_OK; @@ -449,8 +417,7 @@ ncv_world_start(sc, fdone) int fdone; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; u_int8_t stat; if ((slp->sl_cfgflags & CFG_NOPARITY) == 0) @@ -458,18 +425,18 @@ ncv_world_start(sc, fdone) else sc->sc_hw.hw_cfg1 &= ~C1_PARENB; - ncvhw_reset(iot, ioh, &sc->sc_hw); - ncvhw_init(iot, ioh, &sc->sc_hw); + ncvhw_reset(res, &sc->sc_hw); + ncvhw_init(res, &sc->sc_hw); scsi_low_bus_reset(slp); - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_stat); - stat = bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat); + ncvhw_select_register_0(res, &sc->sc_hw); + bus_read_1(res, cr0_stat); + stat = bus_read_1(res, cr0_istat); DELAY(1000); if (((stat & INTR_SBR) == 0) || - (bus_space_read_1(sc->sc_iot, sc->sc_ioh, cr0_istat) & INTR_SBR)) + (bus_read_1(res, cr0_istat) & INTR_SBR)) return ENODEV; return 0; @@ -481,8 +448,7 @@ ncv_msg(sc, ti, msg) struct targ_info *ti; u_int msg; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; struct ncv_targ_info *nti = (void *) ti; u_int hwcycle, period; @@ -512,9 +478,9 @@ ncv_msg(sc, ti, msg) nti->nti_reg_period = period & 0x1f; nti->nti_reg_offset = ti->ti_maxsynch.offset; - bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period); - bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset); - bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3); + bus_write_1(res, cr0_period, nti->nti_reg_period); + bus_write_1(res, cr0_offs, nti->nti_reg_offset); + bus_write_1(res, cr0_cfg3, nti->nti_reg_cfg3); return 0; } @@ -588,18 +554,14 @@ ncv_setup_img(hw, dvcfg, hostid) } int -ncvprobesubr(iot, ioh, dvcfg, hsid) - bus_space_tag_t iot; - bus_space_handle_t ioh; - u_int dvcfg; - int hsid; +ncvprobesubr(struct resource *res, u_int dvcfg, int hsid) { struct ncv_hw hwtab; hwtab = ncv_template; if (ncv_setup_img(&hwtab, dvcfg, hsid)) return 0; - if (ncvhw_check(iot, ioh, &hwtab) != 0) + if (ncvhw_check(res, &hwtab) != 0) return 0; return 1; @@ -630,15 +592,14 @@ ncv_setup_and_start_pio(sc, reqlen) struct ncv_softc *sc; u_int reqlen; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - ncvhw_set_count(iot, ioh, reqlen); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS | CMD_DMA); + ncvhw_select_register_0(res, &sc->sc_hw); + ncvhw_set_count(res, reqlen); + bus_write_1(res, cr0_cmd, CMD_TRANS | CMD_DMA); - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_fstat, FIFO_EN); + ncvhw_select_register_1(res, &sc->sc_hw); + bus_write_1(res, cr1_fstat, FIFO_EN); } static void @@ -647,8 +608,7 @@ ncv_pdma_end(sc, ti) struct targ_info *ti; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; int len; slp->sl_flags &= ~HW_PDMASTART; @@ -660,9 +620,9 @@ ncv_pdma_end(sc, ti) if (ti->ti_phase == PH_DATA) { - len = ncvhw_get_count(sc->sc_iot, sc->sc_ioh); + len = ncvhw_get_count(res); if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE) - len += (bus_space_read_1(sc->sc_iot, sc->sc_ioh, + len += (bus_read_1(res, cr0_sffl) & CR0_SFFLR_BMASK); if ((u_int) len <= (u_int) sc->sc_sdatalen) @@ -698,9 +658,9 @@ bad: } out: - ncvhw_select_register_1(iot, ioh, &sc->sc_hw); - bus_space_write_1(iot, ioh, cr1_fstat, 0); - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); + ncvhw_select_register_1(res, &sc->sc_hw); + bus_write_1(res, cr1_fstat, 0); + ncvhw_select_register_0(res, &sc->sc_hw); } static void @@ -710,8 +670,7 @@ ncv_pio_read(sc, buf, reqlen) u_int reqlen; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; int tout; register u_int8_t fstat; @@ -722,17 +681,17 @@ ncv_pio_read(sc, buf, reqlen) while (reqlen >= FIFO_F_SZ && tout -- > 0) { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); + fstat = bus_read_1(res, cr1_fstat); if (fstat == (u_int8_t) -1) goto out; if (fstat & FIFO_F) { #define NCV_FAST32_ACCESS #ifdef NCV_FAST32_ACCESS - bus_space_read_multi_4(iot, ioh, cr1_fdata, + bus_read_multi_4(res, cr1_fdata, (u_int32_t *) buf, FIFO_F_SZ / 4); #else /* !NCV_FAST32_ACCESS */ - bus_space_read_multi_2(iot, ioh, cr1_fdata, + bus_read_multi_2(res, cr1_fdata, (u_int16_t *) buf, FIFO_F_SZ / 2); #endif /* !NCV_FAST32_ACCESS */ buf += FIFO_F_SZ; @@ -749,10 +708,10 @@ ncv_pio_read(sc, buf, reqlen) while (reqlen > 0 && tout -- > 0) { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); + fstat = bus_read_1(res, cr1_fstat); if ((fstat & FIFO_E) == 0) { - *buf++ = bus_space_read_1(iot, ioh, cr1_fdata); + *buf++ = bus_read_1(res, cr1_fdata); reqlen --; } else @@ -765,7 +724,7 @@ ncv_pio_read(sc, buf, reqlen) } out: - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); + ncvhw_select_register_0(res, &sc->sc_hw); sc->sc_tdatalen = reqlen; } @@ -776,8 +735,7 @@ ncv_pio_write(sc, buf, reqlen) u_int reqlen; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; int tout; register u_int8_t fstat; @@ -788,17 +746,17 @@ ncv_pio_write(sc, buf, reqlen) while (reqlen >= FIFO_F_SZ && tout -- > 0) { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); + fstat = bus_read_1(res, cr1_fstat); if (fstat & FIFO_BRK) goto done; if ((fstat & FIFO_E) != 0) { #ifdef NCV_FAST32_ACCESS - bus_space_write_multi_4(iot, ioh, cr1_fdata, + bus_write_multi_4(res, cr1_fdata, (u_int32_t *) buf, FIFO_F_SZ / 4); #else /* !NCV_FAST32_ACCESS */ - bus_space_write_multi_2(iot, ioh, cr1_fdata, + bus_write_multi_2(res, cr1_fdata, (u_int16_t *) buf, FIFO_F_SZ / 2); #endif /* !NCV_FAST32_ACCESS */ buf += FIFO_F_SZ; @@ -812,13 +770,13 @@ ncv_pio_write(sc, buf, reqlen) while (reqlen > 0 && tout -- > 0) { - fstat = bus_space_read_1(iot, ioh, cr1_fstat); + fstat = bus_read_1(res, cr1_fstat); if (fstat & FIFO_BRK) break; if ((fstat & FIFO_F) == 0) /* fifo not full */ { - bus_space_write_1(iot, ioh, cr1_fdata, *buf++); + bus_write_1(res, cr1_fdata, *buf++); reqlen --; } else @@ -828,7 +786,7 @@ ncv_pio_write(sc, buf, reqlen) } done: - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); + ncvhw_select_register_0(res, &sc->sc_hw); } /************************************************************** @@ -839,19 +797,18 @@ ncv_reselected(sc) struct ncv_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; struct targ_info *ti; u_int sid; - if ((bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK) != 2) + if ((bus_read_1(res, cr0_sffl) & CR0_SFFLR_BMASK) != 2) { device_printf(slp->sl_dev, "illegal fifo bytes\n"); scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, "chip confused"); return EJUSTRETURN; } - sid = (u_int) bus_space_read_1(iot, ioh, cr0_sfifo); + sid = (u_int) bus_read_1(res, cr0_sfifo); sid &= ~(1 << slp->sl_hostid); sid = ffs(sid) - 1; ti = scsi_low_reselected((struct scsi_low_softc *) sc, sid); @@ -861,7 +818,7 @@ ncv_reselected(sc) #ifdef NCV_STATICS ncv_statics.reselect ++; #endif /* NCV_STATICS */ - bus_space_write_1(iot, ioh, cr0_dstid, sid); + bus_write_1(res, cr0_dstid, sid); return 0; } @@ -871,11 +828,10 @@ ncv_disconnected(sc, ti) struct targ_info *ti; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_ENSEL); + bus_write_1(res, cr0_cmd, CMD_FLUSH); + bus_write_1(res, cr0_cmd, CMD_ENSEL); #ifdef NCV_STATICS ncv_statics.disconnect ++; @@ -895,12 +851,11 @@ ncv_target_nexus_establish(sc) struct scsi_low_softc *slp = &sc->sc_sclow; struct targ_info *ti = slp->sl_Tnexus; struct ncv_targ_info *nti = (void *) ti; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; - bus_space_write_1(iot, ioh, cr0_period, nti->nti_reg_period); - bus_space_write_1(iot, ioh, cr0_offs, nti->nti_reg_offset); - bus_space_write_1(iot, ioh, cr0_cfg3, nti->nti_reg_cfg3); + bus_write_1(res, cr0_period, nti->nti_reg_period); + bus_write_1(res, cr0_offs, nti->nti_reg_offset); + bus_write_1(res, cr0_cfg3, nti->nti_reg_cfg3); return 0; } @@ -927,14 +882,13 @@ static int ncv_catch_intr(sc) struct ncv_softc *sc; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; int wc; register u_int8_t status; for (wc = 0; wc < NCV_DELAY_MAX / NCV_DELAY_INTERVAL; wc ++) { - status = bus_space_read_1(iot, ioh, cr0_stat); + status = bus_read_1(res, cr0_stat); if ((status & STAT_INT) != 0) return 0; @@ -949,8 +903,7 @@ ncvintr(arg) { struct ncv_softc *sc = arg; struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; + struct resource *res = sc->port_res; struct targ_info *ti; struct buf *bp; u_int derror, flags; @@ -964,19 +917,19 @@ again: /******************************************** * Status ********************************************/ - ncvhw_select_register_0(iot, ioh, &sc->sc_hw); - status = bus_space_read_1(iot, ioh, cr0_stat); + ncvhw_select_register_0(res, &sc->sc_hw); + status = bus_read_1(res, cr0_stat); if ((status & STAT_INT) == 0 || status == (u_int8_t) -1) return 0; - ireason = bus_space_read_1(iot, ioh, cr0_istat); + ireason = bus_read_1(res, cr0_istat); if ((ireason & INTR_SBR) != 0) { u_int8_t val; /* avoid power off hangup */ - val = bus_space_read_1(iot, ioh, cr0_cfg1); - bus_space_write_1(iot, ioh, cr0_cfg1, val | C1_SRR); + val = bus_read_1(res, cr0_cfg1); + bus_write_1(res, cr0_cfg1, val | C1_SRR); /* status init */ scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, @@ -1183,16 +1136,16 @@ again: scsi_low_attention(slp); } - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - ncvhw_fpush(iot, ioh, + bus_write_1(res, cr0_cmd, CMD_FLUSH); + ncvhw_fpush(res, slp->sl_scp.scp_cmd, slp->sl_scp.scp_cmdlen); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS); + bus_write_1(res, cr0_cmd, CMD_TRANS); break; case STATUS_PHASE: /* status in */ SCSI_LOW_SETUP_PHASE(ti, PH_STAT); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_ICCS); + bus_write_1(res, cr0_cmd, CMD_FLUSH); + bus_write_1(res, cr0_cmd, CMD_ICCS); sc->sc_compseq = 1; break; @@ -1201,7 +1154,7 @@ again: case MESSAGE_OUT_PHASE: /* msg out */ SCSI_LOW_SETUP_PHASE(ti, PH_MSGOUT); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); + bus_write_1(res, cr0_cmd, CMD_FLUSH); flags = SCSI_LOW_MSGOUT_UNIFY; if (ti->ti_ophase != ti->ti_phase) @@ -1213,21 +1166,21 @@ again: scsi_low_attention(slp); } - ncvhw_fpush(iot, ioh, ti->ti_msgoutstr, len); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS); + ncvhw_fpush(res, ti->ti_msgoutstr, len); + bus_write_1(res, cr0_cmd, CMD_TRANS); SCSI_LOW_DEASSERT_ATN(slp); break; case MESSAGE_IN_PHASE: /* msg in */ SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); - len = bus_space_read_1(iot, ioh, cr0_sffl) & CR0_SFFLR_BMASK; + len = bus_read_1(res, cr0_sffl) & CR0_SFFLR_BMASK; if (sc->sc_compseq != 0) { sc->sc_compseq = 0; if ((ireason & INTR_FC) && len == 2) { - regv = bus_space_read_1(iot, ioh, cr0_sfifo); + regv = bus_read_1(res, cr0_sfifo); scsi_low_statusin(slp, ti, regv | derror); len --; } @@ -1236,15 +1189,14 @@ again: slp->sl_error |= FATALIO; scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, - cr0_cmd, CMD_MSGOK); + bus_write_1(res, cr0_cmd, CMD_MSGOK); break; } } else if (ireason & INTR_BS) { - bus_space_write_1(iot, ioh, cr0_cmd, CMD_FLUSH); - bus_space_write_1(iot, ioh, cr0_cmd, CMD_TRANS); + bus_write_1(res, cr0_cmd, CMD_FLUSH); + bus_write_1(res, cr0_cmd, CMD_TRANS); if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0) { if (ncv_catch_intr(sc) == 0) @@ -1255,8 +1207,7 @@ again: if ((ireason & INTR_FC) && len == 1) { - regv = bus_space_read_1(sc->sc_iot, sc->sc_ioh, - cr0_sfifo); + regv = bus_read_1(res, cr0_sfifo); if (scsi_low_msgin(slp, ti, regv | derror) == 0) { if (scsi_low_is_msgout_continue(ti, 0) != 0) @@ -1264,8 +1215,7 @@ again: scsi_low_attention(slp); } } - bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, - CMD_MSGOK); + bus_write_1(res, cr0_cmd, CMD_MSGOK); if ((ncv_io_control & NCV_FAST_INTERRUPTS) != 0) { /* XXX: @@ -1279,8 +1229,7 @@ again: { slp->sl_error |= FATALIO; scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 1); - bus_space_write_1(sc->sc_iot, sc->sc_ioh, cr0_cmd, - CMD_MSGOK); + bus_write_1(res, cr0_cmd, CMD_MSGOK); } break; } diff --git a/sys/dev/ncv/ncr53c500_pccard.c b/sys/dev/ncv/ncr53c500_pccard.c index 72df5868fcd..23c207a1a55 100644 --- a/sys/dev/ncv/ncr53c500_pccard.c +++ b/sys/dev/ncv/ncr53c500_pccard.c @@ -98,7 +98,12 @@ static const struct ncv_product { static void ncv_pccard_intr(void * arg) { + struct ncv_softc *sc; + + sc = arg; + SCSI_LOW_LOCK(&sc->sc_sclow); ncvintr(arg); + SCSI_LOW_UNLOCK(&sc->sc_sclow); } static void @@ -129,6 +134,7 @@ ncv_release_resource(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); } + mtx_destroy(&sc->sc_sclow.sl_lock); } static int @@ -148,6 +154,7 @@ ncv_alloc_resource(device_t dev) return(ENOMEM); } + mtx_init(&sc->sc_sclow.sl_lock, "ncv", NULL, MTX_DEF); sc->port_rid = 0; sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, ioaddr+offset, ioaddr+iosize-offset, @@ -223,7 +230,7 @@ ncv_pccard_probe(device_t dev) strncmp(prodstr, "SOUND/SCSI2 CARD", 16) == 0) { device_set_desc(dev, "RATOC REX-5572"); device_set_flags(dev, FLAGS_REX5572); - return (0); + return (BUS_PROBE_DEFAULT); } return(EIO); } @@ -234,8 +241,6 @@ ncv_pccard_attach(device_t dev) struct ncv_softc *sc = device_get_softc(dev); int error; - bzero(sc, sizeof(struct ncv_softc)); - error = ncv_alloc_resource(dev); if (error) { return(error); @@ -245,8 +250,8 @@ ncv_pccard_attach(device_t dev) ncv_release_resource(dev); return(ENXIO); } - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, ncv_pccard_intr, (void *)sc, &sc->ncv_intrhand); + error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, ncv_pccard_intr, sc, &sc->ncv_intrhand); if (error) { ncv_release_resource(dev); return(error); @@ -293,12 +298,9 @@ static void ncv_card_unload(device_t devi) { struct ncv_softc *sc = device_get_softc(devi); - intrmask_t s; - s = splcam(); - scsi_low_deactivate((struct scsi_low_softc *)sc); - scsi_low_dettach(&sc->sc_sclow); - splx(s); + scsi_low_deactivate(&sc->sc_sclow); + scsi_low_detach(&sc->sc_sclow); } static int @@ -308,8 +310,7 @@ ncvprobe(device_t devi) struct ncv_softc *sc = device_get_softc(devi); u_int32_t flags = device_get_flags(devi); - rv = ncvprobesubr(rman_get_bustag(sc->port_res), - rman_get_bushandle(sc->port_res), + rv = ncvprobesubr(sc->port_res, flags, NCV_HOSTID); return rv; @@ -321,27 +322,15 @@ ncvattach(device_t devi) struct ncv_softc *sc; struct scsi_low_softc *slp; u_int32_t flags = device_get_flags(devi); - intrmask_t s; - char dvname[16]; /* SCSI_LOW_DVNAME_LEN */ - - strcpy(dvname, "ncv"); sc = device_get_softc(devi); - if (sc == NULL) { - return(0); - } slp = &sc->sc_sclow; slp->sl_dev = devi; - sc->sc_iot = rman_get_bustag(sc->port_res); - sc->sc_ioh = rman_get_bushandle(sc->port_res); - slp->sl_hostid = NCV_HOSTID; slp->sl_cfgflags = flags; - s = splcam(); ncvattachsubr(sc); - splx(s); return(NCVIOSZ); } diff --git a/sys/dev/ncv/ncr53c500var.h b/sys/dev/ncv/ncr53c500var.h index 85e3330dacd..d92702fac1e 100644 --- a/sys/dev/ncv/ncr53c500var.h +++ b/sys/dev/ncv/ncr53c500var.h @@ -42,10 +42,6 @@ struct ncv_softc { struct scsi_low_softc sc_sclow; /* generic data */ - bus_space_tag_t sc_iot; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_ioh; - int port_rid; int port_rid_dmy; int irq_rid; @@ -80,7 +76,7 @@ struct ncv_targ_info { /***************************************************************** * Proto *****************************************************************/ -int ncvprobesubr(bus_space_tag_t, bus_space_handle_t ioh, u_int, int); +int ncvprobesubr(struct resource *, u_int, int); void ncvattachsubr(struct ncv_softc *); int ncvintr(void *); diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c index f37bf9e81c4..9369f6cf2a2 100644 --- a/sys/dev/netmap/netmap.c +++ b/sys/dev/netmap/netmap.c @@ -375,9 +375,14 @@ ports attached to the switch) /* reduce conditional code */ // linux API, use for the knlist in FreeBSD -#define init_waitqueue_head(x) knlist_init_mtx(&(x)->si_note, NULL) +/* use a private mutex for the knlist */ +#define init_waitqueue_head(x) do { \ + struct mtx *m = &(x)->m; \ + mtx_init(m, "nm_kn_lock", NULL, MTX_DEF); \ + knlist_init_mtx(&(x)->si.si_note, m); \ + } while (0) -void freebsd_selwakeup(struct selinfo *si, int pri); +#define OS_selrecord(a, b) selrecord(a, &((b)->si)) #define OS_selwakeup(a, b) freebsd_selwakeup(a, b) #elif defined(linux) @@ -806,6 +811,19 @@ netmap_krings_create(struct netmap_adapter *na, u_int tailroom) } +#ifdef __FreeBSD__ +static void +netmap_knlist_destroy(NM_SELINFO_T *si) +{ + /* XXX kqueue(9) needed; these will mirror knlist_init. */ + knlist_delete(&si->si.si_note, curthread, 0 /* not locked */ ); + knlist_destroy(&si->si.si_note); + /* now we don't need the mutex anymore */ + mtx_destroy(&si->m); +} +#endif /* __FreeBSD__ */ + + /* undo the actions performed by netmap_krings_create */ /* call with NMG_LOCK held */ void @@ -816,6 +834,7 @@ netmap_krings_delete(struct netmap_adapter *na) /* we rely on the krings layout described above */ for ( ; kring != na->tailroom; kring++) { mtx_destroy(&kring->q_lock); + netmap_knlist_destroy(&kring->si); } free(na->tx_rings, M_DEVBUF); na->tx_rings = na->rx_rings = na->tailroom = NULL; @@ -996,9 +1015,8 @@ netmap_do_unregif(struct netmap_priv_d *priv, struct netmap_if *nifp) * XXX The wake up now must happen during *_down(), when * we order all activities to stop. -gl */ - /* XXX kqueue(9) needed; these will mirror knlist_init. */ - /* knlist_destroy(&na->tx_si.si_note); */ - /* knlist_destroy(&na->rx_si.si_note); */ + netmap_knlist_destroy(&na->tx_si); + netmap_knlist_destroy(&na->rx_si); /* delete rings and buffers */ netmap_mem_rings_delete(na); @@ -1310,7 +1328,7 @@ netmap_rxsync_from_host(struct netmap_adapter *na, struct thread *td, void *pwai /* access copies of cur,tail in the kring */ if (kring->rcur == kring->rtail && td) /* no bufs available */ - selrecord(td, &kring->si); + OS_selrecord(td, &kring->si); mbq_unlock(q); return ret; @@ -2410,7 +2428,7 @@ flush_tx: } } if (want_tx && retry_tx && !is_kevent) { - selrecord(td, check_all_tx ? + OS_selrecord(td, check_all_tx ? &na->tx_si : &na->tx_rings[priv->np_txqfirst].si); retry_tx = 0; goto flush_tx; @@ -2479,7 +2497,7 @@ do_retry_rx: } if (retry_rx && !is_kevent) - selrecord(td, check_all_rx ? + OS_selrecord(td, check_all_rx ? &na->rx_si : &na->rx_rings[priv->np_rxqfirst].si); if (send_down > 0 || retry_rx) { retry_rx = 0; @@ -3054,8 +3072,15 @@ netmap_init(void) if (error != 0) goto fail; /* XXX could use make_dev_credv() to get error number */ +#ifdef __FreeBSD__ + /* support for the 'eternal' flag */ + netmap_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, + &netmap_cdevsw, 0, NULL, UID_ROOT, GID_WHEEL, 0660, + "netmap"); +#else netmap_dev = make_dev(&netmap_cdevsw, 0, UID_ROOT, GID_WHEEL, 0660, "netmap"); +#endif if (!netmap_dev) goto fail; diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c index 160b7c0ef95..32267081455 100644 --- a/sys/dev/netmap/netmap_freebsd.c +++ b/sys/dev/netmap/netmap_freebsd.c @@ -466,6 +466,8 @@ netmap_dev_pager_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot, if (netmap_verbose) D("handle %p size %jd prot %d foff %jd", handle, (intmax_t)size, prot, (intmax_t)foff); + if (color) + *color = 0; dev_ref(vmh->dev); return 0; } @@ -654,25 +656,24 @@ netmap_open(struct cdev *dev, int oflags, int devtype, struct thread *td) * and do not need the selrecord(). */ -void freebsd_selwakeup(struct selinfo *si, int pri); void -freebsd_selwakeup(struct selinfo *si, int pri) +freebsd_selwakeup(struct nm_selinfo *si, int pri) { if (netmap_verbose) - D("on knote %p", &si->si_note); - selwakeuppri(si, pri); + D("on knote %p", &si->si.si_note); + selwakeuppri(&si->si, pri); /* use a non-zero hint to tell the notification from the * call done in kqueue_scan() which uses 0 */ - KNOTE_UNLOCKED(&si->si_note, 0x100 /* notification */); + KNOTE_UNLOCKED(&si->si.si_note, 0x100 /* notification */); } static void netmap_knrdetach(struct knote *kn) { struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; - struct selinfo *si = priv->np_rxsi; + struct selinfo *si = &priv->np_rxsi->si; D("remove selinfo %p", si); knlist_remove(&si->si_note, kn, 0); @@ -682,7 +683,7 @@ static void netmap_knwdetach(struct knote *kn) { struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; - struct selinfo *si = priv->np_txsi; + struct selinfo *si = &priv->np_txsi->si; D("remove selinfo %p", si); knlist_remove(&si->si_note, kn, 0); @@ -754,7 +755,7 @@ netmap_kqfilter(struct cdev *dev, struct knote *kn) struct netmap_priv_d *priv; int error; struct netmap_adapter *na; - struct selinfo *si; + struct nm_selinfo *si; int ev = kn->kn_filter; if (ev != EVFILT_READ && ev != EVFILT_WRITE) { @@ -777,7 +778,7 @@ netmap_kqfilter(struct cdev *dev, struct knote *kn) kn->kn_fop = (ev == EVFILT_WRITE) ? &netmap_wfiltops : &netmap_rfiltops; kn->kn_hook = priv; - knlist_add(&si->si_note, kn, 1); + knlist_add(&si->si.si_note, kn, 1); // XXX unlock(priv) ND("register %p %s td %p priv %p kn %p np_nifp %p kn_fp/fpop %s", na, na->ifp->if_xname, curthread, priv, kn, diff --git a/sys/dev/netmap/netmap_generic.c b/sys/dev/netmap/netmap_generic.c index 774038206b1..ecdb3682407 100644 --- a/sys/dev/netmap/netmap_generic.c +++ b/sys/dev/netmap/netmap_generic.c @@ -821,7 +821,7 @@ generic_netmap_attach(struct ifnet *ifp) num_tx_desc = num_rx_desc = netmap_generic_ringsize; /* starting point */ - generic_find_num_desc(ifp, &num_tx_desc, &num_rx_desc); + generic_find_num_desc(ifp, &num_tx_desc, &num_rx_desc); /* ignore errors */ ND("Netmap ring size: TX = %d, RX = %d", num_tx_desc, num_rx_desc); if (num_tx_desc == 0 || num_rx_desc == 0) { D("Device has no hw slots (tx %u, rx %u)", num_tx_desc, num_rx_desc); diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h index 76d893588e3..95b3a5deda6 100644 --- a/sys/dev/netmap/netmap_kern.h +++ b/sys/dev/netmap/netmap_kern.h @@ -37,6 +37,7 @@ #define WITH_VALE // comment out to disable VALE support #define WITH_PIPES #define WITH_MONITOR +#define WITH_GENERIC #if defined(__FreeBSD__) @@ -44,6 +45,8 @@ #define unlikely(x) __builtin_expect((long)!!(x), 0L) #define NM_LOCK_T struct mtx + +/* netmap global lock */ #define NMG_LOCK_T struct sx #define NMG_LOCK_INIT() sx_init(&netmap_global_lock, \ "netmap global lock") @@ -52,7 +55,7 @@ #define NMG_UNLOCK() sx_xunlock(&netmap_global_lock) #define NMG_LOCK_ASSERT() sx_assert(&netmap_global_lock, SA_XLOCKED) -#define NM_SELINFO_T struct selinfo +#define NM_SELINFO_T struct nm_selinfo #define MBUF_LEN(m) ((m)->m_pkthdr.len) #define MBUF_IFP(m) ((m)->m_pkthdr.rcvif) #define NM_SEND_UP(ifp, m) ((NA(ifp))->if_input)(ifp, m) @@ -85,6 +88,13 @@ struct netmap_adapter *netmap_getna(if_t ifp); MALLOC_DECLARE(M_NETMAP); +struct nm_selinfo { + struct selinfo si; + struct mtx m; +}; + +void freebsd_selwakeup(struct nm_selinfo *si, int pri); + // XXX linux struct, not used in FreeBSD struct net_device_ops { }; @@ -107,13 +117,20 @@ struct hrtimer { #define NM_ATOMIC_T volatile long unsigned int -// XXX a mtx would suffice here too 20130404 gl -#define NMG_LOCK_T struct semaphore -#define NMG_LOCK_INIT() sema_init(&netmap_global_lock, 1) -#define NMG_LOCK_DESTROY() -#define NMG_LOCK() down(&netmap_global_lock) -#define NMG_UNLOCK() up(&netmap_global_lock) -#define NMG_LOCK_ASSERT() // XXX to be completed +#define NM_MTX_T struct mutex +#define NM_MTX_INIT(m, s) do { (void)s; mutex_init(&(m)); } while (0) +#define NM_MTX_DESTROY(m) do { (void)m; } while (0) +#define NM_MTX_LOCK(m) mutex_lock(&(m)) +#define NM_MTX_UNLOCK(m) mutex_unlock(&(m)) +#define NM_MTX_LOCK_ASSERT(m) mutex_is_locked(&(m)) + +#define NMG_LOCK_T NM_MTX_T +#define NMG_LOCK_INIT() NM_MTX_INIT(netmap_global_lock, \ + "netmap_global_lock") +#define NMG_LOCK_DESTROY() NM_MTX_DESTROY(netmap_global_lock) +#define NMG_LOCK() NM_MTX_LOCK(netmap_global_lock) +#define NMG_UNLOCK() NM_MTX_UNLOCK(netmap_global_lock) +#define NMG_LOCK_ASSERT() NM_MTX_LOCK_ASSERT(netmap_global_lock) #ifndef DEV_NETMAP #define DEV_NETMAP @@ -266,7 +283,7 @@ struct netmap_kring { struct netmap_adapter *na; - /* The folloiwing fields are for VALE switch support */ + /* The following fields are for VALE switch support */ struct nm_bdg_fwd *nkr_ft; uint32_t *nkr_leases; #define NR_NOSLOT ((uint32_t)~0) /* used in nkr_*lease* */ @@ -641,6 +658,7 @@ struct netmap_hw_adapter { /* physical device */ int (*nm_hw_register)(struct netmap_adapter *, int onoff); }; +#ifdef WITH_GENERIC /* Mitigation support. */ struct nm_generic_mit { struct hrtimer mit_timer; @@ -668,6 +686,7 @@ struct netmap_generic_adapter { /* emulated device */ netdev_tx_t (*save_start_xmit)(struct mbuf *, struct ifnet *); #endif }; +#endif /* WITH_GENERIC */ static __inline int netmap_real_tx_rings(struct netmap_adapter *na) @@ -1481,6 +1500,7 @@ struct netmap_monitor_adapter { #endif /* WITH_MONITOR */ +#ifdef WITH_GENERIC /* * generic netmap emulation for devices that do not have * native netmap support. @@ -1512,6 +1532,7 @@ void netmap_mitigation_start(struct nm_generic_mit *mit); void netmap_mitigation_restart(struct nm_generic_mit *mit); int netmap_mitigation_active(struct nm_generic_mit *mit); void netmap_mitigation_cleanup(struct nm_generic_mit *mit); +#endif /* WITH_GENERIC */ diff --git a/sys/dev/netmap/netmap_monitor.c b/sys/dev/netmap/netmap_monitor.c index 485c370d91e..746abb524d0 100644 --- a/sys/dev/netmap/netmap_monitor.c +++ b/sys/dev/netmap/netmap_monitor.c @@ -179,7 +179,7 @@ netmap_monitor_parent_sync(struct netmap_kring *kring, int flags, u_int* ringptr i = nm_next(i, mlim); } - wmb(); + mb(); mkring->nr_hwtail = i; mtx_unlock(&mkring->q_lock); @@ -225,7 +225,7 @@ netmap_monitor_rxsync(struct netmap_kring *kring, int flags) { ND("%s %x", kring->name, flags); kring->nr_hwcur = kring->rcur; - rmb(); + mb(); nm_rxsync_finalize(kring); return 0; } diff --git a/sys/dev/netmap/netmap_pipe.c b/sys/dev/netmap/netmap_pipe.c index bc998c04a17..64828670c35 100644 --- a/sys/dev/netmap/netmap_pipe.c +++ b/sys/dev/netmap/netmap_pipe.c @@ -197,10 +197,10 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) if (m < 0) m += txkring->nkr_num_slots; limit = m; - m = rxkring->nkr_num_slots - 1; /* max avail space on destination */ + m = lim_rx; /* max avail space on destination */ busy = j - rxkring->nr_hwcur; /* busy slots */ if (busy < 0) - busy += txkring->nkr_num_slots; + busy += rxkring->nkr_num_slots; m -= busy; /* subtract busy slots */ ND(2, "m %d limit %d", m, limit); if (m < limit) @@ -228,7 +228,7 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) k = nm_next(k, lim_tx); } - wmb(); /* make sure the slots are updated before publishing them */ + mb(); /* make sure the slots are updated before publishing them */ rxkring->nr_hwtail = j; txkring->nr_hwcur = k; txkring->nr_hwtail = nm_prev(k, lim_tx); @@ -237,7 +237,7 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) ND(2, "after: hwcur %d hwtail %d cur %d head %d tail %d j %d", txkring->nr_hwcur, txkring->nr_hwtail, txkring->rcur, txkring->rhead, txkring->rtail, j); - wmb(); /* make sure rxkring->nr_hwtail is updated before notifying */ + mb(); /* make sure rxkring->nr_hwtail is updated before notifying */ rxkring->na->nm_notify(rxkring->na, rxkring->ring_id, NR_RX, 0); return 0; @@ -253,12 +253,12 @@ netmap_pipe_rxsync(struct netmap_kring *rxkring, int flags) rxkring->nr_hwcur = rxkring->rhead; /* recover user-relased slots */ ND(5, "hwcur %d hwtail %d cur %d head %d tail %d", rxkring->nr_hwcur, rxkring->nr_hwtail, rxkring->rcur, rxkring->rhead, rxkring->rtail); - rmb(); /* paired with the first wmb() in txsync */ + mb(); /* paired with the first mb() in txsync */ nm_rxsync_finalize(rxkring); if (oldhwcur != rxkring->nr_hwcur) { /* we have released some slots, notify the other end */ - wmb(); /* make sure nr_hwcur is updated before notifying */ + mb(); /* make sure nr_hwcur is updated before notifying */ txkring->na->nm_notify(txkring->na, txkring->ring_id, NR_TX, 0); } return 0; diff --git a/sys/dev/nsp/nsp.c b/sys/dev/nsp/nsp.c index dae2bd6403a..5cda44e5328 100644 --- a/sys/dev/nsp/nsp.c +++ b/sys/dev/nsp/nsp.c @@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -178,45 +179,36 @@ struct scsi_low_funcs nspfuncs = { /**************************************************** * hwfuncs ****************************************************/ -static __inline u_int8_t nsp_cr_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs); -static __inline void nsp_cr_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs, u_int8_t va); - -static __inline u_int8_t -nsp_cr_read_1(bst, bsh, ofs) - bus_space_tag_t bst; - bus_space_handle_t bsh; - bus_addr_t ofs; +static __inline uint8_t +nsp_cr_read_1(struct resource *res, bus_addr_t ofs) { - - bus_space_write_1(bst, bsh, nsp_idxr, ofs); - return bus_space_read_1(bst, bsh, nsp_datar); + + bus_write_1(res, nsp_idxr, ofs); + return bus_read_1(res, nsp_datar); } static __inline void -nsp_cr_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_addr_t ofs, - u_int8_t va) +nsp_cr_write_1(struct resource *res, bus_addr_t ofs, uint8_t va) { - bus_space_write_1(bst, bsh, nsp_idxr, ofs); - bus_space_write_1(bst, bsh, nsp_datar, va); + bus_write_1(res, nsp_idxr, ofs); + bus_write_1(res, nsp_datar, va); } static int nsp_expect_signal(struct nsp_softc *sc, u_int8_t curphase, u_int8_t mask) { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int wc; u_int8_t ph, isrc; for (wc = 0; wc < NSP_DELAY_MAX / NSP_DELAY_INTERVAL; wc ++) { - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if (ph == (u_int8_t) -1) return -1; - isrc = bus_space_read_1(bst, bsh, nsp_irqsr); + isrc = bus_read_1(sc->port_res, nsp_irqsr); if (isrc & IRQSR_SCSI) return 0; @@ -234,42 +226,40 @@ static void nsphw_init(sc) struct nsp_softc *sc; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; /* block all interrupts */ - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_ALLMASK); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_ALLMASK); /* setup SCSI interface */ - bus_space_write_1(bst, bsh, nsp_ifselr, IFSELR_IFSEL); + bus_write_1(sc->port_res, nsp_ifselr, IFSELR_IFSEL); - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, 0); + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, 0); - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, XFERMR_IO8); - nsp_cr_write_1(bst, bsh, NSPR_CLKDIVR, sc->sc_iclkdiv); + nsp_cr_write_1(sc->port_res, NSPR_XFERMR, XFERMR_IO8); + nsp_cr_write_1(sc->port_res, NSPR_CLKDIVR, sc->sc_iclkdiv); - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, sc->sc_icr); - nsp_cr_write_1(bst, bsh, NSPR_PARITYR, sc->sc_parr); - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, sc->sc_icr); + nsp_cr_write_1(sc->port_res, NSPR_PARITYR, sc->sc_parr); + nsp_cr_write_1(sc->port_res, NSPR_PTCLRR, PTCLRR_ACK | PTCLRR_REQ | PTCLRR_HOST | PTCLRR_RSS); /* setup fifo asic */ - bus_space_write_1(bst, bsh, nsp_ifselr, IFSELR_REGSEL); - nsp_cr_write_1(bst, bsh, NSPR_TERMPWRC, 0); - if ((nsp_cr_read_1(bst, bsh, NSPR_OCR) & OCR_TERMPWRS) == 0) - nsp_cr_write_1(bst, bsh, NSPR_TERMPWRC, TERMPWRC_POWON); + bus_write_1(sc->port_res, nsp_ifselr, IFSELR_REGSEL); + nsp_cr_write_1(sc->port_res, NSPR_TERMPWRC, 0); + if ((nsp_cr_read_1(sc->port_res, NSPR_OCR) & OCR_TERMPWRS) == 0) + nsp_cr_write_1(sc->port_res, NSPR_TERMPWRC, TERMPWRC_POWON); - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, XFERMR_IO8); - nsp_cr_write_1(bst, bsh, NSPR_CLKDIVR, sc->sc_clkdiv); - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); + nsp_cr_write_1(sc->port_res, NSPR_XFERMR, XFERMR_IO8); + nsp_cr_write_1(sc->port_res, NSPR_CLKDIVR, sc->sc_clkdiv); + nsp_cr_write_1(sc->port_res, NSPR_TIMERCNT, 0); + nsp_cr_write_1(sc->port_res, NSPR_TIMERCNT, 0); - nsp_cr_write_1(bst, bsh, NSPR_SYNCR, 0); - nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, 0); + nsp_cr_write_1(sc->port_res, NSPR_SYNCR, 0); + nsp_cr_write_1(sc->port_res, NSPR_ACKWIDTH, 0); /* enable interrupts and ack them */ - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, sc->sc_icr); - bus_space_write_1(bst, bsh, nsp_irqcr, IRQSR_MASK); + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, sc->sc_icr); + bus_write_1(sc->port_res, nsp_irqcr, IRQSR_MASK); nsp_setup_fifo(sc, NSP_FIFO_OFF, SCSI_LOW_READ, 0); } @@ -281,12 +271,10 @@ static void nsphw_attention(sc) struct nsp_softc *sc; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; u_int8_t cr; - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR)/* & ~SCBUSCR_ACK */; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr | SCBUSCR_ATN); + cr = nsp_cr_read_1(sc->port_res, NSPR_SCBUSCR)/* & ~SCBUSCR_ACK */; + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr | SCBUSCR_ATN); DELAY(10); } @@ -294,19 +282,17 @@ static void nsphw_bus_reset(sc) struct nsp_softc *sc; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int i; - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_ALLMASK); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_ALLMASK); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, SCBUSCR_RST); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, SCBUSCR_RST); DELAY(100 * 1000); /* 100ms */ - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, 0); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, 0); for (i = 0; i < 5; i ++) - (void) nsp_cr_read_1(bst, bsh, NSPR_IRQPHS); + (void) nsp_cr_read_1(sc->port_res, NSPR_IRQPHS); - bus_space_write_1(bst, bsh, nsp_irqcr, IRQSR_MASK); + bus_write_1(sc->port_res, nsp_irqcr, IRQSR_MASK); } static void @@ -314,19 +300,17 @@ nsphw_selection_done_and_expect_msgout(sc) struct nsp_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; /* clear ack counter */ sc->sc_cnt = 0; - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_PT | PTCLRR_ACK | + nsp_cr_write_1(sc->port_res, NSPR_PTCLRR, PTCLRR_PT | PTCLRR_ACK | PTCLRR_REQ | PTCLRR_HOST); /* deassert sel and assert atten */ sc->sc_seltout = 0; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, sc->sc_busc); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, sc->sc_busc); DELAY(1); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, sc->sc_busc | SCBUSCR_ADIR | SCBUSCR_ACKEN); SCSI_LOW_ASSERT_ATN(slp); } @@ -337,21 +321,17 @@ nsphw_start_selection(sc, cb) struct slccb *cb; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; struct targ_info *ti = cb->ti; register u_int8_t arbs, ph; - int s, wc; + int wc; wc = sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; sc->sc_dataout_timeout = 0; /* check bus free */ - s = splhigh(); - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if (ph != SCBUSMON_FREE) { - splx(s); #ifdef NSP_STATICS nsp_statics.arbit_conflict_1 ++; #endif /* NSP_STATICS */ @@ -359,21 +339,20 @@ nsphw_start_selection(sc, cb) } /* start arbitration */ - nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_EXEC); - splx(s); + nsp_cr_write_1(sc->port_res, NSPR_ARBITS, ARBITS_EXEC); SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART); do { /* XXX: what a stupid chip! */ - arbs = nsp_cr_read_1(bst, bsh, NSPR_ARBITS); + arbs = nsp_cr_read_1(sc->port_res, NSPR_ARBITS); DELAY(1); } while ((arbs & (ARBITS_WIN | ARBITS_FAIL)) == 0 && wc -- > 0); if ((arbs & ARBITS_WIN) == 0) { - nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_CLR); + nsp_cr_write_1(sc->port_res, NSPR_ARBITS, ARBITS_CLR); #ifdef NSP_STATICS nsp_statics.arbit_conflict_2 ++; #endif /* NSP_STATICS */ @@ -384,18 +363,17 @@ nsphw_start_selection(sc, cb) SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); scsi_low_arbit_win(slp); - s = splhigh(); DELAY(3); - nsp_cr_write_1(bst, bsh, NSPR_DATA, + nsp_cr_write_1(sc->port_res, NSPR_DATA, sc->sc_idbit | (1 << ti->ti_id)); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, SCBUSCR_SEL | SCBUSCR_BSY | sc->sc_busc); DELAY(3); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, SCBUSCR_SEL | + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, SCBUSCR_SEL | SCBUSCR_BSY | SCBUSCR_DOUT | sc->sc_busc); - nsp_cr_write_1(bst, bsh, NSPR_ARBITS, ARBITS_CLR); + nsp_cr_write_1(sc->port_res, NSPR_ARBITS, ARBITS_CLR); DELAY(3); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, SCBUSCR_SEL | SCBUSCR_DOUT | sc->sc_busc); DELAY(1); @@ -408,7 +386,7 @@ nsphw_start_selection(sc, cb) for (wc = 0; wc < NSP_FIRST_SEL_WAIT / NSP_SEL_CHECK_INTERVAL; wc ++) { - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if ((ph & SCBUSMON_BSY) == 0) { DELAY(NSP_SEL_CHECK_INTERVAL); @@ -416,18 +394,16 @@ nsphw_start_selection(sc, cb) } DELAY(1); - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if ((ph & SCBUSMON_BSY) != 0) { nsphw_selection_done_and_expect_msgout(sc); - splx(s); SCSI_LOW_SETUP_PHASE(ti, PH_SELECTED); return SCSI_LOW_START_OK; } } } - splx(s); /* check a selection timeout */ nsp_start_timer(sc, NSP_TIMER_1MS); @@ -491,8 +467,6 @@ nsp_msg(sc, ti, msg) struct targ_info *ti; u_int msg; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; struct ncp_synch_data *sdp; struct nsp_targ_info *nti = (void *) ti; u_int period, offset; @@ -544,8 +518,8 @@ nsp_msg(sc, ti, msg) error = 0; } - nsp_cr_write_1(bst, bsh, NSPR_SYNCR, nti->nti_reg_syncr); - nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, nti->nti_reg_ackwidth); + nsp_cr_write_1(sc->port_res, NSPR_SYNCR, nti->nti_reg_syncr); + nsp_cr_write_1(sc->port_res, NSPR_ACKWIDTH, nti->nti_reg_ackwidth); return error; } @@ -573,25 +547,20 @@ nsp_start_timer(sc, time) struct nsp_softc *sc; int time; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; sc->sc_timer = time; - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, time); + nsp_cr_write_1(sc->port_res, NSPR_TIMERCNT, time); } /************************************************************** * General probe attach **************************************************************/ int -nspprobesubr(iot, ioh, dvcfg) - bus_space_tag_t iot; - bus_space_handle_t ioh; - u_int dvcfg; +nspprobesubr(struct resource *res, u_int dvcfg) { u_int8_t regv; - regv = bus_space_read_1(iot, ioh, nsp_fifosr); + regv = bus_read_1(res, nsp_fifosr); if (regv < 0x11 || regv >= 0x20) return 0; return 1; @@ -603,8 +572,6 @@ nspattachsubr(sc) { struct scsi_low_softc *slp = &sc->sc_sclow; - printf("\n"); - sc->sc_idbit = (1 << slp->sl_hostid); slp->sl_flags |= HW_READ_PADDING; slp->sl_funcs = &nspfuncs; @@ -621,14 +588,12 @@ static u_int nsp_fifo_count(sc) struct nsp_softc *sc; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; u_int count; - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_RSS_ACK | PTCLRR_PT); - count = bus_space_read_1(bst, bsh, nsp_datar); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 8); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 16); + nsp_cr_write_1(sc->port_res, NSPR_PTCLRR, PTCLRR_RSS_ACK | PTCLRR_PT); + count = bus_read_1(sc->port_res, nsp_datar); + count += (((u_int) bus_read_1(sc->port_res, nsp_datar)) << 8); + count += (((u_int) bus_read_1(sc->port_res, nsp_datar)) << 16); return count; } @@ -636,14 +601,12 @@ static u_int nsp_request_count(sc) struct nsp_softc *sc; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; u_int count; - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_RSS_REQ | PTCLRR_PT); - count = bus_space_read_1(bst, bsh, nsp_datar); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 8); - count += (((u_int) bus_space_read_1(bst, bsh, nsp_datar)) << 16); + nsp_cr_write_1(sc->port_res, NSPR_PTCLRR, PTCLRR_RSS_REQ | PTCLRR_PT); + count = bus_read_1(sc->port_res, nsp_datar); + count += (((u_int) bus_read_1(sc->port_res, nsp_datar)) << 8); + count += (((u_int) bus_read_1(sc->port_res, nsp_datar)) << 16); return count; } @@ -683,7 +646,7 @@ nsp_setup_fifo(sc, on, direction, datalen) /* determine a transfer type */ if (datalen < DEV_BSIZE || (datalen & 3) != 0) { - if (sc->sc_memh != 0 && + if (sc->mem_res != NULL && (nsp_io_control & NSP_USE_MEMIO) != 0) xfermode = XFERMR_XEN | XFERMR_MEM8; else @@ -691,7 +654,7 @@ nsp_setup_fifo(sc, on, direction, datalen) } else { - if (sc->sc_memh != 0 && + if (sc->mem_res != NULL && (nsp_io_control & NSP_USE_MEMIO) != 0) xfermode = XFERMR_XEN | XFERMR_MEM32; else @@ -703,7 +666,7 @@ nsp_setup_fifo(sc, on, direction, datalen) out: sc->sc_xfermr = xfermode; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, NSPR_XFERMR, sc->sc_xfermr); + nsp_cr_write_1(sc->port_res, NSPR_XFERMR, sc->sc_xfermr); } static void @@ -721,7 +684,7 @@ nsp_pdma_end(sc, ti) if ((sc->sc_icr & SCIENR_FIFO) != 0) { sc->sc_icr &= ~SCIENR_FIFO; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, NSPR_SCIENR, sc->sc_icr); + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, sc->sc_icr); } if (cb == NULL) @@ -783,24 +746,22 @@ nsp_data_padding(sc, direction, count) int direction; u_int count; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; if (count > NSP_MAX_DATA_SIZE) count = NSP_MAX_DATA_SIZE; - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, XFERMR_XEN | XFERMR_IO8); + nsp_cr_write_1(sc->port_res, NSPR_XFERMR, XFERMR_XEN | XFERMR_IO8); if (direction == SCSI_LOW_READ) { while (count -- > 0) - (void) bus_space_read_1(bst, bsh, nsp_fifodr); + (void) bus_read_1(sc->port_res, nsp_fifodr); } else { while (count -- > 0) - (void) bus_space_write_1(bst, bsh, nsp_fifodr, 0); + (void) bus_write_1(sc->port_res, nsp_fifodr, 0); } - nsp_cr_write_1(bst, bsh, NSPR_XFERMR, sc->sc_xfermr); + nsp_cr_write_1(sc->port_res, NSPR_XFERMR, sc->sc_xfermr); } static int @@ -809,8 +770,6 @@ nsp_read_fifo(sc, suspendio) int suspendio; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; u_int res; res = nsp_fifo_count(sc); @@ -857,12 +816,12 @@ nsp_read_fifo(sc, suspendio) if ((sc->sc_xfermr & XFERMR_MEM32) != 0) { res &= ~3; - bus_space_read_region_4(sc->sc_memt, sc->sc_memh, 0, + bus_read_region_4(sc->mem_res, 0, (u_int32_t *) slp->sl_scp.scp_data, res >> 2); } else { - bus_space_read_region_1(sc->sc_memt, sc->sc_memh, 0, + bus_read_region_1(sc->mem_res, 0, (u_int8_t *) slp->sl_scp.scp_data, res); } } @@ -871,19 +830,19 @@ nsp_read_fifo(sc, suspendio) if ((sc->sc_xfermr & XFERMR_IO32) != 0) { res &= ~3; - bus_space_read_multi_4(bst, bsh, nsp_fifodr, + bus_read_multi_4(sc->port_res, nsp_fifodr, (u_int32_t *) slp->sl_scp.scp_data, res >> 2); } else { - bus_space_read_multi_1(bst, bsh, nsp_fifodr, + bus_read_multi_1(sc->port_res, nsp_fifodr, (u_int8_t *) slp->sl_scp.scp_data, res); } } - if (nsp_cr_read_1(bst, bsh, NSPR_PARITYR) & PARITYR_PE) + if (nsp_cr_read_1(sc->port_res, NSPR_PARITYR) & PARITYR_PE) { - nsp_cr_write_1(bst, bsh, NSPR_PARITYR, + nsp_cr_write_1(sc->port_res, NSPR_PARITYR, PARITYR_ENABLE | PARITYR_CLEAR); scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_ERROR, 1); } @@ -900,8 +859,6 @@ nsp_write_fifo(sc, suspendio) int suspendio; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; u_int res; register u_int8_t stat; @@ -930,7 +887,7 @@ nsp_write_fifo(sc, suspendio) res = slp->sl_scp.scp_datalen; /* XXX: reconfirm! */ - stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON) & SCBUSMON_PHMASK; + stat = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON) & SCBUSMON_PHMASK; if (stat != PHASE_DATAOUT) return 0; @@ -938,12 +895,12 @@ nsp_write_fifo(sc, suspendio) { if ((sc->sc_xfermr & XFERMR_MEM32) != 0) { - bus_space_write_region_4(sc->sc_memt, sc->sc_memh, 0, + bus_write_region_4(sc->mem_res, 0, (u_int32_t *) slp->sl_scp.scp_data, res >> 2); } else { - bus_space_write_region_1(sc->sc_memt, sc->sc_memh, 0, + bus_write_region_1(sc->mem_res, 0, (u_int8_t *) slp->sl_scp.scp_data, res); } } @@ -951,12 +908,12 @@ nsp_write_fifo(sc, suspendio) { if ((sc->sc_xfermr & XFERMR_IO32) != 0) { - bus_space_write_multi_4(bst, bsh, nsp_fifodr, + bus_write_multi_4(sc->port_res, nsp_fifodr, (u_int32_t *) slp->sl_scp.scp_data, res >> 2); } else { - bus_space_write_multi_1(bst, bsh, nsp_fifodr, + bus_write_multi_1(sc->port_res, nsp_fifodr, (u_int8_t *) slp->sl_scp.scp_data, res); } } @@ -971,19 +928,17 @@ static int nsp_wait_interrupt(sc) struct nsp_softc *sc; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int tout; register u_int8_t isrc; for (tout = 0; tout < DEV_BSIZE / 10; tout ++) { - isrc = bus_space_read_1(bst, bsh, nsp_irqsr); + isrc = bus_read_1(sc->port_res, nsp_irqsr); if ((isrc & (IRQSR_SCSI | IRQSR_FIFO)) != 0) { if ((isrc & IRQSR_FIFO) != 0) { - bus_space_write_1(bst, bsh, + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_FIFOCL); } return 1; @@ -999,8 +954,6 @@ nsp_pio_read(sc, suspendio) int suspendio; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int tout, padding, datalen; register u_int8_t stat, fstat; @@ -1012,7 +965,7 @@ nsp_pio_read(sc, suspendio) ReadLoop: while (1) { - stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + stat = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if (stat == (u_int8_t) -1) return; @@ -1024,12 +977,12 @@ ReadLoop: } /* data phase */ - fstat = bus_space_read_1(bst, bsh, nsp_fifosr); + fstat = bus_read_1(sc->port_res, nsp_fifosr); if ((fstat & FIFOSR_FULLEMP) != 0) { if ((sc->sc_icr & SCIENR_FIFO) != 0) { - bus_space_write_1(bst, bsh, nsp_irqcr, + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_FIFOCL); } @@ -1078,8 +1031,6 @@ nsp_pio_write(sc, suspendio) int suspendio; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; u_int rcount, acount; int tout, datalen; register u_int8_t stat, fstat; @@ -1091,7 +1042,7 @@ nsp_pio_write(sc, suspendio) WriteLoop: while (1) { - stat = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON) & SCBUSMON_PHMASK; + stat = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON) & SCBUSMON_PHMASK; if (stat != PHASE_DATAOUT) return; @@ -1102,12 +1053,12 @@ WriteLoop: return; } - fstat = bus_space_read_1(bst, bsh, nsp_fifosr); + fstat = bus_read_1(sc->port_res, nsp_fifosr); if ((fstat & FIFOSR_FULLEMP) != 0) { if ((sc->sc_icr & SCIENR_FIFO) != 0) { - bus_space_write_1(bst, bsh, nsp_irqcr, + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_FIFOCL); } @@ -1187,14 +1138,12 @@ static int nsp_negate_signal(struct nsp_softc *sc, u_int8_t mask, u_char *s) { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int wc; u_int8_t regv; for (wc = 0; wc < NSP_DELAY_MAX / NSP_DELAY_INTERVAL; wc ++) { - regv = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + regv = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if (regv == (u_int8_t) -1) return -1; if ((regv & mask) == 0) @@ -1214,8 +1163,6 @@ nsp_xfer(sc, buf, len, phase, clear_atn) int phase; int clear_atn; { - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int ptr, rv; for (ptr = 0; len > 0; len --, ptr ++) @@ -1226,18 +1173,18 @@ nsp_xfer(sc, buf, len, phase, clear_atn) if (len == 1 && clear_atn != 0) { - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, SCBUSCR_ADIR | SCBUSCR_ACKEN); SCSI_LOW_DEASSERT_ATN(&sc->sc_sclow); } if (phase & SCBUSMON_IO) { - buf[ptr] = nsp_cr_read_1(bst, bsh, NSPR_DATAACK); + buf[ptr] = nsp_cr_read_1(sc->port_res, NSPR_DATAACK); } else { - nsp_cr_write_1(bst, bsh, NSPR_DATAACK, buf[ptr]); + nsp_cr_write_1(sc->port_res, NSPR_DATAACK, buf[ptr]); } nsp_negate_signal(sc, SCBUSMON_ACK, "xfer"); } @@ -1254,13 +1201,11 @@ nsp_reselected(sc) struct nsp_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; struct targ_info *ti; u_int sid; u_int8_t cr; - sid = (u_int) nsp_cr_read_1(bst, bsh, NSPR_RESELR); + sid = (u_int) nsp_cr_read_1(sc->port_res, NSPR_RESELR); sid &= ~sc->sc_idbit; sid = ffs(sid) - 1; if ((ti = scsi_low_reselected(slp, sid)) == NULL) @@ -1268,11 +1213,11 @@ nsp_reselected(sc) nsp_negate_signal(sc, SCBUSMON_SEL, "reselect"); - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR); + cr = nsp_cr_read_1(sc->port_res, NSPR_SCBUSCR); cr &= ~(SCBUSCR_BSY | SCBUSCR_ATN); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr); cr |= SCBUSCR_ADIR | SCBUSCR_ACKEN; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr); #ifdef NSP_STATICS nsp_statics.reselect ++; @@ -1286,15 +1231,13 @@ nsp_disconnected(sc, ti) struct targ_info *ti; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; - nsp_cr_write_1(bst, bsh, NSPR_PTCLRR, PTCLRR_PT | PTCLRR_ACK | + nsp_cr_write_1(sc->port_res, NSPR_PTCLRR, PTCLRR_PT | PTCLRR_ACK | PTCLRR_REQ | PTCLRR_HOST); if ((sc->sc_icr & SCIENR_FIFO) != 0) { sc->sc_icr &= ~SCIENR_FIFO; - nsp_cr_write_1(bst, bsh, NSPR_SCIENR, sc->sc_icr); + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, sc->sc_icr); } sc->sc_cnt = 0; sc->sc_dataout_timeout = 0; @@ -1326,14 +1269,12 @@ nsp_target_nexus_establish(sc) struct nsp_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; struct targ_info *ti = slp->sl_Tnexus; struct nsp_targ_info *nti = (void *) ti; /* setup synch transfer registers */ - nsp_cr_write_1(bst, bsh, NSPR_SYNCR, nti->nti_reg_syncr); - nsp_cr_write_1(bst, bsh, NSPR_ACKWIDTH, nti->nti_reg_ackwidth); + nsp_cr_write_1(sc->port_res, NSPR_SYNCR, nti->nti_reg_syncr); + nsp_cr_write_1(sc->port_res, NSPR_ACKWIDTH, nti->nti_reg_ackwidth); /* setup pdma fifo (minimum) */ nsp_setup_fifo(sc, NSP_FIFO_ON, SCSI_LOW_READ, 0); @@ -1367,7 +1308,7 @@ nsp_ccb_nexus_establish(sc) (nsp_io_control & NSP_READ_FIFO_INTERRUPTS) != 0) { sc->sc_icr |= SCIENR_FIFO; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, sc->sc_icr); } } @@ -1377,7 +1318,7 @@ nsp_ccb_nexus_establish(sc) (nsp_io_control & NSP_WRITE_FIFO_INTERRUPTS) != 0) { sc->sc_icr |= SCIENR_FIFO; - nsp_cr_write_1(sc->sc_iot, sc->sc_ioh, + nsp_cr_write_1(sc->port_res, NSPR_SCIENR, sc->sc_icr); } } @@ -1408,8 +1349,6 @@ nspintr(arg) { struct nsp_softc *sc = arg; struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; struct targ_info *ti; struct buf *bp; u_int derror, flags; @@ -1422,11 +1361,11 @@ nspintr(arg) if (slp->sl_flags & HW_INACTIVE) return 0; - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_IRQDIS); - isrc = bus_space_read_1(bst, bsh, nsp_irqsr); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_IRQDIS); + isrc = bus_read_1(sc->port_res, nsp_irqsr); if (isrc == (u_int8_t) -1 || (isrc & IRQSR_MASK) == 0) { - bus_space_write_1(bst, bsh, nsp_irqcr, 0); + bus_write_1(sc->port_res, nsp_irqcr, 0); return 0; } @@ -1434,10 +1373,10 @@ nspintr(arg) * Do not read an irqphs register if no scsi phase interrupt. * Unless, you should lose a scsi phase interrupt. */ - ph = nsp_cr_read_1(bst, bsh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if ((isrc & IRQSR_SCSI) != 0) { - irqphs = nsp_cr_read_1(bst, bsh, NSPR_IRQPHS); + irqphs = nsp_cr_read_1(sc->port_res, NSPR_IRQPHS); } else irqphs = 0; @@ -1447,8 +1386,8 @@ nspintr(arg) */ if (sc->sc_timer != 0) { - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); - nsp_cr_write_1(bst, bsh, NSPR_TIMERCNT, 0); + nsp_cr_write_1(sc->port_res, NSPR_TIMERCNT, 0); + nsp_cr_write_1(sc->port_res, NSPR_TIMERCNT, 0); sc->sc_timer = 0; } @@ -1458,7 +1397,7 @@ nspintr(arg) { if ((isrc & IRQSR_MASK) == IRQSR_TIMER && sc->sc_seltout == 0) { - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_TIMERCL); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_TIMERCL); return 1; } regv |= IRQCR_TIMERCL; @@ -1471,7 +1410,7 @@ nspintr(arg) } /* OK. enable all interrupts */ - bus_space_write_1(bst, bsh, nsp_irqcr, regv); + bus_write_1(sc->port_res, nsp_irqcr, regv); /******************************************* * debug section @@ -1502,7 +1441,7 @@ nspintr(arg) if ((irqphs & IRQPHS_RSEL) != 0) { - bus_space_write_1(bst, bsh, nsp_irqcr, IRQCR_RESCL); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_RESCL); if (nsp_reselected(sc) == EJUSTRETURN) return 1; } @@ -1532,7 +1471,7 @@ nspintr(arg) if (sc->sc_seltout >= NSP_SELTIMEOUT) { sc->sc_seltout = 0; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, 0); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, 0); return nsp_disconnected(sc, ti); } sc->sc_seltout ++; @@ -1624,12 +1563,12 @@ nspintr(arg) scsi_low_attention(slp); } - nsp_cr_write_1(bst, bsh, NSPR_CMDCR, CMDCR_PTCLR); + nsp_cr_write_1(sc->port_res, NSPR_CMDCR, CMDCR_PTCLR); for (len = 0; len < slp->sl_scp.scp_cmdlen; len ++) - nsp_cr_write_1(bst, bsh, NSPR_CMDDR, + nsp_cr_write_1(sc->port_res, NSPR_CMDDR, slp->sl_scp.scp_cmd[len]); - nsp_cr_write_1(bst, bsh, NSPR_CMDCR, CMDCR_PTCLR | CMDCR_EXEC); + nsp_cr_write_1(sc->port_res, NSPR_CMDCR, CMDCR_PTCLR | CMDCR_EXEC); break; case IRQPHS_DATAOUT: @@ -1657,10 +1596,10 @@ nspintr(arg) return 1; SCSI_LOW_SETUP_PHASE(ti, PH_STAT); - regv = nsp_cr_read_1(bst, bsh, NSPR_DATA); - if (nsp_cr_read_1(bst, bsh, NSPR_PARITYR) & PARITYR_PE) + regv = nsp_cr_read_1(sc->port_res, NSPR_DATA); + if (nsp_cr_read_1(sc->port_res, NSPR_PARITYR) & PARITYR_PE) { - nsp_cr_write_1(bst, bsh, NSPR_PARITYR, + nsp_cr_write_1(sc->port_res, NSPR_PARITYR, PARITYR_ENABLE | PARITYR_CLEAR); derror = SCSI_LOW_DATA_PE; } @@ -1668,8 +1607,8 @@ nspintr(arg) derror = 0; /* assert ACK */ - cr = SCBUSCR_ACK | nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); + cr = SCBUSCR_ACK | nsp_cr_read_1(sc->port_res, NSPR_SCBUSCR); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr); if (scsi_low_statusin(slp, ti, derror | regv) != 0) { @@ -1680,8 +1619,8 @@ nspintr(arg) nsp_negate_signal(sc, SCBUSMON_REQ, "statin"); /* deassert ACK */ - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR) & (~SCBUSCR_ACK); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); + cr = nsp_cr_read_1(sc->port_res, NSPR_SCBUSCR) & (~SCBUSCR_ACK); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr); break; case IRQPHS_MSGOUT: @@ -1756,10 +1695,10 @@ nspintr(arg) SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); /* read a data */ - regv = nsp_cr_read_1(bst, bsh, NSPR_DATA); - if (nsp_cr_read_1(bst, bsh, NSPR_PARITYR) & PARITYR_PE) + regv = nsp_cr_read_1(sc->port_res, NSPR_DATA); + if (nsp_cr_read_1(sc->port_res, NSPR_PARITYR) & PARITYR_PE) { - nsp_cr_write_1(bst, bsh, + nsp_cr_write_1(sc->port_res, NSPR_PARITYR, PARITYR_ENABLE | PARITYR_CLEAR); derror = SCSI_LOW_DATA_PE; @@ -1770,8 +1709,8 @@ nspintr(arg) } /* assert ack */ - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR) | SCBUSCR_ACK; - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); + cr = nsp_cr_read_1(sc->port_res, NSPR_SCBUSCR) | SCBUSCR_ACK; + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr); if (scsi_low_msgin(slp, ti, regv | derror) == 0) { @@ -1785,8 +1724,8 @@ nspintr(arg) nsp_negate_signal(sc, SCBUSMON_REQ, "msgin"); /* deassert ack */ - cr = nsp_cr_read_1(bst, bsh, NSPR_SCBUSCR) & (~SCBUSCR_ACK); - nsp_cr_write_1(bst, bsh, NSPR_SCBUSCR, cr); + cr = nsp_cr_read_1(sc->port_res, NSPR_SCBUSCR) & (~SCBUSCR_ACK); + nsp_cr_write_1(sc->port_res, NSPR_SCBUSCR, cr); /* catch a next signal */ rv = nsp_expect_signal(sc, PHASE_MSGIN, SCBUSMON_REQ); @@ -1814,15 +1753,13 @@ nsp_timeout(sc) struct nsp_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; int tout; u_int8_t ph, regv; if (slp->sl_Tnexus == NULL) return 0; - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); switch (ph & SCBUSMON_PHMASK) { case PHASE_DATAOUT: @@ -1830,13 +1767,13 @@ nsp_timeout(sc) break; /* check a fifo empty */ - regv = bus_space_read_1(iot, ioh, nsp_fifosr); + regv = bus_read_1(sc->port_res, nsp_fifosr); if ((regv & FIFOSR_FULLEMP) == 0) break; - bus_space_write_1(iot, ioh, nsp_irqcr, IRQCR_FIFOCL); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_FIFOCL); /* check still requested */ - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if ((ph & SCBUSMON_REQ) == 0) break; /* check timeout */ @@ -1853,20 +1790,20 @@ nsp_timeout(sc) tout = NSP_DELAY_MAX; while (tout -- > 0) { - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if ((ph & SCBUSMON_PHMASK) != PHASE_DATAOUT) break; - regv = bus_space_read_1(iot, ioh, nsp_fifosr); + regv = bus_read_1(sc->port_res, nsp_fifosr); if ((regv & FIFOSR_FULLEMP) == 0) { DELAY(1); continue; } - bus_space_write_1(iot, ioh, nsp_irqcr, IRQCR_FIFOCL); + bus_write_1(sc->port_res, nsp_irqcr, IRQCR_FIFOCL); nsp_data_padding(sc, SCSI_LOW_WRITE, 32); } - ph = nsp_cr_read_1(iot, ioh, NSPR_SCBUSMON); + ph = nsp_cr_read_1(sc->port_res, NSPR_SCBUSMON); if ((ph & SCBUSMON_PHMASK) == PHASE_DATAOUT) sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; break; diff --git a/sys/dev/nsp/nsp_pccard.c b/sys/dev/nsp/nsp_pccard.c index 08ed66f5fd1..a235c22fde0 100644 --- a/sys/dev/nsp/nsp_pccard.c +++ b/sys/dev/nsp/nsp_pccard.c @@ -84,7 +84,12 @@ const struct pccard_product nsp_products[] = { static void nsp_pccard_intr(void * arg) { - nspintr(arg); + struct nsp_softc *sc; + + sc = arg; + SCSI_LOW_LOCK(&sc->sc_sclow); + nspintr(sc); + SCSI_LOW_UNLOCK(&sc->sc_sclow); } static void @@ -103,6 +108,7 @@ nsp_release_resource(device_t dev) if (sc->mem_res) bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); + mtx_destroy(&sc->sc_sclow.sl_lock); } static int @@ -116,6 +122,7 @@ nsp_alloc_resource(device_t dev) if (error || iosize < NSP_IOSIZE) return(ENOMEM); + mtx_init(&sc->sc_sclow.sl_lock, "nsp", NULL, MTX_DEF); sc->port_rid = 0; sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, 0, ~0, NSP_IOSIZE, RF_ACTIVE); @@ -167,7 +174,7 @@ nsp_pccard_probe(device_t dev) sizeof(nsp_products[0]), NULL)) != NULL) { if (pp->pp_name) device_set_desc(dev, pp->pp_name); - return(0); + return (BUS_PROBE_DEFAULT); } return(EIO); } @@ -185,8 +192,8 @@ nsp_pccard_attach(device_t dev) nsp_release_resource(dev); return(ENXIO); } - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, nsp_pccard_intr, (void *)sc, &sc->nsp_intrhand); + error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, nsp_pccard_intr, sc, &sc->nsp_intrhand); if (error) { nsp_release_resource(dev); return(error); @@ -231,12 +238,9 @@ static void nsp_card_unload(device_t devi) { struct nsp_softc *sc = device_get_softc(devi); - intrmask_t s; - s = splcam(); - scsi_low_deactivate((struct scsi_low_softc *)sc); - scsi_low_dettach(&sc->sc_sclow); - splx(s); + scsi_low_deactivate(&sc->sc_sclow); + scsi_low_detach(&sc->sc_sclow); } static int @@ -245,8 +249,7 @@ nspprobe(device_t devi) int rv; struct nsp_softc *sc = device_get_softc(devi); - rv = nspprobesubr(rman_get_bustag(sc->port_res), - rman_get_bushandle(sc->port_res), + rv = nspprobesubr(sc->port_res, device_get_flags(devi)); return rv; @@ -259,36 +262,22 @@ nspattach(device_t devi) struct scsi_low_softc *slp; u_int32_t flags = device_get_flags(devi); u_int iobase = bus_get_resource_start(devi, SYS_RES_IOPORT, 0); - intrmask_t s; - char dvname[16]; - - strcpy(dvname,"nsp"); if (iobase == 0) { - printf("%s: no ioaddr is given\n", dvname); - return (0); + device_printf(devi, "no ioaddr is given\n"); + return (ENXIO); } sc = device_get_softc(devi); - if (sc == NULL) - return (0); - slp = &sc->sc_sclow; slp->sl_dev = devi; - sc->sc_iot = rman_get_bustag(sc->port_res); - sc->sc_ioh = rman_get_bushandle(sc->port_res); if (sc->mem_res == NULL) { - printf("WARNING: CANNOT GET Memory RESOURCE going PIO mode"); + device_printf(devi, + "WARNING: CANNOT GET Memory RESOURCE going PIO mode\n"); flags |= PIO_MODE; } - if ((flags & PIO_MODE) == 0) { - sc->sc_memt = rman_get_bustag(sc->mem_res); - sc->sc_memh = rman_get_bushandle(sc->mem_res); - } else { - sc->sc_memh = 0; - } /* slp->sl_irq = devi->pd_irq; */ sc->sc_iclkdiv = CLKDIVR_20M; sc->sc_clkdiv = CLKDIVR_40M; @@ -296,9 +285,7 @@ nspattach(device_t devi) slp->sl_hostid = NSP_HOSTID; slp->sl_cfgflags = flags; - s = splcam(); nspattachsubr(sc); - splx(s); return(NSP_IOSIZE); } diff --git a/sys/dev/nsp/nspvar.h b/sys/dev/nsp/nspvar.h index ec4fd4424f1..ed8a981d158 100644 --- a/sys/dev/nsp/nspvar.h +++ b/sys/dev/nsp/nspvar.h @@ -43,11 +43,6 @@ struct nsp_softc { struct scsi_low_softc sc_sclow; /* generic data */ - bus_space_tag_t sc_iot; - bus_space_handle_t sc_ioh; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_memh; - int port_rid; int irq_rid; int mem_rid; @@ -89,7 +84,7 @@ struct nsp_targ_info { /***************************************************************** * Proto *****************************************************************/ -int nspprobesubr(bus_space_tag_t, bus_space_handle_t, u_int); +int nspprobesubr(struct resource *, u_int); void nspattachsubr(struct nsp_softc *); int nspintr(void *); diff --git a/sys/dev/null/null.c b/sys/dev/null/null.c index f836147a773..c8966df8ac4 100644 --- a/sys/dev/null/null.c +++ b/sys/dev/null/null.c @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -110,9 +109,7 @@ null_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t data __unused, switch (cmd) { case DIOCSKERNELDUMP: - error = priv_check(td, PRIV_SETDUMPER); - if (error == 0) - error = set_dumper(NULL, NULL); + error = set_dumper(NULL, NULL, td); break; case FIONBIO: break; diff --git a/sys/dev/ofw/ofw_iicbus.c b/sys/dev/ofw/ofw_iicbus.c index 1574f6e9674..f6d1be58612 100644 --- a/sys/dev/ofw/ofw_iicbus.c +++ b/sys/dev/ofw/ofw_iicbus.c @@ -101,12 +101,24 @@ ofw_iicbus_attach(device_t dev) { struct iicbus_softc *sc = IICBUS_SOFTC(dev); struct ofw_iicbus_devinfo *dinfo; - phandle_t child; - pcell_t paddr; + phandle_t child, node; + pcell_t freq, paddr; device_t childdev; sc->dev = dev; mtx_init(&sc->lock, "iicbus", NULL, MTX_DEF); + + /* + * If there is a clock-frequency property for the device node, use it as + * the starting value for the bus frequency. Then call the common + * routine that handles the tunable/sysctl which allows the FDT value to + * be overridden by the user. + */ + node = ofw_bus_get_node(dev); + freq = 0; + OF_getencprop(node, "clock-frequency", &freq, sizeof(freq)); + iicbus_init_frequency(dev, freq); + iicbus_reset(dev, IIC_FASTEST, 0, NULL); bus_generic_probe(dev); @@ -115,8 +127,7 @@ ofw_iicbus_attach(device_t dev) /* * Attach those children represented in the device tree. */ - for (child = OF_child(ofw_bus_get_node(dev)); child != 0; - child = OF_peer(child)) { + for (child = OF_child(node); child != 0; child = OF_peer(child)) { /* * Try to get the I2C address first from the i2c-address * property, then try the reg property. It moves around diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index b724d05e042..08ff42772ee 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -992,8 +992,6 @@ cbb_cardbus_reset_power(device_t brdev, device_t child, int on) * a cardbus bus, so that's the only register we check here. */ if (on && CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) { - /* - */ PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, &~CBBM_BRIDGECTRL_RESET, 2); b = pcib_get_bus(child); @@ -1586,13 +1584,17 @@ cbb_resume(device_t self) uint32_t tmp; /* - * Some BIOSes will not save the BARs for the pci chips, so we - * must do it ourselves. If the BAR is reset to 0 for an I/O - * device, it will read back as 0x1, so no explicit test for - * memory devices are needed. + * In the APM and early ACPI era, BIOSes saved the PCI config + * registers. As chips became more complicated, that functionality moved + * into the ACPI code / tables. We must therefore, restore the settings + * we made here to make sure the device come back. Transitions to Dx + * from D0 and back to D0 cause the bridge to lose its config space, so + * all the bus mappings and such are preserved. * - * Note: The PCI bus code should do this automatically for us on - * suspend/resume, but until it does, we have to cope. + * For most drivers, the PCI layer handles this saving. However, since + * there's much black magic and arcane art hidden in these few lines of + * code that would be difficult to transition into the PCI + * layer. chipinit was several years of trial and error to write. */ pci_write_config(self, CBBR_SOCKBASE, rman_get_start(sc->base_res), 4); DEVPRINTF((self, "PCI Memory allocated: %08lx\n", diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 485f7289c96..d2ac111372e 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -3651,7 +3651,7 @@ pci_set_power_child(device_t dev, device_t child, int state) dinfo = device_get_ivars(child); dstate = state; if (device_is_attached(child) && - PCIB_POWER_FOR_SLEEP(pcib, dev, &dstate) == 0) + PCIB_POWER_FOR_SLEEP(pcib, child, &dstate) == 0) pci_set_powerstate(child, dstate); } diff --git a/sys/dev/pst/pst-pci.c b/sys/dev/pst/pst-pci.c index 8ed8fed3b8e..4cc579636ec 100644 --- a/sys/dev/pst/pst-pci.c +++ b/sys/dev/pst/pst-pci.c @@ -73,15 +73,13 @@ iop_pci_attach(device_t dev) struct iop_softc *sc = device_get_softc(dev); int rid; - bzero(sc, sizeof(struct iop_softc)); - /* get resources */ - rid = 0x10; + rid = PCIR_BAR(0); sc->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); if (!sc->r_mem) - return 0; + return ENXIO; rid = 0x00; sc->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, @@ -104,11 +102,16 @@ static int iop_pci_detach(device_t dev) { struct iop_softc *sc = device_get_softc(dev); + int error; + error = bus_generic_detach(dev); + if (error) + return (error); bus_teardown_intr(dev, sc->r_irq, sc->handle); bus_release_resource(dev, SYS_RES_IRQ, 0x00, sc->r_irq); - bus_release_resource(dev, SYS_RES_MEMORY, 0x10, sc->r_mem); - return bus_generic_detach(dev); + bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->r_mem); + mtx_destroy(&sc->mtx); + return (0); } diff --git a/sys/dev/pst/pst-raid.c b/sys/dev/pst/pst-raid.c index e48b1c2f881..084d32ce015 100644 --- a/sys/dev/pst/pst-raid.c +++ b/sys/dev/pst/pst-raid.c @@ -63,7 +63,7 @@ struct pst_softc { struct pst_request { struct pst_softc *psc; /* pointer to softc */ u_int32_t mfa; /* frame addreess */ - struct callout_handle timeout_handle; /* handle for untimeout */ + struct callout timeout; /* timeout timer */ struct bio *bp; /* associated bio ptr */ }; @@ -75,7 +75,7 @@ static int pst_shutdown(device_t); static void pst_start(struct pst_softc *); static void pst_done(struct iop_softc *, u_int32_t, struct i2o_single_reply *); static int pst_rw(struct pst_request *); -static void pst_timeout(struct pst_request *); +static void pst_timeout(void *); static void bpack(int8_t *, int8_t *, int); /* local vars */ @@ -97,7 +97,7 @@ pst_add_raid(struct iop_softc *sc, struct i2o_lct_entry *lct) psc->iop = sc; psc->lct = lct; device_set_softc(child, psc); - return bus_generic_attach(sc->dev); + return device_probe_and_attach(child); } static int @@ -224,6 +224,7 @@ pst_start(struct pst_softc *psc) iop_free_mfa(psc->iop, mfa); return; } + callout_init_mtx(&request->timeout, &psc->iop->mtx, 0); psc->iop->outstanding++; request->psc = psc; request->mfa = mfa; @@ -245,7 +246,7 @@ pst_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply) (struct pst_request *)reply->transaction_context; struct pst_softc *psc = request->psc; - untimeout((timeout_t *)pst_timeout, request, request->timeout_handle); + callout_stop(&request->timeout); request->bp->bio_resid = request->bp->bio_bcount - reply->donecount; biofinish(request->bp, NULL, reply->status ? EIO : 0); free(request, M_PSTRAID); @@ -297,26 +298,25 @@ pst_rw(struct pst_request *request) request->psc->iop->reg->iqueue = request->mfa; - if (dumping) - request->timeout_handle.callout = NULL; - else - request->timeout_handle = - timeout((timeout_t*)pst_timeout, request, 10 * hz); + if (!dumping) + callout_reset(&request->timeout, 10 * hz, pst_timeout, request); return 0; } static void -pst_timeout(struct pst_request *request) +pst_timeout(void *arg) { + struct pst_request *request; + + request = arg; printf("pst: timeout mfa=0x%08x cmd=0x%02x\n", request->mfa, request->bp->bio_cmd); - mtx_lock(&request->psc->iop->mtx); + mtx_assert(&request->psc->iop->mtx, MA_OWNED); iop_free_mfa(request->psc->iop, request->mfa); if ((request->mfa = iop_get_mfa(request->psc->iop)) == 0xffffffff) { printf("pst: timeout no mfa possible\n"); biofinish(request->bp, NULL, EIO); request->psc->iop->outstanding--; - mtx_unlock(&request->psc->iop->mtx); return; } if (pst_rw(request)) { @@ -324,7 +324,6 @@ pst_timeout(struct pst_request *request) biofinish(request->bp, NULL, EIO); request->psc->iop->outstanding--; } - mtx_unlock(&request->psc->iop->mtx); } static void diff --git a/sys/dev/random/fortuna.c b/sys/dev/random/fortuna.c index f8b3e0c32aa..6f6febbe2b2 100644 --- a/sys/dev/random/fortuna.c +++ b/sys/dev/random/fortuna.c @@ -27,13 +27,11 @@ /* This implementation of Fortuna is based on the descriptions found in * ISBN 0-471-22357-3 "Practical Cryptography" by Ferguson and Schneier - * ("K&S"). + * ("F&S"). * - * The above book is superceded by ISBN 978-0-470-47424-2 "Cryptography - * Engineering" by Ferguson, Schneier and Kohno ("FS&K"). - * - * This code has not yet caught up with FS&K, but differences are not - * expected to be complex. + * The above book is superseded by ISBN 978-0-470-47424-2 "Cryptography + * Engineering" by Ferguson, Schneier and Kohno ("FS&K"). The code has + * not yet fully caught up with FS&K. */ #include @@ -252,12 +250,9 @@ reseed(uint8_t *junk, u_int length) mtx_assert(&random_reseed_mtx, MA_OWNED); #endif - /* F&S - K = Hd(K|s) where Hd(m) is H(H(m)) */ + /* FS&K - K = Hd(K|s) where Hd(m) is H(H(0^512|m)) */ randomdev_hash_init(&context); -#if 0 - /* FS&K defines Hd(m) as H(H(0^512|m)) */ - randomdev_hash_iterate(&context, zero_region, KEYSIZE); -#endif + randomdev_hash_iterate(&context, zero_region, 512/8); randomdev_hash_iterate(&context, &fortuna_state.key, sizeof(fortuna_state.key)); randomdev_hash_iterate(&context, junk, length); randomdev_hash_finish(&context, hash); @@ -270,7 +265,7 @@ reseed(uint8_t *junk, u_int length) /* Unblock the device if it was blocked due to being unseeded */ if (uint128_is_zero(fortuna_state.counter.whole)) random_adaptor_unblock(); - /* F&S - C = C + 1 */ + /* FS&K - C = C + 1 */ uint128_increment(&fortuna_state.counter.whole); } diff --git a/sys/dev/random/hash.c b/sys/dev/random/hash.c index 7deee878191..844e423422a 100644 --- a/sys/dev/random/hash.c +++ b/sys/dev/random/hash.c @@ -60,7 +60,7 @@ randomdev_hash_init(struct randomdev_hash *context) /* Iterate the hash */ void -randomdev_hash_iterate(struct randomdev_hash *context, void *data, size_t size) +randomdev_hash_iterate(struct randomdev_hash *context, const void *data, size_t size) { SHA256_Update(&context->sha, data, size); @@ -81,7 +81,7 @@ randomdev_hash_finish(struct randomdev_hash *context, void *buf) * data. Use CBC mode for better avalanche. */ void -randomdev_encrypt_init(struct randomdev_key *context, void *data) +randomdev_encrypt_init(struct randomdev_key *context, const void *data) { rijndael_cipherInit(&context->cipher, MODE_CBC, NULL); @@ -93,7 +93,7 @@ randomdev_encrypt_init(struct randomdev_key *context, void *data) * a multiple of BLOCKSIZE. */ void -randomdev_encrypt(struct randomdev_key *context, void *d_in, void *d_out, u_int length) +randomdev_encrypt(struct randomdev_key *context, const void *d_in, void *d_out, u_int length) { rijndael_blockEncrypt(&context->cipher, &context->key, d_in, length*8, d_out); diff --git a/sys/dev/random/hash.h b/sys/dev/random/hash.h index 57c0c6dfd81..d49de3aff01 100644 --- a/sys/dev/random/hash.h +++ b/sys/dev/random/hash.h @@ -42,9 +42,9 @@ struct randomdev_key { /* Big! Make static! */ }; void randomdev_hash_init(struct randomdev_hash *); -void randomdev_hash_iterate(struct randomdev_hash *, void *, size_t); +void randomdev_hash_iterate(struct randomdev_hash *, const void *, size_t); void randomdev_hash_finish(struct randomdev_hash *, void *); -void randomdev_encrypt_init(struct randomdev_key *, void *); -void randomdev_encrypt(struct randomdev_key *context, void *, void *, u_int); +void randomdev_encrypt_init(struct randomdev_key *, const void *); +void randomdev_encrypt(struct randomdev_key *context, const void *, void *, u_int); #endif diff --git a/sys/dev/random/ivy.c b/sys/dev/random/ivy.c index bbc4e78e740..71a61f4d8d4 100644 --- a/sys/dev/random/ivy.c +++ b/sys/dev/random/ivy.c @@ -70,7 +70,7 @@ ivy_rng_store(u_long *buf) retry = RETRY_COUNT; __asm __volatile( "1:\n\t" - "rdrand %1\n\t" /* read randomness into tmp */ + "rdrand %1\n\t" /* read randomness into rndval */ "jc 2f\n\t" /* CF is set on success, exit retry loop */ "dec %0\n\t" /* otherwise, retry-- */ "jne 1b\n\t" /* and loop if retries are not exhausted */ diff --git a/sys/dev/rp/rp.c b/sys/dev/rp/rp.c index 520ca80f930..5027694d54e 100644 --- a/sys/dev/rp/rp.c +++ b/sys/dev/rp/rp.c @@ -552,24 +552,12 @@ void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags) Begin FreeBsd-specific driver code **********************************************************************/ -struct callout_handle rp_callout_handle; - -static int rp_num_ports_open = 0; -static int rp_ndevs = 0; - -static int rp_num_ports[4]; /* Number of ports on each controller */ - -#define POLL_INTERVAL 1 +#define POLL_INTERVAL (hz / 100) #define RP_ISMULTIPORT(dev) ((dev)->id_flags & 0x1) #define RP_MPMASTER(dev) (((dev)->id_flags >> 8) & 0xff) #define RP_NOTAST4(dev) ((dev)->id_flags & 0x04) -static struct rp_port *p_rp_addr[4]; -static struct rp_port *p_rp_table[MAX_RP_PORTS]; -#define rp_addr(unit) (p_rp_addr[unit]) -#define rp_table(port) (p_rp_table[port]) - /* * The top-level routines begin here */ @@ -676,46 +664,31 @@ static void rp_handle_port(struct rp_port *rp) */ } -static void rp_do_poll(void *not_used) +static void rp_do_poll(void *arg) { CONTROLLER_t *ctl; struct rp_port *rp; struct tty *tp; - int unit, aiop, ch, line, count; + int count; unsigned char CtlMask, AiopMask; - for(unit = 0; unit < rp_ndevs; unit++) { - rp = rp_addr(unit); + rp = arg; + tp = rp->rp_tty; + tty_lock_assert(tp, MA_OWNED); ctl = rp->rp_ctlp; CtlMask = ctl->ctlmask(ctl); - for(aiop=0; CtlMask; CtlMask >>=1, aiop++) { - if(CtlMask & 1) { - AiopMask = sGetAiopIntStatus(ctl, aiop); - for(ch = 0; AiopMask; AiopMask >>=1, ch++) { - if(AiopMask & 1) { - line = (unit << 5) | (aiop << 3) | ch; - rp = rp_table(line); - rp_handle_port(rp); - } - } + if (CtlMask & (1 << rp->rp_aiop)) { + AiopMask = sGetAiopIntStatus(ctl, rp->rp_aiop); + if (AiopMask & (1 << rp->rp_chan)) { + rp_handle_port(rp); } } - for(line = 0, rp = rp_addr(unit); line < rp_num_ports[unit]; - line++, rp++) { - tp = rp->rp_tty; - tty_lock(tp); - count = sGetTxCnt(&rp->rp_channel); - if (count >= 0 && - (count <= rp->rp_restart)) { - rpstart(tp); - } - tty_unlock(tp); + count = sGetTxCnt(&rp->rp_channel); + if (count >= 0 && (count <= rp->rp_restart)) { + rpstart(tp); } - } - if(rp_num_ports_open) - rp_callout_handle = timeout(rp_do_poll, - (void *)NULL, POLL_INTERVAL); + callout_schedule(&rp->rp_timer, POLL_INTERVAL); } static struct ttydevsw rp_tty_class = { @@ -745,7 +718,7 @@ rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports) int unit; int num_chan; int aiop, chan, port; - int ChanStatus, line, count; + int ChanStatus; int retval; struct rp_port *rp; struct tty *tp; @@ -754,9 +727,8 @@ rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports) printf("RocketPort%d (Version %s) %d ports.\n", unit, RocketPortVersion, num_ports); - rp_num_ports[unit] = num_ports; - callout_handle_init(&rp_callout_handle); + ctlp->num_ports = num_ports; ctlp->rp = rp = (struct rp_port *) malloc(sizeof(struct rp_port) * num_ports, M_DEVBUF, M_NOWAIT | M_ZERO); if (rp == NULL) { @@ -765,16 +737,12 @@ rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports) goto nogo; } - count = unit * 32; /* board times max ports per card SG */ - - bzero(rp, sizeof(struct rp_port) * num_ports); - rp_addr(unit) = rp; - port = 0; for(aiop=0; aiop < num_aiops; aiop++) { num_chan = sGetAiopNumChan(ctlp, aiop); for(chan=0; chan < num_chan; chan++, port++, rp++) { rp->rp_tty = tp = tty_alloc(&rp_tty_class, rp); + callout_init_mtx(&rp->rp_timer, tty_getlock(tp), 0); rp->rp_port = port; rp->rp_ctlp = ctlp; rp->rp_unit = unit; @@ -794,13 +762,10 @@ rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports) } ChanStatus = sGetChanStatus(&rp->rp_channel); rp->rp_cts = (ChanStatus & CTS_ACT) != 0; - line = (unit << 5) | (aiop << 3) | chan; - rp_table(line) = rp; tty_makedev(tp, NULL, "R%r%r", unit, port); } } - rp_ndevs++; mtx_init(&ctlp->hwmtx, "rp_hwmtx", NULL, MTX_DEF); ctlp->hwmtx_init = 1; return (0); @@ -814,40 +779,26 @@ nogo: void rp_releaseresource(CONTROLLER_t *ctlp) { - int i, unit; struct rp_port *rp; + int i; - - unit = device_get_unit(ctlp->dev); - if (rp_addr(unit) != NULL) { - for (i = 0; i < rp_num_ports[unit]; i++) { - rp = rp_addr(unit) + i; + if (ctlp->rp != NULL) { + for (i = 0; i < ctlp->num_ports; i++) { + rp = ctlp->rp + i; atomic_add_32(&ctlp->free, 1); tty_lock(rp->rp_tty); tty_rel_gone(rp->rp_tty); } + free(ctlp->rp, M_DEVBUF); + ctlp->rp = NULL; } while (ctlp->free != 0) { pause("rpwt", hz / 10); } - if (ctlp->rp != NULL) { - for (i = 0 ; i < sizeof(p_rp_addr) / sizeof(*p_rp_addr) ; i++) - if (p_rp_addr[i] == ctlp->rp) - p_rp_addr[i] = NULL; - for (i = 0 ; i < sizeof(p_rp_table) / sizeof(*p_rp_table) ; i++) - if (p_rp_table[i] == ctlp->rp) - p_rp_table[i] = NULL; - free(ctlp->rp, M_DEVBUF); - ctlp->rp = NULL; - } -} - -void -rp_untimeout(void) -{ - untimeout(rp_do_poll, (void *)NULL, rp_callout_handle); + if (ctlp->hwmtx_init) + mtx_destroy(&ctlp->hwmtx); } static int @@ -893,15 +844,11 @@ rpopen(struct tty *tp) sSetRTS(&rp->rp_channel); */ - rp_num_ports_open++; - IntMask = sGetChanIntID(&rp->rp_channel); IntMask = IntMask & rp->rp_intmask; ChanStatus = sGetChanStatus(&rp->rp_channel); - if(rp_num_ports_open == 1) - rp_callout_handle = timeout(rp_do_poll, - (void *)NULL, POLL_INTERVAL); + callout_reset(&rp->rp_timer, POLL_INTERVAL, rp_do_poll, rp); device_busy(rp->rp_ctlp->dev); return(0); @@ -913,6 +860,7 @@ rpclose(struct tty *tp) struct rp_port *rp; rp = tty_softc(tp); + callout_stop(&rp->rp_timer); rphardclose(tp); device_unbusy(rp->rp_ctlp->dev); } diff --git a/sys/dev/rp/rp_pci.c b/sys/dev/rp/rp_pci.c index e7b98325bd0..3479ab7c020 100644 --- a/sys/dev/rp/rp_pci.c +++ b/sys/dev/rp/rp_pci.c @@ -237,7 +237,7 @@ rp_pcishutdown(device_t dev) static void rp_pcireleaseresource(CONTROLLER_t *ctlp) { - rp_untimeout(); + rp_releaseresource(ctlp); if (ctlp->io != NULL) { if (ctlp->io[0] != NULL) bus_release_resource(ctlp->dev, SYS_RES_IOPORT, ctlp->io_rid[0], ctlp->io[0]); @@ -248,7 +248,6 @@ rp_pcireleaseresource(CONTROLLER_t *ctlp) free(ctlp->io_rid, M_DEVBUF); ctlp->io = NULL; } - rp_releaseresource(ctlp); } static int diff --git a/sys/dev/rp/rpreg.h b/sys/dev/rp/rpreg.h index c8960eb5dc2..c5a8cac7b07 100644 --- a/sys/dev/rp/rpreg.h +++ b/sys/dev/rp/rpreg.h @@ -364,6 +364,7 @@ struct CONTROLLER_str struct mtx hwmtx; /* Spinlock protecting hardware. */ int hwmtx_init; int free; + int num_ports; /* Device and resource management */ device_t dev; /* device */ @@ -1008,18 +1009,17 @@ void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags); void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags); int rp_attachcommon(CONTROLLER_T *ctlp, int num_aiops, int num_ports); void rp_releaseresource(CONTROLLER_t *ctlp); -void rp_untimeout(void); static __inline void rp_lock(CONTROLLER_T *CtlP) { if (CtlP->hwmtx_init != 0) - mtx_lock_spin(&CtlP->hwmtx); + mtx_lock(&CtlP->hwmtx); } static __inline void rp_unlock(CONTROLLER_T *CtlP) { if (CtlP->hwmtx_init != 0) - mtx_unlock_spin(&CtlP->hwmtx); + mtx_unlock(&CtlP->hwmtx); } #ifndef ROCKET_C diff --git a/sys/dev/rp/rpvar.h b/sys/dev/rp/rpvar.h index f7f28aa6409..fd5faf3d85c 100644 --- a/sys/dev/rp/rpvar.h +++ b/sys/dev/rp/rpvar.h @@ -43,6 +43,7 @@ struct rp_port { struct tty * rp_tty; /* cross reference */ + struct callout rp_timer; unsigned char state; /* state of dtr */ diff --git a/sys/dev/scd/scd.c b/sys/dev/scd/scd.c index 0175db6205c..3959d646c9f 100644 --- a/sys/dev/scd/scd.c +++ b/sys/dev/scd/scd.c @@ -120,7 +120,7 @@ static int get_result(struct scd_softc *, int result_len, u_char *result); static void print_error(struct scd_softc *, int errcode); static void scd_start(struct scd_softc *); -static timeout_t scd_timeout; +static void scd_timeout(void *); static void scd_doread(struct scd_softc *, int state, struct scd_mbx *mbxin); static int scd_eject(struct scd_softc *); @@ -153,7 +153,7 @@ static struct cdevsw scd_cdevsw = { .d_ioctl = scdioctl, .d_strategy = scdstrategy, .d_name = "scd", - .d_flags = D_DISK | D_NEEDGIANT, + .d_flags = D_DISK, }; int @@ -163,11 +163,13 @@ scd_attach(struct scd_softc *sc) unit = device_get_unit(sc->dev); + SCD_LOCK(sc); init_drive(sc); sc->data.flags = SCDINIT; sc->data.audio_status = CD_AS_AUDIO_INVALID; bioq_init(&sc->data.head); + SCD_UNLOCK(sc); sc->scd_dev_t = make_dev(&scd_cdevsw, 8 * unit, UID_ROOT, GID_OPERATOR, 0640, "scd%d", unit); @@ -184,18 +186,18 @@ scdopen(struct cdev *dev, int flags, int fmt, struct thread *td) sc = (struct scd_softc *)dev->si_drv1; - /* not initialized*/ - if (!(sc->data.flags & SCDINIT)) - return (ENXIO); - - /* invalidated in the meantime? mark all open part's invalid */ - if (sc->data.openflag) + /* mark all open part's invalid */ + SCD_LOCK(sc); + if (sc->data.openflag) { + SCD_UNLOCK(sc); return (ENXIO); + } XDEBUG(sc, 1, "DEBUG: status = 0x%x\n", SCD_READ(sc, IREG_STATUS)); if ((rc = spin_up(sc)) != 0) { print_error(sc, rc); + SCD_UNLOCK(sc); return (EIO); } if (!(sc->data.flags & SCDTOC)) { @@ -205,18 +207,21 @@ scdopen(struct cdev *dev, int flags, int fmt, struct thread *td) if (rc == ERR_NOT_SPINNING) { rc = spin_up(sc); if (rc) { - print_error(sc, rc);\ + print_error(sc, rc); + SCD_UNLOCK(sc); return (EIO); } continue; } device_printf(sc->dev, "TOC read error 0x%x\n", rc); + SCD_UNLOCK(sc); return (EIO); } } sc->data.openflag = 1; sc->data.flags |= SCDVALID; + SCD_UNLOCK(sc); return (0); } @@ -228,17 +233,17 @@ scdclose(struct cdev *dev, int flags, int fmt, struct thread *td) sc = (struct scd_softc *)dev->si_drv1; - if (!(sc->data.flags & SCDINIT) || !sc->data.openflag) - return (ENXIO); + SCD_LOCK(sc); + KASSERT(sc->data.openflag, ("device not open")); if (sc->data.audio_status != CD_AS_PLAY_IN_PROGRESS) { (void)send_cmd(sc, CMD_SPIN_DOWN, 0); sc->data.flags &= ~SCDSPINNING; } - /* close channel */ sc->data.openflag = 0; + SCD_UNLOCK(sc); return (0); } @@ -246,12 +251,12 @@ scdclose(struct cdev *dev, int flags, int fmt, struct thread *td) static void scdstrategy(struct bio *bp) { - int s; struct scd_softc *sc; sc = (struct scd_softc *)bp->bio_dev->si_drv1; /* if device invalidated (e.g. media change, door open), error */ + SCD_LOCK(sc); if (!(sc->data.flags & SCDVALID)) { device_printf(sc->dev, "media changed\n"); bp->bio_error = EIO; @@ -276,17 +281,17 @@ scdstrategy(struct bio *bp) bp->bio_resid = 0; /* queue it */ - s = splbio(); bioq_disksort(&sc->data.head, bp); - splx(s); /* now check whether we can perform processing */ scd_start(sc); + SCD_UNLOCK(sc); return; bad: bp->bio_flags |= BIO_ERROR; done: + SCD_UNLOCK(sc); bp->bio_resid = bp->bio_bcount; biodone(bp); return; @@ -296,27 +301,22 @@ static void scd_start(struct scd_softc *sc) { struct bio *bp; - int s = splbio(); - if (sc->data.flags & SCDMBXBSY) { - splx(s); + SCD_ASSERT_LOCKED(sc); + if (sc->data.flags & SCDMBXBSY) return; - } bp = bioq_takefirst(&sc->data.head); if (bp != 0) { /* block found to process, dequeue */ sc->data.flags |= SCDMBXBSY; - splx(s); } else { /* nothing to do */ - splx(s); return; } sc->data.mbx.retry = 3; sc->data.mbx.bp = bp; - splx(s); scd_doread(sc, SCD_S_BEGIN, &(sc->data.mbx)); return; @@ -326,39 +326,47 @@ static int scdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td) { struct scd_softc *sc; + int error; sc = (struct scd_softc *)dev->si_drv1; XDEBUG(sc, 1, "ioctl: cmd=0x%lx\n", cmd); - if (!(sc->data.flags & SCDVALID)) + SCD_LOCK(sc); + if (!(sc->data.flags & SCDVALID)) { + SCD_UNLOCK(sc); return (EIO); + } + error = 0; switch (cmd) { case DIOCGMEDIASIZE: *(off_t *)addr = (off_t)sc->data.disksize * sc->data.blksize; - return (0); break; case DIOCGSECTORSIZE: *(u_int *)addr = sc->data.blksize; - return (0); break; case CDIOCPLAYTRACKS: - return scd_playtracks(sc, (struct ioc_play_track *) addr); + error = scd_playtracks(sc, (struct ioc_play_track *) addr); + break; case CDIOCPLAYBLOCKS: - return (EINVAL); + error = EINVAL; + break; case CDIOCPLAYMSF: - return scd_playmsf(sc, (struct ioc_play_msf *) addr); + error = scd_playmsf(sc, (struct ioc_play_msf *) addr); + break; case CDIOCREADSUBCHANNEL_SYSSPACE: return scd_subchan(sc, (struct ioc_read_subchannel *) addr, 1); case CDIOCREADSUBCHANNEL: return scd_subchan(sc, (struct ioc_read_subchannel *) addr, 0); case CDIOREADTOCHEADER: - return scd_toc_header (sc, (struct ioc_toc_header *) addr); + error = scd_toc_header (sc, (struct ioc_toc_header *) addr); + break; case CDIOREADTOCENTRYS: return scd_toc_entrys (sc, (struct ioc_read_toc_entry*) addr); case CDIOREADTOCENTRY: - return scd_toc_entry (sc, (struct ioc_read_toc_single_entry*) addr); + error = scd_toc_entry (sc, (struct ioc_read_toc_single_entry*) addr); + break; case CDIOCSETPATCH: case CDIOCGETVOL: case CDIOCSETVOL: @@ -367,34 +375,43 @@ scdioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *t case CDIOCSETMUTE: case CDIOCSETLEFT: case CDIOCSETRIGHT: - return (EINVAL); + error = EINVAL; + break; case CDIOCRESUME: - return scd_resume(sc); + error = scd_resume(sc); + break; case CDIOCPAUSE: - return scd_pause(sc); + error = scd_pause(sc); + break; case CDIOCSTART: - return (EINVAL); + error = EINVAL; + break; case CDIOCSTOP: - return scd_stop(sc); + error = scd_stop(sc); + break; case CDIOCEJECT: - return scd_eject(sc); + error = scd_eject(sc); + break; case CDIOCALLOW: - return (0); + break; case CDIOCSETDEBUG: #ifdef SCD_DEBUG scd_debuglevel++; #endif - return (0); + break; case CDIOCCLRDEBUG: #ifdef SCD_DEBUG scd_debuglevel = 0; #endif - return (0); + break; default: device_printf(sc->dev, "unsupported ioctl (cmd=0x%lx)\n", cmd); - return (ENOTTY); + error = ENOTTY; + break; } + SCD_UNLOCK(sc); + return (error); } /*************************************************************** @@ -573,6 +590,7 @@ scd_subchan(struct scd_softc *sc, struct ioc_read_subchannel *sch, int nocopyout data.what.position.absaddr.msf.minute = bcd2bin(q.abs_msf[0]); data.what.position.absaddr.msf.second = bcd2bin(q.abs_msf[1]); data.what.position.absaddr.msf.frame = bcd2bin(q.abs_msf[2]); + SCD_UNLOCK(sc); if (nocopyout == 0) { if (copyout(&data, sch->data, min(sizeof(struct cd_sub_channel_info), sch->data_len))!=0) @@ -680,6 +698,7 @@ scd_timeout(void *arg) struct scd_softc *sc; sc = (struct scd_softc *)arg; + SCD_ASSERT_LOCKED(sc); scd_doread(sc, sc->ch_state, sc->ch_mbxsave); } @@ -693,6 +712,7 @@ scd_doread(struct scd_softc *sc, int state, struct scd_mbx *mbxin) caddr_t addr; static char sdata[3]; /* Must be preserved between calls to this function */ + SCD_ASSERT_LOCKED(sc); loop: switch (state) { case SCD_S_BEGIN: @@ -707,7 +727,7 @@ loop: case SCD_S_WAITSTAT: sc->ch_state = SCD_S_WAITSTAT; - untimeout(scd_timeout, (caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- <= 0) { device_printf(sc->dev, "timeout. drive busy.\n"); goto harderr; @@ -716,7 +736,7 @@ loop: trystat: if (IS_BUSY(sc)) { sc->ch_state = SCD_S_WAITSTAT; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; } @@ -754,19 +774,19 @@ nextblock: mbx->count = 100; sc->ch_state = SCD_S_WAITFIFO; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; case SCD_S_WAITSPIN: sc->ch_state = SCD_S_WAITSPIN; - untimeout(scd_timeout,(caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- <= 0) { device_printf(sc->dev, "timeout waiting for drive to spin up.\n"); goto harderr; } if (!STATUS_BIT(sc, SBIT_RESULT_READY)) { sc->ch_state = SCD_S_WAITSPIN; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; } SCD_WRITE(sc, OREG_CONTROL, CBIT_RESULT_READY_CLEAR); @@ -787,14 +807,14 @@ nextblock: case SCD_S_WAITFIFO: sc->ch_state = SCD_S_WAITFIFO; - untimeout(scd_timeout,(caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- <= 0) { device_printf(sc->dev, "timeout. write param not ready.\n"); goto harderr; } if (!FSTATUS_BIT(sc, FBIT_WPARAM_READY)) { sc->ch_state = SCD_S_WAITFIFO; - sc->ch = timeout(scd_timeout, (caddr_t)sc,hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; } XDEBUG(sc, 1, "mbx->count (writeparamwait) = %d(%d)\n", mbx->count, 100); @@ -807,12 +827,11 @@ writeparam: SCD_WRITE(sc, OREG_COMMAND, CMD_SPIN_UP); mbx->count = 300; sc->ch_state = SCD_S_WAITSPIN; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; } /* send the read command */ - critical_enter(); SCD_WRITE(sc, OREG_WPARAMS, sdata[0]); SCD_WRITE(sc, OREG_WPARAMS, sdata[1]); SCD_WRITE(sc, OREG_WPARAMS, sdata[2]); @@ -820,7 +839,6 @@ writeparam: SCD_WRITE(sc, OREG_WPARAMS, 0); SCD_WRITE(sc, OREG_WPARAMS, 1); SCD_WRITE(sc, OREG_COMMAND, CMD_READ); - critical_exit(); mbx->count = RDELAY_WAITREAD; for (i = 0; i < 50; i++) { @@ -830,12 +848,12 @@ writeparam: } sc->ch_state = SCD_S_WAITREAD; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; case SCD_S_WAITREAD: sc->ch_state = SCD_S_WAITREAD; - untimeout(scd_timeout,(caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- <= 0) { if (STATUS_BIT(sc, SBIT_RESULT_READY)) goto got_param; @@ -847,7 +865,7 @@ writeparam: if (!(sc->data.flags & SCDVALID)) goto changed; sc->ch_state = SCD_S_WAITREAD; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; } XDEBUG(sc, 2, "mbx->count (after RDY_BIT) = %d(%d)\n", mbx->count, RDELAY_WAITREAD); @@ -868,7 +886,7 @@ got_data: case SCD_S_WAITPARAM: sc->ch_state = SCD_S_WAITPARAM; - untimeout(scd_timeout,(caddr_t)sc, sc->ch); + callout_stop(&sc->timer); if (mbx->count-- <= 0) { device_printf(sc->dev, "timeout waiting for params\n"); goto readerr; @@ -877,7 +895,7 @@ got_data: waitfor_param: if (!STATUS_BIT(sc, SBIT_RESULT_READY)) { sc->ch_state = SCD_S_WAITPARAM; - sc->ch = timeout(scd_timeout, (caddr_t)sc, hz/100); /* XXX */ + callout_reset(&sc->timer, hz / 100, scd_timeout, sc); /* XXX */ return; } #ifdef SCD_DEBUG @@ -1293,7 +1311,9 @@ waitfor_status_bits(struct scd_softc *sc, int bits_set, int bits_clear) { break; } + SCD_UNLOCK(sc); pause("waitfor", hz/10); + SCD_LOCK(sc); } } if ((c & bits_set) == bits_set && @@ -1363,6 +1383,7 @@ scd_toc_entrys (struct scd_softc *sc, struct ioc_read_toc_entry *te) toc_entry.addr.msf.second = bcd2bin(sc->data.toc[i].start_msf[1]); toc_entry.addr.msf.frame = bcd2bin(sc->data.toc[i].start_msf[2]); } + SCD_UNLOCK(sc); /* copy the data back */ if (copyout(&toc_entry, te->data, sizeof(struct cd_toc_entry)) != 0) diff --git a/sys/dev/scd/scd_isa.c b/sys/dev/scd/scd_isa.c index 082d0d8461a..78d5a01d033 100644 --- a/sys/dev/scd/scd_isa.c +++ b/sys/dev/scd/scd_isa.c @@ -125,6 +125,7 @@ scd_alloc_resources (device_t dev) sc = device_get_softc(dev); error = 0; + mtx_init(&sc->mtx, "scd", NULL, MTX_DEF); if (sc->port_type) { sc->port = bus_alloc_resource_any(dev, sc->port_type, @@ -134,13 +135,8 @@ scd_alloc_resources (device_t dev) error = ENOMEM; goto bad; } - sc->port_bst = rman_get_bustag(sc->port); - sc->port_bsh = rman_get_bushandle(sc->port); } - mtx_init(&sc->mtx, device_get_nameunit(dev), - "Interrupt lock", MTX_DEF | MTX_RECURSE); - bad: return (error); } @@ -152,14 +148,10 @@ scd_release_resources (device_t dev) sc = device_get_softc(dev); - if (sc->port) { + if (sc->port) bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port); - sc->port_bst = 0; - sc->port_bsh = 0; - } - if (mtx_initialized(&sc->mtx) != 0) - mtx_destroy(&sc->mtx); + mtx_destroy(&sc->mtx); return; } diff --git a/sys/dev/scd/scdvar.h b/sys/dev/scd/scdvar.h index 773a78be1fb..ca6ef9563a1 100644 --- a/sys/dev/scd/scdvar.h +++ b/sys/dev/scd/scdvar.h @@ -40,27 +40,26 @@ struct scd_softc { struct resource * port; int port_rid; int port_type; - bus_space_tag_t port_bst; - bus_space_handle_t port_bsh; struct mtx mtx; - struct callout_handle ch; + struct callout timer; int ch_state; struct scd_mbx * ch_mbxsave; struct scd_data data; }; -#define SCD_LOCK(_sc) splx(&(_sc)->mtx -#define SCD_UNLOCK(_sc) splx(&(_sc)->mtx +#define SCD_LOCK(_sc) mtx_lock(&_sc->mtx) +#define SCD_UNLOCK(_sc) mtx_unlock(&_sc->mtx) +#define SCD_ASSERT_LOCKED(_sc) mtx_assert(&_sc->mtx, MA_OWNED) #define SCD_READ(_sc, _reg) \ - bus_space_read_1(_sc->port_bst, _sc->port_bsh, _reg) + bus_read_1(_sc->port, _reg) #define SCD_READ_MULTI(_sc, _reg, _addr, _count) \ - bus_space_read_multi_1(_sc->port_bst, _sc->port_bsh, _reg, _addr, _count) + bus_read_multi_1(_sc->port, _reg, _addr, _count) #define SCD_WRITE(_sc, _reg, _val) \ - bus_space_write_1(_sc->port_bst, _sc->port_bsh, _reg, _val) + bus_write_1(_sc->port, _reg, _val) int scd_probe (struct scd_softc *); int scd_attach (struct scd_softc *); diff --git a/sys/dev/stg/tmc18c30.c b/sys/dev/stg/tmc18c30.c index 26e6a20d79b..4479fa29de5 100644 --- a/sys/dev/stg/tmc18c30.c +++ b/sys/dev/stg/tmc18c30.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -169,7 +170,7 @@ static __inline void stghw_bcr_write_1(struct stg_softc *sc, u_int8_t bcv) { - bus_space_write_1(sc->sc_iot, sc->sc_ioh, tmc_bctl, bcv); + bus_write_1(sc->port_res, tmc_bctl, bcv); sc->sc_busimg = bcv; } @@ -178,13 +179,11 @@ stghw_check(sc) struct stg_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; u_int fcbsize, fcb; u_int16_t lsb, msb; - lsb = bus_space_read_1(iot, ioh, tmc_idlsb); - msb = bus_space_read_1(iot, ioh, tmc_idmsb); + lsb = bus_read_1(sc->port_res, tmc_idlsb); + msb = bus_read_1(sc->port_res, tmc_idmsb); switch (msb << 8 | lsb) { case 0x6127: @@ -193,7 +192,7 @@ stghw_check(sc) return EINVAL; case 0x60e9: - if (bus_space_read_1(iot, ioh, tmc_cfg2) & 0x02) + if (bus_read_1(sc->port_res, tmc_cfg2) & 0x02) { sc->sc_chip = TMCCHIP_18C30; sc->sc_fsz = TMC18C30_FIFOSZ; @@ -234,17 +233,15 @@ static void stghw_init(sc) struct stg_softc *sc; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - bus_space_write_1(iot, ioh, tmc_ictl, 0); + bus_write_1(sc->port_res, tmc_ictl, 0); stghw_bcr_write_1(sc, BCTL_BUSFREE); - bus_space_write_1(iot, ioh, tmc_fctl, + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); - bus_space_write_1(iot, ioh, tmc_ssctl, 0); + bus_write_1(sc->port_res, tmc_ssctl, 0); } static int @@ -275,7 +272,7 @@ stghw_attention(sc) sc->sc_busc |= BCTL_ATN; sc->sc_busimg |= BCTL_ATN; - bus_space_write_1(sc->sc_iot, sc->sc_ioh, tmc_bctl, sc->sc_busimg); + bus_write_1(sc->port_res, tmc_bctl, sc->sc_busimg); DELAY(10); } @@ -283,11 +280,9 @@ static void stghw_bus_reset(sc) struct stg_softc *sc; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - bus_space_write_1(iot, ioh, tmc_ictl, 0); - bus_space_write_1(iot, ioh, tmc_fctl, 0); + bus_write_1(sc->port_res, tmc_ictl, 0); + bus_write_1(sc->port_res, tmc_fctl, 0); stghw_bcr_write_1(sc, BCTL_RST); DELAY(100000); stghw_bcr_write_1(sc, BCTL_BUSFREE); @@ -298,29 +293,23 @@ stghw_start_selection(sc, cb) struct stg_softc *sc; struct slccb *cb; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct targ_info *ti = cb->ti; register u_int8_t stat; - int s; sc->sc_tmaxcnt = cb->ccb_tcmax * 1000 * 1000; sc->sc_dataout_timeout = 0; sc->sc_ubf_timeout = 0; stghw_bcr_write_1(sc, BCTL_BUSFREE); - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); + bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); - s = splhigh(); - stat = bus_space_read_1(iot, ioh, tmc_astat); + stat = bus_read_1(sc->port_res, tmc_astat); if ((stat & ASTAT_INT) != 0) { - splx(s); return SCSI_LOW_START_FAIL; } - bus_space_write_1(iot, ioh, tmc_scsiid, sc->sc_idbit); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_ARBIT); - splx(s); + bus_write_1(sc->port_res, tmc_scsiid, sc->sc_idbit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_ARBIT); SCSI_LOW_SETUP_PHASE(ti, PH_ARBSTART); return SCSI_LOW_START_OK; @@ -355,8 +344,6 @@ stg_msg(sc, ti, msg) struct targ_info *ti; u_int msg; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct stg_targ_info *sti = (void *) ti; u_int period, offset; @@ -390,7 +377,7 @@ stg_msg(sc, ti, msg) sti->sti_reg_synch ++; sti->sti_reg_synch |= SSCTL_SYNCHEN | SSCTL_FSYNCHEN; } - bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch); + bus_write_1(sc->port_res, tmc_ssctl, sti->sti_reg_synch); return 0; } @@ -398,15 +385,12 @@ stg_msg(sc, ti, msg) * General probe attach **************************************************************/ int -stgprobesubr(iot, ioh, dvcfg) - bus_space_tag_t iot; - bus_space_handle_t ioh; - u_int dvcfg; +stgprobesubr(struct resource *res, u_int dvcfg) { u_int16_t lsb, msb; - lsb = bus_space_read_1(iot, ioh, tmc_idlsb); - msb = bus_space_read_1(iot, ioh, tmc_idmsb); + lsb = bus_read_1(res, tmc_idlsb); + msb = bus_read_1(res, tmc_idmsb); switch (msb << 8 | lsb) { default: @@ -448,8 +432,6 @@ stg_pdma_end(sc, ti) struct targ_info *ti; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct slccb *cb = slp->sl_Qnexus; u_int len, tres; @@ -465,7 +447,7 @@ stg_pdma_end(sc, ti) if (ti->ti_phase == PH_DATA) { - len = bus_space_read_2(iot, ioh, tmc_fdcnt); + len = bus_read_2(sc->port_res, tmc_fdcnt); if (slp->sl_scp.scp_direction == SCSI_LOW_WRITE) { if (len != 0) @@ -504,7 +486,7 @@ stg_pdma_end(sc, ti) } out: - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); } static void @@ -514,16 +496,14 @@ stg_pio_read(sc, ti, thold) u_int thold; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct sc_p *sp = &slp->sl_scp; - int s, tout; + int tout; u_int res; u_int8_t stat; if ((slp->sl_flags & HW_PDMASTART) == 0) { - bus_space_write_1(iot, ioh, tmc_fctl, + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_FIFOEN); slp->sl_flags |= HW_PDMASTART; } @@ -533,21 +513,18 @@ stg_pio_read(sc, ti, thold) { if (thold > 0) { - s = splhigh(); - res = bus_space_read_2(iot, ioh, tmc_fdcnt); + res = bus_read_2(sc->port_res, tmc_fdcnt); if (res < thold) { - bus_space_write_1(iot, ioh, tmc_ictl, + bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); - splx(s); break; } - splx(s); } else { - stat = bus_space_read_1(iot, ioh, tmc_bstat); - res = bus_space_read_2(iot, ioh, tmc_fdcnt); + stat = bus_read_1(sc->port_res, tmc_bstat); + res = bus_read_2(sc->port_res, tmc_fdcnt); if (res == 0) { if ((stat & PHASE_MASK) != DATA_IN_PHASE) @@ -578,7 +555,7 @@ stg_pio_read(sc, ti, thold) res = STG_MAX_DATA_SIZE; while (res -- > 0) { - (void) bus_space_read_1(iot, ioh, tmc_rfifo); + (void) bus_read_1(sc->port_res, tmc_rfifo); } continue; } @@ -586,12 +563,12 @@ stg_pio_read(sc, ti, thold) sp->scp_datalen -= res; if (res & 1) { - *sp->scp_data = bus_space_read_1(iot, ioh, tmc_rfifo); + *sp->scp_data = bus_read_1(sc->port_res, tmc_rfifo); sp->scp_data ++; res --; } - bus_space_read_multi_2(iot, ioh, tmc_rfifo, + bus_read_multi_2(sc->port_res, tmc_rfifo, (u_int16_t *) sp->scp_data, res >> 1); sp->scp_data += res; } @@ -607,25 +584,23 @@ stg_pio_write(sc, ti, thold) u_int thold; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct sc_p *sp = &slp->sl_scp; u_int res; - int s, tout; + int tout; register u_int8_t stat; if ((slp->sl_flags & HW_PDMASTART) == 0) { stat = sc->sc_fcWinit | FCTL_FIFOEN | FCTL_FIFOW; - bus_space_write_1(iot, ioh, tmc_fctl, stat | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, stat); + bus_write_1(sc->port_res, tmc_fctl, stat | FCTL_CLRFIFO); + bus_write_1(sc->port_res, tmc_fctl, stat); slp->sl_flags |= HW_PDMASTART; } tout = sc->sc_tmaxcnt; while (tout -- > 0) { - stat = bus_space_read_1(iot, ioh, tmc_bstat); + stat = bus_read_1(sc->port_res, tmc_bstat); if ((stat & PHASE_MASK) != DATA_OUT_PHASE) break; @@ -638,20 +613,17 @@ stg_pio_write(sc, ti, thold) if (thold > 0) { - s = splhigh(); - res = bus_space_read_2(iot, ioh, tmc_fdcnt); + res = bus_read_2(sc->port_res, tmc_fdcnt); if (res > thold) { - bus_space_write_1(iot, ioh, tmc_ictl, + bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); - splx(s); break; } - splx(s); } else { - res = bus_space_read_2(iot, ioh, tmc_fdcnt); + res = bus_read_2(sc->port_res, tmc_fdcnt); if (res > sc->sc_maxwsize / 2) { DELAY(1); @@ -668,12 +640,12 @@ stg_pio_write(sc, ti, thold) sp->scp_datalen -= res; if ((res & 0x1) != 0) { - bus_space_write_1(iot, ioh, tmc_wfifo, *sp->scp_data); + bus_write_1(sc->port_res, tmc_wfifo, *sp->scp_data); sp->scp_data ++; res --; } - bus_space_write_multi_2(iot, ioh, tmc_wfifo, + bus_write_multi_2(sc->port_res, tmc_wfifo, (u_int16_t *) sp->scp_data, res >> 1); sp->scp_data += res; } @@ -686,14 +658,12 @@ static int stg_negate_signal(struct stg_softc *sc, u_int8_t mask, u_char *s) { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int wc; u_int8_t regv; for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++) { - regv = bus_space_read_1(bst, bsh, tmc_bstat); + regv = bus_read_1(sc->port_res, tmc_bstat); if (regv == (u_int8_t) -1) return -1; if ((regv & mask) == 0) @@ -710,15 +680,13 @@ static int stg_expect_signal(struct stg_softc *sc, u_int8_t phase, u_int8_t mask) { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t bst = sc->sc_iot; - bus_space_handle_t bsh = sc->sc_ioh; int wc; u_int8_t ph; phase &= PHASE_MASK; for (wc = 0; wc < STG_DELAY_MAX / STG_DELAY_INTERVAL; wc ++) { - ph = bus_space_read_1(bst, bsh, tmc_bstat); + ph = bus_read_1(sc->port_res, tmc_bstat); if (ph == (u_int8_t) -1) return -1; if ((ph & PHASE_MASK) != phase) @@ -741,14 +709,12 @@ stg_xfer(sc, buf, len, phase, clear_atn) int phase; int clear_atn; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; int rv, ptr; if (phase & BSTAT_IO) - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); else - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcWinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcWinit); for (ptr = 0; len > 0; len --) { @@ -765,18 +731,18 @@ stg_xfer(sc, buf, len, phase, clear_atn) if (phase & BSTAT_IO) { - buf[ptr ++] = bus_space_read_1(iot, ioh, tmc_rdata); + buf[ptr ++] = bus_read_1(sc->port_res, tmc_rdata); } else { - bus_space_write_1(iot, ioh, tmc_wdata, buf[ptr ++]); + bus_write_1(sc->port_res, tmc_wdata, buf[ptr ++]); } stg_negate_signal(sc, BSTAT_ACK, "xfer"); } bad: - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); return len; } @@ -788,8 +754,6 @@ stg_reselected(sc) struct stg_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; int tout; u_int sid; u_int8_t regv; @@ -799,7 +763,7 @@ stg_reselected(sc) /* XXX: * Selection vs Reselection conflicts. */ - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); stghw_bcr_write_1(sc, BCTL_BUSFREE); } else if (slp->sl_Tnexus != NULL) @@ -816,12 +780,12 @@ stg_reselected(sc) tout = STG_DELAY_SELECT_POLLING_MAX; while (tout -- > 0) { - regv = bus_space_read_1(iot, ioh, tmc_bstat); + regv = bus_read_1(sc->port_res, tmc_bstat); if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == (BSTAT_IO | BSTAT_SEL)) { DELAY(1); - regv = bus_space_read_1(iot, ioh, tmc_bstat); + regv = bus_read_1(sc->port_res, tmc_bstat); if ((regv & (BSTAT_IO | BSTAT_SEL | BSTAT_BSY)) == (BSTAT_IO | BSTAT_SEL)) goto reselect_start; @@ -832,21 +796,21 @@ stg_reselected(sc) return EJUSTRETURN; reselect_start: - sid = (u_int) bus_space_read_1(iot, ioh, tmc_scsiid); + sid = (u_int) bus_read_1(sc->port_res, tmc_scsiid); if ((sid & sc->sc_idbit) == 0) { /* not us */ return EJUSTRETURN; } - bus_space_write_1(iot, ioh, tmc_fctl, + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO | FCTL_CLRINT); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); stghw_bcr_write_1(sc, sc->sc_busc | BCTL_BSY); while (tout -- > 0) { - regv = bus_space_read_1(iot, ioh, tmc_bstat); + regv = bus_read_1(sc->port_res, tmc_bstat); if ((regv & (BSTAT_SEL | BSTAT_BSY)) == BSTAT_BSY) goto reselected; DELAY(1); @@ -872,12 +836,10 @@ stg_disconnected(sc, ti) struct targ_info *ti; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; /* clear bus status & fifo */ - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); stghw_bcr_write_1(sc, BCTL_BUSFREE); sc->sc_icinit &= ~ICTL_FIFO; sc->sc_busc &= ~BCTL_ATN; @@ -899,12 +861,10 @@ stg_target_nexus_establish(sc) struct stg_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct targ_info *ti = slp->sl_Tnexus; struct stg_targ_info *sti = (void *) ti; - bus_space_write_1(iot, ioh, tmc_ssctl, sti->sti_reg_synch); + bus_write_1(sc->port_res, tmc_ssctl, sti->sti_reg_synch); if ((stg_io_control & STG_FIFO_INTERRUPTS) != 0) { sc->sc_icinit |= ICTL_FIFO; @@ -938,19 +898,17 @@ stghw_select_targ_wait(sc, mu) struct stg_softc *sc; int mu; { - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; mu = mu / STGHW_SELECT_INTERVAL; while (mu -- > 0) { - if ((bus_space_read_1(iot, ioh, tmc_bstat) & BSTAT_BSY) == 0) + if ((bus_read_1(sc->port_res, tmc_bstat) & BSTAT_BSY) == 0) { DELAY(STGHW_SELECT_INTERVAL); continue; } DELAY(1); - if ((bus_space_read_1(iot, ioh, tmc_bstat) & BSTAT_BSY) != 0) + if ((bus_read_1(sc->port_res, tmc_bstat) & BSTAT_BSY) != 0) { return 0; } @@ -963,11 +921,9 @@ stg_selection_done_and_expect_msgout(sc) struct stg_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc); SCSI_LOW_ASSERT_ATN(slp); } @@ -978,12 +934,10 @@ stgintr(arg) { struct stg_softc *sc = arg; struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; struct targ_info *ti; struct buf *bp; u_int derror, flags; - int len, s; + int len; u_int8_t status, astatus, regv; /******************************************* @@ -992,19 +946,19 @@ stgintr(arg) if (slp->sl_flags & HW_INACTIVE) return 0; - astatus = bus_space_read_1(iot, ioh, tmc_astat); - status = bus_space_read_1(iot, ioh, tmc_bstat); + astatus = bus_read_1(sc->port_res, tmc_astat); + status = bus_read_1(sc->port_res, tmc_bstat); if ((astatus & ASTAT_STATMASK) == 0 || astatus == (u_int8_t) -1) return 0; - bus_space_write_1(iot, ioh, tmc_ictl, 0); + bus_write_1(sc->port_res, tmc_ictl, 0); if (astatus & ASTAT_SCSIRST) { - bus_space_write_1(iot, ioh, tmc_fctl, + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit | FCTL_CLRFIFO); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); - bus_space_write_1(iot, ioh, tmc_ictl, 0); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_ictl, 0); scsi_low_restart(slp, SCSI_LOW_RESTART_SOFT, "bus reset (power off?)"); @@ -1065,7 +1019,7 @@ stgintr(arg) goto arb_fail; } - status = bus_space_read_1(iot, ioh, tmc_bstat); + status = bus_read_1(sc->port_res, tmc_bstat); if ((status & BSTAT_IO) != 0) { /* XXX: @@ -1075,7 +1029,7 @@ stgintr(arg) stg_statics.arbit_fail_1 ++; #endif /* STG_STATICS */ arb_fail: - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); stghw_bcr_write_1(sc, BCTL_BUSFREE); scsi_low_arbit_fail(slp, slp->sl_Qnexus); goto out; @@ -1087,11 +1041,10 @@ arb_fail: SCSI_LOW_SETUP_PHASE(ti, PH_SELSTART); scsi_low_arbit_win(slp); - s = splhigh(); - bus_space_write_1(iot, ioh, tmc_scsiid, + bus_write_1(sc->port_res, tmc_scsiid, sc->sc_idbit | (1 << ti->ti_id)); stghw_bcr_write_1(sc, sc->sc_imsg | sc->sc_busc | BCTL_SEL); - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcWinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcWinit); if ((stg_io_control & STG_WAIT_FOR_SELECT) != 0) { /* selection abort delay 200 + 100 micro sec */ @@ -1101,7 +1054,6 @@ arb_fail: stg_selection_done_and_expect_msgout(sc); } } - splx(s); goto out; case PH_SELSTART: @@ -1130,7 +1082,7 @@ arb_fail: goto out; /* clear a busy line */ - bus_space_write_1(iot, ioh, tmc_fctl, sc->sc_fcRinit); + bus_write_1(sc->port_res, tmc_fctl, sc->sc_fcRinit); stghw_bcr_write_1(sc, sc->sc_busc); stg_target_nexus_establish(sc); if ((status & PHASE_MASK) != MESSAGE_IN_PHASE) @@ -1209,12 +1161,12 @@ arb_fail: break; SCSI_LOW_SETUP_PHASE(ti, PH_STAT); - regv = bus_space_read_1(iot, ioh, tmc_sdna); + regv = bus_read_1(sc->port_res, tmc_sdna); if (scsi_low_statusin(slp, ti, regv | derror) != 0) { scsi_low_attention(slp); } - if (regv != bus_space_read_1(iot, ioh, tmc_rdata)) + if (regv != bus_read_1(sc->port_res, tmc_rdata)) { device_printf(slp->sl_dev, "STATIN: data mismatch\n"); } @@ -1257,7 +1209,7 @@ arb_fail: SCSI_LOW_SETUP_PHASE(ti, PH_MSGIN); /* read data with NOACK */ - regv = bus_space_read_1(iot, ioh, tmc_sdna); + regv = bus_read_1(sc->port_res, tmc_sdna); if (scsi_low_msgin(slp, ti, derror | regv) == 0) { @@ -1268,7 +1220,7 @@ arb_fail: } /* read data with ACK */ - if (regv != bus_space_read_1(iot, ioh, tmc_rdata)) + if (regv != bus_read_1(sc->port_res, tmc_rdata)) { device_printf(slp->sl_dev, "MSGIN: data mismatch\n"); } @@ -1295,7 +1247,7 @@ arb_fail: } out: - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); + bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); return 1; } @@ -1304,15 +1256,13 @@ stg_timeout(sc) struct stg_softc *sc; { struct scsi_low_softc *slp = &sc->sc_sclow; - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; int tout, count; u_int8_t status; if (slp->sl_Tnexus == NULL) return 0; - status = bus_space_read_1(iot, ioh, tmc_bstat); + status = bus_read_1(sc->port_res, tmc_bstat); if ((status & PHASE_MASK) == 0) { if (sc->sc_ubf_timeout ++ == 0) @@ -1332,7 +1282,7 @@ stg_timeout(sc) break; if ((status & BSTAT_REQ) == 0) break; - if (bus_space_read_2(iot, ioh, tmc_fdcnt) != 0) + if (bus_read_2(sc->port_res, tmc_fdcnt) != 0) break; if ((-- sc->sc_dataout_timeout) > 0) break; @@ -1344,30 +1294,30 @@ stg_timeout(sc) break; } - bus_space_write_1(iot, ioh, tmc_ictl, 0); + bus_write_1(sc->port_res, tmc_ictl, 0); tout = STG_DELAY_MAX; while (tout --) { - status = bus_space_read_1(iot, ioh, tmc_bstat); + status = bus_read_1(sc->port_res, tmc_bstat); if ((status & PHASE_MASK) != DATA_OUT_PHASE) break; - if (bus_space_read_2(iot, ioh, tmc_fdcnt) != 0) + if (bus_read_2(sc->port_res, tmc_fdcnt) != 0) { DELAY(1); continue; } for (count = sc->sc_maxwsize; count > 0; count --) - bus_space_write_1(iot, ioh, tmc_wfifo, 0); + bus_write_1(sc->port_res, tmc_wfifo, 0); } - status = bus_space_read_1(iot, ioh, tmc_bstat); + status = bus_read_1(sc->port_res, tmc_bstat); if ((status & PHASE_MASK) == DATA_OUT_PHASE) sc->sc_dataout_timeout = SCSI_LOW_TIMEOUT_HZ; - bus_space_write_1(iot, ioh, tmc_ictl, sc->sc_icinit); + bus_write_1(sc->port_res, tmc_ictl, sc->sc_icinit); break; default: diff --git a/sys/dev/stg/tmc18c30_isa.c b/sys/dev/stg/tmc18c30_isa.c index af61cfe54d5..e44a8b0e4df 100644 --- a/sys/dev/stg/tmc18c30_isa.c +++ b/sys/dev/stg/tmc18c30_isa.c @@ -79,7 +79,7 @@ stg_isa_probe(device_t dev) stg_release_resource(dev); - return(0); + return (BUS_PROBE_DEFAULT); } static int @@ -95,8 +95,8 @@ stg_isa_attach(device_t dev) return(error); } - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, stg_intr, (void *)sc, &sc->stg_intrhand); + error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, stg_intr, sc, &sc->stg_intrhand); if (error) { stg_release_resource(dev); return(error); diff --git a/sys/dev/stg/tmc18c30_pccard.c b/sys/dev/stg/tmc18c30_pccard.c index bca458fb377..a10c001b07e 100644 --- a/sys/dev/stg/tmc18c30_pccard.c +++ b/sys/dev/stg/tmc18c30_pccard.c @@ -83,7 +83,7 @@ stg_pccard_probe(device_t dev) sizeof(stg_products[0]), NULL)) != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); - return(0); + return (BUS_PROBE_DEFAULT); } return(EIO); } @@ -105,8 +105,8 @@ stg_pccard_attach(device_t dev) stg_release_resource(dev); return(ENXIO); } - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, stg_intr, (void *)sc, &sc->stg_intrhand); + error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, stg_intr, sc, &sc->stg_intrhand); if (error) { stg_release_resource(dev); return(error); diff --git a/sys/dev/stg/tmc18c30_pci.c b/sys/dev/stg/tmc18c30_pci.c index 4c8fb4c5910..0ff2e62212a 100644 --- a/sys/dev/stg/tmc18c30_pci.c +++ b/sys/dev/stg/tmc18c30_pci.c @@ -99,8 +99,8 @@ stg_pci_attach(device_t dev) } /* XXXX remove INTR_ENTROPY below for MFC */ - error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, stg_intr, (void *)sc, &sc->stg_intrhand); + error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, stg_intr, sc, &sc->stg_intrhand); if (error) { stg_release_resource(dev); return(error); diff --git a/sys/dev/stg/tmc18c30_subr.c b/sys/dev/stg/tmc18c30_subr.c index 5c88ecdaa59..8c686d67356 100644 --- a/sys/dev/stg/tmc18c30_subr.c +++ b/sys/dev/stg/tmc18c30_subr.c @@ -68,6 +68,7 @@ stg_alloc_resource(device_t dev) u_long maddr, msize; int error; + mtx_init(&sc->sc_sclow.sl_lock, "stg", NULL, MTX_DEF); sc->port_res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &sc->port_rid, RF_ACTIVE); if (sc->port_res == NULL) { @@ -117,7 +118,7 @@ stg_release_resource(device_t dev) if (sc->mem_res) bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); - return; + mtx_destroy(&sc->sc_sclow.sl_lock); } int @@ -126,8 +127,7 @@ stg_probe(device_t dev) int rv; struct stg_softc *sc = device_get_softc(dev); - rv = stgprobesubr(rman_get_bustag(sc->port_res), - rman_get_bushandle(sc->port_res), + rv = stgprobesubr(sc->port_res, device_get_flags(dev)); return rv; @@ -139,45 +139,38 @@ stg_attach(device_t dev) struct stg_softc *sc; struct scsi_low_softc *slp; u_int32_t flags = device_get_flags(dev); - intrmask_t s; - char dvname[16]; sc = device_get_softc(dev); - strcpy(dvname,"stg"); - slp = &sc->sc_sclow; slp->sl_dev = dev; - sc->sc_iot = rman_get_bustag(sc->port_res); - sc->sc_ioh = rman_get_bushandle(sc->port_res); slp->sl_hostid = STG_HOSTID; slp->sl_cfgflags = flags; - s = splcam(); stgattachsubr(sc); - splx(s); return(STGIOSZ); } int -stg_detach (device_t dev) +stg_detach(device_t dev) { struct stg_softc *sc = device_get_softc(dev); - intrmask_t s; - s = splcam(); - scsi_low_deactivate((struct scsi_low_softc *)sc); - scsi_low_dettach(&sc->sc_sclow); - splx(s); + scsi_low_deactivate(&sc->sc_sclow); + scsi_low_detach(&sc->sc_sclow); stg_release_resource(dev); return (0); } void -stg_intr (void *arg) +stg_intr(void *arg) { - stgintr(arg); - return; + struct stg_softc *sc; + + sc = arg; + SCSI_LOW_LOCK(&sc->sc_sclow); + stgintr(sc); + SCSI_LOW_UNLOCK(&sc->sc_sclow); } diff --git a/sys/dev/stg/tmc18c30var.h b/sys/dev/stg/tmc18c30var.h index 9ad698faf89..06a454b8e77 100644 --- a/sys/dev/stg/tmc18c30var.h +++ b/sys/dev/stg/tmc18c30var.h @@ -44,10 +44,6 @@ struct stg_softc { struct scsi_low_softc sc_sclow; /* generic data */ - bus_space_tag_t sc_iot; - bus_space_tag_t sc_memt; - bus_space_handle_t sc_ioh; - int port_rid; int irq_rid; int mem_rid; @@ -88,7 +84,7 @@ struct stg_targ_info { /***************************************************************** * Proto *****************************************************************/ -int stgprobesubr(bus_space_tag_t, bus_space_handle_t, u_int); +int stgprobesubr(struct resource *, u_int); void stgattachsubr(struct stg_softc *); int stgintr(void *); diff --git a/sys/dev/streams/streams.c b/sys/dev/streams/streams.c index 42265a4ebbe..6a9219eb303 100644 --- a/sys/dev/streams/streams.c +++ b/sys/dev/streams/streams.c @@ -302,7 +302,8 @@ svr4_ptm_alloc(td) ptyname[8] = ttyletters[l]; ptyname[9] = ttynumbers[n]; - error = kern_open(td, ptyname, UIO_SYSSPACE, O_RDWR, 0); + error = kern_openat(td, AT_FDCWD, ptyname, UIO_SYSSPACE, + O_RDWR, 0); switch (error) { case ENOENT: case ENXIO: diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c index 65ecf760f49..6cda04360f0 100644 --- a/sys/dev/uart/uart_bus_fdt.c +++ b/sys/dev/uart/uart_bus_fdt.c @@ -157,3 +157,4 @@ uart_fdt_probe(device_t dev) } DRIVER_MODULE(uart, simplebus, uart_fdt_driver, uart_devclass, 0, 0); +DRIVER_MODULE(uart, ofwbus, uart_fdt_driver, uart_devclass, 0, 0); diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c index 3253cd14a2e..2e5ac8cab17 100644 --- a/sys/dev/uart/uart_dev_pl011.c +++ b/sys/dev/uart/uart_dev_pl011.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #define DR_OE (1 << 11) /* Overrun error */ #define UART_FR 0x06 /* Flag register */ +#define FR_TXFF (1 << 5) /* Transmit FIFO/reg full */ #define FR_RXFF (1 << 6) /* Receive FIFO/reg full */ #define FR_TXFE (1 << 7) /* Transmit FIFO/reg empty */ @@ -194,7 +195,8 @@ static void uart_pl011_putc(struct uart_bas *bas, int c) { - while (!(__uart_getreg(bas, UART_FR) & FR_TXFE)) + /* Wait when TX FIFO full. Push character otherwise. */ + while (__uart_getreg(bas, UART_FR) & FR_TXFF) ; __uart_setreg(bas, UART_DR, c & 0xff); } diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 8e5f6a4f28c..5ec9cdc63ae 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -4370,6 +4370,7 @@ product TREK THUMBDRIVE_8MB 0x9988 ThumbDrive_8MB /* TRENDnet products */ product TRENDNET RTL8192CU 0x624d RTL8192CU +product TRENDNET TEW646UBH 0x646b TEW-646UBH product TRENDNET RTL8188CU 0x648b RTL8188CU /* Tripp-Lite products */ diff --git a/sys/dev/usb/wlan/if_rsu.c b/sys/dev/usb/wlan/if_rsu.c index 4808c0f9f29..a199c290f42 100644 --- a/sys/dev/usb/wlan/if_rsu.c +++ b/sys/dev/usb/wlan/if_rsu.c @@ -121,6 +121,7 @@ static const STRUCT_USB_HOST_ID rsu_devs[] = { RSU_DEV_HT(SITECOMEU, WL349V1), RSU_DEV_HT(SITECOMEU, WL353), RSU_DEV_HT(SWEEX2, LW154), + RSU_DEV_HT(TRENDNET, TEW646UBH), #undef RSU_DEV_HT #undef RSU_DEV }; diff --git a/sys/dev/virtio/block/virtio_blk.c b/sys/dev/virtio/block/virtio_blk.c index a089e3fe78b..b15cb75a3f4 100644 --- a/sys/dev/virtio/block/virtio_blk.c +++ b/sys/dev/virtio/block/virtio_blk.c @@ -243,6 +243,8 @@ static driver_t vtblk_driver = { }; static devclass_t vtblk_devclass; +DRIVER_MODULE(virtio_blk, virtio_mmio, vtblk_driver, vtblk_devclass, + vtblk_modevent, 0); DRIVER_MODULE(virtio_blk, virtio_pci, vtblk_driver, vtblk_devclass, vtblk_modevent, 0); MODULE_VERSION(virtio_blk, 1); diff --git a/sys/dev/virtio/mmio/virtio_mmio.c b/sys/dev/virtio/mmio/virtio_mmio.c new file mode 100644 index 00000000000..d1838ef8d4a --- /dev/null +++ b/sys/dev/virtio/mmio/virtio_mmio.c @@ -0,0 +1,800 @@ +/*- + * Copyright (c) 2014 Ruslan Bukin + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * 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. + */ + +/* + * VirtIO MMIO interface. + * This driver is heavily based on VirtIO PCI interface driver. + */ + +/* + * FDT example: + * virtio_block@1000 { + * compatible = "virtio,mmio"; + * reg = <0x1000 0x100>; + * interrupts = <63>; + * interrupt-parent = <&GIC>; + * }; + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "virtio_mmio_if.h" +#include "virtio_bus_if.h" +#include "virtio_if.h" + +#define PAGE_SHIFT 12 + +struct vtmmio_virtqueue { + struct virtqueue *vtv_vq; + int vtv_no_intr; +}; + +struct vtmmio_softc { + device_t dev; + device_t platform; + struct resource *res[2]; + + uint64_t vtmmio_features; + uint32_t vtmmio_flags; + + /* This "bus" will only ever have one child. */ + device_t vtmmio_child_dev; + struct virtio_feature_desc *vtmmio_child_feat_desc; + + int vtmmio_nvqs; + struct vtmmio_virtqueue *vtmmio_vqs; + void *ih; +}; + +static int vtmmio_probe(device_t); +static int vtmmio_attach(device_t); +static int vtmmio_detach(device_t); +static int vtmmio_suspend(device_t); +static int vtmmio_resume(device_t); +static int vtmmio_shutdown(device_t); +static void vtmmio_driver_added(device_t, driver_t *); +static void vtmmio_child_detached(device_t, device_t); +static int vtmmio_read_ivar(device_t, device_t, int, uintptr_t *); +static int vtmmio_write_ivar(device_t, device_t, int, uintptr_t); +static uint64_t vtmmio_negotiate_features(device_t, uint64_t); +static int vtmmio_with_feature(device_t, uint64_t); +static int vtmmio_alloc_virtqueues(device_t, int, int, + struct vq_alloc_info *); +static int vtmmio_setup_intr(device_t, enum intr_type); +static void vtmmio_stop(device_t); +static int vtmmio_reinit(device_t, uint64_t); +static void vtmmio_reinit_complete(device_t); +static void vtmmio_notify_virtqueue(device_t, uint16_t); +static uint8_t vtmmio_get_status(device_t); +static void vtmmio_set_status(device_t, uint8_t); +static void vtmmio_read_dev_config(device_t, bus_size_t, void *, int); +static void vtmmio_write_dev_config(device_t, bus_size_t, void *, int); +static void vtmmio_describe_features(struct vtmmio_softc *, const char *, + uint64_t); +static void vtmmio_probe_and_attach_child(struct vtmmio_softc *); +static int vtmmio_reinit_virtqueue(struct vtmmio_softc *, int); +static void vtmmio_free_interrupts(struct vtmmio_softc *); +static void vtmmio_free_virtqueues(struct vtmmio_softc *); +static void vtmmio_release_child_resources(struct vtmmio_softc *); +static void vtmmio_reset(struct vtmmio_softc *); +static void vtmmio_select_virtqueue(struct vtmmio_softc *, int); +static void vtmmio_vq_intr(void *); + +/* + * I/O port read/write wrappers. + */ +#define vtmmio_write_config_1(sc, o, v) \ + bus_write_1((sc)->res[0], (o), (v)); \ + VIRTIO_MMIO_NOTE(sc->platform, (o)) +#define vtmmio_write_config_2(sc, o, v) \ + bus_write_2((sc)->res[0], (o), (v)); \ + VIRTIO_MMIO_NOTE(sc->platform, (o)) +#define vtmmio_write_config_4(sc, o, v) \ + bus_write_4((sc)->res[0], (o), (v)); \ + VIRTIO_MMIO_NOTE(sc->platform, (o)) + +#define vtmmio_read_config_1(sc, o) \ + bus_read_1((sc)->res[0], (o)) +#define vtmmio_read_config_2(sc, o) \ + bus_read_2((sc)->res[0], (o)) +#define vtmmio_read_config_4(sc, o) \ + bus_read_4((sc)->res[0], (o)) + +static device_method_t vtmmio_methods[] = { + /* Device interface. */ + DEVMETHOD(device_probe, vtmmio_probe), + DEVMETHOD(device_attach, vtmmio_attach), + DEVMETHOD(device_detach, vtmmio_detach), + DEVMETHOD(device_suspend, vtmmio_suspend), + DEVMETHOD(device_resume, vtmmio_resume), + DEVMETHOD(device_shutdown, vtmmio_shutdown), + + /* Bus interface. */ + DEVMETHOD(bus_driver_added, vtmmio_driver_added), + DEVMETHOD(bus_child_detached, vtmmio_child_detached), + DEVMETHOD(bus_read_ivar, vtmmio_read_ivar), + DEVMETHOD(bus_write_ivar, vtmmio_write_ivar), + + /* VirtIO bus interface. */ + DEVMETHOD(virtio_bus_negotiate_features, vtmmio_negotiate_features), + DEVMETHOD(virtio_bus_with_feature, vtmmio_with_feature), + DEVMETHOD(virtio_bus_alloc_virtqueues, vtmmio_alloc_virtqueues), + DEVMETHOD(virtio_bus_setup_intr, vtmmio_setup_intr), + DEVMETHOD(virtio_bus_stop, vtmmio_stop), + DEVMETHOD(virtio_bus_reinit, vtmmio_reinit), + DEVMETHOD(virtio_bus_reinit_complete, vtmmio_reinit_complete), + DEVMETHOD(virtio_bus_notify_vq, vtmmio_notify_virtqueue), + DEVMETHOD(virtio_bus_read_device_config, vtmmio_read_dev_config), + DEVMETHOD(virtio_bus_write_device_config, vtmmio_write_dev_config), + + DEVMETHOD_END +}; + +static driver_t vtmmio_driver = { + "virtio_mmio", + vtmmio_methods, + sizeof(struct vtmmio_softc) +}; + +devclass_t vtmmio_devclass; + +DRIVER_MODULE(virtio_mmio, simplebus, vtmmio_driver, vtmmio_devclass, 0, 0); +MODULE_VERSION(virtio_mmio, 1); +MODULE_DEPEND(virtio_mmio, simplebus, 1, 1, 1); +MODULE_DEPEND(virtio_mmio, virtio, 1, 1, 1); + +static int +vtmmio_setup_intr(device_t dev, enum intr_type type) +{ + struct vtmmio_softc *sc; + int rid; + int err; + + sc = device_get_softc(dev); + + err = VIRTIO_MMIO_SETUP_INTR(sc->platform, sc->dev, + vtmmio_vq_intr, sc); + if (err == 0) { + /* Okay we have backend-specific interrupts */ + return (0); + } + + rid = 0; + sc->res[1] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (!sc->res[1]) { + device_printf(dev, "Can't allocate interrupt\n"); + return (ENXIO); + } + + if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, + NULL, vtmmio_vq_intr, sc, &sc->ih)) { + device_printf(dev, "Can't setup the interrupt\n"); + return (ENXIO); + } + + return (0); +} + +static int +vtmmio_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_is_compatible(dev, "virtio,mmio")) + return (ENXIO); + + device_set_desc(dev, "VirtIO MMIO adapter"); + return (BUS_PROBE_DEFAULT); +} + +static int +vtmmio_setup_platform(struct vtmmio_softc *sc) +{ + phandle_t platform_node; + struct fdt_ic *ic; + phandle_t xref; + phandle_t node; + + sc->platform = NULL; + + if ((node = ofw_bus_get_node(sc->dev)) == -1) + return (ENXIO); + + if (OF_searchencprop(node, "platform", &xref, + sizeof(xref)) == -1) { + return (ENXIO); + } + + platform_node = OF_node_from_xref(xref); + + SLIST_FOREACH(ic, &fdt_ic_list_head, fdt_ics) { + if (ic->iph == platform_node) { + sc->platform = ic->dev; + break; + } + } + + if (sc->platform == NULL) { + /* No platform-specific device. Ignore it. */ + } + + return (0); +} + +static int +vtmmio_attach(device_t dev) +{ + struct vtmmio_softc *sc; + device_t child; + int rid; + + sc = device_get_softc(dev); + sc->dev = dev; + + vtmmio_setup_platform(sc); + + rid = 0; + sc->res[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (!sc->res[0]) { + device_printf(dev, "Cannot allocate memory window.\n"); + return (ENXIO); + } + + vtmmio_reset(sc); + + /* Tell the host we've noticed this device. */ + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); + + if ((child = device_add_child(dev, NULL, -1)) == NULL) { + device_printf(dev, "Cannot create child device.\n"); + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED); + vtmmio_detach(dev); + return (ENOMEM); + } + + sc->vtmmio_child_dev = child; + vtmmio_probe_and_attach_child(sc); + + return (0); +} + +static int +vtmmio_detach(device_t dev) +{ + struct vtmmio_softc *sc; + device_t child; + int error; + + sc = device_get_softc(dev); + + if ((child = sc->vtmmio_child_dev) != NULL) { + error = device_delete_child(dev, child); + if (error) + return (error); + sc->vtmmio_child_dev = NULL; + } + + vtmmio_reset(sc); + + if (sc->res[0] != NULL) { + bus_release_resource(dev, SYS_RES_MEMORY, 0, + sc->res[0]); + sc->res[0] = NULL; + } + + return (0); +} + +static int +vtmmio_suspend(device_t dev) +{ + + return (bus_generic_suspend(dev)); +} + +static int +vtmmio_resume(device_t dev) +{ + + return (bus_generic_resume(dev)); +} + +static int +vtmmio_shutdown(device_t dev) +{ + + (void) bus_generic_shutdown(dev); + + /* Forcibly stop the host device. */ + vtmmio_stop(dev); + + return (0); +} + +static void +vtmmio_driver_added(device_t dev, driver_t *driver) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + vtmmio_probe_and_attach_child(sc); +} + +static void +vtmmio_child_detached(device_t dev, device_t child) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + vtmmio_reset(sc); + vtmmio_release_child_resources(sc); +} + +static int +vtmmio_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + if (sc->vtmmio_child_dev != child) + return (ENOENT); + + switch (index) { + case VIRTIO_IVAR_DEVTYPE: + case VIRTIO_IVAR_SUBDEVICE: + *result = vtmmio_read_config_4(sc, VIRTIO_MMIO_DEVICE_ID); + break; + case VIRTIO_IVAR_VENDOR: + *result = vtmmio_read_config_4(sc, VIRTIO_MMIO_VENDOR_ID); + break; + default: + return (ENOENT); + } + + return (0); +} + +static int +vtmmio_write_ivar(device_t dev, device_t child, int index, uintptr_t value) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + if (sc->vtmmio_child_dev != child) + return (ENOENT); + + switch (index) { + case VIRTIO_IVAR_FEATURE_DESC: + sc->vtmmio_child_feat_desc = (void *) value; + break; + default: + return (ENOENT); + } + + return (0); +} + +static uint64_t +vtmmio_negotiate_features(device_t dev, uint64_t child_features) +{ + struct vtmmio_softc *sc; + uint64_t host_features, features; + + sc = device_get_softc(dev); + + host_features = vtmmio_read_config_4(sc, VIRTIO_MMIO_HOST_FEATURES); + vtmmio_describe_features(sc, "host", host_features); + + /* + * Limit negotiated features to what the driver, virtqueue, and + * host all support. + */ + features = host_features & child_features; + features = virtqueue_filter_features(features); + sc->vtmmio_features = features; + + vtmmio_describe_features(sc, "negotiated", features); + vtmmio_write_config_4(sc, VIRTIO_MMIO_GUEST_FEATURES, features); + + return (features); +} + +static int +vtmmio_with_feature(device_t dev, uint64_t feature) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + return ((sc->vtmmio_features & feature) != 0); +} + +static int +vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs, + struct vq_alloc_info *vq_info) +{ + struct vtmmio_virtqueue *vqx; + struct vq_alloc_info *info; + struct vtmmio_softc *sc; + struct virtqueue *vq; + int idx, error; + uint16_t size; + + sc = device_get_softc(dev); + + if (sc->vtmmio_nvqs != 0) + return (EALREADY); + if (nvqs <= 0) + return (EINVAL); + + sc->vtmmio_vqs = malloc(nvqs * sizeof(struct vtmmio_virtqueue), + M_DEVBUF, M_NOWAIT | M_ZERO); + if (sc->vtmmio_vqs == NULL) + return (ENOMEM); + + for (idx = 0; idx < nvqs; idx++) { + vqx = &sc->vtmmio_vqs[idx]; + info = &vq_info[idx]; + + vtmmio_select_virtqueue(sc, idx); + size = vtmmio_read_config_2(sc, VIRTIO_MMIO_QUEUE_NUM); + + error = virtqueue_alloc(dev, idx, size, + VIRTIO_MMIO_VRING_ALIGN, 0xFFFFFFFFUL, info, &vq); + if (error) { + device_printf(dev, + "cannot allocate virtqueue %d: %d\n", + idx, error); + break; + } +#if 0 + device_printf(dev, "virtqueue paddr 0x%08lx\n", + (uint64_t)virtqueue_paddr(vq)); +#endif + vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, + virtqueue_paddr(vq) >> PAGE_SHIFT); + + vqx->vtv_vq = *info->vqai_vq = vq; + vqx->vtv_no_intr = info->vqai_intr == NULL; + + sc->vtmmio_nvqs++; + } + + if (error) + vtmmio_free_virtqueues(sc); + + return (error); +} + +static void +vtmmio_stop(device_t dev) +{ + + vtmmio_reset(device_get_softc(dev)); +} + +static int +vtmmio_reinit(device_t dev, uint64_t features) +{ + struct vtmmio_softc *sc; + int idx, error; + + sc = device_get_softc(dev); + + if (vtmmio_get_status(dev) != VIRTIO_CONFIG_STATUS_RESET) + vtmmio_stop(dev); + + /* + * Quickly drive the status through ACK and DRIVER. The device + * does not become usable again until vtmmio_reinit_complete(). + */ + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); + + vtmmio_negotiate_features(dev, features); + + for (idx = 0; idx < sc->vtmmio_nvqs; idx++) { + error = vtmmio_reinit_virtqueue(sc, idx); + if (error) + return (error); + } + + return (0); +} + +static void +vtmmio_reinit_complete(device_t dev) +{ + + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); +} + +static void +vtmmio_notify_virtqueue(device_t dev, uint16_t queue) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + vtmmio_write_config_2(sc, VIRTIO_MMIO_QUEUE_NOTIFY, queue); +} + +static uint8_t +vtmmio_get_status(device_t dev) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + return (vtmmio_read_config_1(sc, VIRTIO_MMIO_STATUS)); +} + +static void +vtmmio_set_status(device_t dev, uint8_t status) +{ + struct vtmmio_softc *sc; + + sc = device_get_softc(dev); + + if (status != VIRTIO_CONFIG_STATUS_RESET) + status |= vtmmio_get_status(dev); + + vtmmio_write_config_1(sc, VIRTIO_MMIO_STATUS, status); +} + +static void +vtmmio_read_dev_config(device_t dev, bus_size_t offset, + void *dst, int length) +{ + struct vtmmio_softc *sc; + bus_size_t off; + uint8_t *d; + int size; + + sc = device_get_softc(dev); + off = VIRTIO_MMIO_CONFIG + offset; + + for (d = dst; length > 0; d += size, off += size, length -= size) { + if (length >= 4) { + size = 4; + *(uint32_t *)d = vtmmio_read_config_4(sc, off); + } else if (length >= 2) { + size = 2; + *(uint16_t *)d = vtmmio_read_config_2(sc, off); + } else { + size = 1; + *d = vtmmio_read_config_1(sc, off); + } + } +} + +static void +vtmmio_write_dev_config(device_t dev, bus_size_t offset, + void *src, int length) +{ + struct vtmmio_softc *sc; + bus_size_t off; + uint8_t *s; + int size; + + sc = device_get_softc(dev); + off = VIRTIO_MMIO_CONFIG + offset; + + for (s = src; length > 0; s += size, off += size, length -= size) { + if (length >= 4) { + size = 4; + vtmmio_write_config_4(sc, off, *(uint32_t *)s); + } else if (length >= 2) { + size = 2; + vtmmio_write_config_2(sc, off, *(uint16_t *)s); + } else { + size = 1; + vtmmio_write_config_1(sc, off, *s); + } + } +} + +static void +vtmmio_describe_features(struct vtmmio_softc *sc, const char *msg, + uint64_t features) +{ + device_t dev, child; + + dev = sc->dev; + child = sc->vtmmio_child_dev; + + if (device_is_attached(child) && bootverbose == 0) + return; + + virtio_describe(dev, msg, features, sc->vtmmio_child_feat_desc); +} + +static void +vtmmio_probe_and_attach_child(struct vtmmio_softc *sc) +{ + device_t dev, child; + + dev = sc->dev; + child = sc->vtmmio_child_dev; + + if (child == NULL) + return; + + if (device_get_state(child) != DS_NOTPRESENT) { + return; + } + + if (device_probe(child) != 0) { + return; + } + + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER); + if (device_attach(child) != 0) { + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_FAILED); + vtmmio_reset(sc); + vtmmio_release_child_resources(sc); + /* Reset status for future attempt. */ + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_ACK); + } else { + vtmmio_set_status(dev, VIRTIO_CONFIG_STATUS_DRIVER_OK); + VIRTIO_ATTACH_COMPLETED(child); + } +} + +static int +vtmmio_reinit_virtqueue(struct vtmmio_softc *sc, int idx) +{ + struct vtmmio_virtqueue *vqx; + struct virtqueue *vq; + int error; + uint16_t size; + + vqx = &sc->vtmmio_vqs[idx]; + vq = vqx->vtv_vq; + + KASSERT(vq != NULL, ("%s: vq %d not allocated", __func__, idx)); + + vtmmio_select_virtqueue(sc, idx); + size = vtmmio_read_config_2(sc, VIRTIO_MMIO_QUEUE_NUM); + + error = virtqueue_reinit(vq, size); + if (error) + return (error); + + vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, + virtqueue_paddr(vq) >> PAGE_SHIFT); + + return (0); +} + +static void +vtmmio_free_interrupts(struct vtmmio_softc *sc) +{ + + if (sc->ih != NULL) + bus_teardown_intr(sc->dev, sc->res[1], sc->ih); + + if (sc->res[1] != NULL) + bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->res[1]); +} + +static void +vtmmio_free_virtqueues(struct vtmmio_softc *sc) +{ + struct vtmmio_virtqueue *vqx; + int idx; + + for (idx = 0; idx < sc->vtmmio_nvqs; idx++) { + vqx = &sc->vtmmio_vqs[idx]; + + vtmmio_select_virtqueue(sc, idx); + vtmmio_write_config_4(sc, VIRTIO_MMIO_QUEUE_PFN, 0); + + virtqueue_free(vqx->vtv_vq); + vqx->vtv_vq = NULL; + } + + free(sc->vtmmio_vqs, M_DEVBUF); + sc->vtmmio_vqs = NULL; + sc->vtmmio_nvqs = 0; +} + +static void +vtmmio_release_child_resources(struct vtmmio_softc *sc) +{ + + vtmmio_free_interrupts(sc); + vtmmio_free_virtqueues(sc); +} + +static void +vtmmio_reset(struct vtmmio_softc *sc) +{ + + /* + * Setting the status to RESET sets the host device to + * the original, uninitialized state. + */ + vtmmio_set_status(sc->dev, VIRTIO_CONFIG_STATUS_RESET); +} + +static void +vtmmio_select_virtqueue(struct vtmmio_softc *sc, int idx) +{ + + vtmmio_write_config_2(sc, VIRTIO_MMIO_QUEUE_SEL, idx); +} + +static void +vtmmio_vq_intr(void *arg) +{ + struct vtmmio_virtqueue *vqx; + struct vtmmio_softc *sc; + struct virtqueue *vq; + int idx; + + sc = arg; + + /* Notify all virtqueues. */ + for (idx = 0; idx < sc->vtmmio_nvqs; idx++) { + vqx = &sc->vtmmio_vqs[idx]; + vq = vqx->vtv_vq; + virtqueue_intr(vq); + }; +} diff --git a/sys/sys/sf_sync.h b/sys/dev/virtio/mmio/virtio_mmio.h similarity index 50% rename from sys/sys/sf_sync.h rename to sys/dev/virtio/mmio/virtio_mmio.h index 04dee3801a5..30e028630f6 100644 --- a/sys/sys/sf_sync.h +++ b/sys/dev/virtio/mmio/virtio_mmio.h @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2013 Adrian Chadd + * Copyright (c) 2014 Ruslan Bukin * All rights reserved. * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) + * ("CTSRD"), as part of the DARPA CRASH research programme. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -26,39 +30,34 @@ * $FreeBSD$ */ -#ifndef _SYS_SF_SYNC_H_ -#define _SYS_SF_SYNC_H_ +#ifndef _VIRTIO_MMIO_H +#define _VIRTIO_MMIO_H -typedef enum { - SF_STATE_NONE, - SF_STATE_SETUP, - SF_STATE_RUNNING, - SF_STATE_COMPLETED, - SF_STATE_FREEING -} sendfile_sync_state_t; +#define VIRTIO_MMIO_MAGIC_VALUE 0x000 +#define VIRTIO_MMIO_VERSION 0x004 +#define VIRTIO_MMIO_DEVICE_ID 0x008 -struct sendfile_sync { - struct mtx mtx; - struct cv cv; - struct knlist klist; - uint32_t flags; - uint32_t count; - int32_t xerrno; /* Completion errno, if retval < 0 */ - off_t retval; /* Completion retval (eg written bytes) */ - sendfile_sync_state_t state; -}; +#define VIRTIO_MMIO_MAGIC_VALUE 0x000 +#define VIRTIO_MMIO_VERSION 0x004 +#define VIRTIO_MMIO_DEVICE_ID 0x008 +#define VIRTIO_MMIO_VENDOR_ID 0x00c +#define VIRTIO_MMIO_HOST_FEATURES 0x010 +#define VIRTIO_MMIO_HOST_FEATURES_SEL 0x014 +#define VIRTIO_MMIO_GUEST_FEATURES 0x020 +#define VIRTIO_MMIO_GUEST_FEATURES_SEL 0x024 +#define VIRTIO_MMIO_GUEST_PAGE_SIZE 0x028 +#define VIRTIO_MMIO_QUEUE_SEL 0x030 +#define VIRTIO_MMIO_QUEUE_NUM_MAX 0x034 +#define VIRTIO_MMIO_QUEUE_NUM 0x038 +#define VIRTIO_MMIO_QUEUE_ALIGN 0x03c +#define VIRTIO_MMIO_QUEUE_PFN 0x040 +#define VIRTIO_MMIO_QUEUE_NOTIFY 0x050 +#define VIRTIO_MMIO_INTERRUPT_STATUS 0x060 +#define VIRTIO_MMIO_INTERRUPT_ACK 0x064 +#define VIRTIO_MMIO_STATUS 0x070 +#define VIRTIO_MMIO_CONFIG 0x100 +#define VIRTIO_MMIO_INT_VRING (1 << 0) +#define VIRTIO_MMIO_INT_CONFIG (1 << 1) +#define VIRTIO_MMIO_VRING_ALIGN 4096 -/* XXX pollution */ -struct sf_hdtr_kq; - -extern struct sendfile_sync * sf_sync_alloc(uint32_t flags); -extern void sf_sync_syscall_wait(struct sendfile_sync *); -extern void sf_sync_free(struct sendfile_sync *); -extern void sf_sync_try_free(struct sendfile_sync *); -extern void sf_sync_ref(struct sendfile_sync *); -extern void sf_sync_deref(struct sendfile_sync *); -extern int sf_sync_kqueue_setup(struct sendfile_sync *, struct sf_hdtr_kq *); -extern void sf_sync_set_state(struct sendfile_sync *, sendfile_sync_state_t, int); -extern void sf_sync_set_retval(struct sendfile_sync *, off_t, int); - -#endif /* !_SYS_SF_BUF_H_ */ +#endif /* _VIRTIO_MMIO_H */ diff --git a/sys/dev/virtio/mmio/virtio_mmio_if.m b/sys/dev/virtio/mmio/virtio_mmio_if.m new file mode 100644 index 00000000000..51511fabe5c --- /dev/null +++ b/sys/dev/virtio/mmio/virtio_mmio_if.m @@ -0,0 +1,76 @@ +#- +# Copyright (c) 2014 Ruslan Bukin +# All rights reserved. +# +# This software was developed by SRI International and the University of +# Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) +# ("CTSRD"), as part of the DARPA CRASH research programme. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include + +# +# This is optional interface to virtio mmio backend. +# Useful when backend is implemented not by the hardware but software, e.g. +# by using another cpu core. +# + +INTERFACE virtio_mmio; + +CODE { + static int + virtio_mmio_write(device_t dev, size_t offset) + { + + return (1); + } + + static int + virtio_mmio_setup_intr(device_t dev, device_t mmio_dev, + void *handler, void *ih_user) + { + + return (1); + } +}; + +# +# Inform backend we have data wrotten to offset. +# +METHOD int note { + device_t dev; + size_t offset; +} DEFAULT virtio_mmio_write; + +# +# Setup backend-specific interrupts. +# +METHOD int setup_intr { + device_t dev; + device_t mmio_dev; + void *handler; + void *ih_user; +} DEFAULT virtio_mmio_setup_intr; diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 1310f30bc23..83cb2d79fe2 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -967,9 +967,14 @@ vtnet_setup_interface(struct vtnet_softc *sc) ifp->if_capabilities |= IFCAP_VLAN_HWTSO; } - if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_CSUM)) + if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_CSUM)) { ifp->if_capabilities |= IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6; + if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_TSO4) || + virtio_with_feature(dev, VIRTIO_NET_F_GUEST_TSO6)) + ifp->if_capabilities |= IFCAP_LRO; + } + if (ifp->if_capabilities & IFCAP_HWCSUM) { /* * VirtIO does not support VLAN tagging, but we can fake @@ -987,12 +992,6 @@ vtnet_setup_interface(struct vtnet_softc *sc) * Capabilities after here are not enabled by default. */ - if (ifp->if_capabilities & IFCAP_RXCSUM) { - if (virtio_with_feature(dev, VIRTIO_NET_F_GUEST_TSO4) || - virtio_with_feature(dev, VIRTIO_NET_F_GUEST_TSO6)) - ifp->if_capabilities |= IFCAP_LRO; - } - if (sc->vtnet_flags & VTNET_FLAG_VLAN_FILTER) { ifp->if_capabilities |= IFCAP_VLAN_HWFILTER; diff --git a/sys/dev/wds/wd7000.c b/sys/dev/wds/wd7000.c index 3ea5b29b3a6..4a0caf4f0f7 100644 --- a/sys/dev/wds/wd7000.c +++ b/sys/dev/wds/wd7000.c @@ -159,8 +159,8 @@ __FBSDID("$FreeBSD$"); #include #include -#define WDSTOPHYS(wp, a) ( ((u_long)a) - ((u_long)wp->dx) + ((u_long)wp->dx_p) ) -#define WDSTOVIRT(wp, a) ( ((char *)a) - ((char*)wp->dx_p) + ((char *)wp->dx) ) +#define WDSTOPHYS(wp, a) ( ((uintptr_t)a) - ((uintptr_t)wp->dx) + (wp->dx_p) ) +#define WDSTOVIRT(wp, a) ( ((a) - (wp->dx_p)) + ((char *)wp->dx) ) /* 0x10000 (64k) should be enough. But just to be sure... */ #define BUFSIZ 0x12000 @@ -298,8 +298,8 @@ struct wdsdx { struct wds { device_t dev; + struct mtx lock; int unit; - int addr; int drq; struct cam_sim *sim; /* SIM descriptor for this card */ struct cam_path *path; /* wildcard path for this card */ @@ -307,7 +307,7 @@ struct wds { u_int32_t data_free; u_int32_t wdsr_free; struct wdsdx *dx; - struct wdsdx *dx_p; /* physical address */ + bus_addr_t dx_p; /* physical address */ struct resource *port_r; int port_rid; struct resource *drq_r; @@ -323,7 +323,8 @@ struct wds { static int wds_probe(device_t dev); static int wds_attach(device_t dev); -static void wds_intr(struct wds *wp); +static void wds_intr(void *arg); +static void wds_intr_locked(struct wds *wp); static void wds_action(struct cam_sim * sim, union ccb * ccb); static void wds_poll(struct cam_sim * sim); @@ -345,8 +346,8 @@ static void wds_done(struct wds *wp, struct wds_req *r, u_int8_t stat); static int wds_runsense(struct wds *wp, struct wds_req *r); static int wds_getvers(struct wds *wp); -static int wds_cmd(int base, u_int8_t * p, int l); -static void wds_wait(int reg, int mask, int val); +static int wds_cmd(struct wds *wp, u_int8_t * p, int l); +static void wds_wait(struct wds *wp, int reg, int mask, int val); static struct wds_req *cmdtovirt(struct wds *wp, u_int32_t phys); @@ -455,6 +456,7 @@ static int wds_probe(device_t dev) { struct wds *wp; + unsigned long addr; int error = 0; int irq; @@ -466,14 +468,13 @@ wds_probe(device_t dev) wp->unit = device_get_unit(dev); wp->dev = dev; - wp->addr = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/); - if (wp->addr == 0 || wp->addr <0x300 - || wp->addr > 0x3f8 || wp->addr & 0x7) { - device_printf(dev, "invalid port address 0x%x\n", wp->addr); + addr = bus_get_resource_start(dev, SYS_RES_IOPORT, 0 /*rid*/); + if (addr == 0 || addr <0x300 || addr > 0x3f8 || addr & 0x7) { + device_printf(dev, "invalid port address 0x%lx\n", addr); return (ENXIO); } - if (bus_set_resource(dev, SYS_RES_IOPORT, 0, wp->addr, WDS_NPORTS) < 0) + if (bus_set_resource(dev, SYS_RES_IOPORT, 0, addr, WDS_NPORTS) < 0) return (ENXIO); /* get the DRQ */ @@ -491,9 +492,8 @@ wds_probe(device_t dev) } wp->port_rid = 0; - wp->port_r = bus_alloc_resource(dev, SYS_RES_IOPORT, &wp->port_rid, - /*start*/ 0, /*end*/ ~0, - /*count*/ 0, RF_ACTIVE); + wp->port_r = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &wp->port_rid, + RF_ACTIVE); if (wp->port_r == NULL) return (ENXIO); @@ -519,32 +519,29 @@ wds_attach(device_t dev) int error = 0; wp = (struct wds *)device_get_softc(dev); + mtx_init(&wp->lock, "wds", NULL, MTX_DEF); wp->port_rid = 0; - wp->port_r = bus_alloc_resource(dev, SYS_RES_IOPORT, &wp->port_rid, - /*start*/ 0, /*end*/ ~0, - /*count*/ 0, RF_ACTIVE); + wp->port_r = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &wp->port_rid, + RF_ACTIVE); if (wp->port_r == NULL) - return (ENXIO); + goto bad; /* We must now release resources on error. */ wp->drq_rid = 0; - wp->drq_r = bus_alloc_resource(dev, SYS_RES_DRQ, &wp->drq_rid, - /*start*/ 0, /*end*/ ~0, - /*count*/ 0, RF_ACTIVE); + wp->drq_r = bus_alloc_resource_any(dev, SYS_RES_DRQ, &wp->drq_rid, + RF_ACTIVE); if (wp->drq_r == NULL) goto bad; wp->intr_rid = 0; - wp->intr_r = bus_alloc_resource(dev, SYS_RES_IRQ, &wp->intr_rid, - /*start*/ 0, /*end*/ ~0, - /*count*/ 0, RF_ACTIVE); + wp->intr_r = bus_alloc_resource_any(dev, SYS_RES_IRQ, &wp->intr_rid, + RF_ACTIVE); if (wp->intr_r == NULL) goto bad; - error = bus_setup_intr(dev, wp->intr_r, INTR_TYPE_CAM | INTR_ENTROPY, - NULL, (driver_intr_t *)wds_intr, (void *)wp, - &wp->intr_cookie); + error = bus_setup_intr(dev, wp->intr_r, INTR_TYPE_CAM | INTR_ENTROPY | + INTR_MPSAFE, NULL, wds_intr, wp, &wp->intr_cookie); if (error) goto bad; @@ -557,8 +554,8 @@ wds_attach(device_t dev) /*maxsize*/ sizeof(* wp->dx), /*nsegments*/ 1, /*maxsegsz*/ sizeof(* wp->dx), /*flags*/ 0, - /*lockfunc*/busdma_lock_mutex, - /*lockarg*/&Giant, + /*lockfunc*/NULL, + /*lockarg*/NULL, &wp->bustag); if (error) goto bad; @@ -607,15 +604,17 @@ wds_attach(device_t dev) goto bad; sim = cam_sim_alloc(wds_action, wds_poll, "wds", (void *) wp, - wp->unit, &Giant, 1, 1, devq); + wp->unit, &wp->lock, 1, 1, devq); if (sim == NULL) { cam_simq_free(devq); goto bad; } wp->sim = sim; + mtx_lock(&wp->lock); if (xpt_bus_register(sim, dev, 0) != CAM_SUCCESS) { cam_sim_free(sim, /* free_devq */ TRUE); + mtx_unlock(&wp->lock); goto bad; } if (xpt_create_path(&pathp, /* periph */ NULL, @@ -623,14 +622,17 @@ wds_attach(device_t dev) CAM_LUN_WILDCARD) != CAM_REQ_CMP) { xpt_bus_deregister(cam_sim_path(sim)); cam_sim_free(sim, /* free_devq */ TRUE); + mtx_unlock(&wp->lock); goto bad; } + mtx_unlock(&wp->lock); wp->path = pathp; return (0); bad: wds_free_resources(wp); + mtx_destroy(&wp->lock); if (error) return (error); else /* exact error is unknown */ @@ -759,19 +761,29 @@ wdsr_alloc(struct wds *wp) } static void -wds_intr(struct wds *wp) +wds_intr(void *arg) +{ + struct wds *wp; + + wp = arg; + mtx_lock(&wp->lock); + wds_intr_locked(wp); + mtx_unlock(&wp->lock); +} + +static void +wds_intr_locked(struct wds *wp) { struct wds_req *rp; struct wds_mb *in; u_int8_t stat; u_int8_t c; - int addr = wp->addr; DBG(DBX "wds%d: interrupt [\n", wp->unit); smallog('['); - if (inb(addr + WDS_STAT) & WDS_IRQ) { - c = inb(addr + WDS_IRQSTAT); + if (bus_read_1(wp->port_r, WDS_STAT) & WDS_IRQ) { + c = bus_read_1(wp->port_r, WDS_IRQSTAT); if ((c & WDSI_MASK) == WDSI_MSVC) { c = c & ~WDSI_MASK; in = &wp->dx->imbs[c]; @@ -790,7 +802,7 @@ wds_intr(struct wds *wp) } else device_printf(wp->dev, "weird interrupt, irqstat=0x%x\n", c); - outb(addr + WDS_IRQACK, 0); + bus_write_1(wp->port_r, WDS_IRQACK, 0); } else { smallog('?'); } @@ -934,12 +946,12 @@ wds_runsense(struct wds *wp, struct wds_req *r) scsi_ulto3b(sizeof(struct scsi_sense_data), r->cmd.len); r->cmd.write = 0x80; - outb(wp->addr + WDS_HCR, WDSH_IRQEN | WDSH_DRQEN); + bus_write_1(wp->port_r, WDS_HCR, WDSH_IRQEN | WDSH_DRQEN); wp->dx->ombs[r->ombn].stat = 1; c = WDSC_MSTART(r->ombn); - if (wds_cmd(wp->addr, &c, sizeof c) != 0) { + if (wds_cmd(wp, &c, sizeof c) != 0) { device_printf(wp->dev, "unable to start outgoing sense mbox\n"); wp->dx->ombs[r->ombn].stat = 0; wdsr_ccb_done(wp, r, r->ccb, CAM_AUTOSENSE_FAIL); @@ -958,12 +970,9 @@ static int wds_getvers(struct wds *wp) { struct wds_req *r; - int base; u_int8_t c; int i; - base = wp->addr; - r = wdsr_alloc(wp); if (!r) { device_printf(wp->dev, "no request slot available!\n"); @@ -978,10 +987,10 @@ wds_getvers(struct wds *wp) bzero(&r->cmd, sizeof r->cmd); r->cmd.cmd = WDSX_GETFIRMREV; - outb(base + WDS_HCR, WDSH_DRQEN); + bus_write_1(wp->port_r, WDS_HCR, WDSH_DRQEN); c = WDSC_MSTART(r->ombn); - if (wds_cmd(base, (u_int8_t *) & c, sizeof c)) { + if (wds_cmd(wp, (u_int8_t *) & c, sizeof c)) { device_printf(wp->dev, "version request failed\n"); wp->wdsr_free |= (1 << r->id); wp->dx->ombs[r->ombn].stat = 0; @@ -989,14 +998,14 @@ wds_getvers(struct wds *wp) } while (1) { i = 0; - while ((inb(base + WDS_STAT) & WDS_IRQ) == 0) { + while ((bus_read_1(wp->port_r, WDS_STAT) & WDS_IRQ) == 0) { DELAY(9000); if (++i == 100) { device_printf(wp->dev, "getvers timeout\n"); return (-1); } } - wds_intr(wp); + wds_intr_locked(wp); if (r->flags & WR_DONE) { device_printf(wp->dev, "firmware version %d.%02d\n", r->cmd.targ, r->cmd.scb[0]); @@ -1016,9 +1025,8 @@ wdsr_ccb_done(struct wds *wp, struct wds_req *r, /* To implement timeouts we would need to know how to abort the * command on controller, and this is a great mystery. * So for now we just pass the responsibility for timeouts - * to the controlles itself, it does that reasonably good. + * to the controller itself, it does that reasonably good. */ - /* untimeout(_timeout, (caddr_t) hcb, ccb->ccb_h.timeout_ch); */ /* we're about to free a hcb, so the shortage has ended */ frag_free(wp, r->mask); if (wp->want_wdsr && status != CAM_REQUEUE_REQ) { @@ -1040,7 +1048,6 @@ wds_scsi_io(struct cam_sim * sim, struct ccb_scsiio * csio) struct wds *wp; struct ccb_hdr *ccb_h; struct wds_req *r; - int base; u_int8_t c; int error; int n; @@ -1072,7 +1079,6 @@ wds_scsi_io(struct cam_sim * sim, struct ccb_scsiio * csio) xpt_done((union ccb *) csio); return; } - base = wp->addr; /* * this check is mostly for debugging purposes, @@ -1150,11 +1156,11 @@ wds_scsi_io(struct cam_sim * sim, struct ccb_scsiio * csio) scsi_ulto3b(0, r->cmd.next); - outb(base + WDS_HCR, WDSH_IRQEN | WDSH_DRQEN); + bus_write_1(wp->port_r, WDS_HCR, WDSH_IRQEN | WDSH_DRQEN); c = WDSC_MSTART(r->ombn); - if (wds_cmd(base, &c, sizeof c) != 0) { + if (wds_cmd(wp, &c, sizeof c) != 0) { device_printf(wp->dev, "unable to start outgoing mbox\n"); wp->dx->ombs[r->ombn].stat = 0; wdsr_ccb_done(wp, r, r->ccb, CAM_RESRC_UNAVAIL); @@ -1170,16 +1176,13 @@ static void wds_action(struct cam_sim * sim, union ccb * ccb) { int unit = cam_sim_unit(sim); - int s; DBG(DBX "wds%d: action 0x%x\n", unit, ccb->ccb_h.func_code); switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: - s = splcam(); DBG(DBX "wds%d: SCSI IO entered\n", unit); wds_scsi_io(sim, &ccb->csio); DBG(DBX "wds%d: SCSI IO returned\n", unit); - splx(s); break; case XPT_RESET_BUS: /* how to do it right ? */ @@ -1242,7 +1245,7 @@ wds_action(struct cam_sim * sim, union ccb * ccb) static void wds_poll(struct cam_sim * sim) { - wds_intr((struct wds *)cam_sim_softc(sim)); + wds_intr_locked(cam_sim_softc(sim)); } /* part of initialization done in probe() */ @@ -1251,32 +1254,29 @@ wds_poll(struct cam_sim * sim) static int wds_preinit(struct wds *wp) { - int base; int i; - base = wp->addr; - /* * Sending a command causes the CMDRDY bit to clear. */ - outb(base + WDS_CMD, WDSC_NOOP); - if (inb(base + WDS_STAT) & WDS_RDY) + bus_write_1(wp->port_r, WDS_CMD, WDSC_NOOP); + if (bus_read_1(wp->port_r, WDS_STAT) & WDS_RDY) return (ENXIO); /* * the controller exists. reset and init. */ - outb(base + WDS_HCR, WDSH_ASCRESET | WDSH_SCSIRESET); + bus_write_1(wp->port_r, WDS_HCR, WDSH_ASCRESET | WDSH_SCSIRESET); DELAY(30); - outb(base + WDS_HCR, 0); + bus_write_1(wp->port_r, WDS_HCR, 0); - if ((inb(base + WDS_STAT) & (WDS_RDY)) != WDS_RDY) { + if ((bus_read_1(wp->port_r, WDS_STAT) & (WDS_RDY)) != WDS_RDY) { for (i = 0; i < 10; i++) { - if ((inb(base + WDS_STAT) & (WDS_RDY)) == WDS_RDY) + if ((bus_read_1(wp->port_r, WDS_STAT) & (WDS_RDY)) == WDS_RDY) break; DELAY(40000); } - if ((inb(base + WDS_STAT) & (WDS_RDY)) != WDS_RDY) + if ((bus_read_1(wp->port_r, WDS_STAT) & (WDS_RDY)) != WDS_RDY) /* probe timeout */ return (ENXIO); } @@ -1291,23 +1291,20 @@ static int wds_init(struct wds *wp) { struct wds_setup init; - int base; int i; struct wds_cmd wc; - base = wp->addr; - - outb(base + WDS_HCR, WDSH_DRQEN); + bus_write_1(wp->port_r, WDS_HCR, WDSH_DRQEN); isa_dmacascade(wp->drq); - if ((inb(base + WDS_STAT) & (WDS_RDY)) != WDS_RDY) { + if ((bus_read_1(wp->port_r, WDS_STAT) & (WDS_RDY)) != WDS_RDY) { for (i = 0; i < 10; i++) { - if ((inb(base + WDS_STAT) & (WDS_RDY)) == WDS_RDY) + if ((bus_read_1(wp->port_r, WDS_STAT) & (WDS_RDY)) == WDS_RDY) break; DELAY(40000); } - if ((inb(base + WDS_STAT) & (WDS_RDY)) != WDS_RDY) + if ((bus_read_1(wp->port_r, WDS_STAT) & (WDS_RDY)) != WDS_RDY) /* probe timeout */ return (1); } @@ -1321,18 +1318,18 @@ wds_init(struct wds *wp) init.nomb = WDS_NOMB; init.nimb = WDS_NIMB; - wds_wait(base + WDS_STAT, WDS_RDY, WDS_RDY); - if (wds_cmd(base, (u_int8_t *) & init, sizeof init) != 0) { + wds_wait(wp, WDS_STAT, WDS_RDY, WDS_RDY); + if (wds_cmd(wp, (u_int8_t *) & init, sizeof init) != 0) { device_printf(wp->dev, "wds_cmd init failed\n"); return (1); } - wds_wait(base + WDS_STAT, WDS_INIT, WDS_INIT); + wds_wait(wp, WDS_STAT, WDS_INIT, WDS_INIT); - wds_wait(base + WDS_STAT, WDS_RDY, WDS_RDY); + wds_wait(wp, WDS_STAT, WDS_RDY, WDS_RDY); bzero(&wc, sizeof wc); wc.cmd = WDSC_DISUNSOL; - if (wds_cmd(base, (char *) &wc, sizeof wc) != 0) { + if (wds_cmd(wp, (char *) &wc, sizeof wc) != 0) { device_printf(wp->dev, "wds_cmd init2 failed\n"); return (1); } @@ -1340,29 +1337,26 @@ wds_init(struct wds *wp) } static int -wds_cmd(int base, u_int8_t * p, int l) +wds_cmd(struct wds *wp, u_int8_t * p, int l) { - int s = splcam(); while (l--) { do { - outb(base + WDS_CMD, *p); - wds_wait(base + WDS_STAT, WDS_RDY, WDS_RDY); - } while (inb(base + WDS_STAT) & WDS_REJ); + bus_write_1(wp->port_r, WDS_CMD, *p); + wds_wait(wp, WDS_STAT, WDS_RDY, WDS_RDY); + } while (bus_read_1(wp->port_r, WDS_STAT) & WDS_REJ); p++; } - wds_wait(base + WDS_STAT, WDS_RDY, WDS_RDY); - - splx(s); + wds_wait(wp, WDS_STAT, WDS_RDY, WDS_RDY); return (0); } static void -wds_wait(int reg, int mask, int val) +wds_wait(struct wds *wp, int reg, int mask, int val) { - while ((inb(reg) & mask) != val) + while ((bus_read_1(wp->port_r, reg) & mask) != val) ; } @@ -1394,9 +1388,9 @@ wds_print(void) if (wp == NULL) continue; printf("wds%d: want_wdsr=0x%x stat=0x%x irq=%s irqstat=0x%x\n", - unit, wp->want_wdsr, inb(wp->addr + WDS_STAT) & 0xff, - (inb(wp->addr + WDS_STAT) & WDS_IRQ) ? "ready" : "no", - inb(wp->addr + WDS_IRQSTAT) & 0xff); + unit, wp->want_wdsr, bus_read_1(wp->port_r, WDS_STAT) & 0xff, + (bus_read_1(wp->port_r, WDS_STAT) & WDS_IRQ) ? "ready" : "no", + bus_read_1(wp->port_r, WDS_IRQSTAT) & 0xff); for (i = 0; i < MAXSIMUL; i++) { r = &wp->dx->req[i]; if( wp->wdsr_free & (1 << r->id) ) { diff --git a/sys/dev/wl/if_wl.c b/sys/dev/wl/if_wl.c index 97800071057..23835c6079b 100644 --- a/sys/dev/wl/if_wl.c +++ b/sys/dev/wl/if_wl.c @@ -232,12 +232,11 @@ __FBSDID("$FreeBSD$"); static char t_packet[ETHERMTU + sizeof(struct ether_header) + sizeof(long)]; -struct wl_softc{ +struct wl_softc { + device_t dev; struct ifnet *ifp; u_char psa[0x40]; u_char nwid[2]; /* current radio modem nwid */ - short base; - short unit; int flags; int tbusy; /* flag to determine if xmit is busy */ u_short begin_fd; @@ -252,10 +251,8 @@ struct wl_softc{ struct resource *res_ioport; struct resource *res_irq; void *intr_cookie; - bus_space_tag_t bt; - bus_space_handle_t bh; struct mtx wl_mtx; - struct callout_handle watchdog_ch; + struct callout watchdog_timer; #ifdef WLCACHE int w_sigitems; /* number of cached entries */ /* array of cache entries */ @@ -328,9 +325,11 @@ SYSCTL_INT(_machdep, OID_AUTO, wl_gather_snr, CTLFLAG_RW, &gathersnr, 0, ""); static int wl_allocate_resources(device_t device); static int wl_deallocate_resources(device_t device); static void wlstart(struct ifnet *ifp); +static void wlstart_locked(struct ifnet *ifp); static void wlinit(void *xsc); +static void wlinit_locked(struct wl_softc *sc); static int wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data); -static timeout_t wlwatchdog; +static void wlwatchdog(void *arg); static void wlintr(void *arg); static void wlxmt(struct wl_softc *sc, struct mbuf *m); static int wldiag(struct wl_softc *sc); @@ -338,7 +337,7 @@ static int wlconfig(struct wl_softc *sc); static int wlcmd(struct wl_softc *sc, char *str); static void wlmmcstat(struct wl_softc *sc); static u_short wlbldru(struct wl_softc *sc); -static u_short wlmmcread(u_int base, u_short reg); +static u_short wlmmcread(struct wl_softc *sc, u_short reg); static void wlinitmmc(struct wl_softc *sc); static int wlhwrst(struct wl_softc *sc); static void wlrustrt(struct wl_softc *sc); @@ -353,12 +352,12 @@ static void wlhdwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, st #ifdef WLDEBUG static void wltbd(struct wl_softc *sc); #endif -static void wlgetpsa(int base, u_char *buf); +static void wlgetpsa(struct wl_softc *sc, u_char *buf); static void wlsetpsa(struct wl_softc *sc); static u_short wlpsacrc(u_char *buf); static void wldump(struct wl_softc *sc); #ifdef WLCACHE -static void wl_cache_store(struct wl_softc *, int, struct ether_header *, struct mbuf *); +static void wl_cache_store(struct wl_softc *, struct ether_header *, struct mbuf *); static void wl_cache_zero(struct wl_softc *sc); #endif @@ -387,10 +386,9 @@ static int wlprobe(device_t device) { struct wl_softc *sc; - short base; char *str = "wl%d: board out of range [0..%d]\n"; u_char inbuf[100]; - unsigned long junk, oldpri, sirq; + unsigned long junk, sirq; int error, irq; error = ISA_PNP_PROBE(device_get_parent(device), device, wl_ids); @@ -402,28 +400,24 @@ wlprobe(device_t device) if (error) goto errexit; - base = rman_get_start(sc->res_ioport); - /* TBD. not true. * regular CMD() will not work, since no softc yet */ -#define PCMD(base, hacr) outw((base), (hacr)) +#define PCMD(sc, hacr) WL_WRITE_2((sc), HACR, (hacr)) - oldpri = splimp(); - PCMD(base, HACR_RESET); /* reset the board */ + PCMD(sc, HACR_RESET); /* reset the board */ DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */ - PCMD(base, HACR_RESET); /* reset the board */ + PCMD(sc, HACR_RESET); /* reset the board */ DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */ - splx(oldpri); /* clear reset command and set PIO#1 in autoincrement mode */ - PCMD(base, HACR_DEFAULT); - PCMD(base, HACR_DEFAULT); - outw(PIOR1(base), 0); /* go to beginning of RAM */ - outsw(PIOP1(base), str, strlen(str)/2+1); /* write string */ + PCMD(sc, HACR_DEFAULT); + PCMD(sc, HACR_DEFAULT); + WL_WRITE_2(sc, PIOR1, 0); /* go to beginning of RAM */ + WL_WRITE_MULTI_2(sc, PIOP1, str, strlen(str)/2+1); /* write string */ - outw(PIOR1(base), 0); /* rewind */ - insw(PIOP1(base), inbuf, strlen(str)/2+1); /* read result */ + WL_WRITE_2(sc, PIOR1, 0); /* rewind */ + WL_READ_MULTI_2(sc, PIOP1, inbuf, strlen(str)/2+1); /* read result */ if (bcmp(str, inbuf, strlen(str))) { error = ENXIO; @@ -434,15 +428,14 @@ wlprobe(device_t device) sc->freq24 = 0; /* 2.4 Gz: frequency */ /* read the PSA from the board into temporary storage */ - wlgetpsa(base, inbuf); + wlgetpsa(sc, inbuf); /* We read the IRQ value from the PSA on the board. */ for (irq = 15; irq >= 0; irq--) if (irqvals[irq] == inbuf[WLPSA_IRQNO]) break; if ((irq == 0) || (irqvals[irq] == 0)){ - printf("wl%d: PSA corrupt (invalid IRQ value)\n", - device_get_unit(device)); + device_printf(device, "PSA corrupt (invalid IRQ value)\n"); } else { /* * If the IRQ requested by the PSA is already claimed by another @@ -452,8 +445,8 @@ wlprobe(device_t device) if (bus_get_resource(device, SYS_RES_IRQ, 0, &sirq, &junk)) goto errexit; if (irq != (int)sirq) - printf("wl%d: board is configured for interrupt %d\n", - device_get_unit(device), irq); + device_printf(device, "board is configured for interrupt %d\n", + irq); } wl_deallocate_resources(device); return (0); @@ -479,13 +472,12 @@ static int wlattach(device_t device) { struct wl_softc *sc; - short base; int error, i, j; - int unit; struct ifnet *ifp; u_char eaddr[6]; sc = device_get_softc(device); + sc->dev = device; ifp = sc->ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { device_printf(device, "can not if_alloc()\n"); @@ -493,7 +485,8 @@ wlattach(device_t device) } mtx_init(&sc->wl_mtx, device_get_nameunit(device), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); + MTX_DEF); + callout_init_mtx(&sc->watchdog_timer, &sc->wl_mtx, 0); error = wl_allocate_resources(device); if (error) { @@ -501,19 +494,14 @@ wlattach(device_t device) return (ENXIO); } - base = rman_get_start(sc->res_ioport); - unit = device_get_unit(device); - #ifdef WLDEBUG - printf("wlattach: base %x, unit %d\n", base, unit); + printf("wlattach: base %lx, unit %d\n", rman_get_start(sc->res_ioport), + device_get_unit(device)); #endif - sc->base = base; - sc->unit = unit; sc->flags = 0; sc->mode = 0; sc->hacr = HACR_RESET; - callout_handle_init(&sc->watchdog_ch); CMD(sc); /* reset the board */ DELAY(DELAYCONST); /* >> 4 clocks at 6MHz */ @@ -522,7 +510,7 @@ wlattach(device_t device) CMD(sc); /* Read the PSA from the board for our later reference */ - wlgetpsa(base, sc->psa); + wlgetpsa(sc, sc->psa); /* fetch NWID */ sc->nwid[0] = sc->psa[WLPSA_NWID]; @@ -541,11 +529,11 @@ wlattach(device_t device) CMD(sc); wlinitmmc(sc); - outw(PIOR1(base), OFFSET_SCB + 8); /* address of scb_crcerrs */ - outw(PIOP1(base), 0); /* clear scb_crcerrs */ - outw(PIOP1(base), 0); /* clear scb_alnerrs */ - outw(PIOP1(base), 0); /* clear scb_rscerrs */ - outw(PIOP1(base), 0); /* clear scb_ovrnerrs */ + WL_WRITE_2(sc, PIOR1, OFFSET_SCB + 8); /* address of scb_crcerrs */ + WL_WRITE_2(sc, PIOP1, 0); /* clear scb_crcerrs */ + WL_WRITE_2(sc, PIOP1, 0); /* clear scb_alnerrs */ + WL_WRITE_2(sc, PIOP1, 0); /* clear scb_rscerrs */ + WL_WRITE_2(sc, PIOP1, 0); /* clear scb_ovrnerrs */ ifp->if_softc = sc; ifp->if_mtu = WAVELAN_MTU; @@ -583,7 +571,6 @@ static int wldetach(device_t device) { struct wl_softc *sc = device_get_softc(device); - device_t parent = device_get_parent(device); struct ifnet *ifp; ifp = sc->ifp; @@ -596,15 +583,16 @@ wldetach(device_t device) CMD(sc); sc->hacr = HACR_DEFAULT; CMD(sc); + callout_stop(&sc->watchdog_timer); + WL_UNLOCK(sc); + callout_drain(&sc->watchdog_timer); if (sc->intr_cookie != NULL) { - BUS_TEARDOWN_INTR(parent, device, sc->res_irq, sc->intr_cookie); + bus_teardown_intr(device, sc->res_irq, sc->intr_cookie); sc->intr_cookie = NULL; } - bus_generic_detach(device); wl_deallocate_resources(device); - WL_UNLOCK(sc); if_free(ifp); mtx_destroy(&sc->wl_mtx); return (0); @@ -656,27 +644,26 @@ wl_deallocate_resources(device_t device) static void wldump(struct wl_softc *sc) { - int base = sc->base; int i; - printf("hasr %04x\n", inw(HASR(base))); + printf("hasr %04x\n", WL_READ_2(sc, HASR)); printf("scb at %04x:\n ", OFFSET_SCB); - outw(PIOR1(base), OFFSET_SCB); + WL_WRITE_2(sc, PIOR1, OFFSET_SCB); for (i = 0; i < 8; i++) - printf("%04x ", inw(PIOP1(base))); + printf("%04x ", WL_READ_2(sc, PIOP1)); printf("\n"); printf("cu at %04x:\n ", OFFSET_CU); - outw(PIOR1(base), OFFSET_CU); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); for (i = 0; i < 8; i++) - printf("%04x ", inw(PIOP1(base))); + printf("%04x ", WL_READ_2(sc, PIOP1)); printf("\n"); printf("tbd at %04x:\n ", OFFSET_TBD); - outw(PIOR1(base), OFFSET_TBD); + WL_WRITE_2(sc, PIOR1, OFFSET_TBD); for (i = 0; i < 4; i++) - printf("%04x ", inw(PIOP1(base))); + printf("%04x ", WL_READ_2(sc, PIOP1)); printf("\n"); } @@ -684,7 +671,6 @@ wldump(struct wl_softc *sc) static void wlinitmmc(struct wl_softc *sc) { - int base = sc->base; int configured; int mode = sc->mode; int i; /* 2.4 Gz */ @@ -747,7 +733,7 @@ wlinitmmc(struct wl_softc *sc) MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */ for (i=0; i<1000; ++i) { /* 2.4 Gz: wait for download */ DELAY(40); /* 2.4 Gz */ - if ((wlmmcread(base,MMC_EECTRLstat) /* 2.4 Gz: check DWLD and */ + if ((wlmmcread(sc, MMC_EECTRLstat) /* 2.4 Gz: check DWLD and */ &(MMC_EECTRLstat_DWLD /* 2.4 Gz: EEBUSY */ +MMC_EECTRLstat_EEBUSY))==0) /* 2.4 Gz: */ break; /* 2.4 Gz: download finished */ @@ -758,7 +744,7 @@ wlinitmmc(struct wl_softc *sc) MMC_EECTRL_EEOP_READ); /* 2.4 Gz: Read EEPROM */ for (i=0; i<1000; ++i) { /* 2.4 Gz: wait for download */ DELAY(40); /* 2.4 Gz */ - if ((wlmmcread(base,MMC_EECTRLstat) /* 2.4 Gz: check DWLD and */ + if ((wlmmcread(sc, MMC_EECTRLstat) /* 2.4 Gz: check DWLD and */ &(MMC_EECTRLstat_DWLD /* 2.4 Gz: EEBUSY */ +MMC_EECTRLstat_EEBUSY))==0) /* 2.4 Gz: */ break; /* 2.4 Gz: download finished */ @@ -772,8 +758,8 @@ wlinitmmc(struct wl_softc *sc) MMC_WRITE(MMC_EECTRL, /* 2.4 Gz: EEPROM read */ MMC_EECTRL_EEOP_READ); /* 2.4 Gz: */ DELAY(40); /* 2.4 Gz */ - i = wlmmcread(base,MMC_EEDATALrv) /* 2.4 Gz: freq val */ - + (wlmmcread(base,MMC_EEDATAHrv)<<8); /* 2.4 Gz */ + i = wlmmcread(sc, MMC_EEDATALrv) /* 2.4 Gz: freq val */ + + (wlmmcread(sc, MMC_EEDATAHrv)<<8); /* 2.4 Gz */ sc->freq24 = (i>>6)+2400; /* 2.4 Gz: save real freq */ } } @@ -793,16 +779,23 @@ static void wlinit(void *xsc) { struct wl_softc *sc = xsc; + + WL_LOCK(sc); + wlinit_locked(sc); + WL_UNLOCK(sc); +} + +static void +wlinit_locked(struct wl_softc *sc) +{ struct ifnet *ifp = sc->ifp; int stat; - u_long oldpri; #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wlinit()\n",sc->unit); + if_printf(ifp, "entered wlinit()\n"); #endif - WL_LOCK(sc); - oldpri = splimp(); + WL_LOCK_ASSERT(sc); if ((stat = wlhwrst(sc)) == TRUE) { sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; /* same as DSF_RUNNING */ /* @@ -813,14 +806,12 @@ wlinit(void *xsc) sc->flags |= DSF_RUNNING; sc->tbusy = 0; - untimeout(wlwatchdog, sc, sc->watchdog_ch); + callout_stop(&sc->watchdog_timer); - wlstart(ifp); + wlstart_locked(ifp); } else { - printf("wl%d init(): trouble resetting board.\n", sc->unit); + if_printf(ifp, "init(): trouble resetting board.\n"); } - splx(oldpri); - WL_UNLOCK(sc); } /* @@ -839,7 +830,7 @@ wlhwrst(struct wl_softc *sc) #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wlhwrst()\n", sc->unit); + if_printf(sc->ifp, "entered wlhwrst()\n"); #endif sc->hacr = HACR_RESET; CMD(sc); /* reset the board */ @@ -881,7 +872,6 @@ wlhwrst(struct wl_softc *sc) static void wlbldcu(struct wl_softc *sc) { - short base = sc->base; scp_t scp; iscp_t iscp; scb_t scb; @@ -893,16 +883,16 @@ wlbldcu(struct wl_softc *sc) scp.scp_sysbus = 0; scp.scp_iscp = OFFSET_ISCP; scp.scp_iscp_base = 0; - outw(PIOR1(base), OFFSET_SCP); - outsw(PIOP1(base), &scp, sizeof(scp_t)/2); + WL_WRITE_2(sc, PIOR1, OFFSET_SCP); + WL_WRITE_MULTI_2(sc, PIOP1, &scp, sizeof(scp_t)/2); bzero(&iscp, sizeof(iscp)); iscp.iscp_busy = 1; iscp.iscp_scb_offset = OFFSET_SCB; iscp.iscp_scb = 0; iscp.iscp_scb_base = 0; - outw(PIOR1(base), OFFSET_ISCP); - outsw(PIOP1(base), &iscp, sizeof(iscp_t)/2); + WL_WRITE_2(sc, PIOR1, OFFSET_ISCP); + WL_WRITE_MULTI_2(sc, PIOP1, &iscp, sizeof(iscp_t)/2); scb.scb_status = 0; scb.scb_command = SCB_RESET; @@ -912,37 +902,37 @@ wlbldcu(struct wl_softc *sc) scb.scb_alnerrs = 0; scb.scb_rscerrs = 0; scb.scb_ovrnerrs = 0; - outw(PIOR1(base), OFFSET_SCB); - outsw(PIOP1(base), &scb, sizeof(scb_t)/2); + WL_WRITE_2(sc, PIOR1, OFFSET_SCB); + WL_WRITE_MULTI_2(sc, PIOP1, &scb, sizeof(scb_t)/2); SET_CHAN_ATTN(sc); - outw(PIOR0(base), OFFSET_ISCP + 0); /* address of iscp_busy */ - for (i = 1000000; inw(PIOP0(base)) && (i-- > 0); ) + WL_WRITE_2(sc, PIOR0, OFFSET_ISCP + 0); /* address of iscp_busy */ + for (i = 1000000; WL_READ_2(sc, PIOP0) && (i-- > 0); ) continue; if (i <= 0) - printf("wl%d bldcu(): iscp_busy timeout.\n", sc->unit); - outw(PIOR0(base), OFFSET_SCB + 0); /* address of scb_status */ + device_printf(sc->dev, "bldcu(): iscp_busy timeout.\n"); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 0); /* address of scb_status */ for (i = STATUS_TRIES; i-- > 0; ) { - if (inw(PIOP0(base)) == (SCB_SW_CX|SCB_SW_CNA)) + if (WL_READ_2(sc, PIOP0) == (SCB_SW_CX|SCB_SW_CNA)) break; } if (i <= 0) - printf("wl%d bldcu(): not ready after reset.\n", sc->unit); + device_printf(sc->dev, "bldcu(): not ready after reset.\n"); wlack(sc); cb.ac_status = 0; cb.ac_command = AC_CW_EL; /* NOP */ cb.ac_link_offset = OFFSET_CU; - outw(PIOR1(base), OFFSET_CU); - outsw(PIOP1(base), &cb, 6/2); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + WL_WRITE_MULTI_2(sc, PIOP1, &cb, 6/2); tbd.act_count = 0; tbd.next_tbd_offset = I82586NULL; tbd.buffer_addr = 0; tbd.buffer_base = 0; - outw(PIOR1(base), OFFSET_TBD); - outsw(PIOP1(base), &tbd, sizeof(tbd_t)/2); + WL_WRITE_2(sc, PIOR1, OFFSET_TBD); + WL_WRITE_MULTI_2(sc, PIOP1, &tbd, sizeof(tbd_t)/2); } /* @@ -957,23 +947,32 @@ wlbldcu(struct wl_softc *sc) static void wlstart(struct ifnet *ifp) { - struct mbuf *m; struct wl_softc *sc = ifp->if_softc; - short base = sc->base; - int scb_status, cu_status, scb_command; WL_LOCK(sc); + wlstart_locked(ifp); + WL_UNLOCK(sc); +} + +static void +wlstart_locked(struct ifnet *ifp) +{ + struct mbuf *m; + struct wl_softc *sc = ifp->if_softc; + int scb_status, cu_status, scb_command; + + WL_LOCK_ASSERT(sc); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("%s: entered wlstart()\n", ifp->if_xname); + if_printf(ifp, "entered wlstart()\n"); #endif - outw(PIOR1(base), OFFSET_CU); - cu_status = inw(PIOP1(base)); - outw(PIOR0(base),OFFSET_SCB + 0); /* scb_status */ - scb_status = inw(PIOP0(base)); - outw(PIOR0(base), OFFSET_SCB + 2); - scb_command = inw(PIOP0(base)); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + cu_status = WL_READ_2(sc, PIOP1); + WL_WRITE_2(sc, PIOR0,OFFSET_SCB + 0); /* scb_status */ + scb_status = WL_READ_2(sc, PIOP0); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); + scb_command = WL_READ_2(sc, PIOP0); /* * don't need OACTIVE check as tbusy here checks to see @@ -983,51 +982,48 @@ wlstart(struct ifnet *ifp) if ((scb_status & 0x0700) == SCB_CUS_IDLE && (cu_status & AC_SW_B) == 0){ sc->tbusy = 0; - untimeout(wlwatchdog, sc, sc->watchdog_ch); + callout_stop(&sc->watchdog_timer); sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; /* * This is probably just a race. The xmt'r is just * became idle but WE have masked interrupts so ... */ #ifdef WLDEBUG - printf("%s: CU idle, scb %04x %04x cu %04x\n", - ifp->if_xname, scb_status, scb_command, cu_status); + if_printf(ifp, "CU idle, scb %04x %04x cu %04x\n", + scb_status, scb_command, cu_status); #endif if (xmt_watch) printf("!!"); } else { - WL_UNLOCK(sc); return; /* genuinely still busy */ } } else if ((scb_status & 0x0700) == SCB_CUS_ACTV || (cu_status & AC_SW_B)){ #ifdef WLDEBUG - printf("%s: CU unexpectedly busy; scb %04x cu %04x\n", - ifp->if_xname, scb_status, cu_status); + if_printf(ifp, "CU unexpectedly busy; scb %04x cu %04x\n", + scb_status, cu_status); #endif - if (xmt_watch) printf("%s: busy?!",ifp->if_xname); - WL_UNLOCK(sc); + if (xmt_watch) + if_printf(ifp, "busy?!\n"); return; /* hey, why are we busy? */ } /* get ourselves some data */ - ifp = sc->ifp; IF_DEQUEUE(&ifp->if_snd, m); - if (m != (struct mbuf *)0) { + if (m != NULL) { /* let BPF see it before we commit it */ BPF_MTAP(ifp, m); sc->tbusy++; /* set the watchdog timer so that if the board * fails to interrupt we will restart */ - /* try 10 ticks, not very long */ - sc->watchdog_ch = timeout(wlwatchdog, sc, 10); + /* try 10 ms, not very long */ + callout_reset(&sc->watchdog_timer, hz / 100, wlwatchdog, sc); sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE; if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1); wlxmt(sc, m); } else { sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } - WL_UNLOCK(sc); return; } @@ -1053,7 +1049,6 @@ static int wlread(struct wl_softc *sc, u_short fd_p) { struct ifnet *ifp = sc->ifp; - short base = sc->base; fd_t fd; struct ether_header *eh; struct mbuf *m; @@ -1066,10 +1061,10 @@ wlread(struct wl_softc *sc, u_short fd_p) #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wlread()\n", sc->unit); + if_printf(ifp, "entered wlread()\n"); #endif if (!((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))) { - printf("%s read(): board is not running.\n", ifp->if_xname); + if_printf(ifp, "read(): board is not running.\n"); sc->hacr &= ~HACR_INTRON; CMD(sc); /* turn off interrupts */ } @@ -1077,19 +1072,19 @@ wlread(struct wl_softc *sc, u_short fd_p) /* * Collect message size. */ - outw(PIOR1(base), fd_p); - insw(PIOP1(base), &fd, sizeof(fd_t)/2); + WL_WRITE_2(sc, PIOR1, fd_p); + WL_READ_MULTI_2(sc, PIOP1, &fd, sizeof(fd_t)/2); if (fd.rbd_offset == I82586NULL) { if (wlhwrst(sc) != TRUE) { sc->hacr &= ~HACR_INTRON; CMD(sc); /* turn off interrupts */ - printf("wl%d read(): hwrst trouble.\n", sc->unit); + if_printf(ifp, "read(): hwrst trouble.\n"); } return 0; } - outw(PIOR1(base), fd.rbd_offset); - insw(PIOP1(base), &rbd, sizeof(rbd_t)/2); + WL_WRITE_2(sc, PIOR1, fd.rbd_offset); + WL_READ_MULTI_2(sc, PIOP1, &rbd, sizeof(rbd_t)/2); bytes_in_msg = rbd.status & RBD_SW_COUNT; /* @@ -1100,7 +1095,7 @@ wlread(struct wl_softc *sc, u_short fd_p) if (wlhwrst(sc) != TRUE) { sc->hacr &= ~HACR_INTRON; CMD(sc); /* turn off interrupts */ - printf("wl%d read(): hwrst trouble.\n", sc->unit); + if_printf(ifp, "read(): hwrst trouble.\n"); } return 0; } @@ -1127,19 +1122,19 @@ wlread(struct wl_softc *sc, u_short fd_p) } else { len = bytes; } - outw(PIOR1(base), rbd.buffer_addr); - insw(PIOP1(base), mb_p, len/2); + WL_WRITE_2(sc, PIOR1, rbd.buffer_addr); + WL_READ_MULTI_2(sc, PIOP1, mb_p, len/2); mlen += bytes; if (bytes > bytes_in_mbuf) { /* XXX something wrong, a packet should fit in 1 cluster */ m_freem(m); - printf("wl%d read(): packet too large (%u > %u)\n", - sc->unit, bytes, bytes_in_mbuf); + if_printf(ifp, "read(): packet too large (%u > %u)\n", + bytes, bytes_in_mbuf); if (wlhwrst(sc) != TRUE) { sc->hacr &= ~HACR_INTRON; CMD(sc); /* turn off interrupts */ - printf("wl%d read(): hwrst trouble.\n", sc->unit); + if_printf(ifp, "read(): hwrst trouble.\n"); } return 0; } @@ -1150,8 +1145,8 @@ wlread(struct wl_softc *sc, u_short fd_p) if (rbd.status & RBD_SW_EOF || rbd.next_rbd_offset == I82586NULL) { break; } - outw(PIOR1(base), rbd.next_rbd_offset); - insw(PIOP1(base), &rbd, sizeof(rbd_t)/2); + WL_WRITE_2(sc, PIOR1, rbd.next_rbd_offset); + WL_READ_MULTI_2(sc, PIOP1, &rbd, sizeof(rbd_t)/2); bytes_in_msg = rbd.status & RBD_SW_COUNT; } else { rbd.buffer_addr += bytes; @@ -1195,11 +1190,11 @@ wlread(struct wl_softc *sc, u_short fd_p) #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: wlrecv %u bytes\n", sc->unit, mlen); + if_printf(ifp, "wlrecv %u bytes\n", mlen); #endif #ifdef WLCACHE - wl_cache_store(sc, base, eh, m); + wl_cache_store(sc, eh, m); #endif /* @@ -1229,25 +1224,24 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ifreq *ifr = (struct ifreq *)data; struct wl_softc *sc = ifp->if_softc; - short base = sc->base; short mode = 0; - int opri, error = 0; + int error = 0; struct thread *td = curthread; /* XXX */ int irq, irqval, i, isroot; - caddr_t up; + char psa_buf[0x40]; + char eeprom_buf[0x80]; #ifdef WLCACHE - int size; + size_t size; char * cpt; #endif - WL_LOCK(sc); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("%s: entered wlioctl()\n", ifp->if_xname); + if_printf(ifp, "entered wlioctl()\n"); #endif - opri = splimp(); switch (cmd) { case SIOCSIFFLAGS: + WL_LOCK(sc); if (ifp->if_flags & IFF_ALLMULTI) { mode |= MOD_ENAL; } @@ -1267,14 +1261,14 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->mode = mode; if (sc->flags & DSF_RUNNING) { sc->flags &= ~DSF_RUNNING; - wlinit(sc); + wlinit_locked(sc); } } /* if interface is marked DOWN and still running then * stop it. */ if ((ifp->if_flags & IFF_UP) == 0 && sc->flags & DSF_RUNNING) { - printf("%s ioctl(): board is not running\n", ifp->if_xname); + if_printf(ifp, "ioctl(): board is not running\n"); sc->flags &= ~DSF_RUNNING; sc->hacr &= ~HACR_INTRON; CMD(sc); /* turn off interrupts */ @@ -1282,13 +1276,14 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* else if interface is UP and RUNNING, start it */ else if (ifp->if_flags & IFF_UP && (sc->flags & DSF_RUNNING) == 0) { - wlinit(sc); + wlinit_locked(sc); } /* if WLDEBUG set on interface, then printf rf-modem regs */ if (ifp->if_flags & IFF_DEBUG) wlmmcstat(sc); + WL_UNLOCK(sc); break; #if MULTICAST case SIOCADDMULTI: @@ -1303,20 +1298,20 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* copy the PSA out to the caller */ case SIOCGWLPSA: - /* pointer to buffer in user space */ - up = (void *)ifr->ifr_data; /* work out if they're root */ isroot = (priv_check(td, PRIV_NET80211_GETKEY) == 0); - + + bzero(psa_buf, sizeof(psa_buf)); + WL_LOCK(sc); for (i = 0; i < 0x40; i++) { /* don't hand the DES key out to non-root users */ if ((i > WLPSA_DESKEY) && (i < (WLPSA_DESKEY + 8)) && !isroot) continue; - if (subyte((up + i), sc->psa[i])) { - WL_UNLOCK(sc); - return(EFAULT); - } + psa_buf[i] = sc->psa[i]; } + WL_UNLOCK(sc); + + error = copyout(psa_buf, ifr->ifr_data, sizeof(psa_buf)); break; @@ -1325,46 +1320,43 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* root only */ if ((error = priv_check(td, PRIV_DRIVER))) break; - error = EINVAL; /* assume the worst */ - /* pointer to buffer in user space containing data */ - up = (void *)ifr->ifr_data; - - /* check validity of input range */ - for (i = 0; i < 0x40; i++) - if (fubyte(up + i) < 0) { - WL_UNLOCK(sc); - return(EFAULT); - } + error = copyin(ifr->ifr_data, psa_buf, sizeof(psa_buf)); + if (error) + break; + /* check IRQ value */ - irqval = fubyte(up+WLPSA_IRQNO); + irqval = psa_buf[WLPSA_IRQNO]; for (irq = 15; irq >= 0; irq--) if (irqvals[irq] == irqval) break; if (irq == 0) /* oops */ break; + WL_LOCK(sc); /* new IRQ */ sc->psa[WLPSA_IRQNO] = irqval; /* local MAC */ for (i = 0; i < 6; i++) - sc->psa[WLPSA_LOCALMAC+i] = fubyte(up+WLPSA_LOCALMAC+i); + sc->psa[WLPSA_LOCALMAC + i] = psa_buf[WLPSA_LOCALMAC + i]; /* MAC select */ - sc->psa[WLPSA_MACSEL] = fubyte(up+WLPSA_MACSEL); + sc->psa[WLPSA_MACSEL] = psa_buf[WLPSA_MACSEL]; /* default nwid */ - sc->psa[WLPSA_NWID] = fubyte(up+WLPSA_NWID); - sc->psa[WLPSA_NWID+1] = fubyte(up+WLPSA_NWID+1); + sc->psa[WLPSA_NWID] = psa_buf[WLPSA_NWID]; + sc->psa[WLPSA_NWID + 1] = psa_buf[WLPSA_NWID + 1]; - error = 0; wlsetpsa(sc); /* update the PSA */ + WL_UNLOCK(sc); break; /* get the current NWID out of the sc since we stored it there */ case SIOCGWLCNWID: + WL_LOCK(sc); ifr->ifr_data = (caddr_t) (sc->nwid[0] << 8 | sc->nwid[1]); + WL_UNLOCK(sc); break; @@ -1381,6 +1373,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* root only */ if ((error = priv_check(td, PRIV_DRIVER))) break; + WL_LOCK(sc); if (!(ifp->if_flags & IFF_UP)) { error = EIO; /* only allowed while up */ } else { @@ -1392,6 +1385,7 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) MMC_WRITE(MMC_NETW_ID_L,sc->nwid[1]); MMC_WRITE(MMC_NETW_ID_H,sc->nwid[0]); } + WL_UNLOCK(sc); break; /* copy the EEPROM in 2.4 Gz WaveMODEM out to the caller */ @@ -1399,25 +1393,21 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* root only */ if ((error = priv_check(td, PRIV_DRIVER))) break; - /* pointer to buffer in user space */ - up = (void *)ifr->ifr_data; - + + bzero(eeprom_buf, sizeof(eeprom_buf)); + WL_LOCK(sc); for (i=0x00; i<0x80; ++i) { /* 2.4 Gz: size of EEPROM */ MMC_WRITE(MMC_EEADDR,i); /* 2.4 Gz: get frequency */ MMC_WRITE(MMC_EECTRL, /* 2.4 Gz: EEPROM read */ MMC_EECTRL_EEOP_READ); /* 2.4 Gz: */ DELAY(40); /* 2.4 Gz */ - if (subyte(up + 2*i, /* 2.4 Gz: pass low byte of */ - wlmmcread(base,MMC_EEDATALrv))) {/* 2.4 Gz: EEPROM word */ - WL_UNLOCK(sc); - return(EFAULT); /* 2.4 Gz: */ - } - if (subyte(up + 2*i+1, /* 2.4 Gz: pass hi byte of */ - wlmmcread(base,MMC_EEDATALrv))) {/* 2.4 Gz: EEPROM word */ - WL_UNLOCK(sc); - return(EFAULT); /* 2.4 Gz: */ - } + eeprom_buf[2 * i] = /* 2.4 Gz: pass low byte of */ + wlmmcread(sc, MMC_EEDATALrv); /* 2.4 Gz: EEPROM word */ + eeprom_buf[2 * i + 1] = /* 2.4 Gz: pass hi byte of */ + wlmmcread(sc, MMC_EEDATALrv); /* 2.4 Gz: EEPROM word */ } + WL_UNLOCK(sc); + error = copyout(ifr->ifr_data, eeprom_buf, sizeof(eeprom_buf)); break; #ifdef WLCACHE @@ -1426,27 +1416,33 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* root only */ if ((error = priv_check(td, PRIV_DRIVER))) break; + WL_LOCK(sc); wl_cache_zero(sc); + WL_UNLOCK(sc); break; /* read out the number of used cache elements */ case SIOCGWLCITEM: + WL_LOCK(sc); ifr->ifr_data = (caddr_t) sc->w_sigitems; + WL_UNLOCK(sc); break; /* read out the wl cache */ case SIOCGWLCACHE: - /* pointer to buffer in user space */ - up = (void *)ifr->ifr_data; - cpt = (char *) &sc->w_sigcache[0]; + WL_LOCK(sc); size = sc->w_sigitems * sizeof(struct w_sigcache); - - for (i = 0; i < size; i++) { - if (subyte((up + i), *cpt++)) { - WL_UNLOCK(sc); - return(EFAULT); - } + cpt = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); + if (cpt == NULL) { + WL_UNLOCK(sc); + return (ENOMEM); } + + bcopy(sc->w_sigcache, cpt, size); + WL_UNLOCK(sc); + + error = copyout(cpt, ifr->ifr_data, size); + free(cpt, M_DEVBUF); break; #endif @@ -1454,8 +1450,6 @@ wlioctl(struct ifnet *ifp, u_long cmd, caddr_t data) error = ether_ioctl(ifp, cmd, data); break; } - splx(opri); - WL_UNLOCK(sc); return (error); } @@ -1474,13 +1468,10 @@ static void wlwatchdog(void *vsc) { struct wl_softc *sc = vsc; - int unit = sc->unit; - log(LOG_ERR, "wl%d: wavelan device timeout on xmit\n", unit); - WL_LOCK(sc); + log(LOG_ERR, "%s: wavelan device timeout on xmit\n", sc->ifp->if_xname); if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1); - wlinit(sc); - WL_UNLOCK(sc); + wlinit_locked(sc); } /* @@ -1499,26 +1490,25 @@ static void wlintr(void *arg) { struct wl_softc *sc = (struct wl_softc *)arg; - short base = sc->base; int ac_status; u_short int_type, int_type1; WL_LOCK(sc); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: wlintr() called\n", sc->unit); + if_printf(sc->ifp, "wlintr() called\n"); #endif - if ((int_type = inw(HASR(base))) & HASR_MMC_INTR) { + if ((int_type = WL_READ_2(sc, HASR)) & HASR_MMC_INTR) { /* handle interrupt from the modem management controler */ /* This will clear the interrupt condition */ - (void) wlmmcread(base,MMC_DCE_STATUS); /* ignored for now */ + (void) wlmmcread(sc, MMC_DCE_STATUS); /* ignored for now */ } if (!(int_type & HASR_INTR)){ /* return if no interrupt from 82586 */ /* commented out. jrb. it happens when reinit occurs printf("wlintr: int_type %x, dump follows\n", int_type); - wldump(unit); + wldump(sc); */ WL_UNLOCK(sc); return; @@ -1527,8 +1517,8 @@ wlintr(void *arg) if (gathersnr) getsnr(sc); for (;;) { - outw(PIOR0(base), OFFSET_SCB + 0); /* get scb status */ - int_type = (inw(PIOP0(base)) & SCB_SW_INT); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 0); /* get scb status */ + int_type = (WL_READ_2(sc, PIOP0) & SCB_SW_INT); if (int_type == 0) /* no interrupts left */ break; @@ -1552,8 +1542,8 @@ wlintr(void *arg) if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d intr(): receiver overrun! begin_fd = %x\n", - sc->unit, sc->begin_fd); + if_printf(sc->ifp, "intr(): receiver overrun! begin_fd = %x\n", + sc->begin_fd); #endif wlrustrt(sc); } @@ -1571,40 +1561,40 @@ wlintr(void *arg) * At present, we only request Interrupt for * XMT. */ - outw(PIOR1(base), OFFSET_CU); /* get command status */ - ac_status = inw(PIOP1(base)); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); /* get command status */ + ac_status = WL_READ_2(sc, PIOP1); if (xmt_watch) { /* report some anomalies */ if (sc->tbusy == 0) { - printf("wl%d: xmt intr but not busy, CU %04x\n", - sc->unit, ac_status); + if_printf(sc->ifp, "xmt intr but not busy, CU %04x\n", + ac_status); } if (ac_status == 0) { - printf("wl%d: xmt intr but ac_status == 0\n", sc->unit); + if_printf(sc->ifp, "xmt intr but ac_status == 0\n"); } if (ac_status & AC_SW_A) { - printf("wl%d: xmt aborted\n", sc->unit); + if_printf(sc->ifp, "xmt aborted\n"); } #ifdef notdef if (ac_status & TC_CARRIER) { - printf("wl%d: no carrier\n", sc->unit); + if_printf(sc->ifp, "no carrier\n"); } #endif /* notdef */ if (ac_status & TC_CLS) { - printf("wl%d: no CTS\n", sc->unit); + if_printf(sc->ifp, "no CTS\n"); } if (ac_status & TC_DMA) { - printf("wl%d: DMA underrun\n", sc->unit); + if_printf(sc->ifp, "DMA underrun\n"); } if (ac_status & TC_DEFER) { - printf("wl%d: xmt deferred\n", sc->unit); + if_printf(sc->ifp, "xmt deferred\n"); } if (ac_status & TC_SQE) { - printf("wl%d: heart beat\n", sc->unit); + if_printf(sc->ifp, "heart beat\n"); } if (ac_status & TC_COLLISION) { - printf("wl%d: too many collisions\n", sc->unit); + if_printf(sc->ifp, "too many collisions\n"); } } /* if the transmit actually failed, or returned some status */ @@ -1620,9 +1610,9 @@ wlintr(void *arg) } } sc->tbusy = 0; - untimeout(wlwatchdog, sc, sc->watchdog_ch); + callout_stop(&sc->watchdog_timer); sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - wlstart(sc->ifp); + wlstart_locked(sc->ifp); } } WL_UNLOCK(sc); @@ -1646,37 +1636,36 @@ wlintr(void *arg) static void wlrcv(struct wl_softc *sc) { - short base = sc->base; u_short fd_p, status, offset, link_offset; #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wlrcv()\n", sc->unit); + if_printf(sc->ifp, "entered wlrcv()\n"); #endif for (fd_p = sc->begin_fd; fd_p != I82586NULL; fd_p = sc->begin_fd) { - outw(PIOR0(base), fd_p + 0); /* address of status */ - status = inw(PIOP0(base)); - outw(PIOR1(base), fd_p + 4); /* address of link_offset */ - link_offset = inw(PIOP1(base)); - offset = inw(PIOP1(base)); /* rbd_offset */ + WL_WRITE_2(sc, PIOR0, fd_p + 0); /* address of status */ + status = WL_READ_2(sc, PIOP0); + WL_WRITE_2(sc, PIOR1, fd_p + 4); /* address of link_offset */ + link_offset = WL_READ_2(sc, PIOP1); + offset = WL_READ_2(sc, PIOP1); /* rbd_offset */ if (status == 0xffff || offset == 0xffff /*I82586NULL*/) { if (wlhwrst(sc) != TRUE) - printf("wl%d rcv(): hwrst ffff trouble.\n", sc->unit); + if_printf(sc->ifp, "rcv(): hwrst ffff trouble.\n"); return; } else if (status & AC_SW_C) { if (status == (RFD_DONE|RFD_RSC)) { /* lost one */ #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d RCV: RSC %x\n", sc->unit, status); + if_printf(sc->ifp, "RCV: RSC %x\n", status); #endif if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); } else if (!(status & RFD_OK)) { - printf("wl%d RCV: !OK %x\n", sc->unit, status); + if_printf(sc->ifp, "RCV: !OK %x\n", status); if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); } else if (status & 0xfff) { /* can't happen */ - printf("wl%d RCV: ERRs %x\n", sc->unit, status); + if_printf(sc->ifp, "RCV: ERRs %x\n", status); if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1); } else if (!wlread(sc, fd_p)) return; @@ -1684,7 +1673,7 @@ wlrcv(struct wl_softc *sc) if (!wlrequeue(sc, fd_p)) { /* abort on chain error */ if (wlhwrst(sc) != TRUE) - printf("wl%d rcv(): hwrst trouble.\n", sc->unit); + if_printf(sc->ifp, "rcv(): hwrst trouble.\n"); return; } sc->begin_fd = link_offset; @@ -1705,32 +1694,31 @@ wlrcv(struct wl_softc *sc) static int wlrequeue(struct wl_softc *sc, u_short fd_p) { - short base = sc->base; fd_t fd; u_short l_rbdp, f_rbdp, rbd_offset; - outw(PIOR0(base), fd_p + 6); - rbd_offset = inw(PIOP0(base)); + WL_WRITE_2(sc, PIOR0, fd_p + 6); + rbd_offset = WL_READ_2(sc, PIOP0); if ((f_rbdp = rbd_offset) != I82586NULL) { l_rbdp = f_rbdp; for (;;) { - outw(PIOR0(base), l_rbdp + 0); /* address of status */ - if (inw(PIOP0(base)) & RBD_SW_EOF) + WL_WRITE_2(sc, PIOR0, l_rbdp + 0); /* address of status */ + if (WL_READ_2(sc, PIOP0) & RBD_SW_EOF) break; - outw(PIOP0(base), 0); - outw(PIOR0(base), l_rbdp + 2); /* next_rbd_offset */ - if ((l_rbdp = inw(PIOP0(base))) == I82586NULL) + WL_WRITE_2(sc, PIOP0, 0); + WL_WRITE_2(sc, PIOR0, l_rbdp + 2); /* next_rbd_offset */ + if ((l_rbdp = WL_READ_2(sc, PIOP0)) == I82586NULL) break; } - outw(PIOP0(base), 0); - outw(PIOR0(base), l_rbdp + 2); /* next_rbd_offset */ - outw(PIOP0(base), I82586NULL); - outw(PIOR0(base), l_rbdp + 8); /* address of size */ - outw(PIOP0(base), inw(PIOP0(base)) | AC_CW_EL); - outw(PIOR0(base), sc->end_rbd + 2); - outw(PIOP0(base), f_rbdp); /* end_rbd->next_rbd_offset */ - outw(PIOR0(base), sc->end_rbd + 8); /* size */ - outw(PIOP0(base), inw(PIOP0(base)) & ~AC_CW_EL); + WL_WRITE_2(sc, PIOP0, 0); + WL_WRITE_2(sc, PIOR0, l_rbdp + 2); /* next_rbd_offset */ + WL_WRITE_2(sc, PIOP0, I82586NULL); + WL_WRITE_2(sc, PIOR0, l_rbdp + 8); /* address of size */ + WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) | AC_CW_EL); + WL_WRITE_2(sc, PIOR0, sc->end_rbd + 2); + WL_WRITE_2(sc, PIOP0, f_rbdp); /* end_rbd->next_rbd_offset */ + WL_WRITE_2(sc, PIOR0, sc->end_rbd + 8); /* size */ + WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) & ~AC_CW_EL); sc->end_rbd = l_rbdp; } @@ -1738,12 +1726,12 @@ wlrequeue(struct wl_softc *sc, u_short fd_p) fd.command = AC_CW_EL; fd.link_offset = I82586NULL; fd.rbd_offset = I82586NULL; - outw(PIOR1(base), fd_p); - outsw(PIOP1(base), &fd, 8/2); + WL_WRITE_2(sc, PIOR1, fd_p); + WL_WRITE_MULTI_2(sc, PIOP1, &fd, 8/2); - outw(PIOR1(base), sc->end_fd + 2); /* addr of command */ - outw(PIOP1(base), 0); /* command = 0 */ - outw(PIOP1(base), fd_p); /* end_fd->link_offset = fd_p */ + WL_WRITE_2(sc, PIOR1, sc->end_fd + 2); /* addr of command */ + WL_WRITE_2(sc, PIOP1, 0); /* command = 0 */ + WL_WRITE_2(sc, PIOP1, fd_p); /* end_fd->link_offset = fd_p */ sc->end_fd = fd_p; return 1; @@ -1776,22 +1764,21 @@ wlxmt(struct wl_softc *sc, struct mbuf *m) ac_t cb; u_short tbd_p = OFFSET_TBD; u_short len, clen = 0; - short base = sc->base; int spin; #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("%s: entered wlxmt()\n", sc->ifp->if_xname); + if_printf(sc->ifp, "entered wlxmt()\n"); #endif cb.ac_status = 0; cb.ac_command = (AC_CW_EL|AC_TRANSMIT|AC_CW_I); cb.ac_link_offset = I82586NULL; - outw(PIOR1(base), OFFSET_CU); - outsw(PIOP1(base), &cb, 6/2); - outw(PIOP1(base), OFFSET_TBD); /* cb.cmd.transmit.tbd_offset */ - outsw(PIOP1(base), eh_p->ether_dhost, WAVELAN_ADDR_SIZE/2); - outw(PIOP1(base), eh_p->ether_type); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + WL_WRITE_MULTI_2(sc, PIOP1, &cb, 6/2); + WL_WRITE_2(sc, PIOP1, OFFSET_TBD); /* cb.cmd.transmit.tbd_offset */ + WL_WRITE_MULTI_2(sc, PIOP1, eh_p->ether_dhost, WAVELAN_ADDR_SIZE/2); + WL_WRITE_2(sc, PIOP1, eh_p->ether_type); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) { @@ -1801,11 +1788,11 @@ wlxmt(struct wl_softc *sc, struct mbuf *m) } } #endif /* WLDEBUG */ - outw(PIOR0(base), OFFSET_TBD); - outw(PIOP0(base), 0); /* act_count */ - outw(PIOR1(base), OFFSET_TBD + 4); - outw(PIOP1(base), xmtdata_p); /* buffer_addr */ - outw(PIOP1(base), 0); /* buffer_base */ + WL_WRITE_2(sc, PIOR0, OFFSET_TBD); + WL_WRITE_2(sc, PIOP0, 0); /* act_count */ + WL_WRITE_2(sc, PIOR1, OFFSET_TBD + 4); + WL_WRITE_2(sc, PIOP1, xmtdata_p); /* buffer_addr */ + WL_WRITE_2(sc, PIOP1, 0); /* buffer_base */ for (;;) { if (count) { if (clen + count > WAVELAN_MTU) @@ -1814,24 +1801,24 @@ wlxmt(struct wl_softc *sc, struct mbuf *m) len = count + 1; else len = count; - outw(PIOR1(base), xmtdata_p); - outsw(PIOP1(base), mb_p, len/2); + WL_WRITE_2(sc, PIOR1, xmtdata_p); + WL_WRITE_MULTI_2(sc, PIOP1, mb_p, len/2); clen += count; - outw(PIOR0(base), tbd_p); /* address of act_count */ - outw(PIOP0(base), inw(PIOP0(base)) + count); + WL_WRITE_2(sc, PIOR0, tbd_p); /* address of act_count */ + WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) + count); xmtdata_p += len; if ((tm_p = tm_p->m_next) == (struct mbuf *)0) break; if (count & 1) { /* go to the next descriptor */ - outw(PIOR0(base), tbd_p + 2); + WL_WRITE_2(sc, PIOR0, tbd_p + 2); tbd_p += sizeof (tbd_t); - outw(PIOP0(base), tbd_p); /* next_tbd_offset */ - outw(PIOR0(base), tbd_p); - outw(PIOP0(base), 0); /* act_count */ - outw(PIOR1(base), tbd_p + 4); - outw(PIOP1(base), xmtdata_p); /* buffer_addr */ - outw(PIOP1(base), 0); /* buffer_base */ + WL_WRITE_2(sc, PIOP0, tbd_p); /* next_tbd_offset */ + WL_WRITE_2(sc, PIOR0, tbd_p); + WL_WRITE_2(sc, PIOP0, 0); /* act_count */ + WL_WRITE_2(sc, PIOR1, tbd_p + 4); + WL_WRITE_2(sc, PIOP1, xmtdata_p); /* buffer_addr */ + WL_WRITE_2(sc, PIOP1, 0); /* buffer_base */ /* at the end -> coallesce remaining mbufs */ if (tbd_p == OFFSET_TBD + (N_TBD-1) * sizeof (tbd_t)) { wlsftwsleaze(&count, &mb_p, &tm_p, sc); @@ -1862,16 +1849,16 @@ wlxmt(struct wl_softc *sc, struct mbuf *m) if (xmt_debug) printf("CLEN = %d\n", clen); #endif /* WLDEBUG */ - outw(PIOR0(base), tbd_p); + WL_WRITE_2(sc, PIOR0, tbd_p); if (clen < ETHERMIN) { - outw(PIOP0(base), inw(PIOP0(base)) + ETHERMIN - clen); - outw(PIOR1(base), xmtdata_p); + WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) + ETHERMIN - clen); + WL_WRITE_2(sc, PIOR1, xmtdata_p); for (xmtshort_p = xmtdata_p; clen < ETHERMIN; clen += 2) - outw(PIOP1(base), 0); + WL_WRITE_2(sc, PIOP1, 0); } - outw(PIOP0(base), inw(PIOP0(base)) | TBD_SW_EOF); - outw(PIOR0(base), tbd_p + 2); - outw(PIOP0(base), I82586NULL); + WL_WRITE_2(sc, PIOP0, WL_READ_2(sc, PIOP0) | TBD_SW_EOF); + WL_WRITE_2(sc, PIOR0, tbd_p + 2); + WL_WRITE_2(sc, PIOP0, I82586NULL); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) { if (xmt_debug) { @@ -1881,20 +1868,20 @@ wlxmt(struct wl_softc *sc, struct mbuf *m) } #endif /* WLDEBUG */ - outw(PIOR0(base), OFFSET_SCB + 2); /* address of scb_command */ + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); /* address of scb_command */ /* * wait for 586 to clear previous command, complain if it takes * too long */ for (spin = 1;;spin = (spin + 1) % 10000) { - if (inw(PIOP0(base)) == 0) { /* it's done, we can go */ + if (WL_READ_2(sc, PIOP0) == 0) { /* it's done, we can go */ break; } if ((spin == 0) && xmt_watch) { /* not waking up, and we care */ - printf("%s: slow accepting xmit\n", sc->ifp->if_xname); + if_printf(sc->ifp, "slow accepting xmit\n"); } } - outw(PIOP0(base), SCB_CU_STRT); /* new command */ + WL_WRITE_2(sc, PIOP0, SCB_CU_STRT); /* new command */ SET_CHAN_ATTN(sc); m_freem(m); @@ -1920,7 +1907,6 @@ wlxmt(struct wl_softc *sc, struct mbuf *m) static u_short wlbldru(struct wl_softc *sc) { - short base = sc->base; fd_t fd; rbd_t rbd; u_short fd_p = OFFSET_RU; @@ -1933,20 +1919,20 @@ wlbldru(struct wl_softc *sc) fd.command = 0; fd.link_offset = fd_p + sizeof(fd_t); fd.rbd_offset = I82586NULL; - outw(PIOR1(base), fd_p); - outsw(PIOP1(base), &fd, 8/2); + WL_WRITE_2(sc, PIOR1, fd_p); + WL_WRITE_MULTI_2(sc, PIOP1, &fd, 8/2); fd_p = fd.link_offset; } fd_p -= sizeof(fd_t); sc->end_fd = fd_p; - outw(PIOR1(base), fd_p + 2); - outw(PIOP1(base), AC_CW_EL); /* command */ - outw(PIOP1(base), I82586NULL); /* link_offset */ + WL_WRITE_2(sc, PIOR1, fd_p + 2); + WL_WRITE_2(sc, PIOP1, AC_CW_EL); /* command */ + WL_WRITE_2(sc, PIOP1, I82586NULL); /* link_offset */ fd_p = OFFSET_RU; - outw(PIOR0(base), fd_p + 6); /* address of rbd_offset */ - outw(PIOP0(base), rbd_p); - outw(PIOR1(base), rbd_p); + WL_WRITE_2(sc, PIOR0, fd_p + 6); /* address of rbd_offset */ + WL_WRITE_2(sc, PIOP0, rbd_p); + WL_WRITE_2(sc, PIOR1, rbd_p); for (i = 0; i < N_RBD; i++) { rbd.status = 0; rbd.buffer_addr = rbd_p + sizeof(rbd_t) + 2; @@ -1960,8 +1946,8 @@ wlbldru(struct wl_softc *sc) rbd.size |= AC_CW_EL; sc->end_rbd = rbd_p; } - outsw(PIOP1(base), &rbd, sizeof(rbd_t)/2); - outw(PIOR1(base), rbd_p); + WL_WRITE_MULTI_2(sc, PIOP1, &rbd, sizeof(rbd_t)/2); + WL_WRITE_2(sc, PIOR1, rbd_p); } return sc->begin_fd; } @@ -1977,24 +1963,23 @@ wlbldru(struct wl_softc *sc) static void wlrustrt(struct wl_softc *sc) { - short base = sc->base; u_short rfa; #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wlrustrt()\n", sc->unit); + if_printf(sc->ifp, "entered wlrustrt()\n"); #endif - outw(PIOR0(base), OFFSET_SCB); - if (inw(PIOP0(base)) & SCB_RUS_READY){ + WL_WRITE_2(sc, PIOR0, OFFSET_SCB); + if (WL_READ_2(sc, PIOP0) & SCB_RUS_READY){ printf("wlrustrt: RUS_READY\n"); return; } - outw(PIOR0(base), OFFSET_SCB + 2); - outw(PIOP0(base), SCB_RU_STRT); /* command */ + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); + WL_WRITE_2(sc, PIOP0, SCB_RU_STRT); /* command */ rfa = wlbldru(sc); - outw(PIOR0(base), OFFSET_SCB + 6); /* address of scb_rfa_offset */ - outw(PIOP0(base), rfa); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 6); /* address of scb_rfa_offset */ + WL_WRITE_2(sc, PIOP0, rfa); SET_CHAN_ATTN(sc); return; @@ -2010,30 +1995,29 @@ wlrustrt(struct wl_softc *sc) static int wldiag(struct wl_softc *sc) { - short base = sc->base; short status; #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wldiag()\n", sc->unit); + if_printf(sc->ifp, "entered wldiag()\n"); #endif - outw(PIOR0(base), OFFSET_SCB); - status = inw(PIOP0(base)); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB); + status = WL_READ_2(sc, PIOP0); if (status & SCB_SW_INT) { /* state is 2000 which seems ok - printf("wl%d diag(): unexpected initial state %\n", - sc->unit, inw(PIOP0(base))); + if_printf(sc->ifp, "diag(): unexpected initial state %\n", + WL_READ_2(sc, PIOP0)); */ wlack(sc); } - outw(PIOR1(base), OFFSET_CU); - outw(PIOP1(base), 0); /* ac_status */ - outw(PIOP1(base), AC_DIAGNOSE|AC_CW_EL);/* ac_command */ + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + WL_WRITE_2(sc, PIOP1, 0); /* ac_status */ + WL_WRITE_2(sc, PIOP1, AC_DIAGNOSE|AC_CW_EL);/* ac_command */ if (wlcmd(sc, "diag()") == 0) return 0; - outw(PIOR0(base), OFFSET_CU); - if (inw(PIOP0(base)) & 0x0800) { - printf("wl%d: i82586 Self Test failed!\n", sc->unit); + WL_WRITE_2(sc, PIOR0, OFFSET_CU); + if (WL_READ_2(sc, PIOP0) & 0x0800) { + if_printf(sc->ifp, "i82586 Self Test failed!\n"); return 0; } return TRUE; @@ -2049,7 +2033,6 @@ static int wlconfig(struct wl_softc *sc) { configure_t configure; - short base = sc->base; #if MULTICAST struct ifmultiaddr *ifma; @@ -2059,20 +2042,20 @@ wlconfig(struct wl_softc *sc) #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: entered wlconfig()\n", sc->unit); + if_printf(sc->ifp, "entered wlconfig()\n"); #endif - outw(PIOR0(base), OFFSET_SCB); - if (inw(PIOP0(base)) & SCB_SW_INT) { + WL_WRITE_2(sc, PIOR0, OFFSET_SCB); + if (WL_READ_2(sc, PIOP0) & SCB_SW_INT) { /* - printf("wl%d config(): unexpected initial state %x\n", - sc->unit, inw(PIOP0(base))); + if_printf(sc->ifp, "config(): unexpected initial state %x\n", + WL_READ_2(sc, PIOP0)); */ } wlack(sc); - outw(PIOR1(base), OFFSET_CU); - outw(PIOP1(base), 0); /* ac_status */ - outw(PIOP1(base), AC_CONFIGURE|AC_CW_EL); /* ac_command */ + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + WL_WRITE_2(sc, PIOP1, 0); /* ac_status */ + WL_WRITE_2(sc, PIOP1, AC_CONFIGURE|AC_CW_EL); /* ac_command */ /* jrb hack */ configure.fifolim_bytecnt = 0x080c; @@ -2105,39 +2088,39 @@ wlconfig(struct wl_softc *sc) #endif if (sc->mode & (MOD_PROM | MOD_ENAL)) configure.hardware |= 1; - outw(PIOR1(base), OFFSET_CU + 6); - outsw(PIOP1(base), &configure, sizeof(configure_t)/2); + WL_WRITE_2(sc, PIOR1, OFFSET_CU + 6); + WL_WRITE_MULTI_2(sc, PIOP1, &configure, sizeof(configure_t)/2); if (wlcmd(sc, "config()-configure") == 0) return 0; #if MULTICAST - outw(PIOR1(base), OFFSET_CU); - outw(PIOP1(base), 0); /* ac_status */ - outw(PIOP1(base), AC_MCSETUP|AC_CW_EL); /* ac_command */ - outw(PIOR1(base), OFFSET_CU + 8); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + WL_WRITE_2(sc, PIOP1, 0); /* ac_status */ + WL_WRITE_2(sc, PIOP1, AC_MCSETUP|AC_CW_EL); /* ac_command */ + WL_WRITE_2(sc, PIOR1, OFFSET_CU + 8); if_maddr_rlock(sc->ifp); TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; addrp = LLADDR((struct sockaddr_dl *)ifma->ifma_addr); - outw(PIOP1(base), addrp[0] + (addrp[1] << 8)); - outw(PIOP1(base), addrp[2] + (addrp[3] << 8)); - outw(PIOP1(base), addrp[4] + (addrp[5] << 8)); + WL_WRITE_2(sc, PIOP1, addrp[0] + (addrp[1] << 8)); + WL_WRITE_2(sc, PIOP1, addrp[2] + (addrp[3] << 8)); + WL_WRITE_2(sc, PIOP1, addrp[4] + (addrp[5] << 8)); ++cnt; } if_maddr_runlock(sc->ifp); - outw(PIOR1(base), OFFSET_CU + 6); /* mc-cnt */ - outw(PIOP1(base), cnt * WAVELAN_ADDR_SIZE); + WL_WRITE_2(sc, PIOR1, OFFSET_CU + 6); /* mc-cnt */ + WL_WRITE_2(sc, PIOP1, cnt * WAVELAN_ADDR_SIZE); if (wlcmd(sc, "config()-mcaddress") == 0) return 0; #endif /* MULTICAST */ - outw(PIOR1(base), OFFSET_CU); - outw(PIOP1(base), 0); /* ac_status */ - outw(PIOP1(base), AC_IASETUP|AC_CW_EL); /* ac_command */ - outw(PIOR1(base), OFFSET_CU + 6); - outsw(PIOP1(base), IF_LLADDR(sc->ifp), WAVELAN_ADDR_SIZE/2); + WL_WRITE_2(sc, PIOR1, OFFSET_CU); + WL_WRITE_2(sc, PIOP1, 0); /* ac_status */ + WL_WRITE_2(sc, PIOP1, AC_IASETUP|AC_CW_EL); /* ac_command */ + WL_WRITE_2(sc, PIOR1, OFFSET_CU + 6); + WL_WRITE_MULTI_2(sc, PIOP1, IF_LLADDR(sc->ifp), WAVELAN_ADDR_SIZE/2); if (wlcmd(sc, "config()-address") == 0) return(0); @@ -2156,37 +2139,38 @@ wlconfig(struct wl_softc *sc) static int wlcmd(struct wl_softc *sc, char *str) { - short base = sc->base; int i; - outw(PIOR0(base), OFFSET_SCB + 2); /* address of scb_command */ - outw(PIOP0(base), SCB_CU_STRT); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); /* address of scb_command */ + WL_WRITE_2(sc, PIOP0, SCB_CU_STRT); SET_CHAN_ATTN(sc); - outw(PIOR0(base), OFFSET_CU); + WL_WRITE_2(sc, PIOR0, OFFSET_CU); for (i = 0; i < 0xffff; i++) - if (inw(PIOP0(base)) & AC_SW_C) + if (WL_READ_2(sc, PIOP0) & AC_SW_C) break; - if (i == 0xffff || !(inw(PIOP0(base)) & AC_SW_OK)) { - printf("wl%d: %s failed; status = %d, inw = %x, outw = %x\n", - sc->unit, str, inw(PIOP0(base)) & AC_SW_OK, inw(PIOP0(base)), inw(PIOR0(base))); - outw(PIOR0(base), OFFSET_SCB); - printf("scb_status %x\n", inw(PIOP0(base))); - outw(PIOR0(base), OFFSET_SCB+2); - printf("scb_command %x\n", inw(PIOP0(base))); - outw(PIOR0(base), OFFSET_SCB+4); - printf("scb_cbl %x\n", inw(PIOP0(base))); - outw(PIOR0(base), OFFSET_CU+2); - printf("cu_cmd %x\n", inw(PIOP0(base))); + if (i == 0xffff || !(WL_READ_2(sc, PIOP0) & AC_SW_OK)) { + if_printf(sc->ifp, "%s failed; status = %d, inw = %x, outw = %x\n", + str, WL_READ_2(sc, PIOP0) & AC_SW_OK, WL_READ_2(sc, PIOP0), + WL_READ_2(sc, PIOR0)); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB); + printf("scb_status %x\n", WL_READ_2(sc, PIOP0)); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB+2); + printf("scb_command %x\n", WL_READ_2(sc, PIOP0)); + WL_WRITE_2(sc, PIOR0, OFFSET_SCB+4); + printf("scb_cbl %x\n", WL_READ_2(sc, PIOP0)); + WL_WRITE_2(sc, PIOR0, OFFSET_CU+2); + printf("cu_cmd %x\n", WL_READ_2(sc, PIOP0)); return(0); } - outw(PIOR0(base), OFFSET_SCB); - if ((inw(PIOP0(base)) & SCB_SW_INT) && (inw(PIOP0(base)) != SCB_SW_CNA)) { + WL_WRITE_2(sc, PIOR0, OFFSET_SCB); + if ((WL_READ_2(sc, PIOP0) & SCB_SW_INT) && + (WL_READ_2(sc, PIOP0) != SCB_SW_CNA)) { /* - printf("wl%d %s: unexpected final state %x\n", - sc->unit, str, inw(PIOP0(base))); + if_printf(sc->ifp, "%s: unexpected final state %x\n", + str, WL_READ_2(sc, PIOP0)); */ } wlack(sc); @@ -2205,22 +2189,21 @@ wlack(struct wl_softc *sc) { int i; u_short cmd; - short base = sc->base; - outw(PIOR1(base), OFFSET_SCB); - if (!(cmd = (inw(PIOP1(base)) & SCB_SW_INT))) + WL_WRITE_2(sc, PIOR1, OFFSET_SCB); + if (!(cmd = (WL_READ_2(sc, PIOP1) & SCB_SW_INT))) return(0); #ifdef WLDEBUG if (sc->ifp->if_flags & IFF_DEBUG) - printf("wl%d: doing a wlack()\n", sc->unit); + if_printf(sc->ifp, "doing a wlack()\n"); #endif - outw(PIOP1(base), cmd); + WL_WRITE_2(sc, PIOP1, cmd); SET_CHAN_ATTN(sc); - outw(PIOR0(base), OFFSET_SCB + 2); /* address of scb_command */ - for (i = 1000000; inw(PIOP0(base)) && (i-- > 0); ) + WL_WRITE_2(sc, PIOR0, OFFSET_SCB + 2); /* address of scb_command */ + for (i = 1000000; WL_READ_2(sc, PIOP0) && (i-- > 0); ) continue; if (i < 1) - printf("wl%d wlack(): board not accepting command.\n", sc->unit); + if_printf(sc->ifp, "wlack(): board not accepting command.\n"); return(cmd); } @@ -2228,15 +2211,14 @@ wlack(struct wl_softc *sc) static void wltbd(struct wl_softc *sc) { - short base = sc->base; u_short tbd_p = OFFSET_TBD; tbd_t tbd; int i = 0; int sum = 0; for (;;) { - outw(PIOR1(base), tbd_p); - insw(PIOP1(base), &tbd, sizeof(tbd_t)/2); + WL_WRITE_2(sc, PIOR1, tbd_p); + WL_READ_MULTI_2(sc, PIOP1, &tbd, sizeof(tbd_t)/2); sum += (tbd.act_count & ~TBD_SW_EOF); printf("%d: addr %x, count %d (%d), next %x, base %x\n", i++, tbd.buffer_addr, @@ -2323,37 +2305,36 @@ wlsftwsleaze(u_short *countp, u_char **mb_pp, struct mbuf **tm_pp, struct wl_sof static void wlmmcstat(struct wl_softc *sc) { - short base = sc->base; u_short tmp; - printf("wl%d: DCE_STATUS: 0x%x, ", sc->unit, - wlmmcread(base,MMC_DCE_STATUS) & 0x0f); - tmp = wlmmcread(base,MMC_CORRECT_NWID_H) << 8; - tmp |= wlmmcread(base,MMC_CORRECT_NWID_L); + device_printf(sc->dev, "DCE_STATUS: 0x%x, ", + wlmmcread(sc, MMC_DCE_STATUS) & 0x0f); + tmp = wlmmcread(sc, MMC_CORRECT_NWID_H) << 8; + tmp |= wlmmcread(sc, MMC_CORRECT_NWID_L); printf("Correct NWID's: %d, ", tmp); - tmp = wlmmcread(base,MMC_WRONG_NWID_H) << 8; - tmp |= wlmmcread(base,MMC_WRONG_NWID_L); + tmp = wlmmcread(sc, MMC_WRONG_NWID_H) << 8; + tmp |= wlmmcread(sc, MMC_WRONG_NWID_L); printf("Wrong NWID's: %d\n", tmp); - printf("THR_PRE_SET: 0x%x, ", wlmmcread(base,MMC_THR_PRE_SET)); + printf("THR_PRE_SET: 0x%x, ", wlmmcread(sc, MMC_THR_PRE_SET)); printf("SIGNAL_LVL: %d, SILENCE_LVL: %d\n", - wlmmcread(base,MMC_SIGNAL_LVL), - wlmmcread(base,MMC_SILENCE_LVL)); + wlmmcread(sc, MMC_SIGNAL_LVL), + wlmmcread(sc, MMC_SILENCE_LVL)); printf("SIGN_QUAL: 0x%x, NETW_ID: %x:%x, DES: %d\n", - wlmmcread(base,MMC_SIGN_QUAL), - wlmmcread(base,MMC_NETW_ID_H), - wlmmcread(base,MMC_NETW_ID_L), - wlmmcread(base,MMC_DES_AVAIL)); + wlmmcread(sc, MMC_SIGN_QUAL), + wlmmcread(sc, MMC_NETW_ID_H), + wlmmcread(sc, MMC_NETW_ID_L), + wlmmcread(sc, MMC_DES_AVAIL)); } static u_short -wlmmcread(u_int base, u_short reg) +wlmmcread(struct wl_softc *sc, u_short reg) { - while (inw(HASR(base)) & HASR_MMC_BUSY) + while (WL_READ_2(sc, HASR) & HASR_MMC_BUSY) continue; - outw(MMCR(base),reg << 1); - while (inw(HASR(base)) & HASR_MMC_BUSY) + WL_WRITE_2(sc, MMCR,reg << 1); + while (WL_READ_2(sc, HASR) & HASR_MMC_BUSY) continue; - return (u_short)inw(MMCR(base)) >> 8; + return (u_short)WL_READ_2(sc, MMCR) >> 8; } static void @@ -2363,8 +2344,8 @@ getsnr(struct wl_softc *sc) /* * SNR retrieval procedure : * - * read signal level : wlmmcread(base, MMC_SIGNAL_LVL); - * read silence level : wlmmcread(base, MMC_SILENCE_LVL); + * read signal level : wlmmcread(sc, MMC_SIGNAL_LVL); + * read silence level : wlmmcread(sc, MMC_SILENCE_LVL); */ MMC_WRITE(MMC_FREEZE,0); /* @@ -2375,22 +2356,22 @@ getsnr(struct wl_softc *sc) /* ** wlgetpsa ** -** Reads the psa for the wavelan at (base) into (buf) +** Reads the psa for the wavelan at (sc) into (buf) */ static void -wlgetpsa(int base, u_char *buf) +wlgetpsa(struct wl_softc *sc, u_char *buf) { int i; - PCMD(base, HACR_DEFAULT & ~HACR_16BITS); - PCMD(base, HACR_DEFAULT & ~HACR_16BITS); + PCMD(sc, HACR_DEFAULT & ~HACR_16BITS); + PCMD(sc, HACR_DEFAULT & ~HACR_16BITS); for (i = 0; i < 0x40; i++) { - outw(PIOR2(base), i); - buf[i] = inb(PIOP2(base)); + WL_WRITE_2(sc, PIOR2, i); + buf[i] = WL_READ_1(sc, PIOP2); } - PCMD(base, HACR_DEFAULT); - PCMD(base, HACR_DEFAULT); + PCMD(sc, HACR_DEFAULT); + PCMD(sc, HACR_DEFAULT); } /* @@ -2405,8 +2386,7 @@ wlgetpsa(int base, u_char *buf) static void wlsetpsa(struct wl_softc *sc) { - short base = sc->base; - int i, oldpri; + int i; u_short crc; crc = wlpsacrc(sc->psa); /* calculate CRC of PSA */ @@ -2414,28 +2394,24 @@ wlsetpsa(struct wl_softc *sc) sc->psa[WLPSA_CRCHIGH] = (crc >> 8) & 0xff; sc->psa[WLPSA_CRCOK] = 0x55; /* default to 'bad' until programming complete */ - oldpri = splimp(); /* ick, long pause */ - - PCMD(base, HACR_DEFAULT & ~HACR_16BITS); - PCMD(base, HACR_DEFAULT & ~HACR_16BITS); + PCMD(sc, HACR_DEFAULT & ~HACR_16BITS); + PCMD(sc, HACR_DEFAULT & ~HACR_16BITS); for (i = 0; i < 0x40; i++) { DELAY(DELAYCONST); - outw(PIOR2(base),i); /* write param memory */ + WL_WRITE_2(sc, PIOR2, i); /* write param memory */ DELAY(DELAYCONST); - outb(PIOP2(base), sc->psa[i]); + WL_WRITE_1(sc, PIOP2, sc->psa[i]); } DELAY(DELAYCONST); - outw(PIOR2(base),WLPSA_CRCOK); /* update CRC flag*/ + WL_WRITE_2(sc, PIOR2, WLPSA_CRCOK); /* update CRC flag*/ DELAY(DELAYCONST); sc->psa[WLPSA_CRCOK] = 0xaa; /* OK now */ - outb(PIOP2(base), 0xaa); /* all OK */ + WL_WRITE_1(sc, PIOP2, 0xaa); /* all OK */ DELAY(DELAYCONST); - PCMD(base, HACR_DEFAULT); - PCMD(base, HACR_DEFAULT); - - splx(oldpri); + PCMD(sc, HACR_DEFAULT); + PCMD(sc, HACR_DEFAULT); } /* @@ -2525,8 +2501,8 @@ wl_cache_zero(struct wl_softc *sc) * throw out non-ip (on by default, but can be turned off) */ static -void wl_cache_store (struct wl_softc *sc, int base, struct ether_header *eh, - struct mbuf *m) +void wl_cache_store (struct wl_softc *sc, struct ether_header *eh, + struct mbuf *m) { #ifdef INET struct ip *ip = NULL; /* Avoid GCC warning */ @@ -2630,9 +2606,9 @@ void wl_cache_store (struct wl_softc *sc, int base, struct ether_header *eh, sc->w_sigcache[w_insertcache].ipsrc = ip->ip_src.s_addr; } bcopy( eh->ether_shost, sc->w_sigcache[w_insertcache].macsrc, 6); - signal = sc->w_sigcache[w_insertcache].signal = wlmmcread(base, MMC_SIGNAL_LVL) & 0x3f; - silence = sc->w_sigcache[w_insertcache].silence = wlmmcread(base, MMC_SILENCE_LVL) & 0x3f; - sc->w_sigcache[w_insertcache].quality = wlmmcread(base, MMC_SIGN_QUAL) & 0x0f; + signal = sc->w_sigcache[w_insertcache].signal = wlmmcread(sc, MMC_SIGNAL_LVL) & 0x3f; + silence = sc->w_sigcache[w_insertcache].silence = wlmmcread(sc, MMC_SILENCE_LVL) & 0x3f; + sc->w_sigcache[w_insertcache].quality = wlmmcread(sc, MMC_SIGN_QUAL) & 0x0f; if (signal > 0) sc->w_sigcache[w_insertcache].snr = signal - silence; diff --git a/sys/dev/wl/if_wl.h b/sys/dev/wl/if_wl.h index e883b782b04..77a24cc12bd 100644 --- a/sys/dev/wl/if_wl.h +++ b/sys/dev/wl/if_wl.h @@ -57,15 +57,15 @@ typedef struct { /* WaveLAN host interface definitions */ -#define HACR(base) (base) /* Host Adapter Command Register */ -#define HASR(base) (base) /* Host Adapter Status Register */ -#define MMCR(base) (base+0x2) /* Modem Management Ctrl Register */ -#define PIOR0(base) (base+0x4) /* Program I/O Address Register 0 */ -#define PIOP0(base) (base+0x6) /* Program I/O Port 0 */ -#define PIOR1(base) (base+0x8) /* Program I/O Address Register 1 */ -#define PIOP1(base) (base+0xa) /* Program I/O Port 1 */ -#define PIOR2(base) (base+0xc) /* Program I/O Address Register 2 */ -#define PIOP2(base) (base+0xe) /* Program I/O Port 2 */ +#define HACR 0x0 /* Host Adapter Command Register */ +#define HASR 0x0 /* Host Adapter Status Register */ +#define MMCR 0x2 /* Modem Management Ctrl Register */ +#define PIOR0 0x4 /* Program I/O Address Register 0 */ +#define PIOP0 0x6 /* Program I/O Port 0 */ +#define PIOR1 0x8 /* Program I/O Address Register 1 */ +#define PIOP1 0xa /* Program I/O Port 1 */ +#define PIOR2 0xc /* Program I/O Address Register 2 */ +#define PIOP2 0xe /* Program I/O Port 2 */ /* Program I/O Mode Register values */ @@ -96,9 +96,21 @@ typedef struct { #define HACR_DEFAULT (HACR_OUT1 | HACR_OUT2 | HACR_16BITS | PIOM(STATIC_PIO, 0) | PIOM(AUTOINCR_PIO, 1) | PIOM(PARAM_ACCESS_PIO, 2)) #define HACR_INTRON (HACR_MASK_82586 | HACR_MASK_MMC | HACR_INTR_CLEN) -#define CMD(sc) \ + +#define WL_READ_1(sc, reg) bus_read_1((sc)->res_ioport, (reg)) +#define WL_READ_2(sc, reg) bus_read_2((sc)->res_ioport, (reg)) +#define WL_READ_MULTI_2(sc, reg, buf, len) \ + bus_read_multi_2((sc)->res_ioport, (reg), (uint16_t *)(buf), (len)) +#define WL_WRITE_1(sc, reg, val) \ + bus_write_1((sc)->res_ioport, (reg), (val)) +#define WL_WRITE_2(sc, reg, val) \ + bus_write_2((sc)->res_ioport, (reg), (val)) +#define WL_WRITE_MULTI_2(sc, reg, buf, len) \ + bus_write_multi_2((sc)->res_ioport, (reg), (uint16_t *)(buf), (len)) + +#define CMD(sc) \ { \ - outw(HACR(sc->base),sc->hacr); \ + WL_WRITE_2(sc, HACR, sc->hacr); \ /* delay for 50 us, might only be needed sometimes */ \ DELAY(DELAYCONST); \ } @@ -108,13 +120,13 @@ typedef struct { */ #define SET_CHAN_ATTN(sc) \ { \ - outw(HACR(sc->base),sc->hacr | HACR_CA); \ + WL_WRITE_2(sc, HACR, sc->hacr | HACR_CA); \ } #define MMC_WRITE(cmd,val) \ - while(inw(HASR(sc->base)) & HASR_MMC_BUSY) ; \ - outw(MMCR(sc->base), \ + while (WL_READ_2(sc, HASR) & HASR_MMC_BUSY) ; \ + WL_WRITE_2(sc, MMCR, \ (u_short)(((u_short)(val) << 8) | ((cmd) << 1) | 1)) #endif /* _IF_WL_H */ diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index 201e5d632ce..a749f90c154 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); */ #include "opt_inet.h" #include "opt_inet6.h" -#include "opt_global.h" #include "opt_sctp.h" diff --git a/sys/fs/ext2fs/ext2_extern.h b/sys/fs/ext2fs/ext2_extern.h index 5edac90e03d..93bd3f7cd0f 100644 --- a/sys/fs/ext2fs/ext2_extern.h +++ b/sys/fs/ext2fs/ext2_extern.h @@ -74,7 +74,9 @@ int ext2_vfree(struct vnode *, ino_t, int); int ext2_vinit(struct mount *, struct vop_vector *, struct vnode **vpp); int ext2_lookup(struct vop_cachedlookup_args *); int ext2_readdir(struct vop_readdir_args *); +#ifdef EXT2FS_DEBUG void ext2_print_inode(struct inode *); +#endif int ext2_direnter(struct inode *, struct vnode *, struct componentname *); int ext2_dirremove(struct vnode *, struct componentname *); diff --git a/sys/fs/ext2fs/ext2_inode_cnv.c b/sys/fs/ext2fs/ext2_inode_cnv.c index cce03d8d165..b69d4e5c8b6 100644 --- a/sys/fs/ext2fs/ext2_inode_cnv.c +++ b/sys/fs/ext2fs/ext2_inode_cnv.c @@ -41,6 +41,7 @@ #define XTIME_TO_NSEC(x) ((x & EXT3_NSEC_MASK) >> 2) #define NSEC_TO_XTIME(t) (le32toh(t << 2) & EXT3_NSEC_MASK) +#ifdef EXT2FS_DEBUG void ext2_print_inode(struct inode *in) { @@ -75,6 +76,7 @@ ext2_print_inode(struct inode *in) ep->e_len, ep->e_start_lo, ep->e_start_hi); printf("\n"); } +#endif /* EXT2FS_DEBUG */ /* * raw ext2 inode to inode diff --git a/sys/fs/ext2fs/ext2_vfsops.c b/sys/fs/ext2fs/ext2_vfsops.c index b05070d3261..b97356d072a 100644 --- a/sys/fs/ext2fs/ext2_vfsops.c +++ b/sys/fs/ext2fs/ext2_vfsops.c @@ -974,9 +974,9 @@ ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) for (i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) ip->i_db[i] = 0; } -/* +#ifdef EXT2FS_DEBUG ext2_print_inode(ip); -*/ +#endif bqrelse(bp); /* diff --git a/sys/geom/bde/g_bde.c b/sys/geom/bde/g_bde.c index e882bb83c6e..93d77336ed7 100644 --- a/sys/geom/bde/g_bde.c +++ b/sys/geom/bde/g_bde.c @@ -204,6 +204,23 @@ g_bde_create_geom(struct gctl_req *req, struct g_class *mp, struct g_provider *p if (gp->softc != NULL) g_free(gp->softc); g_destroy_geom(gp); + switch (error) { + case ENOENT: + gctl_error(req, "Lock was destroyed"); + break; + case ESRCH: + gctl_error(req, "Lock was nuked"); + break; + case EINVAL: + gctl_error(req, "Could not open lock"); + break; + case ENOTDIR: + gctl_error(req, "Lock not found"); + break; + default: + gctl_error(req, "Could not open lock (%d)", error); + break; + } return; } diff --git a/sys/geom/bde/g_bde.h b/sys/geom/bde/g_bde.h index 9332c6b2706..2f29fe32c87 100644 --- a/sys/geom/bde/g_bde.h +++ b/sys/geom/bde/g_bde.h @@ -182,7 +182,7 @@ AES_init(cipherInstance *ci) } static __inline void -AES_makekey(keyInstance *ki, int dir, u_int len, void *key) +AES_makekey(keyInstance *ki, int dir, u_int len, const void *key) { int error; @@ -191,7 +191,7 @@ AES_makekey(keyInstance *ki, int dir, u_int len, void *key) } static __inline void -AES_encrypt(cipherInstance *ci, keyInstance *ki, void *in, void *out, u_int len) +AES_encrypt(cipherInstance *ci, keyInstance *ki, const void *in, void *out, u_int len) { int error; @@ -200,7 +200,7 @@ AES_encrypt(cipherInstance *ci, keyInstance *ki, void *in, void *out, u_int len) } static __inline void -AES_decrypt(cipherInstance *ci, keyInstance *ki, void *in, void *out, u_int len) +AES_decrypt(cipherInstance *ci, keyInstance *ki, const void *in, void *out, u_int len) { int error; diff --git a/sys/geom/geom_dev.c b/sys/geom/geom_dev.c index 7cb756befb8..6380e407f0e 100644 --- a/sys/geom/geom_dev.c +++ b/sys/geom/geom_dev.c @@ -127,14 +127,14 @@ g_dev_fini(struct g_class *mp) } static int -g_dev_setdumpdev(struct cdev *dev) +g_dev_setdumpdev(struct cdev *dev, struct thread *td) { struct g_kerneldump kd; struct g_consumer *cp; int error, len; if (dev == NULL) - return (set_dumper(NULL, NULL)); + return (set_dumper(NULL, NULL, td)); cp = dev->si_drv2; len = sizeof(kd); @@ -142,7 +142,7 @@ g_dev_setdumpdev(struct cdev *dev) kd.length = OFF_MAX; error = g_io_getattr("GEOM::kerneldump", cp, &len, &kd); if (error == 0) { - error = set_dumper(&kd.di, devtoname(dev)); + error = set_dumper(&kd.di, devtoname(dev), td); if (error == 0) dev->si_flags |= SI_DUMPDEV; } @@ -157,7 +157,7 @@ init_dumpdev(struct cdev *dev) return; if (strcmp(devtoname(dev), dumpdev) != 0) return; - if (g_dev_setdumpdev(dev) == 0) { + if (g_dev_setdumpdev(dev, curthread) == 0) { freeenv(dumpdev); dumpdev = NULL; } @@ -453,9 +453,9 @@ g_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread break; case DIOCSKERNELDUMP: if (*(u_int *)data == 0) - error = g_dev_setdumpdev(NULL); + error = g_dev_setdumpdev(NULL, td); else - error = g_dev_setdumpdev(dev); + error = g_dev_setdumpdev(dev, td); break; case DIOCGFLUSH: error = g_io_flush(cp); @@ -673,7 +673,7 @@ g_dev_orphan(struct g_consumer *cp) /* Reset any dump-area set on this device */ if (dev->si_flags & SI_DUMPDEV) - (void)set_dumper(NULL, NULL); + (void)set_dumper(NULL, NULL, curthread); /* Destroy the struct cdev *so we get no more requests */ destroy_dev_sched_cb(dev, g_dev_callback, cp); diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c index 9a1730b0e70..58082367b03 100644 --- a/sys/geom/part/g_part.c +++ b/sys/geom/part/g_part.c @@ -143,6 +143,7 @@ static g_orphan_t g_part_orphan; static g_spoiled_t g_part_spoiled; static g_start_t g_part_start; static g_resize_t g_part_resize; +static g_ioctl_t g_part_ioctl; static struct g_class g_part_class = { .name = "PART", @@ -159,7 +160,8 @@ static struct g_class g_part_class = { .orphan = g_part_orphan, .spoiled = g_part_spoiled, .start = g_part_start, - .resize = g_part_resize + .resize = g_part_resize, + .ioctl = g_part_ioctl, }; DECLARE_GEOM_CLASS(g_part_class, g_part); @@ -2059,6 +2061,25 @@ g_part_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, } } +/*- + * This start routine is only called for non-trivial requests, all the + * trivial ones are handled autonomously by the slice code. + * For requests we handle here, we must call the g_io_deliver() on the + * bio, and return non-zero to indicate to the slice code that we did so. + * This code executes in the "DOWN" I/O path, this means: + * * No sleeping. + * * Don't grab the topology lock. + * * Don't call biowait, g_getattr(), g_setattr() or g_read_data() + */ +static int +g_part_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td) +{ + struct g_part_table *table; + + table = pp->geom->softc; + return G_PART_IOCTL(table, pp, cmd, data, fflag, td); +} + static void g_part_resize(struct g_consumer *cp) { diff --git a/sys/geom/part/g_part_bsd.c b/sys/geom/part/g_part_bsd.c index 5a5eabd3193..e9f09c2108f 100644 --- a/sys/geom/part/g_part_bsd.c +++ b/sys/geom/part/g_part_bsd.c @@ -83,6 +83,8 @@ static const char *g_part_bsd_type(struct g_part_table *, struct g_part_entry *, static int g_part_bsd_write(struct g_part_table *, struct g_consumer *); static int g_part_bsd_resize(struct g_part_table *, struct g_part_entry *, struct g_part_parms *); +static int g_part_bsd_ioctl(struct g_part_table *, struct g_provider *, + u_long cmd, void *data, int fflag, struct thread *td); static kobj_method_t g_part_bsd_methods[] = { KOBJMETHOD(g_part_add, g_part_bsd_add), @@ -98,6 +100,7 @@ static kobj_method_t g_part_bsd_methods[] = { KOBJMETHOD(g_part_read, g_part_bsd_read), KOBJMETHOD(g_part_type, g_part_bsd_type), KOBJMETHOD(g_part_write, g_part_bsd_write), + KOBJMETHOD(g_part_ioctl, g_part_bsd_ioctl), { 0, 0 } }; @@ -494,6 +497,38 @@ g_part_bsd_type(struct g_part_table *basetable, struct g_part_entry *baseentry, return (buf); } +/*- + * This start routine is only called for non-trivial requests, all the + * trivial ones are handled autonomously by the slice code. + * For requests we handle here, we must call the g_io_deliver() on the + * bio, and return non-zero to indicate to the slice code that we did so. + * This code executes in the "DOWN" I/O path, this means: + * * No sleeping. + * * Don't grab the topology lock. + * * Don't call biowait, g_getattr(), g_setattr() or g_read_data() + */ +static int +g_part_bsd_ioctl(struct g_part_table *basetable, struct g_provider *pp, + u_long cmd, void *data, int fflag, struct thread *td) +{ + + switch (cmd) + { + case DIOCGDINFO: + { + struct g_part_bsd_table *table; + u_char *p; + + table = (struct g_part_bsd_table *)basetable; + p = table->bbarea + pp->sectorsize; + return (bsd_disklabel_le_dec(p, data, MAXPARTITIONS)); + } + default: + return (ENOIOCTL); + + } +} + static int g_part_bsd_write(struct g_part_table *basetable, struct g_consumer *cp) { diff --git a/sys/geom/part/g_part_if.m b/sys/geom/part/g_part_if.m index 4152e87fb02..31c1d657ed9 100644 --- a/sys/geom/part/g_part_if.m +++ b/sys/geom/part/g_part_if.m @@ -71,6 +71,14 @@ CODE { { return (ENOSYS); } + + static int + default_ioctl(struct g_part_table *table __unused, struct g_provider *pp __unused, + u_long cmd __unused, void *data __unused, int fflag __unused, + struct thread *td __unused) + { + return (ENOIOCTL); + } }; # add() - scheme specific processing for the add verb. @@ -120,6 +128,16 @@ METHOD void fullname { const char *pfx; } DEFAULT default_fullname; +# ioctl() - implement historic ioctls, perhaps. +METHOD int ioctl { + struct g_part_table *table; + struct g_provider *pp; + u_long cmd; + void *data; + int fflag; + struct thread *td; +} DEFAULT default_ioctl; + # modify() - scheme specific processing for the modify verb. METHOD int modify { struct g_part_table *table; diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index b01af819398..889a20a7fe3 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -318,7 +318,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/i386/conf/XBOX b/sys/i386/conf/XBOX index fb6a5c1570f..73f81e44cc6 100644 --- a/sys/i386/conf/XBOX +++ b/sys/i386/conf/XBOX @@ -66,7 +66,6 @@ device ether # Ethernet support #device tun # Packet tunnel. #device md # Memory "disks" #device gif # IPv6 and IPv4 tunneling -#device faith # IPv6-to-IPv4 relaying (translation) # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/sys/i386/conf/XEN b/sys/i386/conf/XEN index 62bbbb6ba3f..108224cd557 100644 --- a/sys/i386/conf/XEN +++ b/sys/i386/conf/XEN @@ -82,7 +82,6 @@ device ether # Ethernet support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) # Wireless cards options IEEE80211_SUPPORT_MESH diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 851372430e0..68b44e955a1 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -374,6 +374,15 @@ pmap_bootstrap(vm_paddr_t firstaddr) struct sysmaps *sysmaps; int i; + /* + * Add a physical memory segment (vm_phys_seg) corresponding to the + * preallocated kernel page table pages so that vm_page structures + * representing these pages will be created. The vm_page structures + * are required for promotion of the corresponding kernel virtual + * addresses to superpage mappings. + */ + vm_phys_add_seg(KPTphys, KPTphys + ptoa(nkpt)); + /* * Initialize the first available kernel virtual address. However, * using "firstaddr" may waste a few pages of the kernel virtual diff --git a/sys/i386/ibcs2/ibcs2_fcntl.c b/sys/i386/ibcs2/ibcs2_fcntl.c index d2489dfb996..5d06d4d32e9 100644 --- a/sys/i386/ibcs2/ibcs2_fcntl.c +++ b/sys/i386/ibcs2/ibcs2_fcntl.c @@ -189,7 +189,7 @@ ibcs2_open(td, uap) CHECKALTCREAT(td, uap->path, &path); else CHECKALTEXIST(td, uap->path, &path); - ret = kern_open(td, path, UIO_SYSSPACE, flags, uap->mode); + ret = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, flags, uap->mode); #ifdef SPX_HACK if (ret == ENXIO) { @@ -230,8 +230,8 @@ ibcs2_creat(td, uap) int error; CHECKALTCREAT(td, uap->path, &path); - error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC, - uap->mode); + error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, + O_WRONLY | O_CREAT | O_TRUNC, uap->mode); free(path, M_TEMP); return (error); } @@ -245,7 +245,7 @@ ibcs2_access(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_access(td, path, UIO_SYSSPACE, uap->amode); + error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, uap->amode); free(path, M_TEMP); return (error); } diff --git a/sys/i386/ibcs2/ibcs2_misc.c b/sys/i386/ibcs2/ibcs2_misc.c index 42bc4b77579..d81cfeeb97f 100644 --- a/sys/i386/ibcs2/ibcs2_misc.c +++ b/sys/i386/ibcs2/ibcs2_misc.c @@ -646,10 +646,13 @@ ibcs2_mknod(td, uap) int error; CHECKALTCREAT(td, uap->path, &path); - if (S_ISFIFO(uap->mode)) - error = kern_mkfifo(td, path, UIO_SYSSPACE, uap->mode); - else - error = kern_mknod(td, path, UIO_SYSSPACE, uap->mode, uap->dev); + if (S_ISFIFO(uap->mode)) { + error = kern_mkfifoat(td, AT_FDCWD, path, + UIO_SYSSPACE, uap->mode); + } else { + error = kern_mknodat(td, AT_FDCWD, path, UIO_SYSSPACE, + uap->mode, uap->dev); + } free(path, M_TEMP); return (error); } @@ -938,7 +941,8 @@ ibcs2_utime(td, uap) tp = NULL; CHECKALTEXIST(td, uap->path, &path); - error = kern_utimes(td, path, UIO_SYSSPACE, tp, UIO_SYSSPACE); + error = kern_utimesat(td, AT_FDCWD, path, UIO_SYSSPACE, + tp, UIO_SYSSPACE); free(path, M_TEMP); return (error); } @@ -1119,7 +1123,7 @@ ibcs2_unlink(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_unlink(td, path, UIO_SYSSPACE); + error = kern_unlinkat(td, AT_FDCWD, path, UIO_SYSSPACE, 0); free(path, M_TEMP); return (error); } @@ -1147,7 +1151,7 @@ ibcs2_chmod(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_chmod(td, path, UIO_SYSSPACE, uap->mode); + error = kern_fchmodat(td, AT_FDCWD, path, UIO_SYSSPACE, uap->mode, 0); free(path, M_TEMP); return (error); } @@ -1161,7 +1165,8 @@ ibcs2_chown(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_chown(td, path, UIO_SYSSPACE, uap->uid, uap->gid); + error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, uap->uid, + uap->gid, 0); free(path, M_TEMP); return (error); } @@ -1175,7 +1180,7 @@ ibcs2_rmdir(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_rmdir(td, path, UIO_SYSSPACE); + error = kern_rmdirat(td, AT_FDCWD, path, UIO_SYSSPACE); free(path, M_TEMP); return (error); } @@ -1189,7 +1194,7 @@ ibcs2_mkdir(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_mkdir(td, path, UIO_SYSSPACE, uap->mode); + error = kern_mkdirat(td, AT_FDCWD, path, UIO_SYSSPACE, uap->mode); free(path, M_TEMP); return (error); } @@ -1213,7 +1218,7 @@ ibcs2_symlink(td, uap) free(path, M_TEMP); return (error); } - error = kern_symlink(td, path, link, UIO_SYSSPACE); + error = kern_symlinkat(td, path, AT_FDCWD, link, UIO_SYSSPACE); free(path, M_TEMP); free(link, M_TEMP); return (error); @@ -1238,7 +1243,7 @@ ibcs2_rename(td, uap) free(from, M_TEMP); return (error); } - error = kern_rename(td, from, to, UIO_SYSSPACE); + error = kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, UIO_SYSSPACE); free(from, M_TEMP); free(to, M_TEMP); return (error); @@ -1253,8 +1258,8 @@ ibcs2_readlink(td, uap) int error; CHECKALTEXIST(td, uap->path, &path); - error = kern_readlink(td, path, UIO_SYSSPACE, uap->buf, UIO_USERSPACE, - uap->count); + error = kern_readlinkat(td, AT_FDCWD, path, UIO_SYSSPACE, + uap->buf, UIO_USERSPACE, uap->count); free(path, M_TEMP); return (error); } diff --git a/sys/i386/ibcs2/ibcs2_other.c b/sys/i386/ibcs2/ibcs2_other.c index f688661ded5..b49e605eb23 100644 --- a/sys/i386/ibcs2/ibcs2_other.c +++ b/sys/i386/ibcs2/ibcs2_other.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -107,7 +108,7 @@ spx_open(struct thread *td) sun.sun_len = sizeof(struct sockaddr_un) - sizeof(sun.sun_path) + strlen(sun.sun_path) + 1; - error = kern_connect(td, fd, (struct sockaddr *)&sun); + error = kern_connectat(td, AT_FDCWD, fd, (struct sockaddr *)&sun); if (error) { kern_close(td, fd); return error; diff --git a/sys/i386/ibcs2/ibcs2_stat.c b/sys/i386/ibcs2/ibcs2_stat.c index c1097a320a5..55d14af99b5 100644 --- a/sys/i386/ibcs2/ibcs2_stat.c +++ b/sys/i386/ibcs2/ibcs2_stat.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -145,7 +146,7 @@ ibcs2_stat(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_stat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); @@ -166,7 +167,8 @@ ibcs2_lstat(td, uap) CHECKALTEXIST(td, uap->path, &path); - error = kern_lstat(td, path, UIO_SYSSPACE, &st); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, + UIO_SYSSPACE, &st, NULL); free(path, M_TEMP); if (error) return (error); diff --git a/sys/i386/ibcs2/ibcs2_xenix.c b/sys/i386/ibcs2/ibcs2_xenix.c index c5416fb6c52..829f6abba81 100644 --- a/sys/i386/ibcs2/ibcs2_xenix.c +++ b/sys/i386/ibcs2/ibcs2_xenix.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -209,7 +210,8 @@ xenix_eaccess(struct thread *td, struct xenix_eaccess_args *uap) bsd_flags |= X_OK; CHECKALTEXIST(td, uap->path, &path); - error = kern_eaccess(td, path, UIO_SYSSPACE, bsd_flags); + error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, + AT_EACCESS, bsd_flags); free(path, M_TEMP); return (error); } diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h index 975b30231b6..5dc56692adc 100644 --- a/sys/i386/include/vmparam.h +++ b/sys/i386/include/vmparam.h @@ -64,9 +64,15 @@ #endif /* - * The physical address space is densely populated. + * Choose between DENSE and SPARSE based on whether lower execution time or + * lower kernel address space consumption is desired. Under PAE, kernel + * address space is often in short supply. */ +#ifdef PAE +#define VM_PHYSSEG_SPARSE +#else #define VM_PHYSSEG_DENSE +#endif /* * The number of PHYSSEG entries must be one greater than the number diff --git a/sys/i386/isa/spic.c b/sys/i386/isa/spic.c index 70c1cc15b82..89ebb57e469 100644 --- a/sys/i386/isa/spic.c +++ b/sys/i386/isa/spic.c @@ -87,7 +87,6 @@ static d_poll_t spicpoll; static struct cdevsw spic_cdevsw = { .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, .d_open = spicopen, .d_close = spicclose, .d_read = spicread, @@ -106,8 +105,10 @@ struct spic_softc { int sc_opened; int sc_sleeping; int sc_buttonlast; - struct callout_handle sc_timeout_ch; + struct callout sc_timeout; + struct mtx sc_lock; device_t sc_dev; + struct cdev *sc_cdev; struct selinfo sc_rsel; u_char sc_buf[SCBUFLEN]; int sc_count; @@ -337,6 +338,8 @@ spic_attach(device_t dev) sc = device_get_softc(dev); sc->sc_dev = dev; + mtx_init(&sc->sc_lock, "spic", NULL, MTX_DEF); + callout_init_mtx(&sc->sc_timeout, &sc->sc_lock, 0); spic_pollrate = (hz/50); /* Every 50th of a second */ @@ -345,7 +348,8 @@ spic_attach(device_t dev) spic_call1(sc, 0x92); /* There can be only one */ - make_dev(&spic_cdevsw, 0, 0, 0, 0600, "jogdial"); + sc->sc_cdev = make_dev(&spic_cdevsw, 0, 0, 0, 0600, "jogdial"); + sc->sc_cdev->si_drv1 = sc; return 0; } @@ -357,6 +361,7 @@ spictimeout(void *arg) u_char b, event, param; int j; + mtx_assert(&sc->sc_lock, MA_OWNED); if (!sc->sc_opened) { device_printf(sc->sc_dev, "timeout called while closed!\n"); return; @@ -426,7 +431,7 @@ spictimeout(void *arg) } else { /* No event. Wait some more */ - sc->sc_timeout_ch = timeout(spictimeout, sc, spic_pollrate); + callout_reset(&sc->sc_timeout, spic_pollrate, spictimeout, sc); return; } @@ -439,7 +444,7 @@ spictimeout(void *arg) } spic_call2(sc, 0x81, 0xff); /* Clear event */ - sc->sc_timeout_ch = timeout(spictimeout, sc, spic_pollrate); + callout_reset(&sc->sc_timeout, spic_pollrate, spictimeout, sc); } static int @@ -447,17 +452,21 @@ spicopen(struct cdev *dev, int flag, int fmt, struct thread *td) { struct spic_softc *sc; - sc = devclass_get_softc(spic_devclass, 0); + sc = dev->si_drv1; - if (sc->sc_opened) - return EBUSY; + mtx_lock(&sc->sc_lock); + if (sc->sc_opened) { + mtx_unlock(&sc->sc_lock); + return (EBUSY); + } sc->sc_opened++; sc->sc_count=0; /* Start the polling */ - timeout(spictimeout, sc, spic_pollrate); - return 0; + callout_reset(&sc->sc_timeout, spic_pollrate, spictimeout, sc); + mtx_unlock(&sc->sc_lock); + return (0); } static int @@ -465,11 +474,13 @@ spicclose(struct cdev *dev, int flag, int fmt, struct thread *td) { struct spic_softc *sc; - sc = devclass_get_softc(spic_devclass, 0); + sc = dev->si_drv1; + mtx_lock(&sc->sc_lock); /* Stop polling */ - untimeout(spictimeout, sc, sc->sc_timeout_ch); + callout_stop(&sc->sc_timeout); sc->sc_opened = 0; + mtx_unlock(&sc->sc_lock); return 0; } @@ -477,34 +488,31 @@ static int spicread(struct cdev *dev, struct uio *uio, int flag) { struct spic_softc *sc; - int l, s, error; + int l, error; u_char buf[SCBUFLEN]; - sc = devclass_get_softc(spic_devclass, 0); + sc = dev->si_drv1; if (uio->uio_resid <= 0) /* What kind of a read is this?! */ - return 0; + return (0); - s = spltty(); + mtx_lock(&sc->sc_lock); while (!(sc->sc_count)) { sc->sc_sleeping=1; - error = tsleep( sc, PZERO | PCATCH, "jogrea", 0); + error = mtx_sleep(sc, &sc->sc_lock, PZERO | PCATCH, "jogrea", 0); sc->sc_sleeping=0; if (error) { - splx(s); - return error; + mtx_unlock(&sc->sc_lock); + return (error); } } - splx(s); - s = spltty(); l = min(uio->uio_resid, sc->sc_count); bcopy(sc->sc_buf, buf, l); sc->sc_count -= l; bcopy(sc->sc_buf + l, sc->sc_buf, l); - splx(s); - return uiomove(buf, l, uio); - + mtx_unlock(&sc->sc_lock); + return (uiomove(buf, l, uio)); } static int @@ -512,28 +520,28 @@ spicioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *t { struct spic_softc *sc; - sc = devclass_get_softc(spic_devclass, 0); + sc = dev->si_drv1; - return EIO; + return (EIO); } static int spicpoll(struct cdev *dev, int events, struct thread *td) { struct spic_softc *sc; - int revents = 0, s; + int revents = 0; - sc = devclass_get_softc(spic_devclass, 0); - s = spltty(); + sc = dev->si_drv1; + mtx_lock(&sc->sc_lock); if (events & (POLLIN | POLLRDNORM)) { if (sc->sc_count) revents |= events & (POLLIN | POLLRDNORM); else selrecord(td, &sc->sc_rsel); /* Who shall we wake? */ } - splx(s); + mtx_unlock(&sc->sc_lock); - return revents; + return (revents); } diff --git a/sys/i386/xen/locore.s b/sys/i386/xen/locore.s index b67046e50ab..7e676846321 100644 --- a/sys/i386/xen/locore.s +++ b/sys/i386/xen/locore.s @@ -42,7 +42,6 @@ #include "opt_bootp.h" #include "opt_compat.h" #include "opt_nfsroot.h" -#include "opt_global.h" #include "opt_pmap.h" #include diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 9246904f1cf..a065b75bfda 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -527,7 +527,7 @@ proc0_init(void *dummy __unused) siginit(&proc0); /* Create the file descriptor table. */ - p->p_fd = fdinit(NULL); + p->p_fd = fdinit(NULL, false); p->p_fdtol = NULL; /* Create the limits structures. */ diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 3decfd412ad..f85703e4e81 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/kern/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ #include "opt_compat.h" @@ -579,4 +579,5 @@ struct sysent sysent[] = { { AS(pipe2_args), (sy_call_t *)sys_pipe2, AUE_PIPE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 542 = pipe2 */ { AS(aio_mlock_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 543 = aio_mlock */ { AS(procctl_args), (sy_call_t *)sys_procctl, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 544 = procctl */ + { AS(ppoll_args), (sy_call_t *)sys_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = ppoll */ }; diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 3d232cf744c..79a294d37e3 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -668,11 +668,11 @@ stopprofclock(p) PROC_LOCK_ASSERT(p, MA_OWNED); if (p->p_flag & P_PROFIL) { if (p->p_profthreads != 0) { - p->p_flag |= P_STOPPROF; - while (p->p_profthreads != 0) + while (p->p_profthreads != 0) { + p->p_flag |= P_STOPPROF; msleep(&p->p_profthreads, &p->p_mtx, PPAUSE, "stopprof", 0); - p->p_flag &= ~P_STOPPROF; + } } if ((p->p_flag & P_PROFIL) == 0) return; diff --git a/sys/kern/kern_cons.c b/sys/kern/kern_cons.c index 9b7aeaae38a..bbc0e517092 100644 --- a/sys/kern/kern_cons.c +++ b/sys/kern/kern_cons.c @@ -156,6 +156,13 @@ cninit(void) * Make the best console the preferred console. */ cnselect(best_cn); + +#ifdef EARLY_PRINTF + /* + * Release early console. + */ + early_putc = NULL; +#endif } void diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 32c837c57c1..227a531f34f 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1797,7 +1797,7 @@ finstall(struct thread *td, struct file *fp, int *fd, int flags, * If fdp is not NULL, return with it shared locked. */ struct filedesc * -fdinit(struct filedesc *fdp) +fdinit(struct filedesc *fdp, bool prepfiles) { struct filedesc0 *newfdp0; struct filedesc *newfdp; @@ -1818,7 +1818,7 @@ fdinit(struct filedesc *fdp) if (fdp == NULL) return (newfdp); - if (fdp->fd_lastfile >= newfdp->fd_nfiles) + if (prepfiles && fdp->fd_lastfile >= newfdp->fd_nfiles) fdgrowtable(newfdp, fdp->fd_lastfile + 1); FILEDESC_SLOCK(fdp); @@ -1832,10 +1832,14 @@ fdinit(struct filedesc *fdp) if (newfdp->fd_jdir) VREF(newfdp->fd_jdir); - while (fdp->fd_lastfile >= newfdp->fd_nfiles) { + if (!prepfiles) { FILEDESC_SUNLOCK(fdp); - fdgrowtable(newfdp, fdp->fd_lastfile + 1); - FILEDESC_SLOCK(fdp); + } else { + while (fdp->fd_lastfile >= newfdp->fd_nfiles) { + FILEDESC_SUNLOCK(fdp); + fdgrowtable(newfdp, fdp->fd_lastfile + 1); + FILEDESC_SLOCK(fdp); + } } return (newfdp); @@ -1914,7 +1918,7 @@ fdcopy(struct filedesc *fdp) MPASS(fdp != NULL); - newfdp = fdinit(fdp); + newfdp = fdinit(fdp, true); /* copy all passable descriptors (i.e. not kqueue) */ newfdp->fd_freefile = -1; for (i = 0; i <= fdp->fd_lastfile; ++i) { @@ -2215,8 +2219,8 @@ fdcheckstd(struct thread *td) if (devnull != -1) { error = do_dup(td, DUP_FIXED, devnull, i); } else { - error = kern_open(td, "/dev/null", UIO_SYSSPACE, - O_RDWR, 0); + error = kern_openat(td, AT_FDCWD, "/dev/null", + UIO_SYSSPACE, O_RDWR, 0); if (error == 0) { devnull = td->td_retval[0]; KASSERT(devnull == i, ("we didn't get our fd")); @@ -3684,7 +3688,7 @@ badfo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred, static int badfo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags, - int kflags, struct sendfile_sync *sfs, struct thread *td) + int kflags, struct thread *td) { return (EBADF); @@ -3770,7 +3774,7 @@ invfo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred, int invfo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags, - int kflags, struct sendfile_sync *sfs, struct thread *td) + int kflags, struct thread *td) { return (EINVAL); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 55bffe77a9a..e01f12c7d1b 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -281,19 +281,20 @@ MTX_SYSINIT(kqueue_filterops, &filterops_lock, "protect sysfilt_ops", MTX_DEF); static struct { struct filterops *for_fop; + int for_nolock; int for_refcnt; } sysfilt_ops[EVFILT_SYSCOUNT] = { - { &file_filtops }, /* EVFILT_READ */ - { &file_filtops }, /* EVFILT_WRITE */ + { &file_filtops, 1 }, /* EVFILT_READ */ + { &file_filtops, 1 }, /* EVFILT_WRITE */ { &null_filtops }, /* EVFILT_AIO */ - { &file_filtops }, /* EVFILT_VNODE */ - { &proc_filtops }, /* EVFILT_PROC */ - { &sig_filtops }, /* EVFILT_SIGNAL */ - { &timer_filtops }, /* EVFILT_TIMER */ - { &file_filtops }, /* EVFILT_PROCDESC */ - { &fs_filtops }, /* EVFILT_FS */ + { &file_filtops, 1 }, /* EVFILT_VNODE */ + { &proc_filtops, 1 }, /* EVFILT_PROC */ + { &sig_filtops, 1 }, /* EVFILT_SIGNAL */ + { &timer_filtops, 1 }, /* EVFILT_TIMER */ + { &file_filtops, 1 }, /* EVFILT_PROCDESC */ + { &fs_filtops, 1 }, /* EVFILT_FS */ { &null_filtops }, /* EVFILT_LIO */ - { &user_filtops }, /* EVFILT_USER */ + { &user_filtops, 1 }, /* EVFILT_USER */ { &null_filtops }, /* EVFILT_SENDFILE */ }; @@ -465,6 +466,10 @@ knote_fork(struct knlist *list, int pid) list->kl_lock(list->kl_lockarg); SLIST_FOREACH(kn, &list->kl_list, kn_selnext) { + /* + * XXX - Why do we skip the kn if it is _INFLUX? Does this + * mean we will not properly wake up some notes? + */ if ((kn->kn_status & KN_INFLUX) == KN_INFLUX) continue; kq = kn->kn_kq; @@ -1002,6 +1007,9 @@ kqueue_fo_find(int filt) if (filt > 0 || filt + EVFILT_SYSCOUNT < 0) return NULL; + if (sysfilt_ops[~filt].for_nolock) + return sysfilt_ops[~filt].for_fop; + mtx_lock(&filterops_lock); sysfilt_ops[~filt].for_refcnt++; if (sysfilt_ops[~filt].for_fop == NULL) @@ -1018,6 +1026,9 @@ kqueue_fo_release(int filt) if (filt > 0 || filt + EVFILT_SYSCOUNT < 0) return; + if (sysfilt_ops[~filt].for_nolock) + return; + mtx_lock(&filterops_lock); KASSERT(sysfilt_ops[~filt].for_refcnt > 0, ("filter object refcount not valid on release")); @@ -1051,7 +1062,10 @@ kqueue_register(struct kqueue *kq, struct kevent *kev, struct thread *td, int wa if (fops == NULL) return EINVAL; - tkn = knote_alloc(waitok); /* prevent waiting with locks */ + if (kev->flags & EV_ADD) + tkn = knote_alloc(waitok); /* prevent waiting with locks */ + else + tkn = NULL; findkn: if (fops->f_isfd) { @@ -1162,7 +1176,7 @@ findkn: kev->data = 0; kn->kn_kevent = *kev; kn->kn_kevent.flags &= ~(EV_ADD | EV_DELETE | - EV_ENABLE | EV_DISABLE); + EV_ENABLE | EV_DISABLE | EV_FORCEONESHOT); kn->kn_status = KN_INFLUX|KN_DETACHED; error = knote_attach(kn, kq); @@ -1195,6 +1209,11 @@ findkn: goto done; } + if (kev->flags & EV_FORCEONESHOT) { + kn->kn_flags |= EV_ONESHOT; + KNOTE_ACTIVATE(kn, 1); + } + /* * The user may change some filter values after the initial EV_ADD, * but doing so will not reset any filter which has already been @@ -1219,18 +1238,21 @@ findkn: * kn_knlist. */ done_ev_add: - event = kn->kn_fop->f_event(kn, 0); + if ((kev->flags & EV_DISABLE) && + ((kn->kn_status & KN_DISABLED) == 0)) { + kn->kn_status |= KN_DISABLED; + } + + if ((kn->kn_status & KN_DISABLED) == 0) + event = kn->kn_fop->f_event(kn, 0); + else + event = 0; KQ_LOCK(kq); if (event) KNOTE_ACTIVATE(kn, 1); kn->kn_status &= ~(KN_INFLUX | KN_SCAN); KN_LIST_UNLOCK(kn); - if ((kev->flags & EV_DISABLE) && - ((kn->kn_status & KN_DISABLED) == 0)) { - kn->kn_status |= KN_DISABLED; - } - if ((kev->flags & EV_ENABLE) && (kn->kn_status & KN_DISABLED)) { kn->kn_status &= ~KN_DISABLED; if ((kn->kn_status & KN_ACTIVE) && diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 8135afba7e2..62f43ba743b 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -333,7 +333,7 @@ fork_norfproc(struct thread *td, int flags) */ if (flags & RFCFDG) { struct filedesc *fdtmp; - fdtmp = fdinit(td->td_proc->p_fd); + fdtmp = fdinit(td->td_proc->p_fd, false); fdescfree(td); p1->p_fd = fdtmp; } @@ -418,7 +418,7 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2, * Copy filedesc. */ if (flags & RFCFDG) { - fd = fdinit(p1->p_fd); + fd = fdinit(p1->p_fd, false); fdtol = NULL; } else if (flags & RFFDG) { fd = fdcopy(p1->p_fd); diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index 3fc151db298..36a8470d297 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1360,9 +1360,14 @@ lockmgr_printinfo(const struct lock *lk) (uintmax_t)LK_SHARERS(lk->lk_lock)); else { td = lockmgr_xholder(lk); - printf("lock type %s: EXCL by thread %p " - "(pid %d, %s, tid %d)\n", lk->lock_object.lo_name, td, - td->td_proc->p_pid, td->td_proc->p_comm, td->td_tid); + if (td == (struct thread *)LK_KERNPROC) + printf("lock type %s: EXCL by KERNPROC\n", + lk->lock_object.lo_name); + else + printf("lock type %s: EXCL by thread %p " + "(pid %d, %s, tid %d)\n", lk->lock_object.lo_name, + td, td->td_proc->p_pid, td->td_proc->p_comm, + td->td_tid); } x = lk->lk_lock; diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index 467ae1cf5cf..d9849081396 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$"); #include "opt_adaptive_mutexes.h" #include "opt_ddb.h" -#include "opt_global.h" #include "opt_hwpmc_hooks.h" #include "opt_sched.h" diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index dfdca15194a..357099b59b0 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -827,9 +827,14 @@ SYSCTL_STRING(_kern_shutdown, OID_AUTO, dumpdevname, CTLFLAG_RD, /* Registration of dumpers */ int -set_dumper(struct dumperinfo *di, const char *devname) +set_dumper(struct dumperinfo *di, const char *devname, struct thread *td) { size_t wantcopy; + int error; + + error = priv_check(td, PRIV_SETDUMPER); + if (error != 0) + return (error); if (di == NULL) { bzero(&dumper, sizeof dumper); diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 33fdf71e5eb..5b42c6fd118 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -169,7 +169,6 @@ struct umtxq_chain { }; #define UMTXQ_LOCKED_ASSERT(uc) mtx_assert(&(uc)->uc_lock, MA_OWNED) -#define UMTXQ_BUSY_ASSERT(uc) KASSERT(&(uc)->uc_busy, ("umtx chain is not busy")) /* * Don't propagate time-sharing priority, there is a security reason, @@ -1478,7 +1477,7 @@ umtxq_sleep_pi(struct umtx_q *uq, struct umtx_pi *pi, KASSERT(td == curthread, ("inconsistent uq_thread")); uc = umtxq_getchain(&uq->uq_key); UMTXQ_LOCKED_ASSERT(uc); - UMTXQ_BUSY_ASSERT(uc); + KASSERT(uc->uc_busy != 0, ("umtx chain is not busy")); umtxq_insert(uq); mtx_lock_spin(&umtx_lock); if (pi->pi_owner == NULL) { diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index efd66b274ea..cedfc1b3d1d 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -533,6 +533,7 @@ out: if (--p->p_profthreads == 0) { if (p->p_flag & P_STOPPROF) { wakeup(&p->p_profthreads); + p->p_flag &= ~P_STOPPROF; stop = 0; } } diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 1cd1287d257..01996155e4c 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1289,26 +1289,60 @@ selscan(td, ibits, obits, nfd) return (0); } -#ifndef _SYS_SYSPROTO_H_ -struct poll_args { - struct pollfd *fds; - u_int nfds; - int timeout; -}; -#endif int -sys_poll(td, uap) - struct thread *td; - struct poll_args *uap; +sys_poll(struct thread *td, struct poll_args *uap) +{ + struct timespec ts, *tsp; + + if (uap->timeout != INFTIM) { + if (uap->timeout < 0) + return (EINVAL); + ts.tv_sec = uap->timeout / 1000; + ts.tv_nsec = (uap->timeout % 1000) * 1000000; + tsp = &ts; + } else + tsp = NULL; + + return (kern_poll(td, uap->fds, uap->nfds, tsp, NULL)); +} + +int +kern_poll(struct thread *td, struct pollfd *fds, u_int nfds, + struct timespec *tsp, sigset_t *uset) { struct pollfd *bits; struct pollfd smallbits[32]; - sbintime_t asbt, precision, rsbt; - u_int nfds; + sbintime_t sbt, precision, tmp; + time_t over; + struct timespec ts; int error; size_t ni; - nfds = uap->nfds; + precision = 0; + if (tsp != NULL) { + if (tsp->tv_sec < 0) + return (EINVAL); + if (tsp->tv_nsec < 0 || tsp->tv_nsec >= 1000000000) + return (EINVAL); + if (tsp->tv_sec == 0 && tsp->tv_nsec == 0) + sbt = 0; + else { + ts = *tsp; + if (ts.tv_sec > INT32_MAX / 2) { + over = ts.tv_sec - INT32_MAX / 2; + ts.tv_sec -= over; + } else + over = 0; + tmp = tstosbt(ts); + precision = tmp; + precision >>= tc_precexp; + if (TIMESEL(&sbt, tmp)) + sbt += tc_tick_sbt; + sbt += tmp; + } + } else + sbt = -1; + if (nfds > maxfilesperproc && nfds > FD_SETSIZE) return (EINVAL); ni = nfds * sizeof(struct pollfd); @@ -1316,34 +1350,33 @@ sys_poll(td, uap) bits = malloc(ni, M_TEMP, M_WAITOK); else bits = smallbits; - error = copyin(uap->fds, bits, ni); + error = copyin(fds, bits, ni); if (error) goto done; - precision = 0; - if (uap->timeout != INFTIM) { - if (uap->timeout < 0) { - error = EINVAL; + + if (uset != NULL) { + error = kern_sigprocmask(td, SIG_SETMASK, uset, + &td->td_oldsigmask, 0); + if (error) goto done; - } - if (uap->timeout == 0) - asbt = 0; - else { - rsbt = SBT_1MS * uap->timeout; - precision = rsbt; - precision >>= tc_precexp; - if (TIMESEL(&asbt, rsbt)) - asbt += tc_tick_sbt; - asbt += rsbt; - } - } else - asbt = -1; + td->td_pflags |= TDP_OLDMASK; + /* + * Make sure that ast() is called on return to + * usermode and TDP_OLDMASK is cleared, restoring old + * sigmask. + */ + thread_lock(td); + td->td_flags |= TDF_ASTPENDING; + thread_unlock(td); + } + seltdinit(td); /* Iterate until the timeout expires or descriptors become ready. */ for (;;) { error = pollscan(td, bits, nfds); if (error || td->td_retval[0] != 0) break; - error = seltdwait(td, asbt, precision); + error = seltdwait(td, sbt, precision); if (error) break; error = pollrescan(td); @@ -1359,7 +1392,7 @@ done: if (error == EWOULDBLOCK) error = 0; if (error == 0) { - error = pollout(td, bits, uap->fds, nfds); + error = pollout(td, bits, fds, nfds); if (error) goto out; } @@ -1369,6 +1402,35 @@ out: return (error); } +int +sys_ppoll(struct thread *td, struct ppoll_args *uap) +{ + struct timespec ts, *tsp; + sigset_t set, *ssp; + int error; + + if (uap->ts != NULL) { + error = copyin(uap->ts, &ts, sizeof(ts)); + if (error) + return (error); + tsp = &ts; + } else + tsp = NULL; + if (uap->set != NULL) { + error = copyin(uap->set, &set, sizeof(set)); + if (error) + return (error); + ssp = &set; + } else + ssp = NULL; + /* + * fds is still a pointer to user space. kern_poll() will + * take care of copyin that array to the kernel space. + */ + + return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp)); +} + static int pollrescan(struct thread *td) { diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 47cedfeab4b..dd831ae81a6 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -175,16 +175,17 @@ soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, case FIONREAD: /* Unlocked read. */ - *(int *)data = so->so_rcv.sb_cc; + *(int *)data = sbavail(&so->so_rcv); break; case FIONWRITE: /* Unlocked read. */ - *(int *)data = so->so_snd.sb_cc; + *(int *)data = sbavail(&so->so_snd); break; case FIONSPACE: - if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc) || + /* Unlocked read. */ + if ((so->so_snd.sb_hiwat < sbused(&so->so_snd)) || (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) *(int *)data = 0; else @@ -254,6 +255,7 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, struct thread *td) { struct socket *so = fp->f_data; + struct sockbuf *sb; #ifdef MAC int error; #endif @@ -269,15 +271,18 @@ soo_stat(struct file *fp, struct stat *ub, struct ucred *active_cred, * If SBS_CANTRCVMORE is set, but there's still data left in the * receive buffer, the socket is still readable. */ - SOCKBUF_LOCK(&so->so_rcv); - if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 || - so->so_rcv.sb_cc != 0) + sb = &so->so_rcv; + SOCKBUF_LOCK(sb); + if ((sb->sb_state & SBS_CANTRCVMORE) == 0 || sbavail(sb)) ub->st_mode |= S_IRUSR | S_IRGRP | S_IROTH; - ub->st_size = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; - SOCKBUF_UNLOCK(&so->so_rcv); - /* Unlocked read. */ - if ((so->so_snd.sb_state & SBS_CANTSENDMORE) == 0) + ub->st_size = sbavail(sb) - sb->sb_ctl; + SOCKBUF_UNLOCK(sb); + + sb = &so->so_snd; + SOCKBUF_LOCK(sb); + if ((sb->sb_state & SBS_CANTSENDMORE) == 0) ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + SOCKBUF_UNLOCK(sb); ub->st_uid = so->so_cred->cr_uid; ub->st_gid = so->so_cred->cr_gid; return (*so->so_proto->pr_usrreqs->pru_sense)(so, ub); diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 276c34af38b..92780c3b4ad 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/kern/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ const char *syscallnames[] = { @@ -552,4 +552,5 @@ const char *syscallnames[] = { "pipe2", /* 542 = pipe2 */ "aio_mlock", /* 543 = aio_mlock */ "procctl", /* 544 = procctl */ + "ppoll", /* 545 = ppoll */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 35c05f0f62e..e0f8b61e154 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -980,5 +980,8 @@ 543 AUE_NULL NOSTD { int aio_mlock(struct aiocb *aiocbp); } 544 AUE_NULL STD { int procctl(idtype_t idtype, id_t id, \ int com, void *data); } +545 AUE_POLL STD { int ppoll(struct pollfd *fds, u_int nfds, \ + const struct timespec *ts, \ + const sigset_t *set); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c index ce2be6d1fd7..d5fcdc4eb3d 100644 --- a/sys/kern/systrace_args.c +++ b/sys/kern/systrace_args.c @@ -3372,6 +3372,16 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) *n_args = 4; break; } + /* ppoll */ + case 545: { + struct ppoll_args *p = params; + uarg[0] = (intptr_t) p->fds; /* struct pollfd * */ + uarg[1] = p->nfds; /* u_int */ + uarg[2] = (intptr_t) p->ts; /* const struct timespec * */ + uarg[3] = (intptr_t) p->set; /* const sigset_t * */ + *n_args = 4; + break; + } default: *n_args = 0; break; @@ -8990,6 +9000,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) break; }; break; + /* ppoll */ + case 545: + switch(ndx) { + case 0: + p = "struct pollfd *"; + break; + case 1: + p = "u_int"; + break; + case 2: + p = "const struct timespec *"; + break; + case 3: + p = "const sigset_t *"; + break; + default: + break; + }; + break; default: break; }; @@ -10928,6 +10957,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) if (ndx == 0 || ndx == 1) p = "int"; break; + /* ppoll */ + case 545: + if (ndx == 0 || ndx == 1) + p = "int"; + break; default: break; }; diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c index c74343b8f81..01e48b55aac 100644 --- a/sys/kern/uipc_sockbuf.c +++ b/sys/kern/uipc_sockbuf.c @@ -881,12 +881,10 @@ sbcut_internal(struct sockbuf *sb, int len) mfree = NULL; while (len > 0) { - if (m == 0) { - if (next == 0) - panic("sbdrop"); + if (m == NULL) { + KASSERT(next, ("%s: no next, len %d", __func__, len)); m = next; next = m->m_nextpkt; - continue; } if (m->m_len > len) { m->m_len -= len; @@ -905,13 +903,6 @@ sbcut_internal(struct sockbuf *sb, int len) mfree = m; m = n; } - while (m && m->m_len == 0) { - sbfree(sb, m); - n = m->m_next; - m->m_next = mfree; - mfree = m; - m = n; - } if (m) { sb->sb_mb = m; m->m_nextpkt = next; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 706632716b1..240421f694b 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1310,7 +1310,7 @@ restart: resid = 0; if (flags & MSG_EOR) top->m_flags |= M_EOR; - } else { + } else if (resid > 0) { /* * Copy the data from userland into a mbuf * chain. If no data is to be copied in, @@ -1522,12 +1522,12 @@ restart: * 2. MSG_DONTWAIT is not set */ if (m == NULL || (((flags & MSG_DONTWAIT) == 0 && - so->so_rcv.sb_cc < uio->uio_resid) && - so->so_rcv.sb_cc < so->so_rcv.sb_lowat && + sbavail(&so->so_rcv) < uio->uio_resid) && + sbavail(&so->so_rcv) < so->so_rcv.sb_lowat && m->m_nextpkt == NULL && (pr->pr_flags & PR_ATOMIC) == 0)) { - KASSERT(m != NULL || !so->so_rcv.sb_cc, - ("receive: m == %p so->so_rcv.sb_cc == %u", - m, so->so_rcv.sb_cc)); + KASSERT(m != NULL || !sbavail(&so->so_rcv), + ("receive: m == %p sbavail == %u", + m, sbavail(&so->so_rcv))); if (so->so_error) { if (m != NULL) goto dontblock; @@ -1809,9 +1809,7 @@ dontblock: SOCKBUF_LOCK(&so->so_rcv); } } - m->m_data += len; - m->m_len -= len; - so->so_rcv.sb_cc -= len; + sbcut_locked(&so->so_rcv, len); } } SOCKBUF_LOCK_ASSERT(&so->so_rcv); @@ -1976,7 +1974,7 @@ restart: /* Abort if socket has reported problems. */ if (so->so_error) { - if (sb->sb_cc > 0) + if (sbavail(sb) > 0) goto deliver; if (oresid > uio->uio_resid) goto out; @@ -1988,32 +1986,32 @@ restart: /* Door is closed. Deliver what is left, if any. */ if (sb->sb_state & SBS_CANTRCVMORE) { - if (sb->sb_cc > 0) + if (sbavail(sb) > 0) goto deliver; else goto out; } /* Socket buffer is empty and we shall not block. */ - if (sb->sb_cc == 0 && + if (sbavail(sb) == 0 && ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)))) { error = EAGAIN; goto out; } /* Socket buffer got some data that we shall deliver now. */ - if (sb->sb_cc > 0 && !(flags & MSG_WAITALL) && + if (sbavail(sb) > 0 && !(flags & MSG_WAITALL) && ((sb->sb_flags & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)) || - sb->sb_cc >= sb->sb_lowat || - sb->sb_cc >= uio->uio_resid || - sb->sb_cc >= sb->sb_hiwat) ) { + sbavail(sb) >= sb->sb_lowat || + sbavail(sb) >= uio->uio_resid || + sbavail(sb) >= sb->sb_hiwat) ) { goto deliver; } /* On MSG_WAITALL we must wait until all data or error arrives. */ if ((flags & MSG_WAITALL) && - (sb->sb_cc >= uio->uio_resid || sb->sb_cc >= sb->sb_hiwat)) + (sbavail(sb) >= uio->uio_resid || sbavail(sb) >= sb->sb_hiwat)) goto deliver; /* @@ -2027,7 +2025,7 @@ restart: deliver: SOCKBUF_LOCK_ASSERT(&so->so_rcv); - KASSERT(sb->sb_cc > 0, ("%s: sockbuf empty", __func__)); + KASSERT(sbavail(sb) > 0, ("%s: sockbuf empty", __func__)); KASSERT(sb->sb_mb != NULL, ("%s: sb_mb == NULL", __func__)); /* Statistics. */ @@ -2035,7 +2033,7 @@ deliver: uio->uio_td->td_ru.ru_msgrcv++; /* Fill uio until full or current end of socket buffer is reached. */ - len = min(uio->uio_resid, sb->sb_cc); + len = min(uio->uio_resid, sbavail(sb)); if (mp0 != NULL) { /* Dequeue as many mbufs as possible. */ if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) { @@ -2170,9 +2168,9 @@ soreceive_dgram(struct socket *so, struct sockaddr **psa, struct uio *uio, */ SOCKBUF_LOCK(&so->so_rcv); while ((m = so->so_rcv.sb_mb) == NULL) { - KASSERT(so->so_rcv.sb_cc == 0, - ("soreceive_dgram: sb_mb NULL but sb_cc %u", - so->so_rcv.sb_cc)); + KASSERT(sbavail(&so->so_rcv) == 0, + ("soreceive_dgram: sb_mb NULL but sbavail %u", + sbavail(&so->so_rcv))); if (so->so_error) { error = so->so_error; so->so_error = 0; @@ -3248,7 +3246,7 @@ filt_soread(struct knote *kn, long hint) so = kn->kn_fp->f_data; SOCKBUF_LOCK_ASSERT(&so->so_rcv); - kn->kn_data = so->so_rcv.sb_cc - so->so_rcv.sb_ctl; + kn->kn_data = sbavail(&so->so_rcv) - so->so_rcv.sb_ctl; if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { kn->kn_flags |= EV_EOF; kn->kn_fflags = so->so_error; @@ -3260,7 +3258,7 @@ filt_soread(struct knote *kn, long hint) if (kn->kn_data >= kn->kn_sdata) return 1; } else { - if (so->so_rcv.sb_cc >= so->so_rcv.sb_lowat) + if (sbavail(&so->so_rcv) >= so->so_rcv.sb_lowat) return 1; } @@ -3451,7 +3449,7 @@ soisdisconnected(struct socket *so) sorwakeup_locked(so); SOCKBUF_LOCK(&so->so_snd); so->so_snd.sb_state |= SBS_CANTSENDMORE; - sbdrop_locked(&so->so_snd, so->so_snd.sb_cc); + sbdrop_locked(&so->so_snd, sbused(&so->so_snd)); sowwakeup_locked(so); wakeup(&so->so_timeo); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 6d423ba5106..b0d849d93c8 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -63,8 +63,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include #include #include @@ -115,10 +113,6 @@ static int getpeername1(struct thread *td, struct getpeername_args *uap, counter_u64_t sfstat[sizeof(struct sfstat) / sizeof(uint64_t)]; -static int filt_sfsync_attach(struct knote *kn); -static void filt_sfsync_detach(struct knote *kn); -static int filt_sfsync(struct knote *kn, long hint); - /* * sendfile(2)-related variables and associated sysctls */ @@ -128,28 +122,6 @@ static int sfreadahead = 1; SYSCTL_INT(_kern_ipc_sendfile, OID_AUTO, readahead, CTLFLAG_RW, &sfreadahead, 0, "Number of sendfile(2) read-ahead MAXBSIZE blocks"); -#ifdef SFSYNC_DEBUG -static int sf_sync_debug = 0; -SYSCTL_INT(_debug, OID_AUTO, sf_sync_debug, CTLFLAG_RW, - &sf_sync_debug, 0, "Output debugging during sf_sync lifecycle"); -#define SFSYNC_DPRINTF(s, ...) \ - do { \ - if (sf_sync_debug) \ - printf((s), ##__VA_ARGS__); \ - } while (0) -#else -#define SFSYNC_DPRINTF(c, ...) -#endif - -static uma_zone_t zone_sfsync; - -static struct filterops sendfile_filtops = { - .f_isfd = 0, - .f_attach = filt_sfsync_attach, - .f_detach = filt_sfsync_detach, - .f_event = filt_sfsync, -}; - static void sfstat_init(const void *unused) { @@ -159,19 +131,6 @@ sfstat_init(const void *unused) } SYSINIT(sfstat, SI_SUB_MBUF, SI_ORDER_FIRST, sfstat_init, NULL); -static void -sf_sync_init(const void *unused) -{ - - zone_sfsync = uma_zcreate("sendfile_sync", sizeof(struct sendfile_sync), - NULL, NULL, - NULL, NULL, - UMA_ALIGN_CACHE, - 0); - kqueue_add_filteropts(EVFILT_SENDFILE, &sendfile_filtops); -} -SYSINIT(sf_sync, SI_SUB_MBUF, SI_ORDER_FIRST, sf_sync_init, NULL); - static int sfstat_sysctl(SYSCTL_HANDLER_ARGS) { @@ -283,13 +242,13 @@ sys_bind(td, uap) error = getsockaddr(&sa, uap->name, uap->namelen); if (error == 0) { - error = kern_bind(td, uap->s, sa); + error = kern_bindat(td, AT_FDCWD, uap->s, sa); free(sa, M_SONAME); } return (error); } -static int +int kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; @@ -323,13 +282,6 @@ kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) return (error); } -int -kern_bind(struct thread *td, int fd, struct sockaddr *sa) -{ - - return (kern_bindat(td, AT_FDCWD, fd, sa)); -} - /* ARGSUSED */ int sys_bindat(td, uap) @@ -636,13 +588,13 @@ sys_connect(td, uap) error = getsockaddr(&sa, uap->name, uap->namelen); if (error == 0) { - error = kern_connect(td, uap->s, sa); + error = kern_connectat(td, AT_FDCWD, uap->s, sa); free(sa, M_SONAME); } return (error); } -static int +int kern_connectat(struct thread *td, int dirfd, int fd, struct sockaddr *sa) { struct socket *so; @@ -705,13 +657,6 @@ done1: return (error); } -int -kern_connect(struct thread *td, int fd, struct sockaddr *sa) -{ - - return (kern_connectat(td, AT_FDCWD, fd, sa)); -} - /* ARGSUSED */ int sys_connectat(td, uap) @@ -1864,116 +1809,11 @@ getsockaddr(namp, uaddr, len) return (error); } -static int -filt_sfsync_attach(struct knote *kn) -{ - struct sendfile_sync *sfs = (struct sendfile_sync *) kn->kn_sdata; - struct knlist *knl = &sfs->klist; - - SFSYNC_DPRINTF("%s: kn=%p, sfs=%p\n", __func__, kn, sfs); - - /* - * Validate that we actually received this via the kernel API. - */ - if ((kn->kn_flags & EV_FLAG1) == 0) - return (EPERM); - - kn->kn_ptr.p_v = sfs; - kn->kn_flags &= ~EV_FLAG1; - - knl->kl_lock(knl->kl_lockarg); - /* - * If we're in the "freeing" state, - * don't allow the add. That way we don't - * end up racing with some other thread that - * is trying to finish some setup. - */ - if (sfs->state == SF_STATE_FREEING) { - knl->kl_unlock(knl->kl_lockarg); - return (EINVAL); - } - knlist_add(&sfs->klist, kn, 1); - knl->kl_unlock(knl->kl_lockarg); - - return (0); -} - -/* - * Called when a knote is being detached. - */ -static void -filt_sfsync_detach(struct knote *kn) -{ - struct knlist *knl; - struct sendfile_sync *sfs; - int do_free = 0; - - sfs = kn->kn_ptr.p_v; - knl = &sfs->klist; - - SFSYNC_DPRINTF("%s: kn=%p, sfs=%p\n", __func__, kn, sfs); - - knl->kl_lock(knl->kl_lockarg); - if (!knlist_empty(knl)) - knlist_remove(knl, kn, 1); - - /* - * If the list is empty _AND_ the refcount is 0 - * _AND_ we've finished the setup phase and now - * we're in the running phase, we can free the - * underlying sendfile_sync. - * - * But we shouldn't do it before finishing the - * underlying divorce from the knote. - * - * So, we have the sfsync lock held; transition - * it to "freeing", then unlock, then free - * normally. - */ - if (knlist_empty(knl)) { - if (sfs->state == SF_STATE_COMPLETED && sfs->count == 0) { - SFSYNC_DPRINTF("%s: (%llu) sfs=%p; completed, " - "count==0, empty list: time to free!\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - sf_sync_set_state(sfs, SF_STATE_FREEING, 1); - do_free = 1; - } - } - knl->kl_unlock(knl->kl_lockarg); - - /* - * Only call free if we're the one who has transitioned things - * to free. Otherwise we could race with another thread that - * is currently tearing things down. - */ - if (do_free == 1) { - SFSYNC_DPRINTF("%s: (%llu) sfs=%p, %s:%d\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs, - __FILE__, - __LINE__); - sf_sync_free(sfs); - } -} - -static int -filt_sfsync(struct knote *kn, long hint) -{ - struct sendfile_sync *sfs = (struct sendfile_sync *) kn->kn_ptr.p_v; - int ret; - - SFSYNC_DPRINTF("%s: kn=%p, sfs=%p\n", __func__, kn, sfs); - - /* - * XXX add a lock assertion here! - */ - ret = (sfs->count == 0 && sfs->state == SF_STATE_COMPLETED); - - return (ret); -} +struct sendfile_sync { + struct mtx mtx; + struct cv cv; + unsigned count; +}; /* * Add more references to a vm_page + sf_buf + sendfile_sync. @@ -2022,344 +1862,13 @@ sf_ext_free(void *arg1, void *arg2) vm_page_free(pg); vm_page_unlock(pg); - if (sfs != NULL) - sf_sync_deref(sfs); -} - -/* - * Called to remove a reference to a sf_sync object. - * - * This is generally done during the mbuf free path to signify - * that one of the mbufs in the transaction has been completed. - * - * If we're doing SF_SYNC and the refcount is zero then we'll wake - * up any waiters. - * - * IF we're doing SF_KQUEUE and the refcount is zero then we'll - * fire off the knote. - */ -void -sf_sync_deref(struct sendfile_sync *sfs) -{ - int do_free = 0; - - if (sfs == NULL) - return; - - mtx_lock(&sfs->mtx); - KASSERT(sfs->count> 0, ("Sendfile sync botchup count == 0")); - sfs->count --; - - /* - * Only fire off the wakeup / kqueue notification if - * we are in the running state. - */ - if (sfs->count == 0 && sfs->state == SF_STATE_COMPLETED) { - if (sfs->flags & SF_SYNC) - cv_signal(&sfs->cv); - - if (sfs->flags & SF_KQUEUE) { - SFSYNC_DPRINTF("%s: (%llu) sfs=%p: knote!\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - KNOTE_LOCKED(&sfs->klist, 1); - } - - /* - * If we're not waiting around for a sync, - * check if the knote list is empty. - * If it is, we transition to free. - * - * XXX I think it's about time I added some state - * or flag that says whether we're supposed to be - * waiting around until we've done a signal. - * - * XXX Ie, the reason that I don't free it here - * is because the caller will free the last reference, - * not us. That should be codified in some flag - * that indicates "self-free" rather than checking - * for SF_SYNC all the time. - */ - if ((sfs->flags & SF_SYNC) == 0 && knlist_empty(&sfs->klist)) { - SFSYNC_DPRINTF("%s: (%llu) sfs=%p; completed, " - "count==0, empty list: time to free!\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - sf_sync_set_state(sfs, SF_STATE_FREEING, 1); - do_free = 1; - } - - } - mtx_unlock(&sfs->mtx); - - /* - * Attempt to do a free here. - * - * We do this outside of the lock because it may destroy the - * lock in question as it frees things. We can optimise this - * later. - * - * XXX yes, we should make it a requirement to hold the - * lock across sf_sync_free(). - */ - if (do_free == 1) { - SFSYNC_DPRINTF("%s: (%llu) sfs=%p\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - sf_sync_free(sfs); - } -} - -/* - * Allocate a sendfile_sync state structure. - * - * For now this only knows about the "sleep" sync, but later it will - * grow various other personalities. - */ -struct sendfile_sync * -sf_sync_alloc(uint32_t flags) -{ - struct sendfile_sync *sfs; - - sfs = uma_zalloc(zone_sfsync, M_WAITOK | M_ZERO); - mtx_init(&sfs->mtx, "sendfile", NULL, MTX_DEF); - cv_init(&sfs->cv, "sendfile"); - sfs->flags = flags; - sfs->state = SF_STATE_SETUP; - knlist_init_mtx(&sfs->klist, &sfs->mtx); - - SFSYNC_DPRINTF("%s: sfs=%p, flags=0x%08x\n", __func__, sfs, sfs->flags); - - return (sfs); -} - -/* - * Take a reference to a sfsync instance. - * - * This has to map 1:1 to free calls coming in via sf_ext_free(), - * so typically this will be referenced once for each mbuf allocated. - */ -void -sf_sync_ref(struct sendfile_sync *sfs) -{ - - if (sfs == NULL) - return; - - mtx_lock(&sfs->mtx); - sfs->count++; - mtx_unlock(&sfs->mtx); -} - -void -sf_sync_syscall_wait(struct sendfile_sync *sfs) -{ - - if (sfs == NULL) - return; - - KASSERT(mtx_owned(&sfs->mtx), ("%s: sfs=%p: not locked but should be!", - __func__, - sfs)); - - /* - * If we're not requested to wait during the syscall, - * don't bother waiting. - */ - if ((sfs->flags & SF_SYNC) == 0) - goto out; - - /* - * This is a bit suboptimal and confusing, so bear with me. - * - * Ideally sf_sync_syscall_wait() will wait until - * all pending mbuf transmit operations are done. - * This means that when sendfile becomes async, it'll - * run in the background and will transition from - * RUNNING to COMPLETED when it's finished acquiring - * new things to send. Then, when the mbufs finish - * sending, COMPLETED + sfs->count == 0 is enough to - * know that no further work is being done. - * - * So, we will sleep on both RUNNING and COMPLETED. - * It's up to the (in progress) async sendfile loop - * to transition the sf_sync from RUNNING to - * COMPLETED so the wakeup above will actually - * do the cv_signal() call. - */ - if (sfs->state != SF_STATE_COMPLETED && sfs->state != SF_STATE_RUNNING) - goto out; - - if (sfs->count != 0) - cv_wait(&sfs->cv, &sfs->mtx); - KASSERT(sfs->count == 0, ("sendfile sync still busy")); - -out: - return; -} - -/* - * Free an sf_sync if it's appropriate to. - */ -void -sf_sync_free(struct sendfile_sync *sfs) -{ - - if (sfs == NULL) - return; - - SFSYNC_DPRINTF("%s: (%lld) sfs=%p; called; state=%d, flags=0x%08x " - "count=%d\n", - __func__, - (long long) curthread->td_tid, - sfs, - sfs->state, - sfs->flags, - sfs->count); - - mtx_lock(&sfs->mtx); - - /* - * We keep the sf_sync around if the state is active, - * we are doing kqueue notification and we have active - * knotes. - * - * If the caller wants to free us right this second it - * should transition this to the freeing state. - * - * So, complain loudly if they break this rule. - */ - if (sfs->state != SF_STATE_FREEING) { - printf("%s: (%llu) sfs=%p; not freeing; let's wait!\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - mtx_unlock(&sfs->mtx); - return; - } - - KASSERT(sfs->count == 0, ("sendfile sync still busy")); - cv_destroy(&sfs->cv); - /* - * This doesn't call knlist_detach() on each knote; it just frees - * the entire list. - */ - knlist_delete(&sfs->klist, curthread, 1); - mtx_destroy(&sfs->mtx); - SFSYNC_DPRINTF("%s: (%llu) sfs=%p; freeing\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - uma_zfree(zone_sfsync, sfs); -} - -/* - * Setup a sf_sync to post a kqueue notification when things are complete. - */ -int -sf_sync_kqueue_setup(struct sendfile_sync *sfs, struct sf_hdtr_kq *sfkq) -{ - struct kevent kev; - int error; - - sfs->flags |= SF_KQUEUE; - - /* Check the flags are valid */ - if ((sfkq->kq_flags & ~(EV_CLEAR | EV_DISPATCH | EV_ONESHOT)) != 0) - return (EINVAL); - - SFSYNC_DPRINTF("%s: sfs=%p: kqfd=%d, flags=0x%08x, ident=%p, udata=%p\n", - __func__, - sfs, - sfkq->kq_fd, - sfkq->kq_flags, - (void *) sfkq->kq_ident, - (void *) sfkq->kq_udata); - - /* Setup and register a knote on the given kqfd. */ - kev.ident = (uintptr_t) sfkq->kq_ident; - kev.filter = EVFILT_SENDFILE; - kev.flags = EV_ADD | EV_ENABLE | EV_FLAG1 | sfkq->kq_flags; - kev.data = (intptr_t) sfs; - kev.udata = sfkq->kq_udata; - - error = kqfd_register(sfkq->kq_fd, &kev, curthread, 1); - if (error != 0) { - SFSYNC_DPRINTF("%s: returned %d\n", __func__, error); - } - return (error); -} - -void -sf_sync_set_state(struct sendfile_sync *sfs, sendfile_sync_state_t state, - int islocked) -{ - sendfile_sync_state_t old_state; - - if (! islocked) + if (sfs != NULL) { mtx_lock(&sfs->mtx); - - /* - * Update our current state. - */ - old_state = sfs->state; - sfs->state = state; - SFSYNC_DPRINTF("%s: (%llu) sfs=%p; going from %d to %d\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs, - old_state, - state); - - /* - * If we're transitioning from RUNNING to COMPLETED and the count is - * zero, then post the knote. The caller may have completed the - * send before we updated the state to COMPLETED and we need to make - * sure this is communicated. - */ - if (old_state == SF_STATE_RUNNING - && state == SF_STATE_COMPLETED - && sfs->count == 0 - && sfs->flags & SF_KQUEUE) { - SFSYNC_DPRINTF("%s: (%llu) sfs=%p: triggering knote!\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - KNOTE_LOCKED(&sfs->klist, 1); - } - - if (! islocked) + KASSERT(sfs->count > 0, ("Sendfile sync botchup count == 0")); + if (--sfs->count == 0) + cv_signal(&sfs->cv); mtx_unlock(&sfs->mtx); -} - -/* - * Set the retval/errno for the given transaction. - * - * This will eventually/ideally be used when the KNOTE is fired off - * to signify the completion of this transaction. - * - * The sfsync lock should be held before entering this function. - */ -void -sf_sync_set_retval(struct sendfile_sync *sfs, off_t retval, int xerrno) -{ - - KASSERT(mtx_owned(&sfs->mtx), ("%s: sfs=%p: not locked but should be!", - __func__, - sfs)); - - SFSYNC_DPRINTF("%s: (%llu) sfs=%p: errno=%d, retval=%jd\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs, - xerrno, - (intmax_t) retval); - - sfs->retval = retval; - sfs->xerrno = xerrno; + } } /* @@ -2380,174 +1889,15 @@ sys_sendfile(struct thread *td, struct sendfile_args *uap) return (do_sendfile(td, uap, 0)); } -int -_do_sendfile(struct thread *td, int src_fd, int sock_fd, int flags, - int compat, off_t offset, size_t nbytes, off_t *sbytes, - struct uio *hdr_uio, - struct uio *trl_uio, struct sf_hdtr_kq *hdtr_kq) -{ - cap_rights_t rights; - struct sendfile_sync *sfs = NULL; - struct file *fp; - int error; - int do_kqueue = 0; - int do_free = 0; - - AUDIT_ARG_FD(src_fd); - - if (hdtr_kq != NULL) - do_kqueue = 1; - - /* - * sendfile(2) can start at any offset within a file so we require - * CAP_READ+CAP_SEEK = CAP_PREAD. - */ - if ((error = fget_read(td, src_fd, - cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { - goto out; - } - - /* - * IF SF_KQUEUE is set but we haven't copied in anything for - * kqueue data, error out. - */ - if (flags & SF_KQUEUE && do_kqueue == 0) { - SFSYNC_DPRINTF("%s: SF_KQUEUE but no KQUEUE data!\n", __func__); - goto out; - } - - /* - * If we need to wait for completion, initialise the sfsync - * state here. - */ - if (flags & (SF_SYNC | SF_KQUEUE)) - sfs = sf_sync_alloc(flags & (SF_SYNC | SF_KQUEUE)); - - if (flags & SF_KQUEUE) { - error = sf_sync_kqueue_setup(sfs, hdtr_kq); - if (error) { - SFSYNC_DPRINTF("%s: (%llu) error; sfs=%p\n", - __func__, - (unsigned long long) curthread->td_tid, - sfs); - sf_sync_set_state(sfs, SF_STATE_FREEING, 0); - sf_sync_free(sfs); - goto out; - } - } - - /* - * Do the sendfile call. - * - * If this fails, it'll free the mbuf chain which will free up the - * sendfile_sync references. - */ - error = fo_sendfile(fp, sock_fd, hdr_uio, trl_uio, offset, - nbytes, sbytes, flags, compat ? SFK_COMPAT : 0, sfs, td); - - /* - * If the sendfile call succeeded, transition the sf_sync state - * to RUNNING, then COMPLETED. - * - * If the sendfile call failed, then the sendfile call may have - * actually sent some data first - so we check to see whether - * any data was sent. If some data was queued (ie, count > 0) - * then we can't call free; we have to wait until the partial - * transaction completes before we continue along. - * - * This has the side effect of firing off the knote - * if the refcount has hit zero by the time we get here. - */ - if (sfs != NULL) { - mtx_lock(&sfs->mtx); - if (error == 0 || sfs->count > 0) { - /* - * When it's time to do async sendfile, the transition - * to RUNNING signifies that we're actually actively - * adding and completing mbufs. When the last disk - * buffer is read (ie, when we're not doing any - * further read IO and all subsequent stuff is mbuf - * transmissions) we'll transition to COMPLETED - * and when the final mbuf is freed, the completion - * will be signaled. - */ - sf_sync_set_state(sfs, SF_STATE_RUNNING, 1); - - /* - * Set the retval before we signal completed. - * If we do it the other way around then transitioning to - * COMPLETED may post the knote before you set the return - * status! - * - * XXX for now, errno is always 0, as we don't post - * knotes if sendfile failed. Maybe that'll change later. - */ - sf_sync_set_retval(sfs, *sbytes, error); - - /* - * And now transition to completed, which will kick off - * the knote if required. - */ - sf_sync_set_state(sfs, SF_STATE_COMPLETED, 1); - } else { - /* - * Error isn't zero, sfs_count is zero, so we - * won't have some other thing to wake things up. - * Thus free. - */ - sf_sync_set_state(sfs, SF_STATE_FREEING, 1); - do_free = 1; - } - - /* - * Next - wait if appropriate. - */ - sf_sync_syscall_wait(sfs); - - /* - * If we're not doing kqueue notifications, we can - * transition this immediately to the freeing state. - */ - if ((sfs->flags & SF_KQUEUE) == 0) { - sf_sync_set_state(sfs, SF_STATE_FREEING, 1); - do_free = 1; - } - - mtx_unlock(&sfs->mtx); - } - - /* - * If do_free is set, free here. - * - * If we're doing no-kqueue notification and it's just sleep notification, - * we also do free; it's the only chance we have. - */ - if (sfs != NULL && do_free == 1) { - sf_sync_free(sfs); - } - - /* - * XXX Should we wait until the send has completed before freeing the source - * file handle? It's the previous behaviour, sure, but is it required? - * We've wired down the page references after all. - */ - fdrop(fp, td); - -out: - /* Return error */ - return (error); -} - - static int do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) { struct sf_hdtr hdtr; - struct sf_hdtr_kq hdtr_kq; struct uio *hdr_uio, *trl_uio; - int error; + struct file *fp; + cap_rights_t rights; off_t sbytes; - int do_kqueue = 0; + int error; /* * File offset must be positive. If it goes beyond EOF @@ -2563,38 +1913,37 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat) if (error != 0) goto out; if (hdtr.headers != NULL) { - error = copyinuio(hdtr.headers, hdtr.hdr_cnt, &hdr_uio); + error = copyinuio(hdtr.headers, hdtr.hdr_cnt, + &hdr_uio); if (error != 0) goto out; } if (hdtr.trailers != NULL) { - error = copyinuio(hdtr.trailers, hdtr.trl_cnt, &trl_uio); + error = copyinuio(hdtr.trailers, hdtr.trl_cnt, + &trl_uio); if (error != 0) goto out; } - - /* - * If SF_KQUEUE is set, then we need to also copy in - * the kqueue data after the normal hdtr set and set - * do_kqueue=1. - */ - if (uap->flags & SF_KQUEUE) { - error = copyin(((char *) uap->hdtr) + sizeof(hdtr), - &hdtr_kq, - sizeof(hdtr_kq)); - if (error != 0) - goto out; - do_kqueue = 1; - } } - /* Call sendfile */ - error = _do_sendfile(td, uap->fd, uap->s, uap->flags, compat, - uap->offset, uap->nbytes, &sbytes, hdr_uio, trl_uio, &hdtr_kq); + AUDIT_ARG_FD(uap->fd); - if (uap->sbytes != NULL) { + /* + * sendfile(2) can start at any offset within a file so we require + * CAP_READ+CAP_SEEK = CAP_PREAD. + */ + if ((error = fget_read(td, uap->fd, + cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) { + goto out; + } + + error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, uap->offset, + uap->nbytes, &sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); + fdrop(fp, td); + + if (uap->sbytes != NULL) copyout(&sbytes, uap->sbytes, sizeof(off_t)); - } + out: free(hdr_uio, M_IOV); free(trl_uio, M_IOV); @@ -2819,7 +2168,7 @@ kern_sendfile_getsock(struct thread *td, int s, struct file **sock_fp, int vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags, - int kflags, struct sendfile_sync *sfs, struct thread *td) + int kflags, struct thread *td) { struct file *sock_fp; struct vnode *vp; @@ -2829,6 +2178,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct sf_buf *sf; struct vm_page *pg; struct shmfd *shmfd; + struct sendfile_sync *sfs; struct vattr va; off_t off, xfsize, fsbytes, sbytes, rem, obj_size; int error, bsize, nd, hdrlen, mnw; @@ -2837,6 +2187,7 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, obj = NULL; so = NULL; m = NULL; + sfs = NULL; fsbytes = sbytes = 0; hdrlen = mnw = 0; rem = nbytes; @@ -2860,6 +2211,12 @@ vn_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, if (flags & SF_MNOWAIT) mnw = 1; + if (flags & SF_SYNC) { + sfs = malloc(sizeof *sfs, M_TEMP, M_WAITOK | M_ZERO); + mtx_init(&sfs->mtx, "sendfile", NULL, MTX_DEF); + cv_init(&sfs->cv, "sendfile"); + } + #ifdef MAC error = mac_socket_check_send(td->td_ucred, so); if (error != 0) @@ -3106,12 +2463,11 @@ retry_space: loopbytes += xfsize; off += xfsize; - /* - * XXX eventually this should be a sfsync - * method call! - */ - if (sfs != NULL) - sf_sync_ref(sfs); + if (sfs != NULL) { + mtx_lock(&sfs->mtx); + sfs->count++; + mtx_unlock(&sfs->mtx); + } } if (vp != NULL) @@ -3193,6 +2549,16 @@ out: if (m) m_freem(m); + if (sfs != NULL) { + mtx_lock(&sfs->mtx); + if (sfs->count != 0) + cv_wait(&sfs->cv, &sfs->mtx); + KASSERT(sfs->count == 0, ("sendfile sync still busy")); + cv_destroy(&sfs->cv); + mtx_destroy(&sfs->mtx); + free(sfs, M_TEMP); + } + if (error == ERESTART) error = EINTR; diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index 11b27d93d11..00fd8099c2e 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -793,10 +793,9 @@ uipc_rcvd(struct socket *so, int flags) u_int mbcnt, sbcc; unp = sotounpcb(so); - KASSERT(unp != NULL, ("uipc_rcvd: unp == NULL")); - - if (so->so_type != SOCK_STREAM && so->so_type != SOCK_SEQPACKET) - panic("uipc_rcvd socktype %d", so->so_type); + KASSERT(unp != NULL, ("%s: unp == NULL", __func__)); + KASSERT(so->so_type == SOCK_STREAM || so->so_type == SOCK_SEQPACKET, + ("%s: socktype %d", __func__, so->so_type)); /* * Adjust backpressure on sender and wakeup any waiting to write. @@ -810,7 +809,7 @@ uipc_rcvd(struct socket *so, int flags) */ SOCKBUF_LOCK(&so->so_rcv); mbcnt = so->so_rcv.sb_mbcnt; - sbcc = so->so_rcv.sb_cc; + sbcc = sbavail(&so->so_rcv); SOCKBUF_UNLOCK(&so->so_rcv); /* * There is a benign race condition at this point. If we're planning to @@ -846,7 +845,10 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, int error = 0; unp = sotounpcb(so); - KASSERT(unp != NULL, ("uipc_send: unp == NULL")); + KASSERT(unp != NULL, ("%s: unp == NULL", __func__)); + KASSERT(so->so_type == SOCK_STREAM || so->so_type == SOCK_DGRAM || + so->so_type == SOCK_SEQPACKET, + ("%s: socktype %d", __func__, so->so_type)); if (flags & PRUS_OOB) { error = EOPNOTSUPP; @@ -997,8 +999,11 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, } mbcnt = so2->so_rcv.sb_mbcnt; - sbcc = so2->so_rcv.sb_cc; - sorwakeup_locked(so2); + sbcc = sbavail(&so2->so_rcv); + if (sbcc) + sorwakeup_locked(so2); + else + SOCKBUF_UNLOCK(&so2->so_rcv); /* * The PCB lock on unp2 protects the SB_STOP flag. Without it, @@ -1014,9 +1019,6 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, UNP_PCB_UNLOCK(unp2); m = NULL; break; - - default: - panic("uipc_send unknown socktype"); } /* diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 2816e1ba8c7..a050099737a 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -238,7 +238,7 @@ vfs_mountroot_devfs(struct thread *td, struct mount **mpp) *mpp = mp; set_rootvnode(); - error = kern_symlink(td, "/", "dev", UIO_SYSSPACE); + error = kern_symlinkat(td, "/", AT_FDCWD, "dev", UIO_SYSSPACE); if (error) printf("kern_symlink /dev -> / returns %d\n", error); @@ -350,7 +350,8 @@ vfs_mountroot_shuffle(struct thread *td, struct mount *mpdevfs) if (mporoot == mpdevfs) { vfs_unbusy(mpdevfs); /* Unlink the no longer needed /dev/dev -> / symlink */ - error = kern_unlink(td, "/dev/dev", UIO_SYSSPACE); + error = kern_unlinkat(td, AT_FDCWD, "/dev/dev", + UIO_SYSSPACE, 0); if (error && bootverbose) printf("mountroot: unable to unlink /dev/dev " "(error %d)\n", error); @@ -524,12 +525,13 @@ parse_dir_md(char **conf) free(tok, M_TEMP); /* Get file status. */ - error = kern_stat(td, path, UIO_SYSSPACE, &sb); + error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &sb, NULL); if (error) goto out; /* Open /dev/mdctl so that we can attach/detach. */ - error = kern_open(td, "/dev/" MDCTL_NAME, UIO_SYSSPACE, O_RDWR, 0); + error = kern_openat(td, AT_FDCWD, "/dev/" MDCTL_NAME, UIO_SYSSPACE, + O_RDWR, 0); if (error) goto out; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 04c1c7bade1..2bcf85d352c 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -96,8 +96,6 @@ SDT_PROBE_DEFINE2(vfs, , stat, reg, "char *", "int"); static int chroot_refuse_vdir_fds(struct filedesc *fdp); static int getutimes(const struct timeval *, enum uio_seg, struct timespec *); -static int kern_chflags(struct thread *td, const char *path, - enum uio_seg pathseg, u_long flags); static int kern_chflagsat(struct thread *td, int fd, const char *path, enum uio_seg pathseg, u_long flags, int atflag); static int setfflags(struct thread *td, struct vnode *, u_long); @@ -114,11 +112,6 @@ static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred, */ int async_io_version; -#ifdef DEBUG -static int syncprt = 0; -SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, ""); -#endif - /* * Sync each mounted filesystem. */ @@ -1017,7 +1010,8 @@ sys_open(td, uap) } */ *uap; { - return (kern_open(td, uap->path, UIO_USERSPACE, uap->flags, uap->mode)); + return (kern_openat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->flags, uap->mode)); } #ifndef _SYS_SYSPROTO_H_ @@ -1036,14 +1030,6 @@ sys_openat(struct thread *td, struct openat_args *uap) uap->mode)); } -int -kern_open(struct thread *td, char *path, enum uio_seg pathseg, int flags, - int mode) -{ - - return (kern_openat(td, AT_FDCWD, path, pathseg, flags, mode)); -} - int kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int flags, int mode) @@ -1202,7 +1188,7 @@ ocreat(td, uap) } */ *uap; { - return (kern_open(td, uap->path, UIO_USERSPACE, + return (kern_openat(td, AT_FDCWD, uap->path, UIO_USERSPACE, O_WRONLY | O_CREAT | O_TRUNC, uap->mode)); } #endif /* COMPAT_43 */ @@ -1227,7 +1213,8 @@ sys_mknod(td, uap) } */ *uap; { - return (kern_mknod(td, uap->path, UIO_USERSPACE, uap->mode, uap->dev)); + return (kern_mknodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->mode, uap->dev)); } #ifndef _SYS_SYSPROTO_H_ @@ -1246,14 +1233,6 @@ sys_mknodat(struct thread *td, struct mknodat_args *uap) uap->dev)); } -int -kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, int mode, - int dev) -{ - - return (kern_mknodat(td, AT_FDCWD, path, pathseg, mode, dev)); -} - int kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode, int dev) @@ -1373,7 +1352,8 @@ sys_mkfifo(td, uap) } */ *uap; { - return (kern_mkfifo(td, uap->path, UIO_USERSPACE, uap->mode)); + return (kern_mkfifoat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->mode)); } #ifndef _SYS_SYSPROTO_H_ @@ -1391,13 +1371,6 @@ sys_mkfifoat(struct thread *td, struct mkfifoat_args *uap) uap->mode)); } -int -kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, int mode) -{ - - return (kern_mkfifoat(td, AT_FDCWD, path, pathseg, mode)); -} - int kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode) @@ -1470,7 +1443,8 @@ sys_link(td, uap) } */ *uap; { - return (kern_link(td, uap->path, uap->link, UIO_USERSPACE)); + return (kern_linkat(td, AT_FDCWD, AT_FDCWD, uap->path, uap->link, + UIO_USERSPACE, FOLLOW)); } #ifndef _SYS_SYSPROTO_H_ @@ -1534,13 +1508,6 @@ can_hardlink(struct vnode *vp, struct ucred *cred) return (0); } -int -kern_link(struct thread *td, char *path, char *link, enum uio_seg segflg) -{ - - return (kern_linkat(td, AT_FDCWD, AT_FDCWD, path,link, segflg, FOLLOW)); -} - int kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, enum uio_seg segflg, int follow) @@ -1643,7 +1610,8 @@ sys_symlink(td, uap) } */ *uap; { - return (kern_symlink(td, uap->path, uap->link, UIO_USERSPACE)); + return (kern_symlinkat(td, uap->path, AT_FDCWD, uap->link, + UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ @@ -1661,13 +1629,6 @@ sys_symlinkat(struct thread *td, struct symlinkat_args *uap) UIO_USERSPACE)); } -int -kern_symlink(struct thread *td, char *path, char *link, enum uio_seg segflg) -{ - - return (kern_symlinkat(td, path, AT_FDCWD, link, segflg)); -} - int kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, enum uio_seg segflg) @@ -1796,7 +1757,7 @@ sys_unlink(td, uap) } */ *uap; { - return (kern_unlink(td, uap->path, UIO_USERSPACE)); + return (kern_unlinkat(td, AT_FDCWD, uap->path, UIO_USERSPACE, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -1822,13 +1783,6 @@ sys_unlinkat(struct thread *td, struct unlinkat_args *uap) return (kern_unlinkat(td, fd, path, UIO_USERSPACE, 0)); } -int -kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) -{ - - return (kern_unlinkat(td, AT_FDCWD, path, pathseg, 0)); -} - int kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, ino_t oldinum) @@ -2032,7 +1986,8 @@ sys_access(td, uap) } */ *uap; { - return (kern_access(td, uap->path, UIO_USERSPACE, uap->amode)); + return (kern_accessat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + 0, uap->amode)); } #ifndef _SYS_SYSPROTO_H_ @@ -2047,19 +2002,10 @@ int sys_faccessat(struct thread *td, struct faccessat_args *uap) { - if (uap->flag & ~AT_EACCESS) - return (EINVAL); return (kern_accessat(td, uap->fd, uap->path, UIO_USERSPACE, uap->flag, uap->amode)); } -int -kern_access(struct thread *td, char *path, enum uio_seg pathseg, int amode) -{ - - return (kern_accessat(td, AT_FDCWD, path, pathseg, 0, amode)); -} - int kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int flag, int amode) @@ -2070,6 +2016,8 @@ kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, cap_rights_t rights; int error; + if (flag & ~AT_EACCESS) + return (EINVAL); if (amode != F_OK && (amode & ~(R_OK | W_OK | X_OK)) != 0) return (EINVAL); @@ -2124,14 +2072,8 @@ sys_eaccess(td, uap) } */ *uap; { - return (kern_eaccess(td, uap->path, UIO_USERSPACE, uap->amode)); -} - -int -kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, int amode) -{ - - return (kern_accessat(td, AT_FDCWD, path, pathseg, AT_EACCESS, amode)); + return (kern_accessat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + AT_EACCESS, uap->amode)); } #if defined(COMPAT_43) @@ -2156,7 +2098,8 @@ ostat(td, uap) struct ostat osb; int error; - error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, + &sb, NULL); if (error != 0) return (error); cvtstat(&sb, &osb); @@ -2184,7 +2127,8 @@ olstat(td, uap) struct ostat osb; int error; - error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, + UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); cvtstat(&sb, &osb); @@ -2241,7 +2185,8 @@ sys_stat(td, uap) struct stat sb; int error; - error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, + &sb, NULL); if (error == 0) error = copyout(&sb, uap->ub, sizeof (sb)); return (error); @@ -2262,29 +2207,14 @@ sys_fstatat(struct thread *td, struct fstatat_args *uap) int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, - UIO_USERSPACE, &sb); + UIO_USERSPACE, &sb, NULL); if (error == 0) error = copyout(&sb, uap->buf, sizeof (sb)); return (error); } -int -kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) -{ - - return (kern_statat(td, 0, AT_FDCWD, path, pathseg, sbp)); -} - int kern_statat(struct thread *td, int flag, int fd, char *path, - enum uio_seg pathseg, struct stat *sbp) -{ - - return (kern_statat_vnhook(td, flag, fd, path, pathseg, sbp, NULL)); -} - -int -kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, enum uio_seg pathseg, struct stat *sbp, void (*hook)(struct vnode *vp, struct stat *sbp)) { @@ -2342,20 +2272,13 @@ sys_lstat(td, uap) struct stat sb; int error; - error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, + UIO_USERSPACE, &sb, NULL); if (error == 0) error = copyout(&sb, uap->ub, sizeof (sb)); return (error); } -int -kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp) -{ - - return (kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, path, pathseg, - sbp)); -} - /* * Implementation of the NetBSD [l]stat() functions. */ @@ -2402,7 +2325,8 @@ sys_nstat(td, uap) struct nstat nsb; int error; - error = kern_stat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, + &sb, NULL); if (error != 0) return (error); cvtnstat(&sb, &nsb); @@ -2430,7 +2354,8 @@ sys_nlstat(td, uap) struct nstat nsb; int error; - error = kern_lstat(td, uap->path, UIO_USERSPACE, &sb); + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, + UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); cvtnstat(&sb, &nsb); @@ -2519,8 +2444,8 @@ sys_readlink(td, uap) } */ *uap; { - return (kern_readlink(td, uap->path, UIO_USERSPACE, uap->buf, - UIO_USERSPACE, uap->count)); + return (kern_readlinkat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->buf, UIO_USERSPACE, uap->count)); } #ifndef _SYS_SYSPROTO_H_ struct readlinkat_args { @@ -2538,15 +2463,6 @@ sys_readlinkat(struct thread *td, struct readlinkat_args *uap) uap->buf, UIO_USERSPACE, uap->bufsize)); } -int -kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, char *buf, - enum uio_seg bufseg, size_t count) -{ - - return (kern_readlinkat(td, AT_FDCWD, path, pathseg, buf, bufseg, - count)); -} - int kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count) @@ -2655,7 +2571,8 @@ sys_chflags(td, uap) } */ *uap; { - return (kern_chflags(td, uap->path, UIO_USERSPACE, uap->flags)); + return (kern_chflagsat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->flags, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -2680,14 +2597,6 @@ sys_chflagsat(struct thread *td, struct chflagsat_args *uap) return (kern_chflagsat(td, fd, path, UIO_USERSPACE, flags, atflag)); } -static int -kern_chflags(struct thread *td, const char *path, enum uio_seg pathseg, - u_long flags) -{ - - return (kern_chflagsat(td, AT_FDCWD, path, pathseg, flags, 0)); -} - /* * Same as chflags() but doesn't follow symlinks. */ @@ -2808,7 +2717,8 @@ sys_chmod(td, uap) } */ *uap; { - return (kern_chmod(td, uap->path, UIO_USERSPACE, uap->mode)); + return (kern_fchmodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->mode, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -2833,13 +2743,6 @@ sys_fchmodat(struct thread *td, struct fchmodat_args *uap) return (kern_fchmodat(td, fd, path, UIO_USERSPACE, mode, flag)); } -int -kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, int mode) -{ - - return (kern_fchmodat(td, AT_FDCWD, path, pathseg, mode, 0)); -} - /* * Change mode of a file given path name (don't follow links.) */ @@ -2961,7 +2864,8 @@ sys_chown(td, uap) } */ *uap; { - return (kern_chown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); + return (kern_fchownat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->uid, + uap->gid, 0)); } #ifndef _SYS_SYSPROTO_H_ @@ -2986,14 +2890,6 @@ sys_fchownat(struct thread *td, struct fchownat_args *uap) uap->gid, uap->flag)); } -int -kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, - int gid) -{ - - return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, 0)); -} - int kern_fchownat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int uid, int gid, int flag) @@ -3035,16 +2931,8 @@ sys_lchown(td, uap) } */ *uap; { - return (kern_lchown(td, uap->path, UIO_USERSPACE, uap->uid, uap->gid)); -} - -int -kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, - int gid) -{ - - return (kern_fchownat(td, AT_FDCWD, path, pathseg, uid, gid, - AT_SYMLINK_NOFOLLOW)); + return (kern_fchownat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->uid, uap->gid, AT_SYMLINK_NOFOLLOW)); } /* @@ -3174,8 +3062,8 @@ sys_utimes(td, uap) } */ *uap; { - return (kern_utimes(td, uap->path, UIO_USERSPACE, uap->tptr, - UIO_USERSPACE)); + return (kern_utimesat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->tptr, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ @@ -3193,14 +3081,6 @@ sys_futimesat(struct thread *td, struct futimesat_args *uap) uap->times, UIO_USERSPACE)); } -int -kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, - struct timeval *tptr, enum uio_seg tptrseg) -{ - - return (kern_utimesat(td, AT_FDCWD, path, pathseg, tptr, tptrseg)); -} - int kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg) @@ -3500,7 +3380,8 @@ sys_rename(td, uap) } */ *uap; { - return (kern_rename(td, uap->from, uap->to, UIO_USERSPACE)); + return (kern_renameat(td, AT_FDCWD, uap->from, AT_FDCWD, + uap->to, UIO_USERSPACE)); } #ifndef _SYS_SYSPROTO_H_ @@ -3519,13 +3400,6 @@ sys_renameat(struct thread *td, struct renameat_args *uap) UIO_USERSPACE)); } -int -kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) -{ - - return (kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, pathseg)); -} - int kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, enum uio_seg pathseg) @@ -3675,7 +3549,8 @@ sys_mkdir(td, uap) } */ *uap; { - return (kern_mkdir(td, uap->path, UIO_USERSPACE, uap->mode)); + return (kern_mkdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE, + uap->mode)); } #ifndef _SYS_SYSPROTO_H_ @@ -3692,13 +3567,6 @@ sys_mkdirat(struct thread *td, struct mkdirat_args *uap) return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); } -int -kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, int mode) -{ - - return (kern_mkdirat(td, AT_FDCWD, path, segflg, mode)); -} - int kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, int mode) @@ -3777,14 +3645,7 @@ sys_rmdir(td, uap) } */ *uap; { - return (kern_rmdir(td, uap->path, UIO_USERSPACE)); -} - -int -kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) -{ - - return (kern_rmdirat(td, AT_FDCWD, path, pathseg)); + return (kern_rmdirat(td, AT_FDCWD, uap->path, UIO_USERSPACE)); } int @@ -4553,38 +4414,29 @@ kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) off_t olen, ooffset; int error; - fp = NULL; + if (offset < 0 || len <= 0) + return (EINVAL); + /* Check for wrap. */ + if (offset > OFF_MAX - len) + return (EFBIG); error = fget(td, fd, cap_rights_init(&rights, CAP_WRITE), &fp); if (error != 0) - goto out; - - switch (fp->f_type) { - case DTYPE_VNODE: - break; - case DTYPE_PIPE: - case DTYPE_FIFO: + return (error); + if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) { error = ESPIPE; goto out; - default: - error = ENODEV; - goto out; } if ((fp->f_flag & FWRITE) == 0) { error = EBADF; goto out; } - vp = fp->f_vnode; - if (vp->v_type != VREG) { + if (fp->f_type != DTYPE_VNODE) { error = ENODEV; goto out; } - if (offset < 0 || len <= 0) { - error = EINVAL; - goto out; - } - /* Check for wrap. */ - if (offset > OFF_MAX - len) { - error = EFBIG; + vp = fp->f_vnode; + if (vp->v_type != VREG) { + error = ENODEV; goto out; } @@ -4621,8 +4473,7 @@ kern_posix_fallocate(struct thread *td, int fd, off_t offset, off_t len) maybe_yield(); } out: - if (fp != NULL) - fdrop(fp, td); + fdrop(fp, td); return (error); } @@ -4672,15 +4523,11 @@ kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, error = fget(td, fd, cap_rights_init(&rights), &fp); if (error != 0) goto out; - - switch (fp->f_type) { - case DTYPE_VNODE: - break; - case DTYPE_PIPE: - case DTYPE_FIFO: + if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) { error = ESPIPE; goto out; - default: + } + if (fp->f_type != DTYPE_VNODE) { error = ENODEV; goto out; } diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index b3e1c3bf45c..ee45e01aecf 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1881,8 +1881,10 @@ vfs_write_suspend_umnt(struct mount *mp) for (;;) { vn_finished_write(mp); error = vfs_write_suspend(mp, 0); - if (error != 0) + if (error != 0) { + vn_start_write(NULL, &mp, V_WAIT); return (error); + } MNT_ILOCK(mp); if ((mp->mnt_kern_flag & MNTK_SUSPENDED) != 0) break; diff --git a/sys/libkern/strncmp.c b/sys/libkern/strncmp.c index 5758d249980..268ffbe4fe7 100644 --- a/sys/libkern/strncmp.c +++ b/sys/libkern/strncmp.c @@ -10,7 +10,7 @@ * 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. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -33,9 +33,7 @@ __FBSDID("$FreeBSD$"); #include int -strncmp(s1, s2, n) - register const char *s1, *s2; - register size_t n; +strncmp(const char *s1, const char *s2, size_t n) { if (n == 0) @@ -44,7 +42,7 @@ strncmp(s1, s2, n) if (*s1 != *s2++) return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); - if (*s1++ == 0) + if (*s1++ == '\0') break; } while (--n != 0); return (0); diff --git a/sys/mips/atheros/ar71xx_gpio.c b/sys/mips/atheros/ar71xx_gpio.c index 0e1633229cb..45ac8ffda2e 100644 --- a/sys/mips/atheros/ar71xx_gpio.c +++ b/sys/mips/atheros/ar71xx_gpio.c @@ -241,16 +241,8 @@ ar71xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - ar71xx_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); + return (0); } diff --git a/sys/mips/cavium/octeon_gpio.c b/sys/mips/cavium/octeon_gpio.c index 26b42eaca87..36868481a99 100644 --- a/sys/mips/cavium/octeon_gpio.c +++ b/sys/mips/cavium/octeon_gpio.c @@ -219,16 +219,8 @@ octeon_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - octeon_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); + return (0); } diff --git a/sys/mips/conf/GXEMUL b/sys/mips/conf/GXEMUL index ea5862287cc..fa0b9b51899 100644 --- a/sys/mips/conf/GXEMUL +++ b/sys/mips/conf/GXEMUL @@ -55,7 +55,6 @@ device ether # Ethernet support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/sys/mips/conf/GXEMUL32 b/sys/mips/conf/GXEMUL32 index 6bd756f20f7..27854c5fa2a 100644 --- a/sys/mips/conf/GXEMUL32 +++ b/sys/mips/conf/GXEMUL32 @@ -53,7 +53,6 @@ device ether # Ethernet support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/sys/mips/conf/MALTA b/sys/mips/conf/MALTA index fc082ad994a..4a0684db106 100644 --- a/sys/mips/conf/MALTA +++ b/sys/mips/conf/MALTA @@ -68,3 +68,4 @@ device miibus device bpf device md device uart +device random diff --git a/sys/mips/conf/MALTA64 b/sys/mips/conf/MALTA64 index 0f5bfdf4c4e..53c629859d6 100644 --- a/sys/mips/conf/MALTA64 +++ b/sys/mips/conf/MALTA64 @@ -53,7 +53,7 @@ options FFS #Berkeley Fast Filesystem options SOFTUPDATES #Enable FFS soft updates support options UFS_ACL #Support for access control lists options UFS_DIRHASH #Improve performance on big directories -options ROOTDEVNAME=\"ufs:ada0s1a\" +options ROOTDEVNAME=\"ufs:ada0\" # Debugging for use in -current @@ -70,3 +70,4 @@ device miibus device md device bpf device uart +device random diff --git a/sys/mips/conf/OCTEON1 b/sys/mips/conf/OCTEON1 index fb417cfccc0..9f22030c170 100644 --- a/sys/mips/conf/OCTEON1 +++ b/sys/mips/conf/OCTEON1 @@ -261,7 +261,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/mips/include/cache_mipsNN.h b/sys/mips/include/cache_mipsNN.h index 8318bede592..3fd75df93e7 100644 --- a/sys/mips/include/cache_mipsNN.h +++ b/sys/mips/include/cache_mipsNN.h @@ -67,5 +67,15 @@ void mipsNN_pdcache_wbinv_range_index_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_inv_range_128(vm_offset_t, vm_size_t); void mipsNN_pdcache_wb_range_128(vm_offset_t, vm_size_t); #endif +void mipsNN_sdcache_wbinv_all_32(void); +void mipsNN_sdcache_wbinv_range_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wbinv_range_index_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_inv_range_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wb_range_32(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wbinv_all_128(void); +void mipsNN_sdcache_wbinv_range_128(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wbinv_range_index_128(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_inv_range_128(vm_paddr_t, vm_size_t); +void mipsNN_sdcache_wb_range_128(vm_paddr_t, vm_size_t); #endif /* _MACHINE_CACHE_MIPSNN_H_ */ diff --git a/sys/mips/include/cpuinfo.h b/sys/mips/include/cpuinfo.h index 53b966c0a34..baf30392510 100644 --- a/sys/mips/include/cpuinfo.h +++ b/sys/mips/include/cpuinfo.h @@ -67,6 +67,12 @@ struct mips_cpuinfo { u_int8_t dc_nways; u_int16_t dc_nsets; } l1; + struct { + u_int32_t dc_size; + u_int8_t dc_linesize; + u_int8_t dc_nways; + u_int16_t dc_nsets; + } l2; }; extern struct mips_cpuinfo cpuinfo; diff --git a/sys/mips/include/cpuregs.h b/sys/mips/include/cpuregs.h index be8414f8fc3..d3515807c6e 100644 --- a/sys/mips/include/cpuregs.h +++ b/sys/mips/include/cpuregs.h @@ -550,6 +550,13 @@ #define MIPS_CONFIG1_EP 0x00000002 /* EJTAG implemented */ #define MIPS_CONFIG1_FP 0x00000001 /* FPU implemented */ +#define MIPS_CONFIG2_SA_SHIFT 0 /* Secondary cache associativity */ +#define MIPS_CONFIG2_SA_MASK 0xf +#define MIPS_CONFIG2_SL_SHIFT 4 /* Secondary cache line size */ +#define MIPS_CONFIG2_SL_MASK 0xf +#define MIPS_CONFIG2_SS_SHIFT 8 /* Secondary cache sets per way */ +#define MIPS_CONFIG2_SS_MASK 0xf + #define MIPS_CONFIG4_MMUSIZEEXT 0x000000FF /* bits 7.. 0 MMU Size Extension */ #define MIPS_CONFIG4_MMUEXTDEF 0x0000C000 /* bits 15.14 MMU Extension Definition */ #define MIPS_CONFIG4_MMUEXTDEF_MMUSIZEEXT 0x00004000 /* This values denotes CONFIG4 bits */ diff --git a/sys/mips/mips/cache.c b/sys/mips/mips/cache.c index 1a1d374f0ee..70a1db38042 100644 --- a/sys/mips/mips/cache.c +++ b/sys/mips/mips/cache.c @@ -260,19 +260,42 @@ mips_config_cache(struct mips_cpuinfo * cpuinfo) panic("no pdcache_wb_range"); } - /* XXXMIPS: No secondary cache handlers yet */ -#ifdef notyet - if (mips_sdcache_size) { - if (!mips_cache_ops.mco_sdcache_wbinv_all) - panic("no sdcache_wbinv_all"); - if (!mips_cache_ops.mco_sdcache_wbinv_range) - panic("no sdcache_wbinv_range"); - if (!mips_cache_ops.mco_sdcache_wbinv_range_index) - panic("no sdcache_wbinv_range_index"); - if (!mips_cache_ops.mco_sdcache_inv_range) - panic("no sdcache_inv_range"); - if (!mips_cache_ops.mco_sdcache_wb_range) - panic("no sdcache_wb_range"); + /* L2 data cache */ + if (!cpuinfo->l2.dc_size) { + /* No L2 found, ignore */ + return; } + + switch (cpuinfo->l2.dc_linesize) { + case 32: + mips_cache_ops.mco_sdcache_wbinv_all = + mipsNN_sdcache_wbinv_all_32; + mips_cache_ops.mco_sdcache_wbinv_range = + mipsNN_sdcache_wbinv_range_32; + mips_cache_ops.mco_sdcache_wbinv_range_index = + mipsNN_sdcache_wbinv_range_index_32; + mips_cache_ops.mco_sdcache_inv_range = + mipsNN_sdcache_inv_range_32; + mips_cache_ops.mco_sdcache_wb_range = + mipsNN_sdcache_wb_range_32; + break; + case 128: + mips_cache_ops.mco_sdcache_wbinv_all = + mipsNN_sdcache_wbinv_all_128; + mips_cache_ops.mco_sdcache_wbinv_range = + mipsNN_sdcache_wbinv_range_128; + mips_cache_ops.mco_sdcache_wbinv_range_index = + mipsNN_sdcache_wbinv_range_index_128; + mips_cache_ops.mco_sdcache_inv_range = + mipsNN_sdcache_inv_range_128; + mips_cache_ops.mco_sdcache_wb_range = + mipsNN_sdcache_wb_range_128; + break; + default: +#ifdef CACHE_DEBUG + printf(" no sdcache ops for %d byte lines", + cpuinfo->l2.dc_linesize); #endif + break; + } } diff --git a/sys/mips/mips/cache_mipsNN.c b/sys/mips/mips/cache_mipsNN.c index 823391cf933..ac104c2cfd2 100644 --- a/sys/mips/mips/cache_mipsNN.c +++ b/sys/mips/mips/cache_mipsNN.c @@ -52,6 +52,9 @@ __FBSDID("$FreeBSD$"); #define round_line32(x) (((x) + 31) & ~31) #define trunc_line32(x) ((x) & ~31) +#define round_line128(x) (((x) + 127) & ~127) +#define trunc_line128(x) ((x) & ~127) + #if defined(CPU_NLM) static __inline void xlp_sync(void) @@ -100,6 +103,10 @@ static int pdcache_size; static int pdcache_stride; static int pdcache_loopcount; static int pdcache_way_mask; +static int sdcache_size; +static int sdcache_stride; +static int sdcache_loopcount; +static int sdcache_way_mask; void mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) @@ -142,6 +149,11 @@ mipsNN_cache_init(struct mips_cpuinfo * cpuinfo) pdcache_size = cpuinfo->l1.dc_size; pdcache_way_mask = cpuinfo->l1.dc_nways - 1; + sdcache_stride = cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_linesize; + sdcache_loopcount = cpuinfo->l2.dc_nways; + sdcache_size = cpuinfo->l2.dc_size; + sdcache_way_mask = cpuinfo->l2.dc_nways - 1; + #define CACHE_DEBUG #ifdef CACHE_DEBUG printf("Cache info:\n"); @@ -636,3 +648,195 @@ mipsNN_pdcache_wb_range_128(vm_offset_t va, vm_size_t size) } #endif + +void +mipsNN_sdcache_wbinv_all_32(void) +{ + vm_offset_t va = MIPS_PHYS_TO_KSEG0(0); + vm_offset_t eva = va + sdcache_size; + + while (va < eva) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 32); + } +} + +void +mipsNN_sdcache_wbinv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line32(va + size); + + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += 32; + } +} + +void +mipsNN_sdcache_wbinv_range_index_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + /* + * Since we're doing Index ops, we expect to not be able + * to access the address we've been given. So, get the + * bits that determine the cache index, and make a KSEG0 + * address out of them. + */ + va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1)); + + eva = round_line32(va + size); + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += 32; + } +} + +void +mipsNN_sdcache_inv_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line32(va + size); + + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += 32; + } +} + +void +mipsNN_sdcache_wb_range_32(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line32(va + size); + + va = trunc_line32(va); + + while ((eva - va) >= (32 * 32)) { + cache_r4k_op_32lines_32(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += (32 * 32); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += 32; + } +} + +void +mipsNN_sdcache_wbinv_all_128(void) +{ + vm_offset_t va = MIPS_PHYS_TO_KSEG0(0); + vm_offset_t eva = va + sdcache_size; + + while (va < eva) { + cache_r4k_op_32lines_128(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 128); + } +} + +void +mipsNN_sdcache_wbinv_range_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line128(va + size); + + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, + CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB_INV); + va += 128; + } +} + +void +mipsNN_sdcache_wbinv_range_index_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva; + + /* + * Since we're doing Index ops, we expect to not be able + * to access the address we've been given. So, get the + * bits that determine the cache index, and make a KSEG0 + * address out of them. + */ + va = MIPS_PHYS_TO_KSEG0(va & (sdcache_size - 1)); + + eva = round_line128(va + size); + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, + CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_INDEX_WB_INV); + va += 128; + } +} + +void +mipsNN_sdcache_inv_range_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line128(va + size); + + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_INV); + va += 128; + } +} + +void +mipsNN_sdcache_wb_range_128(vm_offset_t va, vm_size_t size) +{ + vm_offset_t eva = round_line128(va + size); + + va = trunc_line128(va); + + while ((eva - va) >= (32 * 128)) { + cache_r4k_op_32lines_128(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += (32 * 128); + } + + while (va < eva) { + cache_op_r4k_line(va, CACHE_R4K_SD|CACHEOP_R4K_HIT_WB); + va += 128; + } +} diff --git a/sys/mips/mips/cpu.c b/sys/mips/mips/cpu.c index c31cd5b5a82..b53bde801b4 100644 --- a/sys/mips/mips/cpu.c +++ b/sys/mips/mips/cpu.c @@ -73,6 +73,7 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) u_int32_t prid; u_int32_t cfg0; u_int32_t cfg1; + u_int32_t cfg2; #if defined(CPU_CNMIPS) u_int32_t cfg4; #endif @@ -186,6 +187,31 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo) * cpuinfo->l1.ic_nsets * cpuinfo->l1.ic_nways; cpuinfo->l1.dc_size = cpuinfo->l1.dc_linesize * cpuinfo->l1.dc_nsets * cpuinfo->l1.dc_nways; + +#ifndef CPU_CNMIPS + /* L2 cache */ + if (!(cfg1 & MIPS_CONFIG_CM)) { + /* We don't have valid cfg2 register */ + return; + } + + cfg2 = mips_rd_config2(); + + tmp = (cfg2 >> MIPS_CONFIG2_SL_SHIFT) & MIPS_CONFIG2_SL_MASK; + if (0 < tmp && tmp <= 7) + cpuinfo->l2.dc_linesize = 2 << tmp; + + tmp = (cfg2 >> MIPS_CONFIG2_SS_SHIFT) & MIPS_CONFIG2_SS_MASK; + if (0 <= tmp && tmp <= 7) + cpuinfo->l2.dc_nsets = 64 << tmp; + + tmp = (cfg2 >> MIPS_CONFIG2_SA_SHIFT) & MIPS_CONFIG2_SA_MASK; + if (0 <= tmp && tmp <= 7) + cpuinfo->l2.dc_nways = tmp + 1; + + cpuinfo->l2.dc_size = cpuinfo->l2.dc_linesize + * cpuinfo->l2.dc_nsets * cpuinfo->l2.dc_nways; +#endif } void @@ -355,6 +381,7 @@ static driver_t cpu_driver = { static int cpu_probe(device_t dev) { + return (0); } diff --git a/sys/mips/mips/stdatomic.c b/sys/mips/mips/stdatomic.c index a587446a8db..f9fb590eb1b 100644 --- a/sys/mips/mips/stdatomic.c +++ b/sys/mips/mips/stdatomic.c @@ -33,10 +33,6 @@ __FBSDID("$FreeBSD$"); #include #include -#ifdef _KERNEL -#include "opt_global.h" -#endif - #if defined(__SYNC_ATOMICS) /* diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index df5efc02033..a4405ae5941 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" #include "opt_ddb.h" -#include "opt_global.h" #include "opt_ktrace.h" #include diff --git a/sys/mips/rmi/rootfs_list.txt b/sys/mips/rmi/rootfs_list.txt index 048321a30ad..86895b6a2f5 100644 --- a/sys/mips/rmi/rootfs_list.txt +++ b/sys/mips/rmi/rootfs_list.txt @@ -197,7 +197,6 @@ ./etc/rc.d/dmesg ./etc/rc.d/dumpon ./etc/rc.d/encswap -./etc/rc.d/faith ./etc/rc.d/fsck ./etc/rc.d/ftp-proxy ./etc/rc.d/ftpd diff --git a/sys/mips/rt305x/rt305x_gpio.c b/sys/mips/rt305x/rt305x_gpio.c index 5f7defbcc4e..a5d72549bd0 100644 --- a/sys/mips/rt305x/rt305x_gpio.c +++ b/sys/mips/rt305x/rt305x_gpio.c @@ -242,18 +242,8 @@ rt305x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (i >= sc->gpio_npins) return (EINVAL); - /* Check for unwanted flags. */ - if ((flags & sc->gpio_pins[i].gp_caps) != flags) - return (EINVAL); - - /* Can't mix input/output together */ - if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == - (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) - return (EINVAL); - rt305x_gpio_pin_configure(sc, &sc->gpio_pins[i], flags); - return (0); } diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 0ca6f63df72..fedc92e362c 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -145,7 +145,6 @@ SUBDIR= \ if_disc \ if_edsc \ if_epair \ - if_faith \ ${_if_gif} \ ${_if_gre} \ ${_if_me} \ diff --git a/sys/modules/cxgb/tom/Makefile b/sys/modules/cxgb/tom/Makefile index 64eecaf367f..0316cce2815 100644 --- a/sys/modules/cxgb/tom/Makefile +++ b/sys/modules/cxgb/tom/Makefile @@ -6,7 +6,7 @@ CXGB = ${.CURDIR}/../../../dev/cxgb KMOD= t3_tom SRCS= cxgb_tom.c cxgb_cpl_io.c cxgb_listen.c cxgb_l2t.c SRCS+= opt_compat.h opt_inet.h opt_inet6.h opt_ipsec.h -SRCS+= opt_tcpdebug.h opt_ddb.h opt_sched.h opt_global.h opt_ktr.h +SRCS+= opt_tcpdebug.h opt_ddb.h opt_sched.h opt_ktr.h SRCS+= device_if.h bus_if.h pci_if.h CFLAGS+= -g -I${CXGB} diff --git a/sys/modules/dpt/Makefile b/sys/modules/dpt/Makefile index 15019e09001..21b3b08ea39 100644 --- a/sys/modules/dpt/Makefile +++ b/sys/modules/dpt/Makefile @@ -20,7 +20,6 @@ opt_eisa.h: .else .if !defined(KERNBUILDDIR) SRCS+= dpt_eisa.c eisa_if.h -#SRCS+= dpt_isa.c isa_if.h opt_eisa.h: echo "#define DEV_EISA 1" > ${.TARGET} @@ -29,7 +28,6 @@ DEV_EISA!= sed -n '/DEV_EISA/p' ${KERNBUILDDIR}/opt_eisa.h .if !empty(DEV_EISA) SRCS+= dpt_eisa.c eisa_if.h .endif -#SRCS+= dpt_isa.c isa_if.h .endif .endif diff --git a/sys/modules/geom/geom_part/geom_part_bsd/Makefile b/sys/modules/geom/geom_part/geom_part_bsd/Makefile index 2a10b34ddd0..9a6e76d3189 100644 --- a/sys/modules/geom/geom_part/geom_part_bsd/Makefile +++ b/sys/modules/geom/geom_part/geom_part_bsd/Makefile @@ -1,9 +1,9 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../../../geom/part +.PATH: ${.CURDIR}/../../../../geom/part ${.CURDIR}/../../../../geom KMOD= geom_part_bsd -SRCS= g_part_bsd.c +SRCS= g_part_bsd.c geom_bsd_enc.c SRCS+= bus_if.h device_if.h g_part_if.h diff --git a/sys/modules/if_faith/Makefile b/sys/modules/if_faith/Makefile deleted file mode 100644 index fe78ec9be48..00000000000 --- a/sys/modules/if_faith/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../net - -KMOD= if_faith -SRCS= if_faith.c opt_inet.h opt_inet6.h - -.include diff --git a/sys/modules/if_gif/Makefile b/sys/modules/if_gif/Makefile index af8c3c72fea..663c679f463 100644 --- a/sys/modules/if_gif/Makefile +++ b/sys/modules/if_gif/Makefile @@ -8,13 +8,6 @@ SYSDIR?=${.CURDIR}/../.. KMOD= if_gif SRCS= if_gif.c in_gif.c opt_inet.h opt_inet6.h -.if defined(KERNBUILDDIR) -OPT_INET6!= cat ${KERNBUILDDIR}/opt_inet6.h; echo -.if empty(OPT_INET6) -MK_INET6_SUPPORT=no -.endif -.endif - .if ${MK_INET6_SUPPORT} != "no" SRCS+= in6_gif.c .endif diff --git a/sys/modules/if_gre/Makefile b/sys/modules/if_gre/Makefile index 54ef274419a..b1d370a47ce 100644 --- a/sys/modules/if_gre/Makefile +++ b/sys/modules/if_gre/Makefile @@ -1,29 +1,16 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../net ${.CURDIR}/../../netinet ${.CURDIR}/../../netinet6 -.include "${.CURDIR}/../../conf/kern.opts.mk" +SYSDIR?=${.CURDIR}/../.. +.PATH: ${SYSDIR}/net ${SYSDIR}/netinet ${SYSDIR}/netinet6 +.include "${SYSDIR}/conf/kern.opts.mk" KMOD= if_gre SRCS= if_gre.c opt_inet.h opt_inet6.h -.if defined(KERNBUILDDIR) -OPT_INET!= cat ${KERNBUILDDIR}/opt_inet.h; echo -.if empty(OPT_INET) -MK_INET_SUPPORT=no -.endif -.endif - .if ${MK_INET_SUPPORT} != "no" SRCS+= ip_gre.c .endif -.if defined(KERNBUILDDIR) -OPT_INET6!= cat ${KERNBUILDDIR}/opt_inet6.h; echo -.if empty(OPT_INET6) -MK_INET6_SUPPORT=no -.endif -.endif - .if ${MK_INET6_SUPPORT} != "no" SRCS+= ip6_gre.c .endif diff --git a/sys/modules/lmc/Makefile b/sys/modules/lmc/Makefile index 7a53f3e4bb0..66fc0e652bb 100644 --- a/sys/modules/lmc/Makefile +++ b/sys/modules/lmc/Makefile @@ -7,12 +7,9 @@ SRCS = if_lmc.c if_lmc.h SRCS += device_if.h bus_if.h pci_if.h SRCS += opt_inet.h opt_inet6.h SRCS += opt_netgraph.h -SRCS += opt_global.h SRCS += opt_bpf.h opt_netgraph.h: echo "#define NETGRAPH 1" > ${.TARGET} -opt_global.h: - echo "#define ALTQ 1" > ${.TARGET} .include diff --git a/sys/net/ethernet.h b/sys/net/ethernet.h index 0ab82851d6f..63103e9fa6f 100644 --- a/sys/net/ethernet.h +++ b/sys/net/ethernet.h @@ -72,6 +72,25 @@ struct ether_addr { #define ETHER_IS_MULTICAST(addr) (*(addr) & 0x01) /* is address mcast/bcast? */ +/* + * 802.1q Virtual LAN header. + */ +struct ether_vlan_header { + uint8_t evl_dhost[ETHER_ADDR_LEN]; + uint8_t evl_shost[ETHER_ADDR_LEN]; + uint16_t evl_encap_proto; + uint16_t evl_tag; + uint16_t evl_proto; +} __packed; + +#define EVL_VLID_MASK 0x0FFF +#define EVL_PRI_MASK 0xE000 +#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK) +#define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7) +#define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1) +#define EVL_MAKETAG(vlid, pri, cfi) \ + ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) + /* * NOTE: 0x0000-0x05DC (0..1500) are generally IEEE 802.3 length fields. * However, there are some conflicts. diff --git a/sys/net/if.c b/sys/net/if.c index d4e52dc0f03..ba6b1181ad5 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -160,7 +160,6 @@ static void if_attachdomain(void *); static void if_attachdomain1(struct ifnet *); static int ifconf(u_long, caddr_t); static void if_freemulti(struct ifmultiaddr *); -static void if_init(void *); static void if_grow(void); static void if_route(struct ifnet *, int flag, int fam); static int if_setflag(struct ifnet *, int, int, int *, int); @@ -207,7 +206,9 @@ VNET_DEFINE(struct ifnet **, ifindex_table); * inversions and deadlocks. */ struct rwlock ifnet_rwlock; +RW_SYSINIT_FLAGS(ifnet_rw, &ifnet_rwlock, "ifnet_rw", RW_RECURSE); struct sx ifnet_sxlock; +SX_SYSINIT_FLAGS(ifnet_sx, &ifnet_sxlock, "ifnet_sx", SX_RECURSE); /* * The allocation of network interfaces is a rather non-atomic affair; we @@ -364,17 +365,6 @@ vnet_if_init(const void *unused __unused) VNET_SYSINIT(vnet_if_init, SI_SUB_INIT_IF, SI_ORDER_SECOND, vnet_if_init, NULL); -/* ARGSUSED*/ -static void -if_init(void *dummy __unused) -{ - - IFNET_LOCK_INIT(); - if_clone_init(); -} -SYSINIT(interfaces, SI_SUB_INIT_IF, SI_ORDER_FIRST, if_init, NULL); - - #ifdef VIMAGE static void vnet_if_uninit(const void *unused __unused) @@ -727,13 +717,6 @@ if_attach_internal(struct ifnet *ifp, int vmove) ifp->if_hw_tsomaxsegsize); } } - /* - * If the "if_hw_tsomax" limit is set, check if it is - * too small: - */ - KASSERT(ifp->if_hw_tsomax == 0 || - ifp->if_hw_tsomax >= (IP_MAXPACKET / 8), - ("%s: if_hw_tsomax is outside of range", __func__)); #endif } #ifdef VIMAGE @@ -2451,6 +2434,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) #ifdef INET6 nd6_setmtu(ifp); #endif + rt_updatemtu(ifp); } break; } diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index abbda41199d..09f8d2a613b 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -103,15 +103,14 @@ static int ifc_simple_match(struct if_clone *, const char *); static int ifc_simple_create(struct if_clone *, char *, size_t, caddr_t); static int ifc_simple_destroy(struct if_clone *, struct ifnet *); -static struct mtx if_cloners_mtx; +static struct mtx if_cloners_mtx; +MTX_SYSINIT(if_cloners_lock, &if_cloners_mtx, "if_cloners lock", MTX_DEF); static VNET_DEFINE(int, if_cloners_count); VNET_DEFINE(LIST_HEAD(, if_clone), if_cloners); #define V_if_cloners_count VNET(if_cloners_count) #define V_if_cloners VNET(if_cloners) -#define IF_CLONERS_LOCK_INIT() \ - mtx_init(&if_cloners_mtx, "if_cloners lock", NULL, MTX_DEF) #define IF_CLONERS_LOCK_ASSERT() mtx_assert(&if_cloners_mtx, MA_OWNED) #define IF_CLONERS_LOCK() mtx_lock(&if_cloners_mtx) #define IF_CLONERS_UNLOCK() mtx_unlock(&if_cloners_mtx) @@ -169,13 +168,6 @@ vnet_if_clone_init(void) LIST_INIT(&V_if_cloners); } -void -if_clone_init(void) -{ - - IF_CLONERS_LOCK_INIT(); -} - /* * Lookup and create a clone network interface. */ diff --git a/sys/net/if_clone.h b/sys/net/if_clone.h index 90d9b7b18a1..67ec8046dff 100644 --- a/sys/net/if_clone.h +++ b/sys/net/if_clone.h @@ -65,7 +65,6 @@ EVENTHANDLER_DECLARE(if_clone_event, if_clone_event_handler_t); #endif /* The below interfaces used only by net/if.c. */ -void if_clone_init(void); void vnet_if_clone_init(void); int if_clone_create(char *, size_t, caddr_t); int if_clone_destroy(const char *); diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 19b3da2a00c..73ad3eb27e1 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -79,11 +79,6 @@ #include #endif #include - -int (*ef_inputp)(struct ifnet*, struct ether_header *eh, struct mbuf *m); -int (*ef_outputp)(struct ifnet *ifp, struct mbuf **mp, - const struct sockaddr *dst, short *tp, int *hlen); - #include #ifdef CTASSERT diff --git a/sys/net/if_types.h b/sys/net/if_types.h index 80a5606ba8a..c9b20db719e 100644 --- a/sys/net/if_types.h +++ b/sys/net/if_types.h @@ -246,7 +246,6 @@ /* not based on IANA assignments */ #define IFT_GIF 0xf0 #define IFT_PVC 0xf1 -#define IFT_FAITH 0xf2 #define IFT_ENC 0xf4 #define IFT_PFLOG 0xf6 #define IFT_PFSYNC 0xf7 diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 2d4751ec27b..2e6daa319ab 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -232,16 +232,24 @@ struct ifnet { counter_u64_t if_counters[IFCOUNTERS]; /* Stuff that's only temporary and doesn't belong here. */ - u_int if_hw_tsomax; /* TSO total burst length - * limit in bytes. A value of - * zero means no limit. Have - * to find a better place for - * it eventually. */ /* - * TSO fields for segment limits. If a field below is zero, - * there is no TSO segment limit. + * Network adapter TSO limits: + * =========================== + * + * If the "if_hw_tsomax" field is zero the maximum segment + * length limit does not apply. If the "if_hw_tsomaxsegcount" + * or the "if_hw_tsomaxsegsize" field is zero the TSO segment + * count limit does not apply. If all three fields are zero, + * there is no TSO limit. + * + * NOTE: The TSO limits only apply to the data payload part of + * a TCP/IP packet. That means there is no need to subtract + * space for ethernet-, vlan-, IP- or TCP- headers from the + * TSO limits unless the hardware driver in question requires + * so. */ + u_int if_hw_tsomax; /* TSO maximum size in bytes */ u_int if_hw_tsomaxsegcount; /* TSO maximum segment count */ u_int if_hw_tsomaxsegsize; /* TSO maximum segment size in bytes */ @@ -421,11 +429,6 @@ struct ifmultiaddr { extern struct rwlock ifnet_rwlock; extern struct sx ifnet_sxlock; -#define IFNET_LOCK_INIT() do { \ - rw_init_flags(&ifnet_rwlock, "ifnet_rw", RW_RECURSE); \ - sx_init_flags(&ifnet_sxlock, "ifnet_sx", SX_RECURSE); \ -} while(0) - #define IFNET_WLOCK() do { \ sx_xlock(&ifnet_sxlock); \ rw_wlock(&ifnet_rwlock); \ diff --git a/sys/net/if_vlan_var.h b/sys/net/if_vlan_var.h index b24087435da..ed4753ecfe4 100644 --- a/sys/net/if_vlan_var.h +++ b/sys/net/if_vlan_var.h @@ -32,22 +32,6 @@ #ifndef _NET_IF_VLAN_VAR_H_ #define _NET_IF_VLAN_VAR_H_ 1 -struct ether_vlan_header { - u_char evl_dhost[ETHER_ADDR_LEN]; - u_char evl_shost[ETHER_ADDR_LEN]; - u_int16_t evl_encap_proto; - u_int16_t evl_tag; - u_int16_t evl_proto; -}; - -#define EVL_VLID_MASK 0x0FFF -#define EVL_PRI_MASK 0xE000 -#define EVL_VLANOFTAG(tag) ((tag) & EVL_VLID_MASK) -#define EVL_PRIOFTAG(tag) (((tag) >> 13) & 7) -#define EVL_CFIOFTAG(tag) (((tag) >> 12) & 1) -#define EVL_MAKETAG(vlid, pri, cfi) \ - ((((((pri) & 7) << 1) | ((cfi) & 1)) << 12) | ((vlid) & EVL_VLID_MASK)) - /* Set the VLAN ID in an mbuf packet header non-destructively. */ #define EVL_APPLY_VLID(m, vlid) \ do { \ diff --git a/sys/net/netmap_user.h b/sys/net/netmap_user.h index 5faf671b897..aab6c358de7 100644 --- a/sys/net/netmap_user.h +++ b/sys/net/netmap_user.h @@ -40,7 +40,7 @@ * From there: * struct netmap_ring *NETMAP_TXRING(nifp, index) * struct netmap_ring *NETMAP_RXRING(nifp, index) - * we can access ring->nr_cur, ring->nr_avail, ring->nr_flags + * we can access ring->cur, ring->head, ring->tail, etc. * * ring->slot[i] gives us the i-th slot (we can access * directly len, flags, buf_idx) @@ -543,7 +543,8 @@ fail: nm_close(d); if (errmsg) D("%s %s", errmsg, ifname); - errno = EINVAL; + if (errno == 0) + errno = EINVAL; return NULL; } diff --git a/sys/net/route.c b/sys/net/route.c index a08f6c56f76..36c1d4fc8d9 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -146,6 +146,14 @@ static int rtrequest1_fib_change(struct rib_head *, struct rt_addrinfo *, static void rt_setmetrics(const struct rt_addrinfo *, struct rtentry *); static int rt_ifdelroute(struct rtentry *rt, void *arg); +struct if_mtuinfo +{ + struct ifnet *ifp; + int mtu; +}; + +static int if_updatemtu_cb(struct radix_node *, void *); + /* * handler for net.my_fibnum */ @@ -1025,6 +1033,72 @@ bad: return (error); } +static int +if_updatemtu_cb(struct radix_node *rn, void *arg) +{ + struct rtentry *rt; + struct if_mtuinfo *ifmtu; + + rt = (struct rtentry *)rn; + ifmtu = (struct if_mtuinfo *)arg; + + if (rt->rt_ifp != ifmtu->ifp) + return (0); + + if (rt->rt_mtu >= ifmtu->mtu) { + /* We have to decrease mtu regardless of flags */ + rt->rt_mtu = ifmtu->mtu; + return (0); + } + + /* + * New MTU is bigger. Check if are allowed to alter it + */ + if ((rt->rt_flags & (RTF_FIXEDMTU | RTF_GATEWAY | RTF_HOST)) != 0) { + + /* + * Skip routes with user-supplied MTU and + * non-interface routes + */ + return (0); + } + + /* We are safe to update route MTU */ + rt->rt_mtu = ifmtu->mtu; + + return (0); +} + +void +rt_updatemtu(struct ifnet *ifp) +{ + struct if_mtuinfo ifmtu; + struct rib_head *rnh; + int i, j; + + ifmtu.ifp = ifp; + + /* + * Try to update rt_mtu for all routes using this interface + * Unfortunately the only way to do this is to traverse all + * routing tables in all fibs/domains. + */ + for (i = 1; i <= AF_MAX; i++) { + ifmtu.mtu = if_getmtu_family(ifp, i); + for (j = 0; j < rt_numfibs; j++) { + rnh = rt_tables_get_rnh(j, i); + if (rnh == NULL) + continue; + RIB_CFG_WLOCK(rnh); + RIB_WLOCK(rnh); + rnh->rnh_walktree(&rnh->head, if_updatemtu_cb, &ifmtu); + RIB_WUNLOCK(rnh); + RIB_CFG_WUNLOCK(rnh); + } + } +} + + #if 0 int p_sockaddr(char *buf, int buflen, struct sockaddr *s); int rt_print(char *buf, int buflen, struct rtentry *rt); @@ -1492,6 +1566,7 @@ rtrequest1_fib_change(struct rib_head *rh, struct rt_addrinfo *info, int error = 0; int free_ifa = 0; int family, mtu; + struct if_mtuinfo ifmtu; rt = (struct rtentry *)rh->rnh_lookup(info->rti_info[RTAX_DST], info->rti_info[RTAX_NETMASK], &rh->head); @@ -1562,12 +1637,19 @@ rtrequest1_fib_change(struct rib_head *rh, struct rt_addrinfo *info, if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest != NULL) rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, info); - /* Ensure route MTU is not bigger than interface MTU */ + /* Alter route MTU if necessary */ if (rt->rt_ifp != NULL) { family = info->rti_info[RTAX_DST]->sa_family; mtu = if_getmtu_family(rt->rt_ifp, family); - if (rt->rt_mtu > mtu) + /* Set default MTU */ + if (rt->rt_mtu == 0) rt->rt_mtu = mtu; + if (rt->rt_mtu != mtu) { + /* Check if we really need to update */ + ifmtu.ifp = rt->rt_ifp; + ifmtu.mtu = mtu; + if_updatemtu_cb(rt->rt_nodes, &ifmtu); + } } if (ret_nrt) { @@ -1585,8 +1667,24 @@ static void rt_setmetrics(const struct rt_addrinfo *info, struct rtentry *rt) { - if (info->rti_mflags & RTV_MTU) + if (info->rti_mflags & RTV_MTU) { + if (info->rti_rmx->rmx_mtu != 0) { + + /* + * MTU was explicitly provided by user. + * Keep it. + */ + rt->rt_flags |= RTF_FIXEDMTU; + } else { + + /* + * User explicitly sets MTU to 0. + * Assume rollback to default. + */ + rt->rt_flags &= ~RTF_FIXEDMTU; + } rt->rt_mtu = info->rti_rmx->rmx_mtu; + } if (info->rti_mflags & RTV_WEIGHT) rt->rt_weight = info->rti_rmx->rmx_weight; /* Kernel -> userland timebase conversion. */ diff --git a/sys/net/route.h b/sys/net/route.h index ce0674925c9..88835d6a8cc 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -160,7 +160,7 @@ struct rtentry { /* 0x10000 unused, was RTF_PRCLONING */ /* 0x20000 unused, was RTF_WASCLONED */ #define RTF_PROTO3 0x40000 /* protocol specific routing flag */ -/* 0x80000 unused */ +#define RTF_FIXEDMTU 0x80000 /* MTU was explicitly specified */ #define RTF_PINNED 0x100000 /* route is immutable */ #define RTF_LOCAL 0x200000 /* route represents a local address */ #define RTF_BROADCAST 0x400000 /* route represents a bcast address */ @@ -332,6 +332,7 @@ int rtsock_routemsg(int, struct ifnet *ifp, int, struct rtentry *, int); int rt_expunge(struct rib_head *, struct rtentry *); void rtfree(struct rtentry *); int rt_check(struct rtentry **, struct rtentry **, struct sockaddr *); +void rt_updatemtu(struct ifnet *); typedef int rt_walktree_f_t(struct rtentry *, void *); typedef void rt_setwarg_t(struct rib_head *, uint32_t, int, void *); diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c index bab8bbbbdd8..d2e04879a9f 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_l2cap.c @@ -1127,9 +1127,8 @@ ng_btsocket_l2cap_process_l2ca_write_rsp(struct ng_mesg *msg, /* * Check if we have more data to send */ - sbdroprecord(&pcb->so->so_snd); - if (pcb->so->so_snd.sb_cc > 0) { + if (sbavail(&pcb->so->so_snd) > 0) { if (ng_btsocket_l2cap_send2(pcb) == 0) ng_btsocket_l2cap_timeout(pcb); else @@ -2513,7 +2512,7 @@ ng_btsocket_l2cap_send2(ng_btsocket_l2cap_pcb_p pcb) mtx_assert(&pcb->pcb_mtx, MA_OWNED); - if (pcb->so->so_snd.sb_cc == 0) + if (sbavail(&pcb->so->so_snd) == 0) return (EINVAL); /* XXX */ m = m_dup(pcb->so->so_snd.sb_mb, M_NOWAIT); diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c index cb3753d4bf0..a2190c78a61 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_rfcomm.c @@ -3279,7 +3279,7 @@ ng_btsocket_rfcomm_pcb_send(ng_btsocket_rfcomm_pcb_p pcb, int limit) } for (error = 0, sent = 0; sent < limit; sent ++) { - length = min(pcb->mtu, pcb->so->so_snd.sb_cc); + length = min(pcb->mtu, sbavail(&pcb->so->so_snd)); if (length == 0) break; diff --git a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c index f0d87b3940b..9ff0cebabb8 100644 --- a/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c +++ b/sys/netgraph/bluetooth/socket/ng_btsocket_sco.c @@ -906,7 +906,7 @@ ng_btsocket_sco_default_msg_input(struct ng_mesg *msg, hook_p hook) sbdroprecord(&pcb->so->so_snd); /* Send more if we have any */ - if (pcb->so->so_snd.sb_cc > 0) + if (sbavail(&pcb->so->so_snd) > 0) if (ng_btsocket_sco_send2(pcb) == 0) ng_btsocket_sco_timeout(pcb); @@ -1748,7 +1748,7 @@ ng_btsocket_sco_send2(ng_btsocket_sco_pcb_p pcb) mtx_assert(&pcb->pcb_mtx, MA_OWNED); while (pcb->rt->pending < pcb->rt->num_pkts && - pcb->so->so_snd.sb_cc > 0) { + sbavail(&pcb->so->so_snd) > 0) { /* Get a copy of the first packet on send queue */ m = m_dup(pcb->so->so_snd.sb_mb, M_NOWAIT); if (m == NULL) { diff --git a/sys/netinet/accf_dns.c b/sys/netinet/accf_dns.c index ec2b4cfb804..85214d6d93c 100644 --- a/sys/netinet/accf_dns.c +++ b/sys/netinet/accf_dns.c @@ -75,7 +75,7 @@ sohasdns(struct socket *so, void *arg, int waitflag) struct sockbuf *sb = &so->so_rcv; /* If the socket is full, we're ready. */ - if (sb->sb_cc >= sb->sb_hiwat || sb->sb_mbcnt >= sb->sb_mbmax) + if (sbused(sb) >= sb->sb_hiwat || sb->sb_mbcnt >= sb->sb_mbmax) goto ready; /* Check to see if we have a request. */ @@ -115,14 +115,14 @@ skippacket(struct sockbuf *sb) { unsigned long packlen; struct packet q, *p = &q; - if (sb->sb_cc < 2) + if (sbavail(sb) < 2) return DNS_WAIT; q.m = sb->sb_mb; q.n = q.m->m_nextpkt; q.moff = 0; q.offset = 0; - q.len = sb->sb_cc; + q.len = sbavail(sb); GET16(p, packlen); if (packlen + 2 > q.len) diff --git a/sys/netinet/accf_http.c b/sys/netinet/accf_http.c index 41e442c4fa7..33734c717a6 100644 --- a/sys/netinet/accf_http.c +++ b/sys/netinet/accf_http.c @@ -92,7 +92,7 @@ sbfull(struct sockbuf *sb) "mbcnt(%ld) >= mbmax(%ld): %d", sb->sb_cc, sb->sb_hiwat, sb->sb_cc >= sb->sb_hiwat, sb->sb_mbcnt, sb->sb_mbmax, sb->sb_mbcnt >= sb->sb_mbmax); - return (sb->sb_cc >= sb->sb_hiwat || sb->sb_mbcnt >= sb->sb_mbmax); + return (sbused(sb) >= sb->sb_hiwat || sb->sb_mbcnt >= sb->sb_mbmax); } /* @@ -162,13 +162,14 @@ static int sohashttpget(struct socket *so, void *arg, int waitflag) { - if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 && !sbfull(&so->so_rcv)) { + if ((so->so_rcv.sb_state & SBS_CANTRCVMORE) == 0 && + !sbfull(&so->so_rcv)) { struct mbuf *m; char *cmp; int cmplen, cc; m = so->so_rcv.sb_mb; - cc = so->so_rcv.sb_cc - 1; + cc = sbavail(&so->so_rcv) - 1; if (cc < 1) return (SU_OK); switch (*mtod(m, char *)) { @@ -215,7 +216,7 @@ soparsehttpvers(struct socket *so, void *arg, int waitflag) goto fallout; m = so->so_rcv.sb_mb; - cc = so->so_rcv.sb_cc; + cc = sbavail(&so->so_rcv); inspaces = spaces = 0; for (m = so->so_rcv.sb_mb; m; m = n) { n = m->m_nextpkt; @@ -304,7 +305,7 @@ soishttpconnected(struct socket *so, void *arg, int waitflag) * have NCHRS left */ copied = 0; - ccleft = so->so_rcv.sb_cc; + ccleft = sbavail(&so->so_rcv); if (ccleft < NCHRS) goto readmore; a = b = c = '\0'; diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 4776278e1b1..1f79761e7eb 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -428,8 +428,7 @@ __END_DECLS #define IP_RECVIF 20 /* bool; receive reception if w/dgram */ /* for IPSEC */ #define IP_IPSEC_POLICY 21 /* int; set/get security policy */ -#define IP_FAITH 22 /* bool; accept FAITH'ed connections */ - + /* unused; was IP_FAITH */ #define IP_ONESBCAST 23 /* bool: send all-ones broadcast */ #define IP_BINDANY 24 /* bool: allow bind to any address */ #define IP_BINDMULTI 25 /* bool: allow multiple listeners on a tuple */ @@ -620,9 +619,9 @@ int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t, #ifdef notyet #define IPCTL_DEFMTU 4 /* default MTU */ #endif -#define IPCTL_RTEXPIRE 5 /* cloned route expiration time */ -#define IPCTL_RTMINEXPIRE 6 /* min value for expiration time */ -#define IPCTL_RTMAXCACHE 7 /* trigger level for dynamic expire */ +/* IPCTL_RTEXPIRE 5 deprecated */ +/* IPCTL_RTMINEXPIRE 6 deprecated */ +/* IPCTL_RTMAXCACHE 7 deprecated */ #define IPCTL_SOURCEROUTE 8 /* may perform source routes */ #define IPCTL_DIRECTEDBROADCAST 9 /* may re-broadcast received packets */ #define IPCTL_INTRQMAXLEN 10 /* max length of netisr queue */ @@ -630,7 +629,7 @@ int getsourcefilter(int, uint32_t, struct sockaddr *, socklen_t, #define IPCTL_STATS 12 /* ipstat structure */ #define IPCTL_ACCEPTSOURCEROUTE 13 /* may accept source routed packets */ #define IPCTL_FASTFORWARDING 14 /* use fast IP forwarding code */ -#define IPCTL_KEEPFAITH 15 /* FAITH IPv4->IPv6 translater ctl */ + /* 15, unused, was: IPCTL_KEEPFAITH */ #define IPCTL_GIF_TTL 16 /* default TTL for gif encap packet */ #endif /* __BSD_VISIBLE */ diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index c1f71071488..6b509d56dac 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1653,11 +1653,6 @@ in_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, inp->inp_lport != lport) continue; - /* XXX inp locking */ - if (ifp && ifp->if_type == IFT_FAITH && - (inp->inp_flags & INP_FAITH) == 0) - continue; - injail = prison_flag(inp->inp_cred, PR_IP4); if (injail) { if (prison_check_ip4(inp->inp_cred, @@ -1732,11 +1727,6 @@ in_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, inp->inp_lport != lport) continue; - /* XXX inp locking */ - if (ifp && ifp->if_type == IFT_FAITH && - (inp->inp_flags & INP_FAITH) == 0) - continue; - injail = prison_flag(inp->inp_cred, PR_IP4); if (injail) { if (prison_check_ip4(inp->inp_cred, @@ -1877,11 +1867,6 @@ in_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in_addr faddr, inp->inp_lport != lport) continue; - /* XXX inp locking */ - if (ifp && ifp->if_type == IFT_FAITH && - (inp->inp_flags & INP_FAITH) == 0) - continue; - injail = prison_flag(inp->inp_cred, PR_IP4); if (injail) { if (prison_check_ip4(inp->inp_cred, @@ -2476,10 +2461,6 @@ db_print_inpflags(int inp_flags) db_printf("%sINP_MTUDISC", comma ? ", " : ""); comma = 1; } - if (inp_flags & INP_FAITH) { - db_printf("%sINP_FAITH", comma ? ", " : ""); - comma = 1; - } if (inp_flags & INP_RECVTTL) { db_printf("%sINP_RECVTTL", comma ? ", " : ""); comma = 1; diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 185bcfb2d06..04ed0b0bdf8 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -511,7 +511,7 @@ short inp_so_options(const struct inpcb *inp); #define INP_ANONPORT 0x00000040 /* port chosen for user */ #define INP_RECVIF 0x00000080 /* receive incoming interface */ #define INP_MTUDISC 0x00000100 /* user can do MTU discovery */ -#define INP_FAITH 0x00000200 /* accept FAITH'ed connections */ + /* 0x000200 unused: was INP_FAITH */ #define INP_RECVTTL 0x00000400 /* receive incoming IP TTL */ #define INP_DONTFRAG 0x00000800 /* don't fragment packet */ #define INP_BINDANY 0x00001000 /* allow bind to any address */ diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index 6a2e2619ddb..a794b556de3 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -39,8 +39,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include #include @@ -59,13 +57,6 @@ extern int in_inithead(void **head, int off); extern int in_detachhead(void **head, int off); #endif -static void in_setifarnh(struct rib_head *rh, uint32_t fibnum, - int af, void *_arg); -static void in_rtqtimo_setrnh(struct rib_head *rh, uint32_t fibnum, - int af, void *_arg); - -#define RTPRF_OURS RTF_PROTO3 /* set on routes we manage */ - /* * Do what we need to do when inserting a route. */ @@ -118,176 +109,6 @@ in_addroute(void *v_arg, void *n_arg, struct radix_head *head, return (rn_addroute(v_arg, n_arg, head, treenodes)); } -/* - * This code is the inverse of in_clsroute: on first reference, if we - * were managing the route, stop doing so and set the expiration timer - * back off again. - */ -static struct radix_node * -in_matroute(void *v_arg, struct radix_head *head) -{ - struct radix_node *rn = rn_match(v_arg, head); - struct rtentry *rt = (struct rtentry *)rn; - - if (rt) { - RT_LOCK(rt); - if (rt->rt_flags & RTPRF_OURS) { - rt->rt_flags &= ~RTPRF_OURS; - rt->rt_expire = 0; - } - RT_UNLOCK(rt); - } - return rn; -} - -static VNET_DEFINE(int, rtq_reallyold) = 60*60; /* one hour is "really old" */ -#define V_rtq_reallyold VNET(rtq_reallyold) -SYSCTL_INT(_net_inet_ip, IPCTL_RTEXPIRE, rtexpire, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(rtq_reallyold), 0, - "Default expiration time on dynamically learned routes"); - -/* - * On last reference drop, mark the route as belong to us so that it can be - * timed out. - */ -static void -in_clsroute(struct radix_node *rn, struct radix_head *head) -{ - struct rtentry *rt = (struct rtentry *)rn; - struct rib_head *rh = (struct rib_head *)head; - - RT_LOCK_ASSERT(rt); - - if (!(rt->rt_flags & RTF_UP)) - return; /* prophylactic measures */ - - if (rt->rt_flags & RTPRF_OURS) - return; - - if (!(rt->rt_flags & RTF_DYNAMIC)) - return; - - /* - * If rtq_reallyold is 0, just delete the route without - * waiting for a timeout cycle to kill it. - */ - if (V_rtq_reallyold != 0) { - rt->rt_flags |= RTPRF_OURS; - rt->rt_expire = time_uptime + V_rtq_reallyold; - } else - rt_expunge(rh, rt); -} - -struct rtqk_arg { - struct rib_head *rh; - int draining; - int killed; - int found; -}; - -/* - * Get rid of old routes. When draining, this deletes everything, even when - * the timeout is not expired yet. - */ -static int -in_rtqkill(struct rtentry *rt, void *rock) -{ - struct rtqk_arg *ap = rock; - int err; - - //RIB_WLOCK_ASSERT(ap->rh); - - if (rt->rt_flags & RTPRF_OURS) { - ap->found++; - - if (ap->draining || rt->rt_expire <= time_uptime) { - if (rt->rt_refcnt > 0) - panic("rtqkill route really not free"); - - err = in_rtrequest(RTM_DELETE, - (struct sockaddr *)rt_key(rt), - rt->rt_gateway, rt_mask(rt), - rt->rt_flags | RTF_RNH_LOCKED, 0, - rt->rt_fibnum); - if (err != 0) { - log(LOG_WARNING, "in_rtqkill: error %d\n", err); - } else - ap->killed++; - } - } - - return 0; -} - -#define RTQ_TIMEOUT 60*10 /* run no less than once every ten minutes */ -static VNET_DEFINE(int, rtq_timeout) = RTQ_TIMEOUT; -static VNET_DEFINE(struct callout, rtq_timer); - -#define V_rtq_timeout VNET(rtq_timeout) -#define V_rtq_timer VNET(rtq_timer) - -static void -in_rtqtimo_setrnh(struct rib_head *rh, uint32_t fibnum, int af, - void *_arg) -{ - struct rtqk_arg *arg; - int draining; - - arg = (struct rtqk_arg *)_arg; - - draining = arg->draining; - memset(arg, 0, sizeof(*arg)); - arg->rh = rh; - arg->draining = arg->draining; -} - -static void -in_rtqtimo(void *rock) -{ - CURVNET_SET((struct vnet *) rock); - struct rtqk_arg arg; - struct timeval atv; - - memset(&arg, 0, sizeof(arg)); - rt_foreach_fib(AF_INET, in_rtqtimo_setrnh, in_rtqkill, &arg); - - atv.tv_usec = 0; - atv.tv_sec = V_rtq_timeout; - callout_reset(&V_rtq_timer, tvtohz(&atv), in_rtqtimo, rock); - CURVNET_RESTORE(); -} - -void -in_rtqdrain(void) -{ - VNET_ITERATOR_DECL(vnet_iter); - struct rtqk_arg arg; - - memset(&arg, 0, sizeof(arg)); - arg.draining = 1; - - VNET_LIST_RLOCK_NOSLEEP(); - VNET_FOREACH(vnet_iter) { - CURVNET_SET(vnet_iter); - - rt_foreach_fib(AF_INET, in_rtqtimo_setrnh, in_rtqkill, &arg); - - CURVNET_RESTORE(); - } - VNET_LIST_RUNLOCK_NOSLEEP(); -} - -void -in_setmatchfunc(struct rib_head *rh, int val) -{ - - RIB_CFG_WLOCK(rh); - RIB_WLOCK(rh); - rh->rnh_matchaddr = (val != 0) ? rn_match : in_matroute; - RIB_WUNLOCK(rh); - RIB_CFG_WUNLOCK(rh); -} - static int _in_rt_was_here; /* * Initialize our routing tree. @@ -302,13 +123,9 @@ in_inithead(void **head, int off) return (0); rh->rnh_addaddr = in_addroute; - in_setmatchfunc(rh, V_drop_redirect); - rh->rnh_close = in_clsroute; *head = (void *)rh; if (_in_rt_was_here == 0 ) { - callout_init(&V_rtq_timer, CALLOUT_MPSAFE); - callout_reset(&V_rtq_timer, 1, in_rtqtimo, curvnet); _in_rt_was_here = 1; } return 1; @@ -319,7 +136,6 @@ int in_detachhead(void **head, int off) { - callout_drain(&V_rtq_timer); return (1); } #endif diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 98020d117db..8cdbe21d401 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -406,7 +406,6 @@ int in_leavegroup_locked(struct in_multi *, /*const*/ struct in_mfilter *); int in_control(struct socket *, u_long, caddr_t, struct ifnet *, struct thread *); -void in_rtqdrain(void); int in_addprefix(struct in_ifaddr *, int); int in_scrubprefix(struct in_ifaddr *, u_int); void ip_input(struct mbuf *); @@ -422,7 +421,6 @@ void in_rtredirect(struct sockaddr *, struct sockaddr *, struct sockaddr *, int, struct sockaddr *, u_int); int in_rtrequest(int, struct sockaddr *, struct sockaddr *, struct sockaddr *, int, struct rtentry **, u_int); -void in_setmatchfunc(struct rib_head *, int); #if 0 int in_rt_getifa(struct rt_addrinfo *, u_int fibnum); diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c index 59c430fc399..d9430a9a150 100644 --- a/sys/netinet/ip_fastfwd.c +++ b/sys/netinet/ip_fastfwd.c @@ -488,7 +488,6 @@ passout: if ((ifp->if_snd.ifq_len + ip_len / ifp->if_mtu + 1) >= ifp->if_snd.ifq_maxlen) { IPSTAT_INC(ips_odropped); - /* would send source quench here but that is depreciated */ goto drop; } #endif diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index de10923dbf5..3844e496587 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -117,6 +117,9 @@ SYSCTL_UINT(_net_inet_icmp, OID_AUTO, maskfake, CTLFLAG_VNET | CTLFLAG_RW, "Fake reply to ICMP Address Mask Request packets."); VNET_DEFINE(int, drop_redirect) = 0; +#define V_drop_redirect VNET(drop_redirect) +SYSCTL_INT(_net_inet_icmp, OID_AUTO, drop_redirect, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(drop_redirect), 0, "Ignore ICMP redirects"); static VNET_DEFINE(int, log_redirect) = 0; #define V_log_redirect VNET(log_redirect) @@ -165,37 +168,6 @@ static void icmp_send(struct mbuf *, struct mbuf *); extern struct protosw inetsw[]; -static int -sysctl_net_icmp_drop_redir(SYSCTL_HANDLER_ARGS) -{ - int error, new; - int i; - struct rib_head *rh; - - new = V_drop_redirect; - error = sysctl_handle_int(oidp, &new, 0, req); - if (error == 0 && req->newptr) { - new = (new != 0) ? 1 : 0; - - if (new == V_drop_redirect) - return (0); - - for (i = 0; i < rt_numfibs; i++) { - if ((rh = rt_tables_get_rnh(i, AF_INET)) == NULL) - continue; - in_setmatchfunc(rh, new); - } - - V_drop_redirect = new; - } - - return (error); -} - -SYSCTL_PROC(_net_inet_icmp, OID_AUTO, drop_redirect, - CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW, 0, 0, - sysctl_net_icmp_drop_redir, "I", "Ignore ICMP redirects"); - /* * Kernel module interface for updating icmpstat. The argument is an index * into icmpstat treated as an array of u_long. While this encodes the @@ -410,19 +382,6 @@ icmp_input(struct mbuf **mp, int *offp, int proto) m->m_len += hlen; m->m_data -= hlen; - if (m->m_pkthdr.rcvif && m->m_pkthdr.rcvif->if_type == IFT_FAITH) { - /* - * Deliver very specific ICMP type only. - */ - switch (icp->icmp_type) { - case ICMP_UNREACH: - case ICMP_TIMXCEED: - break; - default: - goto freeit; - } - } - #ifdef ICMPPRINTFS if (icmpprintfs) printf("icmp_input, type %d code %d\n", icp->icmp_type, @@ -499,12 +458,6 @@ icmp_input(struct mbuf **mp, int *offp, int proto) if (code > 1) goto badcode; code = PRC_PARAMPROB; - goto deliver; - - case ICMP_SOURCEQUENCH: - if (code) - goto badcode; - code = PRC_QUENCH; deliver: /* * Problem with datagram; advise higher level routines. @@ -683,6 +636,7 @@ reflect: case ICMP_TSTAMPREPLY: case ICMP_IREQREPLY: case ICMP_MASKREPLY: + case ICMP_SOURCEQUENCH: default: break; } diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index a58e7672bf0..5dab7314ef1 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -106,18 +106,6 @@ SYSCTL_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_VNET | CTLFLAG_R &VNET_NAME(ipsendredirects), 0, "Enable sending IP redirects"); -static VNET_DEFINE(int, ip_keepfaith); -#define V_ip_keepfaith VNET(ip_keepfaith) -SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(ip_keepfaith), 0, - "Enable packet capture for FAITH IPv4->IPv6 translater daemon"); - -static VNET_DEFINE(int, ip_sendsourcequench); -#define V_ip_sendsourcequench VNET(ip_sendsourcequench) -SYSCTL_INT(_net_inet_ip, OID_AUTO, sendsourcequench, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(ip_sendsourcequench), 0, - "Enable the transmission of source quench packets"); - VNET_DEFINE(int, ip_do_randomid); SYSCTL_INT(_net_inet_ip, OID_AUTO, random_id, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip_do_randomid), 0, @@ -754,18 +742,6 @@ passin: if (ip->ip_dst.s_addr == INADDR_ANY) goto ours; - /* - * FAITH(Firewall Aided Internet Translator) - */ - if (ifp && ifp->if_type == IFT_FAITH) { - if (V_ip_keepfaith) { - if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_ICMP) - goto ours; - } - m_freem(m); - return; - } - /* * Not for us; forward if possible and desirable. */ @@ -1356,7 +1332,6 @@ ip_drain(void) } IPQ_UNLOCK(); VNET_LIST_RUNLOCK_NOSLEEP(); - in_rtqdrain(); } /* @@ -1599,23 +1574,6 @@ ip_forward(struct mbuf *m, int srcrt) break; case ENOBUFS: - /* - * A router should not generate ICMP_SOURCEQUENCH as - * required in RFC1812 Requirements for IP Version 4 Routers. - * Source quench could be a big problem under DoS attacks, - * or if the underlying interface is rate-limited. - * Those who need source quench packets may re-enable them - * via the net.inet.ip.sendsourcequench sysctl. - */ - if (V_ip_sendsourcequench == 0) { - m_freem(mcopy); - return; - } else { - type = ICMP_SOURCEQUENCH; - code = 0; - } - break; - case EACCES: /* ipfw denied packet */ m_freem(mcopy); return; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index e0ead4cf82b..6bf0a6a5e52 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1031,7 +1031,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_RECVDSTADDR: case IP_RECVTTL: case IP_RECVIF: - case IP_FAITH: case IP_ONESBCAST: case IP_DONTFRAG: case IP_RECVTOS: @@ -1098,10 +1097,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) OPTSET(INP_RECVIF); break; - case IP_FAITH: - OPTSET(INP_FAITH); - break; - case IP_ONESBCAST: OPTSET(INP_ONESBCAST); break; @@ -1240,7 +1235,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) case IP_RECVTTL: case IP_RECVIF: case IP_PORTRANGE: - case IP_FAITH: case IP_ONESBCAST: case IP_DONTFRAG: case IP_BINDANY: @@ -1299,10 +1293,6 @@ ip_ctloutput(struct socket *so, struct sockopt *sopt) optval = 0; break; - case IP_FAITH: - optval = OPTBIT(INP_FAITH); - break; - case IP_ONESBCAST: optval = OPTBIT(INP_ONESBCAST); break; diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c index 9d2ca50232f..d65564f990f 100644 --- a/sys/netinet/siftr.c +++ b/sys/netinet/siftr.c @@ -782,9 +782,9 @@ siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp, pn->flags = tp->t_flags; pn->rxt_length = tp->t_rxtcur; pn->snd_buf_hiwater = inp->inp_socket->so_snd.sb_hiwat; - pn->snd_buf_cc = inp->inp_socket->so_snd.sb_cc; + pn->snd_buf_cc = sbused(&inp->inp_socket->so_snd); pn->rcv_buf_hiwater = inp->inp_socket->so_rcv.sb_hiwat; - pn->rcv_buf_cc = inp->inp_socket->so_rcv.sb_cc; + pn->rcv_buf_cc = sbused(&inp->inp_socket->so_rcv); pn->sent_inflight_bytes = tp->snd_max - tp->snd_una; pn->t_segqlen = tp->t_segqlen; diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index f6183b9124e..468f1421056 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -513,6 +513,7 @@ tcp6_input(struct mbuf **mp, int *offp, int proto) { struct mbuf *m = *mp; struct in6_ifaddr *ia6; + struct ip6_hdr *ip6; IP6_EXTHDR_CHECK(m, *offp, sizeof(struct tcphdr), IPPROTO_DONE); @@ -520,7 +521,8 @@ tcp6_input(struct mbuf **mp, int *offp, int proto) * draft-itojun-ipv6-tcp-to-anycast * better place to put this in? */ - ia6 = ip6_getdstifaddr(m); + ip6 = mtod(m, struct ip6_hdr *); + ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); if (ia6 && (ia6->ia6_flags & IN6_IFF_ANYCAST)) { struct ip6_hdr *ip6; @@ -1251,7 +1253,7 @@ relocked: if (isipv6 && !V_ip6_use_deprecated) { struct in6_ifaddr *ia6; - ia6 = ip6_getdstifaddr(m); + ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); if (ia6 != NULL && (ia6->ia6_flags & IN6_IFF_DEPRECATED)) { ifa_free(&ia6->ia_ifa); @@ -1743,7 +1745,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, tcp_timer_activate(tp, TT_REXMT, tp->t_rxtcur); sowwakeup(so); - if (so->so_snd.sb_cc) + if (sbavail(&so->so_snd)) (void) tcp_output(tp); goto check_delack; } @@ -2524,7 +2526,7 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, * Otherwise we would send pure ACKs. */ SOCKBUF_LOCK(&so->so_snd); - avail = so->so_snd.sb_cc - + avail = sbavail(&so->so_snd) - (tp->snd_nxt - tp->snd_una); SOCKBUF_UNLOCK(&so->so_snd); if (avail > 0) @@ -2659,10 +2661,10 @@ process_ACK: cc_ack_received(tp, th, CC_ACK); SOCKBUF_LOCK(&so->so_snd); - if (acked > so->so_snd.sb_cc) { - tp->snd_wnd -= so->so_snd.sb_cc; + if (acked > sbavail(&so->so_snd)) { + tp->snd_wnd -= sbavail(&so->so_snd); mfree = sbcut_locked(&so->so_snd, - (int)so->so_snd.sb_cc); + (int)sbavail(&so->so_snd)); ourfinisacked = 1; } else { mfree = sbcut_locked(&so->so_snd, acked); @@ -2788,7 +2790,7 @@ step6: * actually wanting to send this much urgent data. */ SOCKBUF_LOCK(&so->so_rcv); - if (th->th_urp + so->so_rcv.sb_cc > sb_max) { + if (th->th_urp + sbavail(&so->so_rcv) > sb_max) { th->th_urp = 0; /* XXX */ thflags &= ~TH_URG; /* XXX */ SOCKBUF_UNLOCK(&so->so_rcv); /* XXX */ @@ -2810,7 +2812,7 @@ step6: */ if (SEQ_GT(th->th_seq+th->th_urp, tp->rcv_up)) { tp->rcv_up = th->th_seq + th->th_urp; - so->so_oobmark = so->so_rcv.sb_cc + + so->so_oobmark = sbavail(&so->so_rcv) + (tp->rcv_up - tp->rcv_nxt) - 1; if (so->so_oobmark == 0) so->so_rcv.sb_state |= SBS_RCVATMARK; diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 968b8d28249..6929c86687f 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -324,7 +324,7 @@ after_sack_rexmit: * to send then the probe will be the FIN * itself. */ - if (off < so->so_snd.sb_cc) + if (off < sbused(&so->so_snd)) flags &= ~TH_FIN; sendwin = 1; } else { @@ -350,7 +350,8 @@ after_sack_rexmit: */ if (sack_rxmit == 0) { if (sack_bytes_rxmt == 0) - len = ((long)ulmin(so->so_snd.sb_cc, sendwin) - off); + len = ((long)ulmin(sbavail(&so->so_snd), sendwin) - + off); else { long cwin; @@ -359,8 +360,8 @@ after_sack_rexmit: * sending new data, having retransmitted all the * data possible in the scoreboard. */ - len = ((long)ulmin(so->so_snd.sb_cc, tp->snd_wnd) - - off); + len = ((long)ulmin(sbavail(&so->so_snd), tp->snd_wnd) - + off); /* * Don't remove this (len > 0) check ! * We explicitly check for len > 0 here (although it @@ -459,12 +460,15 @@ after_sack_rexmit: * TODO: Shrink send buffer during idle periods together * with congestion window. Requires another timer. Has to * wait for upcoming tcp timer rewrite. + * + * XXXGL: should there be used sbused() or sbavail()? */ if (V_tcp_do_autosndbuf && so->so_snd.sb_flags & SB_AUTOSIZE) { if ((tp->snd_wnd / 4 * 5) >= so->so_snd.sb_hiwat && - so->so_snd.sb_cc >= (so->so_snd.sb_hiwat / 8 * 7) && - so->so_snd.sb_cc < V_tcp_autosndbuf_max && - sendwin >= (so->so_snd.sb_cc - (tp->snd_nxt - tp->snd_una))) { + sbused(&so->so_snd) >= (so->so_snd.sb_hiwat / 8 * 7) && + sbused(&so->so_snd) < V_tcp_autosndbuf_max && + sendwin >= (sbused(&so->so_snd) - + (tp->snd_nxt - tp->snd_una))) { if (!sbreserve_locked(&so->so_snd, min(so->so_snd.sb_hiwat + V_tcp_autosndbuf_inc, V_tcp_autosndbuf_max), so, curthread)) @@ -501,10 +505,11 @@ after_sack_rexmit: tso = 1; if (sack_rxmit) { - if (SEQ_LT(p->rxmit + len, tp->snd_una + so->so_snd.sb_cc)) + if (SEQ_LT(p->rxmit + len, tp->snd_una + sbused(&so->so_snd))) flags &= ~TH_FIN; } else { - if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + so->so_snd.sb_cc)) + if (SEQ_LT(tp->snd_nxt + len, tp->snd_una + + sbused(&so->so_snd))) flags &= ~TH_FIN; } @@ -534,7 +539,7 @@ after_sack_rexmit: */ if (!(tp->t_flags & TF_MORETOCOME) && /* normal case */ (idle || (tp->t_flags & TF_NODELAY)) && - len + off >= so->so_snd.sb_cc && + len + off >= sbavail(&so->so_snd) && (tp->t_flags & TF_NOPUSH) == 0) { goto send; } @@ -662,7 +667,7 @@ dontupdate: * if window is nonzero, transmit what we can, * otherwise force out a byte. */ - if (so->so_snd.sb_cc && !tcp_timer_active(tp, TT_REXMT) && + if (sbavail(&so->so_snd) && !tcp_timer_active(tp, TT_REXMT) && !tcp_timer_active(tp, TT_PERSIST)) { tp->t_rxtshift = 0; tcp_setpersist(tp); @@ -804,9 +809,9 @@ send: max_len = (if_hw_tsomax - hdrlen); if (max_len <= 0) { len = 0; - } else if (len > (u_int)max_len) { + } else if (len > max_len) { sendalot = 1; - len = (u_int)max_len; + len = max_len; } } @@ -819,7 +824,7 @@ send: max_len = 0; mb = sbsndmbuf(&so->so_snd, off, &moff); - while (mb != NULL && (u_int)max_len < len) { + while (mb != NULL && max_len < len) { u_int mlen; u_int frags; @@ -853,9 +858,9 @@ send: } if (max_len <= 0) { len = 0; - } else if (len > (u_int)max_len) { + } else if (len > max_len) { sendalot = 1; - len = (u_int)max_len; + len = max_len; } } @@ -865,8 +870,8 @@ send: * emptied: */ max_len = (tp->t_maxopd - optlen); - if ((off + len) < so->so_snd.sb_cc) { - moff = len % (u_int)max_len; + if ((off + len) < sbavail(&so->so_snd)) { + moff = len % max_len; if (moff != 0) { len -= moff; sendalot = 1; @@ -877,8 +882,8 @@ send: * In case there are too many small fragments * don't use TSO: */ - if (len <= (u_int)max_len) { - len = (u_int)max_len; + if (len <= max_len) { + len = max_len; sendalot = 1; tso = 0; } @@ -981,7 +986,7 @@ send: * give data to the user when a buffer fills or * a PUSH comes in.) */ - if (off + len == so->so_snd.sb_cc) + if (off + len == sbused(&so->so_snd)) flags |= TH_PUSH; SOCKBUF_UNLOCK(&so->so_snd); } else { diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 1a50a4fe05d..e23c546dd17 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1431,11 +1431,6 @@ tcp_ctlinput(int cmd, struct sockaddr *sa, void *vip) */ else if (PRC_IS_REDIRECT(cmd)) return; - /* - * Source quench is depreciated. - */ - else if (cmd == PRC_QUENCH) - return; /* * Hostdead is ugly because it goes linearly through all PCBs. * XXX: We never get this from ICMP, otherwise it makes an @@ -1541,9 +1536,6 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d) else if (!PRC_IS_REDIRECT(cmd) && ((unsigned)cmd >= PRC_NCMDS || inet6ctlerrmap[cmd] == 0)) return; - /* Source quench is depreciated. */ - else if (cmd == PRC_QUENCH) - return; /* if the parameter is from icmp6, decode it. */ if (d != NULL) { diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index 4353b7750e7..0bf5be4ec96 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -357,6 +357,8 @@ struct tcptw { u_int t_starttime; int tw_time; TAILQ_ENTRY(tcptw) tw_2msl; + void *tw_pspare; /* TCP_SIGNATURE */ + u_int *tw_spare; /* TCP_SIGNATURE */ }; #define intotcpcb(ip) ((struct tcpcb *)(ip)->inp_ppcb) diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index dd088961358..92d07155bcb 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -59,13 +59,6 @@ __FBSDID("$FreeBSD$"); #include -/* - * Define it to get a correct behavior on per-interface statistics. - * You will need to perform an extra routing table lookup, per fragment, - * to do it. This may, or may not be, a performance hit. - */ -#define IN6_IFSTAT_STRICT - static void frag6_enq(struct ip6asfrag *, struct ip6asfrag *); static void frag6_deq(struct ip6asfrag *); static void frag6_insque(struct ip6q *, struct ip6q *); @@ -160,9 +153,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) struct ip6_frag *ip6f; struct ip6q *q6; struct ip6asfrag *af6, *ip6af, *af6dwn; -#ifdef IN6_IFSTAT_STRICT struct in6_ifaddr *ia; -#endif int offset = *offp, nxt, i, next; int first_frag = 0; int fragoff, frgpartlen; /* must be larger than u_int16_t */ @@ -183,18 +174,12 @@ frag6_input(struct mbuf **mp, int *offp, int proto) #endif dstifp = NULL; -#ifdef IN6_IFSTAT_STRICT /* find the destination interface of the packet. */ - if ((ia = ip6_getdstifaddr(m)) != NULL) { + ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); + if (ia != NULL) { dstifp = ia->ia_ifp; ifa_free(&ia->ia_ifa); } -#else - /* we are violating the spec, this is not the destination interface */ - if ((m->m_flags & M_PKTHDR) != 0) - dstifp = m->m_pkthdr.rcvif; -#endif - /* jumbo payload can't contain a fragment header */ if (ip6->ip6_plen == 0) { icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset); diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 2e3bf5852b9..d6036463b3a 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -485,22 +485,6 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) goto freeit; } - if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { - /* - * Deliver very specific ICMP6 type only. - * This is important to deliver TOOBIG. Otherwise PMTUD - * will not work. - */ - switch (icmp6->icmp6_type) { - case ICMP6_DST_UNREACH: - case ICMP6_PACKET_TOO_BIG: - case ICMP6_TIME_EXCEEDED: - break; - default: - goto freeit; - } - } - ICMP6STAT_INC(icp6s_inhist[icmp6->icmp6_type]); icmp6_ifstat_inc(ifp, ifs6_in_msg); if (icmp6->icmp6_type < ICMP6_INFOMSG_MASK) @@ -1316,7 +1300,8 @@ ni6_input(struct mbuf *m, int off) goto bad; /* else it's a link-local multicast, fine */ } else { /* unicast or anycast */ - if ((ia6 = ip6_getdstifaddr(m)) == NULL) + ia6 = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); + if (ia6 == NULL) goto bad; /* XXX impossible */ if ((ia6->ia6_flags & IN6_IFF_TEMPORARY) && @@ -1766,7 +1751,7 @@ ni6_addrs(struct icmp6_nodeinfo *ni6, struct mbuf *m, struct ifnet **ifpp, } IFNET_RLOCK_NOSLEEP(); - TAILQ_FOREACH(ifp, &V_ifnet, if_list) { + TAILQ_FOREACH(ifp, &V_ifnet, if_link) { addrsofif = 0; IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -1853,7 +1838,7 @@ ni6_store_addrs(struct icmp6_nodeinfo *ni6, struct icmp6_nodeinfo *nni6, ifp = ifp0 ? ifp0 : TAILQ_FIRST(&V_ifnet); again: - for (; ifp; ifp = TAILQ_NEXT(ifp, if_list)) { + for (; ifp; ifp = TAILQ_NEXT(ifp, if_link)) { IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_INET6) @@ -2151,7 +2136,6 @@ icmp6_reflect(struct mbuf *m, size_t off) uint32_t scopeid; int e; - /* too short to reflect */ if (off < sizeof(struct ip6_hdr)) { nd6log((LOG_DEBUG, @@ -2210,33 +2194,13 @@ icmp6_reflect(struct mbuf *m, size_t off) * The IN6_IFF_NOTREADY case should be VERY rare, but is possible * (for example) when we encounter an error while forwarding procedure * destined to a duplicated address of ours. - * Note that ip6_getdstifaddr() may fail if we are in an error handling - * procedure of an outgoing packet of our own, in which case we need - * to search in the ifaddr list. */ memset(&src, 0, sizeof(src)); - if (!IN6_IS_ADDR_MULTICAST(&origdst)) { - if ((ia = ip6_getdstifaddr(m))) { - if (!(ia->ia6_flags & - (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) - src = ia->ia_addr.sin6_addr; - ifa_free(&ia->ia_ifa); - } else { - struct sockaddr_in6 d; - - bzero(&d, sizeof(d)); - d.sin6_family = AF_INET6; - d.sin6_len = sizeof(d); - d.sin6_addr = origdst; - ia = (struct in6_ifaddr *) - ifa_ifwithaddr((struct sockaddr *)&d); - if (ia && - !(ia->ia6_flags & - (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) { - src = ia->ia_addr.sin6_addr; - ifa_free(&ia->ia_ifa); - } - } + if (!IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { + ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); + if (ia != NULL && !(ia->ia6_flags & + (IN6_IFF_ANYCAST|IN6_IFF_NOTREADY))) + src = ia->ia_addr.sin6_addr; } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 322344f8e43..1f1017e087d 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -140,8 +140,6 @@ static int in6_notify_ifa(struct ifnet *, struct in6_ifaddr *, struct in6_aliasreq *, int); static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *); -int (*faithprefix_p)(struct in6_addr *); - static int in6_validate_ifra(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int); static struct in6_ifaddr *in6_alloc_ifa(struct ifnet *, @@ -1291,50 +1289,17 @@ in6_broadcast_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, return (error); } -/* - * Leave from multicast groups we have joined for the interface. - */ -static int -in6_purgeaddr_mc(struct ifnet *ifp, struct in6_ifaddr *ia, struct ifaddr *ifa0) -{ - struct in6_multi_mship *imm; - - while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) { - LIST_REMOVE(imm, i6mm_chain); - in6_leavegroup(imm); - } - return (0); -} - void in6_purgeaddr(struct ifaddr *ifa) { struct ifnet *ifp = ifa->ifa_ifp; struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa; + struct in6_multi_mship *imm; int plen, error; - struct ifaddr *ifa0; if (ifa->ifa_carp) (*carp_detach_p)(ifa); - /* - * find another IPv6 address as the gateway for the - * link-local and node-local all-nodes multicast - * address routes - */ - IF_ADDR_RLOCK(ifp); - TAILQ_FOREACH(ifa0, &ifp->if_addrhead, ifa_link) { - if ((ifa0->ifa_addr->sa_family != AF_INET6) || - memcmp(&satosin6(ifa0->ifa_addr)->sin6_addr, - &ia->ia_addr.sin6_addr, sizeof(struct in6_addr)) == 0) - continue; - else - break; - } - if (ifa0 != NULL) - ifa_ref(ifa0); - IF_ADDR_RUNLOCK(ifp); - /* * Remove the loopback route to the interface address. * The check for the current setting of "nd6_useloopback" @@ -1354,11 +1319,10 @@ in6_purgeaddr(struct ifaddr *ifa) nd6_rem_ifa_lle(ia); /* Leave multicast groups. */ - error = in6_purgeaddr_mc(ifp, ia, ifa0); - - if (ifa0 != NULL) - ifa_free(ifa0); - + while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) { + LIST_REMOVE(imm, i6mm_chain); + in6_leavegroup(imm); + } plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ if ((ia->ia_flags & IFA_ROUTE) && plen == 128) { error = rtinit(&(ia->ia_ifa), RTM_DELETE, ia->ia_flags | @@ -1981,34 +1945,20 @@ in6if_do_dad(struct ifnet *ifp) if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) return (0); - switch (ifp->if_type) { -#ifdef IFT_DUMMY - case IFT_DUMMY: -#endif - case IFT_FAITH: - /* - * These interfaces do not have the IFF_LOOPBACK flag, - * but loop packets back. We do not have to do DAD on such - * interfaces. We should even omit it, because loop-backed - * NS would confuse the DAD procedure. - */ + /* + * Our DAD routine requires the interface up and running. + * However, some interfaces can be up before the RUNNING + * status. Additionaly, users may try to assign addresses + * before the interface becomes up (or running). + * We simply skip DAD in such a case as a work around. + * XXX: we should rather mark "tentative" on such addresses, + * and do DAD after the interface becomes ready. + */ + if (!((ifp->if_flags & IFF_UP) && + (ifp->if_drv_flags & IFF_DRV_RUNNING))) return (0); - default: - /* - * Our DAD routine requires the interface up and running. - * However, some interfaces can be up before the RUNNING - * status. Additionaly, users may try to assign addresses - * before the interface becomes up (or running). - * We simply skip DAD in such a case as a work around. - * XXX: we should rather mark "tentative" on such addresses, - * and do DAD after the interface becomes ready. - */ - if (!((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING))) - return (0); - return (1); - } + return (1); } /* @@ -2022,7 +1972,7 @@ in6_setmaxmtu(void) struct ifnet *ifp; IFNET_RLOCK_NOSLEEP(); - TAILQ_FOREACH(ifp, &V_ifnet, if_list) { + TAILQ_FOREACH(ifp, &V_ifnet, if_link) { /* this function can be called during ifnet initialization */ if (!ifp->if_afdata[AF_INET6]) continue; diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index c241d45167c..9ddd89ef74d 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -424,8 +424,7 @@ struct route_in6 { #define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */ #endif /* IPSEC */ -#define IPV6_FAITH 29 /* bool; accept FAITH'ed connections */ - + /* 29; unused; was IPV6_FAITH */ #if 1 /* IPV6FIREWALL */ #define IPV6_FW_ADD 30 /* add a firewall rule to chain */ #define IPV6_FW_DEL 31 /* delete a firewall rule from chain */ @@ -580,7 +579,7 @@ struct ip6_mtuinfo { #define IPV6CTL_SOURCECHECK 10 /* verify source route and intf */ #define IPV6CTL_SOURCECHECK_LOGINT 11 /* minimume logging interval */ #define IPV6CTL_ACCEPT_RTADV 12 -#define IPV6CTL_KEEPFAITH 13 + /* 13; unused; was: IPV6CTL_KEEPFAITH */ #define IPV6CTL_LOG_INTERVAL 14 #define IPV6CTL_HDRNESTLIMIT 15 #define IPV6CTL_DAD_COUNT 16 @@ -594,9 +593,9 @@ struct ip6_mtuinfo { #define IPV6CTL_MAPPED_ADDR 23 #endif #define IPV6CTL_V6ONLY 24 -#define IPV6CTL_RTEXPIRE 25 /* cloned route expiration time */ -#define IPV6CTL_RTMINEXPIRE 26 /* min value for expiration time */ -#define IPV6CTL_RTMAXCACHE 27 /* trigger level for dynamic expire */ +/* IPV6CTL_RTEXPIRE 25 deprecated */ +/* IPV6CTL_RTMINEXPIRE 26 deprecated */ +/* IPV6CTL_RTMAXCACHE 27 deprecated */ #define IPV6CTL_USETEMPADDR 32 /* use temporary addresses (RFC3041) */ #define IPV6CTL_TEMPPLTIME 33 /* preferred lifetime for tmpaddrs */ @@ -670,7 +669,6 @@ extern void addrsel_policy_init(void); #define sin6tosa(sin6) ((struct sockaddr *)(sin6)) #define ifatoia6(ifa) ((struct in6_ifaddr *)(ifa)) -extern int (*faithprefix_p)(struct in6_addr *); #endif /* _KERNEL */ #ifndef _SIZE_T_DECLARED diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index bffdb8f4c13..03c668e13be 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -408,7 +408,7 @@ get_ifid(struct ifnet *ifp0, struct ifnet *altifp, /* next, try to get it from some other hardware interface */ IFNET_RLOCK_NOSLEEP(); - TAILQ_FOREACH(ifp, &V_ifnet, if_list) { + TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp == ifp0) continue; if (in6_get_hw_ifid(ifp, in6) != 0) @@ -848,7 +848,7 @@ in6_tmpaddrtimer(void *arg) V_ip6_temp_regen_advance) * hz, in6_tmpaddrtimer, curvnet); bzero(nullbuf, sizeof(nullbuf)); - TAILQ_FOREACH(ifp, &V_ifnet, if_list) { + TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_afdata[AF_INET6] == NULL) continue; ndi = ND_IFINFO(ifp); diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 243bae13fb6..89a7fea32b3 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -864,12 +864,6 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, struct inpcbhead *head; struct inpcb *inp, *tmpinp; u_short fport = fport_arg, lport = lport_arg; - int faith; - - if (faithprefix_p != NULL) - faith = (*faithprefix_p)(laddr); - else - faith = 0; /* * First look for an exact match. @@ -929,10 +923,6 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, continue; } - /* XXX inp locking */ - if (faith && (inp->inp_flags & INP_FAITH) == 0) - continue; - injail = prison_flag(inp->inp_cred, PR_IP6); if (injail) { if (prison_check_ip6(inp->inp_cred, @@ -995,10 +985,6 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, continue; } - /* XXX inp locking */ - if (faith && (inp->inp_flags & INP_FAITH) == 0) - continue; - injail = prison_flag(inp->inp_cred, PR_IP6); if (injail) { if (prison_check_ip6(inp->inp_cred, @@ -1063,18 +1049,12 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, struct inpcbhead *head; struct inpcb *inp, *tmpinp; u_short fport = fport_arg, lport = lport_arg; - int faith; KASSERT((lookupflags & ~(INPLOOKUP_WILDCARD)) == 0, ("%s: invalid lookup flags %d", __func__, lookupflags)); INP_HASH_LOCK_ASSERT(pcbinfo); - if (faithprefix_p != NULL) - faith = (*faithprefix_p)(laddr); - else - faith = 0; - /* * First look for an exact match. */ @@ -1131,10 +1111,6 @@ in6_pcblookup_hash_locked(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, continue; } - /* XXX inp locking */ - if (faith && (inp->inp_flags & INP_FAITH) == 0) - continue; - injail = prison_flag(inp->inp_cred, PR_IP6); if (injail) { if (prison_check_ip6(inp->inp_cred, diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index 3798636696e..4d328d282ec 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -434,7 +434,6 @@ VNET_DEFINE(int, ip6_rr_prune) = 5; /* router renumbering prefix VNET_DEFINE(int, ip6_mcast_pmtu) = 0; /* enable pMTU discovery for multicast? */ VNET_DEFINE(int, ip6_v6only) = 1; -VNET_DEFINE(int, ip6_keepfaith) = 0; VNET_DEFINE(time_t, ip6_log_time) = (time_t)0L; #ifdef IPSTEALTH VNET_DEFINE(int, ip6stealth) = 0; @@ -543,8 +542,6 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_RFC6204W3, rfc6204w3, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_rfc6204w3), 0, "Accept the default router list from ICMPv6 RA messages even " "when packet forwarding enabled."); -SYSCTL_INT(_net_inet6_ip6, IPV6CTL_KEEPFAITH, keepfaith, - CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_keepfaith), 0, ""); SYSCTL_INT(_net_inet6_ip6, IPV6CTL_LOG_INTERVAL, log_interval, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_log_interval), 0, ""); SYSCTL_INT(_net_inet6_ip6, IPV6CTL_HDRNESTLIMIT, hdrnestlimit, diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c index d6b31347d59..232c133143d 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -179,63 +178,6 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_head *head, return (ret); } -struct rtqk_arg { - struct rib_head *rh; - int mode; - int draining; - int killed; - int found; -}; - -/* - * Age old PMTUs. - */ -struct mtuex_arg { - struct rib_head *rh; -}; -static VNET_DEFINE(struct callout, rtq_mtutimer); -#define V_rtq_mtutimer VNET(rtq_mtutimer) - -static int -in6_mtuexpire(struct rtentry *rt, void *rock) -{ - - if (rt->rt_expire && !(rt->rt_flags & RTF_PROBEMTU)) { - if (rt->rt_expire <= time_uptime) { - rt->rt_flags |= RTF_PROBEMTU; - } - } - - return (0); -} - -#define MTUTIMO_DEFAULT (60*1) - -static void -in6_mtutimo_setwa(struct rib_head *rh, uint32_t fibum, int af, void *_arg) -{ - struct mtuex_arg *arg; - - arg = (struct mtuex_arg *)_arg; - - arg->rh = rh; -} - -static void -in6_mtutimo(void *rock) -{ - CURVNET_SET_QUIET((struct vnet *) rock); - struct timeval atv; - struct mtuex_arg arg; - - rt_foreach_fib(AF_INET6, in6_mtutimo_setwa, in6_mtuexpire, &arg); - - atv.tv_sec = MTUTIMO_DEFAULT; - atv.tv_usec = 0; - callout_reset(&V_rtq_mtutimer, tvtohz(&atv), in6_mtutimo, rock); - CURVNET_RESTORE(); -} - /* * Initialize our routing tree. */ @@ -254,11 +196,8 @@ in6_inithead(void **head, int off) rh->rnh_addaddr = in6_addroute; *head = (void *)rh; - if (V__in6_rt_was_here == 0) { - callout_init(&V_rtq_mtutimer, CALLOUT_MPSAFE); - in6_mtutimo(curvnet); /* kick off timeout first time */ + if (V__in6_rt_was_here == 0) V__in6_rt_was_here = 1; - } return (1); } diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index 9ef6e8726b1..3da35c052d2 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -636,7 +636,6 @@ fib6_selectroute(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, } else goto getroute; } - /* * If the destination address is a multicast address and the outgoing * interface for the address is specified by the caller, use it. @@ -646,6 +645,17 @@ fib6_selectroute(uint32_t fibnum, struct in6_addr *dst, uint32_t scopeid, fill_nhop = 1; goto done; /* we do not need a route for multicast. */ } + /* + * If destination address is LLA or link- or node-local multicast, + * use it's embedded scope zone id to determine outgoing interface. + */ + if (IN6_IS_ADDR_MC_LINKLOCAL(dst) || + IN6_IS_ADDR_MC_NODELOCAL(dst)) { + if (scopeid > 0) { + ifp = in6_getlinkifnet(scopeid); + goto done; + } + } getroute: /* diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index f985108f211..cdc8ce686ac 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -149,10 +149,6 @@ struct rwlock in6_ifaddr_lock; RW_SYSINIT(in6_ifaddr_lock, &in6_ifaddr_lock, "in6_ifaddr_lock"); static void ip6_init2(void *); -static struct ip6aux *ip6_setdstifaddr(struct mbuf *, struct in6_ifaddr *); -static struct ip6aux *ip6_addaux(struct mbuf *); -static struct ip6aux *ip6_findaux(struct mbuf *m); -static void ip6_delaux (struct mbuf *); static int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); #ifdef PULLDOWN_TEST static struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); @@ -400,19 +396,15 @@ out: void ip6_input(struct mbuf *m) { + struct in6_addr odst; struct ip6_hdr *ip6; - int off = sizeof(struct ip6_hdr), nest; + struct in6_ifaddr *ia; u_int32_t plen; u_int32_t rtalert = ~0; + int off = sizeof(struct ip6_hdr), nest; int nxt, ours = 0; - struct ifnet *deliverifp = NULL, *ifp = NULL; - struct in6_addr odst; - struct route_in6 rin6; int srcrt = 0; - struct llentry *lle = NULL; - struct sockaddr_in6 dst6, *dst; - bzero(&rin6, sizeof(struct route_in6)); #ifdef IPSEC /* * should the inner packet be considered authentic? @@ -425,18 +417,12 @@ ip6_input(struct mbuf *m) #endif /* IPSEC */ - /* - * make sure we don't have onion peering information into m_tag. - */ - ip6_delaux(m); - if (m->m_flags & M_FASTFWD_OURS) { /* * Firewall changed destination to local. */ m->m_flags &= ~M_FASTFWD_OURS; ours = 1; - deliverifp = m->m_pkthdr.rcvif; ip6 = mtod(m, struct ip6_hdr *); goto hbhcheck; } @@ -463,10 +449,8 @@ ip6_input(struct mbuf *m) } /* drop the packet if IPv6 operation is disabled on the IF */ - if ((ND_IFINFO(m->m_pkthdr.rcvif)->flags & ND6_IFF_IFDISABLED)) { - m_freem(m); - return; - } + if ((ND_IFINFO(m->m_pkthdr.rcvif)->flags & ND6_IFF_IFDISABLED)) + goto bad; in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive); IP6STAT_INC(ip6s_total); @@ -627,7 +611,6 @@ ip6_input(struct mbuf *m) if (m->m_flags & M_FASTFWD_OURS) { m->m_flags &= ~M_FASTFWD_OURS; ours = 1; - deliverifp = m->m_pkthdr.rcvif; goto hbhcheck; } if ((m->m_flags & M_IP6_NEXTHOP) && @@ -638,7 +621,7 @@ ip6_input(struct mbuf *m) * connected host. */ ip6_forward(m, 1); - goto out; + return; } passin: @@ -661,7 +644,6 @@ passin: IP6STAT_INC(ip6s_badscope); goto bad; } - /* * Multicast check. Assume packet is for us to avoid * prematurely taking locks. @@ -669,53 +651,16 @@ passin: if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { ours = 1; in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast); - deliverifp = m->m_pkthdr.rcvif; goto hbhcheck; } - /* - * Unicast check + * Unicast check + * XXX: For now we keep link-local IPv6 addresses with embedded + * scope zone id, therefore we use zero zoneid here. */ - - bzero(&dst6, sizeof(dst6)); - dst6.sin6_family = AF_INET6; - dst6.sin6_len = sizeof(struct sockaddr_in6); - dst6.sin6_addr = ip6->ip6_dst; - ifp = m->m_pkthdr.rcvif; - IF_AFDATA_RLOCK(ifp); - lle = lla_lookup(LLTABLE6(ifp), 0, - (struct sockaddr *)&dst6); - IF_AFDATA_RUNLOCK(ifp); - if ((lle != NULL) && (lle->la_flags & LLE_IFADDR)) { - struct ifaddr *ifa; - struct in6_ifaddr *ia6; - int bad; - - bad = 1; - IF_ADDR_RLOCK(ifp); - TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family != dst6.sin6_family) - continue; - if (sa_equal(&dst6, ifa->ifa_addr)) - break; - } - KASSERT(ifa != NULL, ("%s: ifa not found for lle %p", - __func__, lle)); - - ia6 = (struct in6_ifaddr *)ifa; - if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { - /* Count the packet in the ip address stats */ - counter_u64_add(ia6->ia_ifa.ifa_ipackets, 1); - counter_u64_add(ia6->ia_ifa.ifa_ibytes, - m->m_pkthdr.len); - - /* - * record address information into m_tag. - */ - (void)ip6_setdstifaddr(m, ia6); - - bad = 0; - } else { + ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); + if (ia != NULL) { + if (ia->ia6_flags & IN6_IFF_NOTREADY) { char ip6bufs[INET6_ADDRSTRLEN]; char ip6bufd[INET6_ADDRSTRLEN]; /* address is not ready, so discard the packet. */ @@ -723,137 +668,15 @@ passin: "ip6_input: packet to an unready address %s->%s\n", ip6_sprintf(ip6bufs, &ip6->ip6_src), ip6_sprintf(ip6bufd, &ip6->ip6_dst))); - } - IF_ADDR_RUNLOCK(ifp); - LLE_RUNLOCK(lle); - if (bad) - goto bad; - else { - ours = 1; - deliverifp = ifp; - goto hbhcheck; - } - } - if (lle != NULL) - LLE_RUNLOCK(lle); - - dst = &rin6.ro_dst; - dst->sin6_len = sizeof(struct sockaddr_in6); - dst->sin6_family = AF_INET6; - dst->sin6_addr = ip6->ip6_dst; - rin6.ro_rt = in6_rtalloc1((struct sockaddr *)dst, 0, 0, M_GETFIB(m)); - if (rin6.ro_rt) - RT_UNLOCK(rin6.ro_rt); - -#define rt6_key(r) ((struct sockaddr_in6 *)((r)->rt_nodes->rn_key)) - - /* - * Accept the packet if the forwarding interface to the destination - * according to the routing table is the loopback interface, - * unless the associated route has a gateway. - * Note that this approach causes to accept a packet if there is a - * route to the loopback interface for the destination of the packet. - * But we think it's even useful in some situations, e.g. when using - * a special daemon which wants to intercept the packet. - * - * XXX: some OSes automatically make a cloned route for the destination - * of an outgoing packet. If the outgoing interface of the packet - * is a loopback one, the kernel would consider the packet to be - * accepted, even if we have no such address assinged on the interface. - * We check the cloned flag of the route entry to reject such cases, - * assuming that route entries for our own addresses are not made by - * cloning (it should be true because in6_addloop explicitly installs - * the host route). However, we might have to do an explicit check - * while it would be less efficient. Or, should we rather install a - * reject route for such a case? - */ - if (rin6.ro_rt && - (rin6.ro_rt->rt_flags & - (RTF_HOST|RTF_GATEWAY)) == RTF_HOST && -#ifdef RTF_WASCLONED - !(rin6.ro_rt->rt_flags & RTF_WASCLONED) && -#endif -#ifdef RTF_CLONED - !(rin6.ro_rt->rt_flags & RTF_CLONED) && -#endif -#if 0 - /* - * The check below is redundant since the comparison of - * the destination and the key of the rtentry has - * already done through looking up the routing table. - */ - IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, - &rt6_key(rin6.ro_rt)->sin6_addr) -#endif - rin6.ro_rt->rt_ifp->if_type == IFT_LOOP) { - int free_ia6 = 0; - struct in6_ifaddr *ia6; - - /* - * found the loopback route to the interface address - */ - if (rin6.ro_rt->rt_gateway->sa_family == AF_LINK) { - struct sockaddr_in6 dest6; - - bzero(&dest6, sizeof(dest6)); - dest6.sin6_family = AF_INET6; - dest6.sin6_len = sizeof(dest6); - dest6.sin6_addr = ip6->ip6_dst; - ia6 = (struct in6_ifaddr *) - ifa_ifwithaddr((struct sockaddr *)&dest6); - if (ia6 == NULL) - goto bad; - free_ia6 = 1; - } - else - ia6 = (struct in6_ifaddr *)rin6.ro_rt->rt_ifa; - - /* - * record address information into m_tag. - */ - (void)ip6_setdstifaddr(m, ia6); - - /* - * packets to a tentative, duplicated, or somehow invalid - * address must not be accepted. - */ - if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) { - /* this address is ready */ - ours = 1; - deliverifp = ia6->ia_ifp; /* correct? */ - /* Count the packet in the ip address stats */ - counter_u64_add(ia6->ia_ifa.ifa_ipackets, 1); - counter_u64_add(ia6->ia_ifa.ifa_ibytes, - m->m_pkthdr.len); - if (free_ia6) - ifa_free(&ia6->ia_ifa); - goto hbhcheck; - } else { - char ip6bufs[INET6_ADDRSTRLEN]; - char ip6bufd[INET6_ADDRSTRLEN]; - /* address is not ready, so discard the packet. */ - nd6log((LOG_INFO, - "ip6_input: packet to an unready address %s->%s\n", - ip6_sprintf(ip6bufs, &ip6->ip6_src), - ip6_sprintf(ip6bufd, &ip6->ip6_dst))); - - if (free_ia6) - ifa_free(&ia6->ia_ifa); + ifa_free(&ia->ia_ifa); goto bad; } - } - - /* - * FAITH (Firewall Aided Internet Translator) - */ - if (V_ip6_keepfaith) { - if (rin6.ro_rt && rin6.ro_rt->rt_ifp && - rin6.ro_rt->rt_ifp->if_type == IFT_FAITH) { - /* XXX do we need more sanity checks? */ - ours = 1; - deliverifp = rin6.ro_rt->rt_ifp; /* faith */ - goto hbhcheck; - } + /* Count the packet in the ip address stats */ + counter_u64_add(ia->ia_ifa.ifa_ipackets, 1); + counter_u64_add(ia->ia_ifa.ifa_ibytes, m->m_pkthdr.len); + ifa_free(&ia->ia_ifa); + ours = 1; + goto hbhcheck; } /* @@ -867,32 +690,6 @@ passin: } hbhcheck: - /* - * record address information into m_tag, if we don't have one yet. - * note that we are unable to record it, if the address is not listed - * as our interface address (e.g. multicast addresses, addresses - * within FAITH prefixes and such). - */ - if (deliverifp) { - struct in6_ifaddr *ia6; - - if ((ia6 = ip6_getdstifaddr(m)) != NULL) { - ifa_free(&ia6->ia_ifa); - } else { - ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst); - if (ia6) { - if (!ip6_setdstifaddr(m, ia6)) { - /* - * XXX maybe we should drop the packet here, - * as we could not provide enough information - * to the upper layers. - */ - } - ifa_free(&ia6->ia_ifa); - } - } - } - /* * Process Hop-by-Hop options header if it's contained. * m may be modified in ip6_hopopts_input(). @@ -900,11 +697,8 @@ passin: */ plen = (u_int32_t)ntohs(ip6->ip6_plen); if (ip6->ip6_nxt == IPPROTO_HOPOPTS) { - int error; - - error = ip6_input_hbh(m, &plen, &rtalert, &off, &nxt, &ours); - if (error != 0) - goto out; + if (ip6_input_hbh(m, &plen, &rtalert, &off, &nxt, &ours) != 0) + return; } else nxt = ip6->ip6_nxt; @@ -951,7 +745,7 @@ passin: } } else if (!ours) { ip6_forward(m, srcrt); - goto out; + return; } ip6 = mtod(m, struct ip6_hdr *); @@ -976,7 +770,7 @@ passin: * Tell launch routine the next header */ IP6STAT_INC(ip6s_delivered); - in6_ifstat_inc(deliverifp, ifs6_in_deliver); + in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_deliver); nest = 0; while (nxt != IPPROTO_DONE) { @@ -1014,47 +808,9 @@ passin: nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); } - goto out; + return; bad: m_freem(m); -out: - if (rin6.ro_rt) - RTFREE(rin6.ro_rt); -} - -/* - * set/grab in6_ifaddr correspond to IPv6 destination address. - * XXX backward compatibility wrapper - * - * XXXRW: We should bump the refcount on ia6 before sticking it in the m_tag, - * and then bump it when the tag is copied, and release it when the tag is - * freed. Unfortunately, m_tags don't support deep copies (yet), so instead - * we just bump the ia refcount when we receive it. This should be fixed. - */ -static struct ip6aux * -ip6_setdstifaddr(struct mbuf *m, struct in6_ifaddr *ia6) -{ - struct ip6aux *ip6a; - - ip6a = ip6_addaux(m); - if (ip6a) - ip6a->ip6a_dstia6 = ia6; - return ip6a; /* NULL if failed to set */ -} - -struct in6_ifaddr * -ip6_getdstifaddr(struct mbuf *m) -{ - struct ip6aux *ip6a; - struct in6_ifaddr *ia; - - ip6a = ip6_findaux(m); - if (ip6a) { - ia = ip6a->ip6a_dstia6; - ifa_ref(&ia->ia_ifa); - return ia; - } else - return NULL; } /* @@ -1817,42 +1573,6 @@ ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp) } } -static struct ip6aux * -ip6_addaux(struct mbuf *m) -{ - struct m_tag *mtag; - - mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); - if (!mtag) { - mtag = m_tag_get(PACKET_TAG_IPV6_INPUT, sizeof(struct ip6aux), - M_NOWAIT); - if (mtag) { - m_tag_prepend(m, mtag); - bzero(mtag + 1, sizeof(struct ip6aux)); - } - } - return mtag ? (struct ip6aux *)(mtag + 1) : NULL; -} - -static struct ip6aux * -ip6_findaux(struct mbuf *m) -{ - struct m_tag *mtag; - - mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); - return mtag ? (struct ip6aux *)(mtag + 1) : NULL; -} - -static void -ip6_delaux(struct mbuf *m) -{ - struct m_tag *mtag; - - mtag = m_tag_find(m, PACKET_TAG_IPV6_INPUT, NULL); - if (mtag) - m_tag_delete(m, mtag); -} - /* * System control for IP6 */ diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index e3e67816aad..3e6d4df71ac 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -273,11 +273,7 @@ ip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, /* * No IPsec processing is needed, free * reference to SP. - * - * NB: null pointer to avoid free at - * done: below. */ - KEY_FREESP(&sp), sp = NULL; goto done; } } diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 67d3f4e50df..07199019d96 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1331,7 +1331,6 @@ ip6_ctloutput(struct socket *so, struct sockopt *sopt) /* FALLTHROUGH */ case IPV6_UNICAST_HOPS: case IPV6_HOPLIMIT: - case IPV6_FAITH: case IPV6_RECVPKTINFO: case IPV6_RECVHOPLIMIT: @@ -1475,10 +1474,6 @@ do { \ OPTSET(IN6P_RTHDR); break; - case IPV6_FAITH: - OPTSET(INP_FAITH); - break; - case IPV6_RECVPATHMTU: /* * We ignore this option for TCP @@ -1746,7 +1741,6 @@ do { \ case IPV6_RECVRTHDR: case IPV6_RECVPATHMTU: - case IPV6_FAITH: case IPV6_V6ONLY: case IPV6_PORTRANGE: case IPV6_RECVTCLASS: @@ -1791,10 +1785,6 @@ do { \ optval = OPTBIT(IN6P_MTU); break; - case IPV6_FAITH: - optval = OPTBIT(INP_FAITH); - break; - case IPV6_V6ONLY: optval = OPTBIT(IN6P_IPV6_V6ONLY); break; diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 018f2ccf818..6a2d86a270f 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -256,37 +256,6 @@ VNET_PCPUSTAT_DECLARE(struct ip6stat, ip6stat); #define IP6STAT_DEC(name) IP6STAT_SUB(name, 1) #endif -#ifdef _KERNEL -/* - * IPv6 onion peeling state. - * it will be initialized when we come into ip6_input(). - * XXX do not make it a kitchen sink! - */ -struct ip6aux { - u_int32_t ip6a_flags; -#define IP6A_SWAP 0x01 /* swapped home/care-of on packet */ -#define IP6A_HASEEN 0x02 /* HA was present */ -#define IP6A_BRUID 0x04 /* BR Unique Identifier was present */ -#define IP6A_RTALERTSEEN 0x08 /* rtalert present */ - - /* ip6.ip6_src */ - struct in6_addr ip6a_careof; /* care-of address of the peer */ - struct in6_addr ip6a_home; /* home address of the peer */ - u_int16_t ip6a_bruid; /* BR unique identifier */ - - /* ip6.ip6_dst */ - struct in6_ifaddr *ip6a_dstia6; /* my ifaddr that matches ip6_dst */ - - /* rtalert */ - u_int16_t ip6a_rtalert; /* rtalert option value */ - - /* - * decapsulation history will be here. - * with IPsec it may not be accurate. - */ -}; -#endif - #ifdef _KERNEL /* flags passed to ip6_output as last parameter */ #define IPV6_UNSPECSRC 0x01 /* allow :: as the source address */ @@ -327,7 +296,6 @@ VNET_DECLARE(int, ip6_norbit_raif); /* Disable R-bit in NA on RA * receiving IF. */ VNET_DECLARE(int, ip6_rfc6204w3); /* Accept defroute from RA even when forwarding enabled */ -VNET_DECLARE(int, ip6_keepfaith); /* Firewall Aided Internet Translator */ VNET_DECLARE(int, ip6_log_interval); VNET_DECLARE(time_t, ip6_log_time); VNET_DECLARE(int, ip6_hdrnestlimit); /* upper limit of # of extension @@ -341,7 +309,6 @@ VNET_DECLARE(int, ip6_dad_count); /* DupAddrDetectionTransmits */ #define V_ip6_no_radr VNET(ip6_no_radr) #define V_ip6_norbit_raif VNET(ip6_norbit_raif) #define V_ip6_rfc6204w3 VNET(ip6_rfc6204w3) -#define V_ip6_keepfaith VNET(ip6_keepfaith) #define V_ip6_log_interval VNET(ip6_log_interval) #define V_ip6_log_time VNET(ip6_log_time) #define V_ip6_hdrnestlimit VNET(ip6_hdrnestlimit) @@ -388,7 +355,6 @@ int ip6proto_register(short); int ip6proto_unregister(short); void ip6_input(struct mbuf *); -struct in6_ifaddr *ip6_getdstifaddr(struct mbuf *); void ip6_freepcbopts(struct ip6_pktopts *); int ip6_unknown_opt(u_int8_t *, struct mbuf *, int); @@ -396,10 +362,6 @@ char * ip6_get_prevhdr(struct mbuf *, int); int ip6_nexthdr(struct mbuf *, int, int, int *); int ip6_lasthdr(struct mbuf *, int, int, int *); -#ifdef __notyet__ -struct ip6aux *ip6_findaux(struct mbuf *); -#endif - extern int (*ip6_mforward)(struct ip6_hdr *, struct ifnet *, struct mbuf *); diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 016a918d306..fd13aee79b1 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1835,7 +1835,7 @@ nd6_slowtimo(void *arg) callout_reset(&V_nd6_slowtimo_ch, ND6_SLOWTIMER_INTERVAL * hz, nd6_slowtimo, curvnet); IFNET_RLOCK_NOSLEEP(); - TAILQ_FOREACH(ifp, &V_ifnet, if_list) { + TAILQ_FOREACH(ifp, &V_ifnet, if_link) { if (ifp->if_afdata[AF_INET6] == NULL) continue; nd6if = ND_IFINFO(ifp); diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 138fdf33161..1ca7278980a 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -430,7 +430,6 @@ void nd6_ns_output(struct ifnet *, const struct in6_addr *, caddr_t nd6_ifptomac(struct ifnet *); void nd6_dad_start(struct ifaddr *, int); void nd6_dad_stop(struct ifaddr *); -void nd6_dad_duplicated(struct ifaddr *); /* nd6_rtr.c */ void nd6_rs_input(struct mbuf *, int, int); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 2cb9400cc58..60080f3c986 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -80,9 +80,12 @@ __FBSDID("$FreeBSD$"); struct dadq; static struct dadq *nd6_dad_find(struct ifaddr *); +static void nd6_dad_add(struct dadq *dp); +static void nd6_dad_del(struct dadq *dp); static void nd6_dad_starttimer(struct dadq *, int); static void nd6_dad_stoptimer(struct dadq *); static void nd6_dad_timer(struct dadq *); +static void nd6_dad_duplicated(struct ifaddr *, struct dadq *); static void nd6_dad_ns_output(struct dadq *, struct ifaddr *); static void nd6_dad_ns_input(struct ifaddr *); static void nd6_dad_na_input(struct ifaddr *); @@ -1148,6 +1151,26 @@ static VNET_DEFINE(struct rwlock, dad_rwlock); #define DADQ_WLOCK() rw_wlock(&V_dad_rwlock) #define DADQ_WUNLOCK() rw_wunlock(&V_dad_rwlock) +static void +nd6_dad_add(struct dadq *dp) +{ + + ifa_ref(dp->dad_ifa); /* just for safety */ + DADQ_WLOCK(); + TAILQ_INSERT_TAIL(&V_dadq, (struct dadq *)dp, dad_list); + DADQ_WUNLOCK(); +} + +static void +nd6_dad_del(struct dadq *dp) +{ + + ifa_free(dp->dad_ifa); + DADQ_WLOCK(); + TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); + DADQ_WUNLOCK(); +} + static struct dadq * nd6_dad_find(struct ifaddr *ifa) { @@ -1239,10 +1262,6 @@ nd6_dad_start(struct ifaddr *ifa, int delay) #ifdef VIMAGE dp->dad_vnet = curvnet; #endif - DADQ_WLOCK(); - TAILQ_INSERT_TAIL(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); - nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); @@ -1253,10 +1272,10 @@ nd6_dad_start(struct ifaddr *ifa, int delay) * (re)initialization. */ dp->dad_ifa = ifa; - ifa_ref(ifa); /* just for safety */ dp->dad_count = V_ip6_dad_count; dp->dad_ns_icount = dp->dad_na_icount = 0; dp->dad_ns_ocount = dp->dad_ns_tcount = 0; + nd6_dad_add(dp); if (delay == 0) { nd6_dad_ns_output(dp, ifa); nd6_dad_starttimer(dp, @@ -1284,12 +1303,8 @@ nd6_dad_stop(struct ifaddr *ifa) nd6_dad_stoptimer(dp); - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); - dp = NULL; - ifa_free(ifa); } static void @@ -1336,12 +1351,9 @@ nd6_dad_timer(struct dadq *dp) nd6log((LOG_INFO, "%s: could not run DAD, driver problem?\n", if_name(ifa->ifa_ifp))); - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); dp = NULL; - ifa_free(ifa); goto done; } @@ -1377,8 +1389,8 @@ nd6_dad_timer(struct dadq *dp) if (duplicate) { /* (*dp) will be freed in nd6_dad_duplicated() */ + nd6_dad_duplicated(ifa, dp); dp = NULL; - nd6_dad_duplicated(ifa); } else { /* * We are done with DAD. No NA came, no NS came. @@ -1394,12 +1406,9 @@ nd6_dad_timer(struct dadq *dp) if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr))); - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); dp = NULL; - ifa_free(ifa); } } @@ -1408,19 +1417,12 @@ done: } void -nd6_dad_duplicated(struct ifaddr *ifa) +nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) { struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa; struct ifnet *ifp; - struct dadq *dp; char ip6buf[INET6_ADDRSTRLEN]; - dp = nd6_dad_find(ifa); - if (dp == NULL) { - log(LOG_ERR, "nd6_dad_duplicated: DAD structure not found\n"); - return; - } - log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: " "NS in/out=%d/%d, NA in=%d\n", if_name(ifa->ifa_ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr), @@ -1473,12 +1475,8 @@ nd6_dad_duplicated(struct ifaddr *ifa) } } - DADQ_WLOCK(); - TAILQ_REMOVE(&V_dadq, (struct dadq *)dp, dad_list); - DADQ_WUNLOCK(); + nd6_dad_del(dp); free(dp, M_IP6NDP); - dp = NULL; - ifa_free(ifa); } static void @@ -1537,8 +1535,8 @@ nd6_dad_ns_input(struct ifaddr *ifa) /* XXX more checks for loopback situation - see nd6_dad_timer too */ if (duplicate) { + nd6_dad_duplicated(ifa, dp); dp = NULL; /* will be freed in nd6_dad_duplicated() */ - nd6_dad_duplicated(ifa); } else { /* * not sure if I got a duplicate. @@ -1562,5 +1560,5 @@ nd6_dad_na_input(struct ifaddr *ifa) dp->dad_na_icount++; /* remove the address. */ - nd6_dad_duplicated(ifa); + nd6_dad_duplicated(ifa, dp); } diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 63c0b0eb254..ffec9a31729 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -169,12 +169,6 @@ rip6_input(struct mbuf **mp, int *offp, int proto) RIP6STAT_INC(rip6s_ipackets); - if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { - /* XXX Send icmp6 host/port unreach? */ - m_freem(m); - return (IPPROTO_DONE); - } - init_sin6(&fromsa, m); /* general init */ ifp = m->m_pkthdr.rcvif; diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c index 15f9230be23..08847e57b0a 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -558,4 +558,25 @@ sa6_checkzone(struct sockaddr_in6 *sa6) return (sa6->sin6_scope_id ? 0: EADDRNOTAVAIL); } +/* + * This function is similar to sa6_checkzone, but it uses given ifp + * to initialize sin6_scope_id. + */ +int +sa6_checkzone_ifp(struct ifnet *ifp, struct sockaddr_in6 *sa6) +{ + int scope; + + scope = in6_addrscope(&sa6->sin6_addr); + if (scope == IPV6_ADDR_SCOPE_LINKLOCAL || + scope == IPV6_ADDR_SCOPE_INTFACELOCAL) { + if (sa6->sin6_scope_id == 0) { + sa6->sin6_scope_id = in6_getscopezone(ifp, scope); + return (0); + } else if (sa6->sin6_scope_id != in6_getscopezone(ifp, scope)) + return (EADDRNOTAVAIL); + } + return (sa6_checkzone(sa6)); +} + diff --git a/sys/netinet6/scope6_var.h b/sys/netinet6/scope6_var.h index 419e6b16146..d3c6445e7ca 100644 --- a/sys/netinet6/scope6_var.h +++ b/sys/netinet6/scope6_var.h @@ -58,6 +58,7 @@ u_int32_t scope6_addr2default(struct in6_addr *); int sa6_embedscope(struct sockaddr_in6 *, int); int sa6_recoverscope(struct sockaddr_in6 *); int sa6_checkzone(struct sockaddr_in6 *); +int sa6_checkzone_ifp(struct ifnet *, struct sockaddr_in6 *); int in6_setscope(struct in6_addr *, struct ifnet *, u_int32_t *); void in6_setllascope(struct in6_addr *in6, struct ifnet *ifp); int in6_clearscope(struct in6_addr *); diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c index a2393ec5120..037127eef68 100644 --- a/sys/netinet6/sctp6_usrreq.c +++ b/sys/netinet6/sctp6_usrreq.c @@ -149,10 +149,6 @@ sctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) { goto out; } - if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) { - /* XXX send icmp6 host/port unreach? */ - goto out; - } length = ntohs(ip6->ip6_plen) + iphlen; /* Validate mbuf chain length with IP payload length. */ if (SCTP_HEADER_LEN(m) != length) { diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 11a97c55ba7..b151273ee00 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -208,12 +208,6 @@ udp6_input(struct mbuf **mp, int *offp, int proto) ifp = m->m_pkthdr.rcvif; ip6 = mtod(m, struct ip6_hdr *); - if (faithprefix_p != NULL && (*faithprefix_p)(&ip6->ip6_dst)) { - /* XXX send icmp6 host/port unreach? */ - m_freem(m); - return (IPPROTO_DONE); - } - #ifndef PULLDOWN_TEST IP6_EXTHDR_CHECK(m, off, sizeof(struct udphdr), IPPROTO_DONE); ip6 = mtod(m, struct ip6_hdr *); diff --git a/sys/netipsec/ipsec_input.c b/sys/netipsec/ipsec_input.c index b0fa0f29aac..06364a3ab38 100644 --- a/sys/netipsec/ipsec_input.c +++ b/sys/netipsec/ipsec_input.c @@ -671,8 +671,8 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(struct ip6_hdr)); /* Save protocol */ - prot = 0; - m_copydata(m, protoff, 1, (unsigned char *) &prot); + m_copydata(m, protoff, 1, &nxt8); + prot = nxt8; #ifdef DEV_ENC if_inc_counter(encif, IFCOUNTER_IPACKETS, 1); @@ -684,9 +684,47 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto return (error); #endif /* DEV_ENC */ + /* IPv6-in-IP encapsulation */ + if (prot == IPPROTO_IPV6 && + saidx->mode != IPSEC_MODE_TRANSPORT) { + if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { + IPSEC_ISTAT(sproto, hdrops); + error = EINVAL; + goto bad; + } + /* ip6n will now contain the inner IPv6 header. */ + m_striphdr(m, 0, skip); + skip = 0; +#ifdef notyet + /* + * Check that the inner source address is the same as + * the proxy address, if available. + */ + if ((saidx->proxy.sa.sa_family == AF_INET6 && + !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) && + !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, + &saidx->proxy.sin6.sin6_addr)) || + (saidx->proxy.sa.sa_family != AF_INET6 && + saidx->proxy.sa.sa_family != 0)) { + + DPRINTF(("%s: inner source address %s doesn't " + "correspond to expected proxy source %s, " + "SA %s/%08lx\n", __func__, + ip6_sprintf(ip6buf, &ip6n.ip6_src), + ipsec_address(&saidx->proxy), + ipsec_address(&saidx->dst), + (u_long) ntohl(sav->spi))); + + IPSEC_ISTAT(sproto, pdrops); + error = EACCES; + goto bad; + } +#endif /* notyet */ + } #ifdef INET /* IP-in-IP encapsulation */ - if (prot == IPPROTO_IPIP) { + else if (prot == IPPROTO_IPIP && + saidx->mode != IPSEC_MODE_TRANSPORT) { if (m->m_pkthdr.len - skip < sizeof(struct ip)) { IPSEC_ISTAT(sproto, hdrops); error = EINVAL; @@ -721,41 +759,8 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto #endif /* notyet */ } #endif /* INET */ - /* IPv6-in-IP encapsulation */ - if (prot == IPPROTO_IPV6) { - if (m->m_pkthdr.len - skip < sizeof(struct ip6_hdr)) { - IPSEC_ISTAT(sproto, hdrops); - error = EINVAL; - goto bad; - } - /* ip6n will now contain the inner IPv6 header. */ - m_striphdr(m, 0, skip); - skip = 0; -#ifdef notyet - /* - * Check that the inner source address is the same as - * the proxy address, if available. - */ - if ((saidx->proxy.sa.sa_family == AF_INET6 && - !IN6_IS_ADDR_UNSPECIFIED(&saidx->proxy.sin6.sin6_addr) && - !IN6_ARE_ADDR_EQUAL(&ip6n.ip6_src, - &saidx->proxy.sin6.sin6_addr)) || - (saidx->proxy.sa.sa_family != AF_INET6 && - saidx->proxy.sa.sa_family != 0)) { - - DPRINTF(("%s: inner source address %s doesn't " - "correspond to expected proxy source %s, " - "SA %s/%08lx\n", __func__, - ip6_sprintf(ip6buf, &ip6n.ip6_src), - ipsec_address(&saidx->proxy), - ipsec_address(&saidx->dst), - (u_long) ntohl(sav->spi))); - - IPSEC_ISTAT(sproto, pdrops); - error = EACCES; - goto bad; - } -#endif /* notyet */ + else { + prot = IPPROTO_IPV6; /* for correct BPF processing */ } /* @@ -807,10 +812,6 @@ ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip, int proto if ((error = ipsec_filter(&m, PFIL_IN, ENC_IN|ENC_AFTER)) != 0) return (error); #endif /* DEV_ENC */ - /* Retrieve new protocol */ - /* We have stripped the IP6 header from the mbuf, we have to use the backuped proto value instead */ - nxt8 = prot; - /* * See the end of ip6_input for this logic. * IPPROTO_IPV[46] case will be processed just like other ones diff --git a/sys/netipsec/ipsec_output.c b/sys/netipsec/ipsec_output.c index a64e3f2d5d2..4b4d9ccbb41 100644 --- a/sys/netipsec/ipsec_output.c +++ b/sys/netipsec/ipsec_output.c @@ -165,11 +165,11 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) * doing further processing. */ if (isr->next) { - IPSECSTAT_INC(ips_out_bundlesa); /* XXX-BZ currently only support same AF bundles. */ switch (saidx->dst.sa.sa_family) { #ifdef INET case AF_INET: + IPSECSTAT_INC(ips_out_bundlesa); return ipsec4_process_packet(m, isr->next, 0, 0); /* NOTREACHED */ #endif @@ -177,6 +177,7 @@ ipsec_process_done(struct mbuf *m, struct ipsecrequest *isr) #ifdef INET6 case AF_INET6: /* XXX */ + IPSEC6STAT_INC(ips_out_bundlesa); return ipsec6_process_packet(m, isr->next); /* NOTREACHED */ #endif /* INET6 */ @@ -358,7 +359,16 @@ again: * this packet because it is responsibility for * upper layer to retransmit the packet. */ - IPSECSTAT_INC(ips_out_nosa); + switch(af) { + case AF_INET: + IPSECSTAT_INC(ips_out_nosa); + break; +#ifdef INET6 + case AF_INET6: + IPSEC6STAT_INC(ips_out_nosa); + break; +#endif + } goto bad; } sav = isr->sav; @@ -640,6 +650,8 @@ ipsec6_process_packet( sav = isr->sav; dst = &sav->sah->saidx.dst; + ip6 = mtod(m, struct ip6_hdr *); + ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); #ifdef DEV_ENC if_inc_counter(encif, IFCOUNTER_OPACKETS, 1); if_inc_counter(encif, IFCOUNTER_OBYTES, m->m_pkthdr.len); @@ -651,8 +663,6 @@ ipsec6_process_packet( goto bad; #endif /* DEV_ENC */ - ip6 = mtod(m, struct ip6_hdr *); /* XXX */ - /* Do the appropriate encapsulation, if necessary */ if (isr->saidx.mode == IPSEC_MODE_TUNNEL || /* Tunnel requ'd */ dst->sa.sa_family != AF_INET6 || /* PF mismatch */ @@ -675,9 +685,6 @@ ipsec6_process_packet( goto bad; } - ip6 = mtod(m, struct ip6_hdr *); - ip6->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); - /* Encapsulate the packet */ error = ipip_output(m, isr, &mp, 0, 0); if (mp == NULL && !error) { diff --git a/sys/netipsec/xform_ipip.c b/sys/netipsec/xform_ipip.c index 830521ac2b1..591c44f9297 100644 --- a/sys/netipsec/xform_ipip.c +++ b/sys/netipsec/xform_ipip.c @@ -488,12 +488,9 @@ ipip_output( ip6o->ip6_flow = 0; ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; ip6o->ip6_vfc |= IPV6_VERSION; - ip6o->ip6_plen = htons(m->m_pkthdr.len); ip6o->ip6_hlim = IPV6_DEFHLIM; ip6o->ip6_dst = saidx->dst.sin6.sin6_addr; ip6o->ip6_src = saidx->src.sin6.sin6_addr; - - /* Fix payload length */ ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6)); switch (tp) { diff --git a/sys/netpfil/ipfw/ip_fw_private.h b/sys/netpfil/ipfw/ip_fw_private.h index b88c5dbfd00..ddb73e7f155 100644 --- a/sys/netpfil/ipfw/ip_fw_private.h +++ b/sys/netpfil/ipfw/ip_fw_private.h @@ -66,14 +66,12 @@ enum { */ struct _ip6dn_args { struct ip6_pktopts *opt_or; - struct route_in6 ro_or; int flags_or; struct ip6_moptions *im6o_or; struct ifnet *origifp_or; struct ifnet *ifp_or; struct sockaddr_in6 dst_or; u_long mtu_or; - struct route_in6 ro_pmtu_or; }; diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 9f0934c78d8..104fc048976 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -141,18 +141,11 @@ struct pf_send_entry { PFSE_ICMP, PFSE_ICMP6, } pfse_type; - union { - struct route ro; - struct { - int type; - int code; - int mtu; - } icmpopts; - } u; -#define pfse_ro u.ro -#define pfse_icmp_type u.icmpopts.type -#define pfse_icmp_code u.icmpopts.code -#define pfse_icmp_mtu u.icmpopts.mtu + struct { + int type; + int code; + int mtu; + } icmpopts; }; STAILQ_HEAD(pf_send_head, pf_send_entry); @@ -1372,8 +1365,8 @@ pf_intr(void *v) ip_output(pfse->pfse_m, NULL, NULL, 0, NULL, NULL); break; case PFSE_ICMP: - icmp_error(pfse->pfse_m, pfse->pfse_icmp_type, - pfse->pfse_icmp_code, 0, pfse->pfse_icmp_mtu); + icmp_error(pfse->pfse_m, pfse->icmpopts.type, + pfse->icmpopts.code, 0, pfse->icmpopts.mtu); break; #endif /* INET */ #ifdef INET6 @@ -1381,8 +1374,8 @@ pf_intr(void *v) ip6_output(pfse->pfse_m, NULL, NULL, 0, NULL, NULL); break; case PFSE_ICMP6: - icmp6_error(pfse->pfse_m, pfse->pfse_icmp_type, - pfse->pfse_icmp_code, pfse->pfse_icmp_mtu); + icmp6_error(pfse->pfse_m, pfse->icmpopts.type, + pfse->icmpopts.code, pfse->icmpopts.mtu); break; #endif /* INET6 */ default: @@ -2414,8 +2407,8 @@ pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, #endif /* INET6 */ } pfse->pfse_m = m0; - pfse->pfse_icmp_type = type; - pfse->pfse_icmp_code = code; + pfse->icmpopts.type = type; + pfse->icmpopts.code = code; pf_send(pfse); } diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index dba56745fae..213e49cb52f 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #ifdef INET6 @@ -3619,12 +3620,11 @@ pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir, int chk; /* We need a proper CSUM before we start (s. OpenBSD ip_output) */ - if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { -#ifdef INET - /* XXX-BZ copy&paste error from r126261? */ - in_delayed_cksum(*m); -#endif - (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; + if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { + in6_delayed_cksum(*m, + (*m)->m_pkthdr.len - sizeof(struct ip6_hdr), + sizeof(struct ip6_hdr)); + (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; } CURVNET_SET(ifp->if_vnet); chk = pf_test6(PF_OUT, ifp, m, inp); diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c index 910424dd768..a6eba64e162 100644 --- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c +++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c @@ -747,7 +747,7 @@ sdp_start_disconnect(struct sdp_sock *ssk) ("sdp_start_disconnect: sdp_drop() returned NULL")); } else { soisdisconnecting(so); - unread = so->so_rcv.sb_cc; + unread = sbused(&so->so_rcv); sbflush(&so->so_rcv); sdp_usrclosed(ssk); if (!(ssk->flags & SDP_DROPPED)) { @@ -1259,7 +1259,7 @@ sdp_sorecv(struct socket *so, struct sockaddr **psa, struct uio *uio, /* We will never ever get anything unless we are connected. */ if (!(so->so_state & (SS_ISCONNECTED|SS_ISDISCONNECTED))) { /* When disconnecting there may be still some data left. */ - if (sb->sb_cc > 0) + if (sbavail(sb)) goto deliver; if (!(so->so_state & SS_ISDISCONNECTED)) error = ENOTCONN; @@ -1267,7 +1267,7 @@ sdp_sorecv(struct socket *so, struct sockaddr **psa, struct uio *uio, } /* Socket buffer is empty and we shall not block. */ - if (sb->sb_cc == 0 && + if (sbavail(sb) == 0 && ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)))) { error = EAGAIN; goto out; @@ -1278,7 +1278,7 @@ restart: /* Abort if socket has reported problems. */ if (so->so_error) { - if (sb->sb_cc > 0) + if (sbavail(sb)) goto deliver; if (oresid > uio->uio_resid) goto out; @@ -1290,25 +1290,25 @@ restart: /* Door is closed. Deliver what is left, if any. */ if (sb->sb_state & SBS_CANTRCVMORE) { - if (sb->sb_cc > 0) + if (sbavail(sb)) goto deliver; else goto out; } /* Socket buffer got some data that we shall deliver now. */ - if (sb->sb_cc > 0 && !(flags & MSG_WAITALL) && + if (sbavail(sb) && !(flags & MSG_WAITALL) && ((so->so_state & SS_NBIO) || (flags & (MSG_DONTWAIT|MSG_NBIO)) || - sb->sb_cc >= sb->sb_lowat || - sb->sb_cc >= uio->uio_resid || - sb->sb_cc >= sb->sb_hiwat) ) { + sbavail(sb) >= sb->sb_lowat || + sbavail(sb) >= uio->uio_resid || + sbavail(sb) >= sb->sb_hiwat) ) { goto deliver; } /* On MSG_WAITALL we must wait until all data or error arrives. */ if ((flags & MSG_WAITALL) && - (sb->sb_cc >= uio->uio_resid || sb->sb_cc >= sb->sb_lowat)) + (sbavail(sb) >= uio->uio_resid || sbavail(sb) >= sb->sb_lowat)) goto deliver; /* @@ -1322,7 +1322,7 @@ restart: deliver: SOCKBUF_LOCK_ASSERT(&so->so_rcv); - KASSERT(sb->sb_cc > 0, ("%s: sockbuf empty", __func__)); + KASSERT(sbavail(sb), ("%s: sockbuf empty", __func__)); KASSERT(sb->sb_mb != NULL, ("%s: sb_mb == NULL", __func__)); /* Statistics. */ @@ -1330,7 +1330,7 @@ deliver: uio->uio_td->td_ru.ru_msgrcv++; /* Fill uio until full or current end of socket buffer is reached. */ - len = min(uio->uio_resid, sb->sb_cc); + len = min(uio->uio_resid, sbavail(sb)); if (mp0 != NULL) { /* Dequeue as many mbufs as possible. */ if (!(flags & MSG_PEEK) && len >= sb->sb_mb->m_len) { @@ -1510,7 +1510,7 @@ sdp_urg(struct sdp_sock *ssk, struct mbuf *mb) if (so == NULL) return; - so->so_oobmark = so->so_rcv.sb_cc + mb->m_pkthdr.len - 1; + so->so_oobmark = sbused(&so->so_rcv) + mb->m_pkthdr.len - 1; sohasoutofband(so); ssk->oobflags &= ~(SDP_HAVEOOB | SDP_HADOOB); if (!(so->so_options & SO_OOBINLINE)) { diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c index f8d6181c0ed..1fe5cb060fa 100644 --- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c +++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_rx.c @@ -183,7 +183,7 @@ sdp_post_recvs_needed(struct sdp_sock *ssk) * Compute bytes in the receive queue and socket buffer. */ bytes_in_process = (posted - SDP_MIN_TX_CREDITS) * buffer_size; - bytes_in_process += ssk->socket->so_rcv.sb_cc; + bytes_in_process += sbused(&ssk->socket->so_rcv); return bytes_in_process < max_bytes; } diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index ea89d325874..299606aa827 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -231,7 +231,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S index 0d11ac8cf90..56ca7155ddd 100644 --- a/sys/powerpc/aim/trap_subr32.S +++ b/sys/powerpc/aim/trap_subr32.S @@ -313,7 +313,6 @@ cpu_reset: mflr %r1 addi %r1,%r1,(124-16)@l - lis %r3,1@l bla CNAME(cpudep_ap_early_bootstrap) lis %r3,1@l bla CNAME(pmap_cpu_bootstrap) diff --git a/sys/powerpc/aim/trap_subr64.S b/sys/powerpc/aim/trap_subr64.S index 688912eb26b..bedf1f1962c 100644 --- a/sys/powerpc/aim/trap_subr64.S +++ b/sys/powerpc/aim/trap_subr64.S @@ -312,7 +312,6 @@ cpu_reset: lis %r3,tocbase@ha ld %r2,tocbase@l(%r3) - lis %r3,1@l bl CNAME(cpudep_ap_early_bootstrap) /* Set PCPU */ nop lis %r3,1@l diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index dfd5a61945d..d1ee43c9cf7 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -154,7 +154,6 @@ device tun # Packet tunnel. device md # Memory "disks" device ofwd # Open Firmware disks device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying/(translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64 index 3ce6e3cdbd5..3e4d72f6581 100644 --- a/sys/powerpc/conf/GENERIC64 +++ b/sys/powerpc/conf/GENERIC64 @@ -157,7 +157,6 @@ device tun # Packet tunnel. device md # Memory "disks" device ofwd # Open Firmware disks device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying/(translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/powerpc/conf/WII b/sys/powerpc/conf/WII index e4d61b25352..8e21f2a0d50 100644 --- a/sys/powerpc/conf/WII +++ b/sys/powerpc/conf/WII @@ -77,7 +77,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying/(translation) device firmware # firmware assist module diff --git a/sys/powerpc/powermac/pmu.c b/sys/powerpc/powermac/pmu.c index 938ca74824c..9df83cbf7bc 100644 --- a/sys/powerpc/powermac/pmu.c +++ b/sys/powerpc/powermac/pmu.c @@ -734,15 +734,15 @@ pmu_intr(void *arg) /* if the lid was just closed, notify devd. */ if ((resp[2] & PMU_ENV_LID_CLOSED) && (!sc->lid_closed)) { sc->lid_closed = 1; - if (devctl_process_running()) - devctl_notify("PMU", "lid", "close", NULL); + devctl_notify("PMU", "lid", "close", NULL); } else if (!(resp[2] & PMU_ENV_LID_CLOSED) && (sc->lid_closed)) { /* if the lid was just opened, notify devd. */ - if (devctl_process_running()) - devctl_notify("PMU", "lid", "open", NULL); sc->lid_closed = 0; + devctl_notify("PMU", "lid", "open", NULL); } + if (resp[2] & PMU_ENV_POWER) + devctl_notify("PMU", "Button", "pressed", NULL); } } diff --git a/sys/powerpc/powermac/pmuvar.h b/sys/powerpc/powermac/pmuvar.h index 98209f8912e..21c56160b62 100644 --- a/sys/powerpc/powermac/pmuvar.h +++ b/sys/powerpc/powermac/pmuvar.h @@ -99,6 +99,7 @@ /* Bits from PMU_GET_LID_STATE or PMU_INT_ENVIRONMENT on core99 */ #define PMU_ENV_LID_CLOSED 0x01 /* The lid is closed */ +#define PMU_ENV_POWER 0x08 /* Power Button pressed */ /* PMU PMU_POWER_EVENTS commands */ enum { diff --git a/sys/powerpc/powerpc/db_trace.c b/sys/powerpc/powerpc/db_trace.c index 2462308b64c..f18554ab2a4 100644 --- a/sys/powerpc/powerpc/db_trace.c +++ b/sys/powerpc/powerpc/db_trace.c @@ -135,9 +135,6 @@ static int db_backtrace(struct thread *td, db_addr_t fp, int count) { db_addr_t stackframe, lr, *args; - db_expr_t diff; - c_db_sym_t sym; - const char *symname; boolean_t kernel_only = TRUE; boolean_t full = FALSE; @@ -265,16 +262,8 @@ db_backtrace(struct thread *td, db_addr_t fp, int count) print_trap: lr = (db_addr_t) tf->srr0; - diff = 0; - symname = NULL; - sym = db_search_symbol(lr, DB_STGY_ANY, &diff); - db_symbol_values(sym, &symname, 0); - if (symname == NULL || !strcmp(symname, "end")) { - db_printf("%#zx: srr1=%#zx\n", lr, tf->srr1); - } else { - db_printf("%s+%#zx: srr1=%#zx\n", symname, diff, - tf->srr1); - } + db_printsym(lr, DB_STGY_ANY); + db_printf(": srr1=%#x\n", tf->srr1); db_printf("%-10s r1=%#zx cr=%#x xer=%#x ctr=%#zx", "", tf->fixreg[1], (uint32_t)tf->cr, (uint32_t)tf->xer, tf->ctr); @@ -288,14 +277,8 @@ db_backtrace(struct thread *td, db_addr_t fp, int count) goto next_frame; } - diff = 0; - symname = NULL; - sym = db_search_symbol(lr, DB_STGY_ANY, &diff); - db_symbol_values(sym, &symname, 0); - if (symname == NULL || !strcmp(symname, "end")) - db_printf("at %zx", lr); - else - db_printf("at %s+%#zx", symname, diff); + db_printf("at "); + db_printsym(lr, DB_STGY_PROC); if (full) /* Print all the args stored in that stackframe. */ db_printf("(%zx, %zx, %zx, %zx, %zx, %zx, %zx, %zx)", diff --git a/sys/powerpc/wii/wii_gpio.c b/sys/powerpc/wii/wii_gpio.c index b9ecccb3980..e6d76b8c2ab 100644 --- a/sys/powerpc/wii/wii_gpio.c +++ b/sys/powerpc/wii/wii_gpio.c @@ -295,11 +295,6 @@ wiigpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) if (pin >= WIIGPIO_NPINS) return (EINVAL); - if ((flags & ~(GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) != 0) - return (EINVAL); - if ((flags & (GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) == - (GPIO_PIN_OUTPUT|GPIO_PIN_INPUT)) - return (EINVAL); sc = device_get_softc(dev); pinbank = WIIGPIO_PINBANK(pin); pinmask = WIIGPIO_PINMASK(pin); diff --git a/sys/rpc/clnt_vc.c b/sys/rpc/clnt_vc.c index 67ad58f5cd1..3899511990a 100644 --- a/sys/rpc/clnt_vc.c +++ b/sys/rpc/clnt_vc.c @@ -860,7 +860,7 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag) * error condition */ do_read = FALSE; - if (so->so_rcv.sb_cc >= sizeof(uint32_t) + if (sbavail(&so->so_rcv) >= sizeof(uint32_t) || (so->so_rcv.sb_state & SBS_CANTRCVMORE) || so->so_error) do_read = TRUE; @@ -913,7 +913,7 @@ clnt_vc_soupcall(struct socket *so, void *arg, int waitflag) * buffered. */ do_read = FALSE; - if (so->so_rcv.sb_cc >= ct->ct_record_resid + if (sbavail(&so->so_rcv) >= ct->ct_record_resid || (so->so_rcv.sb_state & SBS_CANTRCVMORE) || so->so_error) do_read = TRUE; diff --git a/sys/rpc/svc_vc.c b/sys/rpc/svc_vc.c index df1d86e045c..0190a0ce383 100644 --- a/sys/rpc/svc_vc.c +++ b/sys/rpc/svc_vc.c @@ -546,7 +546,7 @@ svc_vc_ack(SVCXPRT *xprt, uint32_t *ack) { *ack = atomic_load_acq_32(&xprt->xp_snt_cnt); - *ack -= xprt->xp_socket->so_snd.sb_cc; + *ack -= sbused(&xprt->xp_socket->so_snd); return (TRUE); } diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index 306f1dad24b..0f9aa1bc1ee 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -225,7 +225,6 @@ device vlan # 802.1Q VLAN support device tun # Packet tunnel. device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) device firmware # firmware assist module # The `bpf' device enables the Berkeley Packet Filter. diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 8c50581cb1c..9d73d59a078 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -336,7 +336,7 @@ struct dumperinfo { off_t mediasize; /* Space available in bytes. */ }; -int set_dumper(struct dumperinfo *, const char *_devname); +int set_dumper(struct dumperinfo *, const char *_devname, struct thread *td); int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); int dumpsys(struct dumperinfo *); int doadump(boolean_t); diff --git a/sys/sys/event.h b/sys/sys/event.h index c712f76ac34..089c9b3874f 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -69,6 +69,7 @@ struct kevent { #define EV_DELETE 0x0002 /* delete event from kq */ #define EV_ENABLE 0x0004 /* enable event */ #define EV_DISABLE 0x0008 /* disable event (not reported) */ +#define EV_FORCEONESHOT 0x0100 /* enable _ONESHOT and force trigger */ /* flags */ #define EV_ONESHOT 0x0010 /* only report one occurrence */ diff --git a/sys/sys/file.h b/sys/sys/file.h index e593d432624..d102a871ee3 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -90,9 +90,6 @@ foffset_get(struct file *fp) return (foffset_lock(fp, FOF_NOLOCK)); } -/* XXX pollution? */ -struct sendfile_sync; - typedef int fo_rdwr_t(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags, struct thread *td); @@ -112,8 +109,7 @@ typedef int fo_chown_t(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred, struct thread *td); typedef int fo_sendfile_t(struct file *fp, int sockfd, struct uio *hdr_uio, struct uio *trl_uio, off_t offset, size_t nbytes, - off_t *sent, int flags, int kflags, - struct sendfile_sync *sfs, struct thread *td); + off_t *sent, int flags, int kflags, struct thread *td); typedef int fo_seek_t(struct file *fp, off_t offset, int whence, struct thread *td); typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif, @@ -371,11 +367,11 @@ fo_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred, static __inline int fo_sendfile(struct file *fp, int sockfd, struct uio *hdr_uio, struct uio *trl_uio, off_t offset, size_t nbytes, off_t *sent, int flags, - int kflags, struct sendfile_sync *sfs, struct thread *td) + int kflags, struct thread *td) { return ((*fp->f_ops->fo_sendfile)(fp, sockfd, hdr_uio, trl_uio, offset, - nbytes, sent, flags, kflags, sfs, td)); + nbytes, sent, flags, kflags, td)); } static __inline int diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 3b8f7ebb335..9cef6aa5a0d 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -158,7 +158,7 @@ void fdsetugidsafety(struct thread *td); struct filedesc *fdcopy(struct filedesc *fdp); void fdunshare(struct thread *td); void fdescfree(struct thread *td); -struct filedesc *fdinit(struct filedesc *fdp); +struct filedesc *fdinit(struct filedesc *fdp, bool prepfiles); struct filedesc *fdshare(struct filedesc *fdp); struct filedesc_to_leader * filedesc_to_leader_alloc(struct filedesc_to_leader *old, diff --git a/sys/sys/param.h b/sys/sys/param.h index 7bd75e4c6ce..1afd4ea3e92 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -58,7 +58,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1100045 /* Master, propagated to newvers */ +#define __FreeBSD_version 1100047 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, diff --git a/sys/sys/poll.h b/sys/sys/poll.h index c955f321c75..ca3ce12873c 100644 --- a/sys/sys/poll.h +++ b/sys/sys/poll.h @@ -95,8 +95,26 @@ struct pollfd { #ifndef _KERNEL +#if __BSD_VISIBLE +#include + +#include +#include + +#ifndef _SIGSET_T_DECLARED +#define _SIGSET_T_DECLARED +typedef __sigset_t sigset_t; +#endif + +#endif + __BEGIN_DECLS int poll(struct pollfd _pfd[], nfds_t _nfds, int _timeout); +#if __BSD_VISIBLE +int ppoll(struct pollfd _pfd[], nfds_t _nfds, + const struct timespec *__restrict _timeout, + const sigset_t *__restrict _newsigmask); +#endif __END_DECLS #endif /* !_KERNEL */ diff --git a/sys/sys/protosw.h b/sys/sys/protosw.h index ba45f946196..2d98a4c25ed 100644 --- a/sys/sys/protosw.h +++ b/sys/sys/protosw.h @@ -274,8 +274,8 @@ int pru_sopoll_notsupp(struct socket *so, int events, struct ucred *cred, #define PRC_IFDOWN 0 /* interface transition */ #define PRC_ROUTEDEAD 1 /* select new route if possible ??? */ #define PRC_IFUP 2 /* interface has come back up */ -#define PRC_QUENCH2 3 /* DEC congestion bit says slow down */ -#define PRC_QUENCH 4 /* some one said to slow down */ +/* was PRC_QUENCH2 3 DEC congestion bit says slow down */ +/* was PRC_QUENCH 4 Deprecated by RFC 6633 */ #define PRC_MSGSIZE 5 /* message size forced drop */ #define PRC_HOSTDEAD 6 /* host appears to be down */ #define PRC_HOSTUNREACH 7 /* deprecated (use PRC_UNREACH_HOST) */ diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h index ef80e9c1457..f9e8da4cde0 100644 --- a/sys/sys/sockbuf.h +++ b/sys/sys/sockbuf.h @@ -165,6 +165,34 @@ int sbwait(struct sockbuf *sb); int sblock(struct sockbuf *sb, int flags); void sbunlock(struct sockbuf *sb); +/* + * Return how much data is available to be taken out of socket + * bufffer right now. + */ +static inline u_int +sbavail(struct sockbuf *sb) +{ + +#if 0 + SOCKBUF_LOCK_ASSERT(sb); +#endif + return (sb->sb_cc); +} + +/* + * Return how much data sits there in the socket buffer + * It might be that some data is not yet ready to be read. + */ +static inline u_int +sbused(struct sockbuf *sb) +{ + +#if 0 + SOCKBUF_LOCK_ASSERT(sb); +#endif + return (sb->sb_cc); +} + /* * How much space is there in a socket buffer (so->so_snd or so->so_rcv)? * This is problematical if the fields are unsigned, as the space might diff --git a/sys/sys/socket.h b/sys/sys/socket.h index cc43fa21dc0..18e2de10e10 100644 --- a/sys/sys/socket.h +++ b/sys/sys/socket.h @@ -583,28 +583,12 @@ struct sf_hdtr { int trl_cnt; /* number of trailer iovec's */ }; -/* - * sendfile(2) kqueue information - */ -struct sf_hdtr_kq { - uintptr_t kq_ident; /* ident (from userland?) */ - void *kq_udata; /* user data pointer */ - uint32_t kq_flags; /* extra flags to pass in */ - int kq_fd; /* kq fd to post completion events on */ -}; - -struct sf_hdtr_all { - struct sf_hdtr hdtr; - struct sf_hdtr_kq kq; -}; - /* * Sendfile-specific flag(s) */ #define SF_NODISKIO 0x00000001 #define SF_MNOWAIT 0x00000002 #define SF_SYNC 0x00000004 -#define SF_KQUEUE 0x00000008 #ifdef _KERNEL #define SFK_COMPAT 0x00000001 diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index bfdae0d0716..dfeeede33bb 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -208,7 +208,7 @@ struct xsocket { /* can we read something from so? */ #define soreadabledata(so) \ - ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \ + (sbavail(&(so)->so_rcv) >= (so)->so_rcv.sb_lowat || \ !TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error) #define soreadable(so) \ (soreadabledata(so) || ((so)->so_rcv.sb_state & SBS_CANTRCVMORE)) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 576b420fff9..b9b5fe4ea2a 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/kern/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ #define SYS_syscall 0 @@ -462,4 +462,5 @@ #define SYS_pipe2 542 #define SYS_aio_mlock 543 #define SYS_procctl 544 -#define SYS_MAXSYSCALL 545 +#define SYS_ppoll 545 +#define SYS_MAXSYSCALL 546 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 47d204612ee..b411627ae0e 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # FreeBSD system call names. # DO NOT EDIT-- this file is automatically generated. # $FreeBSD$ -# created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel +# created from FreeBSD: head/sys/kern/syscalls.master 274462 2014-11-13 05:26:14Z dchagin MIASM = \ syscall.o \ exit.o \ @@ -409,4 +409,5 @@ MIASM = \ accept4.o \ pipe2.o \ aio_mlock.o \ - procctl.o + procctl.o \ + ppoll.o diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 7098c43445a..5e612104035 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -46,6 +46,7 @@ struct ksiginfo; struct mbuf; struct msghdr; struct msqid_ds; +struct pollfd; struct ogetdirentries_args; struct rlimit; struct rusage; @@ -62,22 +63,16 @@ int kern_accept(struct thread *td, int s, struct sockaddr **name, socklen_t *namelen, struct file **fp); int kern_accept4(struct thread *td, int s, struct sockaddr **name, socklen_t *namelen, int flags, struct file **fp); -int kern_access(struct thread *td, char *path, enum uio_seg pathseg, - int flags); int kern_accessat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int flags, int mode); int kern_adjtime(struct thread *td, struct timeval *delta, struct timeval *olddelta); int kern_alternate_path(struct thread *td, const char *prefix, const char *path, enum uio_seg pathseg, char **pathbuf, int create, int dirfd); -int kern_bind(struct thread *td, int fd, struct sockaddr *sa); +int kern_bindat(struct thread *td, int dirfd, int fd, struct sockaddr *sa); int kern_cap_ioctls_limit(struct thread *td, int fd, u_long *cmds, size_t ncmds); int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg); -int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg, - int mode); -int kern_chown(struct thread *td, char *path, enum uio_seg pathseg, int uid, - int gid); int kern_clock_getcpuclockid2(struct thread *td, id_t id, int which, clockid_t *clk_id); int kern_clock_getres(struct thread *td, clockid_t clock_id, @@ -87,9 +82,8 @@ int kern_clock_gettime(struct thread *td, clockid_t clock_id, int kern_clock_settime(struct thread *td, clockid_t clock_id, struct timespec *ats); int kern_close(struct thread *td, int fd); -int kern_connect(struct thread *td, int fd, struct sockaddr *sa); -int kern_eaccess(struct thread *td, char *path, enum uio_seg pathseg, - int flags); +int kern_connectat(struct thread *td, int dirfd, int fd, + struct sockaddr *sa); int kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p); int kern_fchmodat(struct thread *td, int fd, char *path, @@ -127,26 +121,14 @@ int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, int kern_kldload(struct thread *td, const char *file, int *fileid); int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat); int kern_kldunload(struct thread *td, int fileid, int flags); -int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, - int uid, int gid); -int kern_link(struct thread *td, char *path, char *link, - enum uio_seg segflg); int kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2, enum uio_seg segflg, int follow); -int kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, - struct stat *sbp); int kern_lutimes(struct thread *td, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); -int kern_mkdir(struct thread *td, char *path, enum uio_seg segflg, - int mode); int kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg, int mode); -int kern_mkfifo(struct thread *td, char *path, enum uio_seg pathseg, - int mode); int kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode); -int kern_mknod(struct thread *td, char *path, enum uio_seg pathseg, - int mode, int dev); int kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int mode, int dev); int kern_msgctl(struct thread *, int, int, struct msqid_ds *); @@ -156,14 +138,14 @@ int kern_nanosleep(struct thread *td, struct timespec *rqt, struct timespec *rmt); int kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap, long *ploff); -int kern_open(struct thread *td, char *path, enum uio_seg pathseg, - int flags, int mode); int kern_openat(struct thread *td, int fd, char *path, enum uio_seg pathseg, int flags, int mode); int kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name, u_long flags); int kern_pipe(struct thread *td, int fildes[2]); int kern_pipe2(struct thread *td, int fildes[2], int flags); +int kern_poll(struct thread *td, struct pollfd *fds, u_int nfds, + struct timespec *tsp, sigset_t *uset); int kern_posix_fadvise(struct thread *td, int fd, off_t offset, off_t len, int advice); int kern_posix_fallocate(struct thread *td, int fd, off_t offset, @@ -176,18 +158,13 @@ int kern_pselect(struct thread *td, int nd, fd_set *in, fd_set *ou, int kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data); int kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset); -int kern_readlink(struct thread *td, char *path, enum uio_seg pathseg, - char *buf, enum uio_seg bufseg, size_t count); int kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, char *buf, enum uio_seg bufseg, size_t count); int kern_readv(struct thread *td, int fd, struct uio *auio); int kern_recvit(struct thread *td, int s, struct msghdr *mp, enum uio_seg fromseg, struct mbuf **controlp); -int kern_rename(struct thread *td, char *from, char *to, - enum uio_seg pathseg); int kern_renameat(struct thread *td, int oldfd, char *old, int newfd, char *new, enum uio_seg pathseg); -int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg); int kern_rmdirat(struct thread *td, int fd, char *path, enum uio_seg pathseg); int kern_sched_rr_get_interval(struct thread *td, pid_t pid, @@ -220,17 +197,11 @@ int kern_sigprocmask(struct thread *td, int how, int kern_sigsuspend(struct thread *td, sigset_t mask); int kern_sigtimedwait(struct thread *td, sigset_t waitset, struct ksiginfo *ksi, struct timespec *timeout); -int kern_stat(struct thread *td, char *path, enum uio_seg pathseg, - struct stat *sbp); int kern_statat(struct thread *td, int flag, int fd, char *path, - enum uio_seg pathseg, struct stat *sbp); -int kern_statat_vnhook(struct thread *td, int flag, int fd, char *path, enum uio_seg pathseg, struct stat *sbp, void (*hook)(struct vnode *vp, struct stat *sbp)); int kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, struct statfs *buf); -int kern_symlink(struct thread *td, char *path, char *link, - enum uio_seg segflg); int kern_symlinkat(struct thread *td, char *path1, int fd, char *path2, enum uio_seg segflg); int kern_ktimer_create(struct thread *td, clockid_t clock_id, @@ -245,11 +216,8 @@ int kern_thr_new(struct thread *td, struct thr_param *param); int kern_thr_suspend(struct thread *td, struct timespec *tsp); int kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length); -int kern_unlink(struct thread *td, char *path, enum uio_seg pathseg); int kern_unlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, ino_t oldinum); -int kern_utimes(struct thread *td, char *path, enum uio_seg pathseg, - struct timeval *tptr, enum uio_seg tptrseg); int kern_utimesat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct timeval *tptr, enum uio_seg tptrseg); int kern_wait(struct thread *td, pid_t pid, int *status, int options, diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index 3d203aded0b..0c8581668de 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel + * created from FreeBSD: head/sys/kern/syscalls.master 274462 2014-11-13 05:26:14Z dchagin */ #ifndef _SYS_SYSPROTO_H_ @@ -1813,6 +1813,12 @@ struct procctl_args { char com_l_[PADL_(int)]; int com; char com_r_[PADR_(int)]; char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)]; }; +struct ppoll_args { + char fds_l_[PADL_(struct pollfd *)]; struct pollfd * fds; char fds_r_[PADR_(struct pollfd *)]; + char nfds_l_[PADL_(u_int)]; u_int nfds; char nfds_r_[PADR_(u_int)]; + char ts_l_[PADL_(const struct timespec *)]; const struct timespec * ts; char ts_r_[PADR_(const struct timespec *)]; + char set_l_[PADL_(const sigset_t *)]; const sigset_t * set; char set_r_[PADR_(const sigset_t *)]; +}; int nosys(struct thread *, struct nosys_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *); int sys_fork(struct thread *, struct fork_args *); @@ -2204,6 +2210,7 @@ int sys_accept4(struct thread *, struct accept4_args *); int sys_pipe2(struct thread *, struct pipe2_args *); int sys_aio_mlock(struct thread *, struct aio_mlock_args *); int sys_procctl(struct thread *, struct procctl_args *); +int sys_ppoll(struct thread *, struct ppoll_args *); #ifdef COMPAT_43 @@ -2909,6 +2916,7 @@ int freebsd7_shmctl(struct thread *, struct freebsd7_shmctl_args *); #define SYS_AUE_pipe2 AUE_PIPE #define SYS_AUE_aio_mlock AUE_NULL #define SYS_AUE_procctl AUE_NULL +#define SYS_AUE_ppoll AUE_POLL #undef PAD_ #undef PADL_ diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 87b39f18569..b2877c11b5f 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -304,9 +304,23 @@ vm_page_startup(vm_offset_t vaddr) phys_avail[i + 1] = trunc_page(phys_avail[i + 1]); } +#ifdef XEN + /* + * There is no obvious reason why i386 PV Xen needs vm_page structs + * created for these pseudo-physical addresses. XXX + */ + vm_phys_add_seg(0, phys_avail[0]); +#endif + low_water = phys_avail[0]; high_water = phys_avail[1]; + for (i = 0; i < vm_phys_nsegs; i++) { + if (vm_phys_segs[i].start < low_water) + low_water = vm_phys_segs[i].start; + if (vm_phys_segs[i].end > high_water) + high_water = vm_phys_segs[i].end; + } for (i = 0; phys_avail[i + 1]; i += 2) { vm_paddr_t size = phys_avail[i + 1] - phys_avail[i]; @@ -320,10 +334,6 @@ vm_page_startup(vm_offset_t vaddr) high_water = phys_avail[i + 1]; } -#ifdef XEN - low_water = 0; -#endif - end = phys_avail[biggestone+1]; /* @@ -391,6 +401,10 @@ vm_page_startup(vm_offset_t vaddr) first_page = low_water / PAGE_SIZE; #ifdef VM_PHYSSEG_SPARSE page_range = 0; + for (i = 0; i < vm_phys_nsegs; i++) { + page_range += atop(vm_phys_segs[i].end - + vm_phys_segs[i].start); + } for (i = 0; phys_avail[i + 1] != 0; i += 2) page_range += atop(phys_avail[i + 1] - phys_avail[i]); #elif defined(VM_PHYSSEG_DENSE) @@ -432,6 +446,13 @@ vm_page_startup(vm_offset_t vaddr) #endif phys_avail[biggestone + 1] = new_end; + /* + * Add physical memory segments corresponding to the available + * physical pages. + */ + for (i = 0; phys_avail[i + 1] != 0; i += 2) + vm_phys_add_seg(phys_avail[i], phys_avail[i + 1]); + /* * Clear all of the page structures */ diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h index e3d292d745a..a2342f8f14d 100644 --- a/sys/vm/vm_pager.h +++ b/sys/vm/vm_pager.h @@ -56,13 +56,13 @@ typedef boolean_t pgo_haspage_t(vm_object_t, vm_pindex_t, int *, int *); typedef void pgo_pageunswapped_t(vm_page_t); struct pagerops { - pgo_init_t *pgo_init; /* Initialize pager. */ - pgo_alloc_t *pgo_alloc; /* Allocate pager. */ - pgo_dealloc_t *pgo_dealloc; /* Disassociate. */ - pgo_getpages_t *pgo_getpages; /* Get (read) page. */ - pgo_putpages_t *pgo_putpages; /* Put (write) page. */ - pgo_haspage_t *pgo_haspage; /* Does pager have page? */ - pgo_pageunswapped_t *pgo_pageunswapped; + pgo_init_t *pgo_init; /* Initialize pager. */ + pgo_alloc_t *pgo_alloc; /* Allocate pager. */ + pgo_dealloc_t *pgo_dealloc; /* Disassociate. */ + pgo_getpages_t *pgo_getpages; /* Get (read) page. */ + pgo_putpages_t *pgo_putpages; /* Put (write) page. */ + pgo_haspage_t *pgo_haspage; /* Query page. */ + pgo_pageunswapped_t *pgo_pageunswapped; }; extern struct pagerops defaultpagerops; diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index be3d5be7807..95369a8dcb5 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -301,29 +301,19 @@ static void _vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end, int flind, int domain) { struct vm_phys_seg *seg; -#ifdef VM_PHYSSEG_SPARSE - long pages; - int segind; - pages = 0; - for (segind = 0; segind < vm_phys_nsegs; segind++) { - seg = &vm_phys_segs[segind]; - pages += atop(seg->end - seg->start); - } -#endif KASSERT(vm_phys_nsegs < VM_PHYSSEG_MAX, ("vm_phys_create_seg: increase VM_PHYSSEG_MAX")); KASSERT(domain < vm_ndomains, ("vm_phys_create_seg: invalid domain provided")); seg = &vm_phys_segs[vm_phys_nsegs++]; + while (seg > vm_phys_segs && (seg - 1)->start >= end) { + *seg = *(seg - 1); + seg--; + } seg->start = start; seg->end = end; seg->domain = domain; -#ifdef VM_PHYSSEG_SPARSE - seg->first_page = &vm_page_array[pages]; -#else - seg->first_page = PHYS_TO_VM_PAGE(start); -#endif seg->free_queues = &vm_phys_free_queues[domain][flind]; } @@ -356,6 +346,45 @@ vm_phys_create_seg(vm_paddr_t start, vm_paddr_t end, int flind) } } +/* + * Add a physical memory segment. + */ +void +vm_phys_add_seg(vm_paddr_t start, vm_paddr_t end) +{ + + KASSERT((start & PAGE_MASK) == 0, + ("vm_phys_define_seg: start is not page aligned")); + KASSERT((end & PAGE_MASK) == 0, + ("vm_phys_define_seg: end is not page aligned")); +#ifdef VM_FREELIST_ISADMA + if (start < 16777216) { + if (end > 16777216) { + vm_phys_create_seg(start, 16777216, + VM_FREELIST_ISADMA); + vm_phys_create_seg(16777216, end, VM_FREELIST_DEFAULT); + } else + vm_phys_create_seg(start, end, VM_FREELIST_ISADMA); + if (VM_FREELIST_ISADMA >= vm_nfreelists) + vm_nfreelists = VM_FREELIST_ISADMA + 1; + } else +#endif +#ifdef VM_FREELIST_HIGHMEM + if (end > VM_HIGHMEM_ADDRESS) { + if (start < VM_HIGHMEM_ADDRESS) { + vm_phys_create_seg(start, VM_HIGHMEM_ADDRESS, + VM_FREELIST_DEFAULT); + vm_phys_create_seg(VM_HIGHMEM_ADDRESS, end, + VM_FREELIST_HIGHMEM); + } else + vm_phys_create_seg(start, end, VM_FREELIST_HIGHMEM); + if (VM_FREELIST_HIGHMEM >= vm_nfreelists) + vm_nfreelists = VM_FREELIST_HIGHMEM + 1; + } else +#endif + vm_phys_create_seg(start, end, VM_FREELIST_DEFAULT); +} + /* * Initialize the physical memory allocator. */ @@ -363,41 +392,23 @@ void vm_phys_init(void) { struct vm_freelist *fl; - int dom, flind, i, oind, pind; + struct vm_phys_seg *seg; +#ifdef VM_PHYSSEG_SPARSE + long pages; +#endif + int dom, flind, oind, pind, segind; - for (i = 0; phys_avail[i + 1] != 0; i += 2) { -#ifdef VM_FREELIST_ISADMA - if (phys_avail[i] < 16777216) { - if (phys_avail[i + 1] > 16777216) { - vm_phys_create_seg(phys_avail[i], 16777216, - VM_FREELIST_ISADMA); - vm_phys_create_seg(16777216, phys_avail[i + 1], - VM_FREELIST_DEFAULT); - } else { - vm_phys_create_seg(phys_avail[i], - phys_avail[i + 1], VM_FREELIST_ISADMA); - } - if (VM_FREELIST_ISADMA >= vm_nfreelists) - vm_nfreelists = VM_FREELIST_ISADMA + 1; - } else +#ifdef VM_PHYSSEG_SPARSE + pages = 0; #endif -#ifdef VM_FREELIST_HIGHMEM - if (phys_avail[i + 1] > VM_HIGHMEM_ADDRESS) { - if (phys_avail[i] < VM_HIGHMEM_ADDRESS) { - vm_phys_create_seg(phys_avail[i], - VM_HIGHMEM_ADDRESS, VM_FREELIST_DEFAULT); - vm_phys_create_seg(VM_HIGHMEM_ADDRESS, - phys_avail[i + 1], VM_FREELIST_HIGHMEM); - } else { - vm_phys_create_seg(phys_avail[i], - phys_avail[i + 1], VM_FREELIST_HIGHMEM); - } - if (VM_FREELIST_HIGHMEM >= vm_nfreelists) - vm_nfreelists = VM_FREELIST_HIGHMEM + 1; - } else + for (segind = 0; segind < vm_phys_nsegs; segind++) { + seg = &vm_phys_segs[segind]; +#ifdef VM_PHYSSEG_SPARSE + seg->first_page = &vm_page_array[pages]; + pages += atop(seg->end - seg->start); +#else + seg->first_page = PHYS_TO_VM_PAGE(seg->start); #endif - vm_phys_create_seg(phys_avail[i], phys_avail[i + 1], - VM_FREELIST_DEFAULT); } for (dom = 0; dom < vm_ndomains; dom++) { for (flind = 0; flind < vm_nfreelists; flind++) { diff --git a/sys/vm/vm_phys.h b/sys/vm/vm_phys.h index 6d94e07fafa..74440468cd6 100644 --- a/sys/vm/vm_phys.h +++ b/sys/vm/vm_phys.h @@ -69,6 +69,7 @@ extern int vm_phys_nsegs; * The following functions are only to be used by the virtual memory system. */ void vm_phys_add_page(vm_paddr_t pa); +void vm_phys_add_seg(vm_paddr_t start, vm_paddr_t end); vm_page_t vm_phys_alloc_contig(u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment, vm_paddr_t boundary); vm_page_t vm_phys_alloc_freelist_pages(int flind, int pool, int order); diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 050f1b0a819..2aeef7e585c 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -714,7 +714,6 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, int runpg; int runend; struct buf *bp; - struct mount *mp; int count; int error; @@ -727,17 +726,12 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, return VM_PAGER_BAD; bsize = vp->v_mount->mnt_stat.f_iosize; - - /* get the UNDERLYING device for the file with VOP_BMAP() */ - - /* - * originally, we did not check for an error return value -- assuming - * an fs always has a bmap entry point -- that assumption is wrong!!! - */ foff = IDX_TO_OFF(m[reqpage]->pindex); /* - * if we can't bmap, use old VOP code + * Get the underlying device blocks for the file with VOP_BMAP(). + * If the file system doesn't support VOP_BMAP, use old way of + * getting pages via VOP_READ. */ error = VOP_BMAP(vp, foff / bsize, &bo, &reqblock, NULL, NULL); if (error == EOPNOTSUPP) { @@ -911,8 +905,7 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, * and map the pages to be read into the kva, if the filesystem * requires mapped buffers. */ - mp = vp->v_mount; - if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMAPPED_BUFS) != 0 && + if ((vp->v_mount->mnt_kern_flag & MNTK_UNMAPPED_BUFS) != 0 && unmapped_buf_allowed) { bp->b_data = unmapped_buf; bp->b_kvabase = unmapped_buf; @@ -960,7 +953,7 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, } if ((bp->b_flags & B_UNMAPPED) == 0) pmap_qremove(kva, count); - if (mp != NULL && (mp->mnt_kern_flag & MNTK_UNMAPPED_BUFS) != 0) { + if ((vp->v_mount->mnt_kern_flag & MNTK_UNMAPPED_BUFS) != 0) { bp->b_data = (caddr_t)kva; bp->b_kvabase = (caddr_t)kva; bp->b_flags &= ~B_UNMAPPED; @@ -988,11 +981,9 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, */ mt->valid = VM_PAGE_BITS_ALL; KASSERT(mt->dirty == 0, - ("vnode_pager_generic_getpages: page %p is dirty", - mt)); + ("%s: page %p is dirty", __func__, mt)); KASSERT(!pmap_page_is_mapped(mt), - ("vnode_pager_generic_getpages: page %p is mapped", - mt)); + ("%s: page %p is mapped", __func__, mt)); } else { /* * Read did not fill up entire page. @@ -1005,8 +996,7 @@ vnode_pager_generic_getpages(struct vnode *vp, vm_page_t *m, int bytecount, object->un_pager.vnp.vnp_size - tfoff); KASSERT((mt->dirty & vm_page_bits(0, object->un_pager.vnp.vnp_size - tfoff)) == 0, - ("vnode_pager_generic_getpages: page %p is dirty", - mt)); + ("%s: page %p is dirty", __func__, mt)); } if (i != reqpage) diff --git a/sys/xen/gnttab.c b/sys/xen/gnttab.c index ca6fa3b8863..9ab3145b4fe 100644 --- a/sys/xen/gnttab.c +++ b/sys/xen/gnttab.c @@ -13,7 +13,6 @@ #include __FBSDID("$FreeBSD$"); -#include "opt_global.h" #include "opt_pmap.h" #include diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index d0b76ad77cb..d77cef26790 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1954,7 +1954,6 @@ OLD_FILES+=usr/share/man/man3/iconvlist.3.gz .if ${MK_INET6} == no OLD_FILES+=sbin/ping6 OLD_FILES+=sbin/rtsol -OLD_FILES+=usr/sbin/faithd OLD_FILES+=usr/sbin/ip6addrctl OLD_FILES+=usr/sbin/mld6query OLD_FILES+=usr/sbin/ndp diff --git a/tools/build/options/WITHOUT_INCLUDES b/tools/build/options/WITHOUT_INCLUDES new file mode 100644 index 00000000000..8ccb2078d64 --- /dev/null +++ b/tools/build/options/WITHOUT_INCLUDES @@ -0,0 +1,8 @@ +.\" $FreeBSD$ +Set to not install header files. +This option used to be spelled +.Va NO_INCS . +.Bf -symbolic +The option does not work for build targets. +.Ef + diff --git a/tools/build/options/WITHOUT_LIB32 b/tools/build/options/WITHOUT_LIB32 index 4786a153605..93798ebef81 100644 --- a/tools/build/options/WITHOUT_LIB32 +++ b/tools/build/options/WITHOUT_LIB32 @@ -1,4 +1,4 @@ .\" $FreeBSD$ -On amd64, set to not build 32-bit library set and a +On 64-bit platforms, set to not build 32-bit library set and a .Nm ld-elf32.so.1 runtime linker. diff --git a/tools/build/options/WITHOUT_TESTS_SUPPORT b/tools/build/options/WITHOUT_TESTS_SUPPORT new file mode 100644 index 00000000000..805e99b67f1 --- /dev/null +++ b/tools/build/options/WITHOUT_TESTS_SUPPORT @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Set to disables the build of all test-related dependencies, including ATF. diff --git a/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES b/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES new file mode 100644 index 00000000000..2ecbdb72c00 --- /dev/null +++ b/tools/build/options/WITHOUT_USB_GADGET_EXAMPLES @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Set to build USB gadget kernel modules. diff --git a/tools/regression/lib/libc/gen/Makefile b/tools/regression/lib/libc/gen/Makefile index 4cba5de551d..f3a40e351d9 100644 --- a/tools/regression/lib/libc/gen/Makefile +++ b/tools/regression/lib/libc/gen/Makefile @@ -1,7 +1,7 @@ # $FreeBSD$ -TESTS= test-arc4random test-fmtcheck test-fmtmsg test-fnmatch \ - test-fpclassify test-ftw test-popen test-posix_spawn test-wordexp +TESTS= test-fmtcheck test-fmtmsg test-fnmatch \ + test-ftw test-popen test-posix_spawn test-wordexp .PHONY: tests tests: ${TESTS} diff --git a/tools/regression/lib/libc/gen/test-fpclassify.c b/tools/regression/lib/libc/gen/test-fpclassify.c deleted file mode 100644 index 799c134efb7..00000000000 --- a/tools/regression/lib/libc/gen/test-fpclassify.c +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2003 Mike Barcroft - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include -#include - -int -main(void) -{ - - assert(fpclassify((float)0) == FP_ZERO); - assert(fpclassify((float)-0.0) == FP_ZERO); - assert(fpclassify((float)1) == FP_NORMAL); - assert(fpclassify((float)1000) == FP_NORMAL); -#ifndef __alpha__ - assert(fpclassify(0x1.2p-150f) == FP_SUBNORMAL); -#endif - assert(fpclassify(HUGE_VALF) == FP_INFINITE); - assert(fpclassify((float)HUGE_VAL) == FP_INFINITE); - assert(fpclassify((float)HUGE_VALL) == FP_INFINITE); - assert(fpclassify(NAN) == FP_NAN); - - assert(fpclassify((double)0) == FP_ZERO); - assert(fpclassify((double)-0) == FP_ZERO); - assert(fpclassify((double)1) == FP_NORMAL); - assert(fpclassify((double)1000) == FP_NORMAL); -#ifndef __alpha__ - assert(fpclassify(0x1.2p-1075) == FP_SUBNORMAL); -#endif - assert(fpclassify(HUGE_VAL) == FP_INFINITE); - assert(fpclassify((double)HUGE_VALF) == FP_INFINITE); - assert(fpclassify((double)HUGE_VALL) == FP_INFINITE); - assert(fpclassify((double)NAN) == FP_NAN); - - assert(fpclassify((long double)0) == FP_ZERO); - assert(fpclassify((long double)-0.0) == FP_ZERO); - assert(fpclassify((long double)1) == FP_NORMAL); - assert(fpclassify((long double)1000) == FP_NORMAL); -#ifndef __alpha__ - assert(fpclassify(0x1.2p-16383L) == FP_SUBNORMAL); -#endif - assert(fpclassify(HUGE_VALL) == FP_INFINITE); - assert(fpclassify((long double)HUGE_VALF) == FP_INFINITE); - assert(fpclassify((long double)HUGE_VAL) == FP_INFINITE); - assert(fpclassify((long double)NAN) == FP_NAN); - - printf("PASS fpclassify()\n"); - exit(0); -} diff --git a/tools/regression/lib/libc/stdio/Makefile b/tools/regression/lib/libc/stdio/Makefile index d0f8c266b21..276adcb981e 100644 --- a/tools/regression/lib/libc/stdio/Makefile +++ b/tools/regression/lib/libc/stdio/Makefile @@ -1,7 +1,6 @@ # $FreeBSD$ TESTS= test-fdopen \ - test-fmemopen \ test-fopen \ test-freopen \ test-getdelim \ diff --git a/tools/regression/zfs/zpool/add/files.t b/tools/regression/zfs/zpool/add/files.t index 9f57f31d691..59014aafd91 100644 --- a/tools/regression/zfs/zpool/add/files.t +++ b/tools/regression/zfs/zpool/add/files.t @@ -4,8 +4,6 @@ dir=`dirname $0` . ${dir}/../../misc.sh -[ "${os}" = "FreeBSD" ] && die "panics FreeBSD; see bug # 191573" - echo "1..54" files_create 8 diff --git a/tools/tools/nanobsd/pcengines/ALIX_DSK b/tools/tools/nanobsd/pcengines/ALIX_DSK index 32b0b8ca136..1d750e5e2bd 100644 --- a/tools/tools/nanobsd/pcengines/ALIX_DSK +++ b/tools/tools/nanobsd/pcengines/ALIX_DSK @@ -71,7 +71,6 @@ device tun device pty device md device gif -device faith device firmware device bpf device uhci diff --git a/tools/tools/nanobsd/pcengines/ALIX_NFS b/tools/tools/nanobsd/pcengines/ALIX_NFS index fe911da613f..3c0f0da6237 100644 --- a/tools/tools/nanobsd/pcengines/ALIX_NFS +++ b/tools/tools/nanobsd/pcengines/ALIX_NFS @@ -69,7 +69,6 @@ device tun device pty device md device gif -device faith device firmware device bpf device uhci diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh index ebe2c67552c..1a32c60e027 100644 --- a/tools/tools/sysbuild/sysbuild.sh +++ b/tools/tools/sysbuild/sysbuild.sh @@ -160,7 +160,6 @@ fi set -e log_it() ( - set +x a="$*" set `cat /tmp/_sb_log` TX=`date +%s` @@ -175,7 +174,6 @@ log_it() ( ports_recurse() ( - set +x t=$1 shift if [ "x$t" = "x." ] ; then @@ -218,7 +216,6 @@ ports_recurse() ( ) ports_build() ( - set +x ports_recurse . $PORTS_WE_WANT @@ -229,17 +226,21 @@ ports_build() ( t=`echo $p | sed 's,/usr/ports/,,'` pn=`cd $p && make package-name` - if pkg info $pn > /dev/null 2>&1 ; then - log_it "Already installed: $t ($pn)" + if [ "x$p" == "x/usr/ports/ports-mgmt/pkg" -o \ + "x$p" == "x/freebsd/ports/ports-mgmt/pkg" ] ; then + log_it "Very Special: $t ($pn)" + + ( + cd $p + make clean ${PORTS_OPTS} + make all ${PORTS_OPTS} + make install ${PORTS_OPTS} + ) > _.$b 2>&1 < /dev/null continue fi - if [ "x$p" == "x/usr/ports/ports-mgmt/pkg" ] ; then - log_it "Very Special: $t ($pn)" - ( - cd $p - make clean all install ${PORTS_OPTS} - ) > _.$b 2>&1 < /dev/null + if pkg info $pn > /dev/null 2>&1 ; then + log_it "Already installed: $t ($pn)" continue fi @@ -380,7 +381,6 @@ done ####################################################################### if [ "x$1" = "xchroot_script" ] ; then - set +x set -e shift diff --git a/tools/tools/sysdoc/tunables.mdoc b/tools/tools/sysdoc/tunables.mdoc index 1c5569bee9a..7c8c9a345e2 100644 --- a/tools/tools/sysdoc/tunables.mdoc +++ b/tools/tools/sysdoc/tunables.mdoc @@ -1311,14 +1311,6 @@ net.inet.ip.intr_queue_drops --- net.inet.ip.intr_queue_maxlen ---- -net.inet.ip.keepfaith -bool - -This is used in conjunction with -.Xr faithd 8 -to control the FAITH IPv6/v4 translator daemon. - --- net.inet.ip.maxfragpackets @@ -1332,37 +1324,6 @@ bool Controls the sending of ICMP redirects in response to unforwardable IP packets. ---- -net.inet.ip.rtexpire -int - -Lifetime in seconds of protocol-cloned IP routes after the last -reference drops (default one hour). - ---- -net.inet.ip.rtmaxcache -int - -Trigger level of cached, unreferenced, protocol-cloned -routes which initiates dynamic adaptation. - ---- -net.inet.ip.rtminexpire -int - -See -.Xr inet 4 -for more information. - ---- -net.inet.ip.sendsourcequench -bool - -This -.Nm -enables or disables the transmission of -source quench packets. - --- net.inet.ip.sourceroute bool diff --git a/tools/tools/tinybsd/conf/default/TINYBSD b/tools/tools/tinybsd/conf/default/TINYBSD index ae7c9f6390b..aba05c5bcfc 100644 --- a/tools/tools/tinybsd/conf/default/TINYBSD +++ b/tools/tools/tinybsd/conf/default/TINYBSD @@ -148,7 +148,6 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/tools/tools/tinybsd/conf/vpn/TINYBSD b/tools/tools/tinybsd/conf/vpn/TINYBSD index f7159ad8a9b..7e6da0edf1e 100644 --- a/tools/tools/tinybsd/conf/vpn/TINYBSD +++ b/tools/tools/tinybsd/conf/vpn/TINYBSD @@ -138,7 +138,6 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/tools/tools/tinybsd/conf/wrap/TINYBSD b/tools/tools/tinybsd/conf/wrap/TINYBSD index aff67ea95ef..d04b0659c4e 100644 --- a/tools/tools/tinybsd/conf/wrap/TINYBSD +++ b/tools/tools/tinybsd/conf/wrap/TINYBSD @@ -110,7 +110,6 @@ device tun # Packet tunnel. device pty # Pseudo-ttys (telnet etc) device md # Memory "disks" device gif # IPv6 and IPv4 tunneling -device faith # IPv6-to-IPv4 relaying (translation) # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/usr.bin/iscsictl/iscsictl.c b/usr.bin/iscsictl/iscsictl.c index 27467bbe185..a27e32bd28f 100644 --- a/usr.bin/iscsictl/iscsictl.c +++ b/usr.bin/iscsictl/iscsictl.c @@ -758,14 +758,9 @@ main(int argc, char **argv) errx(1, "-n and -p and mutually exclusive"); if (target != NULL) errx(1, "-n and -t and mutually exclusive"); - } else if (portal != NULL) { - if (target != NULL) - errx(1, "-p and -t and mutually exclusive"); - } else if (target != NULL) { - if (portal != NULL) - errx(1, "-t and -p and mutually exclusive"); - } else + } else if (target == NULL && portal == NULL) { errx(1, "must specify either -a, -n, -t, or -p"); + } if (session_id != -1) errx(1, "-i cannot be used with -R"); diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1 index 7517a64cb21..ca497f32a25 100644 --- a/usr.bin/man/man.1 +++ b/usr.bin/man/man.1 @@ -61,23 +61,32 @@ restricts the search to the specific section of the manual. The sections of the manual are: .Bl -enum -offset indent -compact .It -.Fx General Commands Manual +.Fx +General Commands Manual .It -.Fx System Calls Manual +.Fx +System Calls Manual .It -.Fx Library Functions Manual +.Fx +Library Functions Manual .It -.Fx Kernel Interfaces Manual +.Fx +Kernel Interfaces Manual .It -.Fx File Formats Manual +.Fx +File Formats Manual .It -.Fx Games Manual +.Fx +Games Manual .It -.Fx Miscellaneous Information Manual +.Fx +Miscellaneous Information Manual .It -.Fx System Manager's Manual +.Fx +System Manager's Manual .It -.Fx Kernel Developer's Manual +.Fx +Kernel Developer's Manual .El .Pp Options that diff --git a/usr.bin/mkimg/image.c b/usr.bin/mkimg/image.c index 3e7c7d2945a..be1c2e9fcbb 100644 --- a/usr.bin/mkimg/image.c +++ b/usr.bin/mkimg/image.c @@ -405,16 +405,18 @@ image_copyin_mapped(lba_t blk, int fd, uint64_t *sizep) error = 0; while (!error && cur < end) { hole = lseek(fd, cur, SEEK_HOLE); + if (hole == -1) + hole = end; data = lseek(fd, cur, SEEK_DATA); + if (data == -1) + data = end; /* * Treat the entire file as data if sparse files * are not supported by the underlying file system. */ - if (hole == -1 && data == -1) { + if (hole == end && data == end) data = cur; - hole = end; - } if (cur == hole && data > hole) { hole = pos; diff --git a/usr.bin/mkimg/mkimg.1 b/usr.bin/mkimg/mkimg.1 index bfe05c01cc0..56cd605db48 100644 --- a/usr.bin/mkimg/mkimg.1 +++ b/usr.bin/mkimg/mkimg.1 @@ -220,9 +220,9 @@ utility supports assigning labels to the partitions specified. In the following example the file system partition is labeled as 'backup': .Dl % mkimg -s gpt -p freebsd-ufs/backup:=file-system.ufs -o gpt.img .Sh SEE ALSO -.Xr gpart 8 -.Xr makefs 8 -.Xr mdconfig 8 +.Xr gpart 8 , +.Xr makefs 8 , +.Xr mdconfig 8 , .Xr newfs 8 .Sh HISTORY The diff --git a/usr.bin/sort/Makefile b/usr.bin/sort/Makefile index c6eef856101..532e9307caa 100644 --- a/usr.bin/sort/Makefile +++ b/usr.bin/sort/Makefile @@ -13,10 +13,12 @@ CLEANFILES+= sort.1 .if ${MK_SORT_THREADS} != "no" CFLAGS+= -DSORT_THREADS -LDFLAGS+= -lpthread -lmd +LDADD= -lpthread -lmd +DPADD= ${LIBPTHREAD} ${LIBMD} MAN_SUB+= -e 's|%%THREADS%%||g' .else -LDFLAGS+= -lmd +LDADD= -lmd +DPADD= ${LIBMD} MAN_SUB+= -e 's|%%THREADS%%|\.\\"|g' .endif diff --git a/usr.bin/w/w.c b/usr.bin/w/w.c index 059f7ce5602..effd0e304ae 100644 --- a/usr.bin/w/w.c +++ b/usr.bin/w/w.c @@ -509,7 +509,7 @@ pr_header(time_t *nowp, int nusers) } /* Print number of users logged in to system */ - xo_emit(" {:users/%d} user%s", nusers, nusers == 1 ? "" : "s"); + xo_emit(" {:users/%d} {N:user%s}", nusers, nusers == 1 ? "" : "s"); /* * Print 1, 5, and 15 minute load averages. diff --git a/usr.bin/yacc/Makefile b/usr.bin/yacc/Makefile index 45e7929db00..c110f3f5902 100644 --- a/usr.bin/yacc/Makefile +++ b/usr.bin/yacc/Makefile @@ -10,9 +10,10 @@ PROG= yacc SRCS= closure.c error.c graph.c lalr.c lr0.c main.c mkpar.c mstring.c output.c \ reader.c yaccpar.c symtab.c verbose.c warshall.c -CFLAGS+= -DMIXEDCASE_FILENAMES=1 \ - -DHAVE_FCNTL_H=1 \ - -DHAVE_MKSTEMP=1 +CFLAGS+= -DHAVE_FCNTL_H=1 \ + -DHAVE_MKSTEMP=1 \ + -DMAXTABLE=INT_MAX \ + -DMIXEDCASE_FILENAMES=1 YYPATCH!= cat ${BYACC_SRC}/VERSION CFLAGS+= -DYYPATCH=${YYPATCH} diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index b0cff950bf2..df9f8674793 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -160,7 +160,6 @@ SUBDIR+= gpioctl .endif .if ${MK_INET6} != "no" -SUBDIR+= faithd SUBDIR+= ip6addrctl SUBDIR+= mld6query SUBDIR+= ndp diff --git a/usr.sbin/autofs/auto_master.5 b/usr.sbin/autofs/auto_master.5 index 69d6afeac9d..f7f369d4d73 100644 --- a/usr.sbin/autofs/auto_master.5 +++ b/usr.sbin/autofs/auto_master.5 @@ -27,13 +27,17 @@ .\" .\" $FreeBSD$ .\" -.Dd August 23, 2014 +.Dd November 19, 2014 .Dt AUTO_MASTER 5 .Os .Sh NAME .Nm auto_master .Nd auto_master and map file format .Sh DESCRIPTION +The automounter configuration consists of the +.Nm +configuration file, which assigns filesystem paths to map names, +and maps, which contain actual mount information. The .Nm configuration file is used by the @@ -132,8 +136,12 @@ The special option .Li fstype is used to specify filesystem type. It is not passed to the mount program as an option. -Instead, it is passed as argument to +Instead, it is passed as an argument to .Cm "mount -t". +The default +.Li fstype +is +.Ql nfs . The special option .Li nobrowse is used to disable creation of top-level directories for special @@ -153,9 +161,11 @@ prefix it with colon. For example, .Li :/dev/cd0 . .Pp -This example, when used with the +This example, when put into +.Pa /etc/auto_example , +and with .Nm -example above, specifies that the NFS share +referring to the map as described above, specifies that the NFS share .Li 192.168.1.1:/share/example/x will be mounted on .Pa /example/x/ @@ -163,14 +173,21 @@ when any process attempts to access that mountpoint, with .Li intr and .Li nfsv4 -mount options: +mount options, described in +.Xr mount_nfs 8 : .Bd -literal -offset indent .Li x -intr,nfsv4 192.168.1.1:/share/example/x .Ed .Pp +Automatically mount an SMB share on access, as a guest user, +without prompting for a password: +.Bd -literal -offset indent +.Li share -fstype=smbfs,-N ://@server/share +.Ed +.Pp Automatically mount the CD drive on access: .Bd -literal -offset indent -.Li cd -intr,fstype=cd9660 :/dev/cd0 +.Li cd -fstype=cd9660 :/dev/cd0 .Ed .Sh SPECIAL MAPS Special maps have names beginning with @@ -224,7 +241,8 @@ and this in map file: .Bd -literal -offset indent .Li /example/x -intr,nfsv4 192.168.1.1:/share/example/x -.Li /example/cd -intr,fstype=cd9660 :/dev/cd0 +.Li /example/share -fstype=smbfs,-N ://@server/share +.Li /example/cd -fstype=cd9660 :/dev/cd0 .Ed .Sh DIRECTORY SERVICES Both diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 755fa3356b3..a537c489728 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -70,7 +70,8 @@ Required for guests. .It Fl b Enable a low-level console device supported by -.Fx kernels compiled with +.Fx +kernels compiled with .Cd "device bvmconsole" . This option will be deprecated in a future version. .It Fl c Ar numcpus diff --git a/usr.sbin/bhyve/block_if.c b/usr.sbin/bhyve/block_if.c index 4986386de0b..8687e9a39d3 100644 --- a/usr.sbin/bhyve/block_if.c +++ b/usr.sbin/bhyve/block_if.c @@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$"); #define BLOCKIF_SIG 0xb109b109 -#define BLOCKIF_MAXREQ 32 +#define BLOCKIF_MAXREQ 33 enum blockop { BOP_READ, @@ -600,7 +600,7 @@ blockif_queuesz(struct blockif_ctxt *bc) { assert(bc->bc_magic == BLOCKIF_SIG); - return (BLOCKIF_MAXREQ); + return (BLOCKIF_MAXREQ - 1); } int diff --git a/usr.sbin/bsdconfig/networking/share/device.subr b/usr.sbin/bsdconfig/networking/share/device.subr index 42010ab10bf..bb41be300a0 100644 --- a/usr.sbin/bsdconfig/networking/share/device.subr +++ b/usr.sbin/bsdconfig/networking/share/device.subr @@ -82,7 +82,7 @@ f_dialog_menu_netdev() f_struct "$dev" get name if || continue # Skip unsavory interfaces case "$if" in - lo[0-9]*|ppp[0-9]*|sl[0-9]*|faith[0-9]*) continue ;; + lo[0-9]*|ppp[0-9]*|sl[0-9]*) continue ;; esac iflist="$iflist $if" done diff --git a/usr.sbin/bsdconfig/timezone/timezone b/usr.sbin/bsdconfig/timezone/timezone index 0452230441b..66f2d789228 100755 --- a/usr.sbin/bsdconfig/timezone/timezone +++ b/usr.sbin/bsdconfig/timezone/timezone @@ -62,7 +62,7 @@ _PATH_WALL_CMOS_CLOCK="/etc/wall_cmos_clock" REALLYDOIT=1 REINSTALL= USEDIALOG=1 -SKIPUTC= +SKIPUTC= # See MAIN VERBOSE= TZ_OR_FAIL= CHROOTENV= @@ -119,6 +119,9 @@ dialog_menu_main() ############################################################ MAIN +# Skip initial question regarding UTC v. Wall-Clock time if run in VM +[ "$( sysctl -n kern.vm_guest 2> /dev/null )" = "none" ] || SKIPUTC=1 + # Incorporate rc-file if it exists [ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" diff --git a/usr.sbin/ctld/chap.c b/usr.sbin/ctld/chap.c index 635ab8cb024..0678a7770bc 100644 --- a/usr.sbin/ctld/chap.c +++ b/usr.sbin/ctld/chap.c @@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -105,6 +107,29 @@ chap_hex2int(const char hex) } } +static int +chap_b642bin(const char *b64, void **binp, size_t *bin_lenp) +{ + char *bin; + int b64_len, bin_len; + + b64_len = strlen(b64); + bin_len = (b64_len + 3) / 4 * 3; + bin = calloc(bin_len, 1); + if (bin == NULL) + log_err(1, "calloc"); + + bin_len = b64_pton(b64, bin, bin_len); + if (bin_len < 0) { + log_warnx("malformed base64 variable"); + free(bin); + return (-1); + } + *binp = bin; + *bin_lenp = bin_len; + return (0); +} + /* * XXX: Review this _carefully_. */ @@ -116,8 +141,12 @@ chap_hex2bin(const char *hex, void **binp, size_t *bin_lenp) char *bin; size_t bin_off, bin_len; + if (strncasecmp(hex, "0b", strlen("0b")) == 0) + return (chap_b642bin(hex + 2, binp, bin_lenp)); + if (strncasecmp(hex, "0x", strlen("0x")) != 0) { - log_warnx("malformed variable, should start with \"0x\""); + log_warnx("malformed variable, should start with \"0x\"" + " or \"0b\""); return (-1); } @@ -160,6 +189,25 @@ chap_hex2bin(const char *hex, void **binp, size_t *bin_lenp) return (0); } +#ifdef USE_BASE64 +static char * +chap_bin2hex(const char *bin, size_t bin_len) +{ + unsigned char *b64, *tmp; + size_t b64_len; + + b64_len = (bin_len + 2) / 3 * 4 + 3; /* +2 for "0b", +1 for '\0'. */ + b64 = malloc(b64_len); + if (b64 == NULL) + log_err(1, "malloc"); + + tmp = b64; + tmp += sprintf(tmp, "0b"); + b64_ntop(bin, bin_len, tmp, b64_len - 2); + + return (b64); +} +#else static char * chap_bin2hex(const char *bin, size_t bin_len) { @@ -181,6 +229,7 @@ chap_bin2hex(const char *bin, size_t bin_len) return (hex); } +#endif /* !USE_BASE64 */ struct chap * chap_new(void) diff --git a/usr.sbin/ctld/ctl.conf.5 b/usr.sbin/ctld/ctl.conf.5 index 6a6184bcc41..8e427b1c98e 100644 --- a/usr.sbin/ctld/ctl.conf.5 +++ b/usr.sbin/ctld/ctl.conf.5 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 8, 2014 +.Dd November 9, 2014 .Dt CTL.CONF 5 .Os .Sh NAME @@ -218,6 +218,17 @@ An IPv4 or IPv6 address and port to listen on for incoming connections. .\".It Ic listen-iser Ar address .\"An IPv4 or IPv6 address and port to listen on for incoming connections .\"using iSER (iSCSI over RDMA) protocol. +.It Ic redirect Aq Ar address +IPv4 or IPv6 address to redirect initiators to. +When configured, all initiators attempting to connect to portal +belonging to this +.Sy portal-group +will get redirected using "Target moved temporarily" login response. +Redirection happens before authentication and any +.Sy initiator-name +or +.Sy initiator-portal +checks are skipped. .El .Ss target Context .Bl -tag -width indent @@ -296,6 +307,11 @@ The default portal group is .Qq Ar default , which makes the target available on TCP port 3260 on all configured IPv4 and IPv6 addresses. +.It Ic redirect Aq Ar address +IPv4 or IPv6 address to redirect initiators to. +When configured, all initiators attempting to connect to this target +will get redirected using "Target moved temporarily" login response. +Redirection happens after successful authentication. .It Ic lun Ar number Create a .Sy lun diff --git a/usr.sbin/ctld/ctld.8 b/usr.sbin/ctld/ctld.8 index 9cff3a82b42..aa9a414e138 100644 --- a/usr.sbin/ctld/ctld.8 +++ b/usr.sbin/ctld/ctld.8 @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 20, 2014 +.Dd November 9, 2014 .Dt CTLD 8 .Os .Sh NAME @@ -105,6 +105,11 @@ utility exits 0 on success, and >0 if an error occurs. .Xr ctl 4 , .Xr ctl.conf 5 , .Xr ctladm 8 +.Sh HISTORY +The +.Nm +command appeared in +.Fx 10.0 . .Sh AUTHORS The .Nm diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index a480b2ec043..bbf8e7d5064 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -622,6 +622,7 @@ portal_group_delete(struct portal_group *pg) TAILQ_FOREACH_SAFE(portal, &pg->pg_portals, p_next, tmp) portal_delete(portal); free(pg->pg_name); + free(pg->pg_redirection); free(pg); } @@ -1000,6 +1001,22 @@ portal_group_set_filter(struct portal_group *pg, const char *str) return (0); } +int +portal_group_set_redirection(struct portal_group *pg, const char *addr) +{ + + if (pg->pg_redirection != NULL) { + log_warnx("cannot set redirection to \"%s\" for " + "portal-group \"%s\"; already defined", + addr, pg->pg_name); + return (1); + } + + pg->pg_redirection = checked_strdup(addr); + + return (0); +} + static bool valid_hex(const char ch) { @@ -1144,6 +1161,7 @@ target_delete(struct target *targ) TAILQ_FOREACH_SAFE(lun, &targ->t_luns, l_next, tmp) lun_delete(lun); free(targ->t_name); + free(targ->t_redirection); free(targ); } @@ -1160,6 +1178,22 @@ target_find(struct conf *conf, const char *name) return (NULL); } +int +target_set_redirection(struct target *target, const char *addr) +{ + + if (target->t_redirection != NULL) { + log_warnx("cannot set redirection to \"%s\" for " + "target \"%s\"; already defined", + addr, target->t_name); + return (1); + } + + target->t_redirection = checked_strdup(addr); + + return (0); +} + struct lun * lun_new(struct target *targ, int lun_id) { @@ -1486,10 +1520,15 @@ conf_verify(struct conf *conf) return (error); found = true; } - if (!found) { + if (!found && targ->t_redirection == NULL) { log_warnx("no LUNs defined for target \"%s\"", targ->t_name); } + if (found && targ->t_redirection != NULL) { + log_debugx("target \"%s\" contains luns, " + " but configured for redirection", + targ->t_name); + } } TAILQ_FOREACH(pg, &conf->conf_portal_groups, pg_next) { assert(pg->pg_name != NULL); @@ -1506,13 +1545,22 @@ conf_verify(struct conf *conf) if (targ->t_portal_group == pg) break; } - if (targ == NULL) { + if (pg->pg_redirection != NULL) { + if (targ != NULL) { + log_debugx("portal-group \"%s\" assigned " + "to target \"%s\", but configured " + "for redirection", + pg->pg_name, targ->t_name); + } + pg->pg_unassigned = false; + } else if (targ != NULL) { + pg->pg_unassigned = false; + } else { if (strcmp(pg->pg_name, "default") != 0) log_warnx("portal-group \"%s\" not assigned " "to any target", pg->pg_name); pg->pg_unassigned = true; - } else - pg->pg_unassigned = false; + } } TAILQ_FOREACH(ag, &conf->conf_auth_groups, ag_next) { if (ag->ag_name == NULL) diff --git a/usr.sbin/ctld/ctld.h b/usr.sbin/ctld/ctld.h index e7b364240d1..600bd30c4f2 100644 --- a/usr.sbin/ctld/ctld.h +++ b/usr.sbin/ctld/ctld.h @@ -117,6 +117,7 @@ struct portal_group { int pg_discovery_filter; bool pg_unassigned; TAILQ_HEAD(, portal) pg_portals; + char *pg_redirection; uint16_t pg_tag; }; @@ -151,6 +152,7 @@ struct target { struct portal_group *t_portal_group; char *t_name; char *t_alias; + char *t_redirection; }; struct isns { @@ -301,6 +303,8 @@ int portal_group_add_listen(struct portal_group *pg, const char *listen, bool iser); int portal_group_set_filter(struct portal_group *pg, const char *filter); +int portal_group_set_redirection(struct portal_group *pg, + const char *addr); int isns_new(struct conf *conf, const char *addr); void isns_delete(struct isns *is); @@ -312,6 +316,8 @@ struct target *target_new(struct conf *conf, const char *name); void target_delete(struct target *target); struct target *target_find(struct conf *conf, const char *name); +int target_set_redirection(struct target *target, + const char *addr); struct lun *lun_new(struct target *target, int lun_id); void lun_delete(struct lun *lun); diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c index c59cea01b5f..fc41f5178d3 100644 --- a/usr.sbin/ctld/login.c +++ b/usr.sbin/ctld/login.c @@ -612,6 +612,65 @@ login_negotiate_key(struct pdu *request, const char *name, } } +static void +login_redirect(struct pdu *request, const char *target_address) +{ + struct pdu *response; + struct iscsi_bhs_login_response *bhslr2; + struct keys *response_keys; + + response = login_new_response(request); + login_set_csg(response, login_csg(request)); + bhslr2 = (struct iscsi_bhs_login_response *)response->pdu_bhs; + bhslr2->bhslr_status_class = 0x01; + bhslr2->bhslr_status_detail = 0x01; + + response_keys = keys_new(); + keys_add(response_keys, "TargetAddress", target_address); + + keys_save(response_keys, response); + pdu_send(response); + pdu_delete(response); + keys_delete(response_keys); +} + +static bool +login_portal_redirect(struct connection *conn, struct pdu *request) +{ + const struct portal_group *pg; + + pg = conn->conn_portal->p_portal_group; + if (pg->pg_redirection == NULL) + return (false); + + log_debugx("portal-group \"%s\" configured to redirect to %s", + pg->pg_name, pg->pg_redirection); + login_redirect(request, pg->pg_redirection); + + return (true); +} + +static bool +login_target_redirect(struct connection *conn, struct pdu *request) +{ + const char *target_address; + + assert(conn->conn_portal->p_portal_group->pg_redirection == NULL); + + if (conn->conn_target == NULL) + return (false); + + target_address = conn->conn_target->t_redirection; + if (target_address == NULL) + return (false); + + log_debugx("target \"%s\" configured to redirect to %s", + conn->conn_target->t_name, target_address); + login_redirect(request, target_address); + + return (true); +} + static void login_negotiate(struct connection *conn, struct pdu *request) { @@ -619,7 +678,7 @@ login_negotiate(struct connection *conn, struct pdu *request) struct iscsi_bhs_login_response *bhslr2; struct keys *request_keys, *response_keys; int i; - bool skipped_security; + bool redirected, skipped_security; if (request == NULL) { log_debugx("beginning operational parameter negotiation; " @@ -629,6 +688,18 @@ login_negotiate(struct connection *conn, struct pdu *request) } else skipped_security = true; + /* + * RFC 3720, 10.13.5. Status-Class and Status-Detail, says + * the redirection SHOULD be accepted by the initiator before + * authentication, but MUST be be accepted afterwards; that's + * why we're doing it here and not earlier. + */ + redirected = login_target_redirect(conn, request); + if (redirected) { + log_debugx("initiator redirected; exiting"); + exit(0); + } + request_keys = keys_new(); keys_load(request_keys, request); @@ -680,6 +751,7 @@ login(struct connection *conn) struct portal_group *pg; const char *initiator_name, *initiator_alias, *session_type, *target_name, *auth_method; + bool redirected; /* * Handle the initial Login Request - figure out required authentication @@ -722,6 +794,12 @@ login(struct connection *conn) */ setproctitle("%s (%s)", conn->conn_initiator_addr, conn->conn_initiator_name); + redirected = login_portal_redirect(conn, request); + if (redirected) { + log_debugx("initiator redirected; exiting"); + exit(0); + } + initiator_alias = keys_find(request_keys, "InitiatorAlias"); if (initiator_alias != NULL) conn->conn_initiator_alias = checked_strdup(initiator_alias); diff --git a/usr.sbin/ctld/parse.y b/usr.sbin/ctld/parse.y index c801ce69076..a6519dd7033 100644 --- a/usr.sbin/ctld/parse.y +++ b/usr.sbin/ctld/parse.y @@ -61,7 +61,8 @@ extern void yyrestart(FILE *); %token CLOSING_BRACKET DEBUG DEVICE_ID DISCOVERY_AUTH_GROUP DISCOVERY_FILTER %token INITIATOR_NAME INITIATOR_PORTAL ISNS_SERVER ISNS_PERIOD ISNS_TIMEOUT %token LISTEN LISTEN_ISER LUN MAXPROC OPENING_BRACKET OPTION -%token PATH PIDFILE PORTAL_GROUP SEMICOLON SERIAL SIZE STR TARGET TIMEOUT +%token PATH PIDFILE PORTAL_GROUP REDIRECT SEMICOLON SERIAL SIZE STR +%token TARGET TIMEOUT %union { @@ -338,6 +339,8 @@ portal_group_entry: portal_group_listen | portal_group_listen_iser + | + portal_group_redirect ; portal_group_discovery_auth_group: DISCOVERY_AUTH_GROUP STR @@ -393,6 +396,17 @@ portal_group_listen_iser: LISTEN_ISER STR } ; +portal_group_redirect: REDIRECT STR + { + int error; + + error = portal_group_set_redirection(portal_group, $2); + free($2); + if (error != 0) + return (1); + } + ; + target: TARGET target_name OPENING_BRACKET target_entries CLOSING_BRACKET { @@ -433,6 +447,8 @@ target_entry: | target_portal_group | + target_redirect + | target_lun ; @@ -635,6 +651,17 @@ target_portal_group: PORTAL_GROUP STR } ; +target_redirect: REDIRECT STR + { + int error; + + error = target_set_redirection(target, $2); + free($2); + if (error != 0) + return (1); + } + ; + target_lun: LUN lun_number OPENING_BRACKET lun_entries CLOSING_BRACKET { diff --git a/usr.sbin/ctld/token.l b/usr.sbin/ctld/token.l index 822d1ac7e33..d4bf823b8b0 100644 --- a/usr.sbin/ctld/token.l +++ b/usr.sbin/ctld/token.l @@ -72,6 +72,7 @@ isns-server { return ISNS_SERVER; } isns-period { return ISNS_PERIOD; } isns-timeout { return ISNS_TIMEOUT; } portal-group { return PORTAL_GROUP; } +redirect { return REDIRECT; } serial { return SERIAL; } size { return SIZE; } target { return TARGET; } diff --git a/usr.sbin/faithd/Makefile b/usr.sbin/faithd/Makefile deleted file mode 100644 index dec45b9645b..00000000000 --- a/usr.sbin/faithd/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 1996 WIDE Project. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modifications, are permitted provided that the above copyright notice -# and this paragraph are duplicated in all such forms and that any -# documentation, advertising materials, and other materials related to -# such distribution and use acknowledge that the software was developed -# by the WIDE Project, Japan. The name of the Project may not be used to -# endorse or promote products derived from this software without -# specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' -# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT -# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE. -# -# $FreeBSD$ - -PROG= faithd -MAN= faithd.8 -SRCS= faithd.c tcp.c ftp.c prefix.c - -CFLAGS+= -DHAVE_POLL_H - -WARNS?= 2 - -.include diff --git a/usr.sbin/faithd/README b/usr.sbin/faithd/README deleted file mode 100644 index 6628bf63dcb..00000000000 --- a/usr.sbin/faithd/README +++ /dev/null @@ -1,148 +0,0 @@ -Configuring FAITH IPv6-to-IPv4 TCP relay - -Kazu Yamamoto and Jun-ichiro itojun Hagino -$KAME: README,v 1.10 2003/01/06 21:40:33 sumikawa Exp $ -$FreeBSD$ - - -Introduction -============ - -FAITH is an IPv6-to-IPv4 TCP relay. It performs tcp relay just as some of -firewall-oriented gateway does, but between IPv6 and IPv4 with address -translation. -TCP connections has to be made from IPv6 node to IPv4 node. FAITH will -not relay connections for the opposite direction. -To perform relays, FAITH daemon needs to be executed on a router between -your local IPv6 site and outside IPv4 network. The daemon needs to be -invoked per each TCP services (TCP port number). - - IPv4 node "dest" = 123.4.5.6 - | - [[[[ outside IPv4 ocean ]]]] - | - node that runs FAITH-daemon (usually a router) - | - ==+=====+===+==== IPv6, or IPv4/v6 network in your site ^ - | | | connection - clients IPv6 node "src" | - -You will have to allocate an IPv6 address prefix to map IPv4 addresses into. -The following description uses 3ffe:0501:ffff:0000:: as example. -Please use a prefix which belongs to your site. -FAITH will make it possible to make an IPv6 TCP connection From IPv6 node -"src", toward IPv4 node "dest", by specifying FAITH-mapped address -3ffe:0501:ffff:0000::123.4.5.6 -(which is, 3ffe:0501:ffff:0000:0000:0000:7b04:0506). -The address mapping can be performed by hand:-), by special nameserver on -the network, or by special resolver on the source node. - - -Setup -===== - -The following example assumes: -- You have assigned 3ffe:0501:ffff:0000:: as FAITH adderss prefix. -- You are willing to provide IPv6-to IPv4 TCP relay for telnet. - -<> - -(1) If you have IPv6 TCP server for the "telnet" service, i.e. telnetd via - inet6d, disable that daemon. Comment out the line from "inet6d.conf" - and send the HUP signal to "inet6d". - -(2) Execute sysctl as root to enable FAITH support in the kernel. - - # sysctl net.inet6.ip6.keepfaith=1 - -(3) Route packets toward FAITH prefix into "faith0" interface. - - # ifconfig faith0 up - # route add -inet6 3ffe:0501:ffff:0000:: -prefixlen 64 ::1 - # route change -inet6 3ffe:0501:ffff:0000:: -prefixlen 64 -ifp faith0 - -(4) Execute "faithd" by root as follows: - - # faithd telnet /usr/libexec/telnetd telnetd - - 1st argument is a service name you are willing to provide TCP relay. - (it can be specified either by number "23" or by string "telnet") - 2nd argument is a path name for local IPv6 TCP server. If there is a - connection toward the router itself, this program will be invoked. - 3rd and the following arguments are arguments for the local IPv6 TCP - server. (3rd argument is typically the program name without its path.) - - More examples: - - # faithd ftpd /usr/libexec/ftpd ftpd -l - # faithd sshd - -If inetd(8) on your platform have special support for faithd, it is possible -to setup faithd services via inetd(8). Consult manpage for details. - - -<> - -(4) Make sure that packets whose destinations match the prefix can -reach from the IPv6 host to the translating router. - -<> - -There are two ways to translate IPv4 address to IPv6 address: - (a) Faked by DNS - (b) Faked by /etc/hosts. - -(5.a) Install "newbie" and set up FAITH mode. See kit/ports/newbie. - -(5.b) Add an entry into /etc/hosts so that you can resolve hostname into -faked IPv6 addrss. For example, add the following line for www.netbsd.org: - - 3ffe:0501:ffff:0000::140.160.140.252 www.netbsd.org - -<> - -(6) To see if "faithd" works, watch "/var/log/daemon". Note: please -setup "/etc/syslog.conf" so that LOG_DAEMON messages are to be stored -in "/var/log/daemon". - - - daemon.* /var/log/daemon - - -Access control -============== - -Since faithd implements TCP relaying service, it is critical to implement -proper access control to cope with malicious use. Bad guy may try to -use your relay router to circumvent access controls, or may try to -abuse your network (like sending SPAMs from IPv4 address that belong to you). -Install IPv6 packet filter directives that would reject traffic from -unwanted source. If you are using inetd-based setup, you may be able to -use access control mechanisms in inetd. - - -Advanced configuration -====================== - -If you would like to restrict IPv4 destination for translation, you may -want to do the following: - - # route add -inet6 3ffe:0501:ffff:0000::123.0.0.0 -prefixlen 104 ::1 - # route change -inet6 3ffe:0501:ffff:0000::123.0.0.0 -prefixlen 104 \ - -ifp faith0 - -By this way, you can restrict IPv4 destination to 123.0.0.0/8. -You may also want to reject packets toward 3ffe:0501:ffff:0000::/64 which -is not in 3ffe:0501:ffff:0000::123.0.0.0/104. This will be left as excerside -for the reader. - -By doing this, you will be able to provide your IPv4 web server to outside -IPv6 customers, without risks of unwanted open relays. - - [[[[ IPv6 network outside ]]]] | - | | connection - node that runs FAITH-daemon (usually a router) v - | - ========+======== IPv4/v6 network in your site - | (123.0.0.0/8) - IPv4 web server diff --git a/usr.sbin/faithd/faithd.8 b/usr.sbin/faithd/faithd.8 deleted file mode 100644 index 93a835b9a97..00000000000 --- a/usr.sbin/faithd/faithd.8 +++ /dev/null @@ -1,404 +0,0 @@ -.\" $KAME: faithd.8,v 1.37 2002/05/09 14:21:23 itojun Exp $ -.\" -.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. -.\" 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. -.\" 3. Neither the name of the project nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd August 2, 2011 -.Dt FAITHD 8 -.Os -.Sh NAME -.Nm faithd -.Nd FAITH IPv6/v4 translator daemon -.Sh SYNOPSIS -.Nm -.Op Fl dp -.Op Fl f Ar configfile -.Ar service -.Op Ar serverpath Op Ar serverargs -.Sh DESCRIPTION -The -.Nm -utility provides IPv6-to-IPv4 TCP relaying. -It can only be used on an IPv4/v6 dual stack router. -.Pp -When -.Nm -receives -.Tn TCPv6 -traffic, it will relay the -.Tn TCPv6 -traffic to -.Tn TCPv4 . -The destination for the relayed -.Tn TCPv4 -connection will be determined by the last 4 octets of the original -.Tn IPv6 -destination. -For example, if -.Li 3ffe:0501:4819:ffff:: -is reserved for -.Nm , -and the -.Tn TCPv6 -destination address is -.Li 3ffe:0501:4819:ffff::0a01:0101 , -the traffic will be relayed to IPv4 destination -.Li 10.1.1.1 . -.Pp -To use the -.Nm -translation service, -an IPv6 address prefix must be reserved for mapping IPv4 addresses into. -The kernel must be properly configured to route all the TCP connections -toward the reserved IPv6 address prefix into the -.Xr faith 4 -pseudo interface, using the -.Xr route 8 -command. -Also, -.Xr sysctl 8 -should be used to configure -.Dv net.inet6.ip6.keepfaith -to -.Dv 1 . -.Pp -The router must be configured to capture all the TCP traffic -for the reserved -.Tn IPv6 -address prefix, by using -.Xr route 8 -and -.Xr sysctl 8 -commands. -.Pp -The -.Nm -utility needs special name-to-address translation logic, so that -hostnames get resolved into the special -.Tn IPv6 -address prefix. -For small-scale installations, use -.Xr hosts 5 ; -For large-scale installations, it is useful to have -a DNS server with special address translation support. -An implementation called -.Nm totd -is available at -.Pa http://www.vermicelli.pasta.cs.uit.no/software/totd.html . -Make sure you do not propagate translated DNS records over to normal -DNS, as it can cause severe problems. -.Ss Daemon mode -When -.Nm -is invoked as a standalone program, -.Nm -will daemonize itself. -The -.Nm -utility will listen to -.Tn TCPv6 -port -.Ar service . -If -.Tn TCPv6 -traffic to port -.Ar service -is found, it relays the connection. -.Pp -Since -.Nm -listens to TCP port -.Ar service , -it is not possible to run local TCP daemons for port -.Ar service -on the router, using -.Xr inetd 8 -or other standard mechanisms. -By specifying -.Ar serverpath -to -.Nm , -you can run local daemons on the router. -The -.Nm -utility will invoke a local daemon at -.Ar serverpath -if the destination address is a local interface address, -and will perform translation to IPv4 TCP in other cases. -You can also specify -.Ar serverargs -for the arguments for the local daemon. -.Pp -The following options are available: -.Bl -tag -width indent -.It Fl d -Debugging information will be generated using -.Xr syslog 3 . -.It Fl f Ar configfile -Specify a configuration file for access control. -See below. -.It Fl p -Use privileged TCP port number as source port, -for IPv4 TCP connection toward final destination. -For relaying -.Xr ftp 1 , -this flag is not necessary as special program code is supplied. -.El -.Pp -The -.Nm -utility will relay both normal and out-of-band TCP data. -It is capable of emulating TCP half close as well. -The -.Nm -utility includes special support for protocols used by -.Xr ftp 1 . -When translating the FTP protocol, -.Nm -translates network level addresses in -.Li PORT/LPRT/EPRT -and -.Li PASV/LPSV/EPSV -commands. -.Pp -Inactive sessions will be disconnected in 30 minutes, -to prevent stale sessions from chewing up resources. -This may be inappropriate for some services -(should this be configurable?). -.Ss inetd mode -When -.Nm -is invoked via -.Xr inetd 8 , -.Nm -will handle connections passed from standard input. -If the connection endpoint is in the reserved IPv6 address prefix, -.Nm -will relay the connection. -Otherwise, -.Nm -will invoke a service-specific daemon like -.Xr telnetd 8 , -by using the command argument passed from -.Xr inetd 8 . -.Pp -The -.Nm -utility determines operation mode by the local TCP port number, -and enables special protocol handling whenever necessary/possible. -For example, if -.Nm -is invoked via -.Xr inetd 8 -on the FTP port, it will operate as an FTP relay. -.Pp -The operation mode requires special support for -.Nm -in -.Xr inetd 8 . -.Ss Access control -To prevent malicious access, -.Nm -implements simple address-based access control. -With -.Pa /etc/faithd.conf -(or -.Ar configfile -specified by -.Fl f ) , -.Nm -will avoid relaying unwanted traffic. -The -.Pa faithd.conf -configuration file contains directives of the following format: -.Bl -bullet -.It -.Ar src Ns / Ns Ar slen Cm deny Ar dst Ns / Ns Ar dlen -.Pp -If the source address of a query matches -.Ar src Ns / Ns Ar slen , -and the translated destination address matches -.Ar dst Ns / Ns Ar dlen , -deny the connection. -.It -.Ar src Ns / Ns Ar slen Cm permit Ar dst Ns / Ns Ar dlen -.Pp -If the source address of a query matches -.Ar src Ns / Ns Ar slen , -and the translated destination address matches -.Ar dst Ns / Ns Ar dlen , -permit the connection. -.El -.Pp -The directives are evaluated in sequence, -and the first matching entry will be effective. -If there is no match -(if we reach the end of the ruleset) -the traffic will be denied. -.Pp -With inetd mode, -traffic may be filtered by using access control functionality in -.Xr inetd 8 . -.Sh EXIT STATUS -The -.Nm -utility exits with -.Dv EXIT_SUCCESS -.Pq 0 -on success, and -.Dv EXIT_FAILURE -.Pq 1 -on error. -.Sh EXAMPLES -Before invoking -.Nm , -the -.Xr faith 4 -interface has to be configured properly. -.Bd -literal -offset indent -# sysctl net.inet6.ip6.accept_rtadv=0 -# sysctl net.inet6.ip6.forwarding=1 -# sysctl net.inet6.ip6.keepfaith=1 -# ifconfig faith0 up -# route add -inet6 3ffe:501:4819:ffff:: -prefixlen 96 ::1 -# route change -inet6 3ffe:501:4819:ffff:: -prefixlen 96 -ifp faith0 -.Ed -.Ss Daemon mode samples -To translate -.Li telnet -service, and provide no local telnet service, invoke -.Nm -as follows: -.Bd -literal -offset indent -# faithd telnet -.Ed -.Pp -If you would like to provide local telnet service via -.Xr telnetd 8 -on -.Pa /usr/libexec/telnetd , -use the following command line: -.Bd -literal -offset indent -# faithd telnet /usr/libexec/telnetd telnetd -.Ed -.Pp -If you would like to pass extra arguments to the local daemon: -.Bd -literal -offset indent -# faithd ftp /usr/libexec/ftpd ftpd -l -.Ed -.Pp -Here are some other examples. -You may need -.Fl p -if the service checks the source port range. -.Bd -literal -offset indent -# faithd ssh -# faithd telnet /usr/libexec/telnetd telnetd -.Ed -.Ss inetd mode samples -Add the following lines into -.Xr inetd.conf 5 . -Syntax may vary depending upon your operating system. -.Bd -literal -offset indent -telnet stream tcp6/faith nowait root faithd telnetd -ftp stream tcp6/faith nowait root faithd ftpd -l -ssh stream tcp6/faith nowait root faithd /usr/sbin/sshd -i -.Ed -.Pp -.Xr inetd 8 -will open listening sockets with kernel TCP relay support enabled. -Whenever a connection comes in, -.Nm -will be invoked by -.Xr inetd 8 . -If the connection endpoint is in the reserved IPv6 address prefix. -The -.Nm -utility will relay the connection. -Otherwise, -.Nm -will invoke service-specific daemon like -.Xr telnetd 8 . -.Ss Access control samples -The following illustrates a simple -.Pa faithd.conf -setting. -.Bd -literal -offset indent -# permit anyone from 3ffe:501:ffff::/48 to use the translator, -# to connect to the following IPv4 destinations: -# - any location except 10.0.0.0/8 and 127.0.0.0/8. -# Permit no other connections. -# -3ffe:501:ffff::/48 deny 10.0.0.0/8 -3ffe:501:ffff::/48 deny 127.0.0.0/8 -3ffe:501:ffff::/48 permit 0.0.0.0/0 -.Ed -.Sh SEE ALSO -.Xr faith 4 , -.Xr route 8 , -.Xr sysctl 8 -.Rs -.%A Jun-ichiro itojun Hagino -.%A Kazu Yamamoto -.%T "An IPv6-to-IPv4 transport relay translator" -.%B RFC3142 -.%U http://tools.ietf.org/html/rfc3142 -.%D June 2001 -.Re -.\" -.Sh HISTORY -The -.Nm -utility first appeared in the WIDE Hydrangea IPv6 protocol stack kit. -.\" -.Pp -IPv6 and IPsec support based on the KAME Project (http://www.kame.net/) stack -was initially integrated into -.Fx 4.0 . -.Sh SECURITY CONSIDERATIONS -It is very insecure to use IP-address based authentication, for connections relayed by -.Nm , -and any other TCP relaying services. -.Pp -Administrators are advised to limit accesses to -.Nm -using -.Pa faithd.conf , -or by using IPv6 packet filters, to protect the -.Nm -service from malicious parties, and to avoid theft of service/bandwidth. -IPv6 destination addresses can be limited by -carefully configuring routing entries that point to -.Xr faith 4 , -using -.Xr route 8 . -The IPv6 source address needs to be filtered using packet filters. -The documents listed in -.Sx SEE ALSO -have more information on this topic. diff --git a/usr.sbin/faithd/faithd.c b/usr.sbin/faithd/faithd.c deleted file mode 100644 index 1745de1f6b1..00000000000 --- a/usr.sbin/faithd/faithd.c +++ /dev/null @@ -1,908 +0,0 @@ -/* $KAME: faithd.c,v 1.67 2003/10/16 05:26:21 itojun Exp $ */ - -/* - * Copyright (C) 1997 and 1998 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. - */ - -/* - * User level translator from IPv6 to IPv4. - * - * Usage: faithd [ ...] - * e.g. faithd telnet /usr/libexec/telnetd telnetd - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_POLL_H -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#ifdef IFT_FAITH -# define USE_ROUTE -# include -# include -# include -#endif - -#include -#include -#include -#include - -#include "faithd.h" -#include "prefix.h" - -char *serverpath = NULL; -char *serverarg[MAXARGV + 1]; -static char *faithdname = NULL; -char logname[BUFSIZ]; -char procname[BUFSIZ]; - -struct myaddrs { - struct myaddrs *next; - struct sockaddr *addr; -}; -struct myaddrs *myaddrs = NULL; - -static const char *service; -#ifdef USE_ROUTE -static int sockfd = 0; -#endif -int dflag = 0; -static int pflag = 0; -static int inetd = 0; -static char *configfile = NULL; - -int main(int, char **); -static int inetd_main(int, char **); -static int daemon_main(int, char **); -static void play_service(int); -static void play_child(int, struct sockaddr *); -static int faith_prefix(struct sockaddr *); -static int map6to4(struct sockaddr_in6 *, struct sockaddr_in *); -static void sig_child(int); -static void sig_terminate(int); -static void start_daemon(void); -static void exit_stderr(const char *, ...) - __attribute__((__format__(__printf__, 1, 2))); -static void grab_myaddrs(void); -static void free_myaddrs(void); -static void update_myaddrs(void); -static void usage(void); - -int -main(int argc, char **argv) -{ - - /* - * Initializing stuff - */ - - faithdname = strrchr(argv[0], '/'); - if (faithdname) - faithdname++; - else - faithdname = argv[0]; - - if (strcmp(faithdname, "faithd") != 0) { - inetd = 1; - return inetd_main(argc, argv); - } else - return daemon_main(argc, argv); -} - -static int -inetd_main(int argc, char **argv) -{ - char path[MAXPATHLEN]; - struct sockaddr_storage me; - struct sockaddr_storage from; - socklen_t melen, fromlen; - int i; - int error; - const int on = 1; - char sbuf[NI_MAXSERV], snum[NI_MAXSERV]; - - if (config_load(configfile) < 0 && configfile) { - exit_failure("could not load config file"); - /*NOTREACHED*/ - } - - if (strrchr(argv[0], '/') == NULL) - snprintf(path, sizeof(path), "%s/%s", DEFAULT_DIR, argv[0]); - else - snprintf(path, sizeof(path), "%s", argv[0]); - -#ifdef USE_ROUTE - grab_myaddrs(); - - sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); - if (sockfd < 0) { - exit_failure("socket(PF_ROUTE): %s", strerror(errno)); - /*NOTREACHED*/ - } -#endif - - melen = sizeof(me); - if (getsockname(STDIN_FILENO, (struct sockaddr *)&me, &melen) < 0) { - exit_failure("getsockname: %s", strerror(errno)); - /*NOTREACHED*/ - } - fromlen = sizeof(from); - if (getpeername(STDIN_FILENO, (struct sockaddr *)&from, &fromlen) < 0) { - exit_failure("getpeername: %s", strerror(errno)); - /*NOTREACHED*/ - } - if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, - sbuf, sizeof(sbuf), NI_NUMERICHOST) == 0) - service = sbuf; - else - service = DEFAULT_PORT_NAME; - if (getnameinfo((struct sockaddr *)&me, melen, NULL, 0, - snum, sizeof(snum), NI_NUMERICHOST) != 0) - snprintf(snum, sizeof(snum), "?"); - - snprintf(logname, sizeof(logname), "faithd %s", snum); - snprintf(procname, sizeof(procname), "accepting port %s", snum); - openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); - - if (argc >= MAXARGV) { - exit_failure("too many arguments"); - /*NOTREACHED*/ - } - serverarg[0] = serverpath = path; - for (i = 1; i < argc; i++) - serverarg[i] = argv[i]; - serverarg[i] = NULL; - - error = setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &on, - sizeof(on)); - if (error < 0) { - exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno)); - /*NOTREACHED*/ - } - - play_child(STDIN_FILENO, (struct sockaddr *)&from); - exit_failure("should not reach here"); - return 0; /*dummy!*/ -} - -static int -daemon_main(int argc, char **argv) -{ - struct addrinfo hints, *res; - int s_wld, error, i, serverargc, on = 1; - int family = AF_INET6; - int c; - - while ((c = getopt(argc, argv, "df:p")) != -1) { - switch (c) { - case 'd': - dflag++; - break; - case 'f': - configfile = optarg; - break; - case 'p': - pflag++; - break; - default: - usage(); - /*NOTREACHED*/ - } - } - argc -= optind; - argv += optind; - - if (config_load(configfile) < 0 && configfile) { - exit_failure("could not load config file"); - /*NOTREACHED*/ - } - - -#ifdef USE_ROUTE - grab_myaddrs(); -#endif - - switch (argc) { - case 0: - usage(); - /*NOTREACHED*/ - default: - serverargc = argc - NUMARG; - if (serverargc >= MAXARGV) - exit_stderr("too many arguments"); - - serverpath = strdup(argv[NUMPRG]); - if (!serverpath) - exit_stderr("not enough core"); - for (i = 0; i < serverargc; i++) { - serverarg[i] = strdup(argv[i + NUMARG]); - if (!serverarg[i]) - exit_stderr("not enough core"); - } - serverarg[i] = NULL; - /* fall throuth */ - case 1: /* no local service */ - service = argv[NUMPRT]; - break; - } - - start_daemon(); - - /* - * Opening wild card socket for this service. - */ - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE; - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; /* SCTP? */ - error = getaddrinfo(NULL, service, &hints, &res); - if (error) - exit_failure("getaddrinfo: %s", gai_strerror(error)); - - s_wld = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (s_wld == -1) - exit_failure("socket: %s", strerror(errno)); - -#ifdef IPV6_FAITH - if (res->ai_family == AF_INET6) { - error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_FAITH, &on, sizeof(on)); - if (error == -1) - exit_failure("setsockopt(IPV6_FAITH): %s", - strerror(errno)); - } -#endif - - error = setsockopt(s_wld, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); - if (error == -1) - exit_failure("setsockopt(SO_REUSEADDR): %s", strerror(errno)); - - error = setsockopt(s_wld, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); - if (error == -1) - exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno)); - -#ifdef IPV6_V6ONLY - error = setsockopt(s_wld, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); - if (error == -1) - exit_failure("setsockopt(IPV6_V6ONLY): %s", strerror(errno)); -#endif - - error = bind(s_wld, (struct sockaddr *)res->ai_addr, res->ai_addrlen); - if (error == -1) - exit_failure("bind: %s", strerror(errno)); - - error = listen(s_wld, 5); - if (error == -1) - exit_failure("listen: %s", strerror(errno)); - -#ifdef USE_ROUTE - sockfd = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC); - if (sockfd < 0) { - exit_failure("socket(PF_ROUTE): %s", strerror(errno)); - /*NOTREACHED*/ - } -#endif - - /* - * Everything is OK. - */ - - snprintf(logname, sizeof(logname), "faithd %s", service); - snprintf(procname, sizeof(procname), "accepting port %s", service); - openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); - syslog(LOG_INFO, "Starting faith daemon for %s port", service); - - play_service(s_wld); - /* NOTREACHED */ - exit(1); /*pacify gcc*/ -} - -static void -play_service(int s_wld) -{ - struct sockaddr_storage srcaddr; - socklen_t len; - int s_src; - pid_t child_pid; -#ifdef HAVE_POLL_H - struct pollfd pfd[2]; -#else - fd_set rfds; - int maxfd; -#endif - int error; - - /* - * Wait, accept, fork, faith.... - */ -again: - setproctitle("%s", procname); - -#ifdef HAVE_POLL_H - pfd[0].fd = s_wld; - pfd[0].events = POLLIN; - pfd[1].fd = -1; - pfd[1].revents = 0; -#else - FD_ZERO(&rfds); - if (s_wld >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_wld, &rfds); - maxfd = s_wld; -#endif -#ifdef USE_ROUTE - if (sockfd) { -#ifdef HAVE_POLL_H - pfd[1].fd = sockfd; - pfd[1].events = POLLIN; -#else - if (sockfd >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(sockfd, &rfds); - maxfd = (maxfd < sockfd) ? sockfd : maxfd; -#endif - } -#endif - -#ifdef HAVE_POLL_H - error = poll(pfd, sizeof(pfd)/sizeof(pfd[0]), INFTIM); -#else - error = select(maxfd + 1, &rfds, NULL, NULL, NULL); -#endif - if (error < 0) { - if (errno == EINTR) - goto again; - exit_failure("select: %s", strerror(errno)); - /*NOTREACHED*/ - } - -#ifdef USE_ROUTE -#ifdef HAVE_POLL_H - if (pfd[1].revents & POLLIN) -#else - if (FD_ISSET(sockfd, &rfds)) -#endif - { - update_myaddrs(); - } -#endif -#ifdef HAVE_POLL_H - if (pfd[0].revents & POLLIN) -#else - if (FD_ISSET(s_wld, &rfds)) -#endif - { - len = sizeof(srcaddr); - s_src = accept(s_wld, (struct sockaddr *)&srcaddr, &len); - if (s_src < 0) { - if (errno == ECONNABORTED) - goto again; - exit_failure("socket: %s", strerror(errno)); - /*NOTREACHED*/ - } - if (srcaddr.ss_family == AF_INET6 && - IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&srcaddr)->sin6_addr)) { - close(s_src); - syslog(LOG_ERR, "connection from IPv4 mapped address?"); - goto again; - } - - child_pid = fork(); - - if (child_pid == 0) { - /* child process */ - close(s_wld); - closelog(); - openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); - play_child(s_src, (struct sockaddr *)&srcaddr); - exit_failure("should never reach here"); - /*NOTREACHED*/ - } else { - /* parent process */ - close(s_src); - if (child_pid == -1) - syslog(LOG_ERR, "can't fork"); - } - } - goto again; -} - -static void -play_child(int s_src, struct sockaddr *srcaddr) -{ - struct sockaddr_storage dstaddr6; - struct sockaddr_storage dstaddr4; - char src[NI_MAXHOST]; - char dst6[NI_MAXHOST]; - char dst4[NI_MAXHOST]; - socklen_t len = sizeof(dstaddr6); - int s_dst, error, hport, nresvport, on = 1; - struct timeval tv; - struct sockaddr *sa4; - const struct config *conf; - - tv.tv_sec = 1; - tv.tv_usec = 0; - - getnameinfo(srcaddr, srcaddr->sa_len, - src, sizeof(src), NULL, 0, NI_NUMERICHOST); - syslog(LOG_INFO, "accepted a client from %s", src); - - error = getsockname(s_src, (struct sockaddr *)&dstaddr6, &len); - if (error == -1) { - exit_failure("getsockname: %s", strerror(errno)); - /*NOTREACHED*/ - } - - getnameinfo((struct sockaddr *)&dstaddr6, len, - dst6, sizeof(dst6), NULL, 0, NI_NUMERICHOST); - syslog(LOG_INFO, "the client is connecting to %s", dst6); - - if (!faith_prefix((struct sockaddr *)&dstaddr6)) { - if (serverpath) { - /* - * Local service - */ - syslog(LOG_INFO, "executing local %s", serverpath); - if (!inetd) { - dup2(s_src, 0); - close(s_src); - dup2(0, 1); - dup2(0, 2); - } - execv(serverpath, serverarg); - syslog(LOG_ERR, "execv %s: %s", serverpath, - strerror(errno)); - _exit(EXIT_FAILURE); - } else { - close(s_src); - exit_success("no local service for %s", service); - } - } - - /* - * Act as a translator - */ - - switch (((struct sockaddr *)&dstaddr6)->sa_family) { - case AF_INET6: - if (!map6to4((struct sockaddr_in6 *)&dstaddr6, - (struct sockaddr_in *)&dstaddr4)) { - close(s_src); - exit_failure("map6to4 failed"); - /*NOTREACHED*/ - } - syslog(LOG_INFO, "translating from v6 to v4"); - break; - default: - close(s_src); - exit_failure("family not supported"); - /*NOTREACHED*/ - } - - sa4 = (struct sockaddr *)&dstaddr4; - getnameinfo(sa4, sa4->sa_len, - dst4, sizeof(dst4), NULL, 0, NI_NUMERICHOST); - - conf = config_match(srcaddr, sa4); - if (!conf || !conf->permit) { - close(s_src); - if (conf) { - exit_failure("translation to %s not permitted for %s", - dst4, prefix_string(&conf->match)); - /*NOTREACHED*/ - } else { - exit_failure("translation to %s not permitted", dst4); - /*NOTREACHED*/ - } - } - - syslog(LOG_INFO, "the translator is connecting to %s", dst4); - - setproctitle("port %s, %s -> %s", service, src, dst4); - - if (sa4->sa_family == AF_INET6) - hport = ntohs(((struct sockaddr_in6 *)&dstaddr4)->sin6_port); - else /* AF_INET */ - hport = ntohs(((struct sockaddr_in *)&dstaddr4)->sin_port); - - if (pflag) - s_dst = rresvport_af(&nresvport, sa4->sa_family); - else - s_dst = socket(sa4->sa_family, SOCK_STREAM, 0); - if (s_dst < 0) { - exit_failure("socket: %s", strerror(errno)); - /*NOTREACHED*/ - } - - if (conf->src.a.ss_family) { - if (bind(s_dst, (const struct sockaddr *)&conf->src.a, - conf->src.a.ss_len) < 0) { - exit_failure("bind: %s", strerror(errno)); - /*NOTREACHED*/ - } - } - - error = setsockopt(s_dst, SOL_SOCKET, SO_OOBINLINE, &on, sizeof(on)); - if (error < 0) { - exit_failure("setsockopt(SO_OOBINLINE): %s", strerror(errno)); - /*NOTREACHED*/ - } - - error = setsockopt(s_src, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - if (error < 0) { - exit_failure("setsockopt(SO_SNDTIMEO): %s", strerror(errno)); - /*NOTREACHED*/ - } - error = setsockopt(s_dst, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); - if (error < 0) { - exit_failure("setsockopt(SO_SNDTIMEO): %s", strerror(errno)); - /*NOTREACHED*/ - } - - error = connect(s_dst, sa4, sa4->sa_len); - if (error < 0) { - exit_failure("connect: %s", strerror(errno)); - /*NOTREACHED*/ - } - - switch (hport) { - case FTP_PORT: - ftp_relay(s_src, s_dst); - break; - default: - tcp_relay(s_src, s_dst, service); - break; - } - - /* NOTREACHED */ -} - -/* 0: non faith, 1: faith */ -static int -faith_prefix(struct sockaddr *dst) -{ -#ifndef USE_ROUTE - int mib[4], size; - struct in6_addr faith_prefix; - struct sockaddr_in6 *dst6 = (struct sockaddr_in *)dst; - - if (dst->sa_family != AF_INET6) - return 0; - - mib[0] = CTL_NET; - mib[1] = PF_INET6; - mib[2] = IPPROTO_IPV6; - mib[3] = IPV6CTL_FAITH_PREFIX; - size = sizeof(struct in6_addr); - if (sysctl(mib, 4, &faith_prefix, &size, NULL, 0) < 0) { - exit_failure("sysctl: %s", strerror(errno)); - /*NOTREACHED*/ - } - - if (memcmp(dst, &faith_prefix, - sizeof(struct in6_addr) - sizeof(struct in_addr) == 0) { - return 1; - } - return 0; -#else - struct myaddrs *p; - struct sockaddr_in6 *sin6; - struct sockaddr_in *sin4; - struct sockaddr_in6 *dst6; - struct sockaddr_in *dst4; - struct sockaddr_in dstmap; - - dst6 = (struct sockaddr_in6 *)dst; - if (dst->sa_family == AF_INET6 - && IN6_IS_ADDR_V4MAPPED(&dst6->sin6_addr)) { - /* ugly... */ - memset(&dstmap, 0, sizeof(dstmap)); - dstmap.sin_family = AF_INET; - dstmap.sin_len = sizeof(dstmap); - memcpy(&dstmap.sin_addr, &dst6->sin6_addr.s6_addr[12], - sizeof(dstmap.sin_addr)); - dst = (struct sockaddr *)&dstmap; - } - - dst6 = (struct sockaddr_in6 *)dst; - dst4 = (struct sockaddr_in *)dst; - - for (p = myaddrs; p; p = p->next) { - sin6 = (struct sockaddr_in6 *)p->addr; - sin4 = (struct sockaddr_in *)p->addr; - - if (p->addr->sa_len != dst->sa_len - || p->addr->sa_family != dst->sa_family) - continue; - - switch (dst->sa_family) { - case AF_INET6: - if (sin6->sin6_scope_id == dst6->sin6_scope_id - && IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &dst6->sin6_addr)) - return 0; - break; - case AF_INET: - if (sin4->sin_addr.s_addr == dst4->sin_addr.s_addr) - return 0; - break; - } - } - return 1; -#endif -} - -/* 0: non faith, 1: faith */ -static int -map6to4(struct sockaddr_in6 *dst6, struct sockaddr_in *dst4) -{ - memset(dst4, 0, sizeof(*dst4)); - dst4->sin_len = sizeof(*dst4); - dst4->sin_family = AF_INET; - dst4->sin_port = dst6->sin6_port; - memcpy(&dst4->sin_addr, &dst6->sin6_addr.s6_addr[12], - sizeof(dst4->sin_addr)); - - if (dst4->sin_addr.s_addr == INADDR_ANY - || dst4->sin_addr.s_addr == INADDR_BROADCAST - || IN_MULTICAST(ntohl(dst4->sin_addr.s_addr))) - return 0; - - return 1; -} - - -static void -sig_child(int sig __unused) -{ - int status; - pid_t pid; - - while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) - if (WEXITSTATUS(status)) - syslog(LOG_WARNING, "child %ld exit status 0x%x", - (long)pid, status); -} - -void -sig_terminate(int sig __unused) -{ - syslog(LOG_INFO, "Terminating faith daemon"); - exit(EXIT_SUCCESS); -} - -static void -start_daemon(void) -{ -#ifdef SA_NOCLDWAIT - struct sigaction sa; -#endif - - if (daemon(0, 0) == -1) - exit_stderr("daemon: %s", strerror(errno)); - -#ifdef SA_NOCLDWAIT - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = sig_child; - sa.sa_flags = SA_NOCLDWAIT; - sigemptyset(&sa.sa_mask); - sigaction(SIGCHLD, &sa, (struct sigaction *)0); -#else - if (signal(SIGCHLD, sig_child) == SIG_ERR) { - exit_failure("signal CHLD: %s", strerror(errno)); - /*NOTREACHED*/ - } -#endif - - if (signal(SIGTERM, sig_terminate) == SIG_ERR) { - exit_failure("signal TERM: %s", strerror(errno)); - /*NOTREACHED*/ - } -} - -static void -exit_stderr(const char *fmt, ...) -{ - va_list ap; - char buf[BUFSIZ]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - fprintf(stderr, "%s\n", buf); - exit(EXIT_FAILURE); -} - -void -exit_failure(const char *fmt, ...) -{ - va_list ap; - char buf[BUFSIZ]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - syslog(LOG_ERR, "%s", buf); - exit(EXIT_FAILURE); -} - -void -exit_success(const char *fmt, ...) -{ - va_list ap; - char buf[BUFSIZ]; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - syslog(LOG_INFO, "%s", buf); - exit(EXIT_SUCCESS); -} - -#ifdef USE_ROUTE -static void -grab_myaddrs(void) -{ - struct ifaddrs *ifap, *ifa; - struct myaddrs *p; - struct sockaddr_in6 *sin6; - - if (getifaddrs(&ifap) != 0) { - exit_failure("getifaddrs"); - /*NOTREACHED*/ - } - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - switch (ifa->ifa_addr->sa_family) { - case AF_INET: - case AF_INET6: - break; - default: - continue; - } - - p = (struct myaddrs *)malloc(sizeof(struct myaddrs) + - ifa->ifa_addr->sa_len); - if (!p) { - exit_failure("not enough core"); - /*NOTREACHED*/ - } - memcpy(p + 1, ifa->ifa_addr, ifa->ifa_addr->sa_len); - p->next = myaddrs; - p->addr = (struct sockaddr *)(p + 1); -#ifdef __KAME__ - if (ifa->ifa_addr->sa_family == AF_INET6) { - sin6 = (struct sockaddr_in6 *)p->addr; - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) - || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) { - sin6->sin6_scope_id = - ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]); - sin6->sin6_addr.s6_addr[2] = 0; - sin6->sin6_addr.s6_addr[3] = 0; - } - } -#endif - myaddrs = p; - if (dflag) { - char hbuf[NI_MAXHOST]; - getnameinfo(p->addr, p->addr->sa_len, - hbuf, sizeof(hbuf), NULL, 0, - NI_NUMERICHOST); - syslog(LOG_INFO, "my interface: %s %s", hbuf, - ifa->ifa_name); - } - } - - freeifaddrs(ifap); -} - -static void -free_myaddrs(void) -{ - struct myaddrs *p, *q; - - p = myaddrs; - while (p) { - q = p->next; - free(p); - p = q; - } - myaddrs = NULL; -} - -static void -update_myaddrs(void) -{ - char msg[BUFSIZ]; - int len; - struct rt_msghdr *rtm; - - len = read(sockfd, msg, sizeof(msg)); - if (len < 0) { - syslog(LOG_ERR, "read(PF_ROUTE) failed"); - return; - } - rtm = (struct rt_msghdr *)msg; - if (len < 4 || len < rtm->rtm_msglen) { - syslog(LOG_ERR, "read(PF_ROUTE) short read"); - return; - } - if (rtm->rtm_version != RTM_VERSION) { - syslog(LOG_ERR, "routing socket version mismatch"); - close(sockfd); - sockfd = 0; - return; - } - switch (rtm->rtm_type) { - case RTM_NEWADDR: - case RTM_DELADDR: - case RTM_IFINFO: - break; - default: - return; - } - /* XXX more filters here? */ - - syslog(LOG_INFO, "update interface address list"); - free_myaddrs(); - grab_myaddrs(); -} -#endif /*USE_ROUTE*/ - -static void -usage(void) -{ - fprintf(stderr, "usage: %s [-dp] [-f conf] service [serverpath [serverargs]]\n", - faithdname); - exit(0); -} diff --git a/usr.sbin/faithd/faithd.h b/usr.sbin/faithd/faithd.h deleted file mode 100644 index c578d46c4d2..00000000000 --- a/usr.sbin/faithd/faithd.h +++ /dev/null @@ -1,70 +0,0 @@ -/* $KAME: faithd.h,v 1.9 2002/05/09 09:41:24 itojun Exp $ */ - -/* - * Copyright (C) 1997 and 1998 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -extern char logname[]; -extern int dflag; - -extern void tcp_relay(int, int, const char *); -extern void ftp_relay(int, int); -extern int ftp_active(int, int, int *, int *); -extern int ftp_passive(int, int, int *, int *); -extern void exit_success(const char *, ...) - __attribute__((__format__(__printf__, 1, 2))); -extern void exit_failure(const char *, ...) - __attribute__((__format__(__printf__, 1, 2))); - -#define DEFAULT_PORT_NAME "telnet" -#define DEFAULT_DIR "/usr/libexec" -#define DEFAULT_NAME "telnetd" -#define DEFAULT_PATH (DEFAULT_DIR "/" DEFAULT_NAME) - -#define FTP_PORT 21 -#define RLOGIN_PORT 513 -#define RSH_PORT 514 - -#define RETURN_SUCCESS 0 -#define RETURN_FAILURE 1 - -#define YES 1 -#define NO 0 - -#define MSS 2048 -#define MAXARGV 20 - -#define NUMPRT 0 -#define NUMPRG 1 -#define NUMARG 2 - -#define UC(b) (((int)b)&0xff) - -#define FAITH_TIMEOUT (30 * 60) /*second*/ diff --git a/usr.sbin/faithd/ftp.c b/usr.sbin/faithd/ftp.c deleted file mode 100644 index c54371a2c20..00000000000 --- a/usr.sbin/faithd/ftp.c +++ /dev/null @@ -1,1085 +0,0 @@ -/* $KAME: ftp.c,v 1.24 2005/03/16 05:05:48 itojun Exp $ */ - -/* - * Copyright (C) 1997 and 1998 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#ifdef HAVE_POLL_H -#include -#endif -#include -#include - -#include -#include -#include - -#include "faithd.h" - -static char rbuf[MSS]; -static char sbuf[MSS]; -static int passivemode = 0; -static int wport4 = -1; /* listen() to active */ -static int wport6 = -1; /* listen() to passive */ -static int port4 = -1; /* active: inbound passive: outbound */ -static int port6 = -1; /* active: outbound passive: inbound */ -static struct sockaddr_storage data4; /* server data address */ -static struct sockaddr_storage data6; /* client data address */ -static int epsvall = 0; - -enum state { NONE, LPRT, EPRT, LPSV, EPSV }; - -static int ftp_activeconn(void); -static int ftp_passiveconn(void); -static int ftp_copy(int, int); -static int ftp_copyresult(int, int, enum state); -static int ftp_copycommand(int, int, enum state *); - -void -ftp_relay(int ctl6, int ctl4) -{ -#ifdef HAVE_POLL_H - struct pollfd pfd[6]; -#else - fd_set readfds; -#endif - int error; - enum state state = NONE; - struct timeval tv; - - syslog(LOG_INFO, "starting ftp control connection"); - - for (;;) { -#ifdef HAVE_POLL_H - pfd[0].fd = ctl4; - pfd[0].events = POLLIN; - pfd[1].fd = ctl6; - pfd[1].events = POLLIN; - if (0 <= port4) { - pfd[2].fd = port4; - pfd[2].events = POLLIN; - } else - pfd[2].fd = -1; - if (0 <= port6) { - pfd[3].fd = port6; - pfd[3].events = POLLIN; - } else - pfd[3].fd = -1; -#if 0 - if (0 <= wport4) { - pfd[4].fd = wport4; - pfd[4].events = POLLIN; - } else - pfd[4].fd = -1; - if (0 <= wport6) { - pfd[5].fd = wport4; - pfd[5].events = POLLIN; - } else - pfd[5].fd = -1; -#else - pfd[4].fd = pfd[5].fd = -1; - pfd[4].events = pfd[5].events = 0; -#endif -#else - int maxfd = 0; - - FD_ZERO(&readfds); - if (ctl4 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(ctl4, &readfds); - maxfd = ctl4; - if (ctl6 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(ctl6, &readfds); - maxfd = (ctl6 > maxfd) ? ctl6 : maxfd; - if (0 <= port4) { - if (port4 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(port4, &readfds); - maxfd = (port4 > maxfd) ? port4 : maxfd; - } - if (0 <= port6) { - if (port6 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(port6, &readfds); - maxfd = (port6 > maxfd) ? port6 : maxfd; - } -#if 0 - if (0 <= wport4) { - if (wport4 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(wport4, &readfds); - maxfd = (wport4 > maxfd) ? wport4 : maxfd; - } - if (0 <= wport6) { - if (wport6 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(wport6, &readfds); - maxfd = (wport6 > maxfd) ? wport6 : maxfd; - } -#endif -#endif - tv.tv_sec = FAITH_TIMEOUT; - tv.tv_usec = 0; - -#ifdef HAVE_POLL_H - error = poll(pfd, sizeof(pfd)/sizeof(pfd[0]), tv.tv_sec * 1000); -#else - error = select(maxfd + 1, &readfds, NULL, NULL, &tv); -#endif - if (error == -1) { -#ifdef HAVE_POLL_H - exit_failure("poll: %s", strerror(errno)); -#else - exit_failure("select: %s", strerror(errno)); -#endif - } - else if (error == 0) - exit_failure("connection timeout"); - - /* - * The order of the following checks does (slightly) matter. - * It is important to visit all checks (do not use "continue"), - * otherwise some of the pipe may become full and we cannot - * relay correctly. - */ -#ifdef HAVE_POLL_H - if (pfd[1].revents & POLLIN) -#else - if (FD_ISSET(ctl6, &readfds)) -#endif - { - /* - * copy control connection from the client. - * command translation is necessary. - */ - error = ftp_copycommand(ctl6, ctl4, &state); - - if (error < 0) - goto bad; - else if (error == 0) { - close(ctl4); - close(ctl6); - exit_success("terminating ftp control connection"); - /*NOTREACHED*/ - } - } -#ifdef HAVE_POLL_H - if (pfd[0].revents & POLLIN) -#else - if (FD_ISSET(ctl4, &readfds)) -#endif - { - /* - * copy control connection from the server - * translation of result code is necessary. - */ - error = ftp_copyresult(ctl4, ctl6, state); - - if (error < 0) - goto bad; - else if (error == 0) { - close(ctl4); - close(ctl6); - exit_success("terminating ftp control connection"); - /*NOTREACHED*/ - } - } -#ifdef HAVE_POLL_H - if (0 <= port4 && 0 <= port6 && (pfd[2].revents & POLLIN)) -#else - if (0 <= port4 && 0 <= port6 && FD_ISSET(port4, &readfds)) -#endif - { - /* - * copy data connection. - * no special treatment necessary. - */ -#ifdef HAVE_POLL_H - if (pfd[2].revents & POLLIN) -#else - if (FD_ISSET(port4, &readfds)) -#endif - error = ftp_copy(port4, port6); - switch (error) { - case -1: - goto bad; - case 0: - close(port4); - close(port6); - port4 = port6 = -1; - syslog(LOG_INFO, "terminating data connection"); - break; - default: - break; - } - } -#ifdef HAVE_POLL_H - if (0 <= port4 && 0 <= port6 && (pfd[3].revents & POLLIN)) -#else - if (0 <= port4 && 0 <= port6 && FD_ISSET(port6, &readfds)) -#endif - { - /* - * copy data connection. - * no special treatment necessary. - */ -#ifdef HAVE_POLL_H - if (pfd[3].revents & POLLIN) -#else - if (FD_ISSET(port6, &readfds)) -#endif - error = ftp_copy(port6, port4); - switch (error) { - case -1: - goto bad; - case 0: - close(port4); - close(port6); - port4 = port6 = -1; - syslog(LOG_INFO, "terminating data connection"); - break; - default: - break; - } - } -#if 0 -#ifdef HAVE_POLL_H - if (wport4 && (pfd[4].revents & POLLIN)) -#else - if (wport4 && FD_ISSET(wport4, &readfds)) -#endif - { - /* - * establish active data connection from the server. - */ - ftp_activeconn(); - } -#ifdef HAVE_POLL_H - if (wport4 && (pfd[5].revents & POLLIN)) -#else - if (wport6 && FD_ISSET(wport6, &readfds)) -#endif - { - /* - * establish passive data connection from the client. - */ - ftp_passiveconn(); - } -#endif - } - - bad: - exit_failure("%s", strerror(errno)); -} - -static int -ftp_activeconn() -{ - socklen_t n; - int error; -#ifdef HAVE_POLL_H - struct pollfd pfd[1]; -#else - fd_set set; -#endif - struct timeval timeout; - struct sockaddr *sa; - - /* get active connection from server */ -#ifdef HAVE_POLL_H - pfd[0].fd = wport4; - pfd[0].events = POLLIN; -#else - FD_ZERO(&set); - if (wport4 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(wport4, &set); -#endif - timeout.tv_sec = 120; - timeout.tv_usec = 0; - n = sizeof(data4); -#ifdef HAVE_POLL_H - if (poll(pfd, sizeof(pfd)/sizeof(pfd[0]), timeout.tv_sec * 1000) == 0 || - (port4 = accept(wport4, (struct sockaddr *)&data4, &n)) < 0) -#else - if (select(wport4 + 1, &set, NULL, NULL, &timeout) == 0 || - (port4 = accept(wport4, (struct sockaddr *)&data4, &n)) < 0) -#endif - { - close(wport4); - wport4 = -1; - syslog(LOG_INFO, "active mode data connection failed"); - return -1; - } - - /* ask active connection to client */ - sa = (struct sockaddr *)&data6; - port6 = socket(sa->sa_family, SOCK_STREAM, 0); - if (port6 == -1) { - close(port4); - close(wport4); - port4 = wport4 = -1; - syslog(LOG_INFO, "active mode data connection failed"); - return -1; - } - error = connect(port6, sa, sa->sa_len); - if (error < 0) { - close(port6); - close(port4); - close(wport4); - port6 = port4 = wport4 = -1; - syslog(LOG_INFO, "active mode data connection failed"); - return -1; - } - - syslog(LOG_INFO, "active mode data connection established"); - return 0; -} - -static int -ftp_passiveconn() -{ - socklen_t len; - int error; -#ifdef HAVE_POLL_H - struct pollfd pfd[1]; -#else - fd_set set; -#endif - struct timeval timeout; - struct sockaddr *sa; - - /* get passive connection from client */ -#ifdef HAVE_POLL_H - pfd[0].fd = wport6; - pfd[0].events = POLLIN; -#else - FD_ZERO(&set); - if (wport6 >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(wport6, &set); -#endif - timeout.tv_sec = 120; - timeout.tv_usec = 0; - len = sizeof(data6); -#ifdef HAVE_POLL_H - if (poll(pfd, sizeof(pfd)/sizeof(pfd[0]), timeout.tv_sec * 1000) == 0 || - (port6 = accept(wport6, (struct sockaddr *)&data6, &len)) < 0) -#else - if (select(wport6 + 1, &set, NULL, NULL, &timeout) == 0 || - (port6 = accept(wport6, (struct sockaddr *)&data6, &len)) < 0) -#endif - { - close(wport6); - wport6 = -1; - syslog(LOG_INFO, "passive mode data connection failed"); - return -1; - } - - /* ask passive connection to server */ - sa = (struct sockaddr *)&data4; - port4 = socket(sa->sa_family, SOCK_STREAM, 0); - if (port4 == -1) { - close(wport6); - close(port6); - wport6 = port6 = -1; - syslog(LOG_INFO, "passive mode data connection failed"); - return -1; - } - error = connect(port4, sa, sa->sa_len); - if (error < 0) { - close(wport6); - close(port4); - close(port6); - wport6 = port4 = port6 = -1; - syslog(LOG_INFO, "passive mode data connection failed"); - return -1; - } - - syslog(LOG_INFO, "passive mode data connection established"); - return 0; -} - -static int -ftp_copy(int src, int dst) -{ - int error, atmark, n; - - /* OOB data handling */ - error = ioctl(src, SIOCATMARK, &atmark); - if (error != -1 && atmark == 1) { - n = read(src, rbuf, 1); - if (n == -1) - goto bad; - send(dst, rbuf, n, MSG_OOB); -#if 0 - n = read(src, rbuf, sizeof(rbuf)); - if (n == -1) - goto bad; - write(dst, rbuf, n); - return n; -#endif - } - - n = read(src, rbuf, sizeof(rbuf)); - switch (n) { - case -1: - case 0: - return n; - default: - write(dst, rbuf, n); - return n; - } - - bad: - exit_failure("%s", strerror(errno)); - /*NOTREACHED*/ - return 0; /* to make gcc happy */ -} - -static int -ftp_copyresult(int src, int dst, enum state state) -{ - int error, atmark, n; - socklen_t len; - char *param; - int code; - char *a, *p; - int i; - - /* OOB data handling */ - error = ioctl(src, SIOCATMARK, &atmark); - if (error != -1 && atmark == 1) { - n = read(src, rbuf, 1); - if (n == -1) - goto bad; - send(dst, rbuf, n, MSG_OOB); -#if 0 - n = read(src, rbuf, sizeof(rbuf)); - if (n == -1) - goto bad; - write(dst, rbuf, n); - return n; -#endif - } - - n = read(src, rbuf, sizeof(rbuf)); - if (n <= 0) - return n; - rbuf[n] = '\0'; - - /* - * parse argument - */ - p = rbuf; - for (i = 0; i < 3; i++) { - if (!isdigit(*p)) { - /* invalid reply */ - write(dst, rbuf, n); - return n; - } - p++; - } - if (!isspace(*p)) { - /* invalid reply */ - write(dst, rbuf, n); - return n; - } - code = atoi(rbuf); - param = p; - /* param points to first non-command token, if any */ - while (*param && isspace(*param)) - param++; - if (!*param) - param = NULL; - - switch (state) { - case NONE: - if (!passivemode && rbuf[0] == '1') { - if (ftp_activeconn() < 0) { - n = snprintf(rbuf, sizeof(rbuf), - "425 Cannot open data connetion\r\n"); - if (n < 0 || n >= sizeof(rbuf)) - n = 0; - } - } - if (n) - write(dst, rbuf, n); - return n; - case LPRT: - case EPRT: - /* expecting "200 PORT command successful." */ - if (code == 200) { - p = strstr(rbuf, "PORT"); - if (p) { - p[0] = (state == LPRT) ? 'L' : 'E'; - p[1] = 'P'; - } - } else { - close(wport4); - wport4 = -1; - } - write(dst, rbuf, n); - return n; - case LPSV: - case EPSV: - /* - * expecting "227 Entering Passive Mode (x,x,x,x,x,x,x)" - * (in some cases result comes without paren) - */ - if (code != 227) { -passivefail0: - close(wport6); - wport6 = -1; - write(dst, rbuf, n); - return n; - } - - { - unsigned int ho[4], po[2]; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - u_short port; - - /* - * PASV result -> LPSV/EPSV result - */ - p = param; - while (*p && *p != '(' && !isdigit(*p)) /*)*/ - p++; - if (!*p) - goto passivefail0; /*XXX*/ - if (*p == '(') /*)*/ - p++; - n = sscanf(p, "%u,%u,%u,%u,%u,%u", - &ho[0], &ho[1], &ho[2], &ho[3], &po[0], &po[1]); - if (n != 6) - goto passivefail0; /*XXX*/ - - /* keep PORT parameter */ - memset(&data4, 0, sizeof(data4)); - sin = (struct sockaddr_in *)&data4; - sin->sin_len = sizeof(*sin); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = 0; - for (n = 0; n < 4; n++) { - sin->sin_addr.s_addr |= - htonl((ho[n] & 0xff) << ((3 - n) * 8)); - } - sin->sin_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff)); - - /* get ready for passive data connection */ - memset(&data6, 0, sizeof(data6)); - sin6 = (struct sockaddr_in6 *)&data6; - sin6->sin6_len = sizeof(*sin6); - sin6->sin6_family = AF_INET6; - wport6 = socket(sin6->sin6_family, SOCK_STREAM, 0); - if (wport6 == -1) { -passivefail: - n = snprintf(sbuf, sizeof(sbuf), - "500 could not translate from PASV\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } -#ifdef IPV6_FAITH - { - int on = 1; - error = setsockopt(wport6, IPPROTO_IPV6, IPV6_FAITH, - &on, sizeof(on)); - if (error == -1) - exit_failure("setsockopt(IPV6_FAITH): %s", strerror(errno)); - } -#endif - error = bind(wport6, (struct sockaddr *)sin6, sin6->sin6_len); - if (error == -1) { - close(wport6); - wport6 = -1; - goto passivefail; - } - error = listen(wport6, 1); - if (error == -1) { - close(wport6); - wport6 = -1; - goto passivefail; - } - - /* transmit LPSV or EPSV */ - /* - * addr from dst, port from wport6 - */ - len = sizeof(data6); - error = getsockname(wport6, (struct sockaddr *)&data6, &len); - if (error == -1) { - close(wport6); - wport6 = -1; - goto passivefail; - } - sin6 = (struct sockaddr_in6 *)&data6; - port = sin6->sin6_port; - - len = sizeof(data6); - error = getsockname(dst, (struct sockaddr *)&data6, &len); - if (error == -1) { - close(wport6); - wport6 = -1; - goto passivefail; - } - sin6 = (struct sockaddr_in6 *)&data6; - sin6->sin6_port = port; - - if (state == LPSV) { - a = (char *)&sin6->sin6_addr; - p = (char *)&sin6->sin6_port; - n = snprintf(sbuf, sizeof(sbuf), -"228 Entering Long Passive Mode (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)\r\n", - 6, 16, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), - UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), - UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), - 2, UC(p[0]), UC(p[1])); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(dst, sbuf, n); - passivemode = 1; - return n; - } else { - n = snprintf(sbuf, sizeof(sbuf), -"229 Entering Extended Passive Mode (|||%d|)\r\n", - ntohs(sin6->sin6_port)); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(dst, sbuf, n); - passivemode = 1; - return n; - } - } - } - - bad: - exit_failure("%s", strerror(errno)); - /*NOTREACHED*/ - return 0; /* to make gcc happy */ -} - -static int -ftp_copycommand(int src, int dst, enum state *state) -{ - int error, atmark, n; - socklen_t len; - unsigned int af, hal, ho[16], pal, po[2]; - char *a, *p, *q; - char cmd[5], *param; - struct sockaddr_in *sin; - struct sockaddr_in6 *sin6; - enum state nstate; - char ch; - int i; - - /* OOB data handling */ - error = ioctl(src, SIOCATMARK, &atmark); - if (error != -1 && atmark == 1) { - n = read(src, rbuf, 1); - if (n == -1) - goto bad; - send(dst, rbuf, n, MSG_OOB); -#if 0 - n = read(src, rbuf, sizeof(rbuf)); - if (n == -1) - goto bad; - write(dst, rbuf, n); - return n; -#endif - } - - n = read(src, rbuf, sizeof(rbuf)); - if (n <= 0) - return n; - rbuf[n] = '\0'; - - if (n < 4) { - write(dst, rbuf, n); - return n; - } - - /* - * parse argument - */ - p = rbuf; - q = cmd; - for (i = 0; i < 4; i++) { - if (!isalpha(*p)) { - /* invalid command */ - write(dst, rbuf, n); - return n; - } - *q++ = islower(*p) ? toupper(*p) : *p; - p++; - } - if (!isspace(*p)) { - /* invalid command */ - write(dst, rbuf, n); - return n; - } - *q = '\0'; - param = p; - /* param points to first non-command token, if any */ - while (*param && isspace(*param)) - param++; - if (!*param) - param = NULL; - - *state = NONE; - - if (strcmp(cmd, "LPRT") == 0 && param) { - /* - * LPRT -> PORT - */ - nstate = LPRT; - - close(wport4); - close(wport6); - close(port4); - close(port6); - wport4 = wport6 = port4 = port6 = -1; - - if (epsvall) { - n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n", - cmd); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - - n = sscanf(param, -"%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u,%u", - &af, &hal, &ho[0], &ho[1], &ho[2], &ho[3], - &ho[4], &ho[5], &ho[6], &ho[7], - &ho[8], &ho[9], &ho[10], &ho[11], - &ho[12], &ho[13], &ho[14], &ho[15], - &pal, &po[0], &po[1]); - if (n != 21 || af != 6 || hal != 16|| pal != 2) { - n = snprintf(sbuf, sizeof(sbuf), - "501 illegal parameter to LPRT\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - - /* keep LPRT parameter */ - memset(&data6, 0, sizeof(data6)); - sin6 = (struct sockaddr_in6 *)&data6; - sin6->sin6_len = sizeof(*sin6); - sin6->sin6_family = AF_INET6; - for (n = 0; n < 16; n++) - sin6->sin6_addr.s6_addr[n] = ho[n]; - sin6->sin6_port = htons(((po[0] & 0xff) << 8) | (po[1] & 0xff)); - -sendport: - /* get ready for active data connection */ - len = sizeof(data4); - error = getsockname(dst, (struct sockaddr *)&data4, &len); - if (error == -1) { -lprtfail: - n = snprintf(sbuf, sizeof(sbuf), - "500 could not translate to PORT\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - if (((struct sockaddr *)&data4)->sa_family != AF_INET) - goto lprtfail; - sin = (struct sockaddr_in *)&data4; - sin->sin_port = 0; - wport4 = socket(sin->sin_family, SOCK_STREAM, 0); - if (wport4 == -1) - goto lprtfail; - error = bind(wport4, (struct sockaddr *)sin, sin->sin_len); - if (error == -1) { - close(wport4); - wport4 = -1; - goto lprtfail; - } - error = listen(wport4, 1); - if (error == -1) { - close(wport4); - wport4 = -1; - goto lprtfail; - } - - /* transmit PORT */ - len = sizeof(data4); - error = getsockname(wport4, (struct sockaddr *)&data4, &len); - if (error == -1) { - close(wport4); - wport4 = -1; - goto lprtfail; - } - if (((struct sockaddr *)&data4)->sa_family != AF_INET) { - close(wport4); - wport4 = -1; - goto lprtfail; - } - sin = (struct sockaddr_in *)&data4; - a = (char *)&sin->sin_addr; - p = (char *)&sin->sin_port; - n = snprintf(sbuf, sizeof(sbuf), "PORT %d,%d,%d,%d,%d,%d\r\n", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(p[0]), UC(p[1])); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(dst, sbuf, n); - *state = nstate; - passivemode = 0; - return n; - } else if (strcmp(cmd, "EPRT") == 0 && param) { - /* - * EPRT -> PORT - */ - char *afp, *hostp, *portp; - struct addrinfo hints, *res; - - nstate = EPRT; - - close(wport4); - close(wport6); - close(port4); - close(port6); - wport4 = wport6 = port4 = port6 = -1; - - if (epsvall) { - n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n", - cmd); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - - p = param; - ch = *p++; /* boundary character */ - afp = p; - while (*p && *p != ch) - p++; - if (!*p) { -eprtparamfail: - n = snprintf(sbuf, sizeof(sbuf), - "501 illegal parameter to EPRT\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - *p++ = '\0'; - hostp = p; - while (*p && *p != ch) - p++; - if (!*p) - goto eprtparamfail; - *p++ = '\0'; - portp = p; - while (*p && *p != ch) - p++; - if (!*p) - goto eprtparamfail; - *p++ = '\0'; - - n = sscanf(afp, "%d", &af); - if (n != 1 || af != 2) { - n = snprintf(sbuf, sizeof(sbuf), - "501 unsupported address family to EPRT\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - error = getaddrinfo(hostp, portp, &hints, &res); - if (error) { - n = snprintf(sbuf, sizeof(sbuf), - "501 EPRT: %s\r\n", gai_strerror(error)); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - if (res->ai_next) { - n = snprintf(sbuf, sizeof(sbuf), - "501 EPRT: %s resolved to multiple addresses\r\n", hostp); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - freeaddrinfo(res); - return n; - } - - memcpy(&data6, res->ai_addr, res->ai_addrlen); - - freeaddrinfo(res); - goto sendport; - } else if (strcmp(cmd, "LPSV") == 0 && !param) { - /* - * LPSV -> PASV - */ - nstate = LPSV; - - close(wport4); - close(wport6); - close(port4); - close(port6); - wport4 = wport6 = port4 = port6 = -1; - - if (epsvall) { - n = snprintf(sbuf, sizeof(sbuf), "501 %s disallowed in EPSV ALL\r\n", - cmd); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } - - /* transmit PASV */ - n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(dst, sbuf, n); - *state = LPSV; - passivemode = 0; /* to be set to 1 later */ - return n; - } else if (strcmp(cmd, "EPSV") == 0 && !param) { - /* - * EPSV -> PASV - */ - close(wport4); - close(wport6); - close(port4); - close(port6); - wport4 = wport6 = port4 = port6 = -1; - - n = snprintf(sbuf, sizeof(sbuf), "PASV\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(dst, sbuf, n); - *state = EPSV; - passivemode = 0; /* to be set to 1 later */ - return n; - } else if (strcmp(cmd, "EPSV") == 0 && param - && strncasecmp(param, "ALL", 3) == 0 && isspace(param[3])) { - /* - * EPSV ALL - */ - epsvall = 1; - n = snprintf(sbuf, sizeof(sbuf), "200 EPSV ALL command successful.\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } else if (strcmp(cmd, "PORT") == 0 || strcmp(cmd, "PASV") == 0) { - /* - * reject PORT/PASV - */ - n = snprintf(sbuf, sizeof(sbuf), "502 %s not implemented.\r\n", cmd); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - return n; - } else if (passivemode - && (strcmp(cmd, "STOR") == 0 - || strcmp(cmd, "STOU") == 0 - || strcmp(cmd, "RETR") == 0 - || strcmp(cmd, "LIST") == 0 - || strcmp(cmd, "NLST") == 0 - || strcmp(cmd, "APPE") == 0)) { - /* - * commands with data transfer. need to care about passive - * mode data connection. - */ - - if (ftp_passiveconn() < 0) { - n = snprintf(sbuf, sizeof(sbuf), "425 Cannot open data connetion\r\n"); - if (n < 0 || n >= sizeof(sbuf)) - n = 0; - if (n) - write(src, sbuf, n); - } else { - /* simply relay the command */ - write(dst, rbuf, n); - } - - *state = NONE; - return n; - } else { - /* simply relay it */ - *state = NONE; - write(dst, rbuf, n); - return n; - } - - bad: - exit_failure("%s", strerror(errno)); - /*NOTREACHED*/ - return 0; /* to make gcc happy */ -} diff --git a/usr.sbin/faithd/prefix.c b/usr.sbin/faithd/prefix.c deleted file mode 100644 index bdb763ad6f5..00000000000 --- a/usr.sbin/faithd/prefix.c +++ /dev/null @@ -1,345 +0,0 @@ -/* $KAME: prefix.c,v 1.13 2003/09/02 22:50:17 itojun Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2000 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef offsetof -#define offsetof(type, member) ((size_t)(u_long)(&((type *)0)->member)) -#endif - -#include "faithd.h" -#include "prefix.h" - -static int prefix_set(const char *, struct prefix *, int); -static struct config *config_load1(const char *); -#if 0 -static void config_show1(const struct config *); -static void config_show(void); -#endif - -struct config *config_list = NULL; -const int niflags = NI_NUMERICHOST; - -static int -prefix_set(const char *s, struct prefix *prefix, int slash) -{ - char *p = NULL, *q, *r; - struct addrinfo hints, *res = NULL; - int max; - - p = strdup(s); - if (!p) - goto fail; - q = strchr(p, '/'); - if (q) { - if (!slash) - goto fail; - *q++ = '\0'; - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(p, "0", &hints, &res)) - goto fail; - if (res->ai_next || res->ai_addrlen > sizeof(prefix->a)) - goto fail; - memcpy(&prefix->a, res->ai_addr, res->ai_addrlen); - - switch (prefix->a.ss_family) { - case AF_INET: - max = 32; - break; - case AF_INET6: - max = 128; - break; - default: - max = -1; - break; - } - - if (q) { - r = NULL; - prefix->l = (int)strtoul(q, &r, 10); - if (!*q || *r) - goto fail; - if (prefix->l < 0 || prefix->l > max) - goto fail; - } else - prefix->l = max; - - if (p) - free(p); - if (res) - freeaddrinfo(res); - return 0; - -fail: - if (p) - free(p); - if (res) - freeaddrinfo(res); - return -1; -} - -const char * -prefix_string(const struct prefix *prefix) -{ - static char buf[NI_MAXHOST + 20]; - char hbuf[NI_MAXHOST]; - - if (getnameinfo((const struct sockaddr *)&prefix->a, prefix->a.ss_len, - hbuf, sizeof(hbuf), NULL, 0, niflags)) - return NULL; - snprintf(buf, sizeof(buf), "%s/%d", hbuf, prefix->l); - return buf; -} - -int -prefix_match(const struct prefix *prefix, const struct sockaddr *sa) -{ - struct sockaddr_storage a, b; - char *pa, *pb; - int off, l; - - if (prefix->a.ss_family != sa->sa_family || - prefix->a.ss_len != sa->sa_len) - return 0; - - if (prefix->a.ss_len > sizeof(a) || sa->sa_len > sizeof(b)) - return 0; - - switch (prefix->a.ss_family) { - case AF_INET: - off = offsetof(struct sockaddr_in, sin_addr); - break; - case AF_INET6: - off = offsetof(struct sockaddr_in6, sin6_addr); - break; - default: - if (memcmp(&prefix->a, sa, prefix->a.ss_len) != 0) - return 0; - else - return 1; - } - - memcpy(&a, &prefix->a, prefix->a.ss_len); - memcpy(&b, sa, sa->sa_len); - l = prefix->l / 8 + (prefix->l % 8 ? 1 : 0); - - /* overrun check */ - if (off + l > a.ss_len) - return 0; - - pa = ((char *)&a) + off; - pb = ((char *)&b) + off; - if (prefix->l % 8) { - pa[prefix->l / 8] &= 0xff00 >> (prefix->l % 8); - pb[prefix->l / 8] &= 0xff00 >> (prefix->l % 8); - } - if (memcmp(pa, pb, l) != 0) - return 0; - else - return 1; -} - -/* - * prefix/prefixlen permit/deny prefix/prefixlen [srcaddr] - * 3ffe::/16 permit 10.0.0.0/8 10.1.1.1 - */ -static struct config * -config_load1(const char *line) -{ - struct config *conf; - char buf[BUFSIZ]; - char *p; - char *token[4]; - int i; - - if (strlen(line) + 1 > sizeof(buf)) - return NULL; - strlcpy(buf, line, sizeof(buf)); - - p = strchr(buf, '\n'); - if (!p) - return NULL; - *p = '\0'; - p = strchr(buf, '#'); - if (p) - *p = '\0'; - if (strlen(buf) == 0) - return NULL; - - p = buf; - memset(token, 0, sizeof(token)); - for (i = 0; i < sizeof(token) / sizeof(token[0]); i++) { - token[i] = strtok(p, "\t "); - p = NULL; - if (token[i] == NULL) - break; - } - /* extra tokens? */ - if (strtok(p, "\t ") != NULL) - return NULL; - /* insufficient tokens */ - switch (i) { - case 3: - case 4: - break; - default: - return NULL; - } - - conf = (struct config *)malloc(sizeof(*conf)); - if (conf == NULL) - return NULL; - memset(conf, 0, sizeof(*conf)); - - if (strcasecmp(token[1], "permit") == 0) - conf->permit = 1; - else if (strcasecmp(token[1], "deny") == 0) - conf->permit = 0; - else { - /* invalid keyword is considered as "deny" */ - conf->permit = 0; - } - - if (prefix_set(token[0], &conf->match, 1) < 0) - goto fail; - if (prefix_set(token[2], &conf->dest, 1) < 0) - goto fail; - if (token[3]) { - if (prefix_set(token[3], &conf->src, 0) < 0) - goto fail; - } - - return conf; - -fail: - free(conf); - return NULL; -} - -int -config_load(const char *configfile) -{ - FILE *fp; - char buf[BUFSIZ]; - struct config *conf, *p; - struct config sentinel; - - config_list = NULL; - - if (!configfile) - configfile = _PATH_PREFIX_CONF; - fp = fopen(configfile, "r"); - if (fp == NULL) - return -1; - - p = &sentinel; - sentinel.next = NULL; - while (fgets(buf, sizeof(buf), fp) != NULL) { - conf = config_load1(buf); - if (conf) { - p->next = conf; - p = p->next; - } - } - config_list = sentinel.next; - - fclose(fp); - return 0; -} - -#if 0 -static void -config_show1(const struct config *conf) -{ - const char *p; - - p = prefix_string(&conf->match); - printf("%s", p ? p : "?"); - - if (conf->permit) - printf(" permit"); - else - printf(" deny"); - - p = prefix_string(&conf->dest); - printf(" %s", p ? p : "?"); - - printf("\n"); -} - -static void -config_show() -{ - struct config *conf; - - for (conf = config_list; conf; conf = conf->next) - config_show1(conf); -} -#endif - -const struct config * -config_match(struct sockaddr *sa1, struct sockaddr *sa2) -{ - static struct config conf; - const struct config *p; - - if (sa1->sa_len > sizeof(conf.match.a) || - sa2->sa_len > sizeof(conf.dest.a)) - return NULL; - - memset(&conf, 0, sizeof(conf)); - if (!config_list) { - conf.permit = 1; - memcpy(&conf.match.a, sa1, sa1->sa_len); - memcpy(&conf.dest.a, sa2, sa2->sa_len); - return &conf; - } - - for (p = config_list; p; p = p->next) - if (prefix_match(&p->match, sa1) && prefix_match(&p->dest, sa2)) - return p; - - return NULL; -} diff --git a/usr.sbin/faithd/prefix.h b/usr.sbin/faithd/prefix.h deleted file mode 100644 index 4d6b3d59c46..00000000000 --- a/usr.sbin/faithd/prefix.h +++ /dev/null @@ -1,52 +0,0 @@ -/* $KAME: prefix.h,v 1.4 2001/09/05 03:04:21 itojun Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (C) 2000 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. - */ - -struct prefix { - struct sockaddr_storage a; - int l; -}; - -struct config { - struct config *next; - - int permit; - struct prefix match; - struct prefix dest; - struct prefix src; /* src to use for outgoing connection */ -}; - -#define _PATH_PREFIX_CONF "/etc/faithd.conf" - -extern const char *prefix_string(const struct prefix *); -extern int prefix_match(const struct prefix *, const struct sockaddr *); -extern int config_load(const char *); -extern const struct config *config_match(struct sockaddr *, struct sockaddr *); diff --git a/usr.sbin/faithd/tcp.c b/usr.sbin/faithd/tcp.c deleted file mode 100644 index 21976944147..00000000000 --- a/usr.sbin/faithd/tcp.c +++ /dev/null @@ -1,324 +0,0 @@ -/* $KAME: tcp.c,v 1.13 2003/09/02 22:49:21 itojun Exp $ */ - -/* - * Copyright (C) 1997 and 1998 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "faithd.h" - -static char tcpbuf[16*1024]; - /* bigger than MSS and may be lesser than window size */ -static int tblen, tboff, oob_exists; -static fd_set readfds, writefds, exceptfds; -static char atmark_buf[2]; -static pid_t cpid = (pid_t)0; -static pid_t ppid = (pid_t)0; -volatile time_t child_lastactive = (time_t)0; -static time_t parent_lastactive = (time_t)0; - -static void sig_ctimeout(int); -static void sig_child(int); -static void notify_inactive(void); -static void notify_active(void); -static void send_data(int, int, const char *, int); -static void relay(int, int, const char *, int); - -/* - * Inactivity timer: - * - child side (ppid != 0) will send SIGUSR1 to parent every (FAITH_TIMEOUT/4) - * second if traffic is active. if traffic is inactive, don't send SIGUSR1. - * - parent side (ppid == 0) will check the last SIGUSR1 it have seen. - */ -static void -sig_ctimeout(int sig __unused) -{ - /* parent side: record notification from the child */ - if (dflag) - syslog(LOG_DEBUG, "activity timer from child"); - child_lastactive = time(NULL); -} - -/* parent will terminate if child dies. */ -static void -sig_child(int sig __unused) -{ - int status; - pid_t pid; - - pid = wait3(&status, WNOHANG, (struct rusage *)0); - if (pid > 0 && WEXITSTATUS(status)) - syslog(LOG_WARNING, "child %ld exit status 0x%x", - (long)pid, status); - exit_success("terminate connection due to child termination"); -} - -static void -notify_inactive() -{ - time_t t; - - /* only on parent side... */ - if (ppid) - return; - - /* parent side should check for timeout. */ - t = time(NULL); - if (dflag) { - syslog(LOG_DEBUG, "parent side %sactive, child side %sactive", - (FAITH_TIMEOUT < t - parent_lastactive) ? "in" : "", - (FAITH_TIMEOUT < t - child_lastactive) ? "in" : ""); - } - - if (FAITH_TIMEOUT < t - child_lastactive - && FAITH_TIMEOUT < t - parent_lastactive) { - /* both side timeouted */ - signal(SIGCHLD, SIG_DFL); - kill(cpid, SIGTERM); - wait(NULL); - exit_failure("connection timeout"); - /* NOTREACHED */ - } -} - -static void -notify_active() -{ - if (ppid) { - /* child side: notify parent of active traffic */ - time_t t; - t = time(NULL); - if (FAITH_TIMEOUT / 4 < t - child_lastactive) { - if (kill(ppid, SIGUSR1) < 0) { - exit_failure("terminate connection due to parent termination"); - /* NOTREACHED */ - } - child_lastactive = t; - } - } else { - /* parent side */ - parent_lastactive = time(NULL); - } -} - -static void -send_data(int s_rcv, int s_snd, const char *service __unused, int direction) -{ - int cc; - - if (oob_exists) { - cc = send(s_snd, atmark_buf, 1, MSG_OOB); - if (cc == -1) - goto retry_or_err; - oob_exists = 0; - if (s_rcv >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_rcv, &exceptfds); - } - - for (; tboff < tblen; tboff += cc) { - cc = write(s_snd, tcpbuf + tboff, tblen - tboff); - if (cc < 0) - goto retry_or_err; - } -#ifdef DEBUG - if (tblen) { - if (tblen >= sizeof(tcpbuf)) - tblen = sizeof(tcpbuf) - 1; - tcpbuf[tblen] = '\0'; - syslog(LOG_DEBUG, "from %s (%dbytes): %s", - direction == 1 ? "client" : "server", tblen, tcpbuf); - } -#endif /* DEBUG */ - tblen = 0; tboff = 0; - if (s_snd >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_CLR(s_snd, &writefds); - if (s_rcv >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_rcv, &readfds); - return; - retry_or_err: - if (errno != EAGAIN) - exit_failure("writing relay data failed: %s", strerror(errno)); - if (s_snd >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_snd, &writefds); -} - -static void -relay(int s_rcv, int s_snd, const char *service, int direction) -{ - int atmark, error, maxfd; - struct timeval tv; - fd_set oreadfds, owritefds, oexceptfds; - - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptfds); - fcntl(s_snd, F_SETFD, O_NONBLOCK); - oreadfds = readfds; owritefds = writefds; oexceptfds = exceptfds; - if (s_rcv >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_rcv, &readfds); - FD_SET(s_rcv, &exceptfds); - oob_exists = 0; - maxfd = (s_rcv > s_snd) ? s_rcv : s_snd; - - for (;;) { - tv.tv_sec = FAITH_TIMEOUT / 4; - tv.tv_usec = 0; - oreadfds = readfds; - owritefds = writefds; - oexceptfds = exceptfds; - error = select(maxfd + 1, &readfds, &writefds, &exceptfds, &tv); - if (error == -1) { - if (errno == EINTR) - continue; - exit_failure("select: %s", strerror(errno)); - } else if (error == 0) { - readfds = oreadfds; - writefds = owritefds; - exceptfds = oexceptfds; - notify_inactive(); - continue; - } - - /* activity notification */ - notify_active(); - - if (FD_ISSET(s_rcv, &exceptfds)) { - error = ioctl(s_rcv, SIOCATMARK, &atmark); - if (error != -1 && atmark == 1) { - int cc; - oob_read_retry: - cc = read(s_rcv, atmark_buf, 1); - if (cc == 1) { - if (s_rcv >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_CLR(s_rcv, &exceptfds); - if (s_snd >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_snd, &writefds); - oob_exists = 1; - } else if (cc == -1) { - if (errno == EINTR) - goto oob_read_retry; - exit_failure("reading oob data failed" - ": %s", - strerror(errno)); - } - } - } - if (FD_ISSET(s_rcv, &readfds)) { - relaydata_read_retry: - tblen = read(s_rcv, tcpbuf, sizeof(tcpbuf)); - tboff = 0; - - switch (tblen) { - case -1: - if (errno == EINTR) - goto relaydata_read_retry; - exit_failure("reading relay data failed: %s", - strerror(errno)); - /* NOTREACHED */ - case 0: - /* to close opposite-direction relay process */ - shutdown(s_snd, 0); - - close(s_rcv); - close(s_snd); - exit_success("terminating %s relay", service); - /* NOTREACHED */ - default: - if (s_rcv >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_CLR(s_rcv, &readfds); - if (s_snd >= FD_SETSIZE) - exit_failure("descriptor too big"); - FD_SET(s_snd, &writefds); - break; - } - } - if (FD_ISSET(s_snd, &writefds)) - send_data(s_rcv, s_snd, service, direction); - } -} - -void -tcp_relay(int s_src, int s_dst, const char *service) -{ - syslog(LOG_INFO, "starting %s relay", service); - - child_lastactive = parent_lastactive = time(NULL); - - cpid = fork(); - switch (cpid) { - case -1: - exit_failure("tcp_relay: can't fork grand child: %s", - strerror(errno)); - /* NOTREACHED */ - case 0: - /* child process: relay going traffic */ - ppid = getppid(); - /* this is child so reopen log */ - closelog(); - openlog(logname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); - relay(s_src, s_dst, service, 1); - /* NOTREACHED */ - default: - /* parent process: relay coming traffic */ - ppid = (pid_t)0; - signal(SIGUSR1, sig_ctimeout); - signal(SIGCHLD, sig_child); - relay(s_dst, s_src, service, 0); - /* NOTREACHED */ - } -} diff --git a/usr.sbin/faithd/test/faithd.rb b/usr.sbin/faithd/test/faithd.rb deleted file mode 100644 index 682f540db98..00000000000 --- a/usr.sbin/faithd/test/faithd.rb +++ /dev/null @@ -1,312 +0,0 @@ -# faithd, ruby version. requires v6-enabled ruby. -# -# highly experimental (not working right at all) and very limited -# functionality. -# -# $Id: faithd.rb,v 1.1.2.4 1999/05/10 17:06:30 itojun Exp $ -# $FreeBSD$ - -require "socket" -require "thread" - -# XXX should be derived from system headers -IPPROTO_IPV6 = 41 -IPV6_FAITH = 29 -DEBUG = true -DEBUG_LOOPBACK = true - -# TODO: OOB data handling -def tcpcopy(s1, s2, m) - STDERR.print "tcpcopy #{s1} #{s2}\n" if DEBUG - buf = "" - while TRUE - begin - buf = s1.sysread(100) - s2.syswrite(buf) - rescue EOFError - break - rescue IOError - break - end - end - STDERR.print "tcpcopy #{s1} #{s2} finished\n" if DEBUG - s1.shutdown(0) - s2.shutdown(1) -end - -def relay_ftp_passiveconn(s6, s4, dport6, dport4) - Thread.start do - d6 = TCPserver.open("::", dport6).accept - d4 = TCPsocket.open(s4.getpeer[3], dport4) - t = [] - t[0] = Thread.start do - tcpcopy(d6, d4) - end - t[1] = Thread.start do - tcpcopy(d4, d6) - end - for i in t - i.join - end - d4.close - d6.close - end -end - -def ftp_parse_2428(line) - if (line[0] != line[line.length - 1]) - return nil - end - t = line.split(line[0 .. 0]) # as string - if (t.size != 4 || t[1] !~ /^[12]$/ || t[3] !~ /^\d+$/) - return nil - end - return t[1 .. 3] -end - -def relay_ftp_command(s6, s4, state) - STDERR.print "relay_ftp_command start\n" if DEBUG - while TRUE - begin - STDERR.print "s6.gets\n" if DEBUG - line = s6.gets - STDERR.print "line is #{line}\n" if DEBUG - if line == nil - return nil - end - - # translate then copy - STDERR.print "line is #{line}\n" if DEBUG - if (line =~ /^EPSV\r\n/i) - STDERR.print "EPSV -> PASV\n" if DEBUG - line = "PASV\n" - state = "EPSV" - elsif (line =~ /^EPRT\s+(.+)\r\n/i) - t = ftp_parse_2428($1) - if t == nil - s6.puts "501 illegal parameter to EPRT\r\n" - next - end - - # some tricks should be here - s6.puts "501 illegal parameter to EPRT\r\n" - next - end - STDERR.print "fail: send #{line} as is\n" if DEBUG - s4.puts(line) - break - rescue EOFError - return nil - rescue IOError - return nil - end - end - STDERR.print "relay_ftp_command finish\n" if DEBUG - return state -end - -def relay_ftp_status(s4, s6, state) - STDERR.print "relay_ftp_status start\n" if DEBUG - while TRUE - begin - line = s4.gets - if line == nil - return nil - end - - # translate then copy - s6.puts(line) - - next if line =~ /^\d\d\d-/ - next if line !~ /^\d/ - - # special post-processing - case line - when /^221 / # result to QUIT - s4.shutdown(0) - s6.shutdown(1) - end - - break if (line =~ /^\d\d\d /) - rescue EOFError - return nil - rescue IOError - return nil - end - end - STDERR.print "relay_ftp_status finish\n" if DEBUG - return state -end - -def relay_ftp(sock, name) - STDERR.print "relay_ftp(#{sock}, #{name})\n" if DEBUG - while TRUE - STDERR.print "relay_ftp(#{sock}, #{name}) accepting\n" if DEBUG - s = sock.accept - STDERR.print "relay_ftp(#{sock}, #{name}) accepted #{s}\n" if DEBUG - Thread.start do - threads = [] - STDERR.print "accepted #{s} -> #{Thread.current}\n" if DEBUG - s6 = s - dest6 = s.addr[3] - if !DEBUG_LOOPBACK - t = s.getsockname.unpack("x8 x12 C4") - dest4 = "#{t[0]}.#{t[1]}.#{t[2]}.#{t[3]}" - port4 = s.addr[1] - else - dest4 = "127.0.0.1" - port4 = "ftp" - end - if DEBUG - STDERR.print "IPv6 dest: #{dest6} IPv4 dest: #{dest4}\n" if DEBUG - end - STDERR.print "connect to #{dest4} #{port4}\n" if DEBUG - s4 = TCPsocket.open(dest4, port4) - STDERR.print "connected to #{dest4} #{port4}, #{s4.addr[1]}\n" if DEBUG - state = 0 - while TRUE - # translate status line - state = relay_ftp_status(s4, s6, state) - break if state == nil - # translate command line - state = relay_ftp_command(s6, s4, state) - break if state == nil - end - STDERR.print "relay_ftp(#{sock}, #{name}) closing s4\n" if DEBUG - s4.close - STDERR.print "relay_ftp(#{sock}, #{name}) closing s6\n" if DEBUG - s6.close - STDERR.print "relay_ftp(#{sock}, #{name}) done\n" if DEBUG - end - end - STDERR.print "relay_ftp(#{sock}, #{name}) finished\n" if DEBUG -end - -def relay_tcp(sock, name) - STDERR.print "relay_tcp(#{sock}, #{name})\n" if DEBUG - while TRUE - STDERR.print "relay_tcp(#{sock}, #{name}) accepting\n" if DEBUG - s = sock.accept - STDERR.print "relay_tcp(#{sock}, #{name}) accepted #{s}\n" if DEBUG - Thread.start do - threads = [] - STDERR.print "accepted #{s} -> #{Thread.current}\n" if DEBUG - s6 = s - dest6 = s.addr[3] - if !DEBUG_LOOPBACK - t = s.getsockname.unpack("x8 x12 C4") - dest4 = "#{t[0]}.#{t[1]}.#{t[2]}.#{t[3]}" - port4 = s.addr[1] - else - dest4 = "127.0.0.1" - port4 = "telnet" - end - if DEBUG - STDERR.print "IPv6 dest: #{dest6} IPv4 dest: #{dest4}\n" if DEBUG - end - STDERR.print "connect to #{dest4} #{port4}\n" if DEBUG - s4 = TCPsocket.open(dest4, port4) - STDERR.print "connected to #{dest4} #{port4}, #{s4.addr[1]}\n" if DEBUG - [0, 1].each do |i| - threads[i] = Thread.start do - if (i == 0) - tcpcopy(s6, s4) - else - tcpcopy(s4, s6) - end - end - end - STDERR.print "relay_tcp(#{sock}, #{name}) wait\n" if DEBUG - for i in threads - STDERR.print "relay_tcp(#{sock}, #{name}) wait #{i}\n" if DEBUG - i.join - STDERR.print "relay_tcp(#{sock}, #{name}) wait #{i} done\n" if DEBUG - end - STDERR.print "relay_tcp(#{sock}, #{name}) closing s4\n" if DEBUG - s4.close - STDERR.print "relay_tcp(#{sock}, #{name}) closing s6\n" if DEBUG - s6.close - STDERR.print "relay_tcp(#{sock}, #{name}) done\n" if DEBUG - end - end - STDERR.print "relay_tcp(#{sock}, #{name}) finished\n" if DEBUG -end - -def usage() - STDERR.print "usage: #{$0} [-f] port...\n" -end - -#------------------------------------------------------------ - -$mode = "tcp" - -while ARGV[0] =~ /^-/ do - case ARGV[0] - when /^-f/ - $mode = "ftp" - else - usage() - exit 0 - end - ARGV.shift -end - -if ARGV.length == 0 - usage() - exit 1 -end - -ftpport = Socket.getservbyname("ftp") - -res = [] -for port in ARGV - t = Socket.getaddrinfo(nil, port, Socket::PF_INET6, Socket::SOCK_STREAM, - nil, Socket::AI_PASSIVE) - if (t.size <= 0) - STDERR.print "FATAL: getaddrinfo failed (port=#{port})\n" - exit 1 - end - res += t -end - -sockpool = [] -names = [] -listenthreads = [] - -res.each do |i| - s = TCPserver.new(i[3], i[1]) - n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ") - if i[6] == IPPROTO_IPV6 - s.setsockopt(i[6], IPV6_FAITH, 1) - end - s.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1) - sockpool.push s - names.push n -end - -if DEBUG - (0 .. sockpool.size - 1).each do |i| - STDERR.print "listen[#{i}]: #{sockpool[i]} #{names[i]}\n" if DEBUG - end -end - -(0 .. sockpool.size - 1).each do |i| - listenthreads[i] = Thread.start do - if DEBUG - STDERR.print "listen[#{i}]: thread #{Thread.current}\n" if DEBUG - end - STDERR.print "listen[#{i}]: thread #{Thread.current}\n" if DEBUG - case $mode - when "tcp" - relay_tcp(sockpool[i], names[i]) - when "ftp" - relay_ftp(sockpool[i], names[i]) - end - end -end - -for i in listenthreads - i.join -end - -exit 0 diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh index ee702e3a4f7..f586909caa3 100644 --- a/usr.sbin/freebsd-update/freebsd-update.sh +++ b/usr.sbin/freebsd-update/freebsd-update.sh @@ -580,6 +580,7 @@ fetchupgrade_check_params () { _KEYPRINT_z="Key must be given via -k option or configuration file." _KEYPRINT_bad="Invalid key fingerprint: " _WORKDIR_bad="Directory does not exist or is not writable: " + _WORKDIR_bad2="Directory is not on a persistent filesystem: " if [ -z "${SERVERNAME}" ]; then echo -n "`basename $0`: " @@ -603,6 +604,13 @@ fetchupgrade_check_params () { echo ${WORKDIR} exit 1 fi + case `df -T ${WORKDIR}` in */dev/md[0-9]* | *tmpfs*) + echo -n "`basename $0`: " + echo -n "${_WORKDIR_bad2}" + echo ${WORKDIR} + exit 1 + ;; + esac chmod 700 ${WORKDIR} cd ${WORKDIR} || exit 1 diff --git a/usr.sbin/i2c/i2c.c b/usr.sbin/i2c/i2c.c index 3a61aa53fe7..920dda21f33 100644 --- a/usr.sbin/i2c/i2c.c +++ b/usr.sbin/i2c/i2c.c @@ -142,6 +142,7 @@ scan_bus(struct iiccmd cmd, char *dev, int skip, char *skip_addr) if (tokens == NULL) { fprintf(stderr, "Error allocating tokens " "buffer\n"); + error = -1; goto out; } index = skip_get_tokens(skip_addr, tokens, @@ -150,6 +151,7 @@ scan_bus(struct iiccmd cmd, char *dev, int skip, char *skip_addr) if (!no_range && (addr_range.start > addr_range.end)) { fprintf(stderr, "Skip address out of range\n"); + error = -1; goto out; } } @@ -409,8 +411,10 @@ i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) if (i2c_opt.mode == I2C_MODE_STOP_START) { cmd.slave = i2c_opt.addr; error = ioctl(fd, I2CSTOP, &cmd); - if (error == -1) + if (error == -1) { + err_msg = "error sending stop condtion\n"; goto err2; + } } } cmd.slave = i2c_opt.addr; @@ -432,8 +436,10 @@ i2c_read(char *dev, struct options i2c_opt, char *i2c_buf) } } error = ioctl(fd, I2CSTOP, &cmd); - if (error == -1) + if (error == -1) { + err_msg = "error sending stop condtion\n"; goto err2; + } for (i = 0; i < i2c_opt.count; i++) { error = read(fd, &i2c_buf[i], 1); diff --git a/usr.sbin/inetd/inetd.c b/usr.sbin/inetd/inetd.c index eebcfea6f60..c48f33ca93e 100644 --- a/usr.sbin/inetd/inetd.c +++ b/usr.sbin/inetd/inetd.c @@ -69,7 +69,7 @@ __FBSDID("$FreeBSD$"); * or name a tcpmux service * or specify a unix domain socket * socket type stream/dgram/raw/rdm/seqpacket - * protocol tcp[4][6][/faith], udp[4][6], unix + * protocol tcp[4][6], udp[4][6], unix * wait/nowait single-threaded/multi-threaded * user[:group][/login-class] user/group/login-class to run daemon as * server program full path name @@ -1305,14 +1305,6 @@ setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) syslog(LOG_ERR, "setsockopt (IPV6_V6ONLY): %m"); } #undef turnon -#ifdef IPV6_FAITH - if (sep->se_type == FAITH_TYPE) { - if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on, - sizeof(on)) < 0) { - syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); - } - } -#endif #ifdef IPSEC ipsecsetup(sep); #endif @@ -1744,15 +1736,15 @@ more: arg = sskip(&cp); if (strncmp(arg, "tcp", 3) == 0) { sep->se_proto = newstr(strsep(&arg, "/")); - if (arg != NULL) { - if (strcmp(arg, "faith") == 0) - sep->se_type = FAITH_TYPE; + if (arg != NULL && (strcmp(arg, "faith") == 0)) { + syslog(LOG_ERR, "faith has been deprecated"); + goto more; } } else { if (sep->se_type == NORM_TYPE && strncmp(arg, "faith/", 6) == 0) { - arg += 6; - sep->se_type = FAITH_TYPE; + syslog(LOG_ERR, "faith has been deprecated"); + goto more; } sep->se_proto = newstr(arg); } diff --git a/usr.sbin/iscsid/chap.c b/usr.sbin/iscsid/chap.c index abc9a18d7e1..62e39f5a636 100644 --- a/usr.sbin/iscsid/chap.c +++ b/usr.sbin/iscsid/chap.c @@ -33,6 +33,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include #include #include #include @@ -105,6 +107,29 @@ chap_hex2int(const char hex) } } +static int +chap_b642bin(const char *b64, void **binp, size_t *bin_lenp) +{ + char *bin; + int b64_len, bin_len; + + b64_len = strlen(b64); + bin_len = (b64_len + 3) / 4 * 3; + bin = calloc(bin_len, 1); + if (bin == NULL) + log_err(1, "calloc"); + + bin_len = b64_pton(b64, bin, bin_len); + if (bin_len < 0) { + log_warnx("malformed base64 variable"); + free(bin); + return (-1); + } + *binp = bin; + *bin_lenp = bin_len; + return (0); +} + /* * XXX: Review this _carefully_. */ @@ -116,8 +141,12 @@ chap_hex2bin(const char *hex, void **binp, size_t *bin_lenp) char *bin; size_t bin_off, bin_len; + if (strncasecmp(hex, "0b", strlen("0b")) == 0) + return (chap_b642bin(hex + 2, binp, bin_lenp)); + if (strncasecmp(hex, "0x", strlen("0x")) != 0) { - log_warnx("malformed variable, should start with \"0x\""); + log_warnx("malformed variable, should start with \"0x\"" + " or \"0b\""); return (-1); } @@ -160,6 +189,25 @@ chap_hex2bin(const char *hex, void **binp, size_t *bin_lenp) return (0); } +#ifdef USE_BASE64 +static char * +chap_bin2hex(const char *bin, size_t bin_len) +{ + unsigned char *b64, *tmp; + size_t b64_len; + + b64_len = (bin_len + 2) / 3 * 4 + 3; /* +2 for "0b", +1 for '\0'. */ + b64 = malloc(b64_len); + if (b64 == NULL) + log_err(1, "malloc"); + + tmp = b64; + tmp += sprintf(tmp, "0b"); + b64_ntop(bin, bin_len, tmp, b64_len - 2); + + return (b64); +} +#else static char * chap_bin2hex(const char *bin, size_t bin_len) { @@ -181,6 +229,7 @@ chap_bin2hex(const char *bin, size_t bin_len) return (hex); } +#endif /* !USE_BASE64 */ struct chap * chap_new(void) diff --git a/usr.sbin/pw/pw.c b/usr.sbin/pw/pw.c index b0ac7285926..ff48db7af16 100644 --- a/usr.sbin/pw/pw.c +++ b/usr.sbin/pw/pw.c @@ -98,6 +98,7 @@ main(int argc, char *argv[]) int which = -1; char *config = NULL; struct userconf *cnf; + struct stat st; static const char *opts[W_NUM][M_NUM] = { @@ -143,6 +144,13 @@ main(int argc, char *argv[]) if (argv[1][1] == 'V') { optarg = &argv[1][2]; if (*optarg == '\0') { + if (stat(argv[2], &st) != 0) + errx(EX_OSFILE, \ + "no such directory `%s'", + argv[2]); + if (!S_ISDIR(st.st_mode)) + errx(EX_OSFILE, "`%s' not a " + "directory", argv[2]); optarg = argv[2]; ++argv; --argc; diff --git a/usr.sbin/pw/tests/Makefile b/usr.sbin/pw/tests/Makefile index fabf624f347..6bc943370fb 100644 --- a/usr.sbin/pw/tests/Makefile +++ b/usr.sbin/pw/tests/Makefile @@ -5,7 +5,7 @@ TESTSRC= ${.CURDIR}/../../../contrib/netbsd-tests/usr.sbin/useradd TESTSDIR= ${TESTSBASE}/usr.sbin/pw -ATF_TESTS_SH= pw_delete pw_modify +ATF_TESTS_SH= pw_delete pw_lock pw_modify pw_etcdir TEST_METADATA.pw_delete+= required_user="root" TEST_METADATA.pw_modify+= required_user="root" diff --git a/usr.sbin/pw/tests/helper_functions.shin b/usr.sbin/pw/tests/helper_functions.shin index f87b1e7d943..3680dfe608e 100755 --- a/usr.sbin/pw/tests/helper_functions.shin +++ b/usr.sbin/pw/tests/helper_functions.shin @@ -1,5 +1,8 @@ # $FreeBSD$ +# The pw command +PW="pw -V ${HOME}" + # Workdir to run tests in TESTDIR=$(atf_get_srcdir) diff --git a/usr.sbin/pw/tests/pw_delete.sh b/usr.sbin/pw/tests/pw_delete.sh index 0e979391348..832ec932f64 100755 --- a/usr.sbin/pw/tests/pw_delete.sh +++ b/usr.sbin/pw/tests/pw_delete.sh @@ -12,36 +12,36 @@ rmuser_seperate_group_head() { } rmuser_seperate_group_body() { populate_etc_skel - pw -V ${HOME} useradd test || atf_fail "Creating test user" - pw -V ${HOME} groupmod test -M 'test,root' || \ + ${PW} useradd test || atf_fail "Creating test user" + ${PW} groupmod test -M 'test,root' || \ atf_fail "Modifying the group" - pw -V ${HOME} userdel test || atf_fail "delete the user" + ${PW} userdel test || atf_fail "Delete the test user" } -atf_test_case group_do_not_delete_wheel_if_group_unkown -group_do_not_delete_wheel_if_group_unkown_head() { - atf_set "descr" "Make sure we do not consider as gid 0 an unknown group" +atf_test_case group_do_not_delete_wheel_if_group_unknown +group_do_not_delete_wheel_if_group_unknown_head() { + atf_set "descr" "Make sure we do not consider gid 0 an unknown group" } -group_do_not_delete_wheel_if_group_unkown_body() { +group_do_not_delete_wheel_if_group_unknown_body() { populate_etc_skel - atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x pw -V ${HOME} groupshow wheel - atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x pw -V ${HOME} groupdel -g I_do_not_exist - atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x pw -V ${HOME} groupshow wheel + atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel + atf_check -e inline:"pw: -g expects a number\n" -s exit:64 -x ${PW} groupdel -g I_do_not_exist + atf_check -s exit:0 -o inline:"wheel:*:0:root\n" -x ${PW} groupshow wheel } -atf_test_case user_do_not_try_to_delete_root_if_user_unkown -user_do_not_try_to_delete_root_if_user_unkown_head() { - atf_set "descr" "Make sure not to try to remove root if deleteing an unknown user" +atf_test_case user_do_not_try_to_delete_root_if_user_unknown +user_do_not_try_to_delete_root_if_user_unknown_head() { + atf_set "descr" "Make sure not to try to remove root if deleting an unknown user" } -user_do_not_try_to_delete_root_if_user_unkown_body() { +user_do_not_try_to_delete_root_if_user_unknown_body() { populate_etc_skel - atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x pw -V ${HOME} userdel -u plop + atf_check -e inline:"pw: -u expects a number\n" -s exit:64 -x ${PW} userdel -u plop } atf_init_test_cases() { atf_add_test_case rmuser_seperate_group - atf_add_test_case group_do_not_delete_wheel_if_group_unkown - atf_add_test_case user_do_not_try_to_delete_root_if_user_unkown + atf_add_test_case group_do_not_delete_wheel_if_group_unknown + atf_add_test_case user_do_not_try_to_delete_root_if_user_unknown } diff --git a/usr.sbin/pw/tests/pw_etcdir.sh b/usr.sbin/pw/tests/pw_etcdir.sh new file mode 100755 index 00000000000..b237789ed45 --- /dev/null +++ b/usr.sbin/pw/tests/pw_etcdir.sh @@ -0,0 +1,18 @@ +# $FreeBSD$ + +# When the '-V directory' option is provided, the directory must exist +atf_test_case etcdir_must_exist +etcdir_must_exist_head() { + atf_set "descr" "When the '-V directory' option is provided, the directory must exist" +} + +etcdir_must_exist_body() { + local fakedir="/this_directory_does_not_exist" + atf_check -e inline:"pw: no such directory \`$fakedir'\n" \ + -s exit:72 -x pw -V ${fakedir} usershow root +} + +atf_init_test_cases() { + atf_add_test_case etcdir_must_exist +} + diff --git a/usr.sbin/pw/tests/pw_lock.sh b/usr.sbin/pw/tests/pw_lock.sh new file mode 100755 index 00000000000..9f14e24ae07 --- /dev/null +++ b/usr.sbin/pw/tests/pw_lock.sh @@ -0,0 +1,22 @@ +# $FreeBSD$ + +# Import helper functions +. $(atf_get_srcdir)/helper_functions.shin + +# Test locking and unlocking a user account +atf_test_case user_locking cleanup +user_locking_body() { + populate_etc_skel + ${PW} useradd test || atf_fail "Creating test user" + ${PW} lock test || atf_fail "Locking the user" + atf_check -s exit:0 -o match:"^test:\*LOCKED\*\*:1001:" \ + grep "^test:\*LOCKED\*\*:1001:" $HOME/master.passwd + ${PW} unlock test || atf_fail "Locking the user" + atf_check -s exit:0 -o match:"^test:\*:1001:" \ + grep "^test:\*:1001:" $HOME/master.passwd +} + + +atf_init_test_cases() { + atf_add_test_case user_locking +} diff --git a/usr.sbin/pw/tests/pw_modify.sh b/usr.sbin/pw/tests/pw_modify.sh index b81f105d92b..ad7ad0a3b7c 100755 --- a/usr.sbin/pw/tests/pw_modify.sh +++ b/usr.sbin/pw/tests/pw_modify.sh @@ -8,11 +8,11 @@ atf_test_case groupmod_user groupmod_user_body() { populate_etc_skel - atf_check -s exit:0 pw -V ${HOME} addgroup test - atf_check -s exit:0 pw -V ${HOME} groupmod test -m root + atf_check -s exit:0 ${PW} addgroup test + atf_check -s exit:0 ${PW} groupmod test -m root atf_check -s exit:0 -o match:"^test:\*:1001:root$" \ grep "^test:\*:.*:root$" $HOME/group - atf_check -s exit:0 pw -V ${HOME} groupmod test -d root + atf_check -s exit:0 ${PW} groupmod test -d root atf_check -s exit:0 -o match:"^test:\*:1001:$" \ grep "^test:\*:.*:$" $HOME/group } @@ -22,9 +22,9 @@ groupmod_user_body() { atf_test_case groupmod_invalid_user groupmod_invalid_user_body() { populate_etc_skel - atf_check -s exit:0 pw -V ${HOME} addgroup test - atf_check -s exit:67 -e match:"does not exist" pw -V ${HOME} groupmod test -m foo - atf_check -s exit:0 pw -V ${HOME} groupmod test -d foo + atf_check -s exit:0 ${PW} addgroup test + atf_check -s exit:67 -e match:"does not exist" ${PW} groupmod test -m foo + atf_check -s exit:0 ${PW} groupmod test -d foo } atf_test_case groupmod_bug_193704 @@ -33,9 +33,9 @@ groupmod_bug_193704_head() { } groupmod_bug_193704_body() { populate_etc_skel - atf_check -s exit:0 -x pw -V ${HOME} groupadd test - atf_check -s exit:0 -x pw -V ${HOME} groupmod test -l newgroupname - atf_check -s exit:65 -e match:"^pw: unknown group" -x pw -V ${HOME} groupshow test + atf_check -s exit:0 -x ${PW} groupadd test + atf_check -s exit:0 -x ${PW} groupmod test -l newgroupname + atf_check -s exit:65 -e match:"^pw: unknown group" -x ${PW} groupshow test } atf_test_case usermod_bug_185666 @@ -45,17 +45,17 @@ usermod_bug_185666_head() { usermod_bug_185666_body() { populate_etc_skel - atf_check -s exit:0 -x pw -V ${HOME} useradd testuser - atf_check -s exit:0 -x pw -V ${HOME} groupadd testgroup - atf_check -s exit:0 -x pw -V ${HOME} groupadd testgroup2 - atf_check -s exit:0 -x pw -V ${HOME} usermod testuser -G testgroup - atf_check -o inline:"testuser:*:1001:\n" -x pw -V${HOME} groupshow testuser - atf_check -o inline:"testgroup:*:1002:testuser\n" -x pw -V ${HOME} groupshow testgroup - atf_check -o inline:"testgroup2:*:1003:\n" -x pw -V${HOME} groupshow testgroup2 - atf_check -s exit:0 -x pw -V ${HOME} usermod testuser -G testgroup2 - atf_check -o inline:"testuser:*:1001:\n" -x pw -V ${HOME} groupshow testuser - atf_check -o inline:"testgroup:*:1002:\n" -x pw -V ${HOME} groupshow testgroup - atf_check -o inline:"testgroup2:*:1003:testuser\n" -x pw -V ${HOME} groupshow testgroup2 + atf_check -s exit:0 -x ${PW} useradd testuser + atf_check -s exit:0 -x ${PW} groupadd testgroup + atf_check -s exit:0 -x ${PW} groupadd testgroup2 + atf_check -s exit:0 -x ${PW} usermod testuser -G testgroup + atf_check -o inline:"testuser:*:1001:\n" -x ${PW} groupshow testuser + atf_check -o inline:"testgroup:*:1002:testuser\n" -x ${PW} groupshow testgroup + atf_check -o inline:"testgroup2:*:1003:\n" -x ${PW} groupshow testgroup2 + atf_check -s exit:0 -x ${PW} usermod testuser -G testgroup2 + atf_check -o inline:"testuser:*:1001:\n" -x ${PW} groupshow testuser + atf_check -o inline:"testgroup:*:1002:\n" -x ${PW} groupshow testgroup + atf_check -o inline:"testgroup2:*:1003:testuser\n" -x ${PW} groupshow testgroup2 } atf_test_case do_not_duplicate_group_on_gid_change @@ -65,8 +65,8 @@ do_not_duplicate_group_on_gid_change_head() { do_not_duplicate_group_on_gid_change_body() { populate_etc_skel - atf_check -s exit:0 -x pw -V ${HOME} groupadd testgroup - atf_check -s exit:0 -x pw -V ${HOME} groupmod testgroup -g 12345 + atf_check -s exit:0 -x ${PW} groupadd testgroup + atf_check -s exit:0 -x ${PW} groupmod testgroup -g 12345 # use grep to see if the entry has not be duplicated atf_check -o inline:"testgroup:*:12345:\n" -s exit:0 -x grep "^testgroup" ${HOME}/group } diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index cea8533d463..71ba63b4698 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -910,8 +911,16 @@ main(int argc, char **argv) { char title[64], prompt[128]; int c, fd, rv, skiputc; + char vm_guest[16] = ""; + size_t len = sizeof(vm_guest); skiputc = 0; + + /* Default skiputc to 1 for VM guests */ + if (sysctlbyname("kern.vm_guest", vm_guest, &len, NULL, 0) == 0 && + strcmp(vm_guest, "none") != 0) + skiputc = 1; + while ((c = getopt(argc, argv, "C:nrs")) != -1) { switch(c) { case 'C': diff --git a/usr.sbin/usbconfig/dump.c b/usr.sbin/usbconfig/dump.c index 52dd132095d..df5cde0c546 100644 --- a/usr.sbin/usbconfig/dump.c +++ b/usr.sbin/usbconfig/dump.c @@ -110,7 +110,6 @@ dump_field(struct libusb20_device *pdev, const char *plevel, printf(" \n"); return; } - if (strcmp(field, "bmAttributes") == 0) { switch (value & 0x03) { case 0: @@ -142,7 +141,6 @@ dump_field(struct libusb20_device *pdev, const char *plevel, return; } } - if ((field[0] == 'i') && (field[1] != 'd')) { /* Indirect String Descriptor */ if (value == 0) { @@ -157,7 +155,84 @@ dump_field(struct libusb20_device *pdev, const char *plevel, printf(" <%s>\n", temp_string); return; } + if (strlen(plevel) == 2 || strlen(plevel) == 6) { + /* Device and Interface Descriptor class codes */ + + if (strcmp(field, "bInterfaceClass") == 0 || + strcmp(field, "bDeviceClass") == 0) { + + switch (value) { + case 0x00: + printf(" \n"); + break; + case 0x01: + printf("