diff --git a/MAINTAINERS b/MAINTAINERS index 98fa63d98f9f..29236caf6b25 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 07050ef0c56a..8cbd58f5afc2 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 c8072d446059..be0b7c90924c 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 41e036fa8e8e..b9a7b3552fb9 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 c770aca07d59..fa6872017ca3 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 c2c47d511c03..47ab7bf9a1db 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 2315e056aaf4..e37b14868e96 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 a3b461e1159c..baac993a0df7 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 27e63a9438f4..d855f168cc60 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 dce1cb3d765b..d99d8014f049 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 5ed87ce13717..ab69154b8d19 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 54426834d501..0b531c5e6883 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 0f1bfe07b7b1..6acb86b155ba 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 af4ec33dcb9a..2752baae32da 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 ef18b457e056..8a707d1f795c 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 265038ab1bf9..063df4a3c234 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 97f18d7bb223..91857b65a8d6 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 cb38dc2d1282..52bd580c47df 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 99883fecc133..b6a4c12f2500 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 d4036d03b0ce..26d9f364b099 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 55ce7b2e2de5..5dfeab3c0bea 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 2ef37d460b36..d366f3182731 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 762dfa182e2d..ac7240d31140 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 7a5f925f9149..22967c81c9e0 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 dc82b8e25673..dbd52a186c56 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 d13bc1afb68a..db5d367689db 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 43291db28c4d..94c86b0b78c6 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 e72fa8421c4e..428375dbf443 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 38d3e5866b38..a52d316a4184 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 9296aa5b1e24..d394ad808498 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 da0c4be7a221..d211255b8528 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 a3b450960efc..ec244c99ea6e 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 ebb065f4589a..46e5d2e35253 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 784a45ffe908..5afd3d135d85 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 fb7b06c40cf3..5b7bef787fa0 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 85ea1ba908e1..690daefa3f3a 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 e7aa39508c42..df363825fc2d 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 e78f1881512c..8dc8cf933b80 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 94d67d93bd93..0446ec57c6b5 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 911db408e31a..3505bc4ffdca 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 0184e924fabd..41effc1176b2 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 9d4d7bd5835d..caab24811023 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 affdbe56db35..b01685245c19 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 47b8fd0d3b15..16de64b65523 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 cdf8171f02e4..f03cfb636c03 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 b91c1a14a022..f85e6754a4d0 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 ad4fe1ae6bf3..59739980ce4a 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 4d1e3d4376f3..643567605ac6 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 a5f047ec8d3e..b8dff595c914 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 5202074113c3..6bdd4a4b2c6a 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 49a1527817c7..6094f8b28cb6 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 b0a84d411095..1c31d3f9b626 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 40c162b0875a..e9b3b4bd093e 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 2412d12cf0a9..904af12bf687 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 ebe55b9e4fd4..89adc03fe2f5 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 7a6dbe8b78b6..0870e3587209 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 51da744036e1..60c6118be935 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 a87fcc55adcb..a5470f375478 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 2c9a9286f20e..9285ff5a6c5e 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 b502650596d9..c13f838c85f4 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 3ceba8edf6ac..18b7baa146b3 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 8693e62bff8d..427edf7aa95d 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 82becca315a1..9e1115b117ce 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 45d5a4fa69e8..00ffe00d407a 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 000000000000..f70ddcef8940 --- /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 e99824956947..5bbf337efd9e 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 bb3baf013420..1f3998404f3d 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 1611bfa02644..198148c6937c 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 eec2d1033322..5836c8629162 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 a0e912be6fb2..10b8df7ccb7f 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 120981f84666..d6f888fde127 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 a93083a17f69..f51eb2a9d893 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 6dc79531b6e5..9c9a3c743c0b 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 21e625ffcf24..790f3caada48 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 80f5c17c1cb3..bb9d26420c3c 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 7cab9739797b..8b3876fa7882 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 7395d19bf17b..f8c06d394d68 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 bb690607fa0e..7816260e9281 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 fe7b468eb622..8d1ef33a1a2d 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 06016bf31f62..3405e9761017 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 999aa4070e2c..2a9106072386 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 55655eb8cd9e..f1d2b15de633 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 bc34441fe4c7..0670e514e7e1 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 fb8f2855f985..0ca44b47577e 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 d3e1f113abab..c0641dbc6bf7 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 58ecd9639cd2..ec2b9bbf3d52 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 f5ded273de49..2293e2cc9576 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 3b0b8850b580..5a8fa2822429 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 3c869c4f0b96..d66596747f3a 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 c9e52a379a2d..192a4e81f7ed 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 cb008d79ce80..888a8261f8d5 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 0bd6a262e17a..b8b399e7ee20 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 37a426707a69..229c343c7a8b 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 12628c239009..7dedca445288 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 669c7042ff03..85eeac6bee0c 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 5578adcdd489..fe298c552825 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 1de1e874f695..d7c7d9e02d4f 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 ce68336bd328..70f890682a76 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 fddf5eb3967f..d30cb7b97f26 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 1712d813a5d9..b4d9f8a809eb 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 f09228710521..8208cf79231f 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 805773dc948f..621448638372 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 fe59cac09568..926d27406aa2 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 ac7d3ad1be77..6686f022b131 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 e96d7721926f..5e1d17e28e78 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 168bad72c414..cc853073ff45 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 e73e2f4ca026..8d9466881cba 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 d7a06e0fe46a..a3783cb5deee 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 7808891b6407..99871ffdc4b6 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 373528beef87..6c913a4a4c5a 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 1ebbe7dfe21a..a268068b72af 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 b5d1728b64eb..1982a9bcc76b 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 028f398fdae6..db0ff16f504a 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 a85ce9b7215c..841b2bf712e3 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 8a82689221b0..a5e78ffab977 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 a7de9f629815..b19413a01241 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 6d410972d77c..7a8e9f804366 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 62b7235e7640..a8ae6f0f62fa 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 777666f297fb..c01debac5d0b 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 586c2c3bc621..2d186cf1df82 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 2d4c91c60bd3..29b8775681c8 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 1077806c77f8..b7a93630bd40 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 9b79587104cf..17bbb89df76e 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 21db871a70da..8922d5a1e93c 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 ab8806d25641..a58c1a6be5dd 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 7f6f8348acfa..71b6775c30ca 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 b5b07b31b4f0..eb371fabd883 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 575d5d7ef890..e87907721a61 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 a4e03ae9c605..5bb7ae7264dd 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 b6fc4dbf197b..e76cd521559d 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 9bbfab1caa14..44f12327cb96 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 26f75fb31303..b028a1df794d 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 000000000000..c422535cf8a0 --- /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 c39b18744cae..74cce6d5dedc 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 e07aebbdb828..d42bddd4cd09 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 f6eb1ffb08ef..1ddec8256a07 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 9fba74feada9..32f84bf85e49 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 2dce4c51dd55..f55c62e87296 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 8c457cf613d2..80f43b2fc0af 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 191d311fd154..4db5292e49d8 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 5a9421b1b150..bdc43f6e1a26 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 b17c62b7e31a..1b9bf50da22c 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 37b2c88e0ed1..1a2bd12ad2a2 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 8efe56fd2a24..911e68176a2e 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 27a8b30ea3ea..5e78c549981f 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 07f527fe9b7e..c91430c0337d 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 e2466461dd34..bdc29c214ed6 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 79799bf91654..1422390e978d 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 7f066cdf5ad7..9a84542d0905 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 ae377acedc16..8604c55932b5 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 520c9e86a7e5..b8e06544ff90 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 bfa22bfcfd09..f26c190fe9dd 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 c86150f85ff0..12dd3b0d71b5 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 4c3b34021d8c..93e68a20ab07 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 ea54c83ac0cd..8e87775ffb98 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 4790ebd0a572..000000000000 --- 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 9cb07e576980..b38147153b0a 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 1a32d8a125ab..379861b0cadb 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 02c99182fcfc..6d206d5ab1a0 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 b4c1a33ddff4..c50374e7287a 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 ffd34a137ec2..005b8773bfc1 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 07a453779677..c14b35111e78 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 fe887c3ddd57..448bcce26753 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 932186d7fb84..a1c7ada4ff36 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 39e8838942a7..f9a0bd42b6dd 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 eb3d88c0e8ce..ec82c3272d2a 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 000000000000..a6bb1df3c9f2 --- /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 3512dd954081..23d5c1ef8664 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 9f636640a1a2..d137780f1ce1 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 9b641c1dfc81..523a74eacb80 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 f624cf7b1d50..bd6ec0717d91 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 000000000000..dd0f5b0cfb2d --- /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 000000000000..dd0f5b0cfb2d --- /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 000000000000..224f52ea85aa --- /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 cfcc41efb997..5cbd0aa3144b 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 000000000000..dd0f5b0cfb2d --- /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 000000000000..dd0f5b0cfb2d --- /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 000000000000..50f07f07e008 --- /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 000000000000..0764bfa15936 --- /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 000000000000..080dec941a8c --- /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 e8277676818c..aee0f2d03315 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 000000000000..dd0f5b0cfb2d --- /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 000000000000..dd0f5b0cfb2d --- /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 000000000000..4261e4865b52 --- /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 304479f1caac..ddef1a87251e 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 690b03c7ff95..07de1970471e 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 47f889632650..bc1185d61c64 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 2b4cdabec3c8..16b175385b0a 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 4129cf4c2724..cdb379dc6d24 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 71937679edfc..0578287f0256 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 b6baa95ab8c8..3dca2126a7ab 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 8c15c2143e1e..5d23d933ec94 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 0dab89f35943..42dc530a1970 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 f8b18b4a9835..e3f271d4429f 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 d860423f4719..690dfcd436e2 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 8b64be28d384..82edc46690d1 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 000fbe9c1874..5e6f78b4e017 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 604057d147d7..53ec2986341a 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 346f2972e735..76b3d55c2c61 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 8196c43b5840..17cf1cbab65b 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 fecb7a54583b..eddba6cc4e70 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 f0a2df6f6c3c..000000000000 --- 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 0b7a108db52c..b0b5a9ee30e7 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 93015e0551be..815dee7c0385 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 fcd396c1e7d4..dba5e8de5396 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 50491fb2f270..85801f2cf5ed 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 f710a64eae3a..a391e086d6c5 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 be4aad9b9ccb..9d2854c9567d 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 6cbccf3d966f..5c3d6e62a616 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 c30ad573e651..b855f1388da2 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 721fef01c1c2..09583ec10423 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 9cba8961d168..76d4f62f630d 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 d51eea2dc689..d84e4a23c626 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 52181a278775..c4884eb1a8ae 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 000000000000..68689eeeb848 --- /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 51474376319e..a7e7683a5144 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 c6b689d84c61..f0acf16772d3 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 0dbd26b347e7..c696f4c811ad 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 1e2344f2dd29..486914bc19bf 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 e4f71045ab21..340950a3cdd2 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 cb493c96475a..87c0f9998cd7 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 4ff4fc804e80..f69182045e66 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 fceccd218638..aff685b2797b 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 29e698006fac..6a4077c59a59 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 069cf8c7b17c..f8b75ffdc2e5 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 f8ccd4cba5bd..c8d509849b5f 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 ce8dce4d622a..d5652c4a7043 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 b1b89b98d8f4..58cd694d6fdf 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 a5321062cc78..23bf399d3dc3 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 6a08819e4ae1..05bc5863cdd1 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 9e15f8bc2858..f1bb014b2ed6 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 a2db9f023fed..301e0a63306d 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 4c6976525eea..58fa09e1acd4 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 5c3c2580cbe8..a53495765c8d 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 a8903ee82eab..0ade78fd53ab 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 0571c55208b3..051593abb660 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 a92ddba11c76..9f3c27b7b625 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 6cc6fb4c8eff..615e06e4af59 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 c95a5974961a..a3c57a121773 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 3bfdd913ef6d..736959299476 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 df7a9efc7ba9..677d73d9edc2 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 9df7f9c55aaf..88f9949059e0 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 1396578e3e58..5fd56979fbf6 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 88a6462b617b..007862bc6d1f 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 34b64afd234b..c3cba33f8b7d 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 d8fef824394e..3b7139c9dd10 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 b36548943210..c23f75be3f7c 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 3c192ead291b..abcb01474dcf 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 e5d5085bf0e0..7786b76e0a4f 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 b83a877c56b9..a31ff782aacf 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 0767e7324953..d7f804fa26de 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 44c22cb20891..d62efc4ca2fb 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 fc24947c6562..5c7dc992be0e 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 d00eddca5589..c28ebb1c68e3 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 983e6f807617..5fb72b7a3907 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 eb0c880214d3..612ceb9a947a 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 b479ee552249..8f9af0c7a057 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 766db9deacc5..7a9e42f4f07c 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 ef531e142e51..2869f1b5d668 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 6224503f7542..526c5465f195 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 5fb5788028cb..f7080dc93d63 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 48f970d7f4bd..4a2d1e94ff4c 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 baa34838f842..7a773db65636 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 04a7dbe0c34b..62ae7471420e 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 b955338296b8..623346d6016d 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 00b0d4acf0e3..ad38660843cd 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 00b0d4acf0e3..ad38660843cd 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 2a5346aa7b43..39c853b4ec6f 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 00b0d4acf0e3..ad38660843cd 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 00b0d4acf0e3..ad38660843cd 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 00b0d4acf0e3..ad38660843cd 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 00b0d4acf0e3..ad38660843cd 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 241b14aaf973..bd7d296e9840 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 ac19751bd7e5..fda6fd25a07e 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 ce80cefd1aac..d05cd13f9b20 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 16b57c7a6150..8d21c5714302 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 b50caad470ce..cd0111416b9a 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 0180cecff261..fedc11001e96 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 297b6c5b7ef8..408b86a21fc7 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 959eda9125a8..abe7e2ed1671 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 ea0cfae2c559..6ee03705c753 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 8ca669e015eb..0c91e515b277 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 2cca8ae4f346..8d82eff66343 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 5677cdde125f..3c087455bce3 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 5f2e255e7707..730cdf49a0dd 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 4e5b1c92f44c..22256cf1f1e5 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 65d285893e94..52a355d0a545 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 65016f1b5e2d..4ffe435ab68c 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 bd023c70ef47..dda72de8737e 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 a400f821e2e2..4d906b02bc02 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 b4ab0aff5a88..3a455d73899c 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 b19df1af3967..05c40e38a744 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 c724ed074103..5f7d76f0e2ad 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 c9ea6c02a13e..0b9a0b92434a 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 73b8e056cc8c..e7aeed17fb9d 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 1a0cab5d1cd8..00d4f3e73e2a 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 ed9757ecd457..b97040ae870a 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 0b19e76343f0..b39f6b11d26f 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 a3efe9293cb3..f11fa65bcf3d 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 4f39c397a064..8c8e3746eecb 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 f8a4546535e4..1237641583a1 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 53371e642294..08e79ca5b8af 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 c2bcbfd0ccc7..9e53f08a6806 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 5d8c731c886c..84b39dd02929 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 2cdfeb0f2442..9c62669e9b0a 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 83e521765ac0..9fc7a463c653 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 c3a42d026b60..b51dd9791f3a 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 ad1926646871..d85d872f89da 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 23d88fd048bd..804f0c182b6f 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 b5d617025bd0..b03cb0976e6d 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 d9552b2260af..ff90f8b439cc 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 f62e3151f871..a5f32e837be0 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 642a4c05d64e..e7515d5ae773 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 1dc322e02f6f..29ebae53849d 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 73fbf3c9c0ea..71ca04401341 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 dae099b7915b..3fb66c864ee9 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 15ef2aa8bf98..895d632a2620 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 58566203b697..b5c666c02b73 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 df7edf4c1c65..17ca65b7520f 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 5c52042a0149..621f47c8c6bd 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 dea1a8fa7bf1..a9cd4f0de199 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 1caff2c554c6..c397891d4857 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 ab492d80640a..01ef7563eb2a 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 b28125ef60b0..848340ce823e 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 70c186f8d2a9..966f2fa364b1 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 2fefa609ac0c..60d221a08de8 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 fec0037b2b1c..24a44a697769 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 395ea29ff187..962e01d6ee5d 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 925aaea79f35..6b538cf56d61 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 4e88a53fe2f9..4ed8aac29851 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 5f42c79223f5..5595348e9e10 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 3029f7dc4c74..7432290d218c 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 ea17daf81f93..15d34df9a0bd 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 5fec709c9bb3..46d0b6de9fb1 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 d92597e4b0e8..f92ddd446b89 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 c26e53cea635..2084d88ff685 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 3586f8723bd7..70ee9a6a1cb7 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 23480cc57160..1776ed311140 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 87d0650badd5..16d528e025d5 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 de16611af95e..ace71ae74155 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 5ea062ea3686..24c573813535 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 d426e19aafab..5fe4872ffec8 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 e627ff3d0749..069a69b1b881 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 2bf45ea4c3d8..5de34d163335 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 9735e30973bc..a401167ce248 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 db03855862ff..4d4d58d36c1e 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 2fafc0c48875..5d445a57e315 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 e56e61f24b7a..88303b92c9be 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 ff5e8a25a487..4433e186afa6 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 43b255d0dd69..61b786fef9fb 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 2e05c8543c39..b6dd86dd6ad4 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 c5bf2ddb4f79..61f3030049e6 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 c604675285f9..edcfcc1074ee 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 0db5453165f3..9e9b020a832f 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 b6866425d54c..6ed9873e7759 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 91c393f71a28..d287d5d3271d 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 45b38d9a69fa..1436a3bc1665 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 adafa9c5907f..cf40cf2b1e34 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 8c7a0baac5d4..16bb13447a71 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 f323a0da664c..9b3b84b06186 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 df6d15079f05..7a5d0d924b8a 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 75ce17db89fa..0776eda9e4f0 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 187177b39fff..bf7b4d14e6a3 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 122bf52d6ce2..e5f596ac75f8 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 71fbe3226b6a..0e8998b09496 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 9afd201d2054..0db332bbec92 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 000000000000..af610ef25ea5 --- /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 27ad6515c0fb..710276fc8160 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 000000000000..644afd622ba7 --- /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 af686f038b97..ab4f15e10825 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 000000000000..41c50f8f8442 --- /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 7c8d49cde4fe..d996449ef5a2 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 ba89e559cdb8..046aa7d9430c 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 1d3f0db1c3ad..6a96c9c486e6 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 d17af2358464..444d9f75b108 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 a6b8b1551989..7d92526125eb 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 052542ea2d26..10ce2d891200 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 4d1a74d05605..fc79aefa4a63 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 6a998dd6673e..413da4dbc27e 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 7a88462a2c5b..820354ab696f 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 d81f45ee8e89..2d5d79d752f0 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 81d7df2466d1..f417abb6a7ef 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 2690edd1e6f1..95fc7b1eae63 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 51b9129bbdef..59ca453066fc 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 eb4ed4b205c2..e1c8b0008156 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 3a3d2a938c01..a3c4482e668a 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 b47f16981b34..a997b824a8fa 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 475845b27a98..f9caf2eec1d8 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 9af2248dede4..29e5fa243be5 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 3691a3b516dc..89585cf83039 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 b09feac94719..000000000000 --- 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 529bac34f460..d303dfa47bc2 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 9d0c0f038ba7..117e7de7adcc 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 474fb00e22a9..0a0dd84989a9 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 4d6dfd17a5d7..f0ead651ce8c 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 68adab05d5df..efff2c0b5f59 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 47c0b6b725ae..a1c2be0461ba 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 156f05c2b196..2fad4dffb286 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 1b03e9f13239..225e905855ce 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 42dd66cee064..f1506d63093e 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 d919277c12eb..dc567604be95 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 54fe9804eb2d..b5905ad8bc31 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 c57fac584216..120b5e702dea 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 1090042ff511..b2ebad8dad67 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 de7b641257e9..40debb518ed3 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 94b18ddffaef..65088d07de89 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 ec54d49b4cb0..42e1c815cc3c 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 4de98ce7475e..7ef3ba7beb43 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 1b32164d9065..9ae4812b65f8 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 df917ed3729a..efffb32eda54 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 f56e494fea7e..6bce18020425 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 979426084dda..29960d75936f 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 81dcd8d09193..812385ea2cf1 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 78fdb36b72ba..df47b3db0b0c 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 966acc2e598e..4d2acd145ca6 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 8b71f105977d..92e8adb57192 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 adfd4a4f4191..71e45d0b0bd2 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 a58b21b8f08e..1ea371a62a9b 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 7413fa40e9eb..6bec8ebe6a45 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 3bbded420836..836268281e48 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 72df5868fcdf..23c207a1a556 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 85e3330dacde..d92702fac1e7 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 f37bf9e81c45..9369f6cf2a24 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 160b7c0ef955..322670814553 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 774038206b12..ecdb36824077 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 76d893588e34..95b3a5deda69 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 485c370d91e2..746abb524d06 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 bc998c04a17e..64828670c35b 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 dae2bd6403ac..5cda44e5328f 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 08ed66f5fd10..a235c22fde04 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 ec4fd4424f14..ed8a981d158e 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 f836147a773c..c8966df8ac4b 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 1574f6e9674a..f6d1be58612f 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 b724d05e0423..08ff42772ee3 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 485f7289c964..d2ac111372ea 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 8ed8fed3b8ec..4cc579636ec5 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 e48b1c2f8812..084d32ce0158 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 f8b3e0c32aab..6f6febbe2b23 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 7deee8781917..844e423422a3 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 57c0c6dfd81c..d49de3aff010 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 bbc4e78e7402..71a61f4d8d4a 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 520ca80f9301..5027694d54ec 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 e7b98325bd01..3479ab7c020d 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 c8960eb5dc2b..c5a8cac7b079 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 f7f28aa6409c..fd5faf3d85c0 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 0175db6205cb..3959d646c9fa 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 082d0d8461af..78d5a01d0335 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 773a78be1fb6..ca6ef9563a14 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 26e6a20d79be..4479fa29de5b 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 af61cfe54d50..e44a8b0e4df0 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 bca458fb3774..a10c001b07ec 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 4c8fb4c5910a..0ff2e62212a2 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 5c88ecdaa59e..8c686d673563 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 9ad698faf89f..06a454b8e776 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 42265a4ebbe4..6a9219eb3035 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 65ecf760f49b..6cda04360f0e 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 3253cd14a2e0..2e5ac8cab178 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 8e5f6a4f28c6..5ec9cdc63ae7 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 4808c0f9f290..a199c290f426 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 a089e3fe78b2..b15cb75a3f40 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 000000000000..d1838ef8d4ae --- /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 04dee3801a5e..30e028630f66 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 000000000000..51511fabe5c7 --- /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 1310f30bc239..83cb2d79fe25 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 3ea5b29b3a6c..4a0caf4f0f7b 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 978000710573..23835c6079b2 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 e883b782b046..77a24cc12bdf 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 201e5d632cea..a749f90c1546 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 5edac90e03d6..93bd3f7cd0f6 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 cce03d8d1659..b69d4e5c8b6e 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 b05070d32610..b97356d072ac 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 e882bb83c6e5..93d77336ed7e 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 9332c6b27061..2f29fe32c87a 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 7cb756befb8f..6380e407f0e0 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 9a1730b0e702..58082367b037 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 5a5eabd31937..e9f09c2108f2 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 4152e87fb02a..31c1d657ed9d 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 b01af819398e..889a20a7fe30 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 fb6a5c1570f0..73f81e44cc60 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 62bbbb6ba3f5..108224cd5570 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 851372430e0f..68b44e955a11 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 d2489dfb996e..5d06d4d32e9b 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 42bc4b775794..d81cfeeb97f9 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 f688661ded5a..b49e605eb232 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 c1097a320a5e..55d14af99b52 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 c5416fb6c52b..829f6abba814 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 975b30231b62..5dc56692adc8 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 70c1cc15b826..89ebb57e469f 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 b67046e50ab5..7e6768463213 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 9246904f1cf5..a065b75bfda0 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 3decfd412ad3..f85703e4e81a 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 3d232cf744c5..79a294d37e3d 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 9b7aeaae38a7..bbc0e5170923 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 32c837c57c1a..227a531f34fd 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 55bffe77a9a6..e01f12c7d1b2 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 8135afba7e28..62f43ba743b2 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 3fc151db298b..36a8470d2971 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 467ae1cf5cfb..d9849081396e 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 dfdca15194aa..357099b59b09 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 33fdf71e5ebe..5b42c6fd118a 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 efd66b274ea5..cedfc1b3d1db 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 1cd1287d2576..01996155e4cc 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 47cedfeab4b8..dd831ae81a66 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 276c34af38bc..92780c3b4ad4 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 35c05f0f62e8..e0f8b61e154f 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 ce2be6d1fd7a..d5fcdc4eb3d1 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 c74343b8f812..01e48b55aac0 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 706632716b1f..240421f694b2 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 6d423ba5106e..b0d849d93c80 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 11b27d93d115..00fd8099c2e4 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 2816e1ba8c78..a050099737aa 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 04c1c7bade15..2bcf85d352c9 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 b3e1c3bf45cf..ee45e01aecfe 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 5758d249980b..268ffbe4fe77 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 0e1633229cb2..45ac8ffda2ed 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 26b42eaca87c..36868481a996 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 ea5862287ccc..fa0b9b51899e 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 6bd756f20f7d..27854c5fa2a8 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 fc082ad994a5..4a0684db106f 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 0f5bfdf4c4e2..53c629859d6b 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 fb417cfccc0c..9f22030c1709 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 8318bede5920..3fd75df93e7b 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 53b966c0a345..baf303925108 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 be8414f8fc32..d3515807c6e4 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 1a1d374f0ee1..70a1db380421 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 823391cf9331..ac104c2cfd2a 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 c31cd5b5a82a..b53bde801b40 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 a587446a8db2..f9fb590eb1be 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 df5efc02033a..a4405ae5941f 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 048321a30ad9..86895b6a2f5c 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 5f7defbcc4e5..a5d72549bd03 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 0ca6f63df72c..fedc92e362c4 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 64eecaf367fd..0316cce28157 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 15019e090011..21b3b08ea397 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 2a10b34ddd03..9a6e76d31891 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 fe78ec9be48c..000000000000 --- 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 af8c3c72fea9..663c679f4631 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 54ef274419a1..b1d370a47ced 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 7a53f3e4bb07..66fc0e652bb1 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 0ab82851d6f9..63103e9fa6f9 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 d4e52dc0f03e..ba6b1181ad53 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 abbda41199d7..09f8d2a613bf 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 90d9b7b18a15..67ec8046dffc 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 19b3da2a00c1..73ad3eb27e1a 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 80a5606ba8a1..c9b20db719ee 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 2d4751ec27b8..2e6daa319ab4 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 b24087435da2..ed4753ecfe45 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 5faf671b8976..aab6c358de73 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 a08f6c56f76c..36c1d4fc8d97 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 ce0674925c92..88835d6a8cc1 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 bab8bbbbdd85..d2e04879a9f9 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 cb3753d4bf04..a2190c78a618 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 f0d87b3940b7..9ff0cebabb88 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 ec2b4cfb804f..85214d6d93ca 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 41e442c4fa7f..33734c717a62 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 4776278e1b17..1f79761e7ebd 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 c1f71071488b..6b509d56daca 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 185bcfb2d06e..04ed0b0bdf83 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 6a2e2619ddb2..a794b556de35 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 98020d117dba..8cdbe21d401f 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 59c430fc3995..d9430a9a150f 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 de10923dbf58..3844e4965871 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 a58e7672bf0d..5dab7314ef1d 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 e0ead4cf82bf..6bf0a6a5e523 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 9d2ca50232fe..d65564f990fa 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 f6183b9124ec..468f14210565 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 968b8d28249f..6929c86687f5 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 1a50a4fe05dd..e23c546dd17e 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 4353b7750e70..0bf5be4ec96f 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 dd0889613580..92d07155bcb9 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 2e3bf5852b98..d6036463b3ab 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 322344f8e43e..1f1017e087dc 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 c241d45167c8..9ddd89ef74d4 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 bffdb8f4c130..03c668e13be9 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 243bae13fb68..89a7fea32b39 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 3798636696e3..4d328d282ec3 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 d6b31347d593..232c133143dd 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 9ef6e8726b19..3da35c052d27 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 f985108f2112..cdc8ce686aca 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 e3e67816aadf..3e6d4df71ac1 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 67d3f4e50dfe..07199019d968 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 018f2ccf818c..6a2d86a270f7 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 016a918d3060..fd13aee79b11 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 138fdf33161d..1ca7278980a9 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 2cb9400cc58f..60080f3c986b 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 63c0b0eb254e..ffec9a317294 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 15f9230be23c..08847e57b0af 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 419e6b161461..d3c6445e7ca6 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 a2393ec51202..037127eef689 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 11a97c55ba76..b151273ee006 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 b0fa0f29aac5..06364a3ab38f 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 a64e3f2d5d2b..4b4d9ccbb41d 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 830521ac2b13..591c44f92972 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 b88c5dbfd00c..ddb73e7f155e 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 9f0934c78d8b..104fc0489763 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 dba56745fae8..213e49cb52f5 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 910424dd768d..a6eba64e1622 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 f8d6181c0ede..1fe5cb060fa9 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 ea89d3258749..299606aa827a 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 0d11ac8cf907..56ca7155ddd0 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 688912eb26b0..bedf1f1962c4 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 dfd5a61945dd..d1ee43c9cf73 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 3ce6e3cdbd5e..3e4d72f6581b 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 e4d61b253521..8e21f2a0d50b 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 938ca74824c7..9df83cbf7bcf 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 98209f8912e2..21c56160b62d 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 2462308b64cc..f18554ab2a45 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 b9ecccb39809..e6d76b8c2ab1 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 67ad58f5cd1b..3899511990a6 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 df1d86e045cd..0190a0ce3834 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 306f1dad24bb..0f9aa1bc1eed 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 8c50581cb1ca..9d73d59a078c 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 c712f76ac34c..089c9b3874f0 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 e593d4326240..d102a871ee39 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 3b8f7ebb335a..9cef6aa5a0d9 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 7bd75e4c6ce1..1afd4ea3e920 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 c955f321c752..ca3ce12873c6 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 ba45f946196f..2d98a4c25edd 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 ef80e9c14571..f9e8da4cde0b 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 cc43fa21dc09..18e2de10e101 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 bfdae0d07163..dfeeede33bb2 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 576b420fff90..b9b5fe4ea2a3 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 47d204612ee5..b411627ae0ea 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 7098c43445a4..5e6121040352 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 3d203aded0b8..0c8581668def 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 87b39f185699..b2877c11b5fa 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 e3d292d745af..a2342f8f14d5 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 be3d5be78079..95369a8dcb55 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 6d94e07fafad..74440468cd65 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 050f1b0a8196..2aeef7e585c8 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 ca6fa3b8863c..9ab3145b4fee 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 d0b76ad77cb1..d77cef267907 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 000000000000..8ccb2078d643 --- /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 4786a153605d..93798ebef81d 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 000000000000..805e99b67f1b --- /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 000000000000..2ecbdb72c006 --- /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 4cba5de551d2..f3a40e351d90 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 799c134efb7b..000000000000 --- 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 d0f8c266b21c..276adcb981ef 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 9f57f31d691d..59014aafd912 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 32b0b8ca1369..1d750e5e2bd6 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 fe911da613f6..3c0f0da6237e 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 ebe2c67552ca..1a32c60e027e 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 1c5569bee9a2..7c8c9a345e2d 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 ae7c9f6390bf..aba05c5bcfc5 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 f7159ad8a9b7..7e6da0edf1e0 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 aff67ea95efa..d04b0659c4e5 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 27467bbe185f..a27e32bd28f4 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 7517a64cb21c..ca497f32a25b 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 3e7c7d2945a5..be1c2e9fcbb2 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 bfe05c01cc09..56cd605db489 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 c6eef8561010..532e9307caab 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 059f7ce56028..effd0e304ae0 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 45e7929db00b..c110f3f59024 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 b0cff950bf2b..df9f8674793d 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 69d6afeac9d1..f7f369d4d733 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 755fa3356b34..a537c489728c 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 4986386de0b0..8687e9a39d3d 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 42010ab10bf0..bb41be300a0c 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 0452230441b4..66f2d7892286 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 635ab8cb0249..0678a7770bc2 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 6a6184bcc410..8e427b1c98e5 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 9cff3a82b422..aa9a414e1381 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 a480b2ec0431..bbf8e7d50641 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 e7b364240d1c..600bd30c4f23 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 c59cea01b5f9..fc41f5178d34 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 c801ce690764..a6519dd70337 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 822d1ac7e333..d4bf823b8b08 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 dec45b9645b0..000000000000 --- 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 6628bf63dcbc..000000000000 --- 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 93a835b9a97b..000000000000 --- 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 1745de1f6b1a..000000000000 --- 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 c578d46c4d2f..000000000000 --- 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 c54371a2c20e..000000000000 --- 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 bdb763ad6f5b..000000000000 --- 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 4d6b3d59c463..000000000000 --- 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 219769441471..000000000000 --- 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 682f540db98a..000000000000 --- 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 ee702e3a4f71..f586909caa3f 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 3a61aa53fe78..920dda21f334 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 eebcfea6f601..c48f33ca93ed 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 abc9a18d7e1e..62e39f5a6364 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 b0ac7285926d..ff48db7af169 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 fabf624f347f..6bc943370fbe 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 f87b1e7d9436..3680dfe608eb 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 0e9793913481..832ec932f644 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 000000000000..b237789ed457 --- /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 000000000000..9f14e24ae078 --- /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 b81f105d92be..ad7ad0a3b7cf 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 cea8533d4637..71ba63b46989 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 52dd132095dc..df5cde0c546b 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("