summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.inc115
-rw-r--r--ObsoleteFiles.inc31
-rw-r--r--UPDATING8
-rw-r--r--bin/sh/error.c26
-rw-r--r--bin/sh/error.h3
-rw-r--r--bin/sh/eval.c4
-rw-r--r--bin/sh/expand.c18
-rw-r--r--bin/sh/expand.h1
-rw-r--r--bin/sh/trap.c12
-rw-r--r--bin/sh/trap.h1
-rw-r--r--cddl/contrib/opensolaris/cmd/zpool/zpool_main.c98
-rw-r--r--cddl/contrib/opensolaris/lib/libdtrace/common/drti.c6
-rw-r--r--cddl/usr.bin/ctfconvert/ctfconvert.14
-rw-r--r--contrib/binutils/gas/expr.c21
-rw-r--r--contrib/binutils/gas/input-scrub.c2
-rw-r--r--contrib/binutils/gas/read.c23
-rw-r--r--contrib/bzip2/bzip2.11
-rw-r--r--contrib/ee/ee.12
-rw-r--r--contrib/elftoolchain/common/elfdefinitions.h2
-rw-r--r--contrib/elftoolchain/elfcopy/sections.c15
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_get_AT_name.31
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_get_arange_info.31
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_hasattr.31
-rw-r--r--contrib/elftoolchain/libdwarf/dwarf_whatattr.31
-rw-r--r--contrib/elftoolchain/libelf/elf.31
-rw-r--r--contrib/elftoolchain/readelf/readelf.c62
-rw-r--r--contrib/gcc/config/arm/arm.c2
-rw-r--r--contrib/libxo/libxo/libxo.c4
-rw-r--r--contrib/libxo/libxo/xo_create.32
-rw-r--r--contrib/libxo/libxo/xo_emit.32
-rw-r--r--contrib/libxo/libxo/xo_open_container.36
-rw-r--r--contrib/mdocml/INSTALL71
-rw-r--r--contrib/mdocml/LICENSE6
-rw-r--r--contrib/mdocml/Makefile113
-rw-r--r--contrib/mdocml/Makefile.depend16
-rw-r--r--contrib/mdocml/NEWS71
-rw-r--r--contrib/mdocml/TODO55
-rw-r--r--contrib/mdocml/compat_fts.c47
-rw-r--r--contrib/mdocml/compat_reallocarray.c10
-rw-r--r--contrib/mdocml/compat_strcasestr.c3
-rw-r--r--contrib/mdocml/compat_strsep.c3
-rw-r--r--contrib/mdocml/config.h7
-rwxr-xr-xcontrib/mdocml/configure33
-rw-r--r--contrib/mdocml/configure.local.example32
-rw-r--r--contrib/mdocml/example.style.css11
-rw-r--r--contrib/mdocml/html.c6
-rw-r--r--contrib/mdocml/html.h14
-rw-r--r--contrib/mdocml/libman.h6
-rw-r--r--contrib/mdocml/libmandoc.h11
-rw-r--r--contrib/mdocml/libmdoc.h6
-rw-r--r--contrib/mdocml/libroff.h10
-rw-r--r--contrib/mdocml/main.c70
-rw-r--r--contrib/mdocml/main.h12
-rw-r--r--contrib/mdocml/man.h6
-rw-r--r--contrib/mdocml/man_hash.c3
-rw-r--r--contrib/mdocml/man_html.c20
-rw-r--r--contrib/mdocml/man_term.c46
-rw-r--r--contrib/mdocml/mandoc.131
-rw-r--r--contrib/mdocml/mandoc.h14
-rw-r--r--contrib/mdocml/mandoc_aux.h6
-rw-r--r--contrib/mdocml/mandoc_headers.3511
-rw-r--r--contrib/mdocml/mandocdb.c413
-rw-r--r--contrib/mdocml/manpath.h6
-rw-r--r--contrib/mdocml/mansearch.36
-rw-r--r--contrib/mdocml/mansearch.c6
-rw-r--r--contrib/mdocml/mansearch.h8
-rw-r--r--contrib/mdocml/mansearch_const.c3
-rw-r--r--contrib/mdocml/mdoc.718
-rw-r--r--contrib/mdocml/mdoc.h6
-rw-r--r--contrib/mdocml/mdoc_html.c11
-rw-r--r--contrib/mdocml/mdoc_macro.c50
-rw-r--r--contrib/mdocml/mdoc_man.c5
-rw-r--r--contrib/mdocml/mdoc_term.c8
-rw-r--r--contrib/mdocml/mdoc_validate.c4
-rw-r--r--contrib/mdocml/msec.c3
-rw-r--r--contrib/mdocml/out.c4
-rw-r--r--contrib/mdocml/out.h12
-rw-r--r--contrib/mdocml/read.c9
-rw-r--r--contrib/mdocml/roff.710
-rw-r--r--contrib/mdocml/st.in5
-rw-r--r--contrib/mdocml/term.c6
-rw-r--r--contrib/mdocml/term.h18
-rw-r--r--contrib/mdocml/term_ps.c5
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c6
-rw-r--r--contrib/ntp/ntpd/ntp_config.c2
-rw-r--r--contrib/ntp/ntpd/ntp_control.c17
-rw-r--r--contrib/ntp/ntpd/ntp_crypto.c22
-rw-r--r--contrib/ntp/ntpd/ntp_proto.c1
-rw-r--r--contrib/ntp/util/ntp-keygen.c6
-rw-r--r--contrib/ofed/libibverbs/examples/Makefile28
-rw-r--r--contrib/ofed/libibverbs/examples/build/Makefile4
-rw-r--r--contrib/ofed/libibverbs/examples/build/Makefile.inc7
-rw-r--r--contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile9
-rw-r--r--contrib/ofed/libibverbs/examples/build/device_list/Makefile9
-rw-r--r--contrib/ofed/libibverbs/examples/build/devinfo/Makefile9
-rw-r--r--contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile9
-rw-r--r--contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile9
-rw-r--r--contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile9
-rw-r--r--contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile9
-rw-r--r--etc/hosts.allow18
-rw-r--r--etc/services2
-rw-r--r--gnu/lib/libssp/Makefile1
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_arm.c18
-rw-r--r--include/Makefile6
-rw-r--r--lib/Makefile5
-rw-r--r--lib/libbsnmp/libbsnmp/Makefile1
-rw-r--r--lib/libc/gen/cap_rights_get.32
-rw-r--r--lib/libc/gen/ftok.34
-rw-r--r--lib/libc/gen/ftw.310
-rw-r--r--lib/libc/gen/getcap.35
-rw-r--r--lib/libc/gen/posix_spawn.310
-rw-r--r--lib/libc/gen/scandir.36
-rw-r--r--lib/libc/iconv/iconvlist.34
-rw-r--r--lib/libc/locale/digittoint.32
-rw-r--r--lib/libc/locale/xlocale.32
-rw-r--r--lib/libc/net/getaddrinfo.34
-rw-r--r--lib/libc/net/sctp_recvmsg.34
-rw-r--r--lib/libc/net/sctp_send.32
-rw-r--r--lib/libc/posix1e/acl_set_flagset_np.32
-rw-r--r--lib/libc/regex/regcomp.c4
-rw-r--r--lib/libc/rpc/rpc.32
-rw-r--r--lib/libc/rpc/rpc_svc_reg.32
-rw-r--r--lib/libc/stdlib/atexit.34
-rw-r--r--lib/libc/stdlib/exit.32
-rw-r--r--lib/libc/string/strspn.32
-rw-r--r--lib/libc/sys/access.22
-rw-r--r--lib/libc/sys/getdirentries.25
-rw-r--r--lib/libc/sys/getrlimit.22
-rw-r--r--lib/libc/sys/poll.216
-rw-r--r--lib/libc/sys/posix_openpt.22
-rw-r--r--lib/libc/sys/procctl.22
-rw-r--r--lib/libc/sys/revoke.24
-rw-r--r--lib/libc/sys/sched_setscheduler.22
-rw-r--r--lib/libc/sys/sigwaitinfo.22
-rw-r--r--lib/libc/sys/vfork.22
-rw-r--r--lib/libdpv/dpv.34
-rw-r--r--lib/libmandoc/Makefile2
-rw-r--r--lib/libpam/modules/pam_guest/pam_guest.82
-rw-r--r--lib/libproc/proc_sym.c5
-rw-r--r--lib/librtld_db/librtld_db.34
-rw-r--r--lib/libstand/cd9660.c8
-rw-r--r--lib/libstand/ext2fs.c12
-rw-r--r--lib/libstand/nandfs.c2
-rw-r--r--lib/libstand/nfs.c4
-rw-r--r--lib/libstand/read.c2
-rw-r--r--lib/libstand/stand.h3
-rw-r--r--lib/libstand/tftp.c4
-rw-r--r--lib/libstand/twiddle.c21
-rw-r--r--lib/libstand/ufs.c14
-rw-r--r--lib/libstand/write.c2
-rw-r--r--lib/libusb/libusb20.32
-rw-r--r--lib/libutil/quotafile.34
-rw-r--r--lib/libxo/Makefile2
-rw-r--r--lib/msun/man/cexp.32
-rw-r--r--lib/msun/man/complex.32
-rw-r--r--lib/msun/man/csqrt.32
-rw-r--r--lib/msun/man/sin.32
-rw-r--r--lib/msun/src/math_private.h5
-rwxr-xr-xrelease/arm/release.sh8
-rw-r--r--sbin/dhclient/dhclient.conf.52
-rw-r--r--sbin/dhclient/dhclient.leases.52
-rw-r--r--sbin/ifconfig/ifconfig.82
-rw-r--r--sbin/iscontrol/iscontrol.84
-rw-r--r--sbin/mount/mount.82
-rw-r--r--sbin/mount_fusefs/mount_fusefs.84
-rw-r--r--sbin/newfs/newfs.84
-rw-r--r--share/man/man3/ATOMIC_VAR_INIT.32
-rw-r--r--share/man/man3/makedev.34
-rw-r--r--share/man/man3/pthread.322
-rw-r--r--share/man/man3/pthread_attr.32
-rw-r--r--share/man/man3/pthread_cond_init.34
-rw-r--r--share/man/man3/pthread_mutex_init.34
-rw-r--r--share/man/man3/pthread_mutexattr_getkind_np.36
-rw-r--r--share/man/man3/pthread_rwlock_init.34
-rw-r--r--share/man/man3/pthread_rwlockattr_getpshared.34
-rw-r--r--share/man/man3/pthread_rwlockattr_init.34
-rw-r--r--share/man/man3/pthread_rwlockattr_setpshared.34
-rw-r--r--share/man/man4/Makefile3
-rw-r--r--share/man/man4/altera_atse.42
-rw-r--r--share/man/man4/aout.42
-rw-r--r--share/man/man4/ata.44
-rw-r--r--share/man/man4/ath_ahb.42
-rw-r--r--share/man/man4/ath_pci.42
-rw-r--r--share/man/man4/audit.42
-rw-r--r--share/man/man4/bhyve.44
-rw-r--r--share/man/man4/carp.44
-rw-r--r--share/man/man4/ch.42
-rw-r--r--share/man/man4/crypto.41
-rw-r--r--share/man/man4/ehci.44
-rw-r--r--share/man/man4/geom.42
-rw-r--r--share/man/man4/gpib.4100
-rw-r--r--share/man/man4/gpioled.44
-rw-r--r--share/man/man4/hv_ata_pci_disengage.46
-rw-r--r--share/man/man4/hv_kvp.46
-rw-r--r--share/man/man4/hv_netvsc.46
-rw-r--r--share/man/man4/hv_storvsc.46
-rw-r--r--share/man/man4/hv_utils.44
-rw-r--r--share/man/man4/hv_vmbus.44
-rw-r--r--share/man/man4/igmp.46
-rw-r--r--share/man/man4/iicbus.48
-rw-r--r--share/man/man4/ip.44
-rw-r--r--share/man/man4/ip6.42
-rw-r--r--share/man/man4/ipheth.42
-rw-r--r--share/man/man4/ips.42
-rw-r--r--share/man/man4/iscsi_initiator.45
-rw-r--r--share/man/man4/isp.44
-rw-r--r--share/man/man4/ispfw.43
-rw-r--r--share/man/man4/iwi.42
-rw-r--r--share/man/man4/lagg.44
-rw-r--r--share/man/man4/man4.i386/glxsb.42
-rw-r--r--share/man/man4/man4.powerpc/smu.44
-rw-r--r--share/man/man4/man4.powerpc/snd_ai2s.44
-rw-r--r--share/man/man4/man4.powerpc/snd_davbus.44
-rw-r--r--share/man/man4/mmc.42
-rw-r--r--share/man/man4/mmcsd.42
-rw-r--r--share/man/man4/mod_cc.43
-rw-r--r--share/man/man4/mpr.42
-rw-r--r--share/man/man4/mpt.44
-rw-r--r--share/man/man4/mrsas.478
-rw-r--r--share/man/man4/multicast.48
-rw-r--r--share/man/man4/net80211.44
-rw-r--r--share/man/man4/netmap.496
-rw-r--r--share/man/man4/nfe.44
-rw-r--r--share/man/man4/ng_ether_echo.42
-rw-r--r--share/man/man4/ng_netflow.42
-rw-r--r--share/man/man4/nvram2env.42
-rw-r--r--share/man/man4/ohci.44
-rw-r--r--share/man/man4/pass.42
-rw-r--r--share/man/man4/pccbb.44
-rw-r--r--share/man/man4/pcii.497
-rw-r--r--share/man/man4/pflog.46
-rw-r--r--share/man/man4/pfsync.46
-rw-r--r--share/man/man4/pts.42
-rw-r--r--share/man/man4/ral.42
-rw-r--r--share/man/man4/rsu.42
-rw-r--r--share/man/man4/rum.42
-rw-r--r--share/man/man4/run.44
-rw-r--r--share/man/man4/sa.44
-rw-r--r--share/man/man4/send.46
-rw-r--r--share/man/man4/sfxge.42
-rw-r--r--share/man/man4/snd_hda.42
-rw-r--r--share/man/man4/snd_ich.44
-rw-r--r--share/man/man4/tap.42
-rw-r--r--share/man/man4/tnt4882.455
-rw-r--r--share/man/man4/tun.42
-rw-r--r--share/man/man4/uhci.44
-rw-r--r--share/man/man4/umass.44
-rw-r--r--share/man/man4/ural.44
-rw-r--r--share/man/man4/usfs.42
-rw-r--r--share/man/man4/virtio_console.42
-rw-r--r--share/man/man4/virtio_random.42
-rw-r--r--share/man/man4/vxlan.44
-rw-r--r--share/man/man4/wpi.42
-rw-r--r--share/man/man4/wsp.42
-rw-r--r--share/man/man5/periodic.conf.52
-rw-r--r--share/man/man5/pf.conf.52
-rw-r--r--share/man/man5/pf.os.56
-rw-r--r--share/man/man5/rc.conf.52
-rw-r--r--share/man/man5/services.54
-rw-r--r--share/man/man5/src.conf.52
-rw-r--r--share/man/man7/c99.74
-rw-r--r--share/man/man7/environ.72
-rw-r--r--share/man/man7/tuning.72
-rw-r--r--share/man/man8/rc.82
-rw-r--r--share/man/man9/BUF_ISLOCKED.94
-rw-r--r--share/man/man9/BUS_BIND_INTR.92
-rw-r--r--share/man/man9/BUS_DESCRIBE_INTR.92
-rw-r--r--share/man/man9/DB_COMMAND.92
-rw-r--r--share/man/man9/EVENTHANDLER.92
-rw-r--r--share/man/man9/Makefile2
-rw-r--r--share/man/man9/VFS.94
-rw-r--r--share/man/man9/VFS_CHECKEXP.94
-rw-r--r--share/man/man9/VFS_FHTOVP.94
-rw-r--r--share/man/man9/VFS_SET.94
-rw-r--r--share/man/man9/VOP_LOCK.95
-rw-r--r--share/man/man9/VOP_VPTOCNP.94
-rw-r--r--share/man/man9/accf_data.92
-rw-r--r--share/man/man9/accf_dns.92
-rw-r--r--share/man/man9/acl.92
-rw-r--r--share/man/man9/alq.92
-rw-r--r--share/man/man9/devfs_set_cdevpriv.92
-rw-r--r--share/man/man9/eventtimers.94
-rw-r--r--share/man/man9/ieee80211_crypto.94
-rw-r--r--share/man/man9/ifnet.95
-rw-r--r--share/man/man9/kqueue.95
-rw-r--r--share/man/man9/lock.94
-rw-r--r--share/man/man9/locking.96
-rw-r--r--share/man/man9/mbuf.96
-rw-r--r--share/man/man9/mod_cc.99
-rw-r--r--share/man/man9/refcount.92
-rw-r--r--share/man/man9/usbdi.94
-rw-r--r--share/man/man9/vm_page_busy.94
-rw-r--r--share/man/man9/vnet.915
-rw-r--r--share/man/man9/vnode.94
-rw-r--r--share/man/man9/zone.92
-rw-r--r--share/misc/committers-ports.dot3
-rw-r--r--share/mk/bsd.lib.mk7
-rw-r--r--share/mk/src.opts.mk1
-rw-r--r--sys/amd64/amd64/trap.c3
-rw-r--r--sys/amd64/conf/NOTES2
-rw-r--r--sys/amd64/include/vmm.h2
-rw-r--r--sys/amd64/vmm/amd/svm.c96
-rw-r--r--sys/amd64/vmm/intel/vmcs.c6
-rw-r--r--sys/amd64/vmm/intel/vmcs.h2
-rw-r--r--sys/amd64/vmm/intel/vmx.c76
-rw-r--r--sys/amd64/vmm/intel/vmx_msr.c26
-rw-r--r--sys/amd64/vmm/io/vatpic.c41
-rw-r--r--sys/amd64/vmm/vmm.c12
-rw-r--r--sys/arm/allwinner/a20/std.a201
-rw-r--r--sys/arm/allwinner/std.a101
-rw-r--r--sys/arm/altera/socfpga/std.socfpga1
-rw-r--r--sys/arm/arm/db_trace.c19
-rw-r--r--sys/arm/arm/dump_machdep.c16
-rw-r--r--sys/arm/arm/exception.S50
-rw-r--r--sys/arm/arm/gdb_machdep.c24
-rw-r--r--sys/arm/arm/genassym.c19
-rw-r--r--sys/arm/arm/gic.c149
-rw-r--r--sys/arm/arm/identcpu.c2
-rw-r--r--sys/arm/arm/intr.c39
-rw-r--r--sys/arm/arm/machdep.c22
-rw-r--r--sys/arm/arm/mp_machdep.c4
-rw-r--r--sys/arm/arm/nexus.c28
-rw-r--r--sys/arm/arm/stack_machdep.c2
-rw-r--r--sys/arm/arm/swtch.S128
-rw-r--r--sys/arm/arm/trap.c9
-rw-r--r--sys/arm/arm/vm_machdep.c88
-rw-r--r--sys/arm/at91/at91_machdep.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c1818
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_intr.c29
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.c36
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox.h3
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h273
-rw-r--r--sys/arm/broadcom/bcm2835/files.bcm28352
-rw-r--r--sys/arm/broadcom/bcm2835/std.bcm28351
-rw-r--r--sys/arm/conf/APALIS-IMX66
-rw-r--r--sys/arm/conf/ARMADAXP94
-rw-r--r--sys/arm/conf/BEAGLEBONE54
-rw-r--r--sys/arm/conf/CHROMEBOOK-PEACH-PIT18
-rw-r--r--sys/arm/conf/CNS11XXNAS6
-rw-r--r--sys/arm/conf/CUBIEBOARD55
-rw-r--r--sys/arm/conf/CUBIEBOARD285
-rw-r--r--sys/arm/conf/DIGI-CCWMX536
-rw-r--r--sys/arm/conf/DOCKSTAR94
-rw-r--r--sys/arm/conf/DREAMPLUG-100198
-rw-r--r--sys/arm/conf/EA32502
-rw-r--r--sys/arm/conf/EFIKA_MX67
-rw-r--r--sys/arm/conf/EXYNOS5.common71
-rw-r--r--sys/arm/conf/HL2012
-rw-r--r--sys/arm/conf/IMX5352
-rw-r--r--sys/arm/conf/IMX53-QSB4
-rw-r--r--sys/arm/conf/IMX6216
-rw-r--r--sys/arm/conf/PANDABOARD50
-rw-r--r--sys/arm/conf/RK318869
-rw-r--r--sys/arm/conf/RPI-B85
-rw-r--r--sys/arm/conf/SAM9260EK2
-rw-r--r--sys/arm/conf/SOCKIT59
-rw-r--r--sys/arm/conf/SOCKIT-BERI59
-rw-r--r--sys/arm/conf/VERSATILEPB66
-rw-r--r--sys/arm/conf/VYBRID96
-rw-r--r--sys/arm/conf/WANDBOARD-DUAL4
-rw-r--r--sys/arm/conf/WANDBOARD-QUAD4
-rw-r--r--sys/arm/conf/WANDBOARD-SOLO4
-rw-r--r--sys/arm/conf/ZEDBOARD87
-rw-r--r--sys/arm/freescale/imx/imx51_machdep.c37
-rw-r--r--sys/arm/freescale/imx/imx53_machdep.c37
-rw-r--r--sys/arm/freescale/imx/imx6_machdep.c38
-rw-r--r--sys/arm/freescale/imx/std.imx511
-rw-r--r--sys/arm/freescale/imx/std.imx531
-rw-r--r--sys/arm/freescale/imx/std.imx61
-rw-r--r--sys/arm/freescale/vybrid/std.vybrid1
-rw-r--r--sys/arm/include/asm.h76
-rw-r--r--sys/arm/include/cpuconf.h23
-rw-r--r--sys/arm/include/db_machdep.h2
-rw-r--r--sys/arm/include/frame.h72
-rw-r--r--sys/arm/include/intr.h8
-rw-r--r--sys/arm/include/machdep.h3
-rw-r--r--sys/arm/include/pcb.h39
-rw-r--r--sys/arm/include/smp.h2
-rw-r--r--sys/arm/include/sysreg.h26
-rw-r--r--sys/arm/lpc/lpc_intc.c42
-rw-r--r--sys/arm/mv/mpic.c2
-rw-r--r--sys/arm/mv/std-pj4b.mv1
-rw-r--r--sys/arm/rockchip/std.rk30xx1
-rw-r--r--sys/arm/samsung/exynos/std.exynos52501
-rw-r--r--sys/arm/samsung/exynos/std.exynos54201
-rw-r--r--sys/arm/ti/aintc.c36
-rw-r--r--sys/arm/ti/am335x/am335x_usbss.c27
-rw-r--r--sys/arm/ti/std.ti1
-rw-r--r--sys/arm/ti/ti_gpio.c537
-rw-r--r--sys/arm/ti/ti_gpio.h17
-rw-r--r--sys/arm/ti/ti_i2c.c2
-rw-r--r--sys/arm/ti/ti_sdhci.c57
-rw-r--r--sys/arm/ti/ti_wdt.c2
-rw-r--r--sys/arm/xilinx/std.zynq71
-rw-r--r--sys/boot/amd64/boot1.efi/Makefile2
-rwxr-xr-xsys/boot/amd64/boot1.efi/generate-fat.sh4
-rw-r--r--sys/boot/amd64/efi/Makefile2
-rw-r--r--sys/boot/arm/uboot/Makefile2
-rw-r--r--sys/boot/common/console.c29
-rw-r--r--sys/boot/common/loader.88
-rw-r--r--sys/boot/fdt/dts/arm/am335x.dtsi2
-rw-r--r--sys/boot/fdt/dts/arm/rpi.dts11
-rw-r--r--sys/boot/forth/brand.4th.82
-rw-r--r--sys/boot/forth/delay.4th.82
-rw-r--r--sys/boot/forth/loader.conf1
-rw-r--r--sys/boot/forth/menu.4th.84
-rw-r--r--sys/boot/forth/menusets.4th.84
-rw-r--r--sys/boot/forth/version.4th.84
-rw-r--r--sys/boot/i386/libi386/spinconsole.c2
-rw-r--r--sys/boot/powerpc/uboot/Makefile2
-rw-r--r--sys/boot/uboot/common/main.c9
-rw-r--r--sys/cam/ctl/ctl.c461
-rw-r--r--sys/cam/ctl/ctl.h1
-rw-r--r--sys/cam/ctl/ctl_backend.c46
-rw-r--r--sys/cam/ctl/ctl_backend.h9
-rw-r--r--sys/cam/ctl/ctl_backend_block.c44
-rw-r--r--sys/cam/ctl/ctl_backend_ramdisk.c26
-rw-r--r--sys/cam/ctl/ctl_frontend.c84
-rw-r--r--sys/cam/ctl/ctl_frontend_cam_sim.c4
-rw-r--r--sys/cam/ctl/ctl_frontend_internal.c8
-rw-r--r--sys/cam/ctl/ctl_tpc.c49
-rw-r--r--sys/cam/ctl/ctl_tpc.h3
-rw-r--r--sys/cam/ctl/ctl_tpc_local.c5
-rw-r--r--sys/cam/ctl/scsi_ctl.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c10
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c11
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c573
-rw-r--r--sys/cddl/dev/dtrace/amd64/dtrace_subr.c4
-rw-r--r--sys/cddl/dev/dtrace/i386/dtrace_subr.c4
-rw-r--r--sys/cddl/dev/dtrace/mips/dtrace_subr.c5
-rw-r--r--sys/cddl/dev/dtrace/powerpc/dtrace_subr.c5
-rw-r--r--sys/conf/NOTES22
-rw-r--r--sys/conf/files80
-rw-r--r--sys/conf/newvers.sh6
-rw-r--r--sys/conf/options7
-rw-r--r--sys/dev/ahci/ahci.c24
-rw-r--r--sys/dev/ahci/ahci.h3
-rw-r--r--sys/dev/ath/if_ath_sysctl.c10
-rw-r--r--sys/dev/beri/virtio/virtio.c3
-rw-r--r--sys/dev/bge/if_bge.c6
-rw-r--r--sys/dev/cpuctl/cpuctl.c2
-rw-r--r--sys/dev/fdt/fdt_common.c11
-rw-r--r--sys/dev/fxp/if_fxp.c112
-rw-r--r--sys/dev/fxp/if_fxpreg.h2
-rw-r--r--sys/dev/fxp/if_fxpvar.h3
-rw-r--r--sys/dev/gpio/gpio_if.m4
-rw-r--r--sys/dev/ieee488/ibfoo.c1127
-rw-r--r--sys/dev/ieee488/ibfoo_int.h147
-rw-r--r--sys/dev/ieee488/pcii.c255
-rw-r--r--sys/dev/ieee488/tnt4882.c320
-rw-r--r--sys/dev/ieee488/tnt4882.h77
-rw-r--r--sys/dev/ieee488/ugpib.h155
-rw-r--r--sys/dev/ieee488/upd7210.c369
-rw-r--r--sys/dev/ieee488/upd7210.h237
-rw-r--r--sys/dev/ipmi/ipmi_kcs.c13
-rw-r--r--sys/dev/isci/isci_controller.c2
-rw-r--r--sys/dev/isci/isci_sysctl.c5
-rw-r--r--sys/dev/iscsi/iscsi.c4
-rw-r--r--sys/dev/iwn/if_iwn.c13
-rw-r--r--sys/dev/mmc/mmc.c37
-rw-r--r--sys/dev/ofw/ofw_cpu.c14
-rw-r--r--sys/dev/pci/pci.c29
-rw-r--r--sys/dev/sdhci/sdhci.c44
-rw-r--r--sys/dev/sdhci/sdhci.h7
-rw-r--r--sys/dev/usb/quirk/usb_quirk.c1
-rw-r--r--sys/dev/usb/usbdevs3
-rw-r--r--sys/dev/vt/hw/efifb/efifb.c53
-rw-r--r--sys/dev/vt/hw/vga/vt_vga.c55
-rw-r--r--sys/dev/vt/vt.h1
-rw-r--r--sys/dev/vt/vt_core.c4
-rw-r--r--sys/dev/wpi/if_wpi.c30
-rw-r--r--sys/dev/wpi/if_wpireg.h2
-rw-r--r--sys/fs/ext2fs/ext2_vnops.c4
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c2
-rw-r--r--sys/fs/nandfs/nandfs_vnops.c2
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c6
-rw-r--r--sys/fs/nfs/nfs_commonsubs.c3
-rw-r--r--sys/fs/nfs/nfsport.h18
-rw-r--r--sys/fs/nfsclient/nfs.h18
-rw-r--r--sys/fs/nfsclient/nfs_clnode.c2
-rw-r--r--sys/fs/nfsclient/nfs_clport.c2
-rw-r--r--sys/fs/nfsclient/nfs_clvfsops.c11
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c14
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c9
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c125
-rw-r--r--sys/fs/tmpfs/tmpfs_vnops.c6
-rw-r--r--sys/geom/sched/README26
-rw-r--r--sys/geom/sched/g_sched.c170
-rw-r--r--sys/geom/sched/g_sched.h13
-rw-r--r--sys/geom/sched/gs_rr.c12
-rw-r--r--sys/geom/sched/subr_disk.c226
-rw-r--r--sys/i386/i386/trap.c2
-rw-r--r--sys/i386/xen/clock.c2
-rw-r--r--sys/kern/kern_sig.c3
-rw-r--r--sys/kern/subr_fattime.c2
-rw-r--r--sys/kern/uipc_sockbuf.c21
-rw-r--r--sys/kern/uipc_socket.c9
-rw-r--r--sys/kern/vfs_default.c37
-rw-r--r--sys/kern/vfs_vnops.c2
-rw-r--r--sys/mips/beri/beri_machdep.c4
-rw-r--r--sys/mips/mips/trap.c3
-rw-r--r--sys/modules/Makefile3
-rw-r--r--sys/modules/cryptodev/Makefile2
-rw-r--r--sys/modules/dtrace/Makefile1
-rw-r--r--sys/modules/dtrace/dtnfsclient/Makefile17
-rw-r--r--sys/modules/dtrace/dtraceall/dtraceall.c3
-rw-r--r--sys/modules/geom/geom_sched/gs_sched/Makefile2
-rw-r--r--sys/modules/geom/geom_sched/gsched_rr/Makefile2
-rw-r--r--sys/modules/if_gif/Makefile6
-rw-r--r--sys/modules/nfs_common/Makefile8
-rw-r--r--sys/modules/nfsclient/Makefile32
-rw-r--r--sys/modules/nfsserver/Makefile12
-rw-r--r--sys/net/if_gif.c2
-rw-r--r--sys/net/if_gif.h10
-rw-r--r--sys/net/if_gre.c10
-rw-r--r--sys/net/if_gre.h9
-rw-r--r--sys/net/if_stf.c6
-rw-r--r--sys/net/if_stf.h38
-rw-r--r--sys/net80211/ieee80211_output.c2
-rw-r--r--sys/net80211/ieee80211_power.c21
-rw-r--r--sys/net80211/ieee80211_proto.h1
-rw-r--r--sys/net80211/ieee80211_scan.c59
-rw-r--r--sys/net80211/ieee80211_sta.c33
-rw-r--r--sys/netinet/in_gif.c9
-rw-r--r--sys/netinet/in_gif.h44
-rw-r--r--sys/netinet/in_systm.h7
-rw-r--r--sys/netinet/ip_gre.c5
-rw-r--r--sys/netinet/ip_icmp.c2
-rw-r--r--sys/netinet/ip_icmp.h2
-rw-r--r--sys/netinet/sctp_usrreq.c23
-rw-r--r--sys/netinet/sctputil.c15
-rw-r--r--sys/netinet6/in6_gif.c9
-rw-r--r--sys/netinet6/in6_gif.h44
-rw-r--r--sys/netinet6/ip6_gre.c5
-rw-r--r--sys/netipsec/ipsec.c27
-rw-r--r--sys/netipsec/ipsec.h23
-rw-r--r--sys/netipsec/key.c295
-rw-r--r--sys/netipsec/key_debug.c4
-rw-r--r--sys/nfs/bootp_subr.c3
-rw-r--r--sys/nfs/nfs_common.c407
-rw-r--r--sys/nfsclient/nfs_bio.c1794
-rw-r--r--sys/nfsclient/nfs_kdtrace.c542
-rw-r--r--sys/nfsclient/nfs_krpc.c887
-rw-r--r--sys/nfsclient/nfs_nfsiod.c346
-rw-r--r--sys/nfsclient/nfs_node.c276
-rw-r--r--sys/nfsclient/nfs_subs.c1140
-rw-r--r--sys/nfsclient/nfs_vfsops.c1582
-rw-r--r--sys/nfsclient/nfs_vnops.c3544
-rw-r--r--sys/nfsserver/nfs_fha_old.c265
-rw-r--r--sys/nfsserver/nfs_serv.c3767
-rw-r--r--sys/nfsserver/nfs_srvkrpc.c545
-rw-r--r--sys/nfsserver/nfs_srvsubs.c1418
-rw-r--r--sys/powerpc/aim/trap.c2
-rw-r--r--sys/sys/dtrace_bsd.h4
-rw-r--r--sys/sys/mbuf.h5
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/sem.h4
-rw-r--r--sys/sys/time.h2
-rw-r--r--sys/sys/vnode.h1
-rw-r--r--sys/teken/libteken/teken.32
-rw-r--r--sys/ufs/ufs/ufs_vnops.c4
-rw-r--r--sys/vm/vm_page.c6
-rw-r--r--sys/vm/vm_page.h38
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc21
-rw-r--r--tools/build/options/WITHOUT_GPIB2
-rw-r--r--tools/tools/ether_reflect/ether_reflect.14
-rw-r--r--tools/tools/sysbuild/sysbuild.sh8
-rw-r--r--tools/tools/vimage/vimage.84
-rw-r--r--usr.bin/dpv/dpv.14
-rw-r--r--usr.bin/iscsictl/iscsi.conf.54
-rw-r--r--usr.bin/last/last.14
-rw-r--r--usr.bin/man/man.114
-rwxr-xr-xusr.bin/man/man.sh2
-rw-r--r--usr.bin/mandoc/Makefile13
-rw-r--r--usr.bin/mkcsmapper/mkcsmapper.14
-rw-r--r--usr.bin/mkesdb/mkesdb.14
-rw-r--r--usr.bin/patch/patch.c20
-rw-r--r--usr.bin/patch/pch.c14
-rw-r--r--usr.bin/patch/util.c16
-rw-r--r--usr.bin/patch/util.h3
-rw-r--r--usr.bin/rup/rup.14
-rw-r--r--usr.bin/rusers/rusers.14
-rw-r--r--usr.bin/rwall/rwall.14
-rw-r--r--usr.bin/script/script.12
-rw-r--r--usr.bin/seq/seq.19
-rw-r--r--usr.bin/seq/seq.c75
-rw-r--r--usr.bin/setchannel/setchannel.12
-rw-r--r--usr.bin/showmount/showmount.84
-rw-r--r--usr.sbin/bluetooth/btpand/btpand.84
-rwxr-xr-xusr.sbin/bsdinstall/scripts/zfsboot65
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.34
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.34
-rw-r--r--usr.sbin/ctladm/ctladm.c42
-rw-r--r--usr.sbin/ctld/login.c2
-rw-r--r--usr.sbin/freebsd-update/freebsd-update.sh9
-rw-r--r--usr.sbin/gpioctl/gpioctl.84
-rw-r--r--usr.sbin/gssd/gssd.84
-rw-r--r--usr.sbin/iscsid/login.c9
-rw-r--r--usr.sbin/jail/jail.82
-rw-r--r--usr.sbin/kldxref/kldxref.c2
-rw-r--r--usr.sbin/nandsim/nandsim.82
-rw-r--r--usr.sbin/nfsuserd/nfsuserd.84
-rw-r--r--usr.sbin/rpc.umntall/rpc.umntall.82
-rw-r--r--usr.sbin/rtadvctl/rtadvctl.84
-rw-r--r--usr.sbin/rtadvd/rtadvd.conf.52
609 files changed, 8426 insertions, 24104 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1
index 9b036f4..2aa1645 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -1367,6 +1367,11 @@ _share= share/syscons/scrnmaps
_gcc_tools= gnu/usr.bin/cc/cc_tools
.endif
+.if ${MK_INFO} != "no"
+_texinfo= gnu/usr.bin/texinfo/libtxi \
+ gnu/usr.bin/texinfo/makeinfo
+.endif
+
.if ${MK_RESCUE} != "no"
_rescue= rescue/rescue
.endif
@@ -1398,6 +1403,16 @@ build-tools: .MAKE
${MAKE} DIRPRFX=${_tool}/ depend && \
${MAKE} DIRPRFX=${_tool}/ all
.endfor
+.for _tool in \
+ ${_texinfo}
+ ${_+_}@${ECHODIR} "===> ${_tool} (obj,depend,all,install)"; \
+ cd ${.CURDIR}/${_tool} && \
+ ${MAKE} DIRPRFX=${_tool}/ obj && \
+ ${MAKE} DIRPRFX=${_tool}/ depend && \
+ ${MAKE} DIRPRFX=${_tool}/ all && \
+ ${MAKE} DIRPRFX=${_tool}/ install DESTDIR=${WORLDTMP}
+.endfor
+
#
# kernel-tools: Build kernel-building tools
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 84eb573..b1171f2 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -38,7 +38,7 @@
# xargs -n1 | sort | uniq -d;
# done
-# 20141204: new clang import which bumps version from 3.4.1 to 3.5.0.
+# 20141227: new clang import which bumps version from 3.4.1 to 3.5.0.
OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_aes.h
OLD_FILES+=usr/include/clang/3.4.1/__wmmintrin_pclmul.h
OLD_FILES+=usr/include/clang/3.4.1/altivec.h
@@ -74,6 +74,35 @@ OLD_FILES+=usr/include/clang/3.4.1/x86intrin.h
OLD_FILES+=usr/include/clang/3.4.1/xmmintrin.h
OLD_FILES+=usr/include/clang/3.4.1/xopintrin.h
OLD_DIRS+=usr/include/clang/3.4.1
+# 20141226: Remove gpib/ieee488
+OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h
+OLD_FILES+=usr/include/dev/ieee488/tnt4882.h
+OLD_FILES+=usr/include/dev/ieee488/ugpib.h
+OLD_FILES+=usr/include/dev/ieee488/upd7210.h
+OLD_DIRS+=usr/include/dev/ieee488
+OLD_FILES+=usr/include/gpib/gpib.h
+OLD_DIRS+=usr/include/gpib
+OLD_FILES+=usr/lib/libgpib.a
+OLD_FILES+=usr/lib/libgpib_p.a
+OLD_FILES+=usr/lib/libgpib.so
+OLD_LIBS+=usr/lib/libgpib.so.3
+OLD_FILES+=usr/lib/libgpib_p.a
+OLD_FILES+=share/man/man4/pcii.4.gz
+OLD_FILES+=share/man/man4/gpib.4.gz
+OLD_FILES+=share/man/man4/tnt4882.4.gz
+.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64"
+OLD_FILES+=usr/lib32/libgpib.a
+OLD_FILES+=usr/lib32/libgpib_p.a
+OLD_FILES+=usr/lib32/libgpib.so
+OLD_LIBS+=usr/lib32/libgpib.so.3
+.endif
+
+# 20141224: libxo moved to /lib
+OLD_LIBS+=usr/lib/libxo.so.0
+# 20141223: remove in6_gif.h, in_gif.h and if_stf.h
+OLD_FILES+=usr/include/net/if_stf.h
+OLD_FILES+=usr/include/netinet/in_gif.h
+OLD_FILES+=usr/include/netinet6/in6_gif.h
# 20141202: update to mandoc CVS 20141201
OLD_FILES+=usr.bin/preconv
OLD_FILES+=share/man/man1/preconv.1.gz
diff --git a/UPDATING b/UPDATING
index 89a2de7..c84be39 100644
--- a/UPDATING
+++ b/UPDATING
@@ -31,6 +31,14 @@ 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".)
+20141222:
+ The old NFS client and server (kernel options NFSCLIENT, NFSSERVER)
+ kernel sources have been removed. The .h files remain, since some
+ utilities include them. This will need to be fixed later.
+ If "mount -t oldnfs ..." is attempted, it will fail.
+ If the "-o" option on mountd(8), nfsd(8) or nfsstat(1) is used,
+ the utilities will report errors.
+
20141121:
The handling of LOCAL_LIB_DIRS has been altered to skip addition of
directories to top level SUBDIR variable when their parent
diff --git a/bin/sh/error.c b/bin/sh/error.c
index 96a0092..fedffaa 100644
--- a/bin/sh/error.c
+++ b/bin/sh/error.c
@@ -90,13 +90,14 @@ exraise(int e)
/*
- * Called from trap.c when a SIGINT is received. (If the user specifies
- * that SIGINT is to be trapped or ignored using the trap builtin, then
- * this routine is not called.) Suppressint is nonzero when interrupts
- * are held using the INTOFF macro. If SIGINTs are not suppressed and
- * the shell is not a root shell, then we want to be terminated if we
- * get here, as if we were terminated directly by a SIGINT. Arrange for
- * this here.
+ * Called from trap.c when a SIGINT is received and not suppressed, or when
+ * an interrupt is pending and interrupts are re-enabled using INTON.
+ * (If the user specifies that SIGINT is to be trapped or ignored using the
+ * trap builtin, then this routine is not called.) Suppressint is nonzero
+ * when interrupts are held using the INTOFF macro. If SIGINTs are not
+ * suppressed and the shell is not a root shell, then we want to be
+ * terminated if we get here, as if we were terminated directly by a SIGINT.
+ * Arrange for this here.
*/
void
@@ -104,16 +105,6 @@ onint(void)
{
sigset_t sigs;
- /*
- * The !in_dotrap here is safe. The only way we can arrive here
- * with in_dotrap set is that a trap handler set SIGINT to SIG_DFL
- * and killed itself.
- */
-
- if (suppressint && !in_dotrap) {
- intpending++;
- return;
- }
intpending = 0;
sigemptyset(&sigs);
sigprocmask(SIG_SETMASK, &sigs, NULL);
@@ -130,6 +121,7 @@ onint(void)
else {
signal(SIGINT, SIG_DFL);
kill(getpid(), SIGINT);
+ _exit(128 + SIGINT);
}
}
diff --git a/bin/sh/error.h b/bin/sh/error.h
index d0a4bca..a60b1fa 100644
--- a/bin/sh/error.h
+++ b/bin/sh/error.h
@@ -75,11 +75,12 @@ extern volatile sig_atomic_t intpending;
#define is_int_on() suppressint
#define SETINTON(s) suppressint = (s)
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
+#define SET_PENDING_INT intpending = 1
#define CLEAR_PENDING_INT intpending = 0
#define int_pending() intpending
void exraise(int) __dead2;
-void onint(void);
+void onint(void) __dead2;
void warning(const char *, ...) __printflike(1, 2);
void error(const char *, ...) __printf0like(1, 2) __dead2;
void exerror(int, const char *, ...) __printf0like(2, 3) __dead2;
diff --git a/bin/sh/eval.c b/bin/sh/eval.c
index d0460a0..486de9c 100644
--- a/bin/sh/eval.c
+++ b/bin/sh/eval.c
@@ -539,13 +539,13 @@ expredir(union node *n)
case NFROMTO:
case NAPPEND:
case NCLOBBER:
- expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
+ expandarg(redir->nfile.fname, &fn, EXP_TILDE);
redir->nfile.expfname = fn.list->text;
break;
case NFROMFD:
case NTOFD:
if (redir->ndup.vname) {
- expandarg(redir->ndup.vname, &fn, EXP_TILDE | EXP_REDIR);
+ expandarg(redir->ndup.vname, &fn, EXP_TILDE);
fixredir(redir, fn.list->text, 1);
}
break;
diff --git a/bin/sh/expand.c b/bin/sh/expand.c
index fd8b996..b542303 100644
--- a/bin/sh/expand.c
+++ b/bin/sh/expand.c
@@ -171,17 +171,12 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
STPUTC('\0', expdest);
p = grabstackstr(expdest);
exparg.lastp = &exparg.list;
- /*
- * TODO - EXP_REDIR
- */
if (flag & EXP_FULL) {
ifsbreakup(p, &exparg);
*exparg.lastp = NULL;
exparg.lastp = &exparg.list;
expandmeta(exparg.list, flag);
} else {
- if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */
- rmescapes(p);
sp = (struct strlist *)stalloc(sizeof (struct strlist));
sp->text = p;
*exparg.lastp = sp;
@@ -209,7 +204,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
* expansion, and tilde expansion if requested via EXP_TILDE/EXP_VARTILDE.
* Processing ends at a CTLENDVAR or CTLENDARI character as well as '\0'.
* This is used to expand word in ${var+word} etc.
- * If EXP_FULL, EXP_CASE or EXP_REDIR are set, keep and/or generate CTLESC
+ * If EXP_FULL or EXP_CASE are set, keep and/or generate CTLESC
* characters to allow for further processing.
* If EXP_FULL is set, also preserve CTLQUOTEMARK characters.
*/
@@ -217,7 +212,7 @@ static char *
argstr(char *p, int flag)
{
char c;
- int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); /* do CTLESC */
+ int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */
int firsteq = 1;
int split_lit;
int lit_quoted;
@@ -303,7 +298,7 @@ exptilde(char *p, int flag)
char c, *startp = p;
struct passwd *pw;
char *home;
- int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
+ int quotes = flag & (EXP_FULL | EXP_CASE);
while ((c = *p) != '\0') {
switch(c) {
@@ -437,7 +432,7 @@ expbackq(union node *cmd, int quoted, int flag)
char lastc;
int startloc = dest - stackblock();
char const *syntax = quoted? DQSYNTAX : BASESYNTAX;
- int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
+ int quotes = flag & (EXP_FULL | EXP_CASE);
size_t nnl;
INTOFF;
@@ -637,7 +632,7 @@ evalvar(char *p, int flag)
int varlen;
int varlenb;
int easy;
- int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR);
+ int quotes = flag & (EXP_FULL | EXP_CASE);
varflags = (unsigned char)*p++;
subtype = varflags & VSTYPE;
@@ -862,7 +857,7 @@ varisset(const char *name, int nulok)
static void
strtodest(const char *p, int flag, int subtype, int quoted)
{
- if (flag & (EXP_FULL | EXP_CASE | EXP_REDIR) && subtype != VSLENGTH)
+ if (flag & (EXP_FULL | EXP_CASE) && subtype != VSLENGTH)
STPUTS_QUOTES(p, quoted ? DQSYNTAX : BASESYNTAX, expdest);
else
STPUTS(p, expdest);
@@ -1104,7 +1099,6 @@ expandmeta(struct strlist *str, int flag __unused)
struct strlist **savelastp;
struct strlist *sp;
char c;
- /* TODO - EXP_REDIR */
while (str) {
savelastp = exparg.lastp;
diff --git a/bin/sh/expand.h b/bin/sh/expand.h
index 7495a63..93c80f3 100644
--- a/bin/sh/expand.h
+++ b/bin/sh/expand.h
@@ -50,7 +50,6 @@ struct arglist {
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
-#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
#define EXP_SPLIT_LIT 0x20 /* IFS split literal text ${v+-a b c} */
#define EXP_LIT_QUOTED 0x40 /* for EXP_SPLIT_LIT, start off quoted */
diff --git a/bin/sh/trap.c b/bin/sh/trap.c
index 8ea3b12..c23e6bc 100644
--- a/bin/sh/trap.c
+++ b/bin/sh/trap.c
@@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$");
static char sigmode[NSIG]; /* current value of signal */
volatile sig_atomic_t pendingsig; /* indicates some signal received */
volatile sig_atomic_t pendingsig_waitcmd; /* indicates SIGINT/SIGQUIT received */
-int in_dotrap; /* do we execute in a trap handler? */
+static int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[NSIG];
/* indicates specified signal received */
@@ -380,7 +380,15 @@ onsig(int signo)
{
if (signo == SIGINT && trap[SIGINT] == NULL) {
- onint();
+ /*
+ * The !in_dotrap here is safe. The only way we can arrive
+ * here with in_dotrap set is that a trap handler set SIGINT to
+ * SIG_DFL and killed itself.
+ */
+ if (suppressint && !in_dotrap)
+ SET_PENDING_INT;
+ else
+ onint();
return;
}
diff --git a/bin/sh/trap.h b/bin/sh/trap.h
index 541b9b1..a272839 100644
--- a/bin/sh/trap.h
+++ b/bin/sh/trap.h
@@ -35,7 +35,6 @@
extern volatile sig_atomic_t pendingsig;
extern volatile sig_atomic_t pendingsig_waitcmd;
-extern int in_dotrap;
void clear_traps(void);
int have_traps(void);
diff --git a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
index 31340b0..2985d0f 100644
--- a/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
+++ b/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
@@ -4509,11 +4509,12 @@ zpool_do_status(int argc, char **argv)
}
typedef struct upgrade_cbdata {
- int cb_first;
- char cb_poolname[ZPOOL_MAXNAMELEN];
- int cb_argc;
- uint64_t cb_version;
- char **cb_argv;
+ boolean_t cb_first;
+ boolean_t cb_unavail;
+ char cb_poolname[ZPOOL_MAXNAMELEN];
+ int cb_argc;
+ uint64_t cb_version;
+ char **cb_argv;
} upgrade_cbdata_t;
#ifdef __FreeBSD__
@@ -4629,6 +4630,14 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
boolean_t printnl = B_FALSE;
int ret;
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
+ "currently unavailable.\n\n"), zpool_get_name(zhp));
+ cbp->cb_unavail = B_TRUE;
+ /* Allow iteration to continue. */
+ return (0);
+ }
+
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@@ -4690,12 +4699,41 @@ upgrade_cb(zpool_handle_t *zhp, void *arg)
}
static int
+upgrade_list_unavail(zpool_handle_t *zhp, void *arg)
+{
+ upgrade_cbdata_t *cbp = arg;
+
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ if (cbp->cb_first) {
+ (void) fprintf(stderr, gettext("The following pools "
+ "are unavailable and cannot be upgraded as this "
+ "time.\n\n"));
+ (void) fprintf(stderr, gettext("POOL\n"));
+ (void) fprintf(stderr, gettext("------------\n"));
+ cbp->cb_first = B_FALSE;
+ }
+ (void) printf(gettext("%s\n"), zpool_get_name(zhp));
+ cbp->cb_unavail = B_TRUE;
+ }
+ return (0);
+}
+
+static int
upgrade_list_older_cb(zpool_handle_t *zhp, void *arg)
{
upgrade_cbdata_t *cbp = arg;
nvlist_t *config;
uint64_t version;
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ /*
+ * This will have been reported by upgrade_list_unavail so
+ * just allow iteration to continue.
+ */
+ cbp->cb_unavail = B_TRUE;
+ return (0);
+ }
+
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@@ -4729,6 +4767,15 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
nvlist_t *config;
uint64_t version;
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ /*
+ * This will have been reported by upgrade_list_unavail so
+ * just allow iteration to continue.
+ */
+ cbp->cb_unavail = B_TRUE;
+ return (0);
+ }
+
config = zpool_get_config(zhp, NULL);
verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
&version) == 0);
@@ -4782,10 +4829,17 @@ upgrade_one(zpool_handle_t *zhp, void *data)
uint64_t cur_version;
int ret;
+ if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) {
+ (void) fprintf(stderr, gettext("cannot upgrade '%s': pool is "
+ "is currently unavailable.\n\n"), zpool_get_name(zhp));
+ cbp->cb_unavail = B_TRUE;
+ return (1);
+ }
+
if (strcmp("log", zpool_get_name(zhp)) == 0) {
(void) printf(gettext("'log' is now a reserved word\n"
"Pool 'log' must be renamed using export and import"
- " to upgrade.\n"));
+ " to upgrade.\n\n"));
return (1);
}
@@ -4829,7 +4883,7 @@ upgrade_one(zpool_handle_t *zhp, void *data)
#endif /* __FreeBSD __*/
} else if (cur_version == SPA_VERSION) {
(void) printf(gettext("Pool '%s' already has all "
- "supported features enabled.\n"),
+ "supported features enabled.\n\n"),
zpool_get_name(zhp));
}
}
@@ -4986,11 +5040,13 @@ zpool_do_upgrade(int argc, char **argv)
ret = zpool_iter(g_zfs, upgrade_cb, &cb);
if (ret == 0 && cb.cb_first) {
if (cb.cb_version == SPA_VERSION) {
- (void) printf(gettext("All pools are already "
- "formatted using feature flags.\n\n"));
- (void) printf(gettext("Every feature flags "
+ (void) printf(gettext("All %spools are already "
+ "formatted using feature flags.\n\n"),
+ cb.cb_unavail ? gettext("available ") : "");
+ (void) printf(gettext("Every %sfeature flags "
"pool already has all supported features "
- "enabled.\n"));
+ "enabled.\n"),
+ cb.cb_unavail ? gettext("available ") : "");
} else {
(void) printf(gettext("All pools are already "
"formatted with version %llu or higher.\n"),
@@ -4999,12 +5055,21 @@ zpool_do_upgrade(int argc, char **argv)
}
} else if (argc == 0) {
cb.cb_first = B_TRUE;
+ ret = zpool_iter(g_zfs, upgrade_list_unavail, &cb);
+ assert(ret == 0);
+
+ if (!cb.cb_first) {
+ (void) fprintf(stderr, "\n");
+ }
+
+ cb.cb_first = B_TRUE;
ret = zpool_iter(g_zfs, upgrade_list_older_cb, &cb);
assert(ret == 0);
if (cb.cb_first) {
- (void) printf(gettext("All pools are formatted "
- "using feature flags.\n\n"));
+ (void) printf(gettext("All %spools are formatted using "
+ "feature flags.\n\n"), cb.cb_unavail ?
+ gettext("available ") : "");
} else {
(void) printf(gettext("\nUse 'zpool upgrade -v' "
"for a list of available legacy versions.\n"));
@@ -5015,13 +5080,14 @@ zpool_do_upgrade(int argc, char **argv)
assert(ret == 0);
if (cb.cb_first) {
- (void) printf(gettext("Every feature flags pool has "
- "all supported features enabled.\n"));
+ (void) printf(gettext("Every %sfeature flags pool has "
+ "all supported features enabled.\n"),
+ cb.cb_unavail ? gettext("available ") : "");
} else {
(void) printf(gettext("\n"));
}
} else {
- ret = for_each_pool(argc, argv, B_FALSE, NULL,
+ ret = for_each_pool(argc, argv, B_TRUE, NULL,
upgrade_one, &cb);
}
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
index fc86eb7..6f3c9c7 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/drti.c
@@ -127,6 +127,7 @@ dtrace_dof_init(void)
int efd;
char *s;
size_t shstridx;
+ uint64_t aligned_filesz;
#endif
if (getenv("DTRACE_DOF_INIT_DISABLE") != NULL)
@@ -171,6 +172,7 @@ dtrace_dof_init(void)
if (s != NULL && strcmp(s, ".SUNW_dof") == 0) {
dofdata = elf_getdata(scn, NULL);
dof = dofdata->d_buf;
+ break;
}
}
}
@@ -182,7 +184,9 @@ dtrace_dof_init(void)
}
while ((char *) dof < (char *) dofdata->d_buf + dofdata->d_size) {
- dof_next = (void *) ((char *) dof + dof->dofh_filesz);
+ aligned_filesz = (shdr.sh_addralign == 0 ? dof->dofh_filesz :
+ roundup2(dof->dofh_filesz, shdr.sh_addralign));
+ dof_next = (void *) ((char *) dof + aligned_filesz);
#endif
if (dof->dofh_ident[DOF_ID_MAG0] != DOF_MAG_MAG0 ||
diff --git a/cddl/usr.bin/ctfconvert/ctfconvert.1 b/cddl/usr.bin/ctfconvert/ctfconvert.1
index 4de07ec..c5def3e 100644
--- a/cddl/usr.bin/ctfconvert/ctfconvert.1
+++ b/cddl/usr.bin/ctfconvert/ctfconvert.1
@@ -74,8 +74,8 @@ Write the output to file in
.Sh EXIT STATUS
.Ex -std
.Sh SEE ALSO
-.Xr ctfmerge 1 ,
-.Xr ctfdump 1
+.Xr ctfdump 1 ,
+.Xr ctfmerge 1
.Sh HISTORY
The
.Nm
diff --git a/contrib/binutils/gas/expr.c b/contrib/binutils/gas/expr.c
index 11f2942..3f364b5 100644
--- a/contrib/binutils/gas/expr.c
+++ b/contrib/binutils/gas/expr.c
@@ -1040,6 +1040,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
{
for (i = 0; i < expressionP->X_add_number; ++i)
generic_bignum[i] = ~generic_bignum[i];
+
+ /* Extend the bignum to at least the size of .octa. */
+ if (expressionP->X_add_number < SIZE_OF_LARGE_NUMBER)
+ {
+ expressionP->X_add_number = SIZE_OF_LARGE_NUMBER;
+ for (; i < expressionP->X_add_number; ++i)
+ generic_bignum[i] = ~(LITTLENUM_TYPE) 0;
+ }
+
if (c == '-')
for (i = 0; i < expressionP->X_add_number; ++i)
{
@@ -1050,14 +1059,12 @@ operand (expressionS *expressionP, enum expr_mode mode)
}
else if (c == '!')
{
- int nonzero = 0;
for (i = 0; i < expressionP->X_add_number; ++i)
- {
- if (generic_bignum[i])
- nonzero = 1;
- generic_bignum[i] = 0;
- }
- generic_bignum[0] = nonzero;
+ if (generic_bignum[i] != 0)
+ break;
+ expressionP->X_add_number = i >= expressionP->X_add_number;
+ expressionP->X_op = O_constant;
+ expressionP->X_unsigned = 1;
}
}
else if (expressionP->X_op != O_illegal
diff --git a/contrib/binutils/gas/input-scrub.c b/contrib/binutils/gas/input-scrub.c
index 5698a6d..6eb0189 100644
--- a/contrib/binutils/gas/input-scrub.c
+++ b/contrib/binutils/gas/input-scrub.c
@@ -335,7 +335,7 @@ input_scrub_next_buffer (char **bufp)
if (partial_size)
{
- memcpy (buffer_start + BEFORE_SIZE, partial_where,
+ memmove (buffer_start + BEFORE_SIZE, partial_where,
(unsigned int) partial_size);
memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE);
}
diff --git a/contrib/binutils/gas/read.c b/contrib/binutils/gas/read.c
index 0098d76..5e0bdb0 100644
--- a/contrib/binutils/gas/read.c
+++ b/contrib/binutils/gas/read.c
@@ -4117,15 +4117,32 @@ emit_expr (expressionS *exp, unsigned int nbytes)
unsigned int size;
LITTLENUM_TYPE *nums;
- know (nbytes % CHARS_PER_LITTLENUM == 0);
-
size = exp->X_add_number * CHARS_PER_LITTLENUM;
if (nbytes < size)
{
- as_warn (_("bignum truncated to %d bytes"), nbytes);
+ int i = nbytes / CHARS_PER_LITTLENUM;
+ if (i != 0)
+ {
+ LITTLENUM_TYPE sign = 0;
+ if ((generic_bignum[--i]
+ & (1 << (LITTLENUM_NUMBER_OF_BITS - 1))) != 0)
+ sign = ~(LITTLENUM_TYPE) 0;
+ while (++i < exp->X_add_number)
+ if (generic_bignum[i] != sign)
+ break;
+ }
+ if (i < exp->X_add_number)
+ as_warn (_("bignum truncated to %d bytes"), nbytes);
size = nbytes;
}
+ if (nbytes == 1)
+ {
+ md_number_to_chars (p, (valueT) generic_bignum[0], 1);
+ return;
+ }
+ know (nbytes % CHARS_PER_LITTLENUM == 0);
+
if (target_big_endian)
{
while (nbytes > size)
diff --git a/contrib/bzip2/bzip2.1 b/contrib/bzip2/bzip2.1
index ce3a78e..7bd45f0 100644
--- a/contrib/bzip2/bzip2.1
+++ b/contrib/bzip2/bzip2.1
@@ -1,4 +1,3 @@
-.PU
.TH bzip2 1
.SH NAME
bzip2, bunzip2 \- a block-sorting file compressor, v1.0.6
diff --git a/contrib/ee/ee.1 b/contrib/ee/ee.1
index 7d482a8..b66c8aa 100644
--- a/contrib/ee/ee.1
+++ b/contrib/ee/ee.1
@@ -7,7 +7,7 @@
.\" $Header: /home/hugh/sources/old_ae/RCS/ee.1,v 1.22 2001/12/16 04:49:27 hugh Exp $
.\"
.\"
-.TH ee 1 "" "" "" ""
+.TH ee 1 "" "" ""
.SH NAME
ee \- easy editor
.SH SYNOPSIS
diff --git a/contrib/elftoolchain/common/elfdefinitions.h b/contrib/elftoolchain/common/elfdefinitions.h
index 7bed9a1..ccd785b 100644
--- a/contrib/elftoolchain/common/elfdefinitions.h
+++ b/contrib/elftoolchain/common/elfdefinitions.h
@@ -770,6 +770,8 @@ _ELF_DEFINE_EM(EM_ETPU, 178, \
"Freescale Extended Time Processing Unit") \
_ELF_DEFINE_EM(EM_SLE9X, 179, \
"Infineon Technologies SLE9X core") \
+_ELF_DEFINE_EM(EM_AARCH64, 183, \
+ "AArch64 (64-bit ARM)") \
_ELF_DEFINE_EM(EM_AVR32, 185, \
"Atmel Corporation 32-bit microprocessor family") \
_ELF_DEFINE_EM(EM_STM8, 186, \
diff --git a/contrib/elftoolchain/elfcopy/sections.c b/contrib/elftoolchain/elfcopy/sections.c
index d01659a..1ad7252 100644
--- a/contrib/elftoolchain/elfcopy/sections.c
+++ b/contrib/elftoolchain/elfcopy/sections.c
@@ -762,8 +762,8 @@ resync_sections(struct elfcopy *ecp)
s->off = roundup(off, s->align);
} else {
if (s->loadable)
- warnx("moving loadable section,"
- "is this intentional?");
+ warnx("moving loadable section %s, "
+ "is this intentional?", s->name);
s->off = roundup(off, s->align);
}
@@ -1139,12 +1139,6 @@ add_to_shstrtab(struct elfcopy *ecp, const char *name)
struct section *s;
s = ecp->shstrtab;
- if (s->buf == NULL) {
- insert_to_strtab(s, "");
- insert_to_strtab(s, ".symtab");
- insert_to_strtab(s, ".strtab");
- insert_to_strtab(s, ".shstrtab");
- }
insert_to_strtab(s, name);
}
@@ -1206,6 +1200,11 @@ init_shstrtab(struct elfcopy *ecp)
s->loadable = 0;
s->type = SHT_STRTAB;
s->vma = 0;
+
+ insert_to_strtab(s, "");
+ insert_to_strtab(s, ".symtab");
+ insert_to_strtab(s, ".strtab");
+ insert_to_strtab(s, ".shstrtab");
}
void
diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3 b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3
index 5b5d5a1..e88e3cf 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3
+++ b/contrib/elftoolchain/libdwarf/dwarf_get_AT_name.3
@@ -247,6 +247,7 @@ constants.
.It Fn dwarf_get_VIS_name
.Dv DW_VIS_*
constants.
+.El
.Sh RETURN VALUES
These functions return
.Dv DW_DLV_OK on success.
diff --git a/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3 b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3
index e8dac78..2e67871 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3
+++ b/contrib/elftoolchain/libdwarf/dwarf_get_arange_info.3
@@ -102,6 +102,7 @@ One of the arguments
or
.Ar cu_die_offset
was NULL.
+.El
.Sh EXAMPLE
To loop through all the address lookup table entries, use:
.Bd -literal -offset indent
diff --git a/contrib/elftoolchain/libdwarf/dwarf_hasattr.3 b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3
index 5b4699b..d3bcb27 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_hasattr.3
+++ b/contrib/elftoolchain/libdwarf/dwarf_hasattr.3
@@ -85,6 +85,7 @@ Either of argument
or
.Va ret_bool
was NULL.
+.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,
diff --git a/contrib/elftoolchain/libdwarf/dwarf_whatattr.3 b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3
index 7c9a6d0..96d9ad2 100644
--- a/contrib/elftoolchain/libdwarf/dwarf_whatattr.3
+++ b/contrib/elftoolchain/libdwarf/dwarf_whatattr.3
@@ -72,6 +72,7 @@ Either of argument
or
.Va retcode
was NULL.
+.El
.Sh SEE ALSO
.Xr dwarf 3 ,
.Xr dwarf_attr 3 ,
diff --git a/contrib/elftoolchain/libelf/elf.3 b/contrib/elftoolchain/libelf/elf.3
index 462e728..eb5c3eb 100644
--- a/contrib/elftoolchain/libelf/elf.3
+++ b/contrib/elftoolchain/libelf/elf.3
@@ -389,7 +389,6 @@ See
.It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records.
.It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags.
.El
-.TE
.Ss Functional Grouping
This section contains a brief overview of the available functionality
in the ELF library.
diff --git a/contrib/elftoolchain/readelf/readelf.c b/contrib/elftoolchain/readelf/readelf.c
index 779a7ba..8ae3e9b 100644
--- a/contrib/elftoolchain/readelf/readelf.c
+++ b/contrib/elftoolchain/readelf/readelf.c
@@ -487,6 +487,7 @@ elf_machine(unsigned int mach)
case EM_SEP: return "Sharp embedded microprocessor";
case EM_ARCA: return "Arca RISC Microprocessor";
case EM_UNICORE: return "Microprocessor series from PKU-Unity Ltd";
+ case EM_AARCH64: return "AArch64";
default:
snprintf(s_mach, sizeof(s_mach), "<unknown: %#x>", mach);
return (s_mach);
@@ -1041,6 +1042,67 @@ r_type(unsigned int mach, unsigned int type)
case 37: return "R_386_TLS_TPOFF32";
default: return "";
}
+ case EM_AARCH64:
+ switch(type) {
+ case 0: return "R_AARCH64_NONE";
+ case 257: return "R_AARCH64_ABS64";
+ case 258: return "R_AARCH64_ABS32";
+ case 259: return "R_AARCH64_ABS16";
+ case 260: return "R_AARCH64_PREL64";
+ case 261: return "R_AARCH64_PREL32";
+ case 262: return "R_AARCH64_PREL16";
+ case 263: return "R_AARCH64_MOVW_UABS_G0";
+ case 264: return "R_AARCH64_MOVW_UABS_G0_NC";
+ case 265: return "R_AARCH64_MOVW_UABS_G1";
+ case 266: return "R_AARCH64_MOVW_UABS_G1_NC";
+ case 267: return "R_AARCH64_MOVW_UABS_G2";
+ case 268: return "R_AARCH64_MOVW_UABS_G2_NC";
+ case 269: return "R_AARCH64_MOVW_UABS_G3";
+ case 270: return "R_AARCH64_MOVW_SABS_G0";
+ case 271: return "R_AARCH64_MOVW_SABS_G1";
+ case 272: return "R_AARCH64_MOVW_SABS_G2";
+ case 273: return "R_AARCH64_LD_PREL_LO19";
+ case 274: return "R_AARCH64_ADR_PREL_LO21";
+ case 275: return "R_AARCH64_ADR_PREL_PG_HI21";
+ case 276: return "R_AARCH64_ADR_PREL_PG_HI21_NC";
+ case 277: return "R_AARCH64_ADD_ABS_LO12_NC";
+ case 278: return "R_AARCH64_LDST8_ABS_LO12_NC";
+ case 279: return "R_AARCH64_TSTBR14";
+ case 280: return "R_AARCH64_CONDBR19";
+ case 282: return "R_AARCH64_JUMP26";
+ case 283: return "R_AARCH64_CALL26";
+ case 284: return "R_AARCH64_LDST16_ABS_LO12_NC";
+ case 285: return "R_AARCH64_LDST32_ABS_LO12_NC";
+ case 286: return "R_AARCH64_LDST64_ABS_LO12_NC";
+ case 287: return "R_AARCH64_MOVW_PREL_G0";
+ case 288: return "R_AARCH64_MOVW_PREL_G0_NC";
+ case 289: return "R_AARCH64_MOVW_PREL_G1";
+ case 290: return "R_AARCH64_MOVW_PREL_G1_NC";
+ case 291: return "R_AARCH64_MOVW_PREL_G2";
+ case 292: return "R_AARCH64_MOVW_PREL_G2_NC";
+ case 293: return "R_AARCH64_MOVW_PREL_G3";
+ case 299: return "R_AARCH64_LDST128_ABS_LO12_NC";
+ case 300: return "R_AARCH64_MOVW_GOTOFF_G0";
+ case 301: return "R_AARCH64_MOVW_GOTOFF_G0_NC";
+ case 302: return "R_AARCH64_MOVW_GOTOFF_G1";
+ case 303: return "R_AARCH64_MOVW_GOTOFF_G1_NC";
+ case 304: return "R_AARCH64_MOVW_GOTOFF_G2";
+ case 305: return "R_AARCH64_MOVW_GOTOFF_G2_NC";
+ case 306: return "R_AARCH64_MOVW_GOTOFF_G3";
+ case 307: return "R_AARCH64_GOTREL64";
+ case 308: return "R_AARCH64_GOTREL32";
+ case 309: return "R_AARCH64_GOT_LD_PREL19";
+ case 310: return "R_AARCH64_LD64_GOTOFF_LO15";
+ case 311: return "R_AARCH64_ADR_GOT_PAGE";
+ case 312: return "R_AARCH64_LD64_GOT_LO12_NC";
+ case 313: return "R_AARCH64_LD64_GOTPAGE_LO15";
+ case 1024: return "R_AARCH64_COPY";
+ case 1025: return "R_AARCH64_GLOB_DAT";
+ case 1026: return "R_AARCH64_JUMP_SLOT";
+ case 1027: return "R_AARCH64_RELATIVE";
+ case 1031: return "R_AARCH64_TLSDESC";
+ default: return "";
+ }
case EM_ARM:
switch(type) {
case 0: return "R_ARM_NONE";
diff --git a/contrib/gcc/config/arm/arm.c b/contrib/gcc/config/arm/arm.c
index 4029e58..d8f1f07 100644
--- a/contrib/gcc/config/arm/arm.c
+++ b/contrib/gcc/config/arm/arm.c
@@ -604,6 +604,8 @@ static const struct processors all_architectures[] =
{"armv6k", mpcore, "6K", FL_CO_PROC | FL_FOR_ARCH6K, NULL},
{"armv6z", arm1176jzs, "6Z", FL_CO_PROC | FL_FOR_ARCH6Z, NULL},
{"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL},
+ /* Clang compatibility... define __ARM_ARCH_7A__, but codegen is still 6ZK. */
+ {"armv7a", arm1176jzs, "7A", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL},
{"ep9312", ep9312, "4T", FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL},
{"iwmmxt", iwmmxt, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL},
{NULL, arm_none, NULL, 0 , NULL}
diff --git a/contrib/libxo/libxo/libxo.c b/contrib/libxo/libxo/libxo.c
index 89adc03..2c97337 100644
--- a/contrib/libxo/libxo/libxo.c
+++ b/contrib/libxo/libxo/libxo.c
@@ -956,9 +956,6 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
}
memcpy(newfmt + plen, fmt, len);
- /* Add a newline to the fmt string */
- if (!(xop->xo_flags & XOF_WARN_XML))
- newfmt[len++ + plen] = '\n';
newfmt[len + plen] = '\0';
if (xop->xo_flags & XOF_WARN_XML) {
@@ -1010,6 +1007,7 @@ xo_warn_hcv (xo_handle_t *xop, int code, int check_warn,
} else {
vfprintf(stderr, newfmt, vap);
+ fprintf(stderr, ": %s\n", strerror(code));
}
}
diff --git a/contrib/libxo/libxo/xo_create.3 b/contrib/libxo/libxo/xo_create.3
index 1e0a69b..ec241ee 100644
--- a/contrib/libxo/libxo/xo_create.3
+++ b/contrib/libxo/libxo/xo_create.3
@@ -76,7 +76,7 @@ https://github.com/Juniper/libxo/releases
.Sh SEE ALSO
.Xr xo_emit 3
and
-.Xf xo_set_options 3 .
+.Xr xo_set_options 3 .
.Sh HISTORY
The
.Fa libxo
diff --git a/contrib/libxo/libxo/xo_emit.3 b/contrib/libxo/libxo/xo_emit.3
index 1128dc7..9f76e13 100644
--- a/contrib/libxo/libxo/xo_emit.3
+++ b/contrib/libxo/libxo/xo_emit.3
@@ -35,7 +35,7 @@ but using a more complex format description string, as described in
.Pp
.Fn xo_emit
uses the default output handle, as described in
-.Xf libxo 3 ,
+.Xr libxo 3 ,
where
.Fn xo_emit_h
uses an explicit handle.
diff --git a/contrib/libxo/libxo/xo_open_container.3 b/contrib/libxo/libxo/xo_open_container.3
index af54d05..9ba32c9 100644
--- a/contrib/libxo/libxo/xo_open_container.3
+++ b/contrib/libxo/libxo/xo_open_container.3
@@ -105,7 +105,7 @@ container, a warning will be generated.
<div class="data"
data-tag="host-name">my-host.example.org</div>
.Ed
-.SH EMITTING HIERARCHY
+.Sh EMITTING HIERARCHY
To create a container, use the
.Fn xo_open_container
and
@@ -131,7 +131,7 @@ traditional C strings can be used directly.
The close functions with the
.Dq _d
suffix are used in
-.Dq Do The Right Thing
+.Dq \&Do The Right Thing
mode, where the name of the open containers, lists, and
instances are maintained internally by
.Em libxo
@@ -161,7 +161,7 @@ Some user may find tracking the names of open containers, lists, and
instances inconvenient.
.Em libxo
offers
-.Dq Do The Right Thing
+.Dq \&Do The Right Thing
mode, where
.Em libxo
will track the names of open containers, lists, and instances so
diff --git a/contrib/mdocml/INSTALL b/contrib/mdocml/INSTALL
index 31ffaf0..cc30f4c 100644
--- a/contrib/mdocml/INSTALL
+++ b/contrib/mdocml/INSTALL
@@ -1,13 +1,12 @@
-$Id: INSTALL,v 1.5 2014/08/18 13:27:47 kristaps Exp $
+$Id: INSTALL,v 1.9 2014/12/11 07:44:46 schwarze Exp $
About mdocml, the portable mandoc distribution
----------------------------------------------
The mandoc manpage compiler toolset is a suite of tools compiling
mdoc(7), the roff(7) macro language of choice for BSD manual pages,
and man(7), the predominant historical language for UNIX manuals.
-The toolset does not yet implement man(1); that is only scheduled
-for the next release, 1.13.2. It can, however, already serve to
-translate source manpages to the output displayed by man(1).
+Since the present version 1.13.2, it includes a man(1) manual viewer
+in addition to the apropos(1) manual page search tool.
For general information, see <http://mdocml.bsd.lv/>.
In this document, we describe the installation and deployment of
@@ -22,7 +21,7 @@ tech@ mailing list, too.
Enjoy using the mandoc toolset!
-Ingo Schwarze, Karlsruhe, August 2014
+Ingo Schwarze, Karlsruhe, December 2014
Installation
@@ -59,8 +58,8 @@ should work. If the build fails, look at "configure.local.example"
and go back to step 2.
4. Run "make -n install" and check whether everything will be
-installed to the intended places. Otherwise, put some *DIR variables
-into "configure.local" and go back to step 2.
+installed to the intended places. Otherwise, put some *DIR or *NM*
+variables into "configure.local" and go back to step 2.
5. Run "sudo make install". If you intend to build a binary
package using some kind of fake root mechanism, you may need a
@@ -70,14 +69,14 @@ in the "Makefile" to understand how DESTDIR is used.
6. To set up a man.cgi(8) server, read its manual page.
7. To use mandoc(1) as your man(1) formatter, read the "Deployment"
-section below.
+sections below.
Understanding mandoc dependencies
---------------------------------
-The mandoc(1), preconv(1), and demandoc(1) utilities have no external
-dependencies. However, makewhatis(8) and apropos(1) depend on the
-following software:
+The mandoc(1) and demandoc(1) utilities have no external dependencies.
+However, makewhatis(8), apropos(1), and man(1) depend on the following
+software:
1. The SQLite database system, see <http://sqlite.org/>.
The recommended version of SQLite is 3.8.4.3 or newer. The mandoc
@@ -89,14 +88,14 @@ fails due to the missing sqlite3_errstr() API. Both are very minor
problems, apropos(1) is fully usable with SQLite 3.7.5. Versions
older than 3.7.5 may or may not work, they have not been tested.
-1.2. The fts(3) directory traversion functions.
+2. The fts(3) directory traversion functions.
If your system does not have them, the bundled compatibility version
will be used, so you need not worry in that case. But be careful: the
glibc version of fts(3) is known to be broken on 32bit platforms,
see <https://sourceware.org/bugzilla/show_bug.cgi?id=15838>.
If you run into that problem, set "HAVE_FTS=0" in configure.local.
-1.3. Marc Espie's ohash(3) library.
+3. Marc Espie's ohash(3) library.
If your system does not have it, the bundled compatibility version
will be used, so you probably need not worry about it.
@@ -145,11 +144,39 @@ in unusual headers. You can also look at the file "config.h" and
check that no "#define HAVE_*" differ from your expectations.
-Deployment
-----------
-If you want to integrate the mandoc(1) tools with your existing
-man(1) system as a formatter, then contact us first: on systems without
-mandoc(1) as the default, you may have your work cut out for you!
+Deployment using the integrated man(1) viewer
+---------------------------------------------
+This mode of deployment requires database support. In case of
+doubt, look at the section "user settings related to database
+support" in the file configure.local.example.
+
+Deployment requires the following steps:
+
+1. Build and install mandoc as described above in steps 2 to 5
+below "Installation".
+
+2. If your system uses manpath(1), make sure it is configured
+correctly, in particular, it returns all directory trees where
+manual pages are installed. If your system uses man.conf(5), make
+sure it contains a "_whatdb" line for each directory tree, and the
+order of these lines meets your wishes.
+
+3. Run the command "sudo makewhatis" to build mandoc.db(5) databases
+in all the directory trees configured in step 2.
+
+At this point, your new man(1), apropos(1), and whatis(1) should work.
+Otherwise, please look at <http://mdocml.bsd.lv/contact.html>, both
+for help and to have these instructions improved.
+
+Whenever installing new manual pages, re-run makewhatis(8) to update
+the databases, or man(1) will not find the new pages.
+
+
+Deployment using your system's native man(1) viewer
+---------------------------------------------------
+This mode of deployment does not require database support,
+so it works even if you don't have SQLite3.
+
Usually, you can have your default installation and mandoc(1) work right
alongside each other by using user-specific versions of the files
mentioned below.
@@ -174,15 +201,17 @@ mandoc(1)" to disregard them.
of cached pages being pulled up. You can usually do this by commenting
out NOCACHE or similar.
+
mandoc(1) still has a long way to go in understanding non-trivial
low-level roff(7) markup embedded in some man(7) pages. On the BSD
systems using mandoc(1), third-party software is generally vetted
on whether it may be formatted with mandoc(1). If not, groff(1)
is pulled in as a dependency and used to install a pre-formatted
-"catpage" intead of directly as manual page source.
+"catpage" instead of directly as manual page source.
For more background on switching operating systems to use mandoc(1)
-instead of groff(1) to format manuals, see the two BSDCan presentations
-by Ingo Schwarze:
+instead of groff(1) to format manuals, see the BSDCan and EuroBSDCon
+presentations by Ingo Schwarze:
<http://www.openbsd.org/papers/bsdcan11-mandoc-openbsd.html>
<http://www.openbsd.org/papers/bsdcan14-mandoc.pdf>
+<http://www.openbsd.org/papers/eurobsdcon2014-mandoc-paper.pdf>
diff --git a/contrib/mdocml/LICENSE b/contrib/mdocml/LICENSE
index db26171..12bf65a 100644
--- a/contrib/mdocml/LICENSE
+++ b/contrib/mdocml/LICENSE
@@ -1,17 +1,17 @@
-$Id: LICENSE,v 1.4 2014/08/21 00:42:38 schwarze Exp $
+$Id: LICENSE,v 1.5 2014/12/11 07:56:24 schwarze Exp $
With the exceptions noted below, all code and documentation
contained in the mdocml toolkit is protected by the Copyright
of the following developers:
-Copyright (c) 2008, 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
+Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
Copyright (c) 2010, 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
Copyright (c) 1998, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
-Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org>
+Copyright (c) 2003, 2007, 2008, 2014 Jason McIntyre <jmc@openbsd.org>
See the individual source files for information about who contributed
to which file during which years.
diff --git a/contrib/mdocml/Makefile b/contrib/mdocml/Makefile
index a8255fe..e3f48f7 100644
--- a/contrib/mdocml/Makefile
+++ b/contrib/mdocml/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.448 2014/11/28 18:57:31 schwarze Exp $
+# $Id: Makefile,v 1.453 2014/12/09 09:14:33 schwarze Exp $
#
# Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
# Copyright (c) 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,9 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-BASEBIN = mandoc demandoc
-DBBIN = makewhatis
-CGIBIN = man.cgi
+# === LIST OF FILES ====================================================
TESTSRCS = test-dirent-namlen.c \
test-fgetln.c \
@@ -131,6 +129,7 @@ DISTFILES = INSTALL \
mandoc_aux.h \
mandoc_char.7 \
mandoc_escape.3 \
+ mandoc_headers.3 \
mandoc_html.3 \
mandoc_malloc.3 \
manpath.h \
@@ -208,18 +207,19 @@ MANDOC_TERM_OBJS = eqn_term.o \
term_ps.o \
tbl_term.o
-MANDOC_OBJS = $(MANDOC_HTML_OBJS) \
+BASE_OBJS = $(MANDOC_HTML_OBJS) \
$(MANDOC_MAN_OBJS) \
$(MANDOC_TERM_OBJS) \
main.o \
out.o \
tree.o
-MAN_OBJS = $(MANDOC_OBJS)
+MAIN_OBJS = $(BASE_OBJS)
-MAKEWHATIS_OBJS = mandocdb.o mansearch_const.o manpath.o
-
-APROPOS_OBJS = mansearch.o mansearch_const.o manpath.o
+DB_OBJS = mandocdb.o \
+ mansearch.o \
+ mansearch_const.o \
+ manpath.o
CGI_OBJS = $(MANDOC_HTML_OBJS) \
cgi.o \
@@ -237,6 +237,7 @@ WWW_MANS = apropos.1.html \
mandoc.1.html \
mandoc.3.html \
mandoc_escape.3.html \
+ mandoc_headers.3.html \
mandoc_html.3.html \
mandoc_malloc.3.html \
mansearch.3.html \
@@ -261,19 +262,17 @@ WWW_MANS = apropos.1.html \
WWW_OBJS = mdocml.tar.gz \
mdocml.sha256
-include Makefile.local
+# === USER CONFIGURATION ===============================================
-INSTALL_TARGETS = $(BUILD_TARGETS:-build=-install)
+include Makefile.local
# === DEPENDENCY HANDLING ==============================================
all: base-build $(BUILD_TARGETS) Makefile.local
-base-build: $(BASEBIN)
-
-db-build: $(DBBIN)
+base-build: mandoc demandoc
-cgi-build: $(CGIBIN)
+cgi-build: man.cgi
install: base-install $(INSTALL_TARGETS)
@@ -281,6 +280,9 @@ www: $(WWW_OBJS) $(WWW_MANS)
$(WWW_MANS): mandoc
+.PHONY: base-install cgi-install db-install install www-install
+.PHONY: clean distclean depend
+
include Makefile.depend
# === TARGETS CONTAINING SHELL COMMANDS ================================
@@ -290,8 +292,7 @@ distclean: clean
clean:
rm -f libmandoc.a $(LIBMANDOC_OBJS) $(COMPAT_OBJS)
- rm -f mandoc $(MANDOC_OBJS) $(APROPOS_OBJS)
- rm -f makewhatis $(MAKEWHATIS_OBJS)
+ rm -f mandoc $(BASE_OBJS) $(DB_OBJS)
rm -f man.cgi $(CGI_OBJS)
rm -f manpage $(MANPAGE_OBJS)
rm -f demandoc $(DEMANDOC_OBJS)
@@ -306,34 +307,41 @@ base-install: base-build
mkdir -p $(DESTDIR)$(MANDIR)/man1
mkdir -p $(DESTDIR)$(MANDIR)/man3
mkdir -p $(DESTDIR)$(MANDIR)/man7
- $(INSTALL_PROGRAM) $(BASEBIN) $(DESTDIR)$(BINDIR)
+ $(INSTALL_PROGRAM) mandoc demandoc $(DESTDIR)$(BINDIR)
$(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR)
$(INSTALL_LIB) man.h mandoc.h mandoc_aux.h mdoc.h \
$(DESTDIR)$(INCLUDEDIR)
- $(INSTALL_MAN) man.1 mandoc.1 demandoc.1 \
- $(DESTDIR)$(MANDIR)/man1
+ $(INSTALL_MAN) mandoc.1 demandoc.1 $(DESTDIR)$(MANDIR)/man1
$(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \
mchars_alloc.3 tbl.3 $(DESTDIR)$(MANDIR)/man3
- $(INSTALL_MAN) man.7 mdoc.7 roff.7 eqn.7 tbl.7 mandoc_char.7 \
- $(DESTDIR)$(MANDIR)/man7
+ $(INSTALL_MAN) man.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MAN}.7
+ $(INSTALL_MAN) mdoc.7 $(DESTDIR)$(MANDIR)/man7/${MANM_MDOC}.7
+ $(INSTALL_MAN) roff.7 $(DESTDIR)$(MANDIR)/man7/${MANM_ROFF}.7
+ $(INSTALL_MAN) eqn.7 $(DESTDIR)$(MANDIR)/man7/${MANM_EQN}.7
+ $(INSTALL_MAN) tbl.7 $(DESTDIR)$(MANDIR)/man7/${MANM_TBL}.7
+ $(INSTALL_MAN) mandoc_char.7 $(DESTDIR)$(MANDIR)/man7
$(INSTALL_DATA) example.style.css $(DESTDIR)$(EXAMPLEDIR)
-db-install: db-build
+db-install: base-build
mkdir -p $(DESTDIR)$(BINDIR)
mkdir -p $(DESTDIR)$(SBINDIR)
mkdir -p $(DESTDIR)$(MANDIR)/man1
mkdir -p $(DESTDIR)$(MANDIR)/man3
mkdir -p $(DESTDIR)$(MANDIR)/man5
mkdir -p $(DESTDIR)$(MANDIR)/man8
- ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/apropos
- ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/whatis
- $(INSTALL_PROGRAM) makewhatis $(DESTDIR)$(SBINDIR)
- $(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1
- ln -f $(DESTDIR)$(MANDIR)/man1/apropos.1 \
- $(DESTDIR)$(MANDIR)/man1/whatis.1
+ ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_APROPOS)
+ ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_MAN)
+ ln -f $(DESTDIR)$(BINDIR)/mandoc $(DESTDIR)$(BINDIR)/$(BINM_WHATIS)
+ ln -f $(DESTDIR)$(BINDIR)/mandoc \
+ $(DESTDIR)$(SBINDIR)/$(BINM_MAKEWHATIS)
+ $(INSTALL_MAN) apropos.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1
+ $(INSTALL_MAN) man.1 $(DESTDIR)$(MANDIR)/man1/$(BINM_MAN).1
+ ln -f $(DESTDIR)$(MANDIR)/man1/$(BINM_APROPOS).1 \
+ $(DESTDIR)$(MANDIR)/man1/$(BINM_WHATIS).1
$(INSTALL_MAN) mansearch.3 $(DESTDIR)$(MANDIR)/man3
$(INSTALL_MAN) mandoc.db.5 $(DESTDIR)$(MANDIR)/man5
- $(INSTALL_MAN) makewhatis.8 $(DESTDIR)$(MANDIR)/man8
+ $(INSTALL_MAN) makewhatis.8 \
+ $(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8
cgi-install: cgi-build
mkdir -p $(DESTDIR)$(CGIBINDIR)
@@ -346,34 +354,15 @@ cgi-install: cgi-build
$(INSTALL_MAN) apropos.1 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man1/
$(INSTALL_MAN) man.cgi.8 $(DESTDIR)$(WWWPREFIX)/man/mandoc/man8/
-www-install: www
- mkdir -p $(DESTDIR)$(HTDOCDIR)/snapshots
- $(INSTALL_DATA) $(WWW_MANS) style.css $(DESTDIR)$(HTDOCDIR)
- $(INSTALL_DATA) $(WWW_OBJS) $(DESTDIR)$(HTDOCDIR)/snapshots
- $(INSTALL_DATA) mdocml.tar.gz \
- $(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz
- $(INSTALL_DATA) mdocml.sha256 \
- $(DESTDIR)$(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256
-
Makefile.local config.h: configure ${TESTSRCS}
@echo "$@ is out of date; please run ./configure"
@exit 1
-depend: config.h
- mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
- perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
- s|\\\n||g; s| +| |g; s| $$||mg; print;' \
- Makefile.depend > Makefile.tmp
- mv Makefile.tmp Makefile.depend
-
libmandoc.a: $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
$(AR) rs $@ $(COMPAT_OBJS) $(LIBMANDOC_OBJS)
-mandoc: $(MAN_OBJS) libmandoc.a
- $(CC) $(LDFLAGS) -o $@ $(MAN_OBJS) libmandoc.a $(DBLIB)
-
-makewhatis: $(MAKEWHATIS_OBJS) libmandoc.a
- $(CC) $(LDFLAGS) -o $@ $(MAKEWHATIS_OBJS) libmandoc.a $(DBLIB)
+mandoc: $(MAIN_OBJS) libmandoc.a
+ $(CC) $(LDFLAGS) -o $@ $(MAIN_OBJS) libmandoc.a $(DBLIB)
manpage: $(MANPAGE_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(MANPAGE_OBJS) libmandoc.a $(DBLIB)
@@ -384,6 +373,24 @@ man.cgi: $(CGI_OBJS) libmandoc.a
demandoc: $(DEMANDOC_OBJS) libmandoc.a
$(CC) $(LDFLAGS) -o $@ $(DEMANDOC_OBJS) libmandoc.a
+# --- maintainer targets ---
+
+www-install: www
+ mkdir -p $(HTDOCDIR)/snapshots
+ $(INSTALL_DATA) $(WWW_MANS) style.css $(HTDOCDIR)/man
+ $(INSTALL_DATA) $(WWW_OBJS) $(HTDOCDIR)/snapshots
+ $(INSTALL_DATA) mdocml.tar.gz \
+ $(HTDOCDIR)/snapshots/mdocml-$(VERSION).tar.gz
+ $(INSTALL_DATA) mdocml.sha256 \
+ $(HTDOCDIR)/snapshots/mdocml-$(VERSION).sha256
+
+depend: config.h
+ mkdep -f Makefile.depend $(CFLAGS) $(SRCS)
+ perl -e 'undef $$/; $$_ = <>; s|/usr/include/\S+||g; \
+ s|\\\n||g; s| +| |g; s| $$||mg; print;' \
+ Makefile.depend > Makefile.tmp
+ mv Makefile.tmp Makefile.depend
+
mdocml.sha256: mdocml.tar.gz
sha256 mdocml.tar.gz > $@
@@ -394,8 +401,8 @@ mdocml.tar.gz: $(DISTFILES)
( cd .dist/ && tar zcf ../$@ mdocml-$(VERSION) )
rm -rf .dist/
-.PHONY: base-install cgi-install db-install install www-install
-.PHONY: clean distclean depend
+# === SUFFIX RULES =====================================================
+
.SUFFIXES: .1 .3 .5 .7 .8 .h
.SUFFIXES: .1.html .3.html .5.html .7.html .8.html .h.html
diff --git a/contrib/mdocml/Makefile.depend b/contrib/mdocml/Makefile.depend
index d3c13e0..a61de19 100644
--- a/contrib/mdocml/Makefile.depend
+++ b/contrib/mdocml/Makefile.depend
@@ -15,12 +15,12 @@ demandoc.o: demandoc.c config.h man.h mdoc.h mandoc.h
eqn.o: eqn.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h
eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h
-html.o: html.c config.h mandoc.h mandoc_aux.h libmandoc.h out.h html.h main.h
+html.o: html.c config.h mandoc.h mandoc_aux.h out.h html.h main.h
lib.o: lib.c config.h mdoc.h libmdoc.h lib.in
main.o: main.c config.h mandoc.h mandoc_aux.h main.h mdoc.h man.h manpath.h mansearch.h
man.o: man.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
-man_hash.o: man_hash.c config.h man.h mandoc.h libman.h
-man_html.o: man_html.c config.h mandoc.h mandoc_aux.h out.h html.h man.h main.h
+man_hash.o: man_hash.c config.h man.h libman.h
+man_html.o: man_html.c config.h mandoc_aux.h man.h out.h html.h main.h
man_macro.o: man_macro.c config.h man.h mandoc.h libmandoc.h libman.h
man_term.o: man_term.c config.h mandoc.h mandoc_aux.h out.h man.h term.h main.h
man_validate.o: man_validate.c config.h man.h mandoc.h mandoc_aux.h libman.h libmandoc.h
@@ -30,19 +30,19 @@ mandocdb.o: mandocdb.c config.h compat_fts.h compat_ohash.h mdoc.h man.h mandoc.
manpage.o: manpage.c config.h manpath.h mansearch.h
manpath.o: manpath.c config.h mandoc_aux.h manpath.h
mansearch.o: mansearch.c config.h compat_ohash.h mandoc.h mandoc_aux.h manpath.h mansearch.h
-mansearch_const.o: mansearch_const.c config.h manpath.h mansearch.h
+mansearch_const.o: mansearch_const.c config.h mansearch.h
mdoc.o: mdoc.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
mdoc_argv.o: mdoc_argv.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
mdoc_hash.o: mdoc_hash.c config.h mdoc.h libmdoc.h
-mdoc_html.o: mdoc_html.c config.h mandoc.h mandoc_aux.h out.h html.h mdoc.h main.h
+mdoc_html.o: mdoc_html.c config.h mandoc_aux.h mdoc.h out.h html.h main.h
mdoc_macro.o: mdoc_macro.c config.h mdoc.h mandoc.h libmdoc.h libmandoc.h
mdoc_man.o: mdoc_man.c config.h mandoc.h mandoc_aux.h out.h man.h mdoc.h main.h
mdoc_term.o: mdoc_term.c config.h mandoc.h mandoc_aux.h out.h term.h mdoc.h main.h
mdoc_validate.o: mdoc_validate.c config.h mdoc.h mandoc.h mandoc_aux.h libmdoc.h libmandoc.h
-msec.o: msec.c config.h mandoc.h libmandoc.h msec.in
+msec.o: msec.c config.h libmandoc.h msec.in
out.o: out.c config.h mandoc_aux.h mandoc.h out.h
preconv.o: preconv.c config.h mandoc.h libmandoc.h
-read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h main.h
+read.o: read.c config.h mandoc.h mandoc_aux.h libmandoc.h mdoc.h man.h
roff.o: roff.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h predefs.in
st.o: st.c config.h mdoc.h libmdoc.h st.in
tbl.o: tbl.c config.h mandoc.h mandoc_aux.h libmandoc.h libroff.h
@@ -53,7 +53,7 @@ tbl_opts.o: tbl_opts.c config.h mandoc.h libmandoc.h libroff.h
tbl_term.o: tbl_term.c config.h mandoc.h out.h term.h
term.o: term.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
term_ascii.o: term_ascii.c config.h mandoc.h mandoc_aux.h out.h term.h main.h
-term_ps.o: term_ps.c config.h mandoc.h mandoc_aux.h out.h main.h term.h
+term_ps.o: term_ps.c config.h mandoc_aux.h out.h term.h main.h
tree.o: tree.c config.h mandoc.h mdoc.h man.h main.h
test-dirent-namlen.o: test-dirent-namlen.c
test-fgetln.o: test-fgetln.c
diff --git a/contrib/mdocml/NEWS b/contrib/mdocml/NEWS
index f47a807..fbcdfc2 100644
--- a/contrib/mdocml/NEWS
+++ b/contrib/mdocml/NEWS
@@ -1,7 +1,76 @@
-$Id: NEWS,v 1.6 2014/08/11 01:39:00 schwarze Exp $
+$Id: NEWS,v 1.8 2014/12/13 13:43:47 schwarze Exp $
This file lists the most important changes in the mdocml.bsd.lv distribution.
+Changes in version 1.13.2, released on December 13, 2014
+
+ --- MAJOR NEW FEATURES ---
+ * Include an implementation of man(1), the manual page viewer.
+ * Unified set of command line option, each one supported by all
+ command names, including new options -a (format all), -c (no
+ pager), -h (synopsis only), and -w (list filenames).
+ * Support the MANPAGER and PAGER environment variables.
+ * Support gzip'ed manuals by the whole toolset, even as .so targets.
+ * Support UTF-8 and Latin-1 input by the whole toolset, delete preconv(1).
+ * Switch the default output mode from -Tascii to -Tlocale.
+ * Improve -Tascii output for Unicode escape sequences.
+ * Let the -Thtml output mode produce polyglot HTML5.
+ * Many improvements for eqn(7), in particular in-line equations,
+ MathML output in -Thtml mode, and much improved terminal formatting.
+ --- PORTABILITY IMPROVEMENTS ---
+ * Change the build sequence to the usual ./configure; make; make install.
+ * Support ./configure.local for build customizations.
+ * Autodetect wchar, sqlite3, and manpath support.
+ * Provide a fallback version of fts(3) for systems lacking it.
+ * Support choosing alternative binary and manual names.
+ --- MINOR NEW FEATURES ---
+ * Rudimentary implementation of the e, x, and z tbl(7) layout
+ modifiers to equalize, maximize, and ignore the width of columns.
+ * Implement font modifiers in tbl(7) layouts.
+ * Allow comma-separated options in the tbl(7) options line.
+ * Parse and ignore the .pl (page length) roff(7) request.
+ * Implement .An -[no]split for the mdoc(7) -Thtml output mode.
+ * Support bold italic font in PostScript and PDF output.
+ * Warn about commas in function arguments and parentheses in function names.
+ * Warn about botched .Xr ordering and punctuation below SEE ALSO.
+ * Warn about AUTHORS sections without .An macros.
+ * Warn about attempts to call non-callable macros.
+ * New developer documentation manual page mandoc_headers(3).
+ --- BUGFIXES ---
+ * Fix read buffer overrun sometimes triggered by trailing whitespace.
+ * Fix read buffer overrun triggered by certain invalid \H sequences.
+ * Fix NULL pointer access triggered by .Bl without any arguments.
+ * Fix NULL pointer access triggered by .It Nm Fo without .Fc.
+ * Fix NULL pointer access triggered by .Sh Xo .Sh without .Xc.
+ * Fix NULL pointer access triggered by missing .Nm.
+ * Fix an assertion triggered by .It right after .El.
+ * Fix an assertion triggered by .Ec without preceding .Eo.
+ * Fix an assertion triggered by .Sm or .Db with multiple arguments.
+ * Fix assertion failures triggered by very large width arguments.
+ * Fix a division by zero in the roff(7) parser.
+ * Prevent negative arguments to .ll from causing integer underflow.
+ * Correctly autodetect source format even when .Dd is preceded by .ll.
+ * Multiple fixes with respect to .Bd and .Bl -offset and -width.
+ * Many bugfixes with respect to scaling units.
+ * Multiple fixes with respect to delimiter handling by in-line macros.
+ * Multiple fixes with respect to .Pf.
+ * Make \c work properly in no-fill mode.
+ * Stricter syntax checking of Unicode character names.
+ --- THANKS TO ---
+ * Kristaps Dzonsons for rewriting the eqn(7) parser, implementing
+ HTML5 and MathML output, and various other code contributions.
+ * Jonathan Gray (OpenBSD) for extensive testing with afl (the
+ American Fuzzy Lop security fuzzer) resulting in many bug reports.
+ * Anthony Bentley (OpenBSD), Baptiste Daroussin (FreeBSD), Daniel
+ Dickman, Doug Hogan, Jason McIntyre, Theo de Raadt (OpenBSD),
+ and Martin Natano for source code patches.
+ * Carsten Kunze (Heirloom troff), Daniel Levai (Slackware),
+ Garrett D'Amore (illumos), Giovanni Becchis, Matthew Dempsky,
+ Stuart Henderson, Ted Unangst, Todd Miller (OpenBSD), Thomas
+ Klausner (NetBSD), Ulrich Spoerlein (FreeBSD), Justin Haynes,
+ Marcus Merighi, Sebastien Marie, Steffen Nurpmeso and Theo Buehler
+ for bug reports.
+
Changes in version 1.13.1, released on August 10, 2014
--- MAJOR NEW FEATURES ---
diff --git a/contrib/mdocml/TODO b/contrib/mdocml/TODO
index 98cb687..b213e8b 100644
--- a/contrib/mdocml/TODO
+++ b/contrib/mdocml/TODO
@@ -1,6 +1,6 @@
************************************************************************
* Official mandoc TODO.
-* $Id: TODO,v 1.189 2014/11/26 21:40:17 schwarze Exp $
+* $Id: TODO,v 1.195 2014/12/13 13:14:39 schwarze Exp $
************************************************************************
Many issues are annotated for difficulty as follows:
@@ -72,7 +72,8 @@ are mere guesses, and some may be wrong.
- .ta (tab settings) occurs in ircbug(1) and probably gnats(1)
reported by brad@ Sat, 15 Jan 2011 15:50:51 -0500
also Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100
- loc ** exist *** algo ** size ** imp **
+ also posix2time(3) Carsten Kunze Mon, 1 Dec 2014 13:03:10 +0100
+ loc ** exist *** algo ** size ** imp ***
- .ti (temporary indent)
found by naddy@ in xloadimage(1)
@@ -83,14 +84,10 @@ are mere guesses, and some may be wrong.
found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200
loc * exist ** algo ** size ** imp **
-- \c (interrupted text) should prevent the line break
- even inside .Bd literal; that occurs in chat(8)
- also found in cclive(1) - DocBook output
- loc ** exist *** algo ** size * imp *
-
- \h horizontal move
- found in cclive(1) DocBook output
- Anthony J. Bentley on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
+ found in cclive(1) and nasm(1) asciidoc/DocBook output
+ bentley@ on discuss@ Sat, 21 Sep 2013 22:29:34 -0600
+ naddy@ Thu, 4 Dec 2014 16:26:41 +0100
loc ** exist ** algo ** size * imp ** (parser reorg helps a lot)
- \n+ and \n- numerical register increment and decrement
@@ -125,13 +122,6 @@ are mere guesses, and some may be wrong.
from jmc@ Wed, 14 Jul 2010 18:10:32 +0100
loc * exist *** algo *** size ** imp **
-- \\ is now implemented correctly
- * when defining strings and macros using .ds and .de
- * when parsing roff(7) and man(7) macro arguments
- It does not yet work in mdoc(7) macro arguments
- because libmdoc does not yet use mandoc_getarg().
- Also check what happens in plain text, it must be identical to \e.
-
- .Bd -centered implies -filled, not -unfilled, which is not
easy to implement; it requires code similar to .ce, which
we don't have either.
@@ -172,12 +162,6 @@ are mere guesses, and some may be wrong.
is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab."
but should give "ab ."
-- set a meaningful default if no `Bl' list type is assigned
- loc * exist * algo * size * imp ** (already done?)
-
-- have a blank `It' head for `Bl -tag' not puke
- loc * exist * algo * size * imp ** (already done?)
-
- check whether it is correct that `D1' uses INDENT+1;
does it need its own constant?
loc * exist ** algo ** size * imp **
@@ -315,9 +299,18 @@ are mere guesses, and some may be wrong.
* formatting issues: ugly output
************************************************************************
-- a column list with blank `Ta' cells triggers a spurrious
+- revisit empty in-line macros
+ look at the difference between "Em x Em ." and "Sq x Em ."
+ Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100
+ loc *** exist *** algo *** size * imp **
+
+- a column list with blank `Ta' cells triggers a spurious
start-with-whitespace printing of a newline
+- In .Bl -column, .It a<tab>"b<tab>c"
+ shows the quotes in groff, but not in mandoc
+ loc * exist *** algo ** size * imp **
+
- In .Bl -column,
.It Em Authentication<tab>Key Length
ought to render "Key Length" with emphasis, too,
@@ -403,16 +396,6 @@ are mere guesses, and some may be wrong.
Steffen Nurpmeso Sat, 08 Nov 2014 13:34:59 +0100
loc * exist ** algo ** size * imp **
-- .Rv (and probably .Ex) print different text if an `Nm' has been named
- or not (run a manual without `Nm blah' to see this). I'm not sure
- that this exists in the wild, but it's still an error.
- loc * exist * algo * size * imp * (already done?)
-
-- In .Bl -bullet, the groff bullet is "+\b+\bo\bo", the mandoc bullet
- is just "o\bo". The problem is to not break ps/pdf when fixing.
- see for example OpenBSD ksh(1)
- loc ** exist ** algo ** size * imp **
-
- In .Bl -enum -width 0n, groff continues one the same line after
the number, mandoc breaks the line.
mail to kristaps@ Mon, 20 Jul 2009 02:21:39 +0200
@@ -601,3 +584,9 @@ Several areas can be cleaned up to make mandoc even faster. These are
- Have Mac OSX systems automatically disable -static compilation of the
CGI: -static isn't supported.
+************************************************************************
+* to improve in the groff_mdoc(7) macros
+************************************************************************
+
+- use uname(1) to set doc-default-operating-system at install time
+ tobimensch Mon, 1 Dec 2014 00:25:07 +0100
diff --git a/contrib/mdocml/compat_fts.c b/contrib/mdocml/compat_fts.c
index 4caf74c..d6e99e6 100644
--- a/contrib/mdocml/compat_fts.c
+++ b/contrib/mdocml/compat_fts.c
@@ -6,8 +6,8 @@ int dummy;
#else
-/* $Id: compat_fts.c,v 1.4 2014/08/17 20:45:59 schwarze Exp $ */
-/* $OpenBSD: fts.c,v 1.46 2014/05/25 17:47:04 tedu Exp $ */
+/* $Id: compat_fts.c,v 1.6 2014/12/11 18:20:07 schwarze Exp $ */
+/* $OpenBSD: fts.c,v 1.49 2014/11/23 00:14:22 guenther Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -62,6 +62,10 @@ static unsigned short fts_stat(FTS *, FTSENT *);
static int fts_safe_changedir(FTS *, FTSENT *, int, const char *);
#define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#ifndef O_DIRECTORY
+#define O_DIRECTORY 0
+#endif
#define CLR(opt) (sp->fts_options &= ~(opt))
#define ISSET(opt) (sp->fts_options & (opt))
@@ -146,7 +150,8 @@ fts_open(char * const *argv, int options, void *dummy)
* and ".." are all fairly nasty problems. Note, if we can't get the
* descriptor we run anyway, just more slowly.
*/
- if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY, 0)) < 0)
+ if (!ISSET(FTS_NOCHDIR) &&
+ (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) < 0)
SET(FTS_NOCHDIR);
if (nitems == 0)
@@ -406,7 +411,7 @@ fts_build(FTS *sp)
DIR *dirp;
void *oldaddr;
size_t dlen, len, maxlen;
- int nitems, cderrno, descend, level, nlinks, nostat, doadjust;
+ int nitems, cderrno, descend, level, doadjust;
int saved_errno;
char *cp;
@@ -424,14 +429,6 @@ fts_build(FTS *sp)
}
/*
- * Nlinks is the number of possible entries of type directory in the
- * directory if we're cheating on stat calls, 0 if we're not doing
- * any stat calls at all, -1 if we're doing stats on everything.
- */
- nlinks = -1;
- nostat = 0;
-
- /*
* If we're going to need to stat anything or we want to descend
* and stay in the directory, chdir. If this fails we keep going,
* but set a flag so we don't chdir after the post-order visit.
@@ -448,8 +445,7 @@ fts_build(FTS *sp)
*/
cderrno = 0;
if (fts_safe_changedir(sp, cur, dirfd(dirp), NULL)) {
- if (nlinks)
- cur->fts_errno = errno;
+ cur->fts_errno = errno;
cur->fts_flags |= FTS_DONTCHDIR;
descend = 0;
cderrno = errno;
@@ -544,21 +540,9 @@ mem1: saved_errno = errno;
}
if (cderrno) {
- if (nlinks) {
- p->fts_info = FTS_NS;
- p->fts_errno = cderrno;
- } else
- p->fts_info = FTS_NSOK;
+ p->fts_info = FTS_NS;
+ p->fts_errno = cderrno;
p->fts_accpath = cur->fts_accpath;
- } else if (nlinks == 0
-#ifdef DT_DIR
- || (nostat &&
- dp->d_type != DT_DIR && dp->d_type != DT_UNKNOWN)
-#endif
- ) {
- p->fts_accpath =
- ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
- p->fts_info = FTS_NSOK;
} else {
/* Build a file name for fts_stat to stat. */
if (ISSET(FTS_NOCHDIR)) {
@@ -568,11 +552,6 @@ mem1: saved_errno = errno;
p->fts_accpath = p->fts_name;
/* Stat it. */
p->fts_info = fts_stat(sp, p);
-
- /* Decrement link count if applicable. */
- if (nlinks > 0 && (p->fts_info == FTS_D ||
- p->fts_info == FTS_DC || p->fts_info == FTS_DOT))
- --nlinks;
}
/* We walk in directory order so "ls -f" doesn't get upset. */
@@ -803,7 +782,7 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path)
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
- if (fd < 0 && (newfd = open(path, O_RDONLY, 0)) < 0)
+ if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
return (-1);
if (fstat(newfd, &sb)) {
ret = -1;
diff --git a/contrib/mdocml/compat_reallocarray.c b/contrib/mdocml/compat_reallocarray.c
index 6e96a6a..6615190 100644
--- a/contrib/mdocml/compat_reallocarray.c
+++ b/contrib/mdocml/compat_reallocarray.c
@@ -6,7 +6,8 @@ int dummy;
#else
-/* $OpenBSD: malloc.c,v 1.158 2014/04/23 15:07:27 tedu Exp $ */
+/* $Id: compat_reallocarray.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */
+/* $OpenBSD: reallocarray.c,v 1.2 2014/12/08 03:45:00 bcook Exp $ */
/*
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
*
@@ -22,12 +23,17 @@ int dummy;
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+
#include <sys/types.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
-#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4))
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
void *
reallocarray(void *optr, size_t nmemb, size_t size)
diff --git a/contrib/mdocml/compat_strcasestr.c b/contrib/mdocml/compat_strcasestr.c
index 0706ee0..62c0ff7 100644
--- a/contrib/mdocml/compat_strcasestr.c
+++ b/contrib/mdocml/compat_strcasestr.c
@@ -6,7 +6,8 @@ int dummy;
#else
-/* ($)NetBSD: strcasestr.c,v 1.2 2005/02/09 21:35:47 kleink Exp $ */
+/* $Id: compat_strcasestr.c,v 1.4 2014/12/11 09:19:32 schwarze Exp $ */
+/* $NetBSD: strcasestr.c,v 1.3 2005/11/29 03:12:00 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
diff --git a/contrib/mdocml/compat_strsep.c b/contrib/mdocml/compat_strsep.c
index 348f7eb..1df5758 100644
--- a/contrib/mdocml/compat_strsep.c
+++ b/contrib/mdocml/compat_strsep.c
@@ -6,7 +6,8 @@ int dummy;
#else
-/* ($)OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */
+/* $Id: compat_strsep.c,v 1.4 2014/12/11 09:05:01 schwarze Exp $ */
+/* $OpenBSD: strsep.c,v 1.7 2014/02/05 20:42:32 stsp Exp $ */
/*-
* Copyright (c) 1990, 1993
diff --git a/contrib/mdocml/config.h b/contrib/mdocml/config.h
index 0220c99..bc16d92 100644
--- a/contrib/mdocml/config.h
+++ b/contrib/mdocml/config.h
@@ -7,7 +7,7 @@
#include <sys/types.h>
-#define VERSION "1.13.1"
+#define VERSION "1.13.2"
#define HAVE_DIRENT_NAMLEN 1
#define HAVE_FGETLN 1
#define HAVE_FTS 1
@@ -25,6 +25,11 @@
#define HAVE_OHASH 1
#define HAVE_MANPATH 1
+#define BINM_APROPOS "apropos"
+#define BINM_MAN "man"
+#define BINM_WHATIS "whatis"
+#define BINM_MAKEWHATIS "makewhatis"
+
#if !defined(__BEGIN_DECLS)
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
diff --git a/contrib/mdocml/configure b/contrib/mdocml/configure
index 0fb841c..57ac898 100755
--- a/contrib/mdocml/configure
+++ b/contrib/mdocml/configure
@@ -31,7 +31,7 @@ echo "config.log: writing..."
# Initialize all variables here,
# such that nothing can leak in from the environment.
-VERSION="1.13.1"
+VERSION="1.13.2"
echo "VERSION=\"${VERSION}\"" 1>&2
echo "VERSION=\"${VERSION}\"" 1>&3
@@ -75,6 +75,16 @@ WWWPREFIX="/var/www"
HTDOCDIR=
CGIBINDIR=
+BINM_APROPOS="apropos"
+BINM_MAN="man"
+BINM_WHATIS="whatis"
+BINM_MAKEWHATIS="makewhatis"
+MANM_MAN="man"
+MANM_MDOC="mdoc"
+MANM_ROFF="roff"
+MANM_EQN="eqn"
+MANM_TBL="tbl"
+
INSTALL="install"
INSTALL_PROGRAM=
INSTALL_LIB=
@@ -285,6 +295,11 @@ cat << __HEREDOC__
#define HAVE_OHASH ${HAVE_OHASH}
#define HAVE_MANPATH ${HAVE_MANPATH}
+#define BINM_APROPOS "${BINM_APROPOS}"
+#define BINM_MAN "${BINM_MAN}"
+#define BINM_WHATIS "${BINM_WHATIS}"
+#define BINM_MAKEWHATIS "${BINM_MAKEWHATIS}"
+
#if !defined(__BEGIN_DECLS)
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
@@ -358,12 +373,15 @@ if [ ${BUILD_DB} -eq 0 -a ${BUILD_CGI} -gt 0 ]; then
fi
BUILD_TARGETS="base-build"
-[ ${BUILD_DB} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} db-build"
[ ${BUILD_CGI} -gt 0 ] && BUILD_TARGETS="${BUILD_TARGETS} cgi-build"
+INSTALL_TARGETS="base-install"
+[ ${BUILD_DB} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} db-install"
+[ ${BUILD_CGI} -gt 0 ] && INSTALL_TARGETS="${INSTALL_TARGETS} cgi-install"
cat << __HEREDOC__
VERSION = ${VERSION}
BUILD_TARGETS = ${BUILD_TARGETS}
+INSTALL_TARGETS = ${INSTALL_TARGETS}
CFLAGS = ${CFLAGS}
DBLIB = ${DBLIB}
STATIC = ${STATIC}
@@ -377,6 +395,15 @@ EXAMPLEDIR = ${EXAMPLEDIR}
WWWPREFIX = ${WWWPREFIX}
HTDOCDIR = ${HTDOCDIR}
CGIBINDIR = ${CGIBINDIR}
+BINM_APROPOS = ${BINM_APROPOS}
+BINM_MAN = ${BINM_MAN}
+BINM_WHATIS = ${BINM_WHATIS}
+BINM_MAKEWHATIS = ${BINM_MAKEWHATIS}
+MANM_MAN = ${MANM_MAN}
+MANM_MDOC = ${MANM_MDOC}
+MANM_ROFF = ${MANM_ROFF}
+MANM_EQN = ${MANM_EQN}
+MANM_TBL = ${MANM_TBL}
INSTALL = ${INSTALL}
INSTALL_PROGRAM = ${INSTALL_PROGRAM}
INSTALL_LIB = ${INSTALL_LIB}
@@ -385,7 +412,7 @@ INSTALL_DATA = ${INSTALL_DATA}
__HEREDOC__
[ ${BUILD_DB} -gt 0 ] && \
- echo "MAN_OBJS = \$(MANDOC_OBJS) \$(APROPOS_OBJS)"
+ echo "MAIN_OBJS = \$(BASE_OBJS) \$(DB_OBJS)"
echo "Makefile.local: written" 1>&2
echo "Makefile.local: written" 1>&3
diff --git a/contrib/mdocml/configure.local.example b/contrib/mdocml/configure.local.example
index 76dcc62..037d48a 100644
--- a/contrib/mdocml/configure.local.example
+++ b/contrib/mdocml/configure.local.example
@@ -1,4 +1,4 @@
-# $Id: configure.local.example,v 1.1 2014/08/16 19:00:01 schwarze Exp $
+# $Id: configure.local.example,v 1.2 2014/12/09 09:14:33 schwarze Exp $
#
# Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
#
@@ -58,7 +58,7 @@ HAVE_WCHAR=0
# If you do not want uname(3) to be called but instead want a fixed
# string to be used, use the following line:
-OSNAME="OpenBSD 5.5"
+OSNAME="OpenBSD 5.6"
# The following installation directories are used.
# It is possible to set only one or a few of these variables,
@@ -74,6 +74,19 @@ LIBDIR="${PREFIX}/lib/mandoc"
MANDIR="${PREFIX}/man"
EXAMPLEDIR="${PREFIX}/share/examples/mandoc"
+# Some distributions may want to avoid naming conflicts among manuals.
+# If you want to change the names of installed section 7 manual pages,
+# the following alternative names are suggested.
+# The suffix ".7" will automatically be appended.
+# It is possible to set only one or a few of these variables,
+# there is no need to copy the whole block.
+
+MANM_MAN="mandoc_man" # default is "man"
+MANM_MDOC="mandoc_mdoc" # default is "mdoc"
+MANM_ROFF="mandoc_roff" # default is "roff"
+MANM_EQN="mandoc_eqn" # default is "eqn"
+MANM_TBL="mandoc_tbl" # default is "tbl"
+
# It is possible to change the utility program used for installation
# and the modes files are installed with. The defaults are:
@@ -125,6 +138,21 @@ HAVE_MANPATH=1
HAVE_MANPATH=0
+# Some distributions may want to avoid naming conflicts
+# with groff, man-db, or other tools.
+# If you want to change the names of binary programs,
+# the following alternative names are suggested.
+# Using other names is possible as well.
+# This changes the names of the installed section 1 and section 8
+# manual pages as well.
+# It is possible to set only one or a few of these variables,
+# there is no need to copy the whole block.
+
+BINM_APROPOS=mapropos # default is "apropos"
+BINM_MAN=mman # default is "man"
+BINM_WHATIS=mwhatis # default is "whatis"
+BINM_MAKEWHATIS=mandocdb # default is "makewhatis"
+
# --- user settings related man.cgi ------------------------------------
# By default, building man.cgi(8) is disabled. To enable it, copy
diff --git a/contrib/mdocml/example.style.css b/contrib/mdocml/example.style.css
index d7d7e85..905412b 100644
--- a/contrib/mdocml/example.style.css
+++ b/contrib/mdocml/example.style.css
@@ -1,4 +1,4 @@
-/* $Id: example.style.css,v 1.53 2014/09/27 11:16:24 kristaps Exp $ */
+/* $Id: example.style.css,v 1.54 2014/12/10 22:19:45 schwarze Exp $ */
/*
* This is an example style-sheet provided for mandoc(1) and the -Thtml
* or -Txhtml output mode.
@@ -20,11 +20,14 @@ div.mandoc div.subsection { } /* Sub-sections (Ss, SS). */
div.mandoc table.synopsis { } /* SYNOPSIS section table. */
div.mandoc table.foot { } /* Document footer. */
div.mandoc td.foot-date { width: 50%; } /* Document footer: date. */
-div.mandoc td.foot-os { width: 50%; } /* Document footer: OS/source. */
+div.mandoc td.foot-os { width: 50%;
+ text-align: right; } /* Document footer: OS/source. */
div.mandoc table.head { } /* Document header. */
div.mandoc td.head-ltitle { width: 10%; } /* Document header: left-title. */
-div.mandoc td.head-vol { width: 80%; } /* Document header: volume. */
-div.mandoc td.head-rtitle { width: 10%; } /* Document header: right-title. */
+div.mandoc td.head-vol { width: 80%;
+ text-align: center; } /* Document header: volume. */
+div.mandoc td.head-rtitle { width: 10%;
+ text-align: right; } /* Document header: right-title. */
div.mandoc .display { } /* All Bd, D1, Dl. */
div.mandoc .list { } /* All Bl. */
div.mandoc i { } /* Italic: BI, IB, I, (implicit). */
diff --git a/contrib/mdocml/html.c b/contrib/mdocml/html.c
index 050fefe..fe16224 100644
--- a/contrib/mdocml/html.c
+++ b/contrib/mdocml/html.c
@@ -1,4 +1,4 @@
-/* $Id: html.c,v 1.181 2014/10/29 00:17:43 schwarze Exp $ */
+/* $Id: html.c,v 1.183 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -30,7 +30,6 @@
#include "mandoc.h"
#include "mandoc_aux.h"
-#include "libmandoc.h"
#include "out.h"
#include "html.h"
#include "main.h"
@@ -563,8 +562,9 @@ print_text(struct html *h, const char *word)
if ( ! print_encode(h, word, 0)) {
if ( ! (h->flags & HTML_NONOSPACE))
h->flags &= ~HTML_NOSPACE;
+ h->flags &= ~HTML_NONEWLINE;
} else
- h->flags |= HTML_NOSPACE;
+ h->flags |= HTML_NOSPACE | HTML_NONEWLINE;
if (h->metaf) {
print_tagq(h, h->metaf);
diff --git a/contrib/mdocml/html.h b/contrib/mdocml/html.h
index 521635f..bbf6183 100644
--- a/contrib/mdocml/html.h
+++ b/contrib/mdocml/html.h
@@ -1,4 +1,4 @@
-/* $Id: html.h,v 1.67 2014/10/28 17:36:19 schwarze Exp $ */
+/* $Id: html.h,v 1.70 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -14,10 +14,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef HTML_H
-#define HTML_H
-
-__BEGIN_DECLS
enum htmltag {
TAG_HTML,
@@ -130,6 +126,7 @@ struct html {
#define HTML_SKIPCHAR (1 << 6) /* skip the next character */
#define HTML_NOSPLIT (1 << 7) /* do not break line before .An */
#define HTML_SPLIT (1 << 8) /* break line before .An */
+#define HTML_NONEWLINE (1 << 9) /* No line break in nofill mode. */
struct tagq tags; /* stack of open tags */
struct rofftbl tbl; /* current table */
struct tag *tblt; /* current open table scope */
@@ -146,6 +143,11 @@ struct html {
#define HTML_FRAGMENT (1 << 0) /* don't emit HTML/HEAD/BODY */
};
+__BEGIN_DECLS
+
+struct tbl_span;
+struct eqn;
+
void print_gen_decls(struct html *);
void print_gen_head(struct html *);
struct tag *print_otag(struct html *, enum htmltag,
@@ -176,5 +178,3 @@ void buffmt_includes(struct html *, const char *);
int html_strlen(const char *);
__END_DECLS
-
-#endif /*!HTML_H*/
diff --git a/contrib/mdocml/libman.h b/contrib/mdocml/libman.h
index 8f66013..b26c2b6 100644
--- a/contrib/mdocml/libman.h
+++ b/contrib/mdocml/libman.h
@@ -1,4 +1,4 @@
-/* $Id: libman.h,v 1.65 2014/11/28 05:51:32 schwarze Exp $ */
+/* $Id: libman.h,v 1.66 2014/12/01 04:05:31 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef LIBMAN_H
-#define LIBMAN_H
enum man_next {
MAN_NEXT_SIBLING = 0,
@@ -75,5 +73,3 @@ void man_valid_post(struct man *);
void man_unscope(struct man *, const struct man_node *);
__END_DECLS
-
-#endif /*!LIBMAN_H*/
diff --git a/contrib/mdocml/libmandoc.h b/contrib/mdocml/libmandoc.h
index c5a8d5c..6aa8b8dc 100644
--- a/contrib/mdocml/libmandoc.h
+++ b/contrib/mdocml/libmandoc.h
@@ -1,4 +1,4 @@
-/* $Id: libmandoc.h,v 1.49 2014/11/28 06:27:05 schwarze Exp $ */
+/* $Id: libmandoc.h,v 1.51 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef LIBMANDOC_H
-#define LIBMANDOC_H
enum rofferr {
ROFF_CONT, /* continue processing line */
@@ -37,6 +35,11 @@ struct buf {
__BEGIN_DECLS
+struct mparse;
+struct mchars;
+enum mandocerr;
+struct tbl_span;
+struct eqn;
struct roff;
struct mdoc;
struct man;
@@ -91,5 +94,3 @@ const struct tbl_span *roff_span(const struct roff *);
const struct eqn *roff_eqn(const struct roff *);
__END_DECLS
-
-#endif /*!LIBMANDOC_H*/
diff --git a/contrib/mdocml/libmdoc.h b/contrib/mdocml/libmdoc.h
index 056e9c9..b245213 100644
--- a/contrib/mdocml/libmdoc.h
+++ b/contrib/mdocml/libmdoc.h
@@ -1,4 +1,4 @@
-/* $Id: libmdoc.h,v 1.95 2014/11/29 03:37:44 schwarze Exp $ */
+/* $Id: libmdoc.h,v 1.96 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef LIBMDOC_H
-#define LIBMDOC_H
enum mdoc_next {
MDOC_NEXT_SIBLING = 0,
@@ -129,5 +127,3 @@ void mdoc_macroend(struct mdoc *);
enum mdelim mdoc_isdelim(const char *);
__END_DECLS
-
-#endif /*!LIBMDOC_H*/
diff --git a/contrib/mdocml/libroff.h b/contrib/mdocml/libroff.h
index bd9bcd2..dd7ad75 100644
--- a/contrib/mdocml/libroff.h
+++ b/contrib/mdocml/libroff.h
@@ -1,4 +1,4 @@
-/* $Id: libroff.h,v 1.31 2014/10/25 14:35:37 schwarze Exp $ */
+/* $Id: libroff.h,v 1.33 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,10 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef LIBROFF_H
-#define LIBROFF_H
-
-__BEGIN_DECLS
enum tbl_part {
TBL_PART_OPTS, /* in options (first line) */
@@ -66,6 +62,8 @@ struct eqn_def {
size_t valsz;
};
+__BEGIN_DECLS
+
struct tbl_node *tbl_alloc(int, int, struct mparse *);
void tbl_restart(int, int, struct tbl_node *);
void tbl_free(struct tbl_node *);
@@ -84,5 +82,3 @@ enum rofferr eqn_read(struct eqn_node **, int,
const char *, int, int *);
__END_DECLS
-
-#endif /*LIBROFF_H*/
diff --git a/contrib/mdocml/main.c b/contrib/mdocml/main.c
index 3478499..ec6e980 100644
--- a/contrib/mdocml/main.c
+++ b/contrib/mdocml/main.c
@@ -1,4 +1,4 @@
-/* $Id: main.c,v 1.200 2014/11/26 21:40:17 schwarze Exp $ */
+/* $Id: main.c,v 1.205 2014/12/11 19:19:35 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2011, 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -83,12 +83,17 @@ struct curparse {
};
static int koptions(int *, char *);
+#if HAVE_SQLITE3
+int mandocdb(int, char**);
+#endif
static int moptions(int *, char *);
static void mmsg(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
static void parse(struct curparse *, int,
const char *, enum mandoclevel *);
+#if HAVE_SQLITE3
static enum mandoclevel passthrough(const char *, int, int);
+#endif
static void spawn_pager(void);
static int toptions(struct curparse *, char *);
static void usage(enum argmode) __attribute__((noreturn));
@@ -96,6 +101,8 @@ static void version(void) __attribute__((noreturn));
static int woptions(struct curparse *, char *);
static const int sec_prios[] = {1, 4, 5, 8, 6, 3, 7, 2, 9};
+static char help_arg[] = "help";
+static char *help_argv[] = {help_arg, NULL};
static const char *progname;
@@ -105,12 +112,13 @@ main(int argc, char *argv[])
struct curparse curp;
struct mansearch search;
struct manpaths paths;
- char *conf_file, *defpaths, *auxpaths;
+ char *auxpaths;
char *defos;
#if HAVE_SQLITE3
struct manpage *res, *resp;
+ char *conf_file, *defpaths;
size_t isec, i, sz;
- int prio, best_prio;
+ int prio, best_prio, synopsis_only;
char sec;
#endif
enum mandoclevel rc;
@@ -118,7 +126,6 @@ main(int argc, char *argv[])
int fd;
int show_usage;
int use_pager;
- int synopsis_only;
int options;
int c;
@@ -128,34 +135,46 @@ main(int argc, char *argv[])
else
++progname;
+#if HAVE_SQLITE3
+ if (strcmp(progname, BINM_MAKEWHATIS) == 0)
+ return(mandocdb(argc, argv));
+#endif
+
/* Search options. */
memset(&paths, 0, sizeof(struct manpaths));
- conf_file = defpaths = auxpaths = NULL;
+#if HAVE_SQLITE3
+ conf_file = defpaths = NULL;
+#endif
+ auxpaths = NULL;
memset(&search, 0, sizeof(struct mansearch));
search.outkey = "Nd";
- if (strcmp(progname, "man") == 0)
+ if (strcmp(progname, BINM_MAN) == 0)
search.argmode = ARG_NAME;
- else if (strncmp(progname, "apropos", 7) == 0)
+ else if (strcmp(progname, BINM_APROPOS) == 0)
search.argmode = ARG_EXPR;
- else if (strncmp(progname, "whatis", 6) == 0)
+ else if (strcmp(progname, BINM_WHATIS) == 0)
search.argmode = ARG_WORD;
+ else if (strncmp(progname, "help", 4) == 0)
+ search.argmode = ARG_NAME;
else
search.argmode = ARG_FILE;
/* Parser and formatter options. */
memset(&curp, 0, sizeof(struct curparse));
- curp.outtype = OUTT_ASCII;
+ curp.outtype = OUTT_LOCALE;
curp.wlevel = MANDOCLEVEL_FATAL;
options = MPARSE_SO | MPARSE_UTF8 | MPARSE_LATIN1;
defos = NULL;
use_pager = 1;
show_usage = 0;
+#if HAVE_SQLITE3
synopsis_only = 0;
+#endif
outmode = OUTMODE_DEF;
while (-1 != (c = getopt(argc, argv,
@@ -165,7 +184,9 @@ main(int argc, char *argv[])
outmode = OUTMODE_ALL;
break;
case 'C':
+#if HAVE_SQLITE3
conf_file = optarg;
+#endif
break;
case 'c':
use_pager = 0;
@@ -175,7 +196,9 @@ main(int argc, char *argv[])
break;
case 'h':
(void)strlcat(curp.outopts, "synopsis,", BUFSIZ);
+#if HAVE_SQLITE3
synopsis_only = 1;
+#endif
use_pager = 0;
outmode = OUTMODE_ALL;
break;
@@ -209,7 +232,9 @@ main(int argc, char *argv[])
outmode = OUTMODE_ALL;
break;
case 'M':
+#if HAVE_SQLITE3
defpaths = optarg;
+#endif
break;
case 'm':
auxpaths = optarg;
@@ -273,15 +298,24 @@ main(int argc, char *argv[])
resp = NULL;
#endif
- /* Quirk for a man(1) section argument without -s. */
+ /*
+ * Quirks for help(1)
+ * and for a man(1) section argument without -s.
+ */
- if (search.argmode == ARG_NAME &&
- argv[0] != NULL &&
- isdigit((unsigned char)argv[0][0]) &&
- (argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) {
- search.sec = argv[0];
- argv++;
- argc--;
+ if (search.argmode == ARG_NAME) {
+ if (*progname == 'h') {
+ if (argc == 0) {
+ argv = help_argv;
+ argc = 1;
+ }
+ } else if (argv[0] != NULL &&
+ isdigit((unsigned char)argv[0][0]) &&
+ (argv[0][1] == '\0' || !strcmp(argv[0], "3p"))) {
+ search.sec = argv[0];
+ argv++;
+ argc--;
+ }
}
rc = MANDOCLEVEL_OK;
@@ -583,6 +617,7 @@ parse(struct curparse *curp, int fd, const char *file,
*level = rc;
}
+#if HAVE_SQLITE3
static enum mandoclevel
passthrough(const char *file, int fd, int synopsis_only)
{
@@ -646,6 +681,7 @@ fail:
progname, file, syscall, strerror(errno));
return(MANDOCLEVEL_SYSERR);
}
+#endif
static int
koptions(int *options, char *arg)
diff --git a/contrib/mdocml/main.h b/contrib/mdocml/main.h
index c7768e3..147c22f 100644
--- a/contrib/mdocml/main.h
+++ b/contrib/mdocml/main.h
@@ -1,4 +1,4 @@
-/* $Id: main.h,v 1.17 2014/10/28 17:36:19 schwarze Exp $ */
+/* $Id: main.h,v 1.19 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -14,17 +14,15 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MAIN_H
-#define MAIN_H
+
+#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
__BEGIN_DECLS
+struct mchars;
struct mdoc;
struct man;
-#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
-
-
/*
* Definitions for main.c-visible output device functions, e.g., -Thtml
* and -Tascii. Note that ascii_alloc() is named as such in
@@ -56,5 +54,3 @@ void terminal_mdoc(void *, const struct mdoc *);
void terminal_man(void *, const struct man *);
__END_DECLS
-
-#endif /*!MAIN_H*/
diff --git a/contrib/mdocml/man.h b/contrib/mdocml/man.h
index 22827c5..08bfcc8 100644
--- a/contrib/mdocml/man.h
+++ b/contrib/mdocml/man.h
@@ -1,4 +1,4 @@
-/* $Id: man.h,v 1.66 2014/11/28 05:51:32 schwarze Exp $ */
+/* $Id: man.h,v 1.67 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MAN_H
-#define MAN_H
enum mant {
MAN_br = 0,
@@ -116,5 +114,3 @@ const struct mparse *man_mparse(const struct man *);
void man_deroff(char **, const struct man_node *);
__END_DECLS
-
-#endif /*!MAN_H*/
diff --git a/contrib/mdocml/man_hash.c b/contrib/mdocml/man_hash.c
index c52add2..1cbfb1b 100644
--- a/contrib/mdocml/man_hash.c
+++ b/contrib/mdocml/man_hash.c
@@ -1,4 +1,4 @@
-/* $Id: man_hash.c,v 1.28 2014/08/10 23:54:41 schwarze Exp $ */
+/* $Id: man_hash.c,v 1.29 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -24,7 +24,6 @@
#include <string.h>
#include "man.h"
-#include "mandoc.h"
#include "libman.h"
#define HASH_DEPTH 6
diff --git a/contrib/mdocml/man_html.c b/contrib/mdocml/man_html.c
index 6fe40a9..1455e1e 100644
--- a/contrib/mdocml/man_html.c
+++ b/contrib/mdocml/man_html.c
@@ -1,4 +1,4 @@
-/* $Id: man_html.c,v 1.104 2014/09/27 11:17:19 kristaps Exp $ */
+/* $Id: man_html.c,v 1.107 2014/12/04 02:05:42 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -25,11 +25,10 @@
#include <stdlib.h>
#include <string.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
+#include "man.h"
#include "out.h"
#include "html.h"
-#include "man.h"
#include "main.h"
/* TODO: preserve ident widths. */
@@ -213,21 +212,14 @@ print_man_node(MAN_ARGS)
man_root_pre(man, n, mh, h);
break;
case MAN_TEXT:
- /*
- * If we have a blank line, output a vertical space.
- * If we have a space as the first character, break
- * before printing the line's data.
- */
if ('\0' == *n->string) {
print_paragraph(h);
return;
}
-
- if (' ' == *n->string && MAN_LINE & n->flags)
- print_otag(h, TAG_BR, 0, NULL);
- else if (MANH_LITERAL & mh->fl && n->prev)
+ if (n->flags & MAN_LINE && (*n->string == ' ' ||
+ (n->prev != NULL && mh->fl & MANH_LITERAL &&
+ ! (h->flags & HTML_NONEWLINE))))
print_otag(h, TAG_BR, 0, NULL);
-
print_text(h, n->string);
return;
case MAN_EQN:
@@ -290,7 +282,7 @@ a2width(const struct man_node *n, struct roffsu *su)
if (MAN_TEXT != n->type)
return(0);
- if (a2roffsu(n->string, su, SCALE_BU))
+ if (a2roffsu(n->string, su, SCALE_EN))
return(1);
return(0);
diff --git a/contrib/mdocml/man_term.c b/contrib/mdocml/man_term.c
index 2531f81..9a9abaf 100644
--- a/contrib/mdocml/man_term.c
+++ b/contrib/mdocml/man_term.c
@@ -1,4 +1,4 @@
-/* $Id: man_term.c,v 1.156 2014/11/21 01:52:53 schwarze Exp $ */
+/* $Id: man_term.c,v 1.159 2014/12/04 02:05:42 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -123,7 +123,7 @@ static const struct termact termacts[MAN_MAX] = {
{ NULL, NULL, 0 }, /* RE */
{ pre_RS, post_RS, 0 }, /* RS */
{ pre_ign, NULL, 0 }, /* DT */
- { pre_ign, NULL, 0 }, /* UC */
+ { pre_ign, NULL, MAN_NOTEXT }, /* UC */
{ pre_PD, NULL, MAN_NOTEXT }, /* PD */
{ pre_ign, NULL, 0 }, /* AT */
{ pre_in, NULL, MAN_NOTEXT }, /* in */
@@ -201,7 +201,7 @@ a2width(const struct termp *p, const char *cp)
{
struct roffsu su;
- if ( ! a2roffsu(cp, &su, SCALE_BU))
+ if ( ! a2roffsu(cp, &su, SCALE_EN))
return(-1);
return((int)term_hspan(p, &su));
@@ -778,12 +778,18 @@ pre_SS(DECL_ARGS)
mt->fl &= ~MANT_LITERAL;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
- /* If following a prior empty `SS', no vspace. */
- if (n->prev && MAN_SS == n->prev->tok)
- if (NULL == n->prev->body->child)
- break;
- if (NULL == n->prev)
+
+ /*
+ * No vertical space before the first subsection
+ * and after an empty subsection.
+ */
+
+ do {
+ n = n->prev;
+ } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT);
+ if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL))
break;
+
for (i = 0; i < mt->pardist; i++)
term_vspace(p);
break;
@@ -827,13 +833,18 @@ pre_SH(DECL_ARGS)
mt->fl &= ~MANT_LITERAL;
mt->lmargin[mt->lmargincur] = term_len(p, p->defindent);
mt->offset = term_len(p, p->defindent);
- /* If following a prior empty `SH', no vspace. */
- if (n->prev && MAN_SH == n->prev->tok)
- if (NULL == n->prev->body->child)
- break;
- /* If the first macro, no vspae. */
- if (NULL == n->prev)
+
+ /*
+ * No vertical space before the first section
+ * and after an empty section.
+ */
+
+ do {
+ n = n->prev;
+ } while (n != NULL && termacts[n->tok].flags & MAN_NOTEXT);
+ if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL))
break;
+
for (i = 0; i < mt->pardist; i++)
term_vspace(p);
break;
@@ -1018,13 +1029,14 @@ out:
* -man doesn't have nested macros, we don't need to be
* more specific than this.
*/
- if (MANT_LITERAL & mt->fl && ! (TERMP_NOBREAK & p->flags) &&
- (NULL == n->next || MAN_LINE & n->next->flags)) {
+ if (mt->fl & MANT_LITERAL &&
+ ! (p->flags & (TERMP_NOBREAK | TERMP_NONEWLINE)) &&
+ (n->next == NULL || n->next->flags & MAN_LINE)) {
rm = p->rmargin;
rmax = p->maxrmargin;
p->rmargin = p->maxrmargin = TERM_MAXMARGIN;
p->flags |= TERMP_NOSPACE;
- if (NULL != n->string && '\0' != *n->string)
+ if (n->string != NULL && *n->string != '\0')
term_flushln(p);
else
term_newln(p);
diff --git a/contrib/mdocml/mandoc.1 b/contrib/mdocml/mandoc.1
index 9f2d6ba..45a6b0c 100644
--- a/contrib/mdocml/mandoc.1
+++ b/contrib/mdocml/mandoc.1
@@ -1,4 +1,4 @@
-.\" $Id: mandoc.1,v 1.125 2014/11/28 18:09:01 schwarze Exp $
+.\" $Id: mandoc.1,v 1.128 2014/12/02 11:31:51 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2012, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 $Mdocdate: November 28 2014 $
+.Dd $Mdocdate: December 2 2014 $
.Dt MANDOC 1
.Os
.Sh NAME
@@ -49,7 +49,7 @@ or
text from stdin, implying
.Fl m Ns Cm andoc ,
and produces
-.Fl T Ns Cm ascii
+.Fl T Ns Cm locale
output.
.Pp
The options are as follows:
@@ -146,7 +146,7 @@ See
.Sx Output Formats
for available formats.
Defaults to
-.Fl T Ns Cm ascii .
+.Fl T Ns Cm locale .
.It Fl V
Print version and exit.
.It Fl W Ns Ar level
@@ -255,7 +255,6 @@ arguments, which correspond to output modes:
.Bl -tag -width "-Tlocale"
.It Fl T Ns Cm ascii
Produce 7-bit ASCII output.
-This is the default.
See
.Sx ASCII Output .
.It Fl T Ns Cm html
@@ -268,6 +267,7 @@ Implies
.Fl W Ns Cm warning .
.It Fl T Ns Cm locale
Encode output using the current locale.
+This is the default.
See
.Sx Locale Output .
.It Fl T Ns Cm man
@@ -299,8 +299,8 @@ If multiple input files are specified, these will be processed by the
corresponding filter in-order.
.Ss ASCII Output
Output produced by
-.Fl T Ns Cm ascii ,
-which is the default, is rendered in standard 7-bit ASCII documented in
+.Fl T Ns Cm ascii
+is rendered in standard 7-bit ASCII documented in
.Xr ascii 7 .
.Pp
Font styles are applied by using back-spaced encoding such that an
@@ -413,6 +413,8 @@ relative URI.
.Ss Locale Output
Locale-depending output encoding is triggered with
.Fl T Ns Cm locale .
+This is the default.
+.Pp
This option is not available on all systems: systems without locale
support, or those whose internal representation is not natively UCS-4,
will fall back to
@@ -803,6 +805,13 @@ Probably, there are author names lacking markup.
See the
.Xr mdoc 7
manual for replacements.
+.It Sy "macro neither callable nor escaped"
+.Pq mdoc
+The name of a macro that is not callable appears on a macro line.
+It is printed verbatim.
+If the intention is to call it, move it to its own line;
+otherwise, escape it by prepending
+.Sq \e& .
.It Sy "skipping paragraph macro"
In
.Xr mdoc 7
@@ -1047,6 +1056,14 @@ argument is invalid.
The default font
.Cm \efR
is used instead.
+.It Sy "nothing follows prefix"
+.Pq mdoc
+A
+.Ic \&Pf
+macro has no argument, or only one argument and no macro follows
+on the same input line.
+This defeats its purpose; in particular, spacing is not suppressed
+before the text or macros following on the next input line.
.It Sy "missing -std argument, adding it"
.Pq mdoc
An
diff --git a/contrib/mdocml/mandoc.h b/contrib/mdocml/mandoc.h
index 98578ed..e4cdccb 100644
--- a/contrib/mdocml/mandoc.h
+++ b/contrib/mdocml/mandoc.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc.h,v 1.171 2014/11/28 18:09:01 schwarze Exp $ */
+/* $Id: mandoc.h,v 1.176 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MANDOC_H
-#define MANDOC_H
#define ASCII_NBRSP 31 /* non-breaking space */
#define ASCII_HYPH 30 /* breakable hyphen */
@@ -77,6 +75,7 @@ enum mandocerr {
/* related to macros and nesting */
MANDOCERR_MACRO_OBS, /* obsolete macro: macro */
+ MANDOCERR_MACRO_CALL, /* macro neither callable nor escaped: macro */
MANDOCERR_PAR_SKIP, /* skipping paragraph macro: macro ... */
MANDOCERR_PAR_MOVE, /* moving paragraph macro out of list: macro */
MANDOCERR_NS_SKIP, /* skipping no-space macro */
@@ -102,6 +101,7 @@ enum mandocerr {
MANDOCERR_IT_NOBODY, /* empty list item: Bl -type It */
MANDOCERR_BF_NOFONT, /* missing font type, using \fR: Bf */
MANDOCERR_BF_BADFONT, /* unknown font type, using \fR: Bf font */
+ MANDOCERR_PF_SKIP, /* nothing follows prefix: Pf arg */
MANDOCERR_ARG_STD, /* missing -std argument, adding it: macro */
MANDOCERR_EQN_NOBOX, /* missing eqn box, using "": op */
@@ -414,13 +414,13 @@ enum mandoc_esc {
typedef void (*mandocmsg)(enum mandocerr, enum mandoclevel,
const char *, int, int, const char *);
+__BEGIN_DECLS
+
struct mparse;
struct mchars;
struct mdoc;
struct man;
-__BEGIN_DECLS
-
enum mandoc_esc mandoc_escape(const char **, const char **, int *);
struct mchars *mchars_alloc(void);
void mchars_free(struct mchars *);
@@ -437,7 +437,7 @@ void mparse_free(struct mparse *);
void mparse_keep(struct mparse *);
enum mandoclevel mparse_open(struct mparse *, int *, const char *);
enum mandoclevel mparse_readfd(struct mparse *, int, const char *);
-enum mandoclevel mparse_readmem(struct mparse *, const void *, size_t,
+enum mandoclevel mparse_readmem(struct mparse *, void *, size_t,
const char *);
void mparse_reset(struct mparse *);
void mparse_result(struct mparse *,
@@ -448,5 +448,3 @@ const char *mparse_strlevel(enum mandoclevel);
enum mandoclevel mparse_wait(struct mparse *);
__END_DECLS
-
-#endif /*!MANDOC_H*/
diff --git a/contrib/mdocml/mandoc_aux.h b/contrib/mdocml/mandoc_aux.h
index 04f4baf..e72fe4e 100644
--- a/contrib/mdocml/mandoc_aux.h
+++ b/contrib/mdocml/mandoc_aux.h
@@ -1,4 +1,4 @@
-/* $Id: mandoc_aux.h,v 1.2 2014/04/23 21:06:41 schwarze Exp $ */
+/* $Id: mandoc_aux.h,v 1.3 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MANDOC_AUX_H
-#define MANDOC_AUX_H
__BEGIN_DECLS
@@ -29,5 +27,3 @@ char *mandoc_strdup(const char *);
char *mandoc_strndup(const char *, size_t);
__END_DECLS
-
-#endif /*!MANDOC_AUX_H*/
diff --git a/contrib/mdocml/mandoc_headers.3 b/contrib/mdocml/mandoc_headers.3
new file mode 100644
index 0000000..aa8754e
--- /dev/null
+++ b/contrib/mdocml/mandoc_headers.3
@@ -0,0 +1,511 @@
+.Dd December 1, 2014
+.Dt MANDOC_HEADERS 3
+.Os
+.Sh NAME
+.Nm mandoc_headers
+.Nd ordering of mandoc include files
+.Sh DESCRIPTION
+To support a cleaner coding style, the mandoc header files do not
+contain any include directives and do not guard against multiple
+inclusion.
+The application developer has to make sure that the headers are
+included in a proper order, and that no header is included more
+than once.
+.Pp
+The headers and functions form three major groups:
+.Sx Parser interface ,
+.Sx Parser internals ,
+and
+.Sx Formatter interface .
+.Pp
+Various rules are given below prohibiting the inclusion of certain
+combinations of headers into the same file.
+The intention is to keep the following functional components
+separate from each other:
+.Pp
+.Bl -dash -offset indent -compact
+.It
+.Xr mdoc 7
+parser
+.It
+.Xr man 7
+parser
+.It
+.Xr roff 7
+parser
+.It
+.Xr tbl 7
+parser
+.It
+.Xr eqn 7
+parser
+.It
+terminal formatters
+.It
+HTML formatters
+.It
+search tools
+.El
+.Pp
+Note that mere usage of an opaque type does
+.Em not
+require inclusion of the header where that type is defined.
+.Ss Parser interface
+Each of the following headers can be included without including
+any other mandoc header.
+These headers should be included before any other mandoc headers.
+Afterwards, any other mandoc headers can be included as needed.
+.Bl -tag -width Ds
+.It Qq Pa mandoc_aux.h
+Requires
+.In sys/types.h
+for
+.Vt size_t .
+Provides the utility functions documented in
+.Xr mandoc_malloc 3 .
+.It Qq Pa mandoc.h
+Requires
+.In sys/types.h
+for
+.Vt size_t .
+.Pp
+Provides
+.Vt enum mandoc_esc ,
+.Vt enum mandocerr ,
+.Vt enum mandoclevel ,
+.Vt enum tbl_cellt ,
+.Vt enum tbl_datt ,
+.Vt enum tbl_spant ,
+.Vt enum eqn_boxt ,
+.Vt enum eqn_fontt ,
+.Vt enum eqn_pilet ,
+.Vt enum eqn_post ,
+.Vt struct tbl_opts ,
+.Vt struct tbl_head ,
+.Vt struct tbl_cell ,
+.Vt struct tbl_row ,
+.Vt struct tbl_dat ,
+.Vt struct tbl_span ,
+.Vt struct eqn_box ,
+.Vt struct eqn ,
+the function prototype typedef
+.Fn mandocmsg ,
+the function
+.Xr mandoc_escape 3 ,
+the functions described in
+.Xr mchars_alloc 3 ,
+and the functions
+.Fn mparse_*
+described in
+.Xr mandoc 3 .
+.Pp
+Uses the opaque types
+.Vt struct mparse
+from
+.Pa read.c
+and
+.Vt struct mchars
+from
+.Pa chars.c
+for function prototypes.
+Uses the types
+.Vt struct mdoc
+from
+.Pa libmdoc.h
+and
+.Vt struct man
+from
+.Pa libman.h
+as opaque types for function prototypes.
+.It Qq Pa mdoc.h
+Requires
+.In sys/types.h
+for
+.Vt size_t .
+.Pp
+Provides
+.Vt enum mdoct ,
+.Vt enum mdocargt ,
+.Vt enum mdoc_type ,
+.Vt enum mdoc_sec ,
+.Vt enum mdoc_endbody ,
+.Vt enum mdoc_disp ,
+.Vt enum mdoc_list ,
+.Vt enum mdoc_auth ,
+.Vt enum mdoc_font ,
+.Vt struct mdoc_meta ,
+.Vt struct mdoc_argv ,
+.Vt struct mdoc_arg ,
+.Vt struct mdoc_bd ,
+.Vt struct mdoc_bl ,
+.Vt struct mdoc_an ,
+.Vt struct mdoc_bf ,
+.Vt struct mdoc_rs ,
+.Vt struct mdoc_node ,
+and the functions
+.Fn mdoc_*
+described in
+.Xr mandoc 3 .
+.Pp
+Uses the type
+.Vt struct mdoc
+from
+.Pa libmdoc.h
+as an opaque type for function prototypes.
+Uses pointers to the types
+.Vt struct tbl_span
+and
+.Vt struct eqn
+as opaque struct members.
+.Pp
+When this header is included, the same file should not include
+.Pa libman.h
+or
+.Pa libroff.h .
+.It Qq Pa man.h
+Provides
+.Vt enum mant ,
+.Vt enum man_type ,
+.Vt struct man_meta ,
+.Vt struct man_node ,
+and the functions
+.Fn man_*
+described in
+.Xr mandoc 3 .
+.Pp
+Uses the opaque type
+.Vt struct mparse
+from
+.Pa read.c
+for function prototypes.
+Uses the type
+.Vt struct man
+from
+.Pa libman.h
+as an opaque type for function prototypes.
+Uses pointers to the types
+.Vt struct tbl_span
+and
+.Vt struct eqn
+as opaque struct members.
+.Pp
+When this header is included, the same file should not include
+.Pa libmdoc.h
+or
+.Pa libroff.h .
+.El
+.Ss Parser internals
+The following headers require inclusion of a parser interface header
+before they can be included. All parser interface headers should
+precede all parser internal headers. When any parser internal headers
+are included, the same file should not include any formatter headers.
+.Bl -tag -width Ds
+.It Qq Pa libmandoc.h
+Requires
+.In sys/types.h
+for
+.Vt size_t .
+.Pp
+Provides
+.Vt enum rofferr ,
+.Vt struct buf ,
+utility functions needed by multiple parsers,
+and the top-level functions to call the parsers.
+.Pp
+Uses the opaque types
+.Vt struct mparse
+from
+.Pa read.c
+and
+.Vt struct roff
+from
+.Pa roff.c
+for function prototypes.
+Uses the types
+.Vt enum mandocerr ,
+.Vt struct tbl_span ,
+and
+.Vt struct eqn
+from
+.Pa mandoc.h ,
+.Vt struct mdoc
+from
+.Pa libmdoc.h ,
+and
+.Vt struct man
+from
+.Pa libman.h
+as opaque types for function prototypes.
+.It Qq Pa libmdoc.h
+Requires
+.Qq Pa mdoc.h
+for
+.Vt enum mdoct ,
+.Vt enum mdoc_* ,
+and
+.Vt struct mdoc_* .
+.Pp
+Provides
+.Vt enum mdoc_next ,
+.Vt enum margserr ,
+.Vt enum mdelim ,
+.Vt struct mdoc ,
+.Vt struct mdoc_macro ,
+and many functions internal to the
+.Xr mdoc 7
+parser.
+.Pp
+Uses the opaque types
+.Vt struct mparse
+from
+.Pa read.c
+and
+.Vt struct roff
+from
+.Pa roff.c .
+.Pp
+When this header is included, the same file should not include
+.Pa man.h ,
+.Pa libman.h ,
+or
+.Pa libroff.h .
+.It Qq Pa libman.h
+Requires
+.Qq Pa man.h
+for
+.Vt enum mant
+and
+.Vt struct man_node.
+.Pp
+Provides
+.Vt enum man_next ,
+.Vt struct man ,
+.Vt struct man_macro ,
+and many functions internal to the
+.Xr man 7
+parser.
+.Pp
+Uses the opaque types
+.Vt struct mparse
+from
+.Pa read.c
+and
+.Vt struct roff
+from
+.Pa roff.c .
+.Pp
+When this header is included, the same file should not include
+.Pa mdoc.h ,
+.Pa libmdoc.h ,
+or
+.Pa libroff.h .
+.It Qq Pa libroff.h
+Requires
+.In sys/types.h
+for
+.Vt size_t ,
+.Qq Pa mandoc.h
+for
+.Vt struct tbl_*
+and
+.Vt struct eqn ,
+and
+.Qq Pa libmandoc.h
+for
+.Vt enum rofferr .
+.Pp
+Provides
+.Vt enum tbl_part ,
+.Vt struct tbl_node ,
+.Vt struct eqn_def ,
+.Vt struct eqn_node ,
+and many functions internal to the
+.Xr tbl 7
+and
+.Xr eqn 7
+parsers.
+.Pp
+Uses the opaque type
+.Vt struct mparse
+from
+.Pa read.c .
+.Pp
+When this header is included, the same file should not include
+.Pa man.h ,
+.Pa mdoc.h ,
+.Pa libman.h ,
+or
+.Pa libmdoc.h .
+.El
+.Ss Formatter interface
+These headers should be included after any parser interface headers.
+No parser internal headers should be included by the same file.
+.Bl -tag -width Ds
+.It Qq Pa out.h
+Requires
+.In sys/types.h
+for
+.Vt size_t .
+.Pp
+Provides
+.Vt enum roffscale ,
+.Vt struct roffcol ,
+.Vt struct roffsu ,
+.Vt struct rofftbl ,
+.Fn a2roffsu ,
+and
+.Fn tblcalc .
+.Pp
+Uses
+.Vt struct tbl_span
+from
+.Pa mandoc.h
+as an opaque type for function prototypes.
+.Pp
+When this header is included, the same file should not include
+.Pa manpath.h
+or
+.Pa mansearch.h .
+.It Qq Pa term.h
+Requires
+.In sys/types.h
+for
+.Vt size_t
+and
+.Qq Pa out.h
+for
+.Vt struct roffsu
+and
+.Vt struct rofftbl .
+.Pp
+Provides
+.Vt enum termenc ,
+.Vt enum termfont ,
+.Vt enum termtype ,
+.Vt struct termp_tbl ,
+.Vt struct termp ,
+and many terminal formatting functions.
+.Pp
+Uses the opaque types
+.Vt struct mchars
+from
+.Pa chars.c
+and
+.Vt struct termp_ps
+from
+.Pa term_ps.c .
+Uses
+.Vt struct tbl_span
+and
+.Vt struct eqn
+from
+.Pa mandoc.h
+as opaque types for function prototypes.
+.Pp
+When this header is included, the same file should not include
+.Pa html.h ,
+.Pa manpath.h
+or
+.Pa mansearch.h .
+.It Qq Pa html.h
+Requires
+.In sys/types.h
+for
+.Vt size_t ,
+.In stdio.h
+for
+.Dv BUFSIZ ,
+and
+.Qq Pa out.h
+for
+.Vt struct roffsu
+and
+.Vt struct rofftbl .
+.Pp
+Provides
+.Vt enum htmltag ,
+.Vt enum htmlattr ,
+.Vt enum htmlfont ,
+.Vt struct tag ,
+.Vt struct tagq ,
+.Vt struct htmlpair ,
+.Vt struct html ,
+and many HTML formatting functions.
+.Pp
+Uses the opaque type
+.Vt struct mchars
+from
+.Pa chars.c .
+.Pp
+When this header is included, the same file should not include
+.Pa term.h ,
+.Pa manpath.h
+or
+.Pa mansearch.h .
+.It Qq Pa main.h
+Provides the top level steering functions for all formatters.
+.Pp
+Uses the opaque type
+.Vt struct mchars
+from
+.Pa chars.c .
+Uses the types
+.Vt struct mdoc
+from
+.Pa libmdoc.h
+and
+.Vt struct man
+from
+.Pa libman.h
+as opaque types for function prototypes.
+.It Qq Pa manpath.h
+Requires
+.In sys/types.h
+for
+.Vt size_t .
+.Pp
+Provides
+.Vt struct manpaths
+and the functions
+.Fn manpath_manconf ,
+.Fn manpath_parse ,
+and
+.Fn manpath_free .
+.Pp
+When this header is included, the same file should not include
+.Pa out.h ,
+.Pa term.h ,
+or
+.Pa html.h .
+.It Qq Pa mansearch.h
+Requires
+.In sys/types.h
+for
+.Vt size_t
+and
+.In stdint.h
+for
+.Vt uint64_t .
+.Pp
+Provides
+.Vt enum argmode ,
+.Vt struct manpage ,
+.Vt struct mansearch ,
+and the functions
+.Fn mansearch_setup ,
+.Fn mansearch ,
+and
+.Fn mansearch_free .
+.Pp
+Uses
+.Vt struct manpaths
+from
+.Pa manpath.h
+as an opaque type for function prototypes.
+.Pp
+When this header is included, the same file should not include
+.Pa out.h ,
+.Pa term.h ,
+or
+.Pa html.h .
+.El
diff --git a/contrib/mdocml/mandocdb.c b/contrib/mdocml/mandocdb.c
index 4f6a062..a2fac20 100644
--- a/contrib/mdocml/mandocdb.c
+++ b/contrib/mdocml/mandocdb.c
@@ -1,4 +1,4 @@
-/* $Id: mandocdb.c,v 1.171 2014/11/27 01:58:21 schwarze Exp $ */
+/* $Id: mandocdb.c,v 1.179 2014/12/09 07:29:42 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -84,10 +84,9 @@ enum op {
};
struct str {
- char *rendered; /* key in UTF-8 or ASCII form */
const struct mpage *mpage; /* if set, the owning parse */
uint64_t mask; /* bitmask in sequence */
- char key[]; /* may contain escape sequences */
+ char key[]; /* rendered text */
};
struct inodev {
@@ -104,6 +103,7 @@ struct mpage {
char *desc; /* description from file content */
struct mlink *mlinks; /* singly linked list */
int form; /* format from file content */
+ int name_head_done;
};
struct mlink {
@@ -124,11 +124,13 @@ enum stmt {
STMT_INSERT_PAGE, /* insert mpage */
STMT_INSERT_LINK, /* insert mlink */
STMT_INSERT_NAME, /* insert name */
+ STMT_SELECT_NAME, /* retrieve existing name flags */
STMT_INSERT_KEY, /* insert parsed key */
STMT__MAX
};
-typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_node *);
+typedef int (*mdoc_fp)(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
struct mdoc_handler {
mdoc_fp fp; /* optional handler */
@@ -136,7 +138,7 @@ struct mdoc_handler {
};
static void dbclose(int);
-static void dbadd(struct mpage *, struct mchars *);
+static void dbadd(struct mpage *);
static void dbadd_mlink(const struct mlink *mlink);
static void dbadd_mlink_name(const struct mlink *mlink);
static int dbopen(int);
@@ -150,25 +152,37 @@ static void mlink_check(struct mpage *, struct mlink *);
static void mlink_free(struct mlink *);
static void mlinks_undupe(struct mpage *);
static void mpages_free(void);
-static void mpages_merge(struct mchars *, struct mparse *);
+static void mpages_merge(struct mparse *);
static void names_check(void);
static void parse_cat(struct mpage *, int);
-static void parse_man(struct mpage *, const struct man_node *);
-static void parse_mdoc(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_body(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_head(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Fd(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Fn(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Nd(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Nm(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Sh(struct mpage *, const struct mdoc_node *);
-static int parse_mdoc_Xr(struct mpage *, const struct mdoc_node *);
+static void parse_man(struct mpage *, const struct man_meta *,
+ const struct man_node *);
+static void parse_mdoc(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_body(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_head(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_Fd(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static void parse_mdoc_fname(struct mpage *, const struct mdoc_node *);
+static int parse_mdoc_Fn(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_Fo(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_Nd(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_Nm(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_Sh(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
+static int parse_mdoc_Xr(struct mpage *, const struct mdoc_meta *,
+ const struct mdoc_node *);
static void putkey(const struct mpage *, char *, uint64_t);
-static void putkeys(const struct mpage *,
- const char *, size_t, uint64_t);
+static void putkeys(const struct mpage *, char *, size_t, uint64_t);
static void putmdockey(const struct mpage *,
const struct mdoc_node *, uint64_t);
-static void render_key(struct mchars *, struct str *);
+static int render_string(char **, size_t *);
static void say(const char *, const char *, ...);
static int set_basedir(const char *, int);
static int treescan(void);
@@ -185,6 +199,7 @@ static int write_utf8; /* write UTF-8 output; else ASCII */
static int exitcode; /* to be returned by main */
static enum op op; /* operational mode */
static char basedir[PATH_MAX]; /* current base directory */
+static struct mchars *mchars; /* table of named characters */
static struct ohash mpages; /* table of distinct manual pages */
static struct ohash mlinks; /* table of directory entries */
static struct ohash names; /* table of all names */
@@ -290,7 +305,7 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
{ NULL, 0 }, /* Ux */
{ NULL, 0 }, /* Xc */
{ NULL, 0 }, /* Xo */
- { parse_mdoc_head, 0 }, /* Fo */
+ { parse_mdoc_Fo, 0 }, /* Fo */
{ NULL, 0 }, /* Fc */
{ NULL, 0 }, /* Oo */
{ NULL, 0 }, /* Oc */
@@ -321,12 +336,11 @@ static const struct mdoc_handler mdocs[MDOC_MAX] = {
int
-main(int argc, char *argv[])
+mandocdb(int argc, char *argv[])
{
int ch, i;
size_t j, sz;
const char *path_arg;
- struct mchars *mc;
struct manpaths dirs;
struct mparse *mp;
struct ohash_info mpages_info, mlinks_info;
@@ -426,9 +440,9 @@ main(int argc, char *argv[])
}
exitcode = (int)MANDOCLEVEL_OK;
- mc = mchars_alloc();
+ mchars = mchars_alloc();
mp = mparse_alloc(mparse_options, MANDOCLEVEL_FATAL, NULL,
- mc, NULL);
+ mchars, NULL);
ohash_init(&mpages, 6, &mpages_info);
ohash_init(&mlinks, 6, &mlinks_info);
@@ -464,7 +478,7 @@ main(int argc, char *argv[])
goto out;
}
if (OP_DELETE != op)
- mpages_merge(mc, mp);
+ mpages_merge(mp);
dbclose(OP_DEFAULT == op ? 0 : 1);
} else {
/*
@@ -511,7 +525,7 @@ main(int argc, char *argv[])
if (0 == dbopen(0))
continue;
- mpages_merge(mc, mp);
+ mpages_merge(mp);
if (warnings && !nodb &&
! (MPARSE_QUICK & mparse_options))
names_check();
@@ -527,7 +541,7 @@ main(int argc, char *argv[])
out:
manpath_free(&dirs);
mparse_free(mp);
- mchars_free(mc);
+ mchars_free(mchars);
mpages_free();
ohash_delete(&mpages);
ohash_delete(&mlinks);
@@ -1074,7 +1088,7 @@ mlink_check(struct mpage *mpage, struct mlink *mlink)
* and filename to determine whether the file is parsable or not.
*/
static void
-mpages_merge(struct mchars *mc, struct mparse *mp)
+mpages_merge(struct mparse *mp)
{
char any[] = "any";
struct ohash_info str_info;
@@ -1213,16 +1227,14 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
putkey(mpage, mlink->name, NAME_FILE);
}
- assert(NULL == mpage->desc);
- if (NULL != mdoc) {
- if (NULL != (cp = mdoc_meta(mdoc)->name))
- putkey(mpage, cp, NAME_HEAD);
- parse_mdoc(mpage, mdoc_node(mdoc));
- } else if (NULL != man)
- parse_man(mpage, man_node(man));
+ assert(mpage->desc == NULL);
+ if (mdoc != NULL)
+ parse_mdoc(mpage, mdoc_meta(mdoc), mdoc_node(mdoc));
+ else if (man != NULL)
+ parse_man(mpage, man_meta(man), man_node(man));
else
parse_cat(mpage, fd);
- if (NULL == mpage->desc)
+ if (mpage->desc == NULL)
mpage->desc = mandoc_strdup(mpage->mlinks->name);
if (warnings && !use_all)
@@ -1230,7 +1242,7 @@ mpages_merge(struct mchars *mc, struct mparse *mp)
mlink = mlink->next)
mlink_check(mpage, mlink);
- dbadd(mpage, mc);
+ dbadd(mpage);
nextpage:
if (mparse_wait(mp) != MANDOCLEVEL_OK) {
@@ -1427,7 +1439,8 @@ putmdockey(const struct mpage *mpage,
}
static void
-parse_man(struct mpage *mpage, const struct man_node *n)
+parse_man(struct mpage *mpage, const struct man_meta *meta,
+ const struct man_node *n)
{
const struct man_node *head, *body;
char *start, *title;
@@ -1493,6 +1506,11 @@ parse_man(struct mpage *mpage, const struct man_node *n)
break;
putkey(mpage, start, NAME_TITLE);
+ if ( ! (mpage->name_head_done ||
+ strcasecmp(start, meta->title))) {
+ putkey(mpage, start, NAME_HEAD);
+ mpage->name_head_done = 1;
+ }
if (' ' == byte) {
start += sz + 1;
@@ -1507,6 +1525,11 @@ parse_man(struct mpage *mpage, const struct man_node *n)
if (start == title) {
putkey(mpage, start, NAME_TITLE);
+ if ( ! (mpage->name_head_done ||
+ strcasecmp(start, meta->title))) {
+ putkey(mpage, start, NAME_HEAD);
+ mpage->name_head_done = 1;
+ }
free(title);
return;
}
@@ -1537,12 +1560,13 @@ parse_man(struct mpage *mpage, const struct man_node *n)
for (n = n->child; n; n = n->next) {
if (NULL != mpage->desc)
break;
- parse_man(mpage, n);
+ parse_man(mpage, meta, n);
}
}
static void
-parse_mdoc(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
assert(NULL != n);
@@ -1558,7 +1582,7 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node *n)
/* FALLTHROUGH */
case MDOC_TAIL:
if (NULL != mdocs[n->tok].fp)
- if (0 == (*mdocs[n->tok].fp)(mpage, n))
+ if (0 == (*mdocs[n->tok].fp)(mpage, meta, n))
break;
if (mdocs[n->tok].mask)
putmdockey(mpage, n->child,
@@ -1569,14 +1593,15 @@ parse_mdoc(struct mpage *mpage, const struct mdoc_node *n)
continue;
}
if (NULL != n->child)
- parse_mdoc(mpage, n);
+ parse_mdoc(mpage, meta, n);
}
}
static int
-parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
- const char *start, *end;
+ char *start, *end;
size_t sz;
if (SEC_SYNOPSIS != n->sec ||
@@ -1616,41 +1641,61 @@ parse_mdoc_Fd(struct mpage *mpage, const struct mdoc_node *n)
return(0);
}
-static int
-parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_node *n)
+static void
+parse_mdoc_fname(struct mpage *mpage, const struct mdoc_node *n)
{
char *cp;
+ size_t sz;
- if (NULL == (n = n->child) || MDOC_TEXT != n->type)
- return(0);
-
- /*
- * Parse: .Fn "struct type *name" "char *arg".
- * First strip away pointer symbol.
- * Then store the function name, then type.
- * Finally, store the arguments.
- */
+ if (n->type != MDOC_TEXT)
+ return;
- if (NULL == (cp = strrchr(n->string, ' ')))
- cp = n->string;
+ /* Skip function pointer punctuation. */
- while ('*' == *cp)
+ cp = n->string;
+ while (*cp == '(' || *cp == '*')
cp++;
+ sz = strcspn(cp, "()");
- putkey(mpage, cp, TYPE_Fn);
+ putkeys(mpage, cp, sz, TYPE_Fn);
+ if (n->sec == SEC_SYNOPSIS)
+ putkeys(mpage, cp, sz, NAME_SYN);
+}
- if (n->string < cp)
- putkeys(mpage, n->string, cp - n->string, TYPE_Ft);
+static int
+parse_mdoc_Fn(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
+{
- for (n = n->next; NULL != n; n = n->next)
- if (MDOC_TEXT == n->type)
+ if (n->child == NULL)
+ return(0);
+
+ parse_mdoc_fname(mpage, n->child);
+
+ for (n = n->child->next; n != NULL; n = n->next)
+ if (n->type == MDOC_TEXT)
putkey(mpage, n->string, TYPE_Fa);
return(0);
}
static int
-parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_Fo(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
+{
+
+ if (n->type != MDOC_HEAD)
+ return(1);
+
+ if (n->child != NULL)
+ parse_mdoc_fname(mpage, n->child);
+
+ return(0);
+}
+
+static int
+parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
char *cp;
@@ -1669,7 +1714,8 @@ parse_mdoc_Xr(struct mpage *mpage, const struct mdoc_node *n)
}
static int
-parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
if (MDOC_BODY == n->type)
@@ -1678,32 +1724,46 @@ parse_mdoc_Nd(struct mpage *mpage, const struct mdoc_node *n)
}
static int
-parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_Nm(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
if (SEC_NAME == n->sec)
putmdockey(mpage, n->child, NAME_TITLE);
- else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type)
- putmdockey(mpage, n->child, NAME_SYN);
+ else if (SEC_SYNOPSIS == n->sec && MDOC_HEAD == n->type) {
+ if (n->child == NULL)
+ putkey(mpage, meta->name, NAME_SYN);
+ else
+ putmdockey(mpage, n->child, NAME_SYN);
+ }
+ if ( ! (mpage->name_head_done ||
+ n->child == NULL || n->child->string == NULL ||
+ strcasecmp(n->child->string, meta->title))) {
+ putkey(mpage, n->child->string, NAME_HEAD);
+ mpage->name_head_done = 1;
+ }
return(0);
}
static int
-parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_Sh(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
return(SEC_CUSTOM == n->sec && MDOC_HEAD == n->type);
}
static int
-parse_mdoc_head(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_head(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
return(MDOC_HEAD == n->type);
}
static int
-parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n)
+parse_mdoc_body(struct mpage *mpage, const struct mdoc_meta *meta,
+ const struct mdoc_node *n)
{
return(MDOC_BODY == n->type);
@@ -1715,18 +1775,19 @@ parse_mdoc_body(struct mpage *mpage, const struct mdoc_node *n)
* When we finish the manual, we'll dump the table.
*/
static void
-putkeys(const struct mpage *mpage,
- const char *cp, size_t sz, uint64_t v)
+putkeys(const struct mpage *mpage, char *cp, size_t sz, uint64_t v)
{
struct ohash *htab;
struct str *s;
const char *end;
unsigned int slot;
- int i;
+ int i, mustfree;
if (0 == sz)
return;
+ mustfree = render_string(&cp, &sz);
+
if (TYPE_Nm & v) {
htab = &names;
v &= name_mask;
@@ -1734,7 +1795,7 @@ putkeys(const struct mpage *mpage,
name_mask &= ~NAME_FIRST;
if (debug > 1)
say(mpage->mlinks->file,
- "Adding name %*s", sz, cp);
+ "Adding name %*s, bits=%d", sz, cp, v);
} else {
htab = &strings;
if (debug > 1)
@@ -1759,6 +1820,9 @@ putkeys(const struct mpage *mpage,
}
s->mpage = mpage;
s->mask = v;
+
+ if (mustfree)
+ free(cp);
}
/*
@@ -1814,20 +1878,19 @@ utf8(unsigned int cp, char out[7])
}
/*
- * Store the rendered version of a key, or alias the pointer
- * if the key contains no escape sequences.
+ * If the string contains escape sequences,
+ * replace it with an allocated rendering and return 1,
+ * such that the caller can free it after use.
+ * Otherwise, do nothing and return 0.
*/
-static void
-render_key(struct mchars *mc, struct str *key)
+static int
+render_string(char **public, size_t *psz)
{
- size_t sz, bsz, pos;
+ const char *src, *scp, *addcp, *seq;
+ char *dst;
+ size_t ssz, dsz, addsz;
char utfbuf[7], res[6];
- char *buf;
- const char *seq, *cpp, *val;
- int len, u;
- enum mandoc_esc esc;
-
- assert(NULL == key->rendered);
+ int seqlen, unicode;
res[0] = '\\';
res[1] = '\t';
@@ -1836,68 +1899,62 @@ render_key(struct mchars *mc, struct str *key)
res[4] = ASCII_BREAK;
res[5] = '\0';
- val = key->key;
- bsz = strlen(val);
+ src = scp = *public;
+ ssz = *psz;
+ dst = NULL;
+ dsz = 0;
- /*
- * Pre-check: if we have no stop-characters, then set the
- * pointer as ourselvse and get out of here.
- */
- if (strcspn(val, res) == bsz) {
- key->rendered = key->key;
- return;
- }
+ while (scp < src + *psz) {
- /* Pre-allocate by the length of the input */
+ /* Leave normal characters unchanged. */
- buf = mandoc_malloc(++bsz);
- pos = 0;
+ if (strchr(res, *scp) == NULL) {
+ if (dst != NULL)
+ dst[dsz++] = *scp;
+ scp++;
+ continue;
+ }
- while ('\0' != *val) {
/*
- * Halt on the first escape sequence.
- * This also halts on the end of string, in which case
- * we just copy, fallthrough, and exit the loop.
+ * Found something that requires replacing,
+ * make sure we have a destination buffer.
*/
- if ((sz = strcspn(val, res)) > 0) {
- memcpy(&buf[pos], val, sz);
- pos += sz;
- val += sz;
+
+ if (dst == NULL) {
+ dst = mandoc_malloc(ssz + 1);
+ dsz = scp - src;
+ memcpy(dst, src, dsz);
}
- switch (*val) {
- case ASCII_HYPH:
- buf[pos++] = '-';
- val++;
- continue;
+ /* Handle single-char special characters. */
+
+ switch (*scp) {
+ case '\\':
+ break;
case '\t':
/* FALLTHROUGH */
case ASCII_NBRSP:
- buf[pos++] = ' ';
- val++;
+ dst[dsz++] = ' ';
+ scp++;
+ continue;
+ case ASCII_HYPH:
+ dst[dsz++] = '-';
/* FALLTHROUGH */
case ASCII_BREAK:
+ scp++;
continue;
default:
- break;
+ abort();
}
- if ('\\' != *val)
- break;
-
- /* Read past the slash. */
-
- val++;
/*
- * Parse the escape sequence and see if it's a
- * predefined character or special character.
+ * Found an escape sequence.
+ * Read past the slash, then parse it.
+ * Ignore everything except characters.
*/
- esc = mandoc_escape((const char **)&val,
- &seq, &len);
- if (ESCAPE_ERROR == esc)
- break;
- if (ESCAPE_SPECIAL != esc)
+ scp++;
+ if (mandoc_escape(&scp, &seq, &seqlen) != ESCAPE_SPECIAL)
continue;
/*
@@ -1906,32 +1963,44 @@ render_key(struct mchars *mc, struct str *key)
*/
if (write_utf8) {
- if ((u = mchars_spec2cp(mc, seq, len)) <= 0)
+ unicode = mchars_spec2cp(mchars, seq, seqlen);
+ if (unicode <= 0)
continue;
- cpp = utfbuf;
- if (0 == (sz = utf8(u, utfbuf)))
+ addsz = utf8(unicode, utfbuf);
+ if (addsz == 0)
continue;
- sz = strlen(cpp);
+ addcp = utfbuf;
} else {
- cpp = mchars_spec2str(mc, seq, len, &sz);
- if (NULL == cpp)
+ addcp = mchars_spec2str(mchars, seq, seqlen, &addsz);
+ if (addcp == NULL)
continue;
- if (ASCII_NBRSP == *cpp) {
- cpp = " ";
- sz = 1;
+ if (*addcp == ASCII_NBRSP) {
+ addcp = " ";
+ addsz = 1;
}
}
/* Copy the rendered glyph into the stream. */
- bsz += sz;
- buf = mandoc_realloc(buf, bsz);
- memcpy(&buf[pos], cpp, sz);
- pos += sz;
+ ssz += addsz;
+ dst = mandoc_realloc(dst, ssz + 1);
+ memcpy(dst + dsz, addcp, addsz);
+ dsz += addsz;
}
+ if (dst != NULL) {
+ *public = dst;
+ *psz = dsz;
+ }
+
+ /* Trim trailing whitespace and NUL-terminate. */
- buf[pos] = '\0';
- key->rendered = buf;
+ while (*psz > 0 && (*public)[*psz - 1] == ' ')
+ --*psz;
+ if (dst != NULL) {
+ (*public)[*psz] = '\0';
+ return(1);
+ } else
+ return(0);
}
static void
@@ -1951,12 +2020,21 @@ dbadd_mlink(const struct mlink *mlink)
static void
dbadd_mlink_name(const struct mlink *mlink)
{
+ uint64_t bits;
size_t i;
dbadd_mlink(mlink);
i = 1;
- SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, NAME_FILE & NAME_MASK);
+ SQL_BIND_INT64(stmts[STMT_SELECT_NAME], i, mlink->mpage->pageid);
+ bits = NAME_FILE & NAME_MASK;
+ if (sqlite3_step(stmts[STMT_SELECT_NAME]) == SQLITE_ROW) {
+ bits |= sqlite3_column_int64(stmts[STMT_SELECT_NAME], 0);
+ sqlite3_reset(stmts[STMT_SELECT_NAME]);
+ }
+
+ i = 1;
+ SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, bits);
SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, mlink->name);
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mlink->mpage->pageid);
SQL_STEP(stmts[STMT_INSERT_NAME]);
@@ -1970,28 +2048,24 @@ dbadd_mlink_name(const struct mlink *mlink)
* Also, handle escape sequences at the last possible moment.
*/
static void
-dbadd(struct mpage *mpage, struct mchars *mc)
+dbadd(struct mpage *mpage)
{
struct mlink *mlink;
struct str *key;
+ char *cp;
size_t i;
unsigned int slot;
+ int mustfree;
mlink = mpage->mlinks;
if (nodb) {
for (key = ohash_first(&names, &slot); NULL != key;
- key = ohash_next(&names, &slot)) {
- if (key->rendered != key->key)
- free(key->rendered);
+ key = ohash_next(&names, &slot))
free(key);
- }
for (key = ohash_first(&strings, &slot); NULL != key;
- key = ohash_next(&strings, &slot)) {
- if (key->rendered != key->key)
- free(key->rendered);
+ key = ohash_next(&strings, &slot))
free(key);
- }
if (0 == debug)
return;
while (NULL != mlink) {
@@ -2020,21 +2094,17 @@ dbadd(struct mpage *mpage, struct mchars *mc)
if (debug)
say(mlink->file, "Adding to database");
- i = strlen(mpage->desc) + 1;
- key = mandoc_calloc(1, sizeof(struct str) + i);
- memcpy(key->key, mpage->desc, i);
- render_key(mc, key);
-
+ cp = mpage->desc;
+ i = strlen(cp);
+ mustfree = render_string(&cp, &i);
i = 1;
- SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, key->rendered);
+ SQL_BIND_TEXT(stmts[STMT_INSERT_PAGE], i, cp);
SQL_BIND_INT(stmts[STMT_INSERT_PAGE], i, mpage->form);
SQL_STEP(stmts[STMT_INSERT_PAGE]);
mpage->pageid = sqlite3_last_insert_rowid(db);
sqlite3_reset(stmts[STMT_INSERT_PAGE]);
-
- if (key->rendered != key->key)
- free(key->rendered);
- free(key);
+ if (mustfree)
+ free(cp);
while (NULL != mlink) {
dbadd_mlink(mlink);
@@ -2045,31 +2115,23 @@ dbadd(struct mpage *mpage, struct mchars *mc)
for (key = ohash_first(&names, &slot); NULL != key;
key = ohash_next(&names, &slot)) {
assert(key->mpage == mpage);
- if (NULL == key->rendered)
- render_key(mc, key);
i = 1;
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, key->mask);
- SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->rendered);
+ SQL_BIND_TEXT(stmts[STMT_INSERT_NAME], i, key->key);
SQL_BIND_INT64(stmts[STMT_INSERT_NAME], i, mpage->pageid);
SQL_STEP(stmts[STMT_INSERT_NAME]);
sqlite3_reset(stmts[STMT_INSERT_NAME]);
- if (key->rendered != key->key)
- free(key->rendered);
free(key);
}
for (key = ohash_first(&strings, &slot); NULL != key;
key = ohash_next(&strings, &slot)) {
assert(key->mpage == mpage);
- if (NULL == key->rendered)
- render_key(mc, key);
i = 1;
SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, key->mask);
- SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->rendered);
+ SQL_BIND_TEXT(stmts[STMT_INSERT_KEY], i, key->key);
SQL_BIND_INT64(stmts[STMT_INSERT_KEY], i, mpage->pageid);
SQL_STEP(stmts[STMT_INSERT_KEY]);
sqlite3_reset(stmts[STMT_INSERT_KEY]);
- if (key->rendered != key->key)
- free(key->rendered);
free(key);
}
}
@@ -2269,7 +2331,8 @@ create_tables:
" \"bits\" INTEGER NOT NULL,\n"
" \"name\" TEXT NOT NULL,\n"
" \"pageid\" INTEGER NOT NULL REFERENCES mpages(pageid) "
- "ON DELETE CASCADE\n"
+ "ON DELETE CASCADE,\n"
+ " UNIQUE (\"name\", \"pageid\") ON CONFLICT REPLACE\n"
");\n"
"\n"
"CREATE TABLE \"keys\" (\n"
@@ -2307,6 +2370,8 @@ prepare_statements:
sql = "INSERT INTO mlinks "
"(sec,arch,name,pageid) VALUES (?,?,?,?)";
sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_LINK], NULL);
+ sql = "SELECT bits FROM names where pageid = ?";
+ sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_SELECT_NAME], NULL);
sql = "INSERT INTO names "
"(bits,name,pageid) VALUES (?,?,?)";
sqlite3_prepare_v2(db, sql, -1, &stmts[STMT_INSERT_NAME], NULL);
diff --git a/contrib/mdocml/manpath.h b/contrib/mdocml/manpath.h
index 2fe1b36..728373b 100644
--- a/contrib/mdocml/manpath.h
+++ b/contrib/mdocml/manpath.h
@@ -1,4 +1,4 @@
-/* $Id: manpath.h,v 1.6 2012/06/08 10:32:40 kristaps Exp $ */
+/* $Id: manpath.h,v 1.7 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
* Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MANPATH_H
-#define MANPATH_H
/*
* Unsorted list of unique, absolute paths to be searched for manual
@@ -34,5 +32,3 @@ void manpath_parse(struct manpaths *, const char *, char *, char *);
void manpath_free(struct manpaths *);
__END_DECLS
-
-#endif /*!MANPATH_H*/
diff --git a/contrib/mdocml/mansearch.3 b/contrib/mdocml/mansearch.3
index 28590e5..f41e361 100644
--- a/contrib/mdocml/mansearch.3
+++ b/contrib/mdocml/mansearch.3
@@ -1,4 +1,4 @@
-.\" $Id: mansearch.3,v 1.2 2014/08/05 15:29:30 schwarze Exp $
+.\" $Id: mansearch.3,v 1.3 2014/12/12 21:44:33 schwarze Exp $
.\"
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 5 2014 $
+.Dd $Mdocdate: December 12 2014 $
.Dt MANSEARCH 3
.Os
.Sh NAME
@@ -172,7 +172,7 @@ using the following query:
If the
.Fa outkey
differs from
-.Qq Nd ,
+.Qq Ic \&Nd ,
the requested output data is assembled into the
.Va output
field of the result structure by the function
diff --git a/contrib/mdocml/mansearch.c b/contrib/mdocml/mansearch.c
index 77d4c07..dbfbe02 100644
--- a/contrib/mdocml/mansearch.c
+++ b/contrib/mdocml/mansearch.c
@@ -1,4 +1,4 @@
-/* $Id: mansearch.c,v 1.51 2014/11/27 01:58:21 schwarze Exp $ */
+/* $Id: mansearch.c,v 1.52 2014/12/06 01:23:24 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
@@ -246,7 +247,8 @@ mansearch(const struct mansearch *search,
SQLITE_OPEN_READONLY, NULL);
if (SQLITE_OK != c) {
- perror(MANDOC_DB);
+ fprintf(stderr, "%s/%s: %s\n",
+ paths->paths[i], MANDOC_DB, strerror(errno));
sqlite3_close(db);
continue;
}
diff --git a/contrib/mdocml/mansearch.h b/contrib/mdocml/mansearch.h
index 4f92ef2..14ec8ce 100644
--- a/contrib/mdocml/mansearch.h
+++ b/contrib/mdocml/mansearch.h
@@ -1,4 +1,4 @@
-/* $Id: mansearch.h,v 1.21 2014/11/27 01:58:21 schwarze Exp $ */
+/* $Id: mansearch.h,v 1.23 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,8 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MANSEARCH_H
-#define MANSEARCH_H
#define MANDOC_DB "mandoc.db"
@@ -99,6 +97,8 @@ struct mansearch {
__BEGIN_DECLS
+struct manpaths;
+
int mansearch_setup(int);
int mansearch(const struct mansearch *cfg, /* options */
const struct manpaths *paths, /* manpaths */
@@ -109,5 +109,3 @@ int mansearch(const struct mansearch *cfg, /* options */
void mansearch_free(struct manpage *, size_t);
__END_DECLS
-
-#endif /* MANSEARCH_H */
diff --git a/contrib/mdocml/mansearch_const.c b/contrib/mdocml/mansearch_const.c
index 9ba8bc25..61351c3 100644
--- a/contrib/mdocml/mansearch_const.c
+++ b/contrib/mdocml/mansearch_const.c
@@ -1,4 +1,4 @@
-/* $Id: mansearch_const.c,v 1.6 2014/08/10 23:54:41 schwarze Exp $ */
+/* $Id: mansearch_const.c,v 1.7 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -20,7 +20,6 @@
#include <stdint.h>
-#include "manpath.h"
#include "mansearch.h"
const int mansearch_keymax = 40;
diff --git a/contrib/mdocml/mdoc.7 b/contrib/mdocml/mdoc.7
index a13d613..a9b0fe2 100644
--- a/contrib/mdocml/mdoc.7
+++ b/contrib/mdocml/mdoc.7
@@ -1,4 +1,4 @@
-.\" $Id: mdoc.7,v 1.244 2014/11/28 18:36:35 schwarze Exp $
+.\" $Id: mdoc.7,v 1.245 2014/11/30 21:56:18 schwarze Exp $
.\"
.\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 $Mdocdate: November 28 2014 $
+.Dd $Mdocdate: November 30 2014 $
.Dt MDOC 7
.Os
.Sh NAME
@@ -2396,8 +2396,6 @@ The original C standard.
.Pp
.It \-isoC-99
.St -isoC-99
-.It \-ansiC-99
-.St -ansiC-99
.br
The second major version of the C language standard.
.Pp
@@ -2497,9 +2495,6 @@ The following three refer to parts of it.
.br
Networking APIs, including sockets.
.Pp
-.It \-xpg4.3
-.St -xpg4.3
-.Pp
.It \-svid4
.St -svid4 ,
.br
@@ -2529,14 +2524,9 @@ The following refer to parts of it.
.It \-xns5.2
.St -xns5.2
.El
-.It Single UNIX Specification version 3 and related standards
-.Pp
-.Bl -tag -width "-p1003.1g-2000X" -compact
-.It \-p1003.1d-99
-.St -p1003.1d-99
-.br
-Additional real-time extensions.
+.It Single UNIX Specification version 3
.Pp
+.Bl -tag -width "-p1003.1-2001" -compact
.It \-p1003.1-2001
.St -p1003.1-2001
.It \-susv3
diff --git a/contrib/mdocml/mdoc.h b/contrib/mdocml/mdoc.h
index 58ad813..f7c933d 100644
--- a/contrib/mdocml/mdoc.h
+++ b/contrib/mdocml/mdoc.h
@@ -1,4 +1,4 @@
-/* $Id: mdoc.h,v 1.131 2014/07/29 13:58:18 schwarze Exp $ */
+/* $Id: mdoc.h,v 1.132 2014/12/01 04:05:32 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -14,8 +14,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef MDOC_H
-#define MDOC_H
enum mdoct {
MDOC_Ap = 0,
@@ -395,5 +393,3 @@ const struct mdoc_meta *mdoc_meta(const struct mdoc *);
void mdoc_deroff(char **, const struct mdoc_node *);
__END_DECLS
-
-#endif /*!MDOC_H*/
diff --git a/contrib/mdocml/mdoc_html.c b/contrib/mdocml/mdoc_html.c
index 0cd3cf0..ca51049 100644
--- a/contrib/mdocml/mdoc_html.c
+++ b/contrib/mdocml/mdoc_html.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_html.c,v 1.213 2014/11/27 22:27:56 schwarze Exp $ */
+/* $Id: mdoc_html.c,v 1.216 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -26,11 +26,10 @@
#include <string.h>
#include <unistd.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
+#include "mdoc.h"
#include "out.h"
#include "html.h"
-#include "mdoc.h"
#include "main.h"
#define INDENT 5
@@ -1202,7 +1201,8 @@ mdoc_bd_pre(MDOC_ARGS)
default:
break;
}
- if (nn->next && nn->next->line == nn->line)
+ if (h->flags & HTML_NONEWLINE ||
+ (nn->next && ! (nn->next->flags & MDOC_LINE)))
continue;
else if (nn->next)
print_text(h, "\n");
@@ -1869,7 +1869,8 @@ static void
mdoc_pf_post(MDOC_ARGS)
{
- h->flags |= HTML_NOSPACE;
+ if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+ h->flags |= HTML_NOSPACE;
}
static int
diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mdocml/mdoc_macro.c
index b501d4d..b354e54 100644
--- a/contrib/mdocml/mdoc_macro.c
+++ b/contrib/mdocml/mdoc_macro.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_macro.c,v 1.154 2014/11/29 04:31:35 schwarze Exp $ */
+/* $Id: mdoc_macro.c,v 1.157 2014/12/13 13:14:39 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -53,7 +53,8 @@ static void phrase_ta(MACRO_PROT_ARGS);
static void dword(struct mdoc *, int, int, const char *,
enum mdelim, int);
static void append_delims(struct mdoc *, int, int *, char *);
-static enum mdoct lookup(enum mdoct, const char *);
+static enum mdoct lookup(struct mdoc *, enum mdoct,
+ int, int, const char *);
static int macro_or_word(MACRO_PROT_ARGS, int);
static int make_pending(struct mdoc_node *, enum mdoct,
struct mdoc *, int, int);
@@ -245,14 +246,19 @@ mdoc_macroend(struct mdoc *mdoc)
* or as a line macro if from == MDOC_MAX.
*/
static enum mdoct
-lookup(enum mdoct from, const char *p)
+lookup(struct mdoc *mdoc, enum mdoct from, int line, int ppos, const char *p)
{
enum mdoct res;
if (from == MDOC_MAX || mdoc_macros[from].flags & MDOC_PARSED) {
res = mdoc_hash_find(p);
- if (res != MDOC_MAX && mdoc_macros[res].flags & MDOC_CALLABLE)
- return(res);
+ if (res != MDOC_MAX) {
+ if (mdoc_macros[res].flags & MDOC_CALLABLE)
+ return(res);
+ if (res != MDOC_br && res != MDOC_sp && res != MDOC_ll)
+ mandoc_msg(MANDOCERR_MACRO_CALL,
+ mdoc->parse, line, ppos, p);
+ }
}
return(MDOC_MAX);
}
@@ -666,12 +672,10 @@ macro_or_word(MACRO_PROT_ARGS, int parsed)
p = buf + ppos;
ntok = MDOC_MAX;
- if (mdoc->flags & MDOC_PHRASELIT)
- /* nothing */;
- else if (*p == '"')
+ if (*p == '"')
p++;
- else if (parsed)
- ntok = lookup(tok, p);
+ else if (parsed && ! (mdoc->flags & MDOC_PHRASELIT))
+ ntok = lookup(mdoc, tok, line, ppos, p);
if (ntok == MDOC_MAX) {
dword(mdoc, line, ppos, p, DELIM_MAX, tok == MDOC_MAX ||
@@ -832,7 +836,8 @@ blk_exp_close(MACRO_PROT_ARGS)
if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
break;
- ntok = ac == ARGS_QWORD ? MDOC_MAX : lookup(tok, p);
+ ntok = ac == ARGS_QWORD ? MDOC_MAX :
+ lookup(mdoc, tok, line, lastarg, p);
if (ntok == MDOC_MAX) {
dword(mdoc, line, lastarg, p, DELIM_MAX,
@@ -933,7 +938,7 @@ in_line(MACRO_PROT_ARGS)
}
ntok = (ac == ARGS_QWORD || (tok == MDOC_Fn && !cnt)) ?
- MDOC_MAX : lookup(tok, p);
+ MDOC_MAX : lookup(mdoc, tok, line, la, p);
/*
* In this case, we've located a submacro and must
@@ -1389,7 +1394,7 @@ in_line_argn(MACRO_PROT_ARGS)
char *p;
enum mdoct ntok;
- nl = MDOC_NEWLINE & mdoc->flags;
+ nl = mdoc->flags & MDOC_NEWLINE;
/*
* A line macro that has a fixed number of arguments (maxargs).
@@ -1421,11 +1426,18 @@ in_line_argn(MACRO_PROT_ARGS)
mdoc_argv(mdoc, line, tok, &arg, pos, buf);
- for (flushed = j = 0; ; ) {
+ p = NULL;
+ flushed = j = 0;
+ for (;;) {
la = *pos;
ac = mdoc_args(mdoc, line, pos, buf, tok, &p);
- if (ac == ARGS_PUNCT || ac == ARGS_EOLN)
+ if (ac == ARGS_PUNCT || ac == ARGS_EOLN) {
+ if (j < 2 && tok == MDOC_Pf)
+ mandoc_vmsg(MANDOCERR_PF_SKIP,
+ mdoc->parse, line, ppos, "Pf %s",
+ p == NULL ? "at eol" : p);
break;
+ }
if ( ! (mdoc_macros[tok].flags & MDOC_IGNDELIM) &&
ac != ARGS_QWORD && j == 0 &&
@@ -1440,7 +1452,8 @@ in_line_argn(MACRO_PROT_ARGS)
flushed = 1;
}
- ntok = ac == ARGS_QWORD ? MDOC_MAX : lookup(tok, p);
+ ntok = (ac == ARGS_QWORD || (tok == MDOC_Pf && j == 0)) ?
+ MDOC_MAX : lookup(mdoc, tok, line, la, p);
if (ntok != MDOC_MAX) {
if ( ! flushed)
@@ -1463,8 +1476,11 @@ in_line_argn(MACRO_PROT_ARGS)
j++;
}
- if (j == 0)
+ if (j == 0) {
mdoc_elem_alloc(mdoc, line, ppos, tok, arg);
+ if (ac == ARGS_PUNCT && tok == MDOC_Pf)
+ append_delims(mdoc, line, pos, buf);
+ }
if ( ! flushed)
rew_elem(mdoc, tok);
if (nl)
diff --git a/contrib/mdocml/mdoc_man.c b/contrib/mdocml/mdoc_man.c
index 41cc65b..974cfbd 100644
--- a/contrib/mdocml/mdoc_man.c
+++ b/contrib/mdocml/mdoc_man.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_man.c,v 1.76 2014/11/27 22:27:56 schwarze Exp $ */
+/* $Id: mdoc_man.c,v 1.77 2014/11/30 05:29:00 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
*
@@ -1602,7 +1602,8 @@ static void
post_pf(DECL_ARGS)
{
- outflags &= ~MMAN_spc;
+ if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+ outflags &= ~MMAN_spc;
}
static int
diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mdocml/mdoc_term.c
index dcc2682..7f57aed 100644
--- a/contrib/mdocml/mdoc_term.c
+++ b/contrib/mdocml/mdoc_term.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_term.c,v 1.297 2014/11/28 16:54:23 schwarze Exp $ */
+/* $Id: mdoc_term.c,v 1.299 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -1632,7 +1632,8 @@ termp_bd_pre(DECL_ARGS)
default:
break;
}
- if (nn->next && nn->next->line == nn->line)
+ if (p->flags & TERMP_NONEWLINE ||
+ (nn->next && ! (nn->next->flags & MDOC_LINE)))
continue;
term_flushln(p);
p->flags |= TERMP_NOSPACE;
@@ -1734,7 +1735,8 @@ static void
termp_pf_post(DECL_ARGS)
{
- p->flags |= TERMP_NOSPACE;
+ if ( ! (n->next == NULL || n->next->flags & MDOC_LINE))
+ p->flags |= TERMP_NOSPACE;
}
static int
diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mdocml/mdoc_validate.c
index 5a07af3..7990ffe 100644
--- a/contrib/mdocml/mdoc_validate.c
+++ b/contrib/mdocml/mdoc_validate.c
@@ -1,4 +1,4 @@
-/* $Id: mdoc_validate.c,v 1.262 2014/11/28 18:36:35 schwarze Exp $ */
+/* $Id: mdoc_validate.c,v 1.263 2014/11/30 05:29:00 schwarze Exp $ */
/*
* Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -210,7 +210,7 @@ static const struct valids mdoc_valids[MDOC_MAX] = {
{ NULL, NULL }, /* Nx */
{ NULL, NULL }, /* Ox */
{ NULL, NULL }, /* Pc */
- { NULL, ewarn_eq1 }, /* Pf */
+ { NULL, NULL }, /* Pf */
{ NULL, NULL }, /* Po */
{ NULL, NULL }, /* Pq */
{ NULL, NULL }, /* Qc */
diff --git a/contrib/mdocml/msec.c b/contrib/mdocml/msec.c
index 2d0d85b..ffe5024 100644
--- a/contrib/mdocml/msec.c
+++ b/contrib/mdocml/msec.c
@@ -1,4 +1,4 @@
-/* $Id: msec.c,v 1.12 2014/08/10 23:54:41 schwarze Exp $ */
+/* $Id: msec.c,v 1.13 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -20,7 +20,6 @@
#include <string.h>
-#include "mandoc.h"
#include "libmandoc.h"
#define LINE(x, y) \
diff --git a/contrib/mdocml/out.c b/contrib/mdocml/out.c
index 5b08a09..7a61b39 100644
--- a/contrib/mdocml/out.c
+++ b/contrib/mdocml/out.c
@@ -1,4 +1,4 @@
-/* $Id: out.c,v 1.53 2014/10/14 18:18:05 schwarze Exp $ */
+/* $Id: out.c,v 1.54 2014/12/04 02:05:42 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -110,7 +110,7 @@ a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
case '\0':
if (SCALE_MAX == def)
return(0);
- unit = SCALE_EN;
+ unit = def;
break;
case 'u':
unit = SCALE_BU;
diff --git a/contrib/mdocml/out.h b/contrib/mdocml/out.h
index de38ec1..cc218f4 100644
--- a/contrib/mdocml/out.h
+++ b/contrib/mdocml/out.h
@@ -1,4 +1,4 @@
-/* $Id: out.h,v 1.24 2014/10/14 02:16:06 schwarze Exp $ */
+/* $Id: out.h,v 1.26 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -14,8 +14,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef OUT_H
-#define OUT_H
enum roffscale {
SCALE_CM, /* centimeters (c) */
@@ -52,8 +50,6 @@ struct rofftbl {
void *arg; /* passed to slen and len */
};
-__BEGIN_DECLS
-
#define SCALE_VS_INIT(p, v) \
do { (p)->unit = SCALE_VS; \
(p)->scale = (v); } \
@@ -64,10 +60,12 @@ __BEGIN_DECLS
(p)->scale = (v); } \
while (/* CONSTCOND */ 0)
+__BEGIN_DECLS
+
+struct tbl_span;
+
int a2roffsu(const char *, struct roffsu *, enum roffscale);
void tblcalc(struct rofftbl *tbl,
const struct tbl_span *, size_t);
__END_DECLS
-
-#endif /*!OUT_H*/
diff --git a/contrib/mdocml/read.c b/contrib/mdocml/read.c
index 96444f5..8d6cb10 100644
--- a/contrib/mdocml/read.c
+++ b/contrib/mdocml/read.c
@@ -1,4 +1,4 @@
-/* $Id: read.c,v 1.101 2014/11/28 18:09:01 schwarze Exp $ */
+/* $Id: read.c,v 1.104 2014/12/01 04:14:14 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -41,7 +41,6 @@
#include "libmandoc.h"
#include "mdoc.h"
#include "man.h"
-#include "main.h"
#define REPARSE_LIMIT 1000
@@ -120,6 +119,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
/* related to macros and nesting */
"obsolete macro",
+ "macro neither callable nor escaped",
"skipping paragraph macro",
"moving paragraph macro out of list",
"skipping no-space macro",
@@ -145,6 +145,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = {
"empty list item",
"missing font type, using \\fR",
"unknown font type, using \\fR",
+ "nothing follows prefix",
"missing -std argument, adding it",
"missing eqn box, using \"\"",
@@ -754,12 +755,12 @@ mparse_parse_buffer(struct mparse *curp, struct buf blk, const char *file)
}
enum mandoclevel
-mparse_readmem(struct mparse *curp, const void *buf, size_t len,
+mparse_readmem(struct mparse *curp, void *buf, size_t len,
const char *file)
{
struct buf blk;
- blk.buf = UNCONST(buf);
+ blk.buf = buf;
blk.sz = len;
mparse_parse_buffer(curp, blk, file);
diff --git a/contrib/mdocml/roff.7 b/contrib/mdocml/roff.7
index 6e2e8dd..6ee2932 100644
--- a/contrib/mdocml/roff.7
+++ b/contrib/mdocml/roff.7
@@ -1,4 +1,4 @@
-.\" $Id: roff.7,v 1.59 2014/11/19 01:20:25 schwarze Exp $
+.\" $Id: roff.7,v 1.60 2014/12/02 10:08:06 schwarze Exp $
.\"
.\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
.\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -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 $Mdocdate: November 19 2014 $
+.Dd $Mdocdate: December 2 2014 $
.Dt ROFF 7
.Os
.Sh NAME
@@ -1196,8 +1196,10 @@ Bracket building function; ignored by
.Sx Special Characters
with names of arbitrary length.
.Ss \ec
-Interrupt text processing to insert requests or macros; ignored by
-.Xr mandoc 1 .
+When encountered at the end of an input text line,
+the next input text line is considered to continue that line,
+even if there are request or macro lines in between.
+No whitespace is inserted.
.Ss \eD\(aq Ns Ar string Ns \(aq
Draw graphics function; ignored by
.Xr mandoc 1 .
diff --git a/contrib/mdocml/st.in b/contrib/mdocml/st.in
index ee79aed..5d2f129 100644
--- a/contrib/mdocml/st.in
+++ b/contrib/mdocml/st.in
@@ -1,4 +1,4 @@
-/* $Id: st.in,v 1.26 2014/11/16 20:46:21 schwarze Exp $ */
+/* $Id: st.in,v 1.27 2014/11/30 21:56:18 schwarze Exp $ */
/*
* Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -39,7 +39,6 @@ LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)")
LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)")
LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)")
LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)")
-LINE("-p1003.1d-99", "IEEE Std 1003.1d-1999 (\\(lqPOSIX.1d\\(rq)")
LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)")
LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)")
LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)")
@@ -57,7 +56,6 @@ LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)")
LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)")
LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
LINE("-ansiC-89", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)")
-LINE("-ansiC-99", "ANSI/ISO/IEC 9899-1999 (\\(lqANSI\\~C99\\(rq)")
LINE("-ieee754", "IEEE Std 754-1985")
LINE("-iso8802-3", "ISO 8802-3: 1989")
LINE("-iso8601", "ISO 8601")
@@ -65,7 +63,6 @@ LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)")
LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)")
LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)")
LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)")
-LINE("-xpg4.3", "X/Open Portability Guide Issue\\~4, Version\\~3 (\\(lqXPG4.3\\(rq)")
LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)")
LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)")
LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)")
diff --git a/contrib/mdocml/term.c b/contrib/mdocml/term.c
index 5b01aa6..33f8f90 100644
--- a/contrib/mdocml/term.c
+++ b/contrib/mdocml/term.c
@@ -1,4 +1,4 @@
-/* $Id: term.c,v 1.236 2014/11/21 01:52:53 schwarze Exp $ */
+/* $Id: term.c,v 1.237 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -417,7 +417,7 @@ term_word(struct termp *p, const char *word)
else
p->flags |= TERMP_NOSPACE;
- p->flags &= ~TERMP_SENTENCE;
+ p->flags &= ~(TERMP_SENTENCE | TERMP_NONEWLINE);
while ('\0' != *word) {
if ('\\' != *word) {
@@ -487,7 +487,7 @@ term_word(struct termp *p, const char *word)
if (TERMP_SKIPCHAR & p->flags)
p->flags &= ~TERMP_SKIPCHAR;
else if ('\0' == *word)
- p->flags |= TERMP_NOSPACE;
+ p->flags |= (TERMP_NOSPACE | TERMP_NONEWLINE);
continue;
case ESCAPE_SKIPCHAR:
p->flags |= TERMP_SKIPCHAR;
diff --git a/contrib/mdocml/term.h b/contrib/mdocml/term.h
index e17c244..62c6ffe 100644
--- a/contrib/mdocml/term.h
+++ b/contrib/mdocml/term.h
@@ -1,4 +1,4 @@
-/* $Id: term.h,v 1.105 2014/10/28 17:36:19 schwarze Exp $ */
+/* $Id: term.h,v 1.108 2014/12/02 10:08:06 schwarze Exp $ */
/*
* Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011, 2012, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,12 +15,6 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef TERM_H
-#define TERM_H
-
-__BEGIN_DECLS
-
-struct termp;
enum termenc {
TERMENC_ASCII,
@@ -44,6 +38,8 @@ enum termfont {
#define TERM_MAXMARGIN 100000 /* FIXME */
+struct termp;
+
typedef void (*term_margin)(struct termp *, const void *);
struct termp_tbl {
@@ -83,6 +79,7 @@ struct termp {
#define TERMP_HANG (1 << 11) /* See term_flushln(). */
#define TERMP_NOSPLIT (1 << 12) /* Do not break line before .An. */
#define TERMP_SPLIT (1 << 13) /* Break line before .An. */
+#define TERMP_NONEWLINE (1 << 14) /* No line break in nofill mode. */
int *buf; /* Output buffer. */
enum termenc enc; /* Type of encoding. */
const struct mchars *symtab; /* Character table. */
@@ -104,6 +101,11 @@ struct termp {
struct termp_ps *ps;
};
+__BEGIN_DECLS
+
+struct tbl_span;
+struct eqn;
+
const char *ascii_uc2str(int);
void term_eqn(struct termp *, const struct eqn *);
@@ -134,5 +136,3 @@ void term_fontrepl(struct termp *, enum termfont);
void term_fontlast(struct termp *);
__END_DECLS
-
-#endif /*!TERM_H*/
diff --git a/contrib/mdocml/term_ps.c b/contrib/mdocml/term_ps.c
index 2f0b434..e3299d7 100644
--- a/contrib/mdocml/term_ps.c
+++ b/contrib/mdocml/term_ps.c
@@ -1,4 +1,4 @@
-/* $Id: term_ps.c,v 1.69 2014/11/20 13:56:20 schwarze Exp $ */
+/* $Id: term_ps.c,v 1.70 2014/12/01 08:05:52 schwarze Exp $ */
/*
* Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -27,11 +27,10 @@
#include <string.h>
#include <unistd.h>
-#include "mandoc.h"
#include "mandoc_aux.h"
#include "out.h"
-#include "main.h"
#include "term.h"
+#include "main.h"
/* These work the buffer used by the header and footer. */
#define PS_BUFSLOP 128
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
index d665967..a0e77d3 100644
--- a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
@@ -231,6 +231,7 @@ ATF_TC_BODY(hsearch_two, tc)
hdestroy();
}
+#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version
#ifdef __NetBSD__
ATF_TC(hsearch_r_basic);
ATF_TC_HEAD(hsearch_r_basic, tc)
@@ -385,6 +386,7 @@ ATF_TC_BODY(hsearch_r_two, tc)
hdestroy_r(&t);
}
+#endif
ATF_TP_ADD_TCS(tp)
{
@@ -395,13 +397,15 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, hsearch_duplicate);
ATF_TP_ADD_TC(tp, hsearch_nonexistent);
ATF_TP_ADD_TC(tp, hsearch_two);
-
+
+#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version
#ifdef __NetBSD__
ATF_TP_ADD_TC(tp, hsearch_r_basic);
#endif
ATF_TP_ADD_TC(tp, hsearch_r_duplicate);
ATF_TP_ADD_TC(tp, hsearch_r_nonexistent);
ATF_TP_ADD_TC(tp, hsearch_r_two);
+#endif
return atf_no_error();
}
diff --git a/contrib/ntp/ntpd/ntp_config.c b/contrib/ntp/ntpd/ntp_config.c
index a28bd1b..e038f20 100644
--- a/contrib/ntp/ntpd/ntp_config.c
+++ b/contrib/ntp/ntpd/ntp_config.c
@@ -1887,7 +1887,7 @@ getconfig(
for (i = 0; i < 8; i++)
for (j = 1; j < 100; ++j) {
- rankey[i] = (char) (ntp_random() & 0xff);
+ rankey[i] = (char) (arc4random() & 0xff);
if (rankey[i] != 0) break;
}
rankey[8] = 0;
diff --git a/contrib/ntp/ntpd/ntp_control.c b/contrib/ntp/ntpd/ntp_control.c
index 15f5856..dbee89a 100644
--- a/contrib/ntp/ntpd/ntp_control.c
+++ b/contrib/ntp/ntpd/ntp_control.c
@@ -24,6 +24,10 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+#ifndef MIN
+#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
+#endif
+
/*
* Structure to hold request procedure information
*/
@@ -893,6 +897,7 @@ ctl_putdata(
)
{
int overhead;
+ unsigned int currentlen;
overhead = 0;
if (!bin) {
@@ -916,12 +921,22 @@ ctl_putdata(
/*
* Save room for trailing junk
*/
- if (dlen + overhead + datapt > dataend) {
+ while (dlen + overhead + datapt > dataend) {
/*
* Not enough room in this one, flush it out.
*/
+ currentlen = MIN(dlen, dataend - datapt);
+
+ memcpy(datapt, dp, currentlen);
+
+ datapt += currentlen;
+ dp += currentlen;
+ dlen -= currentlen;
+ datalinelen += currentlen;
+
ctl_flushpkt(CTL_MORE);
}
+
memmove((char *)datapt, dp, (unsigned)dlen);
datapt += dlen;
datalinelen += dlen;
diff --git a/contrib/ntp/ntpd/ntp_crypto.c b/contrib/ntp/ntpd/ntp_crypto.c
index cce95a8..37427f4 100644
--- a/contrib/ntp/ntpd/ntp_crypto.c
+++ b/contrib/ntp/ntpd/ntp_crypto.c
@@ -864,12 +864,24 @@ crypto_recv(
* errors.
*/
if (vallen == (u_int) EVP_PKEY_size(host_pkey)) {
- RSA_private_decrypt(vallen,
+ u_int32 *cookiebuf = malloc(
+ RSA_size(host_pkey->pkey.rsa));
+ if (cookiebuf == NULL) {
+ rval = XEVNT_CKY;
+ break;
+ }
+ if (RSA_private_decrypt(vallen,
(u_char *)ep->pkt,
- (u_char *)&temp32,
+ (u_char *)cookiebuf,
host_pkey->pkey.rsa,
- RSA_PKCS1_OAEP_PADDING);
- cookie = ntohl(temp32);
+ RSA_PKCS1_OAEP_PADDING) != 4) {
+ rval = XEVNT_CKY;
+ free(cookiebuf);
+ break;
+ } else {
+ cookie = ntohl(*cookiebuf);
+ free(cookiebuf);
+ }
} else {
rval = XEVNT_CKY;
break;
@@ -3914,7 +3926,7 @@ crypto_setup(void)
rand_file);
exit (-1);
}
- get_systime(&seed);
+ arc4random_buf(&seed, sizeof(l_fp));
RAND_seed(&seed, sizeof(l_fp));
RAND_write_file(rand_file);
OpenSSL_add_all_algorithms();
diff --git a/contrib/ntp/ntpd/ntp_proto.c b/contrib/ntp/ntpd/ntp_proto.c
index 0ab2498..179e118 100644
--- a/contrib/ntp/ntpd/ntp_proto.c
+++ b/contrib/ntp/ntpd/ntp_proto.c
@@ -649,6 +649,7 @@ receive(
has_mac)) {
is_authentic = AUTH_ERROR;
sys_badauth++;
+ return;
} else {
is_authentic = AUTH_OK;
}
diff --git a/contrib/ntp/util/ntp-keygen.c b/contrib/ntp/util/ntp-keygen.c
index 6c14518..056121e 100644
--- a/contrib/ntp/util/ntp-keygen.c
+++ b/contrib/ntp/util/ntp-keygen.c
@@ -642,7 +642,7 @@ gen_md5(
for (i = 1; i <= MD5KEYS; i++) {
for (j = 0; j < 16; j++) {
while (1) {
- temp = ntp_random() & 0xff;
+ temp = arc4random() & 0xff;
if (temp == '#')
continue;
if (temp > 0x20 && temp < 0x7f)
@@ -675,7 +675,7 @@ gen_rsa(
FILE *str;
fprintf(stderr, "Generating RSA keys (%d bits)...\n", modulus);
- rsa = RSA_generate_key(modulus, 3, cb, "RSA");
+ rsa = RSA_generate_key(modulus, 65537, cb, "RSA");
fprintf(stderr, "\n");
if (rsa == NULL) {
fprintf(stderr, "RSA generate keys fails\n%s\n",
@@ -954,7 +954,7 @@ gen_gqpar(
*/
fprintf(stderr,
"Generating GQ parameters (%d bits)...\n", modulus);
- rsa = RSA_generate_key(modulus, 3, cb, "GQ");
+ rsa = RSA_generate_key(modulus, 65537, cb, "GQ");
fprintf(stderr, "\n");
if (rsa == NULL) {
fprintf(stderr, "RSA generate keys fails\n%s\n",
diff --git a/contrib/ofed/libibverbs/examples/Makefile b/contrib/ofed/libibverbs/examples/Makefile
deleted file mode 100644
index 06da511..0000000
--- a/contrib/ofed/libibverbs/examples/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-CFLAGS= -I../../../../sys/ofed/include -libverbs -lmlx4 -lmthca -pthread
-
-all: asyncwatch devinfo device_list rc_pingpong srq_pingpong uc_pingpong ud_pingpong
-
-clean:
- rm asyncwatch devinfo device_list rc_pingpong srq_pingpong uc_pingpong ud_pingpong
-
-asyncwatch:
- gcc -o asyncwatch asyncwatch.c ${CFLAGS}
-
-devinfo:
- gcc -o devinfo devinfo.c ${CFLAGS}
-
-device_list:
- gcc -o device_list device_list.c ${CFLAGS}
-
-rc_pingpong:
- gcc -o rc_pingpong rc_pingpong.c pingpong.c ${CFLAGS}
-
-srq_pingpong:
- gcc -o srq_pingpong srq_pingpong.c pingpong.c ${CFLAGS}
-
-uc_pingpong:
- gcc -o uc_pingpong uc_pingpong.c pingpong.c ${CFLAGS}
-
-ud_pingpong:
- gcc -o ud_pingpong ud_pingpong.c pingpong.c ${CFLAGS}
-
diff --git a/contrib/ofed/libibverbs/examples/build/Makefile b/contrib/ofed/libibverbs/examples/build/Makefile
new file mode 100644
index 0000000..311899d
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/Makefile
@@ -0,0 +1,4 @@
+SUBDIR= asyncwatch devinfo device_list rc_pingpong \
+ srq_pingpong uc_pingpong ud_pingpong
+
+.include <bsd.subdir.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/Makefile.inc b/contrib/ofed/libibverbs/examples/build/Makefile.inc
new file mode 100644
index 0000000..9683a31
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/Makefile.inc
@@ -0,0 +1,7 @@
+CFLAGS+= \
+ -I../../../../../../sys/ofed/include \
+ -I../../../../libibverbs/include \
+ -I../../../../include
+
+LDADD+= -libverbs -lmlx4 -lmthca -pthread
+
diff --git a/contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile b/contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile
new file mode 100644
index 0000000..7a0a5b2
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/asyncwatch/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= asyncwatch
+MAN=
+SRCS= asyncwatch.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/device_list/Makefile b/contrib/ofed/libibverbs/examples/build/device_list/Makefile
new file mode 100644
index 0000000..4cdeff5
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/device_list/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= device_list
+MAN=
+SRCS= device_list.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/devinfo/Makefile b/contrib/ofed/libibverbs/examples/build/devinfo/Makefile
new file mode 100644
index 0000000..ca6fb6c
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/devinfo/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= devinfo
+MAN=
+SRCS= devinfo.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile
new file mode 100644
index 0000000..824b08e
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/rc_pingpong/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= rc_pingpong
+MAN=
+SRCS= rc_pingpong.c pingpong.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile
new file mode 100644
index 0000000..c485d50
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/srq_pingpong/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= srq_pingpong
+MAN=
+SRCS= srq_pingpong.c pingpong.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile
new file mode 100644
index 0000000..7427eb9
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/uc_pingpong/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= uc_pingpong
+MAN=
+SRCS= uc_pingpong.c pingpong.c
+
+.include <bsd.prog.mk>
diff --git a/contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile b/contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile
new file mode 100644
index 0000000..8a0f8e8
--- /dev/null
+++ b/contrib/ofed/libibverbs/examples/build/ud_pingpong/Makefile
@@ -0,0 +1,9 @@
+#
+# $FreeBSD$
+#
+.PATH: ${.CURDIR}/../..
+PROG= ud_pingpong
+MAN=
+SRCS= ud_pingpong.c pingpong.c
+
+.include <bsd.prog.mk>
diff --git a/etc/hosts.allow b/etc/hosts.allow
index 95286d7..3e19bc8 100644
--- a/etc/hosts.allow
+++ b/etc/hosts.allow
@@ -4,15 +4,15 @@
#
# NOTE: The hosts.deny file is deprecated.
# Place both 'allow' and 'deny' rules in the hosts.allow file.
-# See hosts_options(5) for the format of this file.
-# hosts_access(5) no longer fully applies.
-
-# _____ _ _
-# | ____| __ __ __ _ _ __ ___ _ __ | | ___ | |
-# | _| \ \/ / / _` | | '_ ` _ \ | '_ \ | | / _ \ | |
-# | |___ > < | (_| | | | | | | | | |_) | | | | __/ |_|
-# |_____| /_/\_\ \__,_| |_| |_| |_| | .__/ |_| \___| (_)
-# |_|
+# See hosts_options(5) for the format of this file.
+# hosts_access(5) no longer fully applies.
+#
+# _____ _ _
+# | ____| __ __ __ _ _ __ ___ _ __ | | ___ | |
+# | _| \ \/ / / _` | | '_ ` _ \ | '_ \ | | / _ \ | |
+# | |___ > < | (_| | | | | | | | | |_) | | | | __/ |_|
+# |_____| /_/\_\ \__,_| |_| |_| |_| | .__/ |_| \___| (_)
+# |_|
# !!! This is an example! You will need to modify it for your specific
# !!! requirements!
diff --git a/etc/services b/etc/services
index 13ad4c8..1311799 100644
--- a/etc/services
+++ b/etc/services
@@ -2345,6 +2345,8 @@ mdns 5353/tcp #Multicast DNS
mdns 5353/udp #Multicast DNS
postgresql 5432/tcp #PostgreSQL Database
postgresql 5432/udp #PostgreSQL Database
+vami 5480/tcp #VMware Appliance Management Interface, HTTPS-like
+vami 5480/udp #VMware Appliance Management Interface, HTTPS-like
rplay 5555/udp
amqp 5672/sctp #AMQP
amqp 5672/tcp #AMQP
diff --git a/gnu/lib/libssp/Makefile b/gnu/lib/libssp/Makefile
index 6e89771..5a41298 100644
--- a/gnu/lib/libssp/Makefile
+++ b/gnu/lib/libssp/Makefile
@@ -15,6 +15,7 @@ SRCDIR= ${GCCLIB}/libssp
LIB= ssp
SHLIB_MAJOR= 0
+LD_FATAL_WARNINGS= no
SRCS= ssp.c gets-chk.c memcpy-chk.c memmove-chk.c mempcpy-chk.c \
memset-chk.c snprintf-chk.c sprintf-chk.c stpcpy-chk.c \
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_arm.c b/gnu/usr.bin/gdb/kgdb/trgt_arm.c
index 489c046..cb23aa6 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_arm.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_arm.c
@@ -72,20 +72,12 @@ kgdb_trgt_fetch_registers(int regno __unused)
warnx("kvm_read: %s", kvm_geterr(kvm));
memset(&pcb, 0, sizeof(pcb));
}
- for (i = ARM_A1_REGNUM + 8; i <= ARM_SP_REGNUM; i++) {
- supply_register(i, (char *)&pcb.un_32.pcb32_r8 +
- (i - (ARM_A1_REGNUM + 8 )) * 4);
+ for (i = ARM_A1_REGNUM + 4; i <= ARM_SP_REGNUM; i++) {
+ supply_register(i, (char *)&pcb.pcb_regs.sf_r4 +
+ (i - (ARM_A1_REGNUM + 4 )) * 4);
}
- if (pcb.un_32.pcb32_sp != 0) {
- for (i = 0; i < 4; i++) {
- if (kvm_read(kvm, pcb.un_32.pcb32_sp + (i) * 4,
- &reg, 4) != 4) {
- warnx("kvm_read: %s", kvm_geterr(kvm));
- break;
- }
- supply_register(ARM_A1_REGNUM + 4 + i, (char *)&reg);
- }
- if (kvm_read(kvm, pcb.un_32.pcb32_sp + 4 * 4, &reg, 4) != 4)
+ if (pcb.pcb_regs.sf_sp != 0) {
+ if (kvm_read(kvm, pcb.pcb_regs.sf_sp + 4 * 4, &reg, 4) != 4)
warnx("kvm_read :%s", kvm_geterr(kvm));
else
supply_register(ARM_PC_REGNUM, (char *)&reg);
diff --git a/include/Makefile b/include/Makefile
index fe62e5e..fa81527 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -42,7 +42,7 @@ LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \
LSUBDIRS= cam/ata cam/scsi \
dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \
dev/hwpmc \
- dev/ic dev/iicbus ${_dev_ieee488} dev/io dev/lmc dev/mfi dev/nvme \
+ dev/ic dev/iicbus dev/io dev/lmc dev/mfi dev/nvme \
dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/smbus \
dev/speaker dev/usb dev/utopia dev/vkbd dev/wi \
fs/cuse \
@@ -63,10 +63,6 @@ LSUBSUBDIRS= dev/mpt/mpilib
_dev_powermac_nvram= dev/powermac_nvram
.endif
-.if ${MK_GPIB} != "no"
-_dev_ieee488= dev/ieee488
-.endif
-
.if ${MK_GSSAPI} != "no"
SUBDIR+= gssapi
INCS+= gssapi.h
diff --git a/lib/Makefile b/lib/Makefile
index 8bd5653..4d30c53 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -52,7 +52,6 @@ SUBDIR= ${SUBDIR_ORDERED} \
libfetch \
libfigpar \
libgeom \
- ${_libgpib} \
libgpio \
${_libgssapi} \
${_librpcsec_gss} \
@@ -195,10 +194,6 @@ _cuse= libcuse
_libelftc= libelftc
.endif
-.if ${MK_GPIB} != "no"
-_libgpib= libgpib
-.endif
-
.if ${MK_GSSAPI} != "no"
_libgssapi= libgssapi
_librpcsec_gss= librpcsec_gss
diff --git a/lib/libbsnmp/libbsnmp/Makefile b/lib/libbsnmp/libbsnmp/Makefile
index cc294cf..ef6e35b 100644
--- a/lib/libbsnmp/libbsnmp/Makefile
+++ b/lib/libbsnmp/libbsnmp/Makefile
@@ -9,6 +9,7 @@ CONTRIB= ${.CURDIR}/../../../contrib/bsnmp/lib
LIB= bsnmp
SHLIB_MAJOR= 6
+LD_FATAL_WARNINGS= no
CFLAGS+= -I${CONTRIB} -DHAVE_ERR_H -DHAVE_GETADDRINFO -DHAVE_STRLCPY
CFLAGS+= -DHAVE_STDINT_H -DHAVE_INTTYPES_H -DQUADFMT='"llu"' -DQUADXFMT='"llx"'
diff --git a/lib/libc/gen/cap_rights_get.3 b/lib/libc/gen/cap_rights_get.3
index f74d1f7a..a665465 100644
--- a/lib/libc/gen/cap_rights_get.3
+++ b/lib/libc/gen/cap_rights_get.3
@@ -100,10 +100,10 @@ argument points at an invalid address.
.El
.Sh SEE ALSO
.Xr cap_rights_limit 2 ,
-.Xr cap_rights_init 3 ,
.Xr errno 2 ,
.Xr open 2 ,
.Xr assert 3 ,
+.Xr cap_rights_init 3 ,
.Xr err 3 ,
.Xr memcmp 3 ,
.Xr memset 3 ,
diff --git a/lib/libc/gen/ftok.3 b/lib/libc/gen/ftok.3
index 98f8bad..b819dbd 100644
--- a/lib/libc/gen/ftok.3
+++ b/lib/libc/gen/ftok.3
@@ -64,9 +64,9 @@ function will return -1 if
.Fa path
does not exist or if it cannot be accessed by the calling process.
.Sh SEE ALSO
+.Xr msgget 2 ,
.Xr semget 2 ,
-.Xr shmget 2 ,
-.Xr msgget 2
+.Xr shmget 2
.Sh HISTORY
The
.Fn ftok
diff --git a/lib/libc/gen/ftw.3 b/lib/libc/gen/ftw.3
index ba8859b..df8abab 100644
--- a/lib/libc/gen/ftw.3
+++ b/lib/libc/gen/ftw.3
@@ -87,8 +87,9 @@ A directory which cannot be read.
The directory will not be descended into.
.It Dv FTW_DP
A directory being visited in post-order
-.Fn ( nftw
-only).
+.Po Fn nftw
+only
+.Pc .
.It Dv FTW_NS
A file for which no
.Xr stat 2
@@ -100,8 +101,9 @@ structure are undefined.
A symbolic link.
.It Dv FTW_SLN
A symbolic link with a non-existent target
-.Fn ( nftw
-only).
+.Po Fn nftw
+only
+.Pc .
.El
.Pp
The
diff --git a/lib/libc/gen/getcap.3 b/lib/libc/gen/getcap.3
index 73826ae..c3a9ce8 100644
--- a/lib/libc/gen/getcap.3
+++ b/lib/libc/gen/getcap.3
@@ -137,9 +137,10 @@ It must be called before the
call.
If a sequential access is being performed (see below), it must be called
before the first sequential access call
-.Fn ( cgetfirst
+.Po Fn cgetfirst
or
-.Fn cgetnext ) ,
+.Fn cgetnext
+.Pc ,
or be directly preceded by a
.Fn cgetclose
call.
diff --git a/lib/libc/gen/posix_spawn.3 b/lib/libc/gen/posix_spawn.3
index dd5bd2b..52e8171 100644
--- a/lib/libc/gen/posix_spawn.3
+++ b/lib/libc/gen/posix_spawn.3
@@ -413,6 +413,10 @@ including trying to close a descriptor that is not open.
.Xr execve 2 ,
.Xr fcntl 2 ,
.Xr open 2 ,
+.Xr sched_setparam 2 ,
+.Xr sched_setscheduler 2 ,
+.Xr setpgid 2 ,
+.Xr vfork 2 ,
.Xr posix_spawn_file_actions_addclose 3 ,
.Xr posix_spawn_file_actions_adddup2 3 ,
.Xr posix_spawn_file_actions_addopen 3 ,
@@ -431,11 +435,7 @@ including trying to close a descriptor that is not open.
.Xr posix_spawnattr_setschedparam 3 ,
.Xr posix_spawnattr_setschedpolicy 3 ,
.Xr posix_spawnattr_setsigdefault 3 ,
-.Xr posix_spawnattr_setsigmask 3 ,
-.Xr sched_setparam 2 ,
-.Xr sched_setscheduler 2 ,
-.Xr setpgid 2 ,
-.Xr vfork 2
+.Xr posix_spawnattr_setsigmask 3
.Sh STANDARDS
The
.Fn posix_spawn
diff --git a/lib/libc/gen/scandir.3 b/lib/libc/gen/scandir.3
index eaba754..aa8dea0 100644
--- a/lib/libc/gen/scandir.3
+++ b/lib/libc/gen/scandir.3
@@ -92,7 +92,7 @@ by freeing each pointer in the array and then the array itself.
.Pp
The
.Fn scandir_b
-function behaves in the same way as
+function behaves in the same way as
.Fn scandir ,
but takes blocks as arguments instead of function pointers and calls
.Fn qsort_b
@@ -106,8 +106,8 @@ cannot allocate enough memory to hold all the data structures.
.Xr directory 3 ,
.Xr malloc 3 ,
.Xr qsort 3 ,
-.Xr dir 5 ,
-.Xr strcoll 3
+.Xr strcoll 3 ,
+.Xr dir 5
.Sh HISTORY
The
.Fn scandir
diff --git a/lib/libc/iconv/iconvlist.3 b/lib/libc/iconv/iconvlist.3
index bef609b..b1a6e05 100644
--- a/lib/libc/iconv/iconvlist.3
+++ b/lib/libc/iconv/iconvlist.3
@@ -78,9 +78,9 @@ If an error occurs,
will be NULL when calling
.Fn do_one .
.Sh SEE ALSO
-.Xr iconv 3 ,
+.Xr __iconv_free_list 3 ,
.Xr __iconv_get_list 3 ,
-.Xr __iconv_free_list 3
+.Xr iconv 3
.Sh STANDARDS
The
.Nm
diff --git a/lib/libc/locale/digittoint.3 b/lib/libc/locale/digittoint.3
index 4a7f2e2..6670abe 100644
--- a/lib/libc/locale/digittoint.3
+++ b/lib/libc/locale/digittoint.3
@@ -64,5 +64,5 @@ the function will return 0.
.Sh SEE ALSO
.Xr ctype 3 ,
.Xr isdigit 3 ,
-.Xr isxdigit 3,
+.Xr isxdigit 3 ,
.Xr xlocale 3
diff --git a/lib/libc/locale/xlocale.3 b/lib/libc/locale/xlocale.3
index d467a10..da217c6 100644
--- a/lib/libc/locale/xlocale.3
+++ b/lib/libc/locale/xlocale.3
@@ -71,7 +71,7 @@ function.
.Xr localeconv 3 ,
.Xr newlocale 3 ,
.Xr querylocale 3 ,
-.Xr uselocale 3 ,
+.Xr uselocale 3
.Sh CONVENIENCE FUNCTIONS
The xlocale API includes a number of
.Fa _l
diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3
index 5d03aab..570fc2e 100644
--- a/lib/libc/net/getaddrinfo.3
+++ b/lib/libc/net/getaddrinfo.3
@@ -237,8 +237,8 @@ pointer in each
.Li addrinfo
structure until a null pointer is encountered.
The three members
-.Fa ai_family,
-.Fa ai_socktype,
+.Fa ai_family ,
+.Fa ai_socktype ,
and
.Fa ai_protocol
in each returned
diff --git a/lib/libc/net/sctp_recvmsg.3 b/lib/libc/net/sctp_recvmsg.3
index e3ced9c..bb1cf06 100644
--- a/lib/libc/net/sctp_recvmsg.3
+++ b/lib/libc/net/sctp_recvmsg.3
@@ -282,12 +282,12 @@ This typically means that the socket
is not connected and is a one-to-one style socket.
.El
.Sh SEE ALSO
+.Xr getsockopt 2 ,
.Xr recv 2 ,
.Xr select 2 ,
+.Xr setsockopt 2 ,
.Xr socket 2 ,
.Xr write 2 ,
-.Xr getsockopt 2 ,
-.Xr setsockopt 2 ,
.Xr sctp_send 3 ,
.Xr sctp_sendmsg 3 ,
.Xr sendmsg 3 ,
diff --git a/lib/libc/net/sctp_send.3 b/lib/libc/net/sctp_send.3
index 37b0b71..9c7f833 100644
--- a/lib/libc/net/sctp_send.3
+++ b/lib/libc/net/sctp_send.3
@@ -337,7 +337,7 @@ is not connected and is a one-to-one style socket.
.Xr select 2 ,
.Xr sendmsg 2 ,
.Xr socket 2 ,
-.Xr write 2
+.Xr write 2 ,
.Xr sctp_connectx 3 ,
.Xr sctp_recvmsg 3 ,
.Xr sctp_sendmsg 3 ,
diff --git a/lib/libc/posix1e/acl_set_flagset_np.3 b/lib/libc/posix1e/acl_set_flagset_np.3
index 2230c48..685680d 100644
--- a/lib/libc/posix1e/acl_set_flagset_np.3
+++ b/lib/libc/posix1e/acl_set_flagset_np.3
@@ -64,9 +64,9 @@ ACL is already branded as POSIX.1e.
.Sh SEE ALSO
.Xr acl 3 ,
.Xr acl_add_flag_np 3 ,
-.Xr acl_get_brand_np 3 ,
.Xr acl_clear_flags_np 3 ,
.Xr acl_delete_flag_np 3 ,
+.Xr acl_get_brand_np 3 ,
.Xr acl_get_flagset_np 3 ,
.Xr posix1e 3
.Sh STANDARDS
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c
index a01bb95..2ecb88c 100644
--- a/lib/libc/regex/regcomp.c
+++ b/lib/libc/regex/regcomp.c
@@ -1716,8 +1716,10 @@ computematchjumps(struct parse *p, struct re_guts *g)
}
g->matchjump = (int*) malloc(g->mlen * sizeof(unsigned int));
- if (g->matchjump == NULL) /* Not a fatal error */
+ if (g->matchjump == NULL) { /* Not a fatal error */
+ free(pmatches);
return;
+ }
/* Set maximum possible jump for each character in the pattern */
for (mindex = 0; mindex < g->mlen; mindex++)
diff --git a/lib/libc/rpc/rpc.3 b/lib/libc/rpc/rpc.3
index 4fa3e2c..988b5f1 100644
--- a/lib/libc/rpc/rpc.3
+++ b/lib/libc/rpc/rpc.3
@@ -504,7 +504,6 @@ pages on which they are described:
.Sh SEE ALSO
.Xr getnetconfig 3 ,
.Xr getnetpath 3 ,
-.Xr rpcbind 3 ,
.Xr rpc_clnt_auth 3 ,
.Xr rpc_clnt_calls 3 ,
.Xr rpc_clnt_create 3 ,
@@ -513,5 +512,6 @@ pages on which they are described:
.Xr rpc_svc_err 3 ,
.Xr rpc_svc_reg 3 ,
.Xr rpc_xdr 3 ,
+.Xr rpcbind 3 ,
.Xr xdr 3 ,
.Xr netconfig 5
diff --git a/lib/libc/rpc/rpc_svc_reg.3 b/lib/libc/rpc/rpc_svc_reg.3
index aed2ba1..81a749a 100644
--- a/lib/libc/rpc/rpc_svc_reg.3
+++ b/lib/libc/rpc/rpc_svc_reg.3
@@ -176,8 +176,8 @@ Service implementors usually do not need this routine.
.Sh SEE ALSO
.Xr select 2 ,
.Xr rpc 3 ,
-.Xr rpcbind 3 ,
.Xr rpc_svc_calls 3 ,
.Xr rpc_svc_create 3 ,
.Xr rpc_svc_err 3 ,
+.Xr rpcbind 3 ,
.Xr rpcbind 8
diff --git a/lib/libc/stdlib/atexit.3 b/lib/libc/stdlib/atexit.3
index 68f4e8f..3cdc59f 100644
--- a/lib/libc/stdlib/atexit.3
+++ b/lib/libc/stdlib/atexit.3
@@ -88,12 +88,12 @@ The existing list of functions is unmodified.
.It Bq Er ENOSYS
The
.Fn atexit_b
-function was called by a program that did not supply a
+function was called by a program that did not supply a
.Fn _Block_copy
implementation.
.El
.Sh SEE ALSO
-.Xr at_quick_exit 3
+.Xr at_quick_exit 3 ,
.Xr exit 3
.Sh STANDARDS
The
diff --git a/lib/libc/stdlib/exit.3 b/lib/libc/stdlib/exit.3
index 07ce0d7..7d657c9 100644
--- a/lib/libc/stdlib/exit.3
+++ b/lib/libc/stdlib/exit.3
@@ -117,8 +117,8 @@ never return.
.Sh SEE ALSO
.Xr _exit 2 ,
.Xr wait 2 ,
-.Xr atexit 3 ,
.Xr at_quick_exit 3 ,
+.Xr atexit 3 ,
.Xr intro 3 ,
.Xr quick_exit 3 ,
.Xr sysexits 3 ,
diff --git a/lib/libc/string/strspn.3 b/lib/libc/string/strspn.3
index 542b190..4a8e3f4 100644
--- a/lib/libc/string/strspn.3
+++ b/lib/libc/string/strspn.3
@@ -71,7 +71,7 @@ spans the initial part of the null-terminated string
.Fa s
as long as the characters from
.Fa s
-.Sy do not
+.Sy do not
occur in the null-terminated string
.Fa charset
.Po it spans the
diff --git a/lib/libc/sys/access.2 b/lib/libc/sys/access.2
index 46bf948..c70e7a2 100644
--- a/lib/libc/sys/access.2
+++ b/lib/libc/sys/access.2
@@ -136,7 +136,7 @@ and
.Fn access ,
.Fn eaccess ,
or
-.Fn faccessat
+.Fn faccessat
will fail if:
.Bl -tag -width Er
.It Bq Er EINVAL
diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2
index 3fe1632..ab60ed2 100644
--- a/lib/libc/sys/getdirentries.2
+++ b/lib/libc/sys/getdirentries.2
@@ -134,8 +134,9 @@ The current position pointer should only be set to a value returned by
.Xr lseek 2 ,
a value returned in the location pointed to by
.Fa basep
-.Fn ( getdirentries
-only)
+.Po Fn getdirentries
+only
+.Pc
or zero.
.Sh RETURN VALUES
If successful, the number of bytes actually transferred is returned.
diff --git a/lib/libc/sys/getrlimit.2 b/lib/libc/sys/getrlimit.2
index 1f84bfb..5fdd58b 100644
--- a/lib/libc/sys/getrlimit.2
+++ b/lib/libc/sys/getrlimit.2
@@ -194,8 +194,8 @@ raised the maximum limit value, and the caller is not the super-user.
.Xr csh 1 ,
.Xr quota 1 ,
.Xr quotactl 2 ,
-.Xr sigaltstack 2 ,
.Xr sigaction 2 ,
+.Xr sigaltstack 2 ,
.Xr sysctl 3 ,
.Xr ulimit 3
.Sh HISTORY
diff --git a/lib/libc/sys/poll.2 b/lib/libc/sys/poll.2
index 466523b..dbd641f 100644
--- a/lib/libc/sys/poll.2
+++ b/lib/libc/sys/poll.2
@@ -148,8 +148,8 @@ is zero, then
will return without blocking.
.Pp
The
-.Fn ppoll
-system call, unlike
+.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.
@@ -174,10 +174,10 @@ used by
A null pointer may be passed to indicate that
.Fn ppoll
should wait indefinitely.
-Finally,
+Finally,
.Fa newsigmask
specifies a signal mask which is set while waiting for input.
-When
+When
.Fn ppoll
returns, the original signal mask is restored.
.Bd -literal
@@ -246,11 +246,11 @@ The specified time limit is invalid. One of its components is negative or too la
.Xr write 2
.Sh STANDARDS
The
-.Fn poll
+.Fn poll
function conforms to
.St -p1003.1-2001 .
The
-.Fn ppoll
+.Fn ppoll
is not specified by POSIX.
.Sh HISTORY
The
@@ -261,8 +261,8 @@ This manual page and the core of the implementation was taken from
.Nx .
The
.Fn ppoll
-function first appeared in
-.Fx 11.0
+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/sys/posix_openpt.2 b/lib/libc/sys/posix_openpt.2
index 916e75a..d34385f 100644
--- a/lib/libc/sys/posix_openpt.2
+++ b/lib/libc/sys/posix_openpt.2
@@ -110,8 +110,8 @@ is not valid.
Out of pseudo-terminal resources.
.El
.Sh SEE ALSO
-.Xr pts 4 ,
.Xr ptsname 3 ,
+.Xr pts 4 ,
.Xr tty 4
.Sh STANDARDS
The
diff --git a/lib/libc/sys/procctl.2 b/lib/libc/sys/procctl.2
index 70ee276..649e0ad 100644
--- a/lib/libc/sys/procctl.2
+++ b/lib/libc/sys/procctl.2
@@ -107,7 +107,6 @@ reaper.
After the system initialization,
.Xr init 8
is the default reaper.
-.Pp
.It Dv PROC_REAP_RELEASE
Releases the reaper state for the current process.
The reaper of the current process becomes the new reaper of the
@@ -146,6 +145,7 @@ for the specified process id.
The specified process is the root of the reaper tree, i.e.
.Xr init 8 .
.El
+.Pp
The
.Fa rs_children
field returns the number of children of the reaper.
diff --git a/lib/libc/sys/revoke.2 b/lib/libc/sys/revoke.2
index 57abdbb..482cbf6 100644
--- a/lib/libc/sys/revoke.2
+++ b/lib/libc/sys/revoke.2
@@ -97,8 +97,8 @@ operation on the named file.
The caller is neither the owner of the file nor the super user.
.El
.Sh SEE ALSO
-.Xr close 2 ,
-.Xr revoke 1
+.Xr revoke 1 ,
+.Xr close 2
.Sh HISTORY
The
.Fn revoke
diff --git a/lib/libc/sys/sched_setscheduler.2 b/lib/libc/sys/sched_setscheduler.2
index 3e7c42b..b84c1a1 100644
--- a/lib/libc/sys/sched_setscheduler.2
+++ b/lib/libc/sys/sched_setscheduler.2
@@ -151,9 +151,9 @@ argument is invalid, or one or more of the parameters contained in
is outside the valid range for the specified scheduling policy.
.El
.Sh SEE ALSO
-.Xr sched_getparam 2 ,
.Xr sched_get_priority_max 2 ,
.Xr sched_get_priority_min 2 ,
+.Xr sched_getparam 2 ,
.Xr sched_rr_get_interval 2 ,
.Xr sched_setparam 2 ,
.Xr sched_yield 2
diff --git a/lib/libc/sys/sigwaitinfo.2 b/lib/libc/sys/sigwaitinfo.2
index 9109759..b497592 100644
--- a/lib/libc/sys/sigwaitinfo.2
+++ b/lib/libc/sys/sigwaitinfo.2
@@ -172,8 +172,8 @@ system calls fail if:
.Bl -tag -width Er
.It Bq Er EINTR
The wait was interrupted by an unblocked, caught signal.
-.Pp
.El
+.Pp
The
.Fn sigtimedwait
system call may also fail if:
diff --git a/lib/libc/sys/vfork.2 b/lib/libc/sys/vfork.2
index 1cfaa61..f93b429 100644
--- a/lib/libc/sys/vfork.2
+++ b/lib/libc/sys/vfork.2
@@ -100,8 +100,8 @@ since buffered data would then be flushed twice.)
Same as for
.Xr fork 2 .
.Sh SEE ALSO
-.Xr execve 2 ,
.Xr _exit 2 ,
+.Xr execve 2 ,
.Xr fork 2 ,
.Xr rfork 2 ,
.Xr sigaction 2 ,
diff --git a/lib/libdpv/dpv.3 b/lib/libdpv/dpv.3
index 37e1f07..d16e649 100644
--- a/lib/libdpv/dpv.3
+++ b/lib/libdpv/dpv.3
@@ -435,8 +435,8 @@ or desired values.
.El
.Sh SEE ALSO
.Xr dialog 1 ,
-.Xr dialog 3 ,
-.Xr Xdialog 1
+.Xr Xdialog 1 ,
+.Xr dialog 3
.Sh HISTORY
The
.Nm
diff --git a/lib/libmandoc/Makefile b/lib/libmandoc/Makefile
index 0d3d77f..276c463 100644
--- a/lib/libmandoc/Makefile
+++ b/lib/libmandoc/Makefile
@@ -6,7 +6,7 @@ MDOCMLDIR= ${.CURDIR}/../../contrib/mdocml
LIB= mandoc
#NO_PIC=
INTERNALLIB=
-MAN= mandoc.3
+MAN= mandoc.3 mandoc_headers.3
LIBMAN_SRCS= man.c \
man_hash.c \
man_macro.c \
diff --git a/lib/libpam/modules/pam_guest/pam_guest.8 b/lib/libpam/modules/pam_guest/pam_guest.8
index 0bd1755..0b858d6 100644
--- a/lib/libpam/modules/pam_guest/pam_guest.8
+++ b/lib/libpam/modules/pam_guest/pam_guest.8
@@ -82,8 +82,8 @@ password.
Requires the guest user to type in the guest account name as password.
.El
.Sh SEE ALSO
-.Xr pam_getenv 3 ,
.Xr pam_get_item 3 ,
+.Xr pam_getenv 3 ,
.Xr pam.conf 5 ,
.Xr pam 8
.Sh AUTHORS
diff --git a/lib/libproc/proc_sym.c b/lib/libproc/proc_sym.c
index 766ff73..e52f8ff 100644
--- a/lib/libproc/proc_sym.c
+++ b/lib/libproc/proc_sym.c
@@ -501,13 +501,16 @@ ctf_file_t *
proc_name2ctf(struct proc_handle *p, const char *name)
{
#ifndef NO_CTF
+ ctf_file_t *ctf;
prmap_t *map;
int error;
if ((map = proc_name2map(p, name)) == NULL)
return (NULL);
- return (ctf_open(map->pr_mapname, &error));
+ ctf = ctf_open(map->pr_mapname, &error);
+ free(map);
+ return (ctf);
#else
(void)p;
(void)name;
diff --git a/lib/librtld_db/librtld_db.3 b/lib/librtld_db/librtld_db.3
index 211ce79..f310abf 100644
--- a/lib/librtld_db/librtld_db.3
+++ b/lib/librtld_db/librtld_db.3
@@ -167,8 +167,8 @@ You can get the error string using
.Xr ld 1 ,
.Xr ld-elf.so.1 1 ,
.Xr ld.so 1 ,
-.Xr libproc 3 ,
-.Xr rtld 1
+.Xr rtld 1 ,
+.Xr libproc 3
.Sh HISTORY
The
.Nm librtld_db
diff --git a/lib/libstand/cd9660.c b/lib/libstand/cd9660.c
index c6bcef2..5bee879 100644
--- a/lib/libstand/cd9660.c
+++ b/lib/libstand/cd9660.c
@@ -281,7 +281,7 @@ cd9660_open(const char *path, struct open_file *f)
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
vd = buf;
for (bno = 16;; bno++) {
- twiddle();
+ twiddle(1);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
ISO_DEFAULT_BLOCK_SIZE, buf, &read);
if (rc)
@@ -314,7 +314,7 @@ cd9660_open(const char *path, struct open_file *f)
while (off < dsize) {
if ((off % ISO_DEFAULT_BLOCK_SIZE) == 0) {
- twiddle();
+ twiddle(1);
rc = f->f_dev->dv_strategy
(f->f_devdata, F_READ,
cdb2devb(bno + boff),
@@ -374,7 +374,7 @@ cd9660_open(const char *path, struct open_file *f)
/* Check for Rock Ridge since we didn't in the loop above. */
bno = isonum_733(rec.extent) + isonum_711(rec.ext_attr_length);
- twiddle();
+ twiddle(1);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ, cdb2devb(bno),
ISO_DEFAULT_BLOCK_SIZE, buf, &read);
if (rc)
@@ -431,7 +431,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
if (fp->f_buf == (char *)0)
fp->f_buf = malloc(ISO_DEFAULT_BLOCK_SIZE);
- twiddle();
+ twiddle(16);
rc = f->f_dev->dv_strategy(f->f_devdata, F_READ,
cdb2devb(blkno), ISO_DEFAULT_BLOCK_SIZE, fp->f_buf, &read);
if (rc)
diff --git a/lib/libstand/ext2fs.c b/lib/libstand/ext2fs.c
index e0afb3e..d0b91e0 100644
--- a/lib/libstand/ext2fs.c
+++ b/lib/libstand/ext2fs.c
@@ -353,7 +353,7 @@ ext2fs_open(const char *upath, struct open_file *f)
/* allocate space and read super block */
fs = (struct ext2fs *)malloc(sizeof(*fs));
fp->f_fs = fs;
- twiddle();
+ twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
EXT2_SBLOCK, EXT2_SBSIZE, (char *)fs, &buf_size);
if (error)
@@ -395,7 +395,7 @@ ext2fs_open(const char *upath, struct open_file *f)
len = blkgrps * fs->fs_bsize;
fp->f_bg = malloc(len);
- twiddle();
+ twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
EXT2_SBLOCK + EXT2_SBSIZE / DEV_BSIZE, len,
(char *)fp->f_bg, &buf_size);
@@ -507,7 +507,7 @@ ext2fs_open(const char *upath, struct open_file *f)
if (error)
goto out;
- twiddle();
+ twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata,
F_READ, fsb_to_db(fs, disk_block),
fs->fs_bsize, buf, &buf_size);
@@ -568,7 +568,7 @@ read_inode(ino_t inumber, struct open_file *f)
* Read inode and save it.
*/
buf = malloc(fs->fs_bsize);
- twiddle();
+ twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
ino_to_db(fs, fp->f_bg, inumber), fs->fs_bsize, buf, &rsize);
if (error)
@@ -665,7 +665,7 @@ block_map(struct open_file *f, daddr_t file_block, daddr_t *disk_block_p)
if (fp->f_blk[level] == (char *)0)
fp->f_blk[level] =
malloc(fs->fs_bsize);
- twiddle();
+ twiddle(1);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsb_to_db(fp->f_fs, ind_block_num), fs->fs_bsize,
fp->f_blk[level], &fp->f_blksize[level]);
@@ -723,7 +723,7 @@ buf_read_file(struct open_file *f, char **buf_p, size_t *size_p)
bzero(fp->f_buf, block_size);
fp->f_buf_size = block_size;
} else {
- twiddle();
+ twiddle(4);
error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsb_to_db(fs, disk_block), block_size,
fp->f_buf, &fp->f_buf_size);
diff --git a/lib/libstand/nandfs.c b/lib/libstand/nandfs.c
index 713dc12..b8c51e3 100644
--- a/lib/libstand/nandfs.c
+++ b/lib/libstand/nandfs.c
@@ -921,7 +921,7 @@ nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node,
return (0);
}
- twiddle();
+ twiddle(1);
NANDFS_DEBUG("calling get_map with %jx\n", ind_block_num);
map = nandfs_get_map(fs, node, ind_block_num, phys);
if (map == NULL)
diff --git a/lib/libstand/nfs.c b/lib/libstand/nfs.c
index adb0a11..a0b726c 100644
--- a/lib/libstand/nfs.c
+++ b/lib/libstand/nfs.c
@@ -662,7 +662,7 @@ nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
(int)fp->off);
#endif
while ((int)size > 0) {
- twiddle();
+ twiddle(16);
cc = nfs_readdata(fp, fp->off, (void *)addr, size);
/* XXX maybe should retry on certain errors */
if (cc == -1) {
@@ -1311,7 +1311,7 @@ nfs_read(struct open_file *f, void *buf, size_t size, size_t *resid)
(int)fp->off);
#endif
while ((int)size > 0) {
- twiddle();
+ twiddle(16);
cc = nfs_readdata(fp, fp->off, (void *)addr, size);
/* XXX maybe should retry on certain errors */
if (cc == -1) {
diff --git a/lib/libstand/read.c b/lib/libstand/read.c
index 4c67dbe..a984dbe 100644
--- a/lib/libstand/read.c
+++ b/lib/libstand/read.c
@@ -77,7 +77,7 @@ read(int fd, void *dest, size_t bcount)
return (-1);
}
if (f->f_flags & F_RAW) {
- twiddle();
+ twiddle(4);
errno = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
btodb(f->f_offset), bcount, dest, &resid);
if (errno)
diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h
index bcd146a..22ee319 100644
--- a/lib/libstand/stand.h
+++ b/lib/libstand/stand.h
@@ -242,7 +242,8 @@ extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3);
extern int snprintf(char *buf, size_t size, const char *cfmt, ...) __printflike(3, 4);
extern void vsprintf(char *buf, const char *cfmt, __va_list);
-extern void twiddle(void);
+extern void twiddle(u_int callerdiv);
+extern void twiddle_divisor(u_int globaldiv);
extern void ngets(char *, int);
#define gets(x) ngets((x), 0)
diff --git a/lib/libstand/tftp.c b/lib/libstand/tftp.c
index e3983c3..6527c4e 100644
--- a/lib/libstand/tftp.c
+++ b/lib/libstand/tftp.c
@@ -447,14 +447,12 @@ tftp_read(struct open_file *f, void *addr, size_t size,
size_t *resid /* out */)
{
struct tftp_handle *tftpfile;
- static int tc = 0;
tftpfile = (struct tftp_handle *) f->f_fsdata;
while (size > 0) {
int needblock, count;
- if (!(tc++ % 16))
- twiddle();
+ twiddle(32);
needblock = tftpfile->off / tftpfile->tftp_blksize + 1;
diff --git a/lib/libstand/twiddle.c b/lib/libstand/twiddle.c
index e0a4c08..96ebbbe 100644
--- a/lib/libstand/twiddle.c
+++ b/lib/libstand/twiddle.c
@@ -42,11 +42,28 @@ __FBSDID("$FreeBSD$");
/* Extra functions from NetBSD standalone printf.c */
+static u_int globaldiv;
+
void
-twiddle()
+twiddle(u_int callerdiv)
{
- static int pos;
+ static u_int callercnt, globalcnt, pos;
+
+ callercnt++;
+ if (callerdiv > 1 && (callercnt % callerdiv) != 0)
+ return;
+
+ globalcnt++;
+ if (globaldiv > 1 && (globalcnt % globaldiv) != 0)
+ return;
putchar("|/-\\"[pos++ & 3]);
putchar('\b');
}
+
+void
+twiddle_divisor(u_int gdiv)
+{
+
+ globaldiv = gdiv;
+}
diff --git a/lib/libstand/ufs.c b/lib/libstand/ufs.c
index b6f7815..928a1d1 100644
--- a/lib/libstand/ufs.c
+++ b/lib/libstand/ufs.c
@@ -155,7 +155,7 @@ read_inode(inumber, f)
* Read inode and save it.
*/
buf = malloc(fs->fs_bsize);
- twiddle();
+ twiddle(1);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize,
buf, &rsize);
@@ -265,7 +265,7 @@ block_map(f, file_block, disk_block_p)
if (fp->f_blk[level] == (char *)0)
fp->f_blk[level] =
malloc(fs->fs_bsize);
- twiddle();
+ twiddle(1);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fp->f_fs, ind_block_num),
fs->fs_bsize,
@@ -346,7 +346,7 @@ buf_write_file(f, buf_p, size_p)
if (fp->f_buf == (char *)0)
fp->f_buf = malloc(fs->fs_bsize);
- twiddle();
+ twiddle(4);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, disk_block),
block_size, fp->f_buf, &fp->f_buf_size);
@@ -365,7 +365,7 @@ buf_write_file(f, buf_p, size_p)
* Write the block out to storage.
*/
- twiddle();
+ twiddle(4);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
fsbtodb(fs, disk_block),
block_size, fp->f_buf, &fp->f_buf_size);
@@ -406,7 +406,7 @@ buf_read_file(f, buf_p, size_p)
bzero(fp->f_buf, block_size);
fp->f_buf_size = block_size;
} else {
- twiddle();
+ twiddle(4);
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, disk_block),
block_size, fp->f_buf, &fp->f_buf_size);
@@ -515,7 +515,7 @@ ufs_open(upath, f)
/* allocate space and read super block */
fs = malloc(SBLOCKSIZE);
fp->f_fs = fs;
- twiddle();
+ twiddle(1);
/*
* Try reading the superblock in each of its possible locations.
*/
@@ -649,7 +649,7 @@ ufs_open(upath, f)
if (rc)
goto out;
- twiddle();
+ twiddle(1);
rc = (f->f_dev->dv_strategy)(f->f_devdata,
F_READ, fsbtodb(fs, disk_block),
fs->fs_bsize, buf, &buf_size);
diff --git a/lib/libstand/write.c b/lib/libstand/write.c
index dccdb8b..9e02f08 100644
--- a/lib/libstand/write.c
+++ b/lib/libstand/write.c
@@ -80,7 +80,7 @@ write(fd, dest, bcount)
return (-1);
}
if (f->f_flags & F_RAW) {
- twiddle();
+ twiddle(4);
errno = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE,
btodb(f->f_offset), bcount, dest, &resid);
if (errno)
diff --git a/lib/libusb/libusb20.3 b/lib/libusb/libusb20.3
index f6004a5..590ff3c 100644
--- a/lib/libusb/libusb20.3
+++ b/lib/libusb/libusb20.3
@@ -1053,8 +1053,8 @@ This function does not return NULL.
.It Pa /dev/usb
.El
.Sh SEE ALSO
-.Xr usb 4 ,
.Xr libusb 3 ,
+.Xr usb 4 ,
.Xr usbconfig 8 ,
.Xr usbdump 8
.
diff --git a/lib/libutil/quotafile.3 b/lib/libutil/quotafile.3
index 001a66c..362cf01 100644
--- a/lib/libutil/quotafile.3
+++ b/lib/libutil/quotafile.3
@@ -273,8 +273,8 @@ and set
to indicate the error.
.Sh SEE ALSO
.Xr quotactl 2 ,
-.Xr quota.user 5 ,
-.Xr quota.group 5
+.Xr quota.group 5 ,
+.Xr quota.user 5
.Sh HISTORY
The
.Nm quotafile
diff --git a/lib/libxo/Makefile b/lib/libxo/Makefile
index fbe7857..770db20 100644
--- a/lib/libxo/Makefile
+++ b/lib/libxo/Makefile
@@ -7,6 +7,8 @@ LIBXO= ${.CURDIR:H:H}/contrib/libxo
LIB= xo
SHLIB_MAJOR=0
+SHLIBDIR?= /lib
+
SRCS= libxo.c
CFLAGS+=-I${LIBXO}/libxo
diff --git a/lib/msun/man/cexp.3 b/lib/msun/man/cexp.3
index 97e36c1..776e6ce 100644
--- a/lib/msun/man/cexp.3
+++ b/lib/msun/man/cexp.3
@@ -103,7 +103,7 @@ is not finite, the sign of the result is indeterminate.
.Sh SEE ALSO
.Xr complex 3 ,
.Xr exp 3 ,
-.Xr math 3 ,
+.Xr math 3
.Sh STANDARDS
The
.Fn cexp
diff --git a/lib/msun/man/complex.3 b/lib/msun/man/complex.3
index 34eb03e..d286494 100644
--- a/lib/msun/man/complex.3
+++ b/lib/msun/man/complex.3
@@ -103,9 +103,9 @@ ctan tangent
ctanh hyperbolic tangent
.El
.Sh SEE ALSO
-.Xr math 3 ,
.Xr fenv 3 ,
.Xr ieee 3 ,
+.Xr math 3 ,
.Xr tgmath 3
.Rs
.%T "ISO/IEC 9899:TC3"
diff --git a/lib/msun/man/csqrt.3 b/lib/msun/man/csqrt.3
index 1a1dfa0..d8066ae 100644
--- a/lib/msun/man/csqrt.3
+++ b/lib/msun/man/csqrt.3
@@ -85,7 +85,7 @@ an \*(Na is generated, an invalid exception will be thrown.
.Sh SEE ALSO
.Xr cabs 3 ,
.Xr fenv 3 ,
-.Xr math 3 ,
+.Xr math 3
.Sh STANDARDS
The
.Fn csqrt ,
diff --git a/lib/msun/man/sin.3 b/lib/msun/man/sin.3
index c7daf09..4a5352e 100644
--- a/lib/msun/man/sin.3
+++ b/lib/msun/man/sin.3
@@ -70,9 +70,9 @@ functions return the sine value.
.Xr asin 3 ,
.Xr atan 3 ,
.Xr atan2 3 ,
-.Xr csin 3 ,
.Xr cos 3 ,
.Xr cosh 3 ,
+.Xr csin 3 ,
.Xr math 3 ,
.Xr sinh 3 ,
.Xr tan 3 ,
diff --git a/lib/msun/src/math_private.h b/lib/msun/src/math_private.h
index 083197e..afaf201 100644
--- a/lib/msun/src/math_private.h
+++ b/lib/msun/src/math_private.h
@@ -456,9 +456,8 @@ typedef union {
* to -0.0+I*0.0.
*
* The C11 standard introduced the macros CMPLX(), CMPLXF() and CMPLXL()
- * to construct complex values. The functions below are modelled after
- * these macros, with the exception that they cannot be used to
- * construct compile-time complex values.
+ * to construct complex values. Compilers that conform to the C99
+ * standard require the following functions to avoid the above issues.
*/
#ifndef CMPLXF
diff --git a/release/arm/release.sh b/release/arm/release.sh
index 020583f..dbbdbf5 100755
--- a/release/arm/release.sh
+++ b/release/arm/release.sh
@@ -127,6 +127,14 @@ main() {
BATCH=1 FORCE_PKG_REGISTER=1 install clean distclean
done
+ # Certain u-boot versions hardcode the use of a host gcc, and gcc's
+ # build relies on having gperf installed.
+ eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/gperf \
+ WITH_GCC=1 ${WORLD_FLAGS} obj
+ eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/gperf \
+ WITH_GCC=1 ${WORLD_FLAGS} -j1 depend all
+ eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/gperf \
+ WITH_GCC=1 ${WORLD_FLAGS} -j1 install
eval chroot ${CHROOTDIR} make -C /usr/src/gnu/usr.bin/cc \
WITH_GCC=1 ${WORLD_FLAGS} -j1 obj depend all install
diff --git a/sbin/dhclient/dhclient.conf.5 b/sbin/dhclient/dhclient.conf.5
index 3b6ae04..fb9d9f1 100644
--- a/sbin/dhclient/dhclient.conf.5
+++ b/sbin/dhclient/dhclient.conf.5
@@ -524,8 +524,8 @@ In many cases, it is sufficient to just create an empty
file - the defaults are usually fine.
.Sh SEE ALSO
.Xr dhclient.leases 5 ,
-.Xr dhcpd.conf 5 ,
.Xr dhcp-options 5 ,
+.Xr dhcpd.conf 5 ,
.Xr dhclient 8 ,
.Xr dhcpd 8
.Rs
diff --git a/sbin/dhclient/dhclient.leases.5 b/sbin/dhclient/dhclient.leases.5
index f48b106..ebef819 100644
--- a/sbin/dhclient/dhclient.leases.5
+++ b/sbin/dhclient/dhclient.leases.5
@@ -75,8 +75,8 @@ Current lease file.
.El
.Sh SEE ALSO
.Xr dhclient.conf 5 ,
-.Xr dhcpd.conf 5 ,
.Xr dhcp-options 5 ,
+.Xr dhcpd.conf 5 ,
.Xr dhclient 8 ,
.Xr dhcpd 8
.Rs
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 90c8d7a..fdd398b 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -2819,9 +2819,9 @@ tried to alter an interface's configuration.
.Xr devd.conf 5 ,
.\" .Xr eon 5 ,
.Xr devd 8 ,
+.Xr jail 8 ,
.Xr rc 8 ,
.Xr routed 8 ,
-.Xr jail 8 ,
.Xr sysctl 8
.Sh HISTORY
The
diff --git a/sbin/iscontrol/iscontrol.8 b/sbin/iscontrol/iscontrol.8
index eee8776..3fe17a0 100644
--- a/sbin/iscontrol/iscontrol.8
+++ b/sbin/iscontrol/iscontrol.8
@@ -121,8 +121,8 @@ whatever options are specified, and start an iscsi-session.
.Xr iscsi_initiator 4 ,
.Xr sa 4 ,
.Xr iscsi.conf 5 ,
-.Xr iscsictl 8 ,
-.Xr camcontrol 8
+.Xr camcontrol 8 ,
+.Xr iscsictl 8
.Sh STANDARDS
RFC 3720
.\"Sh HISTORY
diff --git a/sbin/mount/mount.8 b/sbin/mount/mount.8
index aa7acfd..55a45e7 100644
--- a/sbin/mount/mount.8
+++ b/sbin/mount/mount.8
@@ -548,6 +548,7 @@ support for a particular file system might be provided either on a static
.Xr ext2fs 5 ,
.Xr fstab 5 ,
.Xr procfs 5 ,
+.Xr tmpfs 5 ,
.Xr automount 8 ,
.Xr fstyp 8 ,
.Xr kldload 8 ,
@@ -558,7 +559,6 @@ support for a particular file system might be provided either on a static
.Xr mount_smbfs 8 ,
.Xr mount_udf 8 ,
.Xr mount_unionfs 8 ,
-.Xr tmpfs 5 ,
.Xr umount 8 ,
.Xr zfs 8 ,
.Xr zpool 8
diff --git a/sbin/mount_fusefs/mount_fusefs.8 b/sbin/mount_fusefs/mount_fusefs.8
index 3e11cf1..3faf618 100644
--- a/sbin/mount_fusefs/mount_fusefs.8
+++ b/sbin/mount_fusefs/mount_fusefs.8
@@ -326,8 +326,8 @@ does not call any external utility and also provides a hacky
.Sh SEE ALSO
.Xr fstat 1 ,
.Xr mount 8 ,
-.Xr umount 8 ,
-.Xr sudo 8
+.Xr sudo 8 ,
+.Xr umount 8
.Sh HISTORY
.Nm
appears as the part of the FreeBSD implementation of the Fuse userspace filesystem
diff --git a/sbin/newfs/newfs.8 b/sbin/newfs/newfs.8
index 6764adc..a4c0358 100644
--- a/sbin/newfs/newfs.8
+++ b/sbin/newfs/newfs.8
@@ -310,10 +310,10 @@ on file systems that contain many small files.
.Xr fsck 8 ,
.Xr gjournal 8 ,
.Xr growfs 8 ,
+.Xr gvinum 8 ,
.Xr makefs 8 ,
.Xr mount 8 ,
-.Xr tunefs 8 ,
-.Xr gvinum 8
+.Xr tunefs 8
.Rs
.%A M. McKusick
.%A W. Joy
diff --git a/share/man/man3/ATOMIC_VAR_INIT.3 b/share/man/man3/ATOMIC_VAR_INIT.3
index f6c0a5d..e278602 100644
--- a/share/man/man3/ATOMIC_VAR_INIT.3
+++ b/share/man/man3/ATOMIC_VAR_INIT.3
@@ -297,5 +297,5 @@ These macros attempt to conform to
These macros appeared in
.Fx 10.0 .
.Sh AUTHORS
-.An Ed Schouten Aq Mt ed@FreeBSD.org
+.An \&Ed Schouten Aq Mt ed@FreeBSD.org
.An David Chisnall Aq Mt theraven@FreeBSD.org
diff --git a/share/man/man3/makedev.3 b/share/man/man3/makedev.3
index b32d69e..87ca953 100644
--- a/share/man/man3/makedev.3
+++ b/share/man/man3/makedev.3
@@ -85,6 +85,6 @@ macro returns a device minor number whose value can span the complete
range of an
.Vt int .
.Sh SEE ALSO
-.Xr devfs 5 ,
+.Xr mknod 2 ,
.Xr devname 3 ,
-.Xr mknod 2
+.Xr devfs 5
diff --git a/share/man/man3/pthread.3 b/share/man/man3/pthread.3
index 78a9153..9a0c5c8 100644
--- a/share/man/man3/pthread.3
+++ b/share/man/man3/pthread.3
@@ -484,14 +484,14 @@ Threaded applications are linked with this library.
.Xr pthread_cancel 3 ,
.Xr pthread_cleanup_pop 3 ,
.Xr pthread_cleanup_push 3 ,
-.Xr pthread_condattr_destroy 3 ,
-.Xr pthread_condattr_init 3 ,
.Xr pthread_cond_broadcast 3 ,
.Xr pthread_cond_destroy 3 ,
.Xr pthread_cond_init 3 ,
.Xr pthread_cond_signal 3 ,
.Xr pthread_cond_timedwait 3 ,
.Xr pthread_cond_wait 3 ,
+.Xr pthread_condattr_destroy 3 ,
+.Xr pthread_condattr_init 3 ,
.Xr pthread_create 3 ,
.Xr pthread_detach 3 ,
.Xr pthread_equal 3 ,
@@ -500,6 +500,11 @@ Threaded applications are linked with this library.
.Xr pthread_join 3 ,
.Xr pthread_key_delete 3 ,
.Xr pthread_kill 3 ,
+.Xr pthread_mutex_destroy 3 ,
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutex_lock 3 ,
+.Xr pthread_mutex_trylock 3 ,
+.Xr pthread_mutex_unlock 3 ,
.Xr pthread_mutexattr_destroy 3 ,
.Xr pthread_mutexattr_getprioceiling 3 ,
.Xr pthread_mutexattr_getprotocol 3 ,
@@ -508,21 +513,16 @@ Threaded applications are linked with this library.
.Xr pthread_mutexattr_setprioceiling 3 ,
.Xr pthread_mutexattr_setprotocol 3 ,
.Xr pthread_mutexattr_settype 3 ,
-.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_init 3 ,
-.Xr pthread_mutex_lock 3 ,
-.Xr pthread_mutex_trylock 3 ,
-.Xr pthread_mutex_unlock 3 ,
.Xr pthread_once 3 ,
-.Xr pthread_rwlockattr_destroy 3 ,
-.Xr pthread_rwlockattr_getpshared 3 ,
-.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3 ,
.Xr pthread_rwlock_destroy 3 ,
.Xr pthread_rwlock_init 3 ,
.Xr pthread_rwlock_rdlock 3 ,
.Xr pthread_rwlock_unlock 3 ,
.Xr pthread_rwlock_wrlock 3 ,
+.Xr pthread_rwlockattr_destroy 3 ,
+.Xr pthread_rwlockattr_getpshared 3 ,
+.Xr pthread_rwlockattr_init 3 ,
+.Xr pthread_rwlockattr_setpshared 3 ,
.Xr pthread_self 3 ,
.Xr pthread_setcancelstate 3 ,
.Xr pthread_setcanceltype 3 ,
diff --git a/share/man/man3/pthread_attr.3 b/share/man/man3/pthread_attr.3
index a99d32d..d6d9801 100644
--- a/share/man/man3/pthread_attr.3
+++ b/share/man/man3/pthread_attr.3
@@ -208,8 +208,8 @@ Invalid or unsupported value for
.Fa contentionscope .
.El
.Sh SEE ALSO
-.Xr pthread_attr_get_np 3 ,
.Xr pthread_attr_affinity_np 3 ,
+.Xr pthread_attr_get_np 3 ,
.Xr pthread_create 3
.Sh STANDARDS
.Fn pthread_attr_init ,
diff --git a/share/man/man3/pthread_cond_init.3 b/share/man/man3/pthread_cond_init.3
index 38843a7..415ce02 100644
--- a/share/man/man3/pthread_cond_init.3
+++ b/share/man/man3/pthread_cond_init.3
@@ -70,12 +70,12 @@ The system temporarily lacks the resources to create another condition
variable.
.El
.Sh SEE ALSO
-.Xr pthread_condattr 3 ,
.Xr pthread_cond_broadcast 3 ,
.Xr pthread_cond_destroy 3 ,
.Xr pthread_cond_signal 3 ,
.Xr pthread_cond_timedwait 3 ,
-.Xr pthread_cond_wait 3
+.Xr pthread_cond_wait 3 ,
+.Xr pthread_condattr 3
.Sh STANDARDS
The
.Fn pthread_cond_init
diff --git a/share/man/man3/pthread_mutex_init.3 b/share/man/man3/pthread_mutex_init.3
index 10a026b..a5a1eca 100644
--- a/share/man/man3/pthread_mutex_init.3
+++ b/share/man/man3/pthread_mutex_init.3
@@ -66,11 +66,11 @@ is invalid.
The process cannot allocate enough memory to create another mutex.
.El
.Sh SEE ALSO
-.Xr pthread_mutexattr 3 ,
.Xr pthread_mutex_destroy 3 ,
.Xr pthread_mutex_lock 3 ,
.Xr pthread_mutex_trylock 3 ,
-.Xr pthread_mutex_unlock 3
+.Xr pthread_mutex_unlock 3 ,
+.Xr pthread_mutexattr 3
.Sh STANDARDS
The
.Fn pthread_mutex_init
diff --git a/share/man/man3/pthread_mutexattr_getkind_np.3 b/share/man/man3/pthread_mutexattr_getkind_np.3
index 548045b..fe5435f 100644
--- a/share/man/man3/pthread_mutexattr_getkind_np.3
+++ b/share/man/man3/pthread_mutexattr_getkind_np.3
@@ -75,7 +75,7 @@ The value specified by
is invalid.
.El
.Sh SEE ALSO
-.Xr pthread_mutexattr_gettype 3 ,
-.Xr pthread_mutexattr_settype 3 ,
.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_init 3
+.Xr pthread_mutex_init 3 ,
+.Xr pthread_mutexattr_gettype 3 ,
+.Xr pthread_mutexattr_settype 3
diff --git a/share/man/man3/pthread_rwlock_init.3 b/share/man/man3/pthread_rwlock_init.3
index cf8cc7e..2617c43 100644
--- a/share/man/man3/pthread_rwlock_init.3
+++ b/share/man/man3/pthread_rwlock_init.3
@@ -85,9 +85,9 @@ The value specified by
is invalid.
.El
.Sh SEE ALSO
+.Xr pthread_rwlock_destroy 3 ,
.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3 ,
-.Xr pthread_rwlock_destroy 3
+.Xr pthread_rwlockattr_setpshared 3
.Sh STANDARDS
The
.Fn pthread_rwlock_init
diff --git a/share/man/man3/pthread_rwlockattr_getpshared.3 b/share/man/man3/pthread_rwlockattr_getpshared.3
index 3fe5de1..3e2f451 100644
--- a/share/man/man3/pthread_rwlockattr_getpshared.3
+++ b/share/man/man3/pthread_rwlockattr_getpshared.3
@@ -71,9 +71,9 @@ The value specified by
is invalid.
.El
.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3 ,
-.Xr pthread_rwlock_init 3
+.Xr pthread_rwlockattr_setpshared 3
.Sh STANDARDS
The
.Fn pthread_rwlockattr_getpshared
diff --git a/share/man/man3/pthread_rwlockattr_init.3 b/share/man/man3/pthread_rwlockattr_init.3
index 54d319f..1cce9cd 100644
--- a/share/man/man3/pthread_rwlockattr_init.3
+++ b/share/man/man3/pthread_rwlockattr_init.3
@@ -55,10 +55,10 @@ function will fail if:
Insufficient memory exists to initialize the attribute object.
.El
.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
.Xr pthread_rwlockattr_destroy 3 ,
.Xr pthread_rwlockattr_getpshared 3 ,
-.Xr pthread_rwlockattr_setpshared 3 ,
-.Xr pthread_rwlock_init 3
+.Xr pthread_rwlockattr_setpshared 3
.Sh STANDARDS
The
.Fn pthread_rwlockattr_init
diff --git a/share/man/man3/pthread_rwlockattr_setpshared.3 b/share/man/man3/pthread_rwlockattr_setpshared.3
index 36bcc69..ccfe886 100644
--- a/share/man/man3/pthread_rwlockattr_setpshared.3
+++ b/share/man/man3/pthread_rwlockattr_setpshared.3
@@ -75,9 +75,9 @@ or
is invalid.
.El
.Sh SEE ALSO
+.Xr pthread_rwlock_init 3 ,
.Xr pthread_rwlockattr_getpshared 3 ,
-.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlock_init 3
+.Xr pthread_rwlockattr_init 3
.Sh STANDARDS
The
.Fn pthread_rwlockattr_setpshared
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 76b3d55..b20cda5 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -156,7 +156,6 @@ MAN= aac.4 \
geom_uncompress.4 \
geom_uzip.4 \
gif.4 \
- gpib.4 \
gpio.4 \
gpioiic.4 \
gpioled.4 \
@@ -372,7 +371,6 @@ MAN= aac.4 \
pci.4 \
pcib.4 \
pcic.4 \
- pcii.4 \
pcm.4 \
pcn.4 \
${_pf.4} \
@@ -495,7 +493,6 @@ MAN= aac.4 \
ti.4 \
timecounters.4 \
tl.4 \
- tnt4882.4 \
${_tpm.4} \
trm.4 \
tty.4 \
diff --git a/share/man/man4/altera_atse.4 b/share/man/man4/altera_atse.4
index 10835cf..1cff0d0 100644
--- a/share/man/man4/altera_atse.4
+++ b/share/man/man4/altera_atse.4
@@ -80,7 +80,7 @@ Only a single MAC address may be stored in flash.
If the address begins with the Altera prefix 00:07:ed and ends in 00 then
up to 16 addresses will be derived from it by adding the unit number of
the interface to the stored address.
-For other prefixes, the address will be assigned to atse0 and random
+For other prefixes, the address will be assigned to atse0 and random
addresses will be used for other interfaces.
If the stored address is invalid, for example all zero's, multicast, or the
default address shipped on all DE4 boards (00:07:ed:ff:ed:15) then a random
diff --git a/share/man/man4/aout.4 b/share/man/man4/aout.4
index 8e7b02b..960ae25 100644
--- a/share/man/man4/aout.4
+++ b/share/man/man4/aout.4
@@ -123,7 +123,7 @@ non-executable mappings.
.Xr execve 2 ,
.Xr a.out 5 ,
.Xr elf 5 ,
-.Xr sysctl 8 .
+.Xr sysctl 8
.Sh HISTORY
The
.Xr a.out 5
diff --git a/share/man/man4/ata.4 b/share/man/man4/ata.4
index 4b53bf7..cf0b5de 100644
--- a/share/man/man4/ata.4
+++ b/share/man/man4/ata.4
@@ -253,10 +253,10 @@ work well on long cables, especially at high speeds.
.Xr ada 4 ,
.Xr ahci 4 ,
.Xr cam 4 ,
-.Xr camcontrol 8 ,
.Xr cd 4 ,
.Xr mvs 4 ,
-.Xr siis 4
+.Xr siis 4 ,
+.Xr camcontrol 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/ath_ahb.4 b/share/man/man4/ath_ahb.4
index 6688dc2..52aceb7 100644
--- a/share/man/man4/ath_ahb.4
+++ b/share/man/man4/ath_ahb.4
@@ -47,7 +47,7 @@ drivers.
This is only relevant for embedded System-on-Chip (SoC) devices such as
the Atheros AR913x series, which include an Atheros wireless MAC on-die.
.Sh SEE ALSO
-.Xr ath 4
+.Xr ath 4 ,
.Xr ath_hal 4
.Sh HISTORY
The
diff --git a/share/man/man4/ath_pci.4 b/share/man/man4/ath_pci.4
index 814e535..0cc36d7 100644
--- a/share/man/man4/ath_pci.4
+++ b/share/man/man4/ath_pci.4
@@ -44,7 +44,7 @@ and
.Xr ath_hal 4
drivers.
.Sh SEE ALSO
-.Xr ath 4
+.Xr ath 4 ,
.Xr ath_hal 4
.Sh HISTORY
The
diff --git a/share/man/man4/audit.4 b/share/man/man4/audit.4
index 9f3f17f..512f5c3 100644
--- a/share/man/man4/audit.4
+++ b/share/man/man4/audit.4
@@ -88,10 +88,10 @@ to track users and events in a fine-grained manner.
.Xr setauid 2 ,
.Xr libbsm 3 ,
.Xr auditpipe 4 ,
+.Xr audit.log 5 ,
.Xr audit_class 5 ,
.Xr audit_control 5 ,
.Xr audit_event 5 ,
-.Xr audit.log 5 ,
.Xr audit_user 5 ,
.Xr audit_warn 5 ,
.Xr rc.conf 5 ,
diff --git a/share/man/man4/bhyve.4 b/share/man/man4/bhyve.4
index 4947ecf..f4ff2e1 100644
--- a/share/man/man4/bhyve.4
+++ b/share/man/man4/bhyve.4
@@ -45,10 +45,10 @@ unmodified guest operating systems on top of FreeBSD.
relies heavily on hardware assist provided by the CPU and chipset to virtualize
processor and memory resources.
.Sh SEE ALSO
+.Xr vmm 4 ,
.Xr bhyve 8 ,
-.Xr bhyveload 8 ,
.Xr bhyvectl 8 ,
-.Xr vmm 4
+.Xr bhyveload 8
.Sh HISTORY
.Nm
first appeared in
diff --git a/share/man/man4/carp.4 b/share/man/man4/carp.4
index ca52ba2..d1844b8 100644
--- a/share/man/man4/carp.4
+++ b/share/man/man4/carp.4
@@ -303,10 +303,10 @@ tcpdump -npi vlan0 -T carp
.Sh SEE ALSO
.Xr inet 4 ,
.Xr pfsync 4 ,
-.Xr rc.conf 5 ,
.Xr devd.conf 5 ,
+.Xr rc.conf 5 ,
.Xr ifconfig 8 ,
-.Xr sysctl 8
+.Xr sysctl 8 ,
.Xr tcpdump 8
.Sh HISTORY
The
diff --git a/share/man/man4/ch.4 b/share/man/man4/ch.4
index 121199b..312a0f1 100644
--- a/share/man/man4/ch.4
+++ b/share/man/man4/ch.4
@@ -325,8 +325,8 @@ If the media changer does not support features requested by the
driver, it will produce both console error messages and failure return
codes to the ioctls described here.
.Sh SEE ALSO
-.Xr cam 4 ,
.Xr chio 1 ,
+.Xr cam 4 ,
.Xr cd 4 ,
.Xr da 4 ,
.Xr sa 4
diff --git a/share/man/man4/crypto.4 b/share/man/man4/crypto.4
index ef35e03..a488d9c 100644
--- a/share/man/man4/crypto.4
+++ b/share/man/man4/crypto.4
@@ -114,7 +114,6 @@ The two modes are described separately below.
.Sh THEORY OF OPERATION
Regardless of whether symmetric-key or asymmetric-key operations are
to be performed, use of the device requires a basic series of steps:
-.Pp
.Bl -enum
.It
Open a file descriptor for the device.
diff --git a/share/man/man4/ehci.4 b/share/man/man4/ehci.4
index 1d06bf9..5e15411 100644
--- a/share/man/man4/ehci.4
+++ b/share/man/man4/ehci.4
@@ -70,10 +70,10 @@ but can be noticed since
2.0 devices plugged in to the same
connector appear to connect to different USB busses.
.Sh SEE ALSO
-.Xr xhci 4 ,
.Xr ohci 4 ,
.Xr uhci 4 ,
-.Xr usb 4
+.Xr usb 4 ,
+.Xr xhci 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4
index c881f47..8f42f1b 100644
--- a/share/man/man4/geom.4
+++ b/share/man/man4/geom.4
@@ -450,8 +450,8 @@ Dump contents of gctl requests.
.El
.Sh SEE ALSO
.Xr libgeom 3 ,
-.Xr disk 9 ,
.Xr DECLARE_GEOM_CLASS 9 ,
+.Xr disk 9 ,
.Xr g_access 9 ,
.Xr g_attach 9 ,
.Xr g_bio 9 ,
diff --git a/share/man/man4/gpib.4 b/share/man/man4/gpib.4
deleted file mode 100644
index b5f29cd..0000000
--- a/share/man/man4/gpib.4
+++ /dev/null
@@ -1,100 +0,0 @@
-.\" Copyright (c) 2010, Joerg Wunsch
-.\" 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$
-.\"
-.Dd January 24, 2010
-.Dt GPIB 4
-.Os
-.Sh NAME
-.Nm gpib
-.Nd General-Purpose Instrument Bus (GPIB) driver
-.Sh SYNOPSIS
-Either of the
-.Xr pcii 4
-or
-.Xr tnt4882 4
-drivers use this driver as the backend.
-.Sh DESCRIPTION
-The
-.Nm
-driver provides support for driving an IEEE-488 bus, also called
-IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
-Bus), or GPIB (General Purpose Instrument Bus).
-The device can become either a listener, talker, controller, and
-in particular a master controller on the bus.
-.Ss Example
-The following example code queries the device provided as
-.Va argv[1]
-for its identification response.
-.Bd -literal
-/* compile with: cc -O -o ibtest ibtest.c -lgpib */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <err.h>
-#include <vis.h>
-
-#include <gpib/gpib.h>
-
-int
-main(int argc, char **argv)
-{
- int dmm;
- unsigned char buf[100];
- char vbuf[sizeof(buf) * 4];
-
- /* DVM */
- dmm = ibdev(0, (argc > 1? atoi(argv[1]): 7), 0,
- T10s, 1, 0);
- if (dmm < 0)
- errx(1, "ibdev = %d\\n", dmm);
- ibwrt(dmm, "*IDN?\\r\\n", 7);
- ibrd(dmm, buf, sizeof(buf) - 1);
- strvisx(vbuf, buf, ibcnt, VIS_WHITE | VIS_CSTYLE);
- printf("%s\\n", vbuf);
- return (0);
-}
-.Ed
-.Sh FILES
-.Bl -tag -width /dev/gpibNNib
-.It Pa /dev/gpib Ns Em N Ns "ib"
-Main device node to access the driver.
-.It Pa /dev/gpib Ns Em N Ns "l"
-Listen-only entry to the driver.
-When opening, an instrument can send data to this device on the
-bus in an unaddressed mode, for example hard-copy printer data.
-.El
-.Sh SEE ALSO
-.Xr gpib 3 ,
-.Xr pcii 4 ,
-.Xr tnt4882 4
-.Sh HISTORY
-The
-.Nm
-driver was written by Poul-Henning Kamp, and first appeared in
-.Fx 5.4 .
-.Sh AUTHORS
-This manual page was written by
-.An J\(:org Wunsch .
diff --git a/share/man/man4/gpioled.4 b/share/man/man4/gpioled.4
index 6d1b41e..3e30595 100644
--- a/share/man/man4/gpioled.4
+++ b/share/man/man4/gpioled.4
@@ -52,8 +52,8 @@ The GPIO pin can then be controlled by writing to this device as described
in
.Xr led 4 .
.Pp
-On a
-.Xr device.hints 5
+On a
+.Xr device.hints 5
based system, like
.Li MIPS ,
these values are configurable for
diff --git a/share/man/man4/hv_ata_pci_disengage.4 b/share/man/man4/hv_ata_pci_disengage.4
index 2123e8b..e7a3352 100644
--- a/share/man/man4/hv_ata_pci_disengage.4
+++ b/share/man/man4/hv_ata_pci_disengage.4
@@ -70,10 +70,10 @@ If CDROM access is a must then users may use
"set hw.ata.disk_enable=1" at boot time to prevent the ATA driver from being
disabled.
.Sh SEE ALSO
-.Xr hv_vmbus 4 ,
-.Xr hv_utils 4 ,
.Xr hv_netvsc 4 ,
-.Xr hv_storvsc 4
+.Xr hv_storvsc 4 ,
+.Xr hv_utils 4 ,
+.Xr hv_vmbus 4
.Sh HISTORY
Support for
.Nm
diff --git a/share/man/man4/hv_kvp.4 b/share/man/man4/hv_kvp.4
index 269eef7..9aaf985 100644
--- a/share/man/man4/hv_kvp.4
+++ b/share/man/man4/hv_kvp.4
@@ -74,11 +74,11 @@ guest's IP address to its original static value.
On the other hand, the get IP functionality is used to update the guest IP
address in the Hyper-V management console window.
.Sh SEE ALSO
-.Xr hv_vmbus 4 ,
-.Xr hv_utils 4 ,
+.Xr hv_ata_pci_disengage 4 ,
.Xr hv_netvsc 4 ,
.Xr hv_storvsc 4 ,
-.Xr hv_ata_pci_disengage 4 ,
+.Xr hv_utils 4 ,
+.Xr hv_vmbus 4 ,
.Xr hv_kvp_daemon 8
.Sh HISTORY
Support for
diff --git a/share/man/man4/hv_netvsc.4 b/share/man/man4/hv_netvsc.4
index 31325bb..a619332d 100644
--- a/share/man/man4/hv_netvsc.4
+++ b/share/man/man4/hv_netvsc.4
@@ -63,10 +63,10 @@ driver.
The VSP in the root partition then forwards the network related requests to
the physical network card.
.Sh SEE ALSO
-.Xr hv_vmbus 4 ,
-.Xr hv_utils 4 ,
+.Xr hv_ata_pci_disengage 4 ,
.Xr hv_storvsc 4 ,
-.Xr hv_ata_pci_disengage 4
+.Xr hv_utils 4 ,
+.Xr hv_vmbus 4
.Sh HISTORY
Support for
.Nm
diff --git a/share/man/man4/hv_storvsc.4 b/share/man/man4/hv_storvsc.4
index 54805f1..0941703 100644
--- a/share/man/man4/hv_storvsc.4
+++ b/share/man/man4/hv_storvsc.4
@@ -69,10 +69,10 @@ CAM control blocks (CCBs) are
converted into VSCSI protocol messages which are delivered to the root
partition VSP over the Hyper-V VMBus.
.Sh SEE ALSO
-.Xr hv_vmbus 4 ,
-.Xr hv_utils 4 ,
+.Xr hv_ata_pci_disengage 4 ,
.Xr hv_netvsc 4 ,
-.Xr hv_ata_pci_disengage 4
+.Xr hv_utils 4 ,
+.Xr hv_vmbus 4
.Sh HISTORY
Support for
.Nm
diff --git a/share/man/man4/hv_utils.4 b/share/man/man4/hv_utils.4
index 82439ea..e005378 100644
--- a/share/man/man4/hv_utils.4
+++ b/share/man/man4/hv_utils.4
@@ -65,10 +65,10 @@ command.
(c) Heartbeat: This feature allows the virtualization server to detect whether
the guest partition is running and responsive.
.Sh SEE ALSO
-.Xr hv_vmbus 4 ,
+.Xr hv_ata_pci_disengage 4 ,
.Xr hv_netvsc 4 ,
.Xr hv_storvsc 4 ,
-.Xr hv_ata_pci_disengage 4
+.Xr hv_vmbus 4
.Sh HISTORY
Support for
.Nm
diff --git a/share/man/man4/hv_vmbus.4 b/share/man/man4/hv_vmbus.4
index daafd5d..d992be5 100644
--- a/share/man/man4/hv_vmbus.4
+++ b/share/man/man4/hv_vmbus.4
@@ -73,10 +73,10 @@ the interface that facilitate high performance bi-directional communication
between the VSCs and VSPs.
All VSCs utilize the VMBus driver.
.Sh SEE ALSO
-.Xr hv_utils 4 ,
+.Xr hv_ata_pci_disengage 4 ,
.Xr hv_netvsc 4 ,
.Xr hv_storvsc 4 ,
-.Xr hv_ata_pci_disengage 4
+.Xr hv_utils 4
.Sh HISTORY
Support for
.Nm
diff --git a/share/man/man4/igmp.4 b/share/man/man4/igmp.4
index 696fa7d..2e82048 100644
--- a/share/man/man4/igmp.4
+++ b/share/man/man4/igmp.4
@@ -126,11 +126,11 @@ This sysctl is normally enabled by default.
.\"
.El
.Sh SEE ALSO
-.Xr ifmcstat 8 ,
+.Xr netstat 1 ,
+.Xr sourcefilter 3 ,
.Xr inet 4 ,
.Xr multicast 4 ,
-.Xr netstat 1 ,
-.Xr sourcefilter 3
+.Xr ifmcstat 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/iicbus.4 b/share/man/man4/iicbus.4
index ce9d586..c89bfaf 100644
--- a/share/man/man4/iicbus.4
+++ b/share/man/man4/iicbus.4
@@ -106,11 +106,11 @@ Some I2C interfaces are available:
.Sh BUS FREQUENCY CONFIGURATION
The operating frequency of an I2C bus may be fixed or configurable.
The bus may be used as part of some larger standard interface, and that
-interface specification may require a fixed frequency.
-The driver for that hardware would not honor an attempt to configure a
+interface specification may require a fixed frequency.
+The driver for that hardware would not honor an attempt to configure a
different speed.
A general purpose I2C bus, such as those found in many embedded systems,
-will often support multiple bus frequencies.
+will often support multiple bus frequencies.
.Pp
When a system supports multiple I2C busses, a different frequency can
be configured for each bus by number, represented by the
@@ -145,7 +145,7 @@ The same variable can be changed at any time with
Reset the bus using
.Xr i2c 8
or the
-.Xr iic 4
+.Xr iic 4
.Va I2CRSTCARD
ioctl to make the change take effect.
.Sh SEE ALSO
diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4
index 68b817d..101993f 100644
--- a/share/man/man4/ip.4
+++ b/share/man/man4/ip.4
@@ -857,12 +857,12 @@ field was not equal to the length of the datagram written to the socket.
.Xr recv 2 ,
.Xr send 2 ,
.Xr byteorder 3 ,
+.Xr sourcefilter 3 ,
.Xr icmp 4 ,
.Xr igmp 4 ,
.Xr inet 4 ,
.Xr intro 4 ,
-.Xr multicast 4 ,
-.Xr sourcefilter 3
+.Xr multicast 4
.Rs
.%A D. Thaler
.%A B. Fenner
diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4
index dba5e8d..d28e37e 100644
--- a/share/man/man4/ip6.4
+++ b/share/man/man4/ip6.4
@@ -653,8 +653,8 @@ An ancillary data object was improperly formed.
.Xr if_nametoindex 3 ,
.Xr bpf 4 ,
.Xr icmp6 4 ,
-.Xr ip 4 ,
.Xr inet6 4 ,
+.Xr ip 4 ,
.Xr netintro 4 ,
.Xr tcp 4 ,
.Xr udp 4
diff --git a/share/man/man4/ipheth.4 b/share/man/man4/ipheth.4
index 85801f2..a237524b 100644
--- a/share/man/man4/ipheth.4
+++ b/share/man/man4/ipheth.4
@@ -80,7 +80,7 @@ Apple iPad tethering (all models)
.Xr netintro 4 ,
.Xr urndis 4 ,
.Xr usb 4 ,
-.Xr ifconfig 8
+.Xr ifconfig 8 ,
.Xr usbconfig 8
.Sh HISTORY
The
diff --git a/share/man/man4/ips.4 b/share/man/man4/ips.4
index b22b91c..a4b8c2c 100644
--- a/share/man/man4/ips.4
+++ b/share/man/man4/ips.4
@@ -187,9 +187,9 @@ driver does not use the
subsystem.
.Sh SEE ALSO
.Xr aac 4 ,
-.Xr mfi 4 ,
.Xr ch 4 ,
.Xr da 4 ,
+.Xr mfi 4 ,
.Xr sysctl 8
.Sh AUTHORS
The
diff --git a/share/man/man4/iscsi_initiator.4 b/share/man/man4/iscsi_initiator.4
index a391e08..df03e6a 100644
--- a/share/man/man4/iscsi_initiator.4
+++ b/share/man/man4/iscsi_initiator.4
@@ -47,7 +47,7 @@ iscsi_initiator_load="YES"
.Sh DESCRIPTION
.Bf -symbolic
This driver, along with its userspace counterpart
-.Xr iscontrol 8 ,
+.Xr iscontrol 8 ,
is obsolete.
Users are advised to use
.Xr iscsi 4
@@ -112,6 +112,7 @@ for each new session.
iSCSI RFC 3720
.\" .Sh HISTORY
.Sh AUTHORS
-This software was written by Daniel Braniss <danny@cs.huji.ac.il>
+This software was written by
+.An Daniel Braniss Aq Mt danny@cs.huji.ac.il
.Sh BUGS
The lun discovery method is old-fashioned.
diff --git a/share/man/man4/isp.4 b/share/man/man4/isp.4
index cf1fa12..6d3a49a 100644
--- a/share/man/man4/isp.4
+++ b/share/man/man4/isp.4
@@ -230,7 +230,9 @@ This is the readonly World Wide Port Name value for this port.
.Sh AUTHORS
The
.Nm
-driver was written by Matthew Jacob originally for NetBSD at
+driver was written by
+.An Matthew Jacob
+originally for NetBSD at
NASA/Ames Research Center.
.Sh BUGS
The driver currently ignores some NVRAM settings.
diff --git a/share/man/man4/ispfw.4 b/share/man/man4/ispfw.4
index 5755501..119b675 100644
--- a/share/man/man4/ispfw.4
+++ b/share/man/man4/ispfw.4
@@ -56,4 +56,5 @@ This will kick the f/w into getting unstuck.
.Sh SEE ALSO
.Xr isp 4
.Sh AUTHORS
-This driver was written by Matthew Jacob.
+This driver was written by
+.An Matthew Jacob .
diff --git a/share/man/man4/iwi.4 b/share/man/man4/iwi.4
index 683f496..911e54c 100644
--- a/share/man/man4/iwi.4
+++ b/share/man/man4/iwi.4
@@ -152,7 +152,7 @@ This should not happen.
.Xr wlan_tkip 4 ,
.Xr wlan_wep 4 ,
.Xr ifconfig 8 ,
-.Xr wpa_supplicant 8 .
+.Xr wpa_supplicant 8
.Sh AUTHORS
The original
.Nm
diff --git a/share/man/man4/lagg.4 b/share/man/man4/lagg.4
index 1b40315..0b66c3d 100644
--- a/share/man/man4/lagg.4
+++ b/share/man/man4/lagg.4
@@ -176,8 +176,8 @@ device will be used:
device as a workaround.)
.Sh SEE ALSO
.Xr ng_one2many 4 ,
-.Xr sysctl 8 ,
-.Xr ifconfig 8
+.Xr ifconfig 8 ,
+.Xr sysctl 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/man4.i386/glxsb.4 b/share/man/man4/man4.i386/glxsb.4
index a77b475..d2a3035 100644
--- a/share/man/man4/man4.i386/glxsb.4
+++ b/share/man/man4/man4.i386/glxsb.4
@@ -70,8 +70,8 @@ device driver with AES keys of length != 128 bits.
.Sh SEE ALSO
.Xr crypto 4 ,
.Xr intro 4 ,
-.Xr pci 4 ,
.Xr ipsec 4 ,
+.Xr pci 4 ,
.Xr random 4 ,
.Xr crypto 9
.Sh HISTORY
diff --git a/share/man/man4/man4.powerpc/smu.4 b/share/man/man4/man4.powerpc/smu.4
index 2e10160..f5930d6 100644
--- a/share/man/man4/man4.powerpc/smu.4
+++ b/share/man/man4/man4.powerpc/smu.4
@@ -109,8 +109,8 @@ annunciator interface at
.Pa /dev/led/sleepled .
.Sh SEE ALSO
.Xr acpi 4 ,
-.Xr pmu 4 ,
-.Xr led 4
+.Xr led 4 ,
+.Xr pmu 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/man4.powerpc/snd_ai2s.4 b/share/man/man4/man4.powerpc/snd_ai2s.4
index 9356600..2773b53 100644
--- a/share/man/man4/man4.powerpc/snd_ai2s.4
+++ b/share/man/man4/man4.powerpc/snd_ai2s.4
@@ -65,8 +65,8 @@ Apple Tumbler Audio
Apple Snapper Audio
.El
.Sh SEE ALSO
-.Xr sound 4 ,
-.Xr snd_davbus 4
+.Xr snd_davbus 4 ,
+.Xr sound 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/man4.powerpc/snd_davbus.4 b/share/man/man4/man4.powerpc/snd_davbus.4
index 9949f9b8..ed3f3ed 100644
--- a/share/man/man4/man4.powerpc/snd_davbus.4
+++ b/share/man/man4/man4.powerpc/snd_davbus.4
@@ -63,8 +63,8 @@ Apple Burgundy Audio
Apple Screamer Audio
.El
.Sh SEE ALSO
-.Xr sound 4 ,
-.Xr snd_ai2s 4
+.Xr snd_ai2s 4 ,
+.Xr sound 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/mmc.4 b/share/man/man4/mmc.4
index 95fe976..184ac90 100644
--- a/share/man/man4/mmc.4
+++ b/share/man/man4/mmc.4
@@ -47,8 +47,8 @@ bus typically has only one slot, and only memory cards.
MultiMediaCards exist only in memory.
SD Cards exist as memory, I/O, or combination cards.
.Sh SEE ALSO
-.Xr mmcsd 4 ,
.Xr at91_mci 4 ,
+.Xr mmcsd 4 ,
.Xr sdhci 4
.Rs
.%T "SD Specifications, Part 1, Physical Layer, Simplified Specification"
diff --git a/share/man/man4/mmcsd.4 b/share/man/man4/mmcsd.4
index 646e032..e25efa3 100644
--- a/share/man/man4/mmcsd.4
+++ b/share/man/man4/mmcsd.4
@@ -37,8 +37,8 @@ The
.Nm
driver implements direct access block device for MMC and SD memory cards.
.Sh SEE ALSO
-.Xr mmc 4 ,
.Xr at91_mci 4 ,
+.Xr mmc 4 ,
.Xr sdhci 4
.Rs
.%T "SD Specifications, Part 1, Physical Layer, Simplified Specification"
diff --git a/share/man/man4/mod_cc.4 b/share/man/man4/mod_cc.4
index 4b08a6d..b280d36 100644
--- a/share/man/man4/mod_cc.4
+++ b/share/man/man4/mod_cc.4
@@ -30,7 +30,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 15, 2011
+.Dd December 26, 2014
.Dt MOD_CC 4
.Os
.Sh NAME
@@ -75,6 +75,7 @@ one of the names listed by the
MIB variable.
.El
.Sh SEE ALSO
+.Xr cc_cdg 4 ,
.Xr cc_chd 4 ,
.Xr cc_cubic 4 ,
.Xr cc_hd 4 ,
diff --git a/share/man/man4/mpr.4 b/share/man/man4/mpr.4
index c85be67..1780a95 100644
--- a/share/man/man4/mpr.4
+++ b/share/man/man4/mpr.4
@@ -59,7 +59,7 @@ mpr_load="YES"
.Ed
.Sh DESCRIPTION
The
-.Nm
+.Nm
driver provides support for LSI Fusion-MPT 3 IT/IR
.Tn SAS
controllers.
diff --git a/share/man/man4/mpt.4 b/share/man/man4/mpt.4
index d514cc9..2e15325 100644
--- a/share/man/man4/mpt.4
+++ b/share/man/man4/mpt.4
@@ -157,8 +157,8 @@ can take on - no separate compilation is required.
.Xr sa 4 ,
.Xr scsi 4 ,
.Xr targ 4 ,
-.Xr mptutil 8 ,
-.Xr gmultipath 8
+.Xr gmultipath 8 ,
+.Xr mptutil 8
.Rs
.%T "LSI Logic Website"
.%U http://www.lsi.com/
diff --git a/share/man/man4/mrsas.4 b/share/man/man4/mrsas.4
index 70cafca..2ed2c84 100644
--- a/share/man/man4/mrsas.4
+++ b/share/man/man4/mrsas.4
@@ -27,7 +27,7 @@
.\" 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.
-.\"
+.\"
.\" The views and conclusions contained in the software and documentation
.\" are those of the authors and should not be interpreted as representing
.\" official policies, either expressed or implied, of the FreeBSD Project.
@@ -57,15 +57,15 @@ mrsas_load="YES"
.Ed
.Sh DESCRIPTION
The
-.Nm
+.Nm
driver will detect LSI's next generation (6Gb/s and 12Gb/s) PCI Express
SAS/SATA RAID controllers.
See the
.Nm HARDWARE
section for the supported devices list.
-A disk (virtual disk/physical disk) attached to the
+A disk (virtual disk/physical disk) attached to the
.Nm
-driver will be visible to the user through
+driver will be visible to the user through
.Xr camcontrol 8
as
.Pa /dev/da?
@@ -79,11 +79,11 @@ The
name is derived from the phrase "MegaRAID SAS HBA", which is
substantially different than the old "MegaRAID" Driver
.Xr mfi 4
-which does not connect targets
-to the
+which does not connect targets
+to the
+.Xr cam 4
+layer and thus requires a new driver which attaches targets to the
.Xr cam 4
-layer and thus requires a new driver which attaches targets to the
-.Xr cam 4
layer.
Older MegaRAID controllers are supported by
.Xr mfi 4
@@ -91,7 +91,7 @@ and will not work with
.Nm ,
but both the
.Xr mfi 4
-and
+and
.Nm
drivers can detect and manage the LSI MegaRAID SAS 2208/2308/3008/3108 series of
controllers.
@@ -104,8 +104,8 @@ driver's behavior for LSI MegaRAID SAS 2208/2308/3008/3108 controllers.
By default, the
.Xr mfi 4
driver will detect these controllers.
-See the
-.Nm PRIORITY
+See the
+.Nm PRIORITY
section to know more about driver priority for MR-Fusion devices.
.Pp
.Nm
@@ -164,16 +164,16 @@ DELL PERC H330
.Sh CONFIGURATION
To disable Online Controller Reset(OCR) for a specific
.Nm
-driver instance, set the
+driver instance, set the
following tunable value in
.Xr loader.conf 5 :
.Bd -literal -offset indent
-dev.mrsas.X.disable_ocr=1
+dev.mrsas.X.disable_ocr=1
.Ed
.Pp
where X is the adapter number.
.Pp
-To change the I/O timeout value for a specific
+To change the I/O timeout value for a specific
.Nm
driver instance, set the following tunable value in
.Xr loader.conf 5 :
@@ -230,12 +230,12 @@ and
.Dv BUS_PROBE_LOW_PRIORITY ) .
MR-Fusion Controllers include all cards with the
Device IDs -
-0x005B,
+0x005B,
0x005D,
0x005F.
.Pp
The
-.Xr mfi 4
+.Xr mfi 4
driver will set a priority of either
.Dv BUS_PROBE_DEFAULT
or
@@ -254,13 +254,13 @@ for the
.Nm
driver to detect a MR-Fusion card instead of the
.Xr mfi 4
-driver.
+driver.
.Bd -ragged -offset indent
.Cd hw.mfi.mrsas_enable="1"
.Ed
.Pp
At boot time, the
-.Xr mfi 4
+.Xr mfi 4
driver will get priority to detect MR-Fusion controllers by default.
Before
changing this default driver selection policy, LSI advises users to understand
@@ -273,9 +273,9 @@ driver to detect MR-Fusion cards, but allow for the ability to choose the
driver to detect MR-Fusion cards.
.Pp
LSI recommends setting hw.mfi.mrsas_enable="0" for customers who are using the
-older
-.Xr mfi 4
-driver and do not want to switch to
+older
+.Xr mfi 4
+driver and do not want to switch to
.Nm .
For those customers who are using a MR-Fusion controller for the first time, LSI
recommends using the
@@ -286,8 +286,8 @@ Changing the default behavior is well tested under most conditions, but
unexpected behavior may pop up if more complex and unrealistic operations are
executed by switching between the
.Xr mfi 4
-and
-.Nm
+and
+.Nm
drivers for MR-Fusion.
Switching drivers is designed to happen only one time.
Although multiple
@@ -296,16 +296,16 @@ The user should decide from
.Nm Start of Day
which driver they want to use for the MR-Fusion card.
.Pp
-The user may see different device names when switching from
-.Xr mfi 4
-to
+The user may see different device names when switching from
+.Xr mfi 4
+to
.Nm .
This behavior is
.Nm Functions As Designed
and the user needs to change the
.Xr fstab 5
-entry manually if they are doing any experiments with
-.Xr mfi 4
+entry manually if they are doing any experiments with
+.Xr mfi 4
and
.Nm
interoperability.
@@ -342,7 +342,7 @@ is the new driver reworked by LSI which supports Thunderbolt and onward
products.
The SAS+SATA RAID controller with device id 0x005b is referred to as
the Thunderbolt controller throughout this man page.
-.Ed
+.Ed
.Bd -ragged
.Nm cam aware HBA drivers:
.Fx
@@ -351,12 +351,12 @@ has a
layer which attaches storage devices and provides a common access mechanism to
storage controllers and attached devices.
The
-.Nm
+.Nm
driver is
.Xr cam 4
-aware and devices associated with
-.Nm
-can be seen using
+aware and devices associated with
+.Nm
+can be seen using
.Xr camcontrol 8 .
The
.Xr mfi 4
@@ -364,13 +364,13 @@ driver does not understand the
.Xr cam 4
layer and it directly associates storage disks to the block layer.
.Pp
-.Nm Thunderbolt Controller:
+.Nm Thunderbolt Controller:
This is the 6Gb/s MegaRAID HBA card which has device id 0x005B.
.Pp
-.Nm Invader Controller:
+.Nm Invader Controller:
This is 12Gb/s MegaRAID HBA card which has device id 0x005D.
.Pp
-.Nm Fury Controller:
+.Nm Fury Controller:
This is the 12Gb/s MegaRAID HBA card which has device id 0x005F.
.Ed
.Sh AUTHORS
@@ -387,11 +387,11 @@ switches between two drivers and does not want to edit
manually).
.Pp
The
-.Nm
+.Nm
driver exposes devices as
.Pa /dev/da? ,
-whereas
-.Xr mfi 4
+whereas
+.Xr mfi 4
exposes devices as
.Pa /dev/mfid? .
.Pp
diff --git a/share/man/man4/multicast.4 b/share/man/man4/multicast.4
index 81d6c77..2a22e57 100644
--- a/share/man/man4/multicast.4
+++ b/share/man/man4/multicast.4
@@ -945,16 +945,16 @@ signal, but the next upcall will be triggered no earlier than
after the previous upcall.
.\"
.Sh SEE ALSO
-.Xr altq 4 ,
-.Xr dummynet 4 ,
.Xr getsockopt 2 ,
-.Xr gif 4 ,
-.Xr gre 4 ,
.Xr recvfrom 2 ,
.Xr recvmsg 2 ,
.Xr setsockopt 2 ,
.Xr socket 2 ,
.Xr sourcefilter 3 ,
+.Xr altq 4 ,
+.Xr dummynet 4 ,
+.Xr gif 4 ,
+.Xr gre 4 ,
.Xr icmp6 4 ,
.Xr igmp 4 ,
.Xr inet 4 ,
diff --git a/share/man/man4/net80211.4 b/share/man/man4/net80211.4
index 3773b98..650bbf4 100644
--- a/share/man/man4/net80211.4
+++ b/share/man/man4/net80211.4
@@ -1313,6 +1313,6 @@ Set whether or not Wi-FI Protected Setup (WPS) is enabled using the value in
.Xr wlan 4 ,
.Xr wlan_acl 4 ,
.Xr wlan_xauth 4 ,
-.Xr ifconfig 8 ,
.Xr hostapd 8 ,
-.Xr wpa_supplicant 8 .
+.Xr ifconfig 8 ,
+.Xr wpa_supplicant 8
diff --git a/share/man/man4/netmap.4 b/share/man/man4/netmap.4
index 9d98561..d051620 100644
--- a/share/man/man4/netmap.4
+++ b/share/man/man4/netmap.4
@@ -104,7 +104,6 @@ various aspects of the
and
.Nm VALE
architecture, features and usage.
-.Pp
.Sh ARCHITECTURE
.Nm
supports raw packet I/O through a
@@ -141,11 +140,10 @@ and
ports
by default use separate memory regions,
but can be independently configured to share memory.
-.Pp
.Sh ENTERING AND EXITING NETMAP MODE
The following section describes the system calls to create
and control
-.Nm netmap
+.Nm netmap
ports (including
.Nm VALE
and
@@ -210,7 +208,6 @@ A
on the file descriptor removes the binding,
and returns the NIC to normal mode (reconnecting the data path
to the host stack), or destroys the virtual port.
-.Pp
.Sh DATA STRUCTURES
The data structures in the mmapped memory region are detailed in
.Xr sys/net/netmap.h ,
@@ -246,7 +243,6 @@ contains the index of the first of these free rings,
which are connected in a list (the first uint32_t of each
buffer being the index of the next buffer in the list).
A 0 indicates the end of the list.
-.Pp
.It Dv struct netmap_ring (one per ring)
.Bd -literal
struct netmap_ring {
@@ -269,7 +265,6 @@ Implements transmit and receive rings, with read/write
pointers, metadata and and an array of
.Pa slots
describing the buffers.
-.Pp
.It Dv struct netmap_slot (one per buffer)
.Bd -literal
struct netmap_slot {
@@ -370,7 +365,6 @@ are pushed to the port, and
.Va tail
may advance if further slots have become available.
Below is an example of the evolution of a TX ring:
-.Pp
.Bd -literal
after the syscall, slots between cur and tail are (a)vailable
head=cur tail
@@ -403,7 +397,6 @@ A transmit ring with pending transmissions has
The function
.Va int nm_tx_pending(ring)
implements this test.
-.Pp
.Ss RECEIVE RINGS
On receive rings, after a
.Nm
@@ -447,7 +440,6 @@ Below is an example of the evolution of an RX ring:
v v v
RX [.......hhhRRRRRRRRRRRR....]
.Ed
-.Pp
.Sh SLOTS AND PACKET BUFFERS
Normally, packets should be stored in the netmap-allocated buffers
assigned to slots when ports are bound to a file descriptor.
@@ -460,7 +452,6 @@ it MUST be used when the buf_idx in the slot is changed.
This can be used to implement
zero-copy forwarding, see
.Sx ZERO-COPY FORWARDING .
-.Pp
.It NS_REPORT
reports when this buffer has been transmitted.
Normally,
@@ -538,7 +529,6 @@ A file descriptor obtained through
.Pa /dev/netmap
also supports the ioctl supported by network devices, see
.Xr netintro 4 .
-.Pp
.Bl -tag -width XXXX
.It Dv NIOCGINFO
returns EINVAL if the named port does not support netmap.
@@ -546,7 +536,6 @@ Otherwise, it returns 0 and (advisory) information
about the port.
Note that all the information below can change before the
interface is actually put in netmap mode.
-.Pp
.Bl -tag -width XX
.It Pa nr_memsize
indicates the size of the
@@ -608,7 +597,6 @@ that application libraries (such as the
.Nm nm_open
indicated below) can use to indicate the specific set of rings.
In the example below, "netmap:foo" is any valid netmap port name.
-.Pp
.Bl -tag -width XXXXX
.It NR_REG_ALL_NIC "netmap:foo"
(default) all hardware ring pairs
@@ -749,7 +737,6 @@ of the packet is successful, or 0 on error;
similar to pcap_dispatch(), applies a callback to incoming packets
.It Va u_char * nm_nextpkt(struct nm_desc *d, struct nm_pkthdr *hdr)
similar to pcap_next(), fetches the next packet
-.Pp
.El
.Sh SUPPORTED DEVICES
.Nm
@@ -790,7 +777,6 @@ are controlled through sysctl variables on FreeBSD
.Em ( dev.netmap.* )
and module parameters on Linux
.Em ( /sys/module/netmap_lin/parameters/* ) :
-.Pp
.Bl -tag -width indent
.It Va dev.netmap.admode: 0
Controls the use of native or emulated adapter mode.
@@ -858,42 +844,6 @@ OS primitives, see
In particular,
.Xr pthread_setaffinity_np 3
may be of use.
-.Sh CAVEATS
-No matter how fast the CPU and OS are,
-achieving line rate on 10G and faster interfaces
-requires hardware with sufficient performance.
-Several NICs are unable to sustain line rate with
-small packet sizes. Insufficient PCIe or memory bandwidth
-can also cause reduced performance.
-.Pp
-Another frequent reason for low performance is the use
-of flow control on the link: a slow receiver can limit
-the transmit speed.
-Be sure to disable flow control when running high
-speed experiments.
-.Pp
-.Ss SPECIAL NIC FEATURES
-.Nm
-is orthogonal to some NIC features such as
-multiqueue, schedulers, packet filters.
-.Pp
-Multiple transmit and receive rings are supported natively
-and can be configured with ordinary OS tools,
-such as
-.Xr ethtool
-or
-device-specific sysctl variables.
-The same goes for Receive Packet Steering (RPS)
-and filtering of incoming traffic.
-.Pp
-.Nm
-.Em does not use
-features such as
-.Em checksum offloading , TCP segmentation offloading ,
-.Em encryption , VLAN encapsulation/decapsulation ,
-etc. .
-When using netmap to exchange packets with the host stack,
-make sure to disable these features.
.Sh EXAMPLES
.Ss TEST PROGRAMS
.Nm
@@ -935,7 +885,7 @@ The following code implements a traffic generator
.Pp
.Bd -literal -compact
#include <net/netmap_user.h>
-...
+\&...
void sender(void)
{
struct netmap_if *nifp;
@@ -970,7 +920,7 @@ A simple receiver can be implemented using the helper functions
.Bd -literal -compact
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
-...
+\&...
void receiver(void)
{
struct nm_desc *d;
@@ -1037,10 +987,8 @@ Other
.Nm
clients attached to the same switch can now communicate
with the network card or the host.
-.Pp
.Sh SEE ALSO
-.Pp
-http://info.iet.unipi.it/~luigi/netmap/
+.Pa http://info.iet.unipi.it/~luigi/netmap/
.Pp
Luigi Rizzo, Revisiting network I/O APIs: the netmap framework,
Communications of the ACM, 55 (3), pp.45-51, March 2012
@@ -1073,3 +1021,39 @@ and
.Nm VALE
have been funded by the European Commission within FP7 Projects
CHANGE (257422) and OPENLAB (287581).
+.Sh CAVEATS
+No matter how fast the CPU and OS are,
+achieving line rate on 10G and faster interfaces
+requires hardware with sufficient performance.
+Several NICs are unable to sustain line rate with
+small packet sizes. Insufficient PCIe or memory bandwidth
+can also cause reduced performance.
+.Pp
+Another frequent reason for low performance is the use
+of flow control on the link: a slow receiver can limit
+the transmit speed.
+Be sure to disable flow control when running high
+speed experiments.
+.Pp
+.Ss SPECIAL NIC FEATURES
+.Nm
+is orthogonal to some NIC features such as
+multiqueue, schedulers, packet filters.
+.Pp
+Multiple transmit and receive rings are supported natively
+and can be configured with ordinary OS tools,
+such as
+.Xr ethtool
+or
+device-specific sysctl variables.
+The same goes for Receive Packet Steering (RPS)
+and filtering of incoming traffic.
+.Pp
+.Nm
+.Em does not use
+features such as
+.Em checksum offloading , TCP segmentation offloading ,
+.Em encryption , VLAN encapsulation/decapsulation ,
+etc. .
+When using netmap to exchange packets with the host stack,
+make sure to disable these features.
diff --git a/share/man/man4/nfe.4 b/share/man/man4/nfe.4
index 2934211..b9f91a2 100644
--- a/share/man/man4/nfe.4
+++ b/share/man/man4/nfe.4
@@ -175,8 +175,8 @@ before a change takes effect.
.Xr pci 4 ,
.Xr polling 4 ,
.Xr rgephy 4 ,
-.Xr sysctl 8 ,
-.Xr ifconfig 8
+.Xr ifconfig 8 ,
+.Xr sysctl 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/ng_ether_echo.4 b/share/man/man4/ng_ether_echo.4
index e86c3a9..a62c553 100644
--- a/share/man/man4/ng_ether_echo.4
+++ b/share/man/man4/ng_ether_echo.4
@@ -64,9 +64,9 @@ This node shuts down upon receipt of a
control message, or when all hooks have been disconnected.
.Sh SEE ALSO
.Xr netgraph 4 ,
-.Xr ng_hole 4 ,
.Xr ng_echo 4 ,
.Xr ng_ether 4 ,
+.Xr ng_hole 4 ,
.Xr ngctl 8
.Sh HISTORY
The
diff --git a/share/man/man4/ng_netflow.4 b/share/man/man4/ng_netflow.4
index fb7e1fa..889c88a 100644
--- a/share/man/man4/ng_netflow.4
+++ b/share/man/man4/ng_netflow.4
@@ -315,8 +315,8 @@ we do not use tee, but send packets back to either node.
SEQ
.Ed
.Sh SEE ALSO
-.Xr netgraph 4 ,
.Xr setfib 2 ,
+.Xr netgraph 4 ,
.Xr ng_ether 4 ,
.Xr ng_iface 4 ,
.Xr ng_ksocket 4 ,
diff --git a/share/man/man4/nvram2env.4 b/share/man/man4/nvram2env.4
index b9b0311..3678160 100644
--- a/share/man/man4/nvram2env.4
+++ b/share/man/man4/nvram2env.4
@@ -107,7 +107,7 @@ hint.nvram.1.base=0x1cff8000
.Ed
.Sh SEE ALSO
.Xr kenv 1 ,
-.Xr kenv 2 .
+.Xr kenv 2
.Sh HISTORY
.Nm
first appeared in
diff --git a/share/man/man4/ohci.4 b/share/man/man4/ohci.4
index b89eeb7..f68afc1 100644
--- a/share/man/man4/ohci.4
+++ b/share/man/man4/ohci.4
@@ -60,9 +60,9 @@ NVIDIA nForce3
Sun PCIO-2 (RIO USB)
.El
.Sh SEE ALSO
-.Xr xhci 4 ,
.Xr ehci 4 ,
-.Xr uhci 4
+.Xr uhci 4 ,
+.Xr xhci 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/pass.4 b/share/man/man4/pass.4
index 7280de1..6b4fb1e 100644
--- a/share/man/man4/pass.4
+++ b/share/man/man4/pass.4
@@ -104,8 +104,8 @@ CAM subsystem.
None.
.Sh SEE ALSO
.Xr cam 3 ,
-.Xr cam 4 ,
.Xr cam_cdbparse 3 ,
+.Xr cam 4 ,
.Xr xpt 4 ,
.Xr camcontrol 8
.Sh HISTORY
diff --git a/share/man/man4/pccbb.4 b/share/man/man4/pccbb.4
index d8d955e..6018bec 100644
--- a/share/man/man4/pccbb.4
+++ b/share/man/man4/pccbb.4
@@ -179,5 +179,5 @@ debugging problems with the bridge chipset.
.El
.Sh SEE ALSO
.Xr cardbus 4 ,
-.Xr pccard 4 ,
-.Xr exca 4
+.Xr exca 4 ,
+.Xr pccard 4
diff --git a/share/man/man4/pcii.4 b/share/man/man4/pcii.4
deleted file mode 100644
index 3369d3f..0000000
--- a/share/man/man4/pcii.4
+++ /dev/null
@@ -1,97 +0,0 @@
-.\" Copyright (c) 2010, Joerg Wunsch
-.\" 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$
-.\"
-.Dd January 24, 2010
-.Dt PCII 4
-.Os
-.Sh NAME
-.Nm pcii
-.Nd National Instruments PCIIA GPIB controller driver
-.Sh SYNOPSIS
-.Cd "device pcii"
-.Pp
-In
-.Pa /boot/device.hints :
-.Cd hint.pcii.0.at="isa"
-.Cd hint.pcii.0.port="0x2e1"
-.Cd hint.pcii.0.irq="7"
-.Cd hint.pcii.0.drq="1"
-.Sh DESCRIPTION
-The
-.Nm
-driver provides support for driving an IEEE-488 bus, also called
-IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
-Bus), or GPIB (General Purpose Instrument Bus).
-The driver supports National Instruments PCIIA cards (sometimes
-also referred to as PC2A) and compatibles.
-These cards use a NEC \(mcPD7210 controller IC as the main
-interface between the host computer and the instrument bus.
-.Ss IO memory space layout
-The PCIIA cards use a very specific IO memory space allocation layout.
-The address bits A0 through A9 (which have traditionally been the only
-address bits evaluated on IBM PC XT extension cards) are hardwired to
-address 0x2e1.
-Bits A10 through A12 are used by the \(mcPD7210 register select lines.
-This makes the individual 7210 registers being 0x400 bytes apart in the
-ISA bus address space.
-Address bits A13 and A14 are compared to a DIP switch setting on the
-card, allowing for up to 4 different cards being installed (at base
-addresses 0x2e1, 0x22e1, 0x42e1, and 0x62e1, respectively).
-A15 has been used to select an optional on-board time-of-day clock
-chip (MM58167A) on the original PCIIA rather than the \(mcPD7210
-(which is not implemented on later boards and clones).
-Finally, the IO addresses 0x2f0 ... 0x2f7 are used for a
-.Em special interrupt handling feature
-(re-enable interrupts so the IRQ can be shared), where actually only
-address 0x2f0 plus the actual IRQ level is required for each card.
-Some clones do not appear to require this special IRQ handling, and
-are thus likely to not support the shared IRQ feature.
-.Pp
-Only the base address of the card needs to be specified in the ISA
-device hints; the driver takes care to derive all other IO addresses
-needed during the probe phase.
-.Ss Supported cards
-The following cards are known to be supported:
-.Bl -bullet -offset indent
-.It
-B&C Microsystems PC488A-0
-.It
-National Instruments GPIB-PCII/PCIIA (in PCIIa mode)
-.It
-Axiom AX5488
-.El
-.Sh SEE ALSO
-.Xr gpib 3 ,
-.Xr gpib 4 ,
-.Xr device.hints 5
-.Sh HISTORY
-The
-.Nm
-driver was written by Poul-Henning Kamp, and first appeared in
-.Fx 5.4 .
-.Sh AUTHORS
-This manual page was written by
-.An J\(:org Wunsch .
diff --git a/share/man/man4/pflog.4 b/share/man/man4/pflog.4
index c1039a3..428bb5b 100644
--- a/share/man/man4/pflog.4
+++ b/share/man/man4/pflog.4
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 31 2007
+.Dd May 31, 2007
.Dt PFLOG 4
.Os
.Sh NAME
@@ -91,13 +91,13 @@ and monitor all packets logged on it:
# tcpdump -n -e -ttt -i pflog1
.Ed
.Sh SEE ALSO
+.Xr tcpdump 1 ,
.Xr inet 4 ,
.Xr inet6 4 ,
.Xr netintro 4 ,
.Xr pf 4 ,
.Xr ifconfig 8 ,
-.Xr pflogd 8 ,
-.Xr tcpdump 1
+.Xr pflogd 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/pfsync.4 b/share/man/man4/pfsync.4
index b00bf9d..c4c366f 100644
--- a/share/man/man4/pfsync.4
+++ b/share/man/man4/pfsync.4
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 20 2011
+.Dd December 20, 2011
.Dt PFSYNC 4
.Os
.Sh NAME
@@ -200,6 +200,7 @@ The following must also be added to
net.inet.carp.preempt=1
.Ed
.Sh SEE ALSO
+.Xr tcpdump 1 ,
.Xr bpf 4 ,
.Xr carp 4 ,
.Xr enc 4 ,
@@ -211,8 +212,7 @@ net.inet.carp.preempt=1
.Xr pf.conf 5 ,
.Xr protocols 5 ,
.Xr rc.conf 5 ,
-.Xr ifconfig 8 ,
-.Xr tcpdump 1
+.Xr ifconfig 8
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/pts.4 b/share/man/man4/pts.4
index e9aaaaa..c142c50 100644
--- a/share/man/man4/pts.4
+++ b/share/man/man4/pts.4
@@ -142,8 +142,8 @@ Pseudo-terminal slave devices.
.Sh DIAGNOSTICS
None.
.Sh SEE ALSO
-.Xr grantpt 3 ,
.Xr posix_openpt 2 ,
+.Xr grantpt 3 ,
.Xr ptsname 3 ,
.Xr pty 4 ,
.Xr tty 4
diff --git a/share/man/man4/ral.4 b/share/man/man4/ral.4
index c99902a..d9024b0 100644
--- a/share/man/man4/ral.4
+++ b/share/man/man4/ral.4
@@ -240,8 +240,8 @@ The driver will reset the hardware.
This should not happen.
.El
.Sh SEE ALSO
-.Xr intro 4 ,
.Xr cardbus 4 ,
+.Xr intro 4 ,
.Xr wlan 4 ,
.Xr wlan_ccmp 4 ,
.Xr wlan_tkip 4 ,
diff --git a/share/man/man4/rsu.4 b/share/man/man4/rsu.4
index 9d2854c..f9a8c9e 100644
--- a/share/man/man4/rsu.4
+++ b/share/man/man4/rsu.4
@@ -153,9 +153,9 @@ This should not happen.
.El
.Sh SEE ALSO
.Xr intro 1 ,
-.Xr usb 4 ,
.Xr netintro 4 ,
.Xr rsufw 4 ,
+.Xr usb 4 ,
.Xr wlan 4 ,
.Xr arp 8 ,
.Xr hostapd 8 ,
diff --git a/share/man/man4/rum.4 b/share/man/man4/rum.4
index 3abcbca..89af445 100644
--- a/share/man/man4/rum.4
+++ b/share/man/man4/rum.4
@@ -162,8 +162,8 @@ This should not happen.
.Xr wlan_tkip 4 ,
.Xr wlan_wep 4 ,
.Xr wlan_xauth 4 ,
-.Xr ifconfig 8 ,
.Xr hostapd 8 ,
+.Xr ifconfig 8 ,
.Xr wpa_supplicant 8 .
.Rs
.%T "Ralink Technology"
diff --git a/share/man/man4/run.4 b/share/man/man4/run.4
index 52ce544..8a2b6bc 100644
--- a/share/man/man4/run.4
+++ b/share/man/man4/run.4
@@ -219,9 +219,9 @@ The driver will reset the hardware.
This should not happen.
.El
.Sh SEE ALSO
-.Xr runfw 4 ,
.Xr intro 4 ,
.Xr netintro 4 ,
+.Xr runfw 4 ,
.Xr usb 4 ,
.Xr wlan 4 ,
.Xr wlan_amrr 4 ,
@@ -229,8 +229,8 @@ This should not happen.
.Xr wlan_tkip 4 ,
.Xr wlan_wep 4 ,
.Xr wlan_xauth 4 ,
-.Xr ifconfig 8 ,
.Xr hostapd 8 ,
+.Xr ifconfig 8 ,
.Xr wpa_supplicant 8
.Pp
Ralink Technology:
diff --git a/share/man/man4/sa.4 b/share/man/man4/sa.4
index aa72f68..f5984aa 100644
--- a/share/man/man4/sa.4
+++ b/share/man/man4/sa.4
@@ -264,8 +264,8 @@ accessing the device, e.g.).
.Sh DIAGNOSTICS
None.
.Sh SEE ALSO
-.Xr cam 4 ,
-.Xr mt 1
+.Xr mt 1 ,
+.Xr cam 4
.Sh AUTHORS
.An -nosplit
The
diff --git a/share/man/man4/send.4 b/share/man/man4/send.4
index 4af510a..e69e6e3 100644
--- a/share/man/man4/send.4
+++ b/share/man/man4/send.4
@@ -196,9 +196,9 @@ Occurs if interface output routines fail to send the packet out of the
interface.
.El
.Sh SEE ALSO
-.Xr recvfrom 2
-.Xr sendto 2
-.Xr socket 2
+.Xr recvfrom 2 ,
+.Xr sendto 2 ,
+.Xr socket 2 ,
.Xr loader.conf 5
.Sh HISTORY
The
diff --git a/share/man/man4/sfxge.4 b/share/man/man4/sfxge.4
index 7930fcf..e6fe6a4 100644
--- a/share/man/man4/sfxge.4
+++ b/share/man/man4/sfxge.4
@@ -114,11 +114,11 @@ For general information and support,
go to the Solarflare support website at:
.Pa https://support.solarflare.com .
.Sh SEE ALSO
+.Xr cpuset 1 ,
.Xr arp 4 ,
.Xr netintro 4 ,
.Xr ng_ether 4 ,
.Xr vlan 4 ,
-.Xr cpuset 1 ,
.Xr ifconfig 8
.Sh AUTHORS
The
diff --git a/share/man/man4/snd_hda.4 b/share/man/man4/snd_hda.4
index cdb2a62..40a8862 100644
--- a/share/man/man4/snd_hda.4
+++ b/share/man/man4/snd_hda.4
@@ -590,8 +590,8 @@ driver supports more than two hundred different controllers and CODECs.
There is no sense to list all of them here, as in most cases specific CODEC
configuration and wiring are more important then type of the CODEC itself.
.Sh SEE ALSO
-.Xr sound 4 ,
.Xr snd_ich 4 ,
+.Xr sound 4 ,
.Xr device.hints 5 ,
.Xr loader.conf 5 ,
.Xr sysctl 8
diff --git a/share/man/man4/snd_ich.4 b/share/man/man4/snd_ich.4
index 528d28c..b03a0fd 100644
--- a/share/man/man4/snd_ich.4
+++ b/share/man/man4/snd_ich.4
@@ -99,8 +99,8 @@ NVIDIA nForce4
SiS 7012
.El
.Sh SEE ALSO
-.Xr sound 4 ,
-.Xr snd_hda 4
+.Xr snd_hda 4 ,
+.Xr sound 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/tap.4 b/share/man/man4/tap.4
index 229de60..6e42996 100644
--- a/share/man/man4/tap.4
+++ b/share/man/man4/tap.4
@@ -34,7 +34,7 @@ or a terminal for
and a character-special device
.Dq control
interface.
-A client program transfers Ethernet frames to or from the
+A client program transfers Ethernet frames to or from the
.Nm
.Dq control
interface.
diff --git a/share/man/man4/tnt4882.4 b/share/man/man4/tnt4882.4
deleted file mode 100644
index e3eacbb..0000000
--- a/share/man/man4/tnt4882.4
+++ /dev/null
@@ -1,55 +0,0 @@
-.\" Copyright (c) 2010, Joerg Wunsch
-.\" 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$
-.\"
-.Dd January 24, 2010
-.Dt TNT4882 4
-.Os
-.Sh NAME
-.Nm tnt4882
-.Nd National Instruments TNT4882A GPIB controller driver
-.Sh SYNOPSIS
-.Cd "device tnt4882"
-.Sh DESCRIPTION
-The
-.Nm
-driver provides support for driving an IEEE-488 bus, also called
-IEC-625 (or just "IEC bus"), or HP-IB (Hewlett Packard Instrument
-Bus), or GPIB (General Purpose Instrument Bus).
-The driver supports National Instruments PCI GPIB cards using
-the TNT4882 bus interface chip.
-This chip emulates a NEC \(mcPD7210 controller IC as the main
-interface between the host computer and the instrument bus.
-.Sh SEE ALSO
-.Xr gpib 3 ,
-.Xr gpib 4
-.Sh HISTORY
-The
-.Nm
-driver was written by Poul-Henning Kamp, and first appeared in
-.Fx 5.4 .
-.Sh AUTHORS
-This manual page was written by
-.An J\(:org Wunsch .
diff --git a/share/man/man4/tun.4 b/share/man/man4/tun.4
index 0b88b72..9a21711 100644
--- a/share/man/man4/tun.4
+++ b/share/man/man4/tun.4
@@ -35,7 +35,7 @@ or a terminal for
and a character-special device
.Dq control
interface.
-A client program transfers IP (by default) packets to or from the
+A client program transfers IP (by default) packets to or from the
.Nm
.Dq control
interface.
diff --git a/share/man/man4/uhci.4 b/share/man/man4/uhci.4
index 9fcd4d4..90458ce 100644
--- a/share/man/man4/uhci.4
+++ b/share/man/man4/uhci.4
@@ -50,9 +50,9 @@ Intel 82371SB (PIIX3)
VIA 83C572
.El
.Sh SEE ALSO
-.Xr xhci 4 ,
.Xr ehci 4 ,
-.Xr ohci 4
+.Xr ohci 4 ,
+.Xr xhci 4
.Sh HISTORY
The
.Nm
diff --git a/share/man/man4/umass.4 b/share/man/man4/umass.4
index b4c08d7..badb97b 100644
--- a/share/man/man4/umass.4
+++ b/share/man/man4/umass.4
@@ -62,7 +62,7 @@ or
.Xr ohci 4
or
.Xr ehci 4
-or
+or
.Xr xhci 4
must be configured in the kernel.
Additionally, since
@@ -240,11 +240,11 @@ when using
.Xr mount 8 .
.Sh SEE ALSO
.Xr ehci 4 ,
-.Xr xhci 4 ,
.Xr ohci 4 ,
.Xr uhci 4 ,
.Xr usb 4 ,
.Xr vpo 4 ,
+.Xr xhci 4 ,
.Xr disktab 5 ,
.Xr bsdlabel 8 ,
.Xr camcontrol 8
diff --git a/share/man/man4/ural.4 b/share/man/man4/ural.4
index 1563fde..4b412f5 100644
--- a/share/man/man4/ural.4
+++ b/share/man/man4/ural.4
@@ -142,9 +142,9 @@ This should not happen.
.Xr wlan_tkip 4 ,
.Xr wlan_wep 4 ,
.Xr wlan_xauth 4 ,
-.Xr ifconfig 8 ,
.Xr hostapd 8 ,
-.Xr wpa_supplicant 8 .
+.Xr ifconfig 8 ,
+.Xr wpa_supplicant 8
.Rs
.%T "Ralink Technology"
.%U http://www.ralinktech.com/
diff --git a/share/man/man4/usfs.4 b/share/man/man4/usfs.4
index 215d31e..a72a8d8 100644
--- a/share/man/man4/usfs.4
+++ b/share/man/man4/usfs.4
@@ -54,7 +54,7 @@ the USB stack is activated in USB device side mode.
.Pp
Upon attach the driver creates a RAM disk which can be read and written.
.Sh SEE ALSO
-.Xr umass 4
+.Xr umass 4 ,
.Xr usb 4
.Sh HISTORY
The
diff --git a/share/man/man4/virtio_console.4 b/share/man/man4/virtio_console.4
index b855f13..542c845 100644
--- a/share/man/man4/virtio_console.4
+++ b/share/man/man4/virtio_console.4
@@ -58,7 +58,7 @@ each port is accessible through
.It Pa /dev/ttyV?.??
.El
.Sh SEE ALSO
-.Xr tty 4
+.Xr tty 4 ,
.Xr virtio 4
.Sh HISTORY
The
diff --git a/share/man/man4/virtio_random.4 b/share/man/man4/virtio_random.4
index 5ce7d17..d44b08d 100644
--- a/share/man/man4/virtio_random.4
+++ b/share/man/man4/virtio_random.4
@@ -52,7 +52,7 @@ device driver provides support for VirtIO entropy devices.
The entropy device supplies high-quality randomness from the
hypervisor to the guest.
.Sh SEE ALSO
-.Xr random 4
+.Xr random 4 ,
.Xr virtio 4
.Sh HISTORY
The
diff --git a/share/man/man4/vxlan.4 b/share/man/man4/vxlan.4
index ec95db1..167d5b0 100644
--- a/share/man/man4/vxlan.4
+++ b/share/man/man4/vxlan.4
@@ -215,9 +215,9 @@ Once created, the
interface can be configured with
.Xr ifconfig 8 .
.Sh SEE ALSO
-.Xr ifconfig 8 ,
.Xr inet 4 ,
-.Xr inet 6 ,
+.Xr inet6 4 ,
+.Xr ifconfig 8 ,
.Xr sysctl 8 ,
.Xr vlan 8
.Rs
diff --git a/share/man/man4/wpi.4 b/share/man/man4/wpi.4
index f2d4251..4cf33c4 100644
--- a/share/man/man4/wpi.4
+++ b/share/man/man4/wpi.4
@@ -117,12 +117,12 @@ The hardware switch controlling the radio is currently turned off.
Data transmission is not possible in this state.
.El
.Sh SEE ALSO
-.Xr wpifw 4 ,
.Xr pci 4 ,
.Xr wlan 4 ,
.Xr wlan_ccmp 4 ,
.Xr wlan_tkip 4 ,
.Xr wlan_wep 4 ,
+.Xr wpifw 4 ,
.Xr ifconfig 8 ,
.Xr wpa_supplicant 8
.Sh AUTHORS
diff --git a/share/man/man4/wsp.4 b/share/man/man4/wsp.4
index 24c9b77..32ec798 100644
--- a/share/man/man4/wsp.4
+++ b/share/man/man4/wsp.4
@@ -52,7 +52,7 @@ device found in many Apple laptops.
.Pp
The driver simulates a three-button mouse using multi-finger tap
detection.
-A single-finger press generates a left button click.
+A single-finger press generates a left button click.
A two-finger tap maps to the right button; whereas a three-finger tap
gets treated as a middle button click.
.Pp
diff --git a/share/man/man5/periodic.conf.5 b/share/man/man5/periodic.conf.5
index 83897c1..d5526f9 100644
--- a/share/man/man5/periodic.conf.5
+++ b/share/man/man5/periodic.conf.5
@@ -705,7 +705,7 @@ they will be always run unless their
or
.Va ..._period
variable is set to
-.Dq No .
+.Dq NO .
.Bl -tag -offset 4n -width 2n
.It Va security_status_diff_flags
.Pq Vt str
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
index 4f95933..4ed941c 100644
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -28,7 +28,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 29 2012
+.Dd June 29, 2012
.Dt PF.CONF 5
.Os
.Sh NAME
diff --git a/share/man/man5/pf.os.5 b/share/man/man5/pf.os.5
index 5930525..18c7246 100644
--- a/share/man/man5/pf.os.5
+++ b/share/man/man5/pf.os.5
@@ -16,7 +16,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 31 2007
+.Dd May 31, 2007
.Dt PF.OS 5
.Os
.Sh NAME
@@ -217,7 +217,7 @@ almost translates into the following fingerprint
57344:64:1:44:M1460: exampleOS:1.0::exampleOS 1.0
.Ed
.Sh SEE ALSO
+.Xr tcpdump 1 ,
.Xr pf 4 ,
.Xr pf.conf 5 ,
-.Xr pfctl 8 ,
-.Xr tcpdump 1
+.Xr pfctl 8
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index 09583ec..5c4803f 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -4547,9 +4547,9 @@ ruleset to load for
.Xr rfcomm_pppd 8 ,
.Xr route 8 ,
.Xr routed 8 ,
-.Xr rpcbind 8 ,
.Xr rpc.lockd 8 ,
.Xr rpc.statd 8 ,
+.Xr rpcbind 8 ,
.Xr rwhod 8 ,
.Xr savecore 8 ,
.Xr sdpd 8 ,
diff --git a/share/man/man5/services.5 b/share/man/man5/services.5
index 6469cfc..adda70a 100644
--- a/share/man/man5/services.5
+++ b/share/man/man5/services.5
@@ -91,8 +91,8 @@ file resides in
.Pa /etc .
.El
.Sh SEE ALSO
-.Xr getservent 3
-.Xr nsswitch.conf 5
+.Xr getservent 3 ,
+.Xr nsswitch.conf 5 ,
.Xr services_mkdb 8
.Sh HISTORY
The
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 4232141..1ebeb5c 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1143,7 +1143,7 @@ support files (fonts and keymaps).
Set this to not add warning flags to the compiler invocations.
Useful as a temporary workaround when code enters the tree
which triggers warnings in environments that differ from the
-original develoepr.
+original developer.
.It Va WITHOUT_WIRELESS
.\" from FreeBSD: head/tools/build/options/WITHOUT_WIRELESS 183242 2008-09-21 22:02:26Z sam
Set to not build programs used for 802.11 wireless networks; especially
diff --git a/share/man/man7/c99.7 b/share/man/man7/c99.7
index fcf1476..b968a4e 100644
--- a/share/man/man7/c99.7
+++ b/share/man/man7/c99.7
@@ -142,9 +142,9 @@ Most of the UNIX-like operating systems use GNU C as a system compiler,
but those addition in GNU C should not be considered as
standard features.
.Sh SEE ALSO
-.Xr cc 1 ,
.Xr c89 1 ,
-.Xr c99 1
+.Xr c99 1 ,
+.Xr cc 1
.Sh STANDARDS
.Rs
.%A ANSI
diff --git a/share/man/man7/environ.7 b/share/man/man7/environ.7
index 8269488..2870d8e 100644
--- a/share/man/man7/environ.7
+++ b/share/man/man7/environ.7
@@ -250,8 +250,8 @@ built-in command in
.Xr sh 1 ,
.Xr execve 2 ,
.Xr execle 3 ,
-.Xr getenv 3 ,
.Xr getbsize 3 ,
+.Xr getenv 3 ,
.Xr setenv 3 ,
.Xr setlocale 3 ,
.Xr system 3 ,
diff --git a/share/man/man7/tuning.7 b/share/man/man7/tuning.7
index baf0bcc..12b03c2 100644
--- a/share/man/man7/tuning.7
+++ b/share/man/man7/tuning.7
@@ -747,8 +747,8 @@ over services you export from your box (web services, email).
.Xr login.conf 5 ,
.Xr rc.conf 5 ,
.Xr sysctl.conf 5 ,
-.Xr firewall 7 ,
.Xr eventtimers 7 ,
+.Xr firewall 7 ,
.Xr hier 7 ,
.Xr ports 7 ,
.Xr boot 8 ,
diff --git a/share/man/man8/rc.8 b/share/man/man8/rc.8
index ff0aa84..5d296cd 100644
--- a/share/man/man8/rc.8
+++ b/share/man/man8/rc.8
@@ -550,8 +550,8 @@ is unnecessary, but is often included.
.Xr kill 1 ,
.Xr rc.conf 5 ,
.Xr init 8 ,
-.Xr rcorder 8 ,
.Xr rc.subr 8 ,
+.Xr rcorder 8 ,
.Xr reboot 8 ,
.Xr savecore 8
.Sh HISTORY
diff --git a/share/man/man9/BUF_ISLOCKED.9 b/share/man/man9/BUF_ISLOCKED.9
index 2471db9..8616ff5 100644
--- a/share/man/man9/BUF_ISLOCKED.9
+++ b/share/man/man9/BUF_ISLOCKED.9
@@ -59,11 +59,11 @@ A shared lock is held.
The lock is not held by anyone.
.El
.Sh SEE ALSO
-.Xr lockstatus 9 ,
.Xr buf 9 ,
.Xr BUF_LOCK 9 ,
.Xr BUF_UNLOCK 9 ,
-.Xr lockmgr 9
+.Xr lockmgr 9 ,
+.Xr lockstatus 9
.Sh AUTHORS
This manual page was written by
.An Attilio Rao Aq Mt attilio@FreeBSD.org .
diff --git a/share/man/man9/BUS_BIND_INTR.9 b/share/man/man9/BUS_BIND_INTR.9
index 2e22dea..1c97897 100644
--- a/share/man/man9/BUS_BIND_INTR.9
+++ b/share/man/man9/BUS_BIND_INTR.9
@@ -86,8 +86,8 @@ The most recent binding request is the one that will be in effect.
.Sh RETURN VALUES
Zero is returned on success, otherwise an appropriate error is returned.
.Sh SEE ALSO
-.Xr BUS_SETUP_INTR 9 ,
.Xr cpuset 2 ,
+.Xr BUS_SETUP_INTR 9 ,
.Xr device 9
.Sh HISTORY
The
diff --git a/share/man/man9/BUS_DESCRIBE_INTR.9 b/share/man/man9/BUS_DESCRIBE_INTR.9
index b7f137b..1000455 100644
--- a/share/man/man9/BUS_DESCRIBE_INTR.9
+++ b/share/man/man9/BUS_DESCRIBE_INTR.9
@@ -87,9 +87,9 @@ the interrupt handler name.
.Sh RETURN VALUES
Zero is returned on success, otherwise an appropriate error is returned.
.Sh SEE ALSO
-.Xr BUS_SETUP_INTR 9 ,
.Xr systat 1 ,
.Xr vmstat 8 ,
+.Xr BUS_SETUP_INTR 9 ,
.Xr device 9 ,
.Xr printf 9
.Sh HISTORY
diff --git a/share/man/man9/DB_COMMAND.9 b/share/man/man9/DB_COMMAND.9
index bf3faea..34d7b50 100644
--- a/share/man/man9/DB_COMMAND.9
+++ b/share/man/man9/DB_COMMAND.9
@@ -68,7 +68,7 @@ command, respectively.
.Pp
The general command syntax:
.Cm command Ns Op Li \&/ Ns Ar modifier
-.Ar address Ns Op Li , Ns Ar count ,
+.Ar address Ns Op , Ns Ar count ,
translates into the following parameters for
.Fa command_function :
.Bl -tag -width Fa -offset indent
diff --git a/share/man/man9/EVENTHANDLER.9 b/share/man/man9/EVENTHANDLER.9
index 711c6ef..c8f3002 100644
--- a/share/man/man9/EVENTHANDLER.9
+++ b/share/man/man9/EVENTHANDLER.9
@@ -261,7 +261,7 @@ operation.
Callbacks invoked when a process exits.
.It Vt process_fini
Callback invoked when a process memory is destroyed.
-This is never called.
+This is never called.
.It Vt process_fork
Callbacks invoked when a process forks a child.
.It Vt process_init
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
index 195613f..cf64df7 100644
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -1080,6 +1080,8 @@ MLINKS+=microuptime.9 binuptime.9 \
microuptime.9 sbinuptime.9
MLINKS+=mi_switch.9 cpu_switch.9 \
mi_switch.9 cpu_throw.9
+MLINKS+=mod_cc.9 CCV.9 \
+ mod_cc.9 DECLARE_CC_MODULE.9
MLINKS+=mtx_pool.9 mtx_pool_alloc.9 \
mtx_pool.9 mtx_pool_create.9 \
mtx_pool.9 mtx_pool_destroy.9 \
diff --git a/share/man/man9/VFS.9 b/share/man/man9/VFS.9
index cf5189e..86852ce 100644
--- a/share/man/man9/VFS.9
+++ b/share/man/man9/VFS.9
@@ -54,8 +54,8 @@ rather than implementing empty functions or casting to
.Xr VFS_SYNC 9 ,
.Xr VFS_UNMOUNT 9 ,
.Xr VFS_VGET 9 ,
-.Xr VOP_VPTOFH 9 ,
-.Xr vnode 9
+.Xr vnode 9 ,
+.Xr VOP_VPTOFH 9
.Sh AUTHORS
This manual page was written by
.An Doug Rabson .
diff --git a/share/man/man9/VFS_CHECKEXP.9 b/share/man/man9/VFS_CHECKEXP.9
index 62d545c..42aeeb6 100644
--- a/share/man/man9/VFS_CHECKEXP.9
+++ b/share/man/man9/VFS_CHECKEXP.9
@@ -81,8 +81,8 @@ and
.Sh SEE ALSO
.Xr VFS 9 ,
.Xr VFS_FHTOVP 9 ,
-.Xr VOP_VPTOFH 9 ,
-.Xr vnode 9
+.Xr vnode 9 ,
+.Xr VOP_VPTOFH 9
.Sh AUTHORS
This manual page was written by
.An Alfred Perlstein .
diff --git a/share/man/man9/VFS_FHTOVP.9 b/share/man/man9/VFS_FHTOVP.9
index 39a6168..cdc03e1 100644
--- a/share/man/man9/VFS_FHTOVP.9
+++ b/share/man/man9/VFS_FHTOVP.9
@@ -76,8 +76,8 @@ The locked vnode for the file will be returned in
.Sh SEE ALSO
.Xr VFS 9 ,
.Xr VFS_CHECKEXP 9 ,
-.Xr VOP_VPTOFH 9 ,
-.Xr vnode 9
+.Xr vnode 9 ,
+.Xr VOP_VPTOFH 9
.Sh AUTHORS
This manual page was written by
.An Doug Rabson .
diff --git a/share/man/man9/VFS_SET.9 b/share/man/man9/VFS_SET.9
index c35935e..e0388fd 100644
--- a/share/man/man9/VFS_SET.9
+++ b/share/man/man9/VFS_SET.9
@@ -104,8 +104,8 @@ VFS_SET(myfs_vfsops, myfs, 0);
.Xr jail 2 ,
.Xr jail 8 ,
.Xr DECLARE_MODULE 9 ,
-.Xr vfsconf 9 ,
-.Xr vfs_modevent 9
+.Xr vfs_modevent 9 ,
+.Xr vfsconf 9
.Sh AUTHORS
This manual page was written by
.An Chad David Aq Mt davidc@acns.ab.ca .
diff --git a/share/man/man9/VOP_LOCK.9 b/share/man/man9/VOP_LOCK.9
index b4fdc7a..db46080 100644
--- a/share/man/man9/VOP_LOCK.9
+++ b/share/man/man9/VOP_LOCK.9
@@ -100,8 +100,9 @@ with these control flags:
.Bl -tag -width ".Dv LK_CANRECURSE" -offset indent -compact
.It Dv LK_INTERLOCK
Specify when the caller already has a simple lock
-.Fn ( VOP_LOCK
-will unlock the simple lock after getting the lock).
+.Po Fn VOP_LOCK
+will unlock the simple lock after getting the lock
+.Pc .
.It Dv LK_RETRY
Retry until locked.
.El
diff --git a/share/man/man9/VOP_VPTOCNP.9 b/share/man/man9/VOP_VPTOCNP.9
index f2d5ddc..7404260 100644
--- a/share/man/man9/VOP_VPTOCNP.9
+++ b/share/man/man9/VOP_VPTOCNP.9
@@ -78,8 +78,8 @@ The buffer was not large enough to hold the vnode's component name.
The vnode was not found on the file system.
.El
.Sh SEE ALSO
-.Xr VOP_LOOKUP 9 ,
-.Xr vnode 9
+.Xr vnode 9 ,
+.Xr VOP_LOOKUP 9
.Sh NOTES
This interface is a work in progress.
.Sh HISTORY
diff --git a/share/man/man9/accf_data.9 b/share/man/man9/accf_data.9
index 2d3b7a2..9caeba9 100644
--- a/share/man/man9/accf_data.9
+++ b/share/man/man9/accf_data.9
@@ -67,7 +67,7 @@ on the socket
.Sh SEE ALSO
.Xr setsockopt 2 ,
.Xr accept_filter 9 ,
-.Xr accf_dns 9
+.Xr accf_dns 9 ,
.Xr accf_http 9
.Sh HISTORY
The accept filter mechanism and the
diff --git a/share/man/man9/accf_dns.9 b/share/man/man9/accf_dns.9
index 4a2dad2..0ea4bf4 100644
--- a/share/man/man9/accf_dns.9
+++ b/share/man/man9/accf_dns.9
@@ -69,8 +69,8 @@ on a socket
.Sh SEE ALSO
.Xr setsockopt 2 ,
.Xr accept_filter 9 ,
+.Xr accf_data 9 ,
.Xr accf_http 9
-.Xr accf_data 9
.Sh HISTORY
The accept filter mechanism was introduced in
.Fx 4.0 .
diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9
index c6c7159..a4ee9cd 100644
--- a/share/man/man9/acl.9
+++ b/share/man/man9/acl.9
@@ -207,10 +207,10 @@ The following values are valid:
.El
.Sh SEE ALSO
.Xr acl 3 ,
+.Xr vaccess 9 ,
.Xr vaccess_acl_nfs4 9 ,
.Xr vaccess_acl_posix1e 9 ,
.Xr VFS 9 ,
-.Xr vaccess 9 ,
.Xr VOP_ACLCHECK 9 ,
.Xr VOP_GETACL 9 ,
.Xr VOP_SETACL 9
diff --git a/share/man/man9/alq.9 b/share/man/man9/alq.9
index b8b0c23..b13e73d 100644
--- a/share/man/man9/alq.9
+++ b/share/man/man9/alq.9
@@ -417,10 +417,10 @@ and either the queue is full or the system is shutting down.
NOTE: invalid arguments to non-void functions will result in
undefined behaviour.
.Sh SEE ALSO
+.Xr syslog 3 ,
.Xr kproc 9 ,
.Xr ktr 9 ,
.Xr msleep_spin 9 ,
-.Xr syslog 3 ,
.Xr vnode 9
.Sh HISTORY
The
diff --git a/share/man/man9/devfs_set_cdevpriv.9 b/share/man/man9/devfs_set_cdevpriv.9
index 736a007..85df4f3 100644
--- a/share/man/man9/devfs_set_cdevpriv.9
+++ b/share/man/man9/devfs_set_cdevpriv.9
@@ -114,8 +114,8 @@ filedescriptor, or
was called.
.El
.Sh SEE ALSO
-.Xr open 2 ,
.Xr close 2 ,
+.Xr open 2 ,
.Xr devfs 5 ,
.Xr kern_openat 9
.Sh HISTORY
diff --git a/share/man/man9/eventtimers.9 b/share/man/man9/eventtimers.9
index 09cd8b3..686f63c 100644
--- a/share/man/man9/eventtimers.9
+++ b/share/man/man9/eventtimers.9
@@ -179,13 +179,13 @@ methods control timers associated with the current CPU.
Driver may deregister its functionality by calling
.Fn et_deregister .
.Pp
-If the frequency of the clock hardware can change while it is
+If the frequency of the clock hardware can change while it is
running (for example, during power-saving modes), the driver must call
.Fn et_change_frequency
on each change.
If the given event timer is the active timer,
.Fn et_change_frequency
-stops the timer on all CPUs, updates
+stops the timer on all CPUs, updates
.Va et->frequency ,
then restarts the timer on all CPUs so that all
current events are rescheduled using the new frequency.
diff --git a/share/man/man9/ieee80211_crypto.9 b/share/man/man9/ieee80211_crypto.9
index c82b876..1335551 100644
--- a/share/man/man9/ieee80211_crypto.9
+++ b/share/man/man9/ieee80211_crypto.9
@@ -253,8 +253,8 @@ and
These calls also synchronize hardware key state update
when receive traffic is active.
.Sh SEE ALSO
-.Xr ieee80211 9 ,
.Xr ioctl 2 ,
.Xr wlan_ccmp 4 ,
.Xr wlan_tkip 4 ,
-.Xr wlan_wep 4
+.Xr wlan_wep 4 ,
+.Xr ieee80211 9
diff --git a/share/man/man9/ifnet.9 b/share/man/man9/ifnet.9
index 7aef4de..0e55850 100644
--- a/share/man/man9/ifnet.9
+++ b/share/man/man9/ifnet.9
@@ -418,7 +418,7 @@ lock used to protect interface-related address lists.
.Xr queue 3
macro glue for the list of clonable network interfaces.
.It Va if_groups
-.Pq Fn TAILQ_HEAD ", ifg_list"
+.Pq Fn TAILQ_HEAD "" "ifg_list"
The head of the
.Xr queue 3
.Li TAILQ
@@ -1410,7 +1410,8 @@ address whose remote address is
if one is found.
If
.Fa ignore_ptp
-is true, skip point-to-point interface addresses. The
+is true, skip point-to-point interface addresses.
+The
.Fa fib
parameter is handled the same way as by
.Fn ifa_ifwithdstaddr .
diff --git a/share/man/man9/kqueue.9 b/share/man/man9/kqueue.9
index 28aadee..a8137bd 100644
--- a/share/man/man9/kqueue.9
+++ b/share/man/man9/kqueue.9
@@ -395,8 +395,9 @@ There must be no
.Vt knotes
associated with the
.Vt knlist
-.Fn ( knlist_empty
-returns true)
+.Po Fn knlist_empty
+returns true
+.Pc
and no more
.Vt knotes
may be attached to the object.
diff --git a/share/man/man9/lock.9 b/share/man/man9/lock.9
index 2c874f2..69afdc4 100644
--- a/share/man/man9/lock.9
+++ b/share/man/man9/lock.9
@@ -411,12 +411,12 @@ will be the result of trying.
.Sh SEE ALSO
.Xr condvar 9 ,
.Xr locking 9 ,
+.Xr mtx_assert 9 ,
.Xr mutex 9 ,
+.Xr panic 9 ,
.Xr rwlock 9 ,
.Xr sleep 9 ,
.Xr sx 9 ,
-.Xr mtx_assert 9 ,
-.Xr panic 9 ,
.Xr VOP_PRINT 9
.Sh AUTHORS
This manual page was written by
diff --git a/share/man/man9/locking.9 b/share/man/man9/locking.9
index f8ac5f2..76ce70b 100644
--- a/share/man/man9/locking.9
+++ b/share/man/man9/locking.9
@@ -391,17 +391,17 @@ At this time this is a rather easy to remember table.
.El
.Sh SEE ALSO
.Xr witness 4 ,
+.Xr BUS_SETUP_INTR 9 ,
.Xr condvar 9 ,
.Xr lock 9 ,
+.Xr LOCK_PROFILING 9 ,
.Xr mtx_pool 9 ,
.Xr mutex 9 ,
.Xr rmlock 9 ,
.Xr rwlock 9 ,
.Xr sema 9 ,
.Xr sleep 9 ,
-.Xr sx 9 ,
-.Xr BUS_SETUP_INTR 9 ,
-.Xr LOCK_PROFILING 9
+.Xr sx 9
.Sh HISTORY
These
functions appeared in
diff --git a/share/man/man9/mbuf.9 b/share/man/man9/mbuf.9
index 6edbf44..2bde56d3 100644
--- a/share/man/man9/mbuf.9
+++ b/share/man/man9/mbuf.9
@@ -1183,8 +1183,10 @@ slab allocation.
.Sh AUTHORS
The original
.Nm
-manual page was written by Yar Tikhiy.
+manual page was written by
+.An Yar Tikhiy .
The
.Xr uma 9
.Vt mbuf
-allocator was written by Bosko Milekic.
+allocator was written by
+.An Bosko Milekic .
diff --git a/share/man/man9/mod_cc.9 b/share/man/man9/mod_cc.9
index 12bc9be..f1cd5be 100644
--- a/share/man/man9/mod_cc.9
+++ b/share/man/man9/mod_cc.9
@@ -31,19 +31,19 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 15, 2011
+.Dd December 26, 2014
.Dt MOD_CC 9
.Os
.Sh NAME
.Nm mod_cc ,
.Nm DECLARE_CC_MODULE ,
-.Nm CC_VAR
+.Nm CCV
.Nd Modular Congestion Control
.Sh SYNOPSIS
.In netinet/cc.h
.In netinet/cc/cc_module.h
.Fn DECLARE_CC_MODULE "ccname" "ccalgo"
-.Fn CC_VAR "ccv" "what"
+.Fn CCV "ccv" "what"
.Sh DESCRIPTION
The
.Nm
@@ -223,7 +223,7 @@ To aid the eventual transition towards this goal, direct use of variables from
the transport protocol's data structures is strongly discouraged.
However, it is inevitable at the current time to require access to some of these
variables, and so the
-.Fn CC_VAR
+.Fn CCV
macro exists as a convenience accessor.
The
.Fa ccv
@@ -290,6 +290,7 @@ by the value of the congestion window.
Algorithms should use the absence of this flag being set to avoid accumulating
a large difference between the congestion window and send window.
.Sh SEE ALSO
+.Xr cc_cdg 4 ,
.Xr cc_chd 4 ,
.Xr cc_cubic 4 ,
.Xr cc_hd 4 ,
diff --git a/share/man/man9/refcount.9 b/share/man/man9/refcount.9
index e7702a2..b3c8d7f 100644
--- a/share/man/man9/refcount.9
+++ b/share/man/man9/refcount.9
@@ -39,7 +39,7 @@
.In sys/param.h
.In sys/refcount.h
.Ft void
-.Fn refcount_init "volatile u_int *count, u_int value"
+.Fn refcount_init "volatile u_int *count" "u_int value"
.Ft void
.Fn refcount_acquire "volatile u_int *count"
.Ft int
diff --git a/share/man/man9/usbdi.9 b/share/man/man9/usbdi.9
index 283cda0..a42626a 100644
--- a/share/man/man9/usbdi.9
+++ b/share/man/man9/usbdi.9
@@ -199,7 +199,7 @@ callback.
.
.Fn usbd_transfer_start
This function will start the USB transfer pointed to by
-.Fa xfer,
+.Fa xfer ,
if not already started.
.
This function is always non-blocking and must be called with the
@@ -212,7 +212,7 @@ pointer.
.
.Fn usbd_transfer_stop
This function will stop the USB transfer pointed to by
-.Fa xfer,
+.Fa xfer ,
if not already stopped.
.
This function is always non-blocking and must be called with the
diff --git a/share/man/man9/vm_page_busy.9 b/share/man/man9/vm_page_busy.9
index 9503dac..f4e922a 100644
--- a/share/man/man9/vm_page_busy.9
+++ b/share/man/man9/vm_page_busy.9
@@ -205,7 +205,6 @@ function panics if
.Fa m
is not exclusive busied.
.Sh SEE ALSO
-.Xr VOP_GETPAGES 9 ,
.Xr vm_page_aflag 9 ,
.Xr vm_page_alloc 9 ,
.Xr vm_page_deactivate 9 ,
@@ -213,4 +212,5 @@ is not exclusive busied.
.Xr vm_page_grab 9 ,
.Xr vm_page_insert 9 ,
.Xr vm_page_lookup 9 ,
-.Xr vm_page_rename 9
+.Xr vm_page_rename 9 ,
+.Xr VOP_GETPAGES 9
diff --git a/share/man/man9/vnet.9 b/share/man/man9/vnet.9
index 68689ee..cf7ea46 100644
--- a/share/man/man9/vnet.9
+++ b/share/man/man9/vnet.9
@@ -100,8 +100,7 @@
.Fa "struct vnet *"
.Fc
.\"
-.Fo CURVNET_RESTORE
-.Fc
+.Fn CURVNET_RESTORE
.\"
.Fo VNET_ITERATOR_DECL
.Fa "struct vnet *"
@@ -113,14 +112,10 @@
.\" ------------------------------------------------------------
.Ss "Locking"
.\"
-.Fo VNET_LIST_RLOCK
-.Fc
-.Fo VNET_LIST_RUNLOCK
-.Fc
-.Fo VNET_LIST_RLOCK_NOSLEEP
-.Fc
-.Fo VNET_LIST_RUNLOCK_NOSLEEP
-.Fc
+.Fn VNET_LIST_RLOCK
+.Fn VNET_LIST_RUNLOCK
+.Fn VNET_LIST_RLOCK_NOSLEEP
+.Fn VNET_LIST_RUNLOCK_NOSLEEP
.\" ------------------------------------------------------------
.Ss "Startup and Teardown Functions"
.\"
diff --git a/share/man/man9/vnode.9 b/share/man/man9/vnode.9
index 074d8ec..666db1e 100644
--- a/share/man/man9/vnode.9
+++ b/share/man/man9/vnode.9
@@ -158,6 +158,7 @@ interlock, will cause a LOR (Lock Order Reversal) due to the
intertwining of VM Objects and Vnodes.
.Sh SEE ALSO
.Xr malloc 9 ,
+.Xr VFS 9 ,
.Xr VOP_ACCESS 9 ,
.Xr VOP_ACLCHECK 9 ,
.Xr VOP_ADVISE 9 ,
@@ -190,8 +191,7 @@ intertwining of VM Objects and Vnodes.
.Xr VOP_SETEXTATTR 9 ,
.Xr VOP_STRATEGY 9 ,
.Xr VOP_VPTOCNP 9 ,
-.Xr VOP_VPTOFH 9 ,
-.Xr VFS 9
+.Xr VOP_VPTOFH 9
.Sh AUTHORS
This manual page was written by
.An Doug Rabson .
diff --git a/share/man/man9/zone.9 b/share/man/man9/zone.9
index ed5939b..2df14b02 100644
--- a/share/man/man9/zone.9
+++ b/share/man/man9/zone.9
@@ -337,7 +337,7 @@ macro declares a static read only
oid that exports the approximate current occupancy of the zone.
The
.Fa zone
-argument should be a pointer to
+argument should be a pointer to
.Vt uma_zone_t .
A read of the oid returns value obtained through
.Fn uma_zone_get_cur .
diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot
index ae0390f..e97acba 100644
--- a/share/misc/committers-ports.dot
+++ b/share/misc/committers-ports.dot
@@ -67,6 +67,7 @@ beech [label="Beech Rintoul\nbeech@FreeBSD.org\n2007/05/30"]
bf [label="Brendan Fabeny\nbf@FreeBSD.org\n2010/06/02"]
bland [label="Alexander Nedotsukov\nbland@FreeBSD.org\n2003/08/14"]
bmah [label="Bruce A. Mah\nbmah@FreeBSD.org\n2000/08/23"]
+bofh [label="Muhammad Moinur Rahman\nbofh@FreeBSD.org\n2014/12/23"]
brix [label="Henrik Brix Andersen\nbrix@FreeBSD.org\n2007/10/31"]
brooks [label="Brooks Davies\nbrooks@FreeBSD.org\n2004/05/03"]
bsam [label="Boris Samorodov\nbsam@FreeBSD.org\n2006/07/20"]
@@ -263,6 +264,7 @@ bdrewery -> sbruno
bdrewery -> trociny
bapt -> bdrewery
+bapt -> bofh
bapt -> eadler
bapt -> grembo
bapt -> jlaffaye
@@ -430,6 +432,7 @@ marcus -> bland
marcus -> eik
marcus -> jmallett
+marino -> bofh
marino -> robak
makc -> alonso
diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk
index f0acf16..6a6f3f2 100644
--- a/share/mk/bsd.lib.mk
+++ b/share/mk/bsd.lib.mk
@@ -207,7 +207,12 @@ _LIBS+= ${SHLIB_NAME}
SOLINKOPTS= -shared -Wl,-x
.if !defined(ALLOW_SHARED_TEXTREL)
-SOLINKOPTS+= -Wl,--fatal-warnings -Wl,--warn-shared-textrel
+.if defined(LD_FATAL_WARNINGS) && ${LD_FATAL_WARNINGS} == "no"
+SOLINKOPTS+= -Wl,--no-fatal-warnings
+.else
+SOLINKOPTS+= -Wl,--fatal-warnings
+.endif
+SOLINKOPTS+= -Wl,--warn-shared-textrel
.endif
.if target(beforelinking)
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 1c6ce51..d66bbaa 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -85,7 +85,6 @@ __DEFAULT_YES_OPTIONS = \
GDB \
GNU \
GNU_GREP_COMPAT \
- GPIB \
GPIO \
GPL_DTC \
GROFF \
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 4880c91..67842cf 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -614,7 +614,8 @@ trap_check(struct trapframe *frame)
{
#ifdef KDTRACE_HOOKS
- if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
+ if (dtrace_trap_func != NULL &&
+ (*dtrace_trap_func)(frame, frame->tf_trapno) != 0)
return;
#endif
trap(frame);
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index d1220b6..9b697f0 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -215,7 +215,7 @@ hint.atkbd.0.irq="1"
# Options for atkbd:
options ATKBD_DFLT_KEYMAP # specify the built-in keymap
-makeoptions ATKBD_DFLT_KEYMAP=jp.106
+makeoptions ATKBD_DFLT_KEYMAP=fr.dvorak
# `flags' for atkbd:
# 0x01 Force detection of keyboard, else we always assume a keyboard
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index 0f19110..8a8c3f4 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -358,6 +358,8 @@ void vm_copyin(struct vm *vm, int vcpuid, struct vm_copyinfo *copyinfo,
void *kaddr, size_t len);
void vm_copyout(struct vm *vm, int vcpuid, const void *kaddr,
struct vm_copyinfo *copyinfo, size_t len);
+
+int vcpu_trace_exceptions(struct vm *vm, int vcpuid);
#endif /* KERNEL */
#define VM_MAXCPU 16 /* maximum virtual cpus */
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index 753799a..7d75046 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <machine/specialreg.h>
#include <machine/smp.h>
#include <machine/vmm.h>
+#include <machine/vmm_dev.h>
#include <machine/vmm_instruction_emul.h>
#include "vmm_lapic.h"
@@ -429,8 +430,24 @@ vmcb_init(struct svm_softc *sc, int vcpu, uint64_t iopm_base_pa,
svm_enable_intercept(sc, vcpu, VMCB_CR_INTCPT, mask);
}
- /* Intercept Machine Check exceptions. */
- svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(IDT_MC));
+
+ /*
+ * Intercept everything when tracing guest exceptions otherwise
+ * just intercept machine check exception.
+ */
+ if (vcpu_trace_exceptions(sc->vm, vcpu)) {
+ for (n = 0; n < 32; n++) {
+ /*
+ * Skip unimplemented vectors in the exception bitmap.
+ */
+ if (n == 2 || n == 9) {
+ continue;
+ }
+ svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(n));
+ }
+ } else {
+ svm_enable_intercept(sc, vcpu, VMCB_EXC_INTCPT, BIT(IDT_MC));
+ }
/* Intercept various events (for e.g. I/O, MSR and CPUID accesses) */
svm_enable_intercept(sc, vcpu, VMCB_CTRL1_INTCPT, VMCB_INTCPT_IO);
@@ -1176,9 +1193,10 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
struct vmcb_state *state;
struct vmcb_ctrl *ctrl;
struct svm_regctx *ctx;
+ struct vm_exception exception;
uint64_t code, info1, info2, val;
uint32_t eax, ecx, edx;
- int handled;
+ int error, errcode_valid, handled, idtvec, reflect;
bool retu;
ctx = svm_get_guest_regctx(svm_sc, vcpu);
@@ -1237,8 +1255,78 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
case VMCB_EXIT_NMI: /* external NMI */
handled = 1;
break;
- case VMCB_EXIT_MC: /* machine check */
+ case 0x40 ... 0x5F:
vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_EXCEPTION, 1);
+ reflect = 1;
+ idtvec = code - 0x40;
+ switch (idtvec) {
+ case IDT_MC:
+ /*
+ * Call the machine check handler by hand. Also don't
+ * reflect the machine check back into the guest.
+ */
+ reflect = 0;
+ VCPU_CTR0(svm_sc->vm, vcpu, "Vectoring to MCE handler");
+ __asm __volatile("int $18");
+ break;
+ case IDT_PF:
+ error = svm_setreg(svm_sc, vcpu, VM_REG_GUEST_CR2,
+ info2);
+ KASSERT(error == 0, ("%s: error %d updating cr2",
+ __func__, error));
+ /* fallthru */
+ case IDT_NP:
+ case IDT_SS:
+ case IDT_GP:
+ case IDT_AC:
+ case IDT_TS:
+ errcode_valid = 1;
+ break;
+
+ case IDT_DF:
+ errcode_valid = 1;
+ info1 = 0;
+ break;
+
+ case IDT_BP:
+ case IDT_OF:
+ case IDT_BR:
+ /*
+ * The 'nrip' field is populated for INT3, INTO and
+ * BOUND exceptions and this also implies that
+ * 'inst_length' is non-zero.
+ *
+ * Reset 'inst_length' to zero so the guest %rip at
+ * event injection is identical to what it was when
+ * the exception originally happened.
+ */
+ VCPU_CTR2(svm_sc->vm, vcpu, "Reset inst_length from %d "
+ "to zero before injecting exception %d",
+ vmexit->inst_length, idtvec);
+ vmexit->inst_length = 0;
+ /* fallthru */
+ default:
+ errcode_valid = 0;
+ break;
+ }
+ KASSERT(vmexit->inst_length == 0, ("invalid inst_length (%d) "
+ "when reflecting exception %d into guest",
+ vmexit->inst_length, idtvec));
+
+ if (reflect) {
+ /* Reflect the exception back into the guest */
+ exception.vector = idtvec;
+ exception.error_code_valid = errcode_valid;
+ exception.error_code = errcode_valid ? info1 : 0;
+ VCPU_CTR2(svm_sc->vm, vcpu, "Reflecting exception "
+ "%d/%#x into the guest", exception.vector,
+ exception.error_code);
+ error = vm_inject_exception(svm_sc->vm, vcpu,
+ &exception);
+ KASSERT(error == 0, ("%s: vm_inject_exception error %d",
+ __func__, error));
+ }
+ handled = 1;
break;
case VMCB_EXIT_MSR: /* MSR access. */
eax = state->rax;
diff --git a/sys/amd64/vmm/intel/vmcs.c b/sys/amd64/vmm/intel/vmcs.c
index 51e5c2c..ae4d9db 100644
--- a/sys/amd64/vmm/intel/vmcs.c
+++ b/sys/amd64/vmm/intel/vmcs.c
@@ -332,7 +332,6 @@ vmcs_init(struct vmcs *vmcs)
int error, codesel, datasel, tsssel;
u_long cr0, cr4, efer;
uint64_t pat, fsbase, idtrbase;
- uint32_t exc_bitmap;
codesel = vmm_get_host_codesel();
datasel = vmm_get_host_datasel();
@@ -417,11 +416,6 @@ vmcs_init(struct vmcs *vmcs)
if ((error = vmwrite(VMCS_HOST_RIP, (u_long)vmx_exit_guest)) != 0)
goto done;
- /* exception bitmap */
- exc_bitmap = 1 << IDT_MC;
- if ((error = vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap)) != 0)
- goto done;
-
/* link pointer */
if ((error = vmwrite(VMCS_LINK_POINTER, ~0)) != 0)
goto done;
diff --git a/sys/amd64/vmm/intel/vmcs.h b/sys/amd64/vmm/intel/vmcs.h
index 6122de5..6d78a69 100644
--- a/sys/amd64/vmm/intel/vmcs.h
+++ b/sys/amd64/vmm/intel/vmcs.h
@@ -321,7 +321,7 @@ vmcs_write(uint32_t encoding, uint64_t val)
#define EXIT_REASON_MTF 37
#define EXIT_REASON_MONITOR 39
#define EXIT_REASON_PAUSE 40
-#define EXIT_REASON_MCE 41
+#define EXIT_REASON_MCE_DURING_ENTRY 41
#define EXIT_REASON_TPR 43
#define EXIT_REASON_APIC_ACCESS 44
#define EXIT_REASON_VIRTUALIZED_EOI 45
diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c
index c855697..c3dd04e 100644
--- a/sys/amd64/vmm/intel/vmx.c
+++ b/sys/amd64/vmm/intel/vmx.c
@@ -283,8 +283,8 @@ exit_reason_to_str(int reason)
return "monitor";
case EXIT_REASON_PAUSE:
return "pause";
- case EXIT_REASON_MCE:
- return "mce";
+ case EXIT_REASON_MCE_DURING_ENTRY:
+ return "mce-during-entry";
case EXIT_REASON_TPR:
return "tpr";
case EXIT_REASON_APIC_ACCESS:
@@ -821,6 +821,7 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
int i, error;
struct vmx *vmx;
struct vmcs *vmcs;
+ uint32_t exc_bitmap;
vmx = malloc(sizeof(struct vmx), M_VMX, M_WAITOK | M_ZERO);
if ((uintptr_t)vmx & PAGE_MASK) {
@@ -911,6 +912,14 @@ vmx_vminit(struct vm *vm, pmap_t pmap)
error += vmwrite(VMCS_ENTRY_CTLS, entry_ctls);
error += vmwrite(VMCS_MSR_BITMAP, vtophys(vmx->msr_bitmap));
error += vmwrite(VMCS_VPID, vpid[i]);
+
+ /* exception bitmap */
+ if (vcpu_trace_exceptions(vm, i))
+ exc_bitmap = 0xffffffff;
+ else
+ exc_bitmap = 1 << IDT_MC;
+ error += vmwrite(VMCS_EXCEPTION_BITMAP, exc_bitmap);
+
if (virtual_interrupt_delivery) {
error += vmwrite(VMCS_APIC_ACCESS, APIC_ACCESS_ADDRESS);
error += vmwrite(VMCS_VIRTUAL_APIC,
@@ -2056,8 +2065,9 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
struct vlapic *vlapic;
struct vm_inout_str *vis;
struct vm_task_switch *ts;
+ struct vm_exception vmexc;
uint32_t eax, ecx, edx, idtvec_info, idtvec_err, intr_info, inst_info;
- uint32_t intr_type, reason;
+ uint32_t intr_type, intr_vec, reason;
uint64_t exitintinfo, qual, gpa;
bool retu;
@@ -2074,6 +2084,18 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
vmm_stat_incr(vmx->vm, vcpu, VMEXIT_COUNT, 1);
/*
+ * VM-entry failures during or after loading guest state.
+ *
+ * These VM-exits are uncommon but must be handled specially
+ * as most VM-exit fields are not populated as usual.
+ */
+ if (__predict_false(reason == EXIT_REASON_MCE_DURING_ENTRY)) {
+ VCPU_CTR0(vmx->vm, vcpu, "Handling MCE during VM-entry");
+ __asm __volatile("int $18");
+ return (1);
+ }
+
+ /*
* VM exits that can be triggered during event delivery need to
* be handled specially by re-injecting the event if the IDT
* vectoring information field's valid bit is set.
@@ -2305,6 +2327,9 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
KASSERT((intr_info & VMCS_INTR_VALID) != 0,
("VM exit interruption info invalid: %#x", intr_info));
+ intr_vec = intr_info & 0xff;
+ intr_type = intr_info & VMCS_INTR_T_MASK;
+
/*
* If Virtual NMIs control is 1 and the VM-exit is due to a
* fault encountered during the execution of IRET then we must
@@ -2315,16 +2340,55 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
* See "Information for VM Exits Due to Vectored Events".
*/
if ((idtvec_info & VMCS_IDT_VEC_VALID) == 0 &&
- (intr_info & 0xff) != IDT_DF &&
+ (intr_vec != IDT_DF) &&
(intr_info & EXIT_QUAL_NMIUDTI) != 0)
vmx_restore_nmi_blocking(vmx, vcpu);
/*
* The NMI has already been handled in vmx_exit_handle_nmi().
*/
- if ((intr_info & VMCS_INTR_T_MASK) == VMCS_INTR_T_NMI)
+ if (intr_type == VMCS_INTR_T_NMI)
return (1);
- break;
+
+ /*
+ * Call the machine check handler by hand. Also don't reflect
+ * the machine check back into the guest.
+ */
+ if (intr_vec == IDT_MC) {
+ VCPU_CTR0(vmx->vm, vcpu, "Vectoring to MCE handler");
+ __asm __volatile("int $18");
+ return (1);
+ }
+
+ if (intr_vec == IDT_PF) {
+ error = vmxctx_setreg(vmxctx, VM_REG_GUEST_CR2, qual);
+ KASSERT(error == 0, ("%s: vmxctx_setreg(cr2) error %d",
+ __func__, error));
+ }
+
+ /*
+ * Software exceptions exhibit trap-like behavior. This in
+ * turn requires populating the VM-entry instruction length
+ * so that the %rip in the trap frame is past the INT3/INTO
+ * instruction.
+ */
+ if (intr_type == VMCS_INTR_T_SWEXCEPTION)
+ vmcs_write(VMCS_ENTRY_INST_LENGTH, vmexit->inst_length);
+
+ /* Reflect all other exceptions back into the guest */
+ bzero(&vmexc, sizeof(struct vm_exception));
+ vmexc.vector = intr_vec;
+ if (intr_info & VMCS_INTR_DEL_ERRCODE) {
+ vmexc.error_code_valid = 1;
+ vmexc.error_code = vmcs_read(VMCS_EXIT_INTR_ERRCODE);
+ }
+ VCPU_CTR2(vmx->vm, vcpu, "Reflecting exception %d/%#x into "
+ "the guest", vmexc.vector, vmexc.error_code);
+ error = vm_inject_exception(vmx->vm, vcpu, &vmexc);
+ KASSERT(error == 0, ("%s: vm_inject_exception error %d",
+ __func__, error));
+ return (1);
+
case EXIT_REASON_EPT_FAULT:
/*
* If 'gpa' lies within the address space allocated to
diff --git a/sys/amd64/vmm/intel/vmx_msr.c b/sys/amd64/vmm/intel/vmx_msr.c
index 746ca73..f6bbf2a 100644
--- a/sys/amd64/vmm/intel/vmx_msr.c
+++ b/sys/amd64/vmm/intel/vmx_msr.c
@@ -376,9 +376,31 @@ vmx_rdmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t *val, bool *retu)
int
vmx_wrmsr(struct vmx *vmx, int vcpuid, u_int num, uint64_t val, bool *retu)
{
- int error = 0;
-
+ uint64_t changed;
+ int error;
+
+ error = 0;
switch (num) {
+ case MSR_IA32_MISC_ENABLE:
+ changed = val ^ misc_enable;
+ /*
+ * If the host has disabled the NX feature then the guest
+ * also cannot use it. However, a Linux guest will try to
+ * enable the NX feature by writing to the MISC_ENABLE MSR.
+ *
+ * This can be safely ignored because the memory management
+ * code looks at CPUID.80000001H:EDX.NX to check if the
+ * functionality is actually enabled.
+ */
+ changed &= ~(1UL << 34);
+
+ /*
+ * Punt to userspace if any other bits are being modified.
+ */
+ if (changed)
+ error = EINVAL;
+
+ break;
default:
error = EINVAL;
break;
diff --git a/sys/amd64/vmm/io/vatpic.c b/sys/amd64/vmm/io/vatpic.c
index c6d4590..74a7027 100644
--- a/sys/amd64/vmm/io/vatpic.c
+++ b/sys/amd64/vmm/io/vatpic.c
@@ -112,6 +112,16 @@ struct vatpic {
static void vatpic_set_pinstate(struct vatpic *vatpic, int pin, bool newstate);
+static __inline bool
+master_atpic(struct vatpic *vatpic, struct atpic *atpic)
+{
+
+ if (atpic == &vatpic->atpic[0])
+ return (true);
+ else
+ return (false);
+}
+
static __inline int
vatpic_get_highest_isrpin(struct atpic *atpic)
{
@@ -250,6 +260,7 @@ vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->mask = 0;
atpic->lowprio = 7;
atpic->rd_cmd_reg = 0;
+ atpic->poll = 0;
if ((val & ICW1_SNGL) != 0) {
VATPIC_CTR0(vatpic, "vatpic cascade mode required");
@@ -301,6 +312,15 @@ vatpic_icw4(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
if ((val & ICW4_AEOI) != 0)
atpic->aeoi = true;
+ if ((val & ICW4_SFNM) != 0) {
+ if (master_atpic(vatpic, atpic)) {
+ atpic->sfn = true;
+ } else {
+ VATPIC_CTR1(vatpic, "Ignoring special fully nested "
+ "mode on slave atpic: %#x", val);
+ }
+ }
+
atpic->icw_num = 0;
atpic->ready = true;
@@ -354,11 +374,17 @@ vatpic_ocw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
{
VATPIC_CTR1(vatpic, "atpic ocw3 0x%x", val);
- atpic->poll = ((val & OCW3_P) != 0);
+ if (val & OCW3_ESMM) {
+ VATPIC_CTR0(vatpic, "atpic special mask mode not implemented");
+ return (-1);
+ }
if (val & OCW3_RR) {
/* read register command */
atpic->rd_cmd_reg = val & OCW3_RIS;
+
+ /* Polling mode */
+ atpic->poll = ((val & OCW3_P) != 0);
}
return (0);
@@ -578,12 +604,19 @@ static int
vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
int bytes, uint32_t *eax)
{
+ int pin;
+
VATPIC_LOCK(vatpic);
if (atpic->poll) {
- VATPIC_CTR0(vatpic, "vatpic polled mode not supported");
- VATPIC_UNLOCK(vatpic);
- return (-1);
+ atpic->poll = 0;
+ pin = vatpic_get_highest_irrpin(atpic);
+ if (pin >= 0) {
+ vatpic_pin_accepted(atpic, pin);
+ *eax = 0x80 | pin;
+ } else {
+ *eax = 0;
+ }
} else {
if (port & ICU_IMR_OFFSET) {
/* read interrrupt mask register */
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index e7fbada..d9cb6f3 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -207,6 +207,11 @@ static int vmm_ipinum;
SYSCTL_INT(_hw_vmm, OID_AUTO, ipinum, CTLFLAG_RD, &vmm_ipinum, 0,
"IPI vector used for vcpu notifications");
+static int trace_guest_exceptions;
+SYSCTL_INT(_hw_vmm, OID_AUTO, trace_guest_exceptions, CTLFLAG_RDTUN,
+ &trace_guest_exceptions, 0,
+ "Trap into hypervisor on all guest exceptions and reflect them back");
+
static void
vcpu_cleanup(struct vm *vm, int i, bool destroy)
{
@@ -250,6 +255,13 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create)
vmm_stat_init(vcpu->stats);
}
+int
+vcpu_trace_exceptions(struct vm *vm, int vcpuid)
+{
+
+ return (trace_guest_exceptions);
+}
+
struct vm_exit *
vm_exitinfo(struct vm *vm, int cpuid)
{
diff --git a/sys/arm/allwinner/a20/std.a20 b/sys/arm/allwinner/a20/std.a20
index f582e91..7beb2bd 100644
--- a/sys/arm/allwinner/a20/std.a20
+++ b/sys/arm/allwinner/a20/std.a20
@@ -3,6 +3,7 @@
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
makeoption ARM_LITTLE_ENDIAN
# Physical memory starts at 0x40200000. We assume images are loaded at
diff --git a/sys/arm/allwinner/std.a10 b/sys/arm/allwinner/std.a10
index 11ef732..338395d 100644
--- a/sys/arm/allwinner/std.a10
+++ b/sys/arm/allwinner/std.a10
@@ -3,6 +3,7 @@
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
makeoption ARM_LITTLE_ENDIAN
# Physical memory starts at 0x40200000. We assume images are loaded at
diff --git a/sys/arm/altera/socfpga/std.socfpga b/sys/arm/altera/socfpga/std.socfpga
index c6607a5..2bc45b9 100644
--- a/sys/arm/altera/socfpga/std.socfpga
+++ b/sys/arm/altera/socfpga/std.socfpga
@@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
options PHYSADDR=0x00000000
diff --git a/sys/arm/arm/db_trace.c b/sys/arm/arm/db_trace.c
index e0d7552..04ab565 100644
--- a/sys/arm/arm/db_trace.c
+++ b/sys/arm/arm/db_trace.c
@@ -345,9 +345,16 @@ db_unwind_tab(struct unwind_state *state)
/*
* The program counter was not updated, load it from the link register.
*/
- if (state->registers[PC] == 0)
+ if (state->registers[PC] == 0) {
state->registers[PC] = state->registers[LR];
+ /*
+ * If the program counter changed, flag it in the update mask.
+ */
+ if (state->start_pc != state->registers[PC])
+ state->update_mask |= 1 << PC;
+ }
+
return 0;
}
@@ -602,14 +609,14 @@ db_trace_thread(struct thread *thr, int count)
ctx = kdb_thr_ctx(thr);
#ifdef __ARM_EABI__
- state.registers[FP] = ctx->un_32.pcb32_r11;
- state.registers[SP] = ctx->un_32.pcb32_sp;
- state.registers[LR] = ctx->un_32.pcb32_lr;
- state.registers[PC] = ctx->un_32.pcb32_pc;
+ state.registers[FP] = ctx->pcb_regs.sf_r11;
+ state.registers[SP] = ctx->pcb_regs.sf_sp;
+ state.registers[LR] = ctx->pcb_regs.sf_lr;
+ state.registers[PC] = ctx->pcb_regs.sf_pc;
db_stack_trace_cmd(&state);
#else
- db_stack_trace_cmd(ctx->un_32.pcb32_r11, -1, TRUE);
+ db_stack_trace_cmd(ctx->pcb_regs.sf_r11, -1, TRUE);
#endif
} else
db_trace_self();
diff --git a/sys/arm/arm/dump_machdep.c b/sys/arm/arm/dump_machdep.c
index 19c19c90..61d6eb5 100644
--- a/sys/arm/arm/dump_machdep.c
+++ b/sys/arm/arm/dump_machdep.c
@@ -160,11 +160,13 @@ static int
cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
{
struct dumperinfo *di = (struct dumperinfo*)arg;
- vm_paddr_t pa;
+ vm_paddr_t a, pa;
+ void *va;
uint32_t pgs;
size_t counter, sz, chunk;
- int c, error;
+ int i, c, error;
+ va = 0;
error = 0; /* catch case in which chunk size is 0 */
counter = 0;
pgs = mdp->md_size / PAGE_SIZE;
@@ -194,16 +196,14 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
printf(" %d", pgs * PAGE_SIZE);
counter &= (1<<24) - 1;
}
- if (pa == (pa & L1_ADDR_BITS)) {
- pmap_kenter_section(0, pa & L1_ADDR_BITS, 0);
- cpu_tlb_flushID_SE(0);
- cpu_cpwait();
+ for (i = 0; i < chunk; i++) {
+ a = pa + i * PAGE_SIZE;
+ va = pmap_kenter_temporary(trunc_page(a), i);
}
#ifdef SW_WATCHDOG
wdog_kern_pat(WD_LASTVAL);
#endif
- error = dump_write(di,
- (void *)(pa - (pa & L1_ADDR_BITS)),0, dumplo, sz);
+ error = dump_write(di, va, 0, dumplo, sz);
if (error)
break;
dumplo += sz;
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index 5cef965..3886968 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -241,26 +241,26 @@ __FBSDID("$FreeBSD$");
#define UNWINDSVCFRAME
#endif
-#define DO_AST \
- ldr r0, [sp] /* Get the SPSR from stack */ ;\
- mrs r4, cpsr /* save CPSR */ ;\
- orr r1, r4, #(PSR_I|PSR_F) ;\
- msr cpsr_c, r1 /* Disable interrupts */ ;\
- and r0, r0, #(PSR_MODE) /* Returning to USR mode? */ ;\
- teq r0, #(PSR_USR32_MODE) ;\
- bne 2f /* Nope, get out now */ ;\
- bic r4, r4, #(PSR_I|PSR_F) ;\
-1: GET_CURTHREAD_PTR(r5) ;\
- ldr r1, [r5, #(TD_FLAGS)] ;\
- and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED) ;\
- teq r1, #0x00000000 ;\
- beq 2f /* Nope. Just bail */ ;\
- msr cpsr_c, r4 /* Restore interrupts */ ;\
- mov r0, sp ;\
- bl _C_LABEL(ast) /* ast(frame) */ ;\
- orr r0, r4, #(PSR_I|PSR_F) ;\
- msr cpsr_c, r0 ;\
- b 1b ;\
+#define DO_AST \
+ ldr r0, [sp]; /* Get the SPSR from stack */ \
+ mrs r4, cpsr; /* save CPSR */ \
+ orr r1, r4, #(PSR_I|PSR_F); \
+ msr cpsr_c, r1; /* Disable interrupts */ \
+ and r0, r0, #(PSR_MODE); /* Returning to USR mode? */ \
+ teq r0, #(PSR_USR32_MODE); \
+ bne 2f; /* Nope, get out now */ \
+ bic r4, r4, #(PSR_I|PSR_F); \
+1: GET_CURTHREAD_PTR(r5); \
+ ldr r1, [r5, #(TD_FLAGS)]; \
+ and r1, r1, #(TDF_ASTPENDING|TDF_NEEDRESCHED); \
+ teq r1, #0; \
+ beq 2f; /* Nope. Just bail */ \
+ msr cpsr_c, r4; /* Restore interrupts */ \
+ mov r0, sp; \
+ bl _C_LABEL(ast); /* ast(frame) */ \
+ orr r0, r4, #(PSR_I|PSR_F); \
+ msr cpsr_c, r0; \
+ b 1b; \
2:
@@ -320,7 +320,8 @@ ASENTRY_NP(prefetch_abort_entry)
PUSHFRAMEINSVC /* mode stack, build trapframe there. */
adr lr, exception_exit /* Return from handler via standard */
mov r0, sp /* exception exit routine. Pass the */
- b prefetch_abort_handler /* trapframe to the handler. */
+ mov r1, #1 /* Type flag */
+ b _C_LABEL(abort_handler)
END(prefetch_abort_entry)
/*
@@ -337,9 +338,10 @@ ASENTRY_NP(data_abort_entry)
#endif
sub lr, lr, #8 /* Adjust the lr. Transition to scv32 */
PUSHFRAMEINSVC /* mode stack, build trapframe there. */
- adr lr, exception_exit /* Return from handler via standard */
- mov r0, sp /* exception exit routine. Pass the */
- b data_abort_handler /* trapframe to the handler. */
+ adr lr, exception_exit /* Exception exit routine */
+ mov r0, sp /* Trapframe to the handler */
+ mov r1, #0 /* Type flag */
+ b _C_LABEL(abort_handler)
END(data_abort_entry)
/*
diff --git a/sys/arm/arm/gdb_machdep.c b/sys/arm/arm/gdb_machdep.c
index 11b9c0d..8cc7a19 100644
--- a/sys/arm/arm/gdb_machdep.c
+++ b/sys/arm/arm/gdb_machdep.c
@@ -67,22 +67,26 @@ gdb_cpu_getreg(int regnum, size_t *regsz)
}
switch (regnum) {
- case 8: return (&kdb_thrctx->un_32.pcb32_r8);
- case 9: return (&kdb_thrctx->un_32.pcb32_r9);
- case 10: return (&kdb_thrctx->un_32.pcb32_r10);
- case 11: return (&kdb_thrctx->un_32.pcb32_r11);
- case 12: return (&kdb_thrctx->un_32.pcb32_r12);
- case 13: stacktest = kdb_thrctx->un_32.pcb32_sp + 5 * 4;
+ case 4: return (&kdb_thrctx->pcb_regs.sf_r4);
+ case 5: return (&kdb_thrctx->pcb_regs.sf_r5);
+ case 6: return (&kdb_thrctx->pcb_regs.sf_r6);
+ case 7: return (&kdb_thrctx->pcb_regs.sf_r7);
+ case 8: return (&kdb_thrctx->pcb_regs.sf_r8);
+ case 9: return (&kdb_thrctx->pcb_regs.sf_r9);
+ case 10: return (&kdb_thrctx->pcb_regs.sf_r10);
+ case 11: return (&kdb_thrctx->pcb_regs.sf_r11);
+ case 12: return (&kdb_thrctx->pcb_regs.sf_r12);
+ case 13: stacktest = kdb_thrctx->pcb_regs.sf_sp + 5 * 4;
return (&stacktest);
case 15:
/*
* On context switch, the PC is not put in the PCB, but
* we can retrieve it from the stack.
*/
- if (kdb_thrctx->un_32.pcb32_sp > KERNBASE) {
- kdb_thrctx->un_32.pcb32_pc = *(register_t *)
- (kdb_thrctx->un_32.pcb32_sp + 4 * 4);
- return (&kdb_thrctx->un_32.pcb32_pc);
+ if (kdb_thrctx->pcb_regs.sf_sp > KERNBASE) {
+ kdb_thrctx->pcb_regs.sf_pc = *(register_t *)
+ (kdb_thrctx->pcb_regs.sf_sp + 4 * 4);
+ return (&kdb_thrctx->pcb_regs.sf_pc);
}
}
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index ab0be4c..ce7b88d 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -63,13 +63,18 @@ ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
ASSYM(PCB_PAGEDIR, offsetof(struct pcb, pcb_pagedir));
ASSYM(PCB_L1VEC, offsetof(struct pcb, pcb_l1vec));
ASSYM(PCB_PL1VEC, offsetof(struct pcb, pcb_pl1vec));
-ASSYM(PCB_R8, offsetof(struct pcb, un_32.pcb32_r8));
-ASSYM(PCB_R9, offsetof(struct pcb, un_32.pcb32_r9));
-ASSYM(PCB_R10, offsetof(struct pcb, un_32.pcb32_r10));
-ASSYM(PCB_R11, offsetof(struct pcb, un_32.pcb32_r11));
-ASSYM(PCB_R12, offsetof(struct pcb, un_32.pcb32_r12));
-ASSYM(PCB_PC, offsetof(struct pcb, un_32.pcb32_pc));
-ASSYM(PCB_SP, offsetof(struct pcb, un_32.pcb32_sp));
+ASSYM(PCB_R4, offsetof(struct pcb, pcb_regs.sf_r4));
+ASSYM(PCB_R5, offsetof(struct pcb, pcb_regs.sf_r5));
+ASSYM(PCB_R6, offsetof(struct pcb, pcb_regs.sf_r6));
+ASSYM(PCB_R7, offsetof(struct pcb, pcb_regs.sf_r7));
+ASSYM(PCB_R8, offsetof(struct pcb, pcb_regs.sf_r8));
+ASSYM(PCB_R9, offsetof(struct pcb, pcb_regs.sf_r9));
+ASSYM(PCB_R10, offsetof(struct pcb, pcb_regs.sf_r10));
+ASSYM(PCB_R11, offsetof(struct pcb, pcb_regs.sf_r11));
+ASSYM(PCB_R12, offsetof(struct pcb, pcb_regs.sf_r12));
+ASSYM(PCB_SP, offsetof(struct pcb, pcb_regs.sf_sp));
+ASSYM(PCB_LR, offsetof(struct pcb, pcb_regs.sf_lr));
+ASSYM(PCB_PC, offsetof(struct pcb, pcb_regs.sf_pc));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index f1bb014..af667ca 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -99,13 +99,13 @@ __FBSDID("$FreeBSD$");
#define GICD_ICFGR_TRIG_MASK 0x2
struct arm_gic_softc {
+ device_t gic_dev;
struct resource * gic_res[3];
bus_space_tag_t gic_c_bst;
bus_space_tag_t gic_d_bst;
bus_space_handle_t gic_c_bsh;
bus_space_handle_t gic_d_bsh;
uint8_t ver;
- device_t dev;
struct mtx mutex;
uint32_t nirqs;
};
@@ -118,14 +118,14 @@ static struct resource_spec arm_gic_spec[] = {
static struct arm_gic_softc *arm_gic_sc = NULL;
-#define gic_c_read_4(reg) \
- bus_space_read_4(arm_gic_sc->gic_c_bst, arm_gic_sc->gic_c_bsh, reg)
-#define gic_c_write_4(reg, val) \
- bus_space_write_4(arm_gic_sc->gic_c_bst, arm_gic_sc->gic_c_bsh, reg, val)
-#define gic_d_read_4(reg) \
- bus_space_read_4(arm_gic_sc->gic_d_bst, arm_gic_sc->gic_d_bsh, reg)
-#define gic_d_write_4(reg, val) \
- bus_space_write_4(arm_gic_sc->gic_d_bst, arm_gic_sc->gic_d_bsh, reg, val)
+#define gic_c_read_4(_sc, _reg) \
+ bus_space_read_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg))
+#define gic_c_write_4(_sc, _reg, _val) \
+ bus_space_write_4((_sc)->gic_c_bst, (_sc)->gic_c_bsh, (_reg), (_val))
+#define gic_d_read_4(_sc, _reg) \
+ bus_space_read_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg))
+#define gic_d_write_4(_sc, _reg, _val) \
+ bus_space_write_4((_sc)->gic_d_bst, (_sc)->gic_d_bsh, (_reg), (_val))
static int gic_config_irq(int irq, enum intr_trigger trig,
enum intr_polarity pol);
@@ -158,35 +158,32 @@ arm_gic_probe(device_t dev)
void
gic_init_secondary(void)
{
- int i, nirqs;
+ struct arm_gic_softc *sc = arm_gic_sc;
+ int i;
- /* Get the number of interrupts */
- nirqs = gic_d_read_4(GICD_TYPER);
- nirqs = 32 * ((nirqs & 0x1f) + 1);
-
- for (i = 0; i < nirqs; i += 4)
- gic_d_write_4(GICD_IPRIORITYR(i >> 2), 0);
+ for (i = 0; i < sc->nirqs; i += 4)
+ gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
/* Set all the interrupts to be in Group 0 (secure) */
- for (i = 0; i < nirqs; i += 32) {
- gic_d_write_4(GICD_IGROUPR(i >> 5), 0);
+ for (i = 0; i < sc->nirqs; i += 32) {
+ gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
}
/* Enable CPU interface */
- gic_c_write_4(GICC_CTLR, 1);
+ gic_c_write_4(sc, GICC_CTLR, 1);
/* Set priority mask register. */
- gic_c_write_4(GICC_PMR, 0xff);
+ gic_c_write_4(sc, GICC_PMR, 0xff);
/* Enable interrupt distribution */
- gic_d_write_4(GICD_CTLR, 0x01);
+ gic_d_write_4(sc, GICD_CTLR, 0x01);
/*
* Activate the timer interrupts: virtual, secure, and non-secure.
*/
- gic_d_write_4(GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F)));
- gic_d_write_4(GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
- gic_d_write_4(GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F)));
+ gic_d_write_4(sc, GICD_ISENABLER(27 >> 5), (1UL << (27 & 0x1F)));
+ gic_d_write_4(sc, GICD_ISENABLER(29 >> 5), (1UL << (29 & 0x1F)));
+ gic_d_write_4(sc, GICD_ISENABLER(30 >> 5), (1UL << (30 & 0x1F)));
}
int
@@ -245,13 +242,15 @@ arm_gic_attach(device_t dev)
return (ENXIO);
sc = device_get_softc(dev);
- sc->dev = dev;
if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
device_printf(dev, "could not allocate resources\n");
return (ENXIO);
}
+ sc->gic_dev = dev;
+ arm_gic_sc = sc;
+
/* Initialize mutex */
mtx_init(&sc->mutex, "GIC lock", "", MTX_SPIN);
@@ -263,100 +262,81 @@ arm_gic_attach(device_t dev)
sc->gic_c_bst = rman_get_bustag(sc->gic_res[1]);
sc->gic_c_bsh = rman_get_bushandle(sc->gic_res[1]);
- arm_gic_sc = sc;
-
/* Disable interrupt forwarding to the CPU interface */
- gic_d_write_4(GICD_CTLR, 0x00);
+ gic_d_write_4(sc, GICD_CTLR, 0x00);
/* Get the number of interrupts */
- sc->nirqs = gic_d_read_4(GICD_TYPER);
+ sc->nirqs = gic_d_read_4(sc, GICD_TYPER);
sc->nirqs = 32 * ((sc->nirqs & 0x1f) + 1);
/* Set up function pointers */
arm_post_filter = gic_post_filter;
arm_config_irq = gic_config_irq;
- icciidr = gic_c_read_4(GICC_IIDR);
+ icciidr = gic_c_read_4(sc, GICC_IIDR);
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);
/* Set all global interrupts to be level triggered, active low. */
for (i = 32; i < sc->nirqs; i += 16) {
- gic_d_write_4(GICD_ICFGR(i >> 4), 0x00000000);
+ gic_d_write_4(sc, GICD_ICFGR(i >> 4), 0x00000000);
}
/* Disable all interrupts. */
for (i = 32; i < sc->nirqs; i += 32) {
- gic_d_write_4(GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
+ gic_d_write_4(sc, GICD_ICENABLER(i >> 5), 0xFFFFFFFF);
}
for (i = 0; i < sc->nirqs; i += 4) {
- gic_d_write_4(GICD_IPRIORITYR(i >> 2), 0);
- gic_d_write_4(GICD_ITARGETSR(i >> 2), 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24);
+ gic_d_write_4(sc, GICD_IPRIORITYR(i >> 2), 0);
+ gic_d_write_4(sc, GICD_ITARGETSR(i >> 2),
+ 1 << 0 | 1 << 8 | 1 << 16 | 1 << 24);
}
/* Set all the interrupts to be in Group 0 (secure) */
for (i = 0; i < sc->nirqs; i += 32) {
- gic_d_write_4(GICD_IGROUPR(i >> 5), 0);
+ gic_d_write_4(sc, GICD_IGROUPR(i >> 5), 0);
}
/* Enable CPU interface */
- gic_c_write_4(GICC_CTLR, 1);
+ gic_c_write_4(sc, GICC_CTLR, 1);
/* Set priority mask register. */
- gic_c_write_4(GICC_PMR, 0xff);
+ gic_c_write_4(sc, GICC_PMR, 0xff);
/* Enable interrupt distribution */
- gic_d_write_4(GICD_CTLR, 0x01);
+ gic_d_write_4(sc, GICD_CTLR, 0x01);
return (0);
}
-static device_method_t arm_gic_methods[] = {
- DEVMETHOD(device_probe, arm_gic_probe),
- DEVMETHOD(device_attach, arm_gic_attach),
- { 0, 0 }
-};
-
-static driver_t arm_gic_driver = {
- "gic",
- arm_gic_methods,
- sizeof(struct arm_gic_softc),
-};
-
-static devclass_t arm_gic_devclass;
-
-EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
-EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
- BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
-
static void
gic_post_filter(void *arg)
{
+ struct arm_gic_softc *sc = arm_gic_sc;
uintptr_t irq = (uintptr_t) arg;
if (irq > GIC_LAST_IPI)
arm_irq_memory_barrier(irq);
- gic_c_write_4(GICC_EOIR, irq);
+ gic_c_write_4(sc, GICC_EOIR, irq);
}
int
arm_get_next_irq(int last_irq)
{
+ struct arm_gic_softc *sc = arm_gic_sc;
uint32_t active_irq;
- active_irq = gic_c_read_4(GICC_IAR);
+ active_irq = gic_c_read_4(sc, GICC_IAR);
/*
* Immediatly EOIR the SGIs, because doing so requires the other
* bits (ie CPU number), not just the IRQ number, and we do not
* have this information later.
*/
-
if ((active_irq & 0x3ff) <= GIC_LAST_IPI)
- gic_c_write_4(GICC_EOIR, active_irq);
+ gic_c_write_4(sc, GICC_EOIR, active_irq);
active_irq &= 0x3FF;
if (active_irq == 0x3FF) {
@@ -371,29 +351,33 @@ arm_get_next_irq(int last_irq)
void
arm_mask_irq(uintptr_t nb)
{
+ struct arm_gic_softc *sc = arm_gic_sc;
- gic_d_write_4(GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F)));
- gic_c_write_4(GICC_EOIR, nb);
+ gic_d_write_4(sc, GICD_ICENABLER(nb >> 5), (1UL << (nb & 0x1F)));
+ gic_c_write_4(sc, GICC_EOIR, nb);
}
void
arm_unmask_irq(uintptr_t nb)
{
+ struct arm_gic_softc *sc = arm_gic_sc;
if (nb > GIC_LAST_IPI)
arm_irq_memory_barrier(nb);
- gic_d_write_4(GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F)));
+ gic_d_write_4(sc, GICD_ISENABLER(nb >> 5), (1UL << (nb & 0x1F)));
}
static int
gic_config_irq(int irq, enum intr_trigger trig,
enum intr_polarity pol)
{
+ struct arm_gic_softc *sc = arm_gic_sc;
+ device_t dev = sc->gic_dev;
uint32_t reg;
uint32_t mask;
/* Function is public-accessible, so validate input arguments */
- if ((irq < 0) || (irq >= arm_gic_sc->nirqs))
+ if ((irq < 0) || (irq >= sc->nirqs))
goto invalid_args;
if ((trig != INTR_TRIGGER_EDGE) && (trig != INTR_TRIGGER_LEVEL) &&
(trig != INTR_TRIGGER_CONFORM))
@@ -402,9 +386,9 @@ gic_config_irq(int irq, enum intr_trigger trig,
(pol != INTR_POLARITY_CONFORM))
goto invalid_args;
- mtx_lock_spin(&arm_gic_sc->mutex);
+ mtx_lock_spin(&sc->mutex);
- reg = gic_d_read_4(GICD_ICFGR(irq >> 4));
+ reg = gic_d_read_4(sc, GICD_ICFGR(irq >> 4));
mask = (reg >> 2*(irq % 16)) & 0x3;
if (pol == INTR_POLARITY_LOW) {
@@ -426,14 +410,14 @@ gic_config_irq(int irq, enum intr_trigger trig,
/* Set mask */
reg = reg & ~(0x3 << 2*(irq % 16));
reg = reg | (mask << 2*(irq % 16));
- gic_d_write_4(GICD_ICFGR(irq >> 4), reg);
+ gic_d_write_4(sc, GICD_ICFGR(irq >> 4), reg);
- mtx_unlock_spin(&arm_gic_sc->mutex);
+ mtx_unlock_spin(&sc->mutex);
return (0);
invalid_args:
- device_printf(arm_gic_sc->dev, "gic_config_irg, invalid parameters\n");
+ device_printf(dev, "gic_config_irg, invalid parameters\n");
return (EINVAL);
}
@@ -441,17 +425,18 @@ invalid_args:
void
pic_ipi_send(cpuset_t cpus, u_int ipi)
{
+ struct arm_gic_softc *sc = arm_gic_sc;
uint32_t val = 0, i;
for (i = 0; i < MAXCPU; i++)
if (CPU_ISSET(i, &cpus))
val |= 1 << (16 + i);
- gic_d_write_4(GICD_SGIR(0), val | ipi);
+ gic_d_write_4(sc, GICD_SGIR(0), val | ipi);
}
int
-pic_ipi_get(int i)
+pic_ipi_read(int i)
{
if (i != -1) {
@@ -463,6 +448,7 @@ pic_ipi_get(int i)
return (0);
return (i);
}
+
return (0x3ff);
}
@@ -472,3 +458,22 @@ pic_ipi_clear(int ipi)
}
#endif
+static device_method_t arm_gic_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, arm_gic_probe),
+ DEVMETHOD(device_attach, arm_gic_attach),
+ { 0, 0 }
+};
+
+static driver_t arm_gic_driver = {
+ "gic",
+ arm_gic_methods,
+ sizeof(struct arm_gic_softc),
+};
+
+static devclass_t arm_gic_devclass;
+
+EARLY_DRIVER_MODULE(gic, simplebus, arm_gic_driver, arm_gic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(gic, ofwbus, arm_gic_driver, arm_gic_devclass, 0, 0,
+ BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm/arm/identcpu.c b/sys/arm/arm/identcpu.c
index 955b9f5..1b808ae 100644
--- a/sys/arm/arm/identcpu.c
+++ b/sys/arm/arm/identcpu.c
@@ -457,7 +457,7 @@ identify_arm_cpu(void)
if (arm_cache_level) {
printf("LoUU:%d LoC:%d LoUIS:%d \n", CPU_CLIDR_LOUU(arm_cache_level) + 1,
- arm_cache_loc, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
+ arm_cache_loc + 1, CPU_CLIDR_LOUIS(arm_cache_level) + 1);
i = 0;
while (((type = CPU_CLIDR_CTYPE(arm_cache_level, i)) != 0) && i < 7) {
printf("Cache level %d: \n", i + 1);
diff --git a/sys/arm/arm/intr.c b/sys/arm/arm/intr.c
index 83eca07..030407a 100644
--- a/sys/arm/arm/intr.c
+++ b/sys/arm/arm/intr.c
@@ -36,8 +36,11 @@
* Soft interrupt and other generic interrupt functions.
*/
+#include "opt_platform.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
@@ -47,10 +50,16 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/conf.h>
+
#include <machine/atomic.h>
#include <machine/intr.h>
#include <machine/cpu.h>
+#ifdef FDT
+#include <dev/fdt/fdt_common.h>
+#include <machine/fdt.h>
+#endif
+
#define INTRNAME_LEN (MAXCOMLEN + 1)
typedef void (*mask_fn)(void *);
@@ -89,6 +98,36 @@ intr_init(void *unused)
SYSINIT(intr_init, SI_SUB_INTR, SI_ORDER_FIRST, intr_init, NULL);
+#ifdef FDT
+int
+arm_fdt_map_irq(phandle_t iparent, pcell_t *intr, int icells)
+{
+ fdt_pic_decode_t intr_decode;
+ phandle_t intr_parent;
+ int i, rv, interrupt, trig, pol;
+
+ intr_parent = OF_node_from_xref(iparent);
+ for (i = 0; i < icells; i++)
+ intr[i] = cpu_to_fdt32(intr[i]);
+
+ for (i = 0; fdt_pic_table[i] != NULL; i++) {
+ intr_decode = fdt_pic_table[i];
+ rv = intr_decode(intr_parent, intr, &interrupt, &trig, &pol);
+
+ if (rv == 0) {
+ /* This was recognized as our PIC and decoded. */
+ interrupt = FDT_MAP_IRQ(intr_parent, interrupt);
+ return (interrupt);
+ }
+ }
+
+ /* Not in table, so guess */
+ interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0]));
+
+ return (interrupt);
+}
+#endif
+
void
arm_setup_irqhandler(const char *name, driver_filter_t *filt,
void (*hand)(void*), void *arg, int irq, int flags, void **cookiep)
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 341ea4a..f3e75d5 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -378,7 +378,7 @@ cpu_startup(void *dummy)
bufinit();
vm_pager_bufferinit();
- pcb->un_32.pcb32_sp = (u_int)thread0.td_kstack +
+ pcb->pcb_regs.sf_sp = (u_int)thread0.td_kstack +
USPACE_SVC_STACK_TOP;
vector_page_setprot(VM_PROT_READ);
pmap_set_pcb_pagedir(pmap_kernel(), pcb);
@@ -770,14 +770,18 @@ sys_sigreturn(td, uap)
void
makectx(struct trapframe *tf, struct pcb *pcb)
{
- pcb->un_32.pcb32_r8 = tf->tf_r8;
- pcb->un_32.pcb32_r9 = tf->tf_r9;
- pcb->un_32.pcb32_r10 = tf->tf_r10;
- pcb->un_32.pcb32_r11 = tf->tf_r11;
- pcb->un_32.pcb32_r12 = tf->tf_r12;
- pcb->un_32.pcb32_pc = tf->tf_pc;
- pcb->un_32.pcb32_lr = tf->tf_usr_lr;
- pcb->un_32.pcb32_sp = tf->tf_usr_sp;
+ pcb->pcb_regs.sf_r4 = tf->tf_r4;
+ pcb->pcb_regs.sf_r5 = tf->tf_r5;
+ pcb->pcb_regs.sf_r6 = tf->tf_r6;
+ pcb->pcb_regs.sf_r7 = tf->tf_r7;
+ pcb->pcb_regs.sf_r8 = tf->tf_r8;
+ pcb->pcb_regs.sf_r9 = tf->tf_r9;
+ pcb->pcb_regs.sf_r10 = tf->tf_r10;
+ pcb->pcb_regs.sf_r11 = tf->tf_r11;
+ pcb->pcb_regs.sf_r12 = tf->tf_r12;
+ pcb->pcb_regs.sf_pc = tf->tf_pc;
+ pcb->pcb_regs.sf_lr = tf->tf_usr_lr;
+ pcb->pcb_regs.sf_sp = tf->tf_usr_sp;
}
/*
diff --git a/sys/arm/arm/mp_machdep.c b/sys/arm/arm/mp_machdep.c
index a1b29c1..32dce4d 100644
--- a/sys/arm/arm/mp_machdep.c
+++ b/sys/arm/arm/mp_machdep.c
@@ -266,7 +266,7 @@ ipi_handler(void *arg)
cpu = PCPU_GET(cpuid);
- ipi = pic_ipi_get((int)arg);
+ ipi = pic_ipi_read((int)arg);
while ((ipi != 0x3ff)) {
switch (ipi) {
@@ -329,7 +329,7 @@ ipi_handler(void *arg)
}
pic_ipi_clear(ipi);
- ipi = pic_ipi_get(-1);
+ ipi = pic_ipi_read(-1);
}
return (FILTER_HANDLED);
diff --git a/sys/arm/arm/nexus.c b/sys/arm/arm/nexus.c
index 6678d5d..06f2d6f 100644
--- a/sys/arm/arm/nexus.c
+++ b/sys/arm/arm/nexus.c
@@ -39,6 +39,8 @@
* and I/O memory address space.
*/
+#include "opt_platform.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -60,10 +62,7 @@ __FBSDID("$FreeBSD$");
#include <machine/resource.h>
#include <machine/intr.h>
-#include "opt_platform.h"
-
#ifdef FDT
-#include <dev/fdt/fdt_common.h>
#include <machine/fdt.h>
#include "ofw_bus_if.h"
#endif
@@ -351,28 +350,7 @@ static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
{
- fdt_pic_decode_t intr_decode;
- phandle_t intr_parent;
- int i, rv, interrupt, trig, pol;
-
- intr_parent = OF_node_from_xref(iparent);
- for (i = 0; i < icells; i++)
- intr[i] = cpu_to_fdt32(intr[i]);
-
- for (i = 0; fdt_pic_table[i] != NULL; i++) {
- intr_decode = fdt_pic_table[i];
- rv = intr_decode(intr_parent, intr, &interrupt, &trig, &pol);
-
- if (rv == 0) {
- /* This was recognized as our PIC and decoded. */
- interrupt = FDT_MAP_IRQ(intr_parent, interrupt);
- return (interrupt);
- }
- }
-
- /* Not in table, so guess */
- interrupt = FDT_MAP_IRQ(intr_parent, fdt32_to_cpu(intr[0]));
- return (interrupt);
+ return (arm_fdt_map_irq(iparent, intr, icells));
}
#endif
diff --git a/sys/arm/arm/stack_machdep.c b/sys/arm/arm/stack_machdep.c
index f1708f5..9c984a9 100644
--- a/sys/arm/arm/stack_machdep.c
+++ b/sys/arm/arm/stack_machdep.c
@@ -76,7 +76,7 @@ stack_save_td(struct stack *st, struct thread *td)
* as it doesn't have a frame pointer, however it's value is not used
* when building for EABI.
*/
- frame = (u_int32_t *)td->td_pcb->un_32.pcb32_r11;
+ frame = (u_int32_t *)td->td_pcb->pcb_regs.sf_r11;
stack_zero(st);
stack_capture(st, frame);
}
diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S
index 610d575..e9d6f61 100644
--- a/sys/arm/arm/swtch.S
+++ b/sys/arm/arm/swtch.S
@@ -116,6 +116,14 @@ __FBSDID("$FreeBSD$");
.Lblocked_lock:
.word _C_LABEL(blocked_lock)
+/*
+ * cpu_throw(oldtd, newtd)
+ *
+ * Remove current thread state, then select the next thread to run
+ * and load its state.
+ * r0 = oldtd
+ * r1 = newtd
+ */
ENTRY(cpu_throw)
mov r5, r1
@@ -144,7 +152,6 @@ ENTRY(cpu_throw)
* r0 = Pointer to L1 slot for vector_page (or NULL)
* r1 = lwp0's DACR
* r5 = lwp0
- * r6 = exit func
* r7 = lwp0's PCB
* r9 = cpufuncs
*/
@@ -181,25 +188,11 @@ ENTRY(cpu_throw)
mov lr, pc
ldr pc, [r9, #CF_CONTEXT_SWITCH]
- /* Restore all the save registers */
-#ifndef _ARM_ARCH_5E
- add r1, r7, #PCB_R8
- ldmia r1, {r8-r13}
-#else
- ldr r8, [r7, #(PCB_R8)]
- ldr r9, [r7, #(PCB_R9)]
- ldr r10, [r7, #(PCB_R10)]
- ldr r11, [r7, #(PCB_R11)]
- ldr r12, [r7, #(PCB_R12)]
- ldr r13, [r7, #(PCB_SP)]
-#endif
-
GET_PCPU(r6, r4)
/* Hook in a new pcb */
str r7, [r6, #PC_CURPCB]
/* We have a new curthread now so make a note it */
- add r6, r6, #PC_CURTHREAD
- str r5, [r6]
+ str r5, [r6, #PC_CURTHREAD]
#ifndef ARM_TP_ADDRESS
mcr p15, 0, r5, c13, c0, 4
#endif
@@ -215,22 +208,31 @@ ENTRY(cpu_throw)
#else
mcr p15, 0, r6, c13, c0, 3
#endif
-
- add sp, sp, #4;
- ldmfd sp!, {r4-r7, pc}
+ /* Restore all the saved registers and exit */
+ add r3, r7, #PCB_R4
+ ldmia r3, {r4-r12, sp, pc}
END(cpu_throw)
+/*
+ * cpu_switch(oldtd, newtd, lock)
+ *
+ * Save the current thread state, then select the next thread to run
+ * and load its state.
+ * r0 = oldtd
+ * r1 = newtd
+ * r2 = lock (new lock for old thread)
+ */
ENTRY(cpu_switch)
- stmfd sp!, {r4-r7, lr}
- sub sp, sp, #4;
-#ifdef __ARM_EABI__
- .save {r4-r7, lr}
- .pad #4
-#endif
+ /* Interrupts are disabled. */
+ /* Save all the registers in the old thread's pcb. */
+ ldr r3, [r0, #(TD_PCB)]
+
+ /* Restore all the saved registers and exit */
+ add r3, #(PCB_R4)
+ stmia r3, {r4-r12, sp, lr, pc}
mov r6, r2 /* Save the mutex */
-.Lswitch_resume:
/* rem: r0 = old lwp */
/* rem: interrupts are disabled */
@@ -246,30 +248,12 @@ ENTRY(cpu_switch)
ldr r2, [r1, #TD_PCB]
str r2, [r7, #PC_CURPCB]
- /* rem: r1 = new process */
- /* rem: interrupts are enabled */
-
/* Stage two : Save old context */
/* Get the user structure for the old thread. */
ldr r2, [r0, #(TD_PCB)]
mov r4, r0 /* Save the old thread. */
- /* Save all the registers in the old thread's pcb */
-#ifndef _ARM_ARCH_5E
- add r7, r2, #(PCB_R8)
- stmia r7, {r8-r13}
-#else
- strd r8, [r2, #(PCB_R8)]
- strd r10, [r2, #(PCB_R10)]
- strd r12, [r2, #(PCB_R12)]
-#endif
- str pc, [r2, #(PCB_PC)]
-
- /*
- * NOTE: We can now use r8-r13 until it is time to restore
- * them for the new process.
- */
#ifdef ARM_TP_ADDRESS
/* Store the old tp */
ldr r3, =ARM_TP_ADDRESS
@@ -318,7 +302,6 @@ ENTRY(cpu_switch)
/* rem: r2 = old PCB */
/* rem: r9 = new PCB */
- /* rem: interrupts are enabled */
ldr r5, [r9, #(PCB_DACR)] /* r5 = new DACR */
mov r2, #DOMAIN_CLIENT
@@ -336,7 +319,6 @@ ENTRY(cpu_switch)
mrc p15, 0, r10, c2, c0, 0 /* r10 = old L1 */
ldr r11, [r9, #(PCB_PAGEDIR)] /* r11 = new L1 */
-
teq r10, r11 /* Same L1? */
cmpeq r0, r5 /* Same DACR? */
beq .Lcs_context_switched /* yes! */
@@ -426,54 +408,18 @@ ENTRY(cpu_switch)
/* rem: r9 = new PCB */
- /* Restore all the save registers */
-#ifndef _ARM_ARCH_5E
- add r7, r9, #PCB_R8
- ldmia r7, {r8-r13}
- sub r7, r7, #PCB_R8 /* restore PCB pointer */
-#else
- mov r7, r9
- ldr r8, [r7, #(PCB_R8)]
- ldr r9, [r7, #(PCB_R9)]
- ldr r10, [r7, #(PCB_R10)]
- ldr r11, [r7, #(PCB_R11)]
- ldr r12, [r7, #(PCB_R12)]
- ldr r13, [r7, #(PCB_SP)]
-#endif
-
- /* rem: r5 = new lwp's proc */
- /* rem: r6 = lock */
- /* rem: r7 = new PCB */
-
-.Lswitch_return:
-
- /*
- * Pull the registers that got pushed when either savectx() or
- * cpu_switch() was called and return.
- */
- add sp, sp, #4;
- ldmfd sp!, {r4-r7, pc}
-#ifdef DIAGNOSTIC
-.Lswitch_bogons:
- adr r0, .Lswitch_panic_str
- bl _C_LABEL(panic)
-1: nop
- b 1b
-
-.Lswitch_panic_str:
- .asciz "cpu_switch: sched_qs empty with non-zero sched_whichqs!\n"
-#endif
+ /* Restore all the saved registers and exit */
+ add r3, r9, #PCB_R4
+ ldmia r3, {r4-r12, sp, pc}
END(cpu_switch)
ENTRY(savectx)
- stmfd sp!, {r4-r7, lr}
+ stmfd sp!, {lr}
sub sp, sp, #4
- /*
- * r0 = pcb
- */
- /* Store all the registers in the process's pcb */
- add r2, r0, #(PCB_R8)
- stmia r2, {r8-r13}
+
+ /* Store all the registers in the thread's pcb */
+ add r3, r0, #(PCB_R4)
+ stmia r3, {r4-r12, sp, lr, pc}
#ifdef VFP
fmrx r2, fpexc /* If the VFP is enabled */
tst r2, #(VFPEXC_EN) /* the current thread has */
@@ -482,7 +428,7 @@ ENTRY(savectx)
blne _C_LABEL(vfp_store) /* and disable the VFP. */
#endif
add sp, sp, #4;
- ldmfd sp!, {r4-r7, pc}
+ ldmfd sp!, {pc}
END(savectx)
ENTRY(fork_trampoline)
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c
index ec14feb..081cfaa 100644
--- a/sys/arm/arm/trap.c
+++ b/sys/arm/arm/trap.c
@@ -127,6 +127,7 @@ static int dab_align(struct trapframe *, u_int, u_int, struct thread *,
struct ksig *);
static int dab_buserr(struct trapframe *, u_int, u_int, struct thread *,
struct ksig *);
+static void prefetch_abort_handler(struct trapframe *);
static const struct data_abort data_aborts[] = {
{dab_fatal, "Vector Exception"},
@@ -171,7 +172,7 @@ call_trapsignal(struct thread *td, int sig, u_long code)
}
void
-data_abort_handler(struct trapframe *tf)
+abort_handler(struct trapframe *tf, int type)
{
struct vm_map *map;
struct pcb *pcb;
@@ -184,6 +185,8 @@ data_abort_handler(struct trapframe *tf)
struct ksig ksig;
struct proc *p;
+ if (type == 1)
+ return (prefetch_abort_handler(tf));
/* Grab FAR/FSR before enabling interrupts */
far = cpu_faultaddress();
@@ -545,7 +548,7 @@ dab_buserr(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
* If the current trapframe is at the top of the kernel stack,
* the fault _must_ have come from user mode.
*/
- if (tf != ((struct trapframe *)pcb->un_32.pcb32_sp) - 1) {
+ if (tf != ((struct trapframe *)pcb->pcb_regs.sf_sp) - 1) {
/*
* Kernel mode. We're either about to die a
* spectacular death, or pcb_onfault will come
@@ -605,7 +608,7 @@ dab_buserr(struct trapframe *tf, u_int fsr, u_int far, struct thread *td,
* does no have read permission so send it a signal.
* Otherwise fault the page in and try again.
*/
-void
+static void
prefetch_abort_handler(struct trapframe *tf)
{
struct thread *td;
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 7758a22..42587f5 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$");
* struct switchframe and trapframe must both be a multiple of 8
* for correct stack alignment.
*/
-CTASSERT(sizeof(struct switchframe) == 24);
+CTASSERT(sizeof(struct switchframe) == 48);
CTASSERT(sizeof(struct trapframe) == 80);
/*
@@ -93,43 +93,55 @@ cpu_fork(register struct thread *td1, register struct proc *p2,
{
struct pcb *pcb2;
struct trapframe *tf;
- struct switchframe *sf;
struct mdproc *mdp2;
if ((flags & RFPROC) == 0)
return;
- pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
+
+ /* Point the pcb to the top of the stack */
+ pcb2 = (struct pcb *)
+ (td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1;
#ifdef __XSCALE__
#ifndef CPU_XSCALE_CORE3
pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE);
#endif
#endif
td2->td_pcb = pcb2;
+
+ /* Clone td1's pcb */
bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
+
+ /* Point to mdproc and then copy over td1's contents */
mdp2 = &p2->p_md;
bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2));
- pcb2->un_32.pcb32_sp = td2->td_kstack +
- USPACE_SVC_STACK_TOP - sizeof(*pcb2);
+
+ /* Point the frame to the stack in front of pcb and copy td1's frame */
+ td2->td_frame = (struct trapframe *)pcb2 - 1;
+ *td2->td_frame = *td1->td_frame;
+
+ /*
+ * Create a new fresh stack for the new process.
+ * Copy the trap frame for the return to user mode as if from a
+ * syscall. This copies most of the user mode register values.
+ */
+ pmap_set_pcb_pagedir(vmspace_pmap(p2->p_vmspace), pcb2);
+ pcb2->pcb_regs.sf_r4 = (register_t)fork_return;
+ pcb2->pcb_regs.sf_r5 = (register_t)td2;
+ pcb2->pcb_regs.sf_lr = (register_t)fork_trampoline;
+ pcb2->pcb_regs.sf_sp = STACKALIGN(td2->td_frame);
+
pcb2->pcb_vfpcpu = -1;
pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ;
- pmap_activate(td2);
- td2->td_frame = tf = (struct trapframe *)STACKALIGN(
- pcb2->un_32.pcb32_sp - sizeof(struct trapframe));
- *tf = *td1->td_frame;
- sf = (struct switchframe *)tf - 1;
- sf->sf_r4 = (u_int)fork_return;
- sf->sf_r5 = (u_int)td2;
- sf->sf_pc = (u_int)fork_trampoline;
+
+ tf = td2->td_frame;
tf->tf_spsr &= ~PSR_C;
tf->tf_r0 = 0;
tf->tf_r1 = 0;
- pcb2->un_32.pcb32_sp = (u_int)sf;
- KASSERT((pcb2->un_32.pcb32_sp & 7) == 0,
- ("cpu_fork: Incorrect stack alignment"));
+
/* Setup to release spin count in fork_exit(). */
td2->td_md.md_spinlock_count = 1;
- td2->td_md.md_saved_cspr = 0;
+ td2->td_md.md_saved_cspr = PSR_SVC32_MODE;;
#ifdef ARM_TP_ADDRESS
td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS;
#else
@@ -218,25 +230,21 @@ cpu_set_syscall_retval(struct thread *td, int error)
void
cpu_set_upcall(struct thread *td, struct thread *td0)
{
- struct trapframe *tf;
- struct switchframe *sf;
bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb));
- tf = td->td_frame;
- sf = (struct switchframe *)tf - 1;
- sf->sf_r4 = (u_int)fork_return;
- sf->sf_r5 = (u_int)td;
- sf->sf_pc = (u_int)fork_trampoline;
- tf->tf_spsr &= ~PSR_C;
- tf->tf_r0 = 0;
- td->td_pcb->un_32.pcb32_sp = (u_int)sf;
- KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
- ("cpu_set_upcall: Incorrect stack alignment"));
+
+ td->td_pcb->pcb_regs.sf_r4 = (register_t)fork_return;
+ td->td_pcb->pcb_regs.sf_r5 = (register_t)td;
+ td->td_pcb->pcb_regs.sf_lr = (register_t)fork_trampoline;
+ td->td_pcb->pcb_regs.sf_sp = STACKALIGN(td->td_frame);
+
+ td->td_frame->tf_spsr &= ~PSR_C;
+ td->td_frame->tf_r0 = 0;
/* Setup to release spin count in fork_exit(). */
td->td_md.md_spinlock_count = 1;
- td->td_md.md_saved_cspr = 0;
+ td->td_md.md_saved_cspr = PSR_SVC32_MODE;
}
/*
@@ -250,8 +258,7 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg,
{
struct trapframe *tf = td->td_frame;
- tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size
- - sizeof(struct trapframe));
+ tf->tf_usr_sp = STACKALIGN((int)stack->ss_sp + stack->ss_size);
tf->tf_pc = (int)entry;
tf->tf_r0 = (int)arg;
tf->tf_spsr = PSR_USR32_MODE;
@@ -289,9 +296,8 @@ cpu_thread_alloc(struct thread *td)
* placed into the stack pointer which must be 8 byte aligned in
* the ARM EABI.
*/
- td->td_frame = (struct trapframe *)STACKALIGN((u_int)td->td_kstack +
- USPACE_SVC_STACK_TOP - sizeof(struct pcb) -
- sizeof(struct trapframe));
+ td->td_frame = (struct trapframe *)((caddr_t)td->td_pcb) - 1;
+
#ifdef __XSCALE__
#ifndef CPU_XSCALE_CORE3
pmap_use_minicache(td->td_kstack, td->td_kstack_pages * PAGE_SIZE);
@@ -318,16 +324,8 @@ cpu_thread_clean(struct thread *td)
void
cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
{
- struct switchframe *sf;
- struct trapframe *tf;
-
- tf = td->td_frame;
- sf = (struct switchframe *)tf - 1;
- sf->sf_r4 = (u_int)func;
- sf->sf_r5 = (u_int)arg;
- td->td_pcb->un_32.pcb32_sp = (u_int)sf;
- KASSERT((td->td_pcb->un_32.pcb32_sp & 7) == 0,
- ("cpu_set_fork_handler: Incorrect stack alignment"));
+ td->td_pcb->pcb_regs.sf_r4 = (register_t)func; /* function */
+ td->td_pcb->pcb_regs.sf_r5 = (register_t)arg; /* first arg */
}
/*
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index 0f6b79b..293a352 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -117,8 +117,6 @@ extern struct bus_space at91_bs_tag;
struct pv_addr kernel_pt_table[NUM_KERNEL_PTS];
-extern uint32_t at91_master_clock;
-
/* Static device mappings. */
const struct arm_devmap_entry at91_devmap[] = {
/*
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
new file mode 100644
index 0000000..686e80c
--- /dev/null
+++ b/sys/arm/broadcom/bcm2835/bcm2835_cpufreq.c
@@ -0,0 +1,1818 @@
+/*-
+ * Copyright (C) 2013-2014 Daisuke Aoyama <aoyama@peach.ne.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/sema.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+
+#include <arm/broadcom/bcm2835/bcm2835_mbox.h>
+#include <arm/broadcom/bcm2835/bcm2835_mbox_prop.h>
+#include <arm/broadcom/bcm2835/bcm2835_vcbus.h>
+
+#include "cpufreq_if.h"
+#include "mbox_if.h"
+
+#ifdef DEBUG
+#define DPRINTF(fmt, ...) do { \
+ printf("%s:%u: ", __func__, __LINE__); \
+ printf(fmt, ##__VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(fmt, ...)
+#endif
+
+#define HZ2MHZ(freq) ((freq) / (1000 * 1000))
+#define MHZ2HZ(freq) ((freq) * (1000 * 1000))
+#define OFFSET2MVOLT(val) (1200 + ((val) * 25))
+#define MVOLT2OFFSET(val) (((val) - 1200) / 25)
+#define RAW2K(temp) (((temp) + 273150) / 1000)
+#define K2RAW(temp) (((temp) * 1000) - 273150)
+
+#define DEFAULT_ARM_FREQUENCY 700
+#define DEFAULT_CORE_FREQUENCY 250
+#define DEFAULT_SDRAM_FREQUENCY 400
+#define DEFAULT_LOWEST_FREQ 300
+#define TRANSITION_LATENCY 1000
+#define MIN_OVER_VOLTAGE -16
+#define MAX_OVER_VOLTAGE 6
+#define MSG_ERROR -999999999
+#define MHZSTEP 100
+#define HZSTEP (MHZ2HZ(MHZSTEP))
+
+#define VC_LOCK(sc) do { \
+ sema_wait(&vc_sema); \
+ } while (0)
+#define VC_UNLOCK(sc) do { \
+ sema_post(&vc_sema); \
+ } while (0)
+
+/* ARM->VC mailbox property semaphore */
+static struct sema vc_sema;
+
+static struct sysctl_ctx_list bcm2835_sysctl_ctx;
+
+struct bcm2835_cpufreq_softc {
+ device_t dev;
+ int arm_max_freq;
+ int arm_min_freq;
+ int core_max_freq;
+ int core_min_freq;
+ int sdram_max_freq;
+ int sdram_min_freq;
+ int max_voltage_core;
+ int min_voltage_core;
+
+ /* the values written in mbox */
+ int voltage_core;
+ int voltage_sdram;
+ int voltage_sdram_c;
+ int voltage_sdram_i;
+ int voltage_sdram_p;
+ int turbo_mode;
+
+ /* mbox buffer (physical address) */
+ bus_dma_tag_t dma_tag;
+ bus_dmamap_t dma_map;
+ bus_size_t dma_size;
+ void *dma_buf;
+ bus_addr_t dma_phys;
+
+ /* initial hook for waiting mbox intr */
+ struct intr_config_hook init_hook;
+};
+
+static int cpufreq_verbose = 0;
+TUNABLE_INT("hw.bcm2835.cpufreq.verbose", &cpufreq_verbose);
+static int cpufreq_lowest_freq = DEFAULT_LOWEST_FREQ;
+TUNABLE_INT("hw.bcm2835.cpufreq.lowest_freq", &cpufreq_lowest_freq);
+
+#ifdef PROP_DEBUG
+static void
+bcm2835_dump(const void *data, int len)
+{
+ const uint8_t *p = (const uint8_t*)data;
+ int i;
+
+ printf("dump @ %p:\n", data);
+ for (i = 0; i < len; i++) {
+ printf("%2.2x ", p[i]);
+ if ((i % 4) == 3)
+ printf(" ");
+ if ((i % 16) == 15)
+ printf("\n");
+ }
+ printf("\n");
+}
+#endif
+
+static int
+bcm2835_mbox_call_prop(struct bcm2835_cpufreq_softc *sc)
+{
+ struct bcm2835_mbox_hdr *msg = (struct bcm2835_mbox_hdr *)sc->dma_buf;
+ struct bcm2835_mbox_tag_hdr *tag, *last;
+ uint8_t *up;
+ device_t mbox;
+ size_t hdr_size;
+ int idx;
+ int err;
+
+ /*
+ * For multiple calls, locking is not here. The caller must have
+ * VC semaphore.
+ */
+
+ /* get mbox device */
+ mbox = devclass_get_device(devclass_find("mbox"), 0);
+ if (mbox == NULL) {
+ device_printf(sc->dev, "can't find mbox\n");
+ return (-1);
+ }
+
+ /* go mailbox property */
+#ifdef PROP_DEBUG
+ bcm2835_dump(msg, 64);
+#endif
+ bus_dmamap_sync(sc->dma_tag, sc->dma_map,
+ BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
+ MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)sc->dma_phys);
+ MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, &err);
+ bus_dmamap_sync(sc->dma_tag, sc->dma_map, BUS_DMASYNC_POSTREAD);
+#ifdef PROP_DEBUG
+ bcm2835_dump(msg, 64);
+#endif
+
+ /* check response code */
+ if (msg->code != BCM2835_MBOX_CODE_RESP_SUCCESS) {
+ device_printf(sc->dev, "mbox response error\n");
+ return (-1);
+ }
+
+ /* tag = first tag */
+ up = (uint8_t *)msg;
+ hdr_size = sizeof(struct bcm2835_mbox_hdr);
+ tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size);
+ /* last = end of buffer specified by header */
+ last = (struct bcm2835_mbox_tag_hdr *)(up + msg->buf_size);
+
+ /* loop unitl end tag (=0x0) */
+ hdr_size = sizeof(struct bcm2835_mbox_tag_hdr);
+ for (idx = 0; tag->tag != 0; idx++) {
+ if ((tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) == 0) {
+ device_printf(sc->dev, "tag%d response error\n", idx);
+ return (-1);
+ }
+ /* clear response bit */
+ tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
+
+ /* get next tag */
+ up = (uint8_t *)tag;
+ tag = (struct bcm2835_mbox_tag_hdr *)(up + hdr_size +
+ tag->val_buf_size);
+
+ /* check buffer size of header */
+ if (tag > last) {
+ device_printf(sc->dev, "mbox buffer size error\n");
+ return (-1);
+ }
+ }
+
+ return (0);
+}
+
+static int
+bcm2835_cpufreq_get_clock_rate(struct bcm2835_cpufreq_softc *sc,
+ uint32_t clock_id)
+{
+ struct msg_get_clock_rate *msg;
+ int rate;
+ int err;
+
+ /*
+ * Get clock rate
+ * Tag: 0x00030002
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: clock id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: clock id
+ * u32: rate (in Hz)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_clock_rate *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.clock_id = clock_id;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get clock rate (id=%u)\n",
+ clock_id);
+ return (MSG_ERROR);
+ }
+
+ /* result (Hz) */
+ rate = (int)msg->body.resp.rate_hz;
+ DPRINTF("clock = %d(Hz)\n", rate);
+ return (rate);
+}
+
+static int
+bcm2835_cpufreq_get_max_clock_rate(struct bcm2835_cpufreq_softc *sc,
+ uint32_t clock_id)
+{
+ struct msg_get_max_clock_rate *msg;
+ int rate;
+ int err;
+
+ /*
+ * Get max clock rate
+ * Tag: 0x00030004
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: clock id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: clock id
+ * u32: rate (in Hz)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_max_clock_rate *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.clock_id = clock_id;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get max clock rate (id=%u)\n",
+ clock_id);
+ return (MSG_ERROR);
+ }
+
+ /* result (Hz) */
+ rate = (int)msg->body.resp.rate_hz;
+ DPRINTF("clock = %d(Hz)\n", rate);
+ return (rate);
+}
+
+static int
+bcm2835_cpufreq_get_min_clock_rate(struct bcm2835_cpufreq_softc *sc,
+ uint32_t clock_id)
+{
+ struct msg_get_min_clock_rate *msg;
+ int rate;
+ int err;
+
+ /*
+ * Get min clock rate
+ * Tag: 0x00030007
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: clock id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: clock id
+ * u32: rate (in Hz)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_min_clock_rate *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.clock_id = clock_id;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get min clock rate (id=%u)\n",
+ clock_id);
+ return (MSG_ERROR);
+ }
+
+ /* result (Hz) */
+ rate = (int)msg->body.resp.rate_hz;
+ DPRINTF("clock = %d(Hz)\n", rate);
+ return (rate);
+}
+
+static int
+bcm2835_cpufreq_set_clock_rate(struct bcm2835_cpufreq_softc *sc,
+ uint32_t clock_id, uint32_t rate_hz)
+{
+ struct msg_set_clock_rate *msg;
+ int rate;
+ int err;
+
+ /*
+ * Set clock rate
+ * Tag: 0x00038002
+ * Request:
+ * Length: 8
+ * Value:
+ * u32: clock id
+ * u32: rate (in Hz)
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: clock id
+ * u32: rate (in Hz)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_set_clock_rate *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.clock_id = clock_id;
+ msg->body.req.rate_hz = rate_hz;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't set clock rate (id=%u)\n",
+ clock_id);
+ return (MSG_ERROR);
+ }
+
+ /* workaround for core clock */
+ if (clock_id == BCM2835_MBOX_CLOCK_ID_CORE) {
+ /* for safety (may change voltage without changing clock) */
+ DELAY(TRANSITION_LATENCY);
+
+ /*
+ * XXX: the core clock is unable to change at once,
+ * to change certainly, write it twice now.
+ */
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_CLOCK_RATE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.clock_id = clock_id;
+ msg->body.req.rate_hz = rate_hz;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev,
+ "can't set clock rate (id=%u)\n", clock_id);
+ return (MSG_ERROR);
+ }
+ }
+
+ /* result (Hz) */
+ rate = (int)msg->body.resp.rate_hz;
+ DPRINTF("clock = %d(Hz)\n", rate);
+ return (rate);
+}
+
+static int
+bcm2835_cpufreq_get_turbo(struct bcm2835_cpufreq_softc *sc)
+{
+ struct msg_get_turbo *msg;
+ int level;
+ int err;
+
+ /*
+ * Get turbo
+ * Tag: 0x00030009
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: id
+ * u32: level
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_turbo *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TURBO;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.id = 0;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get turbo\n");
+ return (MSG_ERROR);
+ }
+
+ /* result 0=non-turbo, 1=turbo */
+ level = (int)msg->body.resp.level;
+ DPRINTF("level = %d\n", level);
+ return (level);
+}
+
+static int
+bcm2835_cpufreq_set_turbo(struct bcm2835_cpufreq_softc *sc, uint32_t level)
+{
+ struct msg_set_turbo *msg;
+ int value;
+ int err;
+
+ /*
+ * Set turbo
+ * Tag: 0x00038009
+ * Request:
+ * Length: 8
+ * Value:
+ * u32: id
+ * u32: level
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: id
+ * u32: level
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_set_turbo *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* replace unknown value to OFF */
+ if (level != BCM2835_MBOX_TURBO_ON && level != BCM2835_MBOX_TURBO_OFF)
+ level = BCM2835_MBOX_TURBO_OFF;
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_TURBO;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.id = 0;
+ msg->body.req.level = level;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't set turbo\n");
+ return (MSG_ERROR);
+ }
+
+ /* result 0=non-turbo, 1=turbo */
+ value = (int)msg->body.resp.level;
+ DPRINTF("level = %d\n", value);
+ return (value);
+}
+
+static int
+bcm2835_cpufreq_get_voltage(struct bcm2835_cpufreq_softc *sc,
+ uint32_t voltage_id)
+{
+ struct msg_get_voltage *msg;
+ int value;
+ int err;
+
+ /*
+ * Get voltage
+ * Tag: 0x00030003
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: voltage id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: voltage id
+ * u32: value (offset from 1.2V in units of 0.025V)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_voltage *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_VOLTAGE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.voltage_id = voltage_id;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get voltage\n");
+ return (MSG_ERROR);
+ }
+
+ /* result (offset from 1.2V) */
+ value = (int)msg->body.resp.value;
+ DPRINTF("value = %d\n", value);
+ return (value);
+}
+
+static int
+bcm2835_cpufreq_get_max_voltage(struct bcm2835_cpufreq_softc *sc,
+ uint32_t voltage_id)
+{
+ struct msg_get_max_voltage *msg;
+ int value;
+ int err;
+
+ /*
+ * Get voltage
+ * Tag: 0x00030005
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: voltage id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: voltage id
+ * u32: value (offset from 1.2V in units of 0.025V)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_max_voltage *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MAX_VOLTAGE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.voltage_id = voltage_id;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get max voltage\n");
+ return (MSG_ERROR);
+ }
+
+ /* result (offset from 1.2V) */
+ value = (int)msg->body.resp.value;
+ DPRINTF("value = %d\n", value);
+ return (value);
+}
+static int
+bcm2835_cpufreq_get_min_voltage(struct bcm2835_cpufreq_softc *sc,
+ uint32_t voltage_id)
+{
+ struct msg_get_min_voltage *msg;
+ int value;
+ int err;
+
+ /*
+ * Get voltage
+ * Tag: 0x00030008
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: voltage id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: voltage id
+ * u32: value (offset from 1.2V in units of 0.025V)
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_min_voltage *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_MIN_VOLTAGE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.voltage_id = voltage_id;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get min voltage\n");
+ return (MSG_ERROR);
+ }
+
+ /* result (offset from 1.2V) */
+ value = (int)msg->body.resp.value;
+ DPRINTF("value = %d\n", value);
+ return (value);
+}
+
+static int
+bcm2835_cpufreq_set_voltage(struct bcm2835_cpufreq_softc *sc,
+ uint32_t voltage_id, int32_t value)
+{
+ struct msg_set_voltage *msg;
+ int err;
+
+ /*
+ * Set voltage
+ * Tag: 0x00038003
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: voltage id
+ * u32: value (offset from 1.2V in units of 0.025V)
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: voltage id
+ * u32: value (offset from 1.2V in units of 0.025V)
+ */
+
+ /*
+ * over_voltage:
+ * 0 (1.2 V). Values above 6 are only allowed when force_turbo or
+ * current_limit_override are specified (which set the warranty bit).
+ */
+ if (value > MAX_OVER_VOLTAGE || value < MIN_OVER_VOLTAGE) {
+ /* currently not supported */
+ device_printf(sc->dev, "not supported voltage: %d\n", value);
+ return (MSG_ERROR);
+ }
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_set_voltage *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_SET_VOLTAGE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.voltage_id = voltage_id;
+ msg->body.req.value = (uint32_t)value;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't set voltage\n");
+ return (MSG_ERROR);
+ }
+
+ /* result (offset from 1.2V) */
+ value = (int)msg->body.resp.value;
+ DPRINTF("value = %d\n", value);
+ return (value);
+}
+
+static int
+bcm2835_cpufreq_get_temperature(struct bcm2835_cpufreq_softc *sc)
+{
+ struct msg_get_temperature *msg;
+ int value;
+ int err;
+
+ /*
+ * Get temperature
+ * Tag: 0x00030006
+ * Request:
+ * Length: 4
+ * Value:
+ * u32: temperature id
+ * Response:
+ * Length: 8
+ * Value:
+ * u32: temperature id
+ * u32: value
+ */
+
+ /* using DMA buffer for VC */
+ msg = (struct msg_get_temperature *)sc->dma_buf;
+ if (sizeof(*msg) > sc->dma_size) {
+ device_printf(sc->dev, "DMA size overflow (%zu>%lu)\n",
+ sizeof(*msg), sc->dma_size);
+ return (MSG_ERROR);
+ }
+
+ /* setup single tag buffer */
+ memset(msg, 0, sizeof(*msg));
+ msg->hdr.buf_size = sizeof(*msg);
+ msg->hdr.code = BCM2835_MBOX_CODE_REQ;
+ msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_TEMPERATURE;
+ msg->tag_hdr.val_buf_size = sizeof(msg->body);
+ msg->tag_hdr.val_len = sizeof(msg->body.req);
+ msg->body.req.temperature_id = 0;
+ msg->end_tag = 0;
+
+ /* call mailbox property */
+ err = bcm2835_mbox_call_prop(sc);
+ if (err) {
+ device_printf(sc->dev, "can't get temperature\n");
+ return (MSG_ERROR);
+ }
+
+ /* result (temperature of degree C) */
+ value = (int)msg->body.resp.value;
+ DPRINTF("value = %d\n", value);
+ return (value);
+}
+
+
+
+static int
+sysctl_bcm2835_cpufreq_arm_freq(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
+ val);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set clock arm_freq error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_core_freq(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
+ val);
+ if (err == MSG_ERROR) {
+ VC_UNLOCK(sc);
+ device_printf(sc->dev, "set clock core_freq error\n");
+ return (EIO);
+ }
+ VC_UNLOCK(sc);
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_sdram_freq(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_SDRAM,
+ val);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set clock sdram_freq error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_turbo(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_turbo(sc);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ if (val > 0)
+ sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
+ else
+ sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
+
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_turbo(sc, sc->turbo_mode);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set turbo error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_core(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+ return (EINVAL);
+ sc->voltage_core = val;
+
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_CORE,
+ sc->voltage_core);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set voltage core error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram_c(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+ return (EINVAL);
+ sc->voltage_sdram_c = val;
+
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
+ sc->voltage_sdram_c);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set voltage sdram_c error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram_i(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+ return (EINVAL);
+ sc->voltage_sdram_i = val;
+
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
+ sc->voltage_sdram_i);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set voltage sdram_i error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram_p(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+ return (EINVAL);
+ sc->voltage_sdram_p = val;
+
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
+ sc->voltage_sdram_p);
+ VC_UNLOCK(sc);
+ if (err == MSG_ERROR) {
+ device_printf(sc->dev, "set voltage sdram_p error\n");
+ return (EIO);
+ }
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_voltage_sdram(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* multiple write only */
+ if (!req->newptr)
+ return (EINVAL);
+ val = 0;
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err)
+ return (err);
+
+ /* write request */
+ if (val > MAX_OVER_VOLTAGE || val < MIN_OVER_VOLTAGE)
+ return (EINVAL);
+ sc->voltage_sdram = val;
+
+ VC_LOCK(sc);
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_C,
+ val);
+ if (err == MSG_ERROR) {
+ VC_UNLOCK(sc);
+ device_printf(sc->dev, "set voltage sdram_c error\n");
+ return (EIO);
+ }
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_I,
+ val);
+ if (err == MSG_ERROR) {
+ VC_UNLOCK(sc);
+ device_printf(sc->dev, "set voltage sdram_i error\n");
+ return (EIO);
+ }
+ err = bcm2835_cpufreq_set_voltage(sc, BCM2835_MBOX_VOLTAGE_ID_SDRAM_P,
+ val);
+ if (err == MSG_ERROR) {
+ VC_UNLOCK(sc);
+ device_printf(sc->dev, "set voltage sdram_p error\n");
+ return (EIO);
+ }
+ VC_UNLOCK(sc);
+ DELAY(TRANSITION_LATENCY);
+
+ return (0);
+}
+
+static int
+sysctl_bcm2835_cpufreq_temperature(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_temperature(sc);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ return (EINVAL);
+}
+
+static int
+sysctl_bcm2835_devcpu_temperature(SYSCTL_HANDLER_ARGS)
+{
+ struct bcm2835_cpufreq_softc *sc = arg1;
+ int val;
+ int err;
+
+ /* get realtime value */
+ VC_LOCK(sc);
+ val = bcm2835_cpufreq_get_temperature(sc);
+ VC_UNLOCK(sc);
+ if (val == MSG_ERROR)
+ return (EIO);
+
+ /* 1/1000 celsius (raw) to 1/10 kelvin */
+ val = RAW2K(val) * 10;
+
+ err = sysctl_handle_int(oidp, &val, 0, req);
+ if (err || !req->newptr) /* error || read request */
+ return (err);
+
+ /* write request */
+ return (EINVAL);
+}
+
+
+static void
+bcm2835_cpufreq_init(void *arg)
+{
+ struct bcm2835_cpufreq_softc *sc = arg;
+ struct sysctl_ctx_list *ctx;
+ device_t cpu;
+ int arm_freq, core_freq, sdram_freq;
+ int arm_max_freq, arm_min_freq, core_max_freq, core_min_freq;
+ int sdram_max_freq, sdram_min_freq;
+ int voltage_core, voltage_sdram_c, voltage_sdram_i, voltage_sdram_p;
+ int max_voltage_core, min_voltage_core;
+ int max_voltage_sdram_c, min_voltage_sdram_c;
+ int max_voltage_sdram_i, min_voltage_sdram_i;
+ int max_voltage_sdram_p, min_voltage_sdram_p;
+ int turbo, temperature;
+
+ VC_LOCK(sc);
+
+ /* current clock */
+ arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM);
+ core_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE);
+ sdram_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM);
+
+ /* max/min clock */
+ arm_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM);
+ arm_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM);
+ core_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE);
+ core_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE);
+ sdram_max_freq = bcm2835_cpufreq_get_max_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM);
+ sdram_min_freq = bcm2835_cpufreq_get_min_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM);
+
+ /* turbo mode */
+ turbo = bcm2835_cpufreq_get_turbo(sc);
+ if (turbo > 0)
+ sc->turbo_mode = BCM2835_MBOX_TURBO_ON;
+ else
+ sc->turbo_mode = BCM2835_MBOX_TURBO_OFF;
+
+ /* voltage */
+ voltage_core = bcm2835_cpufreq_get_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_CORE);
+ voltage_sdram_c = bcm2835_cpufreq_get_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+ voltage_sdram_i = bcm2835_cpufreq_get_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+ voltage_sdram_p = bcm2835_cpufreq_get_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+
+ /* current values (offset from 1.2V) */
+ sc->voltage_core = voltage_core;
+ sc->voltage_sdram = voltage_sdram_c;
+ sc->voltage_sdram_c = voltage_sdram_c;
+ sc->voltage_sdram_i = voltage_sdram_i;
+ sc->voltage_sdram_p = voltage_sdram_p;
+
+ /* max/min voltage */
+ max_voltage_core = bcm2835_cpufreq_get_max_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_CORE);
+ min_voltage_core = bcm2835_cpufreq_get_min_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_CORE);
+ max_voltage_sdram_c = bcm2835_cpufreq_get_max_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+ max_voltage_sdram_i = bcm2835_cpufreq_get_max_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+ max_voltage_sdram_p = bcm2835_cpufreq_get_max_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+ min_voltage_sdram_c = bcm2835_cpufreq_get_min_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_C);
+ min_voltage_sdram_i = bcm2835_cpufreq_get_min_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_I);
+ min_voltage_sdram_p = bcm2835_cpufreq_get_min_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_SDRAM_P);
+
+ /* temperature */
+ temperature = bcm2835_cpufreq_get_temperature(sc);
+
+ /* show result */
+ if (cpufreq_verbose || bootverbose) {
+ device_printf(sc->dev, "Boot settings:\n");
+ device_printf(sc->dev,
+ "current ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
+ HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
+ (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
+
+ device_printf(sc->dev,
+ "max/min ARM %d/%dMHz, Core %d/%dMHz, SDRAM %d/%dMHz\n",
+ HZ2MHZ(arm_max_freq), HZ2MHZ(arm_min_freq),
+ HZ2MHZ(core_max_freq), HZ2MHZ(core_min_freq),
+ HZ2MHZ(sdram_max_freq), HZ2MHZ(sdram_min_freq));
+
+ device_printf(sc->dev,
+ "current Core %dmV, SDRAM_C %dmV, SDRAM_I %dmV, "
+ "SDRAM_P %dmV\n",
+ OFFSET2MVOLT(voltage_core), OFFSET2MVOLT(voltage_sdram_c),
+ OFFSET2MVOLT(voltage_sdram_i),
+ OFFSET2MVOLT(voltage_sdram_p));
+
+ device_printf(sc->dev,
+ "max/min Core %d/%dmV, SDRAM_C %d/%dmV, SDRAM_I %d/%dmV, "
+ "SDRAM_P %d/%dmV\n",
+ OFFSET2MVOLT(max_voltage_core),
+ OFFSET2MVOLT(min_voltage_core),
+ OFFSET2MVOLT(max_voltage_sdram_c),
+ OFFSET2MVOLT(min_voltage_sdram_c),
+ OFFSET2MVOLT(max_voltage_sdram_i),
+ OFFSET2MVOLT(min_voltage_sdram_i),
+ OFFSET2MVOLT(max_voltage_sdram_p),
+ OFFSET2MVOLT(min_voltage_sdram_p));
+
+ device_printf(sc->dev,
+ "Temperature %d.%dC\n", (temperature / 1000),
+ (temperature % 1000) / 100);
+ } else { /* !cpufreq_verbose && !bootverbose */
+ device_printf(sc->dev,
+ "ARM %dMHz, Core %dMHz, SDRAM %dMHz, Turbo %s\n",
+ HZ2MHZ(arm_freq), HZ2MHZ(core_freq), HZ2MHZ(sdram_freq),
+ (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) ? "ON" : "OFF");
+ }
+
+ /* keep in softc (MHz/mV) */
+ sc->arm_max_freq = HZ2MHZ(arm_max_freq);
+ sc->arm_min_freq = HZ2MHZ(arm_min_freq);
+ sc->core_max_freq = HZ2MHZ(core_max_freq);
+ sc->core_min_freq = HZ2MHZ(core_min_freq);
+ sc->sdram_max_freq = HZ2MHZ(sdram_max_freq);
+ sc->sdram_min_freq = HZ2MHZ(sdram_min_freq);
+ sc->max_voltage_core = OFFSET2MVOLT(max_voltage_core);
+ sc->min_voltage_core = OFFSET2MVOLT(min_voltage_core);
+
+ /* if turbo is on, set to max values */
+ if (sc->turbo_mode == BCM2835_MBOX_TURBO_ON) {
+ bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
+ arm_max_freq);
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
+ core_max_freq);
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_max_freq);
+ DELAY(TRANSITION_LATENCY);
+ } else {
+ bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_ARM,
+ arm_min_freq);
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc, BCM2835_MBOX_CLOCK_ID_CORE,
+ core_min_freq);
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM, sdram_min_freq);
+ DELAY(TRANSITION_LATENCY);
+ }
+
+ VC_UNLOCK(sc);
+
+ /* add human readable temperature to dev.cpu node */
+ cpu = device_get_parent(sc->dev);
+ if (cpu != NULL) {
+ ctx = device_get_sysctl_ctx(cpu);
+ SYSCTL_ADD_PROC(ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(cpu)), OID_AUTO,
+ "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+ sysctl_bcm2835_devcpu_temperature, "IK",
+ "Current SoC temperature");
+ }
+
+ /* release this hook (continue boot) */
+ config_intrhook_disestablish(&sc->init_hook);
+}
+
+static void
+bcm2835_cpufreq_identify(driver_t *driver, device_t parent)
+{
+
+ DPRINTF("driver=%p, parent=%p\n", driver, parent);
+ if (device_find_child(parent, "bcm2835_cpufreq", -1) != NULL)
+ return;
+ if (BUS_ADD_CHILD(parent, 0, "bcm2835_cpufreq", -1) == NULL)
+ device_printf(parent, "add child failed\n");
+}
+
+static int
+bcm2835_cpufreq_probe(device_t dev)
+{
+
+ device_set_desc(dev, "CPU Frequency Control");
+ return (0);
+}
+
+static void
+bcm2835_cpufreq_cb(void *arg, bus_dma_segment_t *segs, int nseg, int err)
+{
+ bus_addr_t *addr;
+
+ if (err)
+ return;
+ addr = (bus_addr_t *)arg;
+ *addr = PHYS_TO_VCBUS(segs[0].ds_addr);
+}
+
+static int
+bcm2835_cpufreq_attach(device_t dev)
+{
+ struct bcm2835_cpufreq_softc *sc;
+ struct sysctl_oid *oid;
+ int err;
+
+ /* set self dev */
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* initial values */
+ sc->arm_max_freq = -1;
+ sc->arm_min_freq = -1;
+ sc->core_max_freq = -1;
+ sc->core_min_freq = -1;
+ sc->sdram_max_freq = -1;
+ sc->sdram_min_freq = -1;
+ sc->max_voltage_core = 0;
+ sc->min_voltage_core = 0;
+
+ /* create VC mbox buffer */
+ sc->dma_size = PAGE_SIZE;
+ err = bus_dma_tag_create(
+ bus_get_dma_tag(sc->dev),
+ PAGE_SIZE, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ sc->dma_size, 1, /* maxsize, nsegments */
+ sc->dma_size, 0, /* maxsegsize, flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->dma_tag);
+ if (err) {
+ device_printf(dev, "can't create DMA tag\n");
+ return (ENXIO);
+ }
+
+ err = bus_dmamem_alloc(sc->dma_tag, (void **)&sc->dma_buf, 0,
+ &sc->dma_map);
+ if (err) {
+ bus_dma_tag_destroy(sc->dma_tag);
+ device_printf(dev, "can't allocate dmamem\n");
+ return (ENXIO);
+ }
+
+ err = bus_dmamap_load(sc->dma_tag, sc->dma_map, sc->dma_buf,
+ sc->dma_size, bcm2835_cpufreq_cb, &sc->dma_phys, 0);
+ if (err) {
+ bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
+ bus_dma_tag_destroy(sc->dma_tag);
+ device_printf(dev, "can't load DMA map\n");
+ return (ENXIO);
+ }
+ /* OK, ready to use VC buffer */
+
+ /* setup sysctl at first device */
+ if (device_get_unit(dev) == 0) {
+ sysctl_ctx_init(&bcm2835_sysctl_ctx);
+ /* create node for hw.cpufreq */
+ oid = SYSCTL_ADD_NODE(&bcm2835_sysctl_ctx,
+ SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, "cpufreq",
+ CTLFLAG_RD, NULL, "");
+
+ /* Frequency (Hz) */
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "arm_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ sysctl_bcm2835_cpufreq_arm_freq, "IU",
+ "ARM frequency (Hz)");
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "core_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ sysctl_bcm2835_cpufreq_core_freq, "IU",
+ "Core frequency (Hz)");
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "sdram_freq", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ sysctl_bcm2835_cpufreq_sdram_freq, "IU",
+ "SDRAM frequency (Hz)");
+
+ /* Turbo state */
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "turbo", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ sysctl_bcm2835_cpufreq_turbo, "IU",
+ "Disables dynamic clocking");
+
+ /* Voltage (offset from 1.2V in units of 0.025V) */
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "voltage_core", CTLTYPE_INT | CTLFLAG_RW, sc, 0,
+ sysctl_bcm2835_cpufreq_voltage_core, "I",
+ "ARM/GPU core voltage"
+ "(offset from 1.2V in units of 0.025V)");
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "voltage_sdram", CTLTYPE_INT | CTLFLAG_WR, sc,
+ 0, sysctl_bcm2835_cpufreq_voltage_sdram, "I",
+ "SDRAM voltage (offset from 1.2V in units of 0.025V)");
+
+ /* Voltage individual SDRAM */
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "voltage_sdram_c", CTLTYPE_INT | CTLFLAG_RW, sc,
+ 0, sysctl_bcm2835_cpufreq_voltage_sdram_c, "I",
+ "SDRAM controller voltage"
+ "(offset from 1.2V in units of 0.025V)");
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "voltage_sdram_i", CTLTYPE_INT | CTLFLAG_RW, sc,
+ 0, sysctl_bcm2835_cpufreq_voltage_sdram_i, "I",
+ "SDRAM I/O voltage (offset from 1.2V in units of 0.025V)");
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "voltage_sdram_p", CTLTYPE_INT | CTLFLAG_RW, sc,
+ 0, sysctl_bcm2835_cpufreq_voltage_sdram_p, "I",
+ "SDRAM phy voltage (offset from 1.2V in units of 0.025V)");
+
+ /* Temperature */
+ SYSCTL_ADD_PROC(&bcm2835_sysctl_ctx, SYSCTL_CHILDREN(oid),
+ OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, sc, 0,
+ sysctl_bcm2835_cpufreq_temperature, "I",
+ "SoC temperature (thousandths of a degree C)");
+ }
+
+ /* ARM->VC lock */
+ sema_init(&vc_sema, 1, "vcsema");
+
+ /* register callback for using mbox when interrupts are enabled */
+ sc->init_hook.ich_func = bcm2835_cpufreq_init;
+ sc->init_hook.ich_arg = sc;
+
+ if (config_intrhook_establish(&sc->init_hook) != 0) {
+ bus_dmamap_unload(sc->dma_tag, sc->dma_map);
+ bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
+ bus_dma_tag_destroy(sc->dma_tag);
+ device_printf(dev, "config_intrhook_establish failed\n");
+ return (ENOMEM);
+ }
+
+ /* this device is controlled by cpufreq(4) */
+ cpufreq_register(dev);
+
+ return (0);
+}
+
+static int
+bcm2835_cpufreq_detach(device_t dev)
+{
+ struct bcm2835_cpufreq_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ sema_destroy(&vc_sema);
+
+ if (sc->dma_phys != 0)
+ bus_dmamap_unload(sc->dma_tag, sc->dma_map);
+ if (sc->dma_buf != NULL)
+ bus_dmamem_free(sc->dma_tag, sc->dma_buf, sc->dma_map);
+ if (sc->dma_tag != NULL)
+ bus_dma_tag_destroy(sc->dma_tag);
+
+ return (cpufreq_unregister(dev));
+}
+
+static int
+bcm2835_cpufreq_set(device_t dev, const struct cf_setting *cf)
+{
+ struct bcm2835_cpufreq_softc *sc;
+ uint32_t rate_hz, rem;
+ int cur_freq, resp_freq, arm_freq, min_freq, core_freq;
+
+ if (cf == NULL || cf->freq < 0)
+ return (EINVAL);
+
+ sc = device_get_softc(dev);
+
+ /* setting clock (Hz) */
+ rate_hz = (uint32_t)MHZ2HZ(cf->freq);
+ rem = rate_hz % HZSTEP;
+ rate_hz -= rem;
+ if (rate_hz == 0)
+ return (EINVAL);
+
+ /* adjust min freq */
+ min_freq = sc->arm_min_freq;
+ if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
+ if (min_freq > cpufreq_lowest_freq)
+ min_freq = cpufreq_lowest_freq;
+
+ if (rate_hz < MHZ2HZ(min_freq) || rate_hz > MHZ2HZ(sc->arm_max_freq))
+ return (EINVAL);
+
+ /* set new value and verify it */
+ VC_LOCK(sc);
+ cur_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM);
+ resp_freq = bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM, rate_hz);
+ DELAY(TRANSITION_LATENCY);
+ arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM);
+
+ /*
+ * if non-turbo and lower than or equal min_freq,
+ * clock down core and sdram to default first.
+ */
+ if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON) {
+ core_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE);
+ if (rate_hz > MHZ2HZ(sc->arm_min_freq)) {
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE,
+ MHZ2HZ(sc->core_max_freq));
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM,
+ MHZ2HZ(sc->sdram_max_freq));
+ DELAY(TRANSITION_LATENCY);
+ } else {
+ if (sc->core_min_freq < DEFAULT_CORE_FREQUENCY &&
+ core_freq > DEFAULT_CORE_FREQUENCY) {
+ /* first, down to 250, then down to min */
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE,
+ MHZ2HZ(DEFAULT_CORE_FREQUENCY));
+ DELAY(TRANSITION_LATENCY);
+ /* reset core voltage */
+ bcm2835_cpufreq_set_voltage(sc,
+ BCM2835_MBOX_VOLTAGE_ID_CORE, 0);
+ DELAY(TRANSITION_LATENCY);
+ }
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_CORE,
+ MHZ2HZ(sc->core_min_freq));
+ DELAY(TRANSITION_LATENCY);
+ bcm2835_cpufreq_set_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_SDRAM,
+ MHZ2HZ(sc->sdram_min_freq));
+ DELAY(TRANSITION_LATENCY);
+ }
+ }
+
+ VC_UNLOCK(sc);
+
+ if (resp_freq < 0 || arm_freq < 0 || resp_freq != arm_freq) {
+ device_printf(dev, "wrong freq\n");
+ return (EIO);
+ }
+ DPRINTF("cpufreq: %d -> %d\n", cur_freq, arm_freq);
+
+ return (0);
+}
+
+static int
+bcm2835_cpufreq_get(device_t dev, struct cf_setting *cf)
+{
+ struct bcm2835_cpufreq_softc *sc;
+ int arm_freq;
+
+ if (cf == NULL)
+ return (EINVAL);
+
+ sc = device_get_softc(dev);
+ memset(cf, CPUFREQ_VAL_UNKNOWN, sizeof(*cf));
+ cf->dev = NULL;
+
+ /* get cuurent value */
+ VC_LOCK(sc);
+ arm_freq = bcm2835_cpufreq_get_clock_rate(sc,
+ BCM2835_MBOX_CLOCK_ID_ARM);
+ VC_UNLOCK(sc);
+ if (arm_freq < 0) {
+ device_printf(dev, "can't get clock\n");
+ return (EINVAL);
+ }
+
+ /* CPU clock in MHz or 100ths of a percent. */
+ cf->freq = HZ2MHZ(arm_freq);
+ /* Voltage in mV. */
+ cf->volts = CPUFREQ_VAL_UNKNOWN;
+ /* Power consumed in mW. */
+ cf->power = CPUFREQ_VAL_UNKNOWN;
+ /* Transition latency in us. */
+ cf->lat = TRANSITION_LATENCY;
+ /* Driver providing this setting. */
+ cf->dev = dev;
+
+ return (0);
+}
+
+static int
+bcm2835_cpufreq_make_freq_list(device_t dev, struct cf_setting *sets,
+ int *count)
+{
+ struct bcm2835_cpufreq_softc *sc;
+ int freq, min_freq, volts, rem;
+ int idx;
+
+ sc = device_get_softc(dev);
+ freq = sc->arm_max_freq;
+ min_freq = sc->arm_min_freq;
+
+ /* adjust head freq to STEP */
+ rem = freq % MHZSTEP;
+ freq -= rem;
+ if (freq < min_freq)
+ freq = min_freq;
+
+ /* if non-turbo, add extra low freq */
+ if (sc->turbo_mode != BCM2835_MBOX_TURBO_ON)
+ if (min_freq > cpufreq_lowest_freq)
+ min_freq = cpufreq_lowest_freq;
+
+ /* from freq to min_freq */
+ for (idx = 0; idx < *count && freq >= min_freq; idx++) {
+ if (freq > sc->arm_min_freq)
+ volts = sc->max_voltage_core;
+ else
+ volts = sc->min_voltage_core;
+ sets[idx].freq = freq;
+ sets[idx].volts = volts;
+ sets[idx].lat = TRANSITION_LATENCY;
+ sets[idx].dev = dev;
+ freq -= MHZSTEP;
+ }
+ *count = ++idx;
+
+ return (0);
+}
+
+static int
+bcm2835_cpufreq_settings(device_t dev, struct cf_setting *sets, int *count)
+{
+ struct bcm2835_cpufreq_softc *sc;
+
+ if (sets == NULL || count == NULL)
+ return (EINVAL);
+
+ sc = device_get_softc(dev);
+ if (sc->arm_min_freq < 0 || sc->arm_max_freq < 0) {
+ printf("device is not configured\n");
+ return (EINVAL);
+ }
+
+ /* fill data with unknown value */
+ memset(sets, CPUFREQ_VAL_UNKNOWN, sizeof(*sets) * (*count));
+ /* create new array up to count */
+ bcm2835_cpufreq_make_freq_list(dev, sets, count);
+
+ return (0);
+}
+
+static int
+bcm2835_cpufreq_type(device_t dev, int *type)
+{
+
+ if (type == NULL)
+ return (EINVAL);
+ *type = CPUFREQ_TYPE_ABSOLUTE;
+
+ return (0);
+}
+
+static device_method_t bcm2835_cpufreq_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, bcm2835_cpufreq_identify),
+ DEVMETHOD(device_probe, bcm2835_cpufreq_probe),
+ DEVMETHOD(device_attach, bcm2835_cpufreq_attach),
+ DEVMETHOD(device_detach, bcm2835_cpufreq_detach),
+
+ /* cpufreq interface */
+ DEVMETHOD(cpufreq_drv_set, bcm2835_cpufreq_set),
+ DEVMETHOD(cpufreq_drv_get, bcm2835_cpufreq_get),
+ DEVMETHOD(cpufreq_drv_settings, bcm2835_cpufreq_settings),
+ DEVMETHOD(cpufreq_drv_type, bcm2835_cpufreq_type),
+
+ DEVMETHOD_END
+};
+
+static devclass_t bcm2835_cpufreq_devclass;
+static driver_t bcm2835_cpufreq_driver = {
+ "bcm2835_cpufreq",
+ bcm2835_cpufreq_methods,
+ sizeof(struct bcm2835_cpufreq_softc),
+};
+
+DRIVER_MODULE(bcm2835_cpufreq, cpu, bcm2835_cpufreq_driver,
+ bcm2835_cpufreq_devclass, 0, 0);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
index 7a06eb0..4d14892 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
@@ -83,10 +83,10 @@ struct bcm_intc_softc {
static struct bcm_intc_softc *bcm_intc_sc = NULL;
-#define intc_read_4(reg) \
- bus_space_read_4(bcm_intc_sc->intc_bst, bcm_intc_sc->intc_bsh, reg)
-#define intc_write_4(reg, val) \
- bus_space_write_4(bcm_intc_sc->intc_bst, bcm_intc_sc->intc_bsh, reg, val)
+#define intc_read_4(_sc, reg) \
+ bus_space_read_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg))
+#define intc_write_4(_sc, reg, val) \
+ bus_space_write_4((_sc)->intc_bst, (_sc)->intc_bsh, (reg), (val))
static int
bcm_intc_probe(device_t dev)
@@ -145,6 +145,7 @@ DRIVER_MODULE(intc, simplebus, bcm_intc_driver, bcm_intc_devclass, 0, 0);
int
arm_get_next_irq(int last_irq)
{
+ struct bcm_intc_softc *sc = bcm_intc_sc;
uint32_t pending;
int32_t irq = last_irq + 1;
@@ -154,7 +155,7 @@ arm_get_next_irq(int last_irq)
/* TODO: should we mask last_irq? */
if (irq < BANK1_START) {
- pending = intc_read_4(INTC_PENDING_BASIC);
+ pending = intc_read_4(sc, INTC_PENDING_BASIC);
if ((pending & 0xFF) == 0) {
irq = BANK1_START; /* skip to next bank */
} else do {
@@ -164,7 +165,7 @@ arm_get_next_irq(int last_irq)
} while (irq < BANK1_START);
}
if (irq < BANK2_START) {
- pending = intc_read_4(INTC_PENDING_BANK1);
+ pending = intc_read_4(sc, INTC_PENDING_BANK1);
if (pending == 0) {
irq = BANK2_START; /* skip to next bank */
} else do {
@@ -174,7 +175,7 @@ arm_get_next_irq(int last_irq)
} while (irq < BANK2_START);
}
if (irq < BANK3_START) {
- pending = intc_read_4(INTC_PENDING_BANK2);
+ pending = intc_read_4(sc, INTC_PENDING_BANK2);
if (pending != 0) do {
if (pending & (1 << IRQ_BANK2(irq)))
return irq;
@@ -187,14 +188,15 @@ arm_get_next_irq(int last_irq)
void
arm_mask_irq(uintptr_t nb)
{
+ struct bcm_intc_softc *sc = bcm_intc_sc;
dprintf("%s: %d\n", __func__, nb);
if (IS_IRQ_BASIC(nb))
- intc_write_4(INTC_DISABLE_BASIC, (1 << nb));
+ intc_write_4(sc, INTC_DISABLE_BASIC, (1 << nb));
else if (IS_IRQ_BANK1(nb))
- intc_write_4(INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb)));
+ intc_write_4(sc, INTC_DISABLE_BANK1, (1 << IRQ_BANK1(nb)));
else if (IS_IRQ_BANK2(nb))
- intc_write_4(INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb)));
+ intc_write_4(sc, INTC_DISABLE_BANK2, (1 << IRQ_BANK2(nb)));
else
printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
}
@@ -202,14 +204,15 @@ arm_mask_irq(uintptr_t nb)
void
arm_unmask_irq(uintptr_t nb)
{
+ struct bcm_intc_softc *sc = bcm_intc_sc;
dprintf("%s: %d\n", __func__, nb);
if (IS_IRQ_BASIC(nb))
- intc_write_4(INTC_ENABLE_BASIC, (1 << nb));
+ intc_write_4(sc, INTC_ENABLE_BASIC, (1 << nb));
else if (IS_IRQ_BANK1(nb))
- intc_write_4(INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb)));
+ intc_write_4(sc, INTC_ENABLE_BANK1, (1 << IRQ_BANK1(nb)));
else if (IS_IRQ_BANK2(nb))
- intc_write_4(INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb)));
+ intc_write_4(sc, INTC_ENABLE_BANK2, (1 << IRQ_BANK2(nb)));
else
printf("arm_mask_irq: Invalid IRQ number: %d\n", nb);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
index 7628eb6..f87003f 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.c
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/rman.h>
+#include <sys/sema.h>
#include <sys/timeet.h>
#include <sys/timetc.h>
#include <sys/watchdog.h>
@@ -88,8 +89,8 @@ struct bcm_mbox_softc {
void* intr_hl;
bus_space_tag_t bst;
bus_space_handle_t bsh;
- int valid[BCM2835_MBOX_CHANS];
int msg[BCM2835_MBOX_CHANS];
+ struct sema sema[BCM2835_MBOX_CHANS];
};
#define mbox_read_4(sc, reg) \
@@ -105,23 +106,19 @@ bcm_mbox_intr(void *arg)
uint32_t data;
uint32_t msg;
- MBOX_LOCK(sc);
while (!(mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY)) {
msg = mbox_read_4(sc, REG_READ);
dprintf("bcm_mbox_intr: raw data %08x\n", msg);
chan = MBOX_CHAN(msg);
data = MBOX_DATA(msg);
- if (sc->valid[chan]) {
+ if (sc->msg[chan]) {
printf("bcm_mbox_intr: channel %d oveflow\n", chan);
continue;
}
dprintf("bcm_mbox_intr: chan %d, data %08x\n", chan, data);
- sc->msg[chan] = data;
- sc->valid[chan] = 1;
- wakeup(&sc->msg[chan]);
-
+ sc->msg[chan] = msg;
+ sema_post(&sc->sema[chan]);
}
- MBOX_UNLOCK(sc);
}
static int
@@ -172,12 +169,13 @@ bcm_mbox_attach(device_t dev)
mtx_init(&sc->lock, "vcio mbox", NULL, MTX_DEF);
for (i = 0; i < BCM2835_MBOX_CHANS; i++) {
- sc->valid[0] = 0;
- sc->msg[0] = 0;
+ sc->msg[i] = 0;
+ sema_init(&sc->sema[i], 0, "mbox");
}
/* Read all pending messages */
- bcm_mbox_intr(sc);
+ while ((mbox_read_4(sc, REG_STATUS) & STATUS_EMPTY) == 0)
+ (void)mbox_read_4(sc, REG_READ);
mbox_write_4(sc, REG_CONFIG, CONFIG_DATA_IRQ);
@@ -219,10 +217,18 @@ bcm_mbox_read(device_t dev, int chan, uint32_t *data)
dprintf("bcm_mbox_read: chan %d\n", chan);
MBOX_LOCK(sc);
- while (!sc->valid[chan])
- msleep(&sc->msg[chan], &sc->lock, PZERO, "vcio mbox read", 0);
- *data = sc->msg[chan];
- sc->valid[chan] = 0;
+ while (sema_trywait(&sc->sema[chan]) == 0) {
+ /* do not unlock sc while waiting for the mbox */
+ if (sema_timedwait(&sc->sema[chan], 10*hz) == 0)
+ break;
+ printf("timeout sema for chan %d\n", chan);
+ }
+ /*
+ * get data from intr handler, the same channel is never coming
+ * because of holding sc lock.
+ */
+ *data = MBOX_DATA(sc->msg[chan]);
+ sc->msg[chan] = 0;
MBOX_UNLOCK(sc);
dprintf("bcm_mbox_read: chan %d, data %08x\n", chan, *data);
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
index 52f48e4..17e59eb 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox.h
@@ -36,6 +36,7 @@
#define BCM2835_MBOX_CHAN_LEDS 4
#define BCM2835_MBOX_CHAN_BUTTONS 5
#define BCM2835_MBOX_CHAN_TS 6
-#define BCM2835_MBOX_CHANS 7
+#define BCM2835_MBOX_CHAN_PROP 8
+#define BCM2835_MBOX_CHANS 9
#endif /* _BCM2835_MBOX_H_ */
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
new file mode 100644
index 0000000..a2e212e
--- /dev/null
+++ b/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h
@@ -0,0 +1,273 @@
+/*-
+ * Copyright (C) 2013-2014 Daisuke Aoyama <aoyama@peach.ne.jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BCM2835_MBOX_PROP_H_
+#define _BCM2835_MBOX_PROP_H_
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+/*
+ * Mailbox property interface:
+ * https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+ */
+#define BCM2835_MBOX_CODE_REQ 0
+#define BCM2835_MBOX_CODE_RESP_SUCCESS 0x80000000
+#define BCM2835_MBOX_CODE_RESP_ERROR 0x80000001
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000
+
+struct bcm2835_mbox_hdr {
+ uint32_t buf_size;
+ uint32_t code;
+};
+
+struct bcm2835_mbox_tag_hdr {
+ uint32_t tag;
+ uint32_t val_buf_size;
+ uint32_t val_len;
+};
+
+#define BCM2835_MBOX_CLOCK_ID_EMMC 0x00000001
+#define BCM2835_MBOX_CLOCK_ID_UART 0x00000002
+#define BCM2835_MBOX_CLOCK_ID_ARM 0x00000003
+#define BCM2835_MBOX_CLOCK_ID_CORE 0x00000004
+#define BCM2835_MBOX_CLOCK_ID_V3D 0x00000005
+#define BCM2835_MBOX_CLOCK_ID_H264 0x00000006
+#define BCM2835_MBOX_CLOCK_ID_ISP 0x00000007
+#define BCM2835_MBOX_CLOCK_ID_SDRAM 0x00000008
+#define BCM2835_MBOX_CLOCK_ID_PIXEL 0x00000009
+#define BCM2835_MBOX_CLOCK_ID_PWM 0x0000000a
+
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
+#define BCM2835_MBOX_TAG_SET_CLOCK_RATE 0x00038002
+#define BCM2835_MBOX_TAG_GET_MAX_CLOCK_RATE 0x00030004
+#define BCM2835_MBOX_TAG_GET_MIN_CLOCK_RATE 0x00030007
+
+struct msg_get_clock_rate {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t clock_id;
+ } req;
+ struct {
+ uint32_t clock_id;
+ uint32_t rate_hz;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_set_clock_rate {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t clock_id;
+ uint32_t rate_hz;
+ } req;
+ struct {
+ uint32_t clock_id;
+ uint32_t rate_hz;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_get_max_clock_rate {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t clock_id;
+ } req;
+ struct {
+ uint32_t clock_id;
+ uint32_t rate_hz;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_get_min_clock_rate {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t clock_id;
+ } req;
+ struct {
+ uint32_t clock_id;
+ uint32_t rate_hz;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+#define BCM2835_MBOX_TURBO_ON 1
+#define BCM2835_MBOX_TURBO_OFF 0
+
+#define BCM2835_MBOX_TAG_GET_TURBO 0x00030009
+#define BCM2835_MBOX_TAG_SET_TURBO 0x00038009
+
+struct msg_get_turbo {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t id;
+ } req;
+ struct {
+ uint32_t id;
+ uint32_t level;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_set_turbo {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t id;
+ uint32_t level;
+ } req;
+ struct {
+ uint32_t id;
+ uint32_t level;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+#define BCM2835_MBOX_VOLTAGE_ID_CORE 0x00000001
+#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_C 0x00000002
+#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_P 0x00000003
+#define BCM2835_MBOX_VOLTAGE_ID_SDRAM_I 0x00000004
+
+#define BCM2835_MBOX_TAG_GET_VOLTAGE 0x00030003
+#define BCM2835_MBOX_TAG_SET_VOLTAGE 0x00038003
+#define BCM2835_MBOX_TAG_GET_MAX_VOLTAGE 0x00030005
+#define BCM2835_MBOX_TAG_GET_MIN_VOLTAGE 0x00030008
+
+struct msg_get_voltage {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t voltage_id;
+ } req;
+ struct {
+ uint32_t voltage_id;
+ uint32_t value;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_set_voltage {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t voltage_id;
+ uint32_t value;
+ } req;
+ struct {
+ uint32_t voltage_id;
+ uint32_t value;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_get_max_voltage {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t voltage_id;
+ } req;
+ struct {
+ uint32_t voltage_id;
+ uint32_t value;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_get_min_voltage {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t voltage_id;
+ } req;
+ struct {
+ uint32_t voltage_id;
+ uint32_t value;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+#define BCM2835_MBOX_TAG_GET_TEMPERATURE 0x00030006
+#define BCM2835_MBOX_TAG_GET_MAX_TEMPERATURE 0x0003000a
+
+struct msg_get_temperature {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t temperature_id;
+ } req;
+ struct {
+ uint32_t temperature_id;
+ uint32_t value;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+struct msg_get_max_temperature {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ uint32_t temperature_id;
+ } req;
+ struct {
+ uint32_t temperature_id;
+ uint32_t value;
+ } resp;
+ } body;
+ uint32_t end_tag;
+};
+
+#endif /* _BCM2835_MBOX_PROP_H_ */
diff --git a/sys/arm/broadcom/bcm2835/files.bcm2835 b/sys/arm/broadcom/bcm2835/files.bcm2835
index 865f2d0..11158cb 100644
--- a/sys/arm/broadcom/bcm2835/files.bcm2835
+++ b/sys/arm/broadcom/bcm2835/files.bcm2835
@@ -2,6 +2,7 @@
arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc
arm/broadcom/bcm2835/bcm2835_common.c optional fdt
+arm/broadcom/bcm2835/bcm2835_cpufreq.c standard
arm/broadcom/bcm2835/bcm2835_dma.c standard
arm/broadcom/bcm2835/bcm2835_fb.c optional sc
arm/broadcom/bcm2835/bcm2835_fbd.c optional vt
@@ -25,3 +26,4 @@ arm/arm/cpufunc_asm_armv6.S standard
kern/kern_clocksource.c standard
dev/mbox/mbox_if.m standard
+dev/ofw/ofw_cpu.c standard
diff --git a/sys/arm/broadcom/bcm2835/std.bcm2835 b/sys/arm/broadcom/bcm2835/std.bcm2835
index ebc1fb0..026f5b2 100644
--- a/sys/arm/broadcom/bcm2835/std.bcm2835
+++ b/sys/arm/broadcom/bcm2835/std.bcm2835
@@ -2,6 +2,7 @@
machine arm armv6
cpu CPU_ARM1176
+makeoptions CONF_CFLAGS="-mcpu=arm1176jzf-s -Wa,-mcpu=arm1176jzf-s"
files "../broadcom/bcm2835/files.bcm2835"
diff --git a/sys/arm/conf/APALIS-IMX6 b/sys/arm/conf/APALIS-IMX6
index 137677f..ceb21c7 100644
--- a/sys/arm/conf/APALIS-IMX6
+++ b/sys/arm/conf/APALIS-IMX6
@@ -26,6 +26,6 @@ makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=apalis-imx6.dts
+options FDT
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=apalis-imx6.dts
diff --git a/sys/arm/conf/ARMADAXP b/sys/arm/conf/ARMADAXP
index edfe75c..ce0f0d4 100644
--- a/sys/arm/conf/ARMADAXP
+++ b/sys/arm/conf/ARMADAXP
@@ -1,8 +1,22 @@
#
# Custom kernel for Marvell Armada XP
#
-# $FreeBSD$
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
+# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
+#
+# The handbook is also available locally in /usr/share/doc/handbook
+# if you've installed the doc distribution, otherwise always see the
+# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
+# latest information.
#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
+# in NOTES.
+#
+# $FreeBSD$
ident MV-88F78XX0
include "../mv/armadaxp/std.mv78x60"
@@ -10,58 +24,75 @@ include "../mv/armadaxp/std.mv78x60"
options SOC_MV_ARMADAXP
makeoptions MODULES_OVERRIDE=""
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
+options HZ=1000
#options SCHED_ULE # ULE scheduler
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
options FFS # Berkeley Fast Filesystem
-options NFSCL # Network Filesystem Client
+options SOFTUPDATES # Enable FFS soft updates support
+options UFS_ACL # Support for access control lists
+options UFS_DIRHASH # Improve performance on big directories
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
-options BOOTP
-options BOOTP_NFSROOT
-options BOOTP_NFSV3
-options BOOTP_WIRED_TO=mge0
-
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT
-options ROOTDEVNAME=\"ufs:/dev/da0p1\"
-
+options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options MUTEX_NOINLINE
-options RWLOCK_NOINLINE
-options NO_FFS_SNAPSHOT
-options NO_SWAPPING
-options VFP
-
-options SMP
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-# Debugging
-#options VERBOSE_SYSINIT
+# Debugging for use in -current
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
options ALT_BREAK_TO_DEBUGGER
-options DDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
options GDB
-#options DIAGNOSTIC
#options INVARIANTS # Enable calls of extra sanity checking
#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options KDB
-options KDB_TRACE
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options WITNESS_KDB
+#options DIAGNOSTIC
#options KTR
#options KTR_VERBOSE=0
#options KTR_ENTRIES=16384
#options KTR_MASK=(KTR_SPARE2)
#options KTR_COMPILE=KTR_ALL
-#options WITNESS # Enable checks to detect deadlocks and cycles
-#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-#options WITNESS_KDB
+
+# NFS root from boopt/dhcp
+options BOOTP
+options BOOTP_NFSROOT
+options BOOTP_NFSV3
+options BOOTP_WIRED_TO=mge0
+
+options ROOTDEVNAME=\"ufs:/dev/da0p1\"
+
+options MUTEX_NOINLINE
+options RWLOCK_NOINLINE
+options NO_FFS_SNAPSHOT
+options NO_SWAPPING
# Pseudo devices
device random
@@ -94,14 +125,13 @@ device mge # Marvell Gigabit Ethernet controller
device mii
device e1000phy
device bpf
-options HZ=1000
options DEVICE_POLLING
device vlan
#PCI/PCIE
device pci
-#FDT
-options FDT
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=db78460.dts
diff --git a/sys/arm/conf/BEAGLEBONE b/sys/arm/conf/BEAGLEBONE
index 0363274..6f7e53e 100644
--- a/sys/arm/conf/BEAGLEBONE
+++ b/sys/arm/conf/BEAGLEBONE
@@ -1,10 +1,11 @@
+#
# BEAGLEBONE -- Custom configuration for the BeagleBone ARM development
# platforms, check out http://www.beagleboard.org/bone and
# http://www.beagleboard.org/black. This kernel config file is used for the
# original BeagleBone and the BeagleBone Black.
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -28,37 +29,47 @@ makeoptions WITHOUT_MODULES="ahc"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
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 GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options PREEMPTION
options PLATFORM
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
@@ -66,19 +77,19 @@ options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-options NFSCL
-#options NFSD
-options NFSLOCKD
+# NFS server support
+#options NFSD
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCL
+# NFS root from boopt/dhcp
+#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
-#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=cpsw0
+# Boot device is 2nd slice on MMC/SD card
+options ROOTDEVNAME=\"ufs:mmcsd0s2\"
+
# MMC/SD/SDIO Card slot support
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
@@ -90,9 +101,6 @@ device iic
device ti_i2c
device am335x_pmic # AM335x Power Management IC (TPC65217)
-# Boot device is 2nd slice on MMC/SD card
-options ROOTDEVNAME=\"ufs:mmcsd0s2\"
-
# Console and misc
device uart
device uart_ns8250
@@ -148,6 +156,6 @@ device usb_template # Control of the gadget
device usfs
# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=beaglebone.dts
+options FDT # Configure using FDT/DTB data
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=beaglebone.dts
diff --git a/sys/arm/conf/CHROMEBOOK-PEACH-PIT b/sys/arm/conf/CHROMEBOOK-PEACH-PIT
index 7bcfed7..e01128c 100644
--- a/sys/arm/conf/CHROMEBOOK-PEACH-PIT
+++ b/sys/arm/conf/CHROMEBOOK-PEACH-PIT
@@ -33,15 +33,15 @@ device kbdmux
device ukbd
# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCL
-#options BOOTP_NFSROOT
-#options BOOTP_COMPAT
-#options BOOTP
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ue0
-#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/root\"
+#options NFS_ROOT # NFS usable as /, requires NFSCL
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ue0
+#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/root\"
#FDT
-options FDT
-options FDT_DTB_STATIC
+options FDT
+options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=exynos5420-peach-pit.dts
diff --git a/sys/arm/conf/CNS11XXNAS b/sys/arm/conf/CNS11XXNAS
index 53640ff..903fd05 100644
--- a/sys/arm/conf/CNS11XXNAS
+++ b/sys/arm/conf/CNS11XXNAS
@@ -103,7 +103,7 @@ device bpf
device loop
device md
-device random # Entropy device
+device random # Entropy device
device usb
@@ -114,12 +114,12 @@ device umass
device scbus # SCSI bus (required for ATA/SCSI)
device da # Direct Access (disks)
device pass
-device cfi
+device cfi
#device udav # Davicom DM9601E USB
device geom_label
device geom_journal
-device geom_part_bsd
+device geom_part_bsd
options ROOTDEVNAME=\"ufs:da0s1a\"
diff --git a/sys/arm/conf/CUBIEBOARD b/sys/arm/conf/CUBIEBOARD
index a0b318e..40fe313 100644
--- a/sys/arm/conf/CUBIEBOARD
+++ b/sys/arm/conf/CUBIEBOARD
@@ -1,8 +1,9 @@
+#
# CUBIEBOARD -- Custom configuration for the CUBIEBOARD ARM development
# platform, check out http://www.cubieboard.org
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -27,36 +28,46 @@ makeoptions WITHOUT_MODULES="ahc"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options SCTP # Stream Control Transmission Protocol
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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
@@ -64,30 +75,24 @@ options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-#options NFSCL
-#options NFSSERVER # Network Filesystem Server
-#options NFSCLIENT # Network Filesystem Client
-
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+# NFS root from boopt/dhcp
+#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
-#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=cpsw0
-# MMC/SD/SDIO card slot support
-#device mmc # mmc/sd bus
-#device mmcsd # mmc/sd flash cards
-
# Boot device is 2nd slice on MMC/SD card
options ROOTDEVNAME=\"ufs:/dev/da0s2\"
+# MMC/SD/SDIO Card slot support
+#device mmc # mmc/sd bus
+#device mmcsd # mmc/sd flash cards
+
# ATA controllers
#device ahci # AHCI-compatible SATA controllers
#device ata # Legacy ATA/SATA controllers
-#options ATA_STATIC_ID # Static device numbering
+#options ATA_STATIC_ID # Static device numbering
# Console and misc
device uart
@@ -134,7 +139,7 @@ device emac
device miibus
# Flattened Device Tree
-options FDT
+options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=cubieboard.dts
diff --git a/sys/arm/conf/CUBIEBOARD2 b/sys/arm/conf/CUBIEBOARD2
index 1c5184c..785364c 100644
--- a/sys/arm/conf/CUBIEBOARD2
+++ b/sys/arm/conf/CUBIEBOARD2
@@ -1,8 +1,9 @@
+#
# CUBIEBOARD2 -- Custom configuration for the CUBIEBOARD2 ARM development
# platform, check out http://www.cubieboard.org
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -20,74 +21,79 @@
ident CUBIEBOARD2
-include "../allwinner/a20/std.a20"
+include "../allwinner/a20/std.a20"
makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options SCTP # Stream Control Transmission Protocol
options FFS # Berkeley Fast Filesystem
options SOFTUPDATES # Enable FFS soft updates support
-options UFS_ACL # Support for access control lists
+options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
-options MSDOSFS # MSDOS Filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options SYSVSHM # SYSV-style shared memory
+options SYSVMSG # SYSV-style message queues
+options SYSVSEM # SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options WITNESS # Enable checks to detect deadlocks and cycles
+options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-#options NFSCL
-#options NFSSERVER # Network Filesystem Server
-#options NFSCLIENT # Network Filesystem Client
-
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+# NFS root from boopt/dhcp
+#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
-#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=cpsw0
-# MMC/SD/SDIO card slot support
-#device mmc # mmc/sd bus
-#device mmcsd # mmc/sd flash cards
-
# Boot device is 2nd slice on MMC/SD card
options ROOTDEVNAME=\"ufs:/dev/da0s2\"
+# MMC/SD/SDIO Card slot support
+#device mmc # mmc/sd bus
+#device mmcsd # mmc/sd flash cards
+
# ATA controllers
-#device ahci # AHCI-compatible SATA controllers
-#device ata # Legacy ATA/SATA controllers
-#options ATA_STATIC_ID # Static device numbering
+#device ahci # AHCI-compatible SATA controllers
+#device ata # Legacy ATA/SATA controllers
+#options ATA_STATIC_ID # Static device numbering
# Console and misc
device uart
@@ -98,8 +104,8 @@ device md
device random # Entropy device
# I2C support
-#device iicbus
-#device iic
+#device iicbus
+#device iic
# GPIO
device gpio
@@ -114,8 +120,8 @@ device usb
options USB_DEBUG
#options USB_REQ_DEBUG
#options USB_VERBOSE
-#device uhci
-#device ohci
+#device uhci
+#device ohci
device ehci
device umass
@@ -125,7 +131,7 @@ device loop
device ether
device mii
device smscphy
-#device cpsw
+#device cpsw
device bpf
device emac
@@ -134,8 +140,7 @@ device emac
device miibus
# Flattened Device Tree
-options FDT
+options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=cubieboard2.dts
-options SMP # Enable multiple cores
diff --git a/sys/arm/conf/DIGI-CCWMX53 b/sys/arm/conf/DIGI-CCWMX53
index 7756558..20dec9c 100644
--- a/sys/arm/conf/DIGI-CCWMX53
+++ b/sys/arm/conf/DIGI-CCWMX53
@@ -22,7 +22,7 @@
include "IMX53"
ident DIGI-CCWMX53
-makeoptions WITHOUT_MODULES="ahc"
+makeoptions WITHOUT_MODULES="ahc"
# required for netbooting
#options BOOTP
@@ -34,5 +34,5 @@ makeoptions WITHOUT_MODULES="ahc"
#options ROOTDEVNAME=\"ufs:ada0s2a\"
# Flattened Device Tree
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=digi-ccwmx53.dts
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=digi-ccwmx53.dts
diff --git a/sys/arm/conf/DOCKSTAR b/sys/arm/conf/DOCKSTAR
index a3c57a1..ad1e74d 100644
--- a/sys/arm/conf/DOCKSTAR
+++ b/sys/arm/conf/DOCKSTAR
@@ -54,15 +54,15 @@ options FDT_DTB_STATIC
# Misc pseudo devices
device bpf # Required for DHCP
-device firmware # firmware(9) required for USB wlan
-device gif # IPv6 and IPv4 tunneling
+device firmware # firmware(9) required for USB wlan
+device gif # IPv6 and IPv4 tunneling
device loop # Network loopback
-device md # Memory/malloc disk
+device md # Memory/malloc disk
device pty # BSD-style compatibility pseudo ttys
device random # Entropy device
-device tun # Packet tunnel.
+device tun # Packet tunnel.
device ether # Required for all ethernet devices
-device vlan # 802.1Q VLAN support
+device vlan # 802.1Q VLAN support
device wlan # 802.11 WLAN support
# cam support for umass and ahci
@@ -80,66 +80,66 @@ device e1000phy
# USB
options USB_HOST_ALIGN=32 # Align DMA to cacheline
-#options USB_DEBUG # Compile in USB debug support
-device usb # Basic usb support
-device ehci # USB host controller
-device umass # Mass storage
-device uhid # Human-interface devices
-device rum # Ralink Technology RT2501USB wireless NICs
-device uath # Atheros AR5523 wireless NICs
-device ural # Ralink Technology RT2500USB wireless NICs
-device zyd # ZyDAS zb1211/zb1211b wireless NICs
-device urtw # Realtek RTL8187B/L USB
-device upgt # Conexant/Intersil PrismGT SoftMAC USB
-device u3g # USB-based 3G modems (Option, Huawei, Sierra)
+#options USB_DEBUG # Compile in USB debug support
+device usb # Basic usb support
+device ehci # USB host controller
+device umass # Mass storage
+device uhid # Human-interface devices
+device rum # Ralink Technology RT2501USB wireless NICs
+device uath # Atheros AR5523 wireless NICs
+device ural # Ralink Technology RT2500USB wireless NICs
+device zyd # ZyDAS zb1211/zb1211b wireless NICs
+device urtw # Realtek RTL8187B/L USB
+device upgt # Conexant/Intersil PrismGT SoftMAC USB
+device u3g # USB-based 3G modems (Option, Huawei, Sierra)
# I2C (TWSI)
device iic
device iicbus
# Sound
-device sound
-device snd_uaudio
+device sound
+device snd_uaudio
#crypto
-device cesa # Marvell security engine
-device crypto
-device cryptodev
+device cesa # Marvell security engine
+device crypto
+device cryptodev
# IPSec
-device enc
-options IPSEC
-options IPSEC_NAT_T
-options TCP_SIGNATURE # include support for RFC 2385
+device enc
+options IPSEC
+options IPSEC_NAT_T
+options TCP_SIGNATURE # include support for RFC 2385
# IPFW
-options IPFIREWALL
-options IPFIREWALL_DEFAULT_TO_ACCEPT
-options IPFIREWALL_VERBOSE
-options IPFIREWALL_VERBOSE_LIMIT=100
-options IPFIREWALL_NAT
-options LIBALIAS
-options DUMMYNET
-options IPDIVERT
+options IPFIREWALL
+options IPFIREWALL_DEFAULT_TO_ACCEPT
+options IPFIREWALL_VERBOSE
+options IPFIREWALL_VERBOSE_LIMIT=100
+options IPFIREWALL_NAT
+options LIBALIAS
+options DUMMYNET
+options IPDIVERT
#PF
-device pf
-device pflog
-device pfsync
+device pf
+device pflog
+device pfsync
# ALTQ, required for PF
-options ALTQ # Basic ALTQ support
-options ALTQ_CBQ # Class Based Queueing
-options ALTQ_RED # Random Early Detection
-options ALTQ_RIO # RED In/Out
-options ALTQ_HFSC # Hierarchical Packet Scheduler
-options ALTQ_CDNR # Traffic conditioner
-options ALTQ_PRIQ # Priority Queueing
-options ALTQ_NOPCC # Required if the TSC is unusable
+options ALTQ # Basic ALTQ support
+options ALTQ_CBQ # Class Based Queueing
+options ALTQ_RED # Random Early Detection
+options ALTQ_RIO # RED In/Out
+options ALTQ_HFSC # Hierarchical Packet Scheduler
+options ALTQ_CDNR # Traffic conditioner
+options ALTQ_PRIQ # Priority Queueing
+options ALTQ_NOPCC # Required if the TSC is unusable
#options ALTQ_DEBUG
# Debugging
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
options ALT_BREAK_TO_DEBUGGER
options DDB
@@ -154,7 +154,7 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require
# Enable these options for nfs root configured via BOOTP.
options NFSCL # Network Filesystem Client
options NFSLOCKD # Network Lock Manager
-#options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+#options NFS_ROOT # NFS usable as /, requires NFSCL
#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_NFSV3
diff --git a/sys/arm/conf/DREAMPLUG-1001 b/sys/arm/conf/DREAMPLUG-1001
index 7369592..135cba0 100644
--- a/sys/arm/conf/DREAMPLUG-1001
+++ b/sys/arm/conf/DREAMPLUG-1001
@@ -57,22 +57,22 @@ options FDT_DTB_STATIC
# Misc pseudo devices
device bpf # Required for DHCP
-device firmware # firmware(9) required for USB wlan
-device gif # IPv6 and IPv4 tunneling
+device firmware # firmware(9) required for USB wlan
+device gif # IPv6 and IPv4 tunneling
device loop # Network loopback
-device md # Memory/malloc disk
+device md # Memory/malloc disk
device pty # BSD-style compatibility pseudo ttys
device random # Entropy device
-device tun # Packet tunnel.
+device tun # Packet tunnel.
device ether # Required for all ethernet devices
-device vlan # 802.1Q VLAN support
+device vlan # 802.1Q VLAN support
device wlan # 802.11 WLAN support
# cam support for umass and ahci
device scbus
device pass
device da
-device cd
+device cd
# Serial ports
device uart
@@ -84,18 +84,18 @@ device e1000phy
# USB
options USB_HOST_ALIGN=32 # Align DMA to cacheline
-#options USB_DEBUG # Compile in USB debug support
-device usb # Basic usb support
-device ehci # USB host controller
-device umass # Mass storage
-device uhid # Human-interface devices
-device rum # Ralink Technology RT2501USB wireless NICs
-device uath # Atheros AR5523 wireless NICs
-device ural # Ralink Technology RT2500USB wireless NICs
-device zyd # ZyDAS zb1211/zb1211b wireless NICs
-device urtw # Realtek RTL8187B/L USB
-device upgt # Conexant/Intersil PrismGT SoftMAC USB
-device u3g # USB-based 3G modems (Option, Huawei, Sierra)
+#options USB_DEBUG # Compile in USB debug support
+device usb # Basic usb support
+device ehci # USB host controller
+device umass # Mass storage
+device uhid # Human-interface devices
+device rum # Ralink Technology RT2501USB wireless NICs
+device uath # Atheros AR5523 wireless NICs
+device ural # Ralink Technology RT2500USB wireless NICs
+device zyd # ZyDAS zb1211/zb1211b wireless NICs
+device urtw # Realtek RTL8187B/L USB
+device upgt # Conexant/Intersil PrismGT SoftMAC USB
+device u3g # USB-based 3G modems (Option, Huawei, Sierra)
# I2C (TWSI)
device iic
@@ -106,48 +106,48 @@ device mvs
device ahci
# Sound
-device sound
-device snd_uaudio
+device sound
+device snd_uaudio
#crypto
-device cesa # Marvell security engine
-device crypto
-device cryptodev
+device cesa # Marvell security engine
+device crypto
+device cryptodev
# IPSec
-device enc
-options IPSEC
-options IPSEC_NAT_T
-options TCP_SIGNATURE # include support for RFC 2385
+device enc
+options IPSEC
+options IPSEC_NAT_T
+options TCP_SIGNATURE # include support for RFC 2385
# IPFW
-options IPFIREWALL
-options IPFIREWALL_DEFAULT_TO_ACCEPT
-options IPFIREWALL_VERBOSE
-options IPFIREWALL_VERBOSE_LIMIT=100
-options IPFIREWALL_NAT
-options LIBALIAS
-options DUMMYNET
-options IPDIVERT
+options IPFIREWALL
+options IPFIREWALL_DEFAULT_TO_ACCEPT
+options IPFIREWALL_VERBOSE
+options IPFIREWALL_VERBOSE_LIMIT=100
+options IPFIREWALL_NAT
+options LIBALIAS
+options DUMMYNET
+options IPDIVERT
#PF
-device pf
-device pflog
-device pfsync
+device pf
+device pflog
+device pfsync
# ALTQ, required for PF
-options ALTQ # Basic ALTQ support
-options ALTQ_CBQ # Class Based Queueing
-options ALTQ_RED # Random Early Detection
-options ALTQ_RIO # RED In/Out
-options ALTQ_HFSC # Hierarchical Packet Scheduler
-options ALTQ_CDNR # Traffic conditioner
-options ALTQ_PRIQ # Priority Queueing
-options ALTQ_NOPCC # Required if the TSC is unusable
+options ALTQ # Basic ALTQ support
+options ALTQ_CBQ # Class Based Queueing
+options ALTQ_RED # Random Early Detection
+options ALTQ_RIO # RED In/Out
+options ALTQ_HFSC # Hierarchical Packet Scheduler
+options ALTQ_CDNR # Traffic conditioner
+options ALTQ_PRIQ # Priority Queueing
+options ALTQ_NOPCC # Required if the TSC is unusable
#options ALTQ_DEBUG
# Debugging
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
options ALT_BREAK_TO_DEBUGGER
options DDB
@@ -162,7 +162,7 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require
# Enable these options for nfs root configured via BOOTP.
options NFSCL # Network Filesystem Client
options NFSLOCKD # Network Lock Manager
-#options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+#options NFS_ROOT # NFS usable as /, requires NFSCL
#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_NFSV3
@@ -178,7 +178,7 @@ options ROOTDEVNAME=\"ufs:/dev/da1s1a\"
# create a kernel config file that looks like this:
#
# include DREAMPLUG-1001
-# nomakeoptions FDT_DTS_FILE
+# nomakeoptions FDT_DTS_FILE
# makeoptions FDT_DTS_FILE=dreamplug-1001N.dts
# device nand
diff --git a/sys/arm/conf/EA3250 b/sys/arm/conf/EA3250
index 82bc386..d2d691b 100644
--- a/sys/arm/conf/EA3250
+++ b/sys/arm/conf/EA3250
@@ -19,7 +19,7 @@ options INET6 # IPv6 communications protocols
options FFS # Berkeley Fast Filesystem
options NFSCL # Network Filesystem Client
options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+options NFS_ROOT # NFS usable as /, requires NFSCL
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
options TMPFS # Efficient memory filesystem
diff --git a/sys/arm/conf/EFIKA_MX b/sys/arm/conf/EFIKA_MX
index 677d73d..459cd79 100644
--- a/sys/arm/conf/EFIKA_MX
+++ b/sys/arm/conf/EFIKA_MX
@@ -1,3 +1,4 @@
+#
# Kernel configuration for Efika MX Smarttop/Smartbook boards
#
# For more information on this file, please read the config(5) manual page,
@@ -21,34 +22,32 @@ ident EFIKA_MX
include "../freescale/imx/std.imx51"
-makeoptions WITHOUT_MODULES="ahc"
-
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-#options DEBUG
+makeoptions WITHOUT_MODULES="ahc"
options SCHED_4BSD # 4BSD scheduler
-#options PREEMPTION # Enable kernel thread preemption
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
-#options INET6 # IPv6 communications protocols
-#options SCTP # Stream Control Transmission Protocol
+options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
#options MD_ROOT # MD is a potential root device
options NFSCL # New Network Filesystem Client
#options NFSD # New Network Filesystem Server
options NFSLOCKD # Network Lock Manager
options NFS_ROOT # NFS usable as /, requires NFSCL
-options TMPFS # Efficient memory filesystem
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
-#options PROCFS # Process filesystem (requires PSEUDOFS)
+options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
#options COMPAT_FREEBSD5 # Compatible with FreeBSD5
#options COMPAT_FREEBSD6 # Compatible with FreeBSD6
@@ -59,16 +58,34 @@ options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options PLATFORM
options INCLUDE_CONFIG_FILE # Include this file in kernel
-options VFP # vfp/neon
+options VFP # Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options BREAK_TO_DEBUGGER
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
+#options GDB # Support remote GDB
+options DEADLKRES # Enable the deadlock resolver
+options INVARIANTS # Enable calls of extra sanity checking
+options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-# required for netbooting
+# NFS root from boopt/dhcp
#options BOOTP
-#options BOOTP_COMPAT
#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ue0
-#
+
options ROOTDEVNAME=\"ufs:ada0s2a\"
@@ -79,18 +96,6 @@ options ROOTDEVNAME=\"ufs:ada0s2a\"
#options NO_SYSCTL_DESCR
#options RWLOCK_NOINLINE
-# Debugging support. Always need this:
-options KDB # Enable kernel debugger support.
-# For minimum debugger support (stable branch) use:
-#options KDB_TRACE # Print a stack trace for a panic.
-# For full debugger support use this instead:
-options DDB # Support DDB.
-#options GDB # Support remote GDB.
-options DEADLKRES # Enable the deadlock resolver
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-options WITNESS # Enable checks to detect deadlocks and cycles
-
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
# Note that 'bpf' is required for DHCP.
@@ -162,15 +167,15 @@ device wlan_tkip # 802.11 TKIP support
device wlan_amrr # AMRR transmit rate control algorithm
# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=efikamx.dts
+options FDT # Configure using FDT/DTB data
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=efikamx.dts
# NOTE: serial console will be disabled if syscons enabled
# Uncomment following lines for framebuffer/syscons support
device sc
device kbdmux
-options SC_DFLT_FONT # compile font in
-makeoptions SC_DFLT_FONT=cp437
+options SC_DFLT_FONT # compile font in
+makeoptions SC_DFLT_FONT=cp437
device ukbd # Allow keyboard like HIDs to control console
device ums
diff --git a/sys/arm/conf/EXYNOS5.common b/sys/arm/conf/EXYNOS5.common
index 7cd577d..0179d5b 100644
--- a/sys/arm/conf/EXYNOS5.common
+++ b/sys/arm/conf/EXYNOS5.common
@@ -1,3 +1,4 @@
+#
# Kernel configuration for Samsung Exynos 5 SoC.
#
# For more information on this file, please read the config(5) manual page,
@@ -20,70 +21,72 @@
makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT # GUID partition tables
-options TMPFS # Efficient memory filesystem
+options SCTP # Stream Control Transmission Protocol
options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES
+options SOFTUPDATES # Enable FFS soft updates support
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE
+options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options KBD_INSTALL_CDEV
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-options SMP
-
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
-#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
#options INVARIANTS # Enable calls of extra sanity checking
#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-#options WITNESS # Enable checks to detect deadlocks and cycles
-#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ue0
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCL
-#options BOOTP_NFSROOT
-#options BOOTP_COMPAT
-#options BOOTP
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ue0
+options ROOTDEVNAME=\"ufs:/dev/da0\"
+# MMC/SD/SDIO Card slot support
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
device dwmmc
-options ROOTDEVNAME=\"ufs:/dev/da0\"
-
# Pseudo devices
device loop
@@ -96,8 +99,8 @@ device gpio
options USB_HOST_ALIGN=64 # Align usb buffers to cache line size.
device usb
options USB_DEBUG
-#options USB_REQ_DEBUG
-#options USB_VERBOSE
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
#device musb
device ehci
#device ohci
diff --git a/sys/arm/conf/HL201 b/sys/arm/conf/HL201
index efdea82..8a15544 100644
--- a/sys/arm/conf/HL201
+++ b/sys/arm/conf/HL201
@@ -143,5 +143,5 @@ options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=hl201.dts
options EARLY_PRINTF
-options SOCDEV_PA=0xfc000000
+options SOCDEV_PA=0xfc000000
options SOCDEV_VA=0xdc000000
diff --git a/sys/arm/conf/IMX53 b/sys/arm/conf/IMX53
index 5fd5697..12cd4cf 100644
--- a/sys/arm/conf/IMX53
+++ b/sys/arm/conf/IMX53
@@ -1,3 +1,4 @@
+#
# Kernel configuration for i.MX53 boards
#
# For more information on this file, please read the config(5) manual page,
@@ -21,32 +22,29 @@ ident IMX53
include "../freescale/imx/std.imx53"
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-#options DEBUG
-
options SCHED_4BSD # 4BSD scheduler
-#options PREEMPTION # Enable kernel thread preemption
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
-#options SCTP # Stream Control Transmission Protocol
+options SCTP # Stream Control Transmission Protocol
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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
-#options MD_ROOT # MD is a potential root device
+options QUOTA # Enable disk quotas for UFS
options NFSCL # New Network Filesystem Client
#options NFSD # New Network Filesystem Server
options NFSLOCKD # Network Lock Manager
options NFS_ROOT # NFS usable as /, requires NFSCL
-options TMPFS # Efficient memory filesystem
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
-#options PROCFS # Process filesystem (requires PSEUDOFS)
+options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT # GUID Partition Tables.
options GEOM_LABEL # Provides labelization
#options COMPAT_FREEBSD5 # Compatible with FreeBSD5
#options COMPAT_FREEBSD6 # Compatible with FreeBSD6
@@ -57,27 +55,31 @@ options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options PLATFORM
options INCLUDE_CONFIG_FILE # Include this file in kernel
-options VFP # vfp/neon
-
-# kernel/memory size reduction
-#options MUTEX_NOINLINE
-#options NO_FFS_SNAPSHOT
-#options NO_SWAPPING
-#options NO_SYSCTL_DESCR
-#options RWLOCK_NOINLINE
+options VFP # Enable floating point hardware support
-# Debugging support. Always need this:
-options KDB # Enable kernel debugger support.
+# Debugging for use in -current
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options KDB # Enable kernel debugger support
# For minimum debugger support (stable branch) use:
-#options KDB_TRACE # Print a stack trace for a panic.
+#options KDB_TRACE # Print a stack trace for a panic
# For full debugger support use this instead:
-options DDB # Support DDB.
-#options GDB # Support remote GDB.
+options DDB # Enable the kernel debugger
+#options GDB # Support remote GDB
options DEADLKRES # Enable the deadlock resolver
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+
+# kernel/memory size reduction
+#options MUTEX_NOINLINE
+#options NO_FFS_SNAPSHOT
+#options NO_SWAPPING
+#options NO_SYSCTL_DESCR
+#options RWLOCK_NOINLINE
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
@@ -161,12 +163,12 @@ device wlan_amrr # AMRR transmit rate control algorithm
# Flattened Device Tree
-options FDT
+options FDT # Configure using FDT/DTB data
# NOTE: serial console will be disabled if syscons enabled
# Uncomment following lines for framebuffer/syscons support
#device sc
#device vt
#device kbdmux
-#options SC_DFLT_FONT # compile font in
-#makeoptions SC_DFLT_FONT=cp437
+#options SC_DFLT_FONT # compile font in
+#makeoptions SC_DFLT_FONT=cp437
diff --git a/sys/arm/conf/IMX53-QSB b/sys/arm/conf/IMX53-QSB
index fdaa4ec..fdde591 100644
--- a/sys/arm/conf/IMX53-QSB
+++ b/sys/arm/conf/IMX53-QSB
@@ -34,5 +34,5 @@ options HZ=250 # 4ms scheduling quantum
#options ROOTDEVNAME=\"ufs:ada0s2a\"
# Flattened Device Tree
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=imx53-qsb.dts
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=imx53-qsb.dts
diff --git a/sys/arm/conf/IMX6 b/sys/arm/conf/IMX6
index 007862b..bdaab26 100644
--- a/sys/arm/conf/IMX6
+++ b/sys/arm/conf/IMX6
@@ -1,3 +1,4 @@
+#
# Kernel configuration for Freescale i.MX6 systems.
#
# For more information on this file, please read the config(5) manual page,
@@ -20,140 +21,143 @@
ident IMX6
include "../freescale/imx/std.imx6"
-options HZ=500 # Scheduling quantum is 2 milliseconds.
-options SCHED_ULE # ULE scheduler
-options PREEMPTION # Enable kernel thread preemption
-options INET # InterNETworking
-options INET6 # IPv6 communications protocols
-options SCTP # Stream Control Transmission Protocol
-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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
-#options MD_ROOT # MD is a potential root device
-options NFSCL # New Network Filesystem Client
-#options NFSD # New Network Filesystem Server
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCL
+options HZ=500 # Scheduling quantum is 2 milliseconds.
+options SCHED_ULE # ULE scheduler
+options PREEMPTION # Enable kernel thread preemption
+options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
+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 UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+#options NFSD # New Network Filesystem Server
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
options TMPFS # Efficient memory filesystem
-options MSDOSFS # MSDOS Filesystem
-options CD9660 # ISO 9660 Filesystem
-#options PROCFS # Process filesystem (requires PSEUDOFS)
-options PSEUDOFS # Pseudo-filesystem framework
+options GEOM_PART_GPT # GUID Partition Tables
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT # GUID Partition Tables.
-options GEOM_LABEL # Provides labelization
-options KTRACE # ktrace(1) support
-options SYSVSHM # SYSV-style shared memory
-options SYSVMSG # SYSV-style message queues
-options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
-options INCLUDE_CONFIG_FILE # Include this file in kernel
-
-# Debugging support. Always need this:
-options KDB # Enable kernel debugger support.
-# For minimum debugger support use KDB_TRACE, for interactive use DDB.
-#options KDB_TRACE # Print a stack trace for a panic.
-options DDB # Support DDB.
+options GEOM_LABEL # Provides labelization
+options KTRACE # ktrace(1) support
+options SYSVSHM # SYSV-style shared memory
+options SYSVMSG # SYSV-style message queues
+options SYSVSEM # SYSV-style semaphores
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options INCLUDE_CONFIG_FILE # Include this file in kernel
+options PLATFORM
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
+
+# Debugging for use in -current
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
# For full debugger support use this instead:
-#options GDB # Support remote GDB.
+options DDB # Enable the kernel debugger
+#options GDB # Support remote GDB.
# Other debugging options...
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options ALT_BREAK_TO_DEBUGGER # Use <CR><tilde><ctrl-b> to enter debugger.
-#options DEBUG
-#options DEADLKRES # Enable the deadlock resolver
-#options INVARIANTS # Enable calls of extra sanity checking
-#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-#options WITNESS # Enable checks to detect deadlocks and cycles
+options ALT_BREAK_TO_DEBUGGER # Use <CR><tilde><ctrl-b> to enter debugger.
+#options DEADLKRES # Enable the deadlock resolver
+#options INVARIANTS # Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ffec0
+
+# U-Boot stuff lives on slice 1, FreeBSD on slice 2.
+options ROOTDEVNAME=\"ufs:mmcsd0s2a\"
# Pseudo devices.
-device loop # Network loopback
-device random # Entropy device
-device vlan # 802.1Q VLAN support
-device tun # Packet tunnel.
-device md # Memory "disks"
-#device gif # IPv6 and IPv4 tunneling
-#device firmware # firmware assist module
-device ether # Ethernet support
-device miibus # Required for ethernet
-device bpf # Berkeley packet filter (required for DHCP)
+device loop # Network loopback
+device random # Entropy device
+device vlan # 802.1Q VLAN support
+device tun # Packet tunnel.
+device md # Memory "disks"
+#device gif # IPv6 and IPv4 tunneling
+#device firmware # firmware assist module
+device ether # Ethernet support
+device miibus # Required for ethernet
+device bpf # Berkeley packet filter (required for DHCP)
# General-purpose input/output
-device gpio
+device gpio
# Serial (COM) ports
-device uart # Multi-uart driver
+device uart # Multi-uart driver
# SDCard
-device sdhci # SD controller
-device mmc # SD/MMC protocol
-device mmcsd # SDCard disk device
+device sdhci # SD controller
+device mmc # SD/MMC protocol
+device mmcsd # SDCard disk device
# SCSI peripherals
-device scbus # SCSI bus (required for ATA/SCSI)
-device da # Direct Access (disks)
-device cd # CD
-device pass # Passthrough device (direct ATA/SCSI access)
+device scbus # SCSI bus (required for ATA/SCSI)
+device da # Direct Access (disks)
+device cd # CD
+device pass # Passthrough device (direct ATA/SCSI access)
# USB support
-#options USB_DEBUG # enable debug msgs
-device ehci # OHCI USB interface
-device usb # USB Bus (required)
-device umass # Disks/Mass storage - Requires scbus and da
-device uhid # "Human Interface Devices"
-device u3g # USB modems
-#device ukbd # Allow keyboard like HIDs to control console
-#device ums # USB mouse
+#options USB_DEBUG # enable debug msgs
+device ehci # OHCI USB interface
+device usb # USB Bus (required)
+device umass # Disks/Mass storage - Requires scbus and da
+device uhid # "Human Interface Devices"
+device u3g # USB modems
+#device ukbd # Allow keyboard like HIDs to control console
+#device ums # USB mouse
# USB Ethernet, requires miibus
-#device aue # ADMtek USB Ethernet
-#device axe # ASIX Electronics USB Ethernet
-#device cdce # Generic USB over Ethernet
-#device cue # CATC USB Ethernet
-#device kue # Kawasaki LSI USB Ethernet
-#device rue # RealTek RTL8150 USB Ethernet
-#device udav # Davicom DM9601E USB
+#device aue # ADMtek USB Ethernet
+#device axe # ASIX Electronics USB Ethernet
+#device cdce # Generic USB over Ethernet
+#device cue # CATC USB Ethernet
+#device kue # Kawasaki LSI USB Ethernet
+#device rue # RealTek RTL8150 USB Ethernet
+#device udav # Davicom DM9601E USB
# USB Wireless
-#device rum # Ralink Technology RT2501USB wireless NICs
+#device rum # Ralink Technology RT2501USB wireless NICs
# Wireless NIC cards
-#device wlan # 802.11 support
-#device wlan_wep # 802.11 WEP support
-#device wlan_ccmp # 802.11 CCMP support
-#device wlan_tkip # 802.11 TKIP support
-#device wlan_amrr # AMRR transmit rate control algorithm
+#device wlan # 802.11 support
+#device wlan_wep # 802.11 WEP support
+#device wlan_ccmp # 802.11 CCMP support
+#device wlan_tkip # 802.11 TKIP support
+#device wlan_amrr # AMRR transmit rate control algorithm
# NOTE: serial console will be disabled if syscons enabled
# Uncomment following lines for framebuffer/syscons support
# Wandboard has no video console support yet.
-#device sc
-#device kbdmux
-#options SC_DFLT_FONT # compile font in
-#makeoptions SC_DFLT_FONT=cp437
-
-# required for netbooting
-#options BOOTP
-#options BOOTP_COMPAT
-#options BOOTP_NFSROOT
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ffec0
-
-# U-Boot stuff lives on slice 1, FreeBSD on slice 2.
-options ROOTDEVNAME=\"ufs:mmcsd0s2a\"
+#device sc
+#device kbdmux
+#options SC_DFLT_FONT # compile font in
+#makeoptions SC_DFLT_FONT=cp437
-# ARM and SoC-specific options
-options FDT # Configure using FDT/DTB data.
-options SMP # Enable multiple cores
-options VFP # Enable floating point hardware support
-options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
# SoC-specific devices
-device ffec # Freescale Fast Ethernet Controller
-device fsliic # Freescale i2c/iic
-device iic # iic protocol
-device iicbus # iic bus
-#device imxwdt # Watchdog. WARNING: can't be disabled!!!
+device ffec # Freescale Fast Ethernet Controller
+device fsliic # Freescale i2c/iic
+device iic # iic protocol
+device iicbus # iic bus
+#device imxwdt # Watchdog. WARNING: can't be disabled!!!
diff --git a/sys/arm/conf/PANDABOARD b/sys/arm/conf/PANDABOARD
index cc345cb..7a71d12 100644
--- a/sys/arm/conf/PANDABOARD
+++ b/sys/arm/conf/PANDABOARD
@@ -1,8 +1,9 @@
+#
# PANDABOARD -- Custom configuration for the PandaBoard ARM development
# platform, check out www.pandaboard.org
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -28,44 +29,53 @@ hints "PANDABOARD.hints"
include "../ti/omap4/pandaboard/std.pandaboard"
-#To statically compile in device wiring instead of /boot/device.hints
makeoptions MODULES_OVERRIDE=""
-makeoptions WITHOUT_MODULES="ahc"
+makeoptions WITHOUT_MODULES="ahc"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
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 GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options PREEMPTION
options PLATFORM
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
-options SMP # Enable multiple cores
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
#options INVARIANTS # Enable calls of extra sanity checking
#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
@@ -73,14 +83,10 @@ options DDB # Enable the kernel debugger
#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-options NFSCL
-
-# NFS root
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
+# NFS root from boopt/dhcp
+#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
-#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ue0
@@ -146,6 +152,6 @@ device twl_vreg
device twl_clks
# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=pandaboard.dts
+options FDT # Configure using FDT/DTB data
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=pandaboard.dts
diff --git a/sys/arm/conf/RK3188 b/sys/arm/conf/RK3188
index d6a26dd..ab9d20a 100644
--- a/sys/arm/conf/RK3188
+++ b/sys/arm/conf/RK3188
@@ -1,7 +1,8 @@
+#
# Kernel configuration for Rockchip RK3188 systems.
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -23,56 +24,61 @@ include "../rockchip/std.rk30xx"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
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 GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
-options SMP # Enable multiple cores
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
-#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
-#options INVARIANTS # Enable calls of extra sanity checking
-#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options INVARIANTS # Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
options WITNESS # Enable checks to detect deadlocks and cycles
options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
options DIAGNOSTIC
-# NFS support
-#options NFSCL
-#options NFSSERVER # Network Filesystem Server
-#options NFSCLIENT # Network Filesystem Client
+# Boot device is 2nd slice on USB
+options ROOTDEVNAME=\"ufs:/dev/da0s2\"
-# MMC/SD/SDIO card slot support
+# MMC/SD/SDIO Card slot support
#device mmc # mmc/sd bus
#device mmcsd # mmc/sd flash cards
-# Boot device is 2nd slice on USB
-options ROOTDEVNAME=\"ufs:/dev/da0s2\"
-
# Console and misc
device uart
device uart_ns8250
@@ -96,8 +102,8 @@ device pass
options USB_HOST_ALIGN=32 # Align usb buffers to cache line size.
device usb
options USB_DEBUG
-#options USB_REQ_DEBUG
-#options USB_VERBOSE
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
device dwcotg # DWC OTG controller
device umass
@@ -109,10 +115,10 @@ device mii
device bpf
# Wireless NIC cards
-options IEEE80211_DEBUG
-options IEEE80211_AMPDU_AGE
-options IEEE80211_SUPPORT_MESH
-options IEEE80211_SUPPORT_TDMA
+options IEEE80211_DEBUG
+options IEEE80211_AMPDU_AGE
+options IEEE80211_SUPPORT_MESH
+options IEEE80211_SUPPORT_TDMA
device wlan # 802.11 support
device wlan_wep # 802.11 WEP support
device wlan_ccmp # 802.11 CCMP support
@@ -121,8 +127,9 @@ device urtwn
device urtwnfw
device firmware # Used by the above
-# USB ethernet support, requires miibus
+# USB Ethernet support, requires miibus
device miibus
device udav
-options FDT # Configure using FDT/DTB data.
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B
index 322a4ec..c1013d1 100644
--- a/sys/arm/conf/RPI-B
+++ b/sys/arm/conf/RPI-B
@@ -1,7 +1,8 @@
+#
# RPI-B -- Custom configuration for the Raspberry Pi
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -11,8 +12,8 @@
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
@@ -21,10 +22,9 @@ ident RPI-B
include "../broadcom/bcm2835/std.rpi"
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options HZ=100
-
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
options SCTP # Stream Control Transmission Protocol
@@ -32,42 +32,62 @@ 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 GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
-device snp
-
-options NFSCL # Network Filesystem Client
-
-#options NFS_ROOT # NFS usable as /, requires NFSCLIENT
-#options BOOTP_NFSROOT
-#options BOOTP_COMPAT
-#options BOOTP
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ue0
-
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-#options ROOTDEVNAME=\"ufs:mmcsd0s2\"
-
-options PREEMPTION
options PLATFORM
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+
+# Debugging for use in -current
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options BREAK_TO_DEBUGGER
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
+options INVARIANTS # Enable calls of extra sanity checking
+options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ue0
+
+#options ROOTDEVNAME=\"ufs:mmcsd0s2\"
device bpf
device loop
device ether
device uart
-device pl011
-
device pty
+device snp
+device pl011
# Comment following lines for boot console on serial port
device vt
@@ -86,11 +106,6 @@ device iic
device iicbus
device bcm2835_bsc
-options KDB
-options DDB # Enable the kernel debugger
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-
device md
device random # Entropy device
@@ -114,10 +129,8 @@ device spibus
device bcm2835_spi
# Flattened Device Tree
-options FDT
+options FDT # Configure using FDT/DTB data
# Note: DTB is normally loaded and modified by RPi boot loader, then
# handed to kernel via U-Boot and ubldr.
-#options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=rpi.dts
-
-options VFP # vfp/neon
+#options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=rpi.dts
diff --git a/sys/arm/conf/SAM9260EK b/sys/arm/conf/SAM9260EK
index c3cba33..dd0d52e 100644
--- a/sys/arm/conf/SAM9260EK
+++ b/sys/arm/conf/SAM9260EK
@@ -180,5 +180,5 @@ device nand # NAND interface on CS3
#makeoptions FDT_DTS_FILE=sam9260ek.dts
options EARLY_PRINTF
-options SOCDEV_PA=0xfc000000
+options SOCDEV_PA=0xfc000000
options SOCDEV_VA=0xdc000000
diff --git a/sys/arm/conf/SOCKIT b/sys/arm/conf/SOCKIT
index 5a9ade5..744559a 100644
--- a/sys/arm/conf/SOCKIT
+++ b/sys/arm/conf/SOCKIT
@@ -1,3 +1,4 @@
+#
# Kernel configuration for Terasic SoCKit (Altera Cyclone V SoC).
#
# For more information on this file, please read the config(5) manual page,
@@ -22,44 +23,51 @@ include "../altera/socfpga/std.socfpga"
makeoptions MODULES_OVERRIDE=""
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT # GUID partition tables
-options TMPFS # Efficient memory filesystem
+options SCTP # Stream Control Transmission Protocol
options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES
+options SOFTUPDATES # Enable FFS soft updates support
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE
+options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options KBD_INSTALL_CDEV
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-options SMP
-
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
@@ -67,25 +75,20 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require
#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
-
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCL
+# NFS root from boopt/dhcp
+#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
-#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ue0
+options ROOTDEVNAME=\"ufs:/dev/da0\"
+
+# MMC/SD/SDIO Card slot support
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
device dwmmc
-options ROOTDEVNAME=\"ufs:/dev/da0\"
-
# Pseudo devices
device loop
@@ -132,7 +135,7 @@ device miibus
device axe # ASIX Electronics USB Ethernet
device bpf # Berkeley packet filter
-#FDT
-options FDT
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=socfpga-sockit.dts
diff --git a/sys/arm/conf/SOCKIT-BERI b/sys/arm/conf/SOCKIT-BERI
index 76306de..918da53 100644
--- a/sys/arm/conf/SOCKIT-BERI
+++ b/sys/arm/conf/SOCKIT-BERI
@@ -1,3 +1,4 @@
+#
# Kernel configuration for Terasic SoCKit (Altera Cyclone V SoC).
#
# For more information on this file, please read the config(5) manual page,
@@ -22,44 +23,51 @@ include "../altera/socfpga/std.socfpga"
makeoptions MODULES_OVERRIDE=""
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options GEOM_PART_GPT # GUID partition tables
-options TMPFS # Efficient memory filesystem
+options SCTP # Stream Control Transmission Protocol
options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES
+options SOFTUPDATES # Enable FFS soft updates support
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE
+options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options KBD_INSTALL_CDEV
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-options SMP
-
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
options INVARIANTS # Enable calls of extra sanity checking
options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
@@ -67,25 +75,20 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require
#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
#options DIAGNOSTIC
-# NFS support
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
-
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCL
+# NFS root from boopt/dhcp
+#options BOOTP
#options BOOTP_NFSROOT
#options BOOTP_COMPAT
-#options BOOTP
#options BOOTP_NFSV3
#options BOOTP_WIRED_TO=ue0
+options ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\"
+
+# MMC/SD/SDIO Card slot support
device mmc # mmc/sd bus
device mmcsd # mmc/sd flash cards
device dwmmc
-options ROOTDEVNAME=\"ufs:/dev/mmcsd0s4\"
-
# Pseudo devices
device loop
@@ -139,7 +142,7 @@ device miibus
device axe # ASIX Electronics USB Ethernet
device bpf # Berkeley packet filter
-#FDT
-options FDT
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=socfpga-sockit-beri.dts
diff --git a/sys/arm/conf/VERSATILEPB b/sys/arm/conf/VERSATILEPB
index fb2087a..2132389 100644
--- a/sys/arm/conf/VERSATILEPB
+++ b/sys/arm/conf/VERSATILEPB
@@ -1,7 +1,8 @@
+#
# VERSATILEPB - Configuration for QEMU version of Versatile Platform Board
#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
@@ -11,8 +12,8 @@
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
@@ -29,36 +30,53 @@ makeoptions KERNVIRTADDR=0xc0100000
options KERNPHYSADDR=0x00100000
makeoptions KERNPHYSADDR=0x00100000
options PHYSADDR=0x00000000
-options FREEBSD_BOOT_LOADER
-options LINUX_BOOT_ABI
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options HZ=100
-
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
+options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
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
-device snp
-
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
+options MSDOSFS # MSDOS Filesystem
+options CD9660 # ISO 9660 Filesystem
+options PROCFS # Process filesystem (requires PSEUDOFS)
+options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
options GEOM_PART_BSD # BSD partition scheme
options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
-options PSEUDOFS # Pseudo-filesystem framework
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
-options ROOTDEVNAME=\"ufs:da0s1a\"
-options VFP # vfp/neon
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options LINUX_BOOT_ABI # Process metadata passed from Linux boot loaders
+options VFP # Enable floating point hardware support
-options PREEMPTION
+# Debugging for use in -current
+makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
+options INVARIANTS # Enable calls of extra sanity checking
+options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+
+options ROOTDEVNAME=\"ufs:da0s1a\"
device bpf
device loop
@@ -72,6 +90,7 @@ device pl011
device pl190
device pty
+device snp
device pci
@@ -87,18 +106,13 @@ device pass # Passthrough device (direct ATA/SCSI access)
# Comment following lines for headless setup
device sc
device kbdmux
-options SC_DFLT_FONT # compile font in
-makeoptions SC_DFLT_FONT=cp437
-
-options KDB
-options DDB # Enable the kernel debugger
-options INVARIANTS # Enable calls of extra sanity checking
-options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+options SC_DFLT_FONT # compile font in
+makeoptions SC_DFLT_FONT=cp437
device md
device random # Entropy device
# Flattened Device Tree
-options FDT
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=versatilepb.dts
+options FDT # Configure using FDT/DTB data
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=versatilepb.dts
diff --git a/sys/arm/conf/VYBRID b/sys/arm/conf/VYBRID
index e2e1def..7ff206e 100644
--- a/sys/arm/conf/VYBRID
+++ b/sys/arm/conf/VYBRID
@@ -1,3 +1,4 @@
+#
# Kernel configuration for Vybrid Family boards.
#
# For more information on this file, please read the config(5) manual page,
@@ -23,75 +24,79 @@ include "../freescale/vybrid/std.vybrid"
makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
-makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
options FFS # Berkeley Fast Filesystem
-options SOFTUPDATES
+options SOFTUPDATES # Enable FFS soft updates support
options UFS_ACL # Support for access control lists
options UFS_DIRHASH # Improve performance on big directories
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
+#options NANDFS # NAND Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
-#options NANDFS # NAND Filesystem
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options COMPAT_43 # Compatible with BSD 4.3 [KEEP THIS!]
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
-options KTRACE
+options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options KBD_INSTALL_CDEV
-options PREEMPTION
-options FREEBSD_BOOT_LOADER
-options MUTEX_NOINLINE
-options RWLOCK_NOINLINE
-options NO_FFS_SNAPSHOT
-options NO_SWAPPING
-options VFP # vfp/neon
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+#options SMP # Enable multiple cores
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
-#options VERBOSE_SYSINIT # Enable verbose sysinit messages
-options KDB
+#options VERBOSE_SYSINIT # Enable verbose sysinit messages
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
options DDB # Enable the kernel debugger
-#options INVARIANTS # Enable calls of extra sanity checking
-#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-#options WITNESS # Enable checks to detect deadlocks and cycles
-#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
-#options DIAGNOSTIC
-
-# NFS support
-options NFSCL # Network Filesystem Client
-options NFSLOCKD # Network Lock Manager
-options NFS_ROOT # NFS usable as /, requires NFSCLIENT
-
-# Uncomment this for NFS root
-#options NFS_ROOT # NFS usable as /, requires NFSCL
-#options BOOTP_NFSROOT
-#options BOOTP_COMPAT
-#options BOOTP
-#options BOOTP_NFSV3
-#options BOOTP_WIRED_TO=ffec0
-
-device mmc # mmc/sd bus
-device mmcsd # mmc/sd flash cards
-device sdhci # generic sdhci
+#options INVARIANTS # Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
+#options BOOTP_WIRED_TO=ffec0
#options ROOTDEVNAME=\"nfs:10.5.0.1:/tftpboot/cosmic\"
#options ROOTDEVNAME=\"nandfs:/dev/gnand0s.root\"
options ROOTDEVNAME=\"ufs:/dev/da0\"
-#options SMP
+options MUTEX_NOINLINE
+options RWLOCK_NOINLINE
+options NO_FFS_SNAPSHOT
+options NO_SWAPPING
+
+# MMC/SD/SDIO Card slot support
+device mmc # mmc/sd bus
+device mmcsd # mmc/sd flash cards
+device sdhci # generic sdhci
# Pseudo devices
@@ -105,8 +110,8 @@ device gpio
options USB_HOST_ALIGN=32 # Align usb buffers to cache line size.
device usb
options USB_DEBUG
-#options USB_REQ_DEBUG
-#options USB_VERBOSE
+#options USB_REQ_DEBUG
+#options USB_VERBOSE
#device musb
device ehci
#device ohci
@@ -150,4 +155,5 @@ device vt
device kbdmux
device ukbd
-options FDT
+# Flattened Device Tree
+options FDT # Configure using FDT/DTB data
diff --git a/sys/arm/conf/WANDBOARD-DUAL b/sys/arm/conf/WANDBOARD-DUAL
index 1e690c9..66e2535 100644
--- a/sys/arm/conf/WANDBOARD-DUAL
+++ b/sys/arm/conf/WANDBOARD-DUAL
@@ -23,6 +23,6 @@ include "IMX6"
ident WANDBOARD-DUAL
# Flattened Device Tree
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=wandboard-dual.dts
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=wandboard-dual.dts
diff --git a/sys/arm/conf/WANDBOARD-QUAD b/sys/arm/conf/WANDBOARD-QUAD
index 121e712..830a445 100644
--- a/sys/arm/conf/WANDBOARD-QUAD
+++ b/sys/arm/conf/WANDBOARD-QUAD
@@ -23,6 +23,6 @@ include "IMX6"
ident WANDBOARD-QUAD
# Flattened Device Tree
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=wandboard-quad.dts
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=wandboard-quad.dts
diff --git a/sys/arm/conf/WANDBOARD-SOLO b/sys/arm/conf/WANDBOARD-SOLO
index 424bc5f..39a0c7c 100644
--- a/sys/arm/conf/WANDBOARD-SOLO
+++ b/sys/arm/conf/WANDBOARD-SOLO
@@ -23,6 +23,6 @@ include "IMX6"
ident WANDBOARD-SOLO
# Flattened Device Tree
-options FDT_DTB_STATIC
-makeoptions FDT_DTS_FILE=wandboard-solo.dts
+options FDT_DTB_STATIC
+makeoptions FDT_DTS_FILE=wandboard-solo.dts
diff --git a/sys/arm/conf/ZEDBOARD b/sys/arm/conf/ZEDBOARD
index 8ec0df1..e1200bf 100644
--- a/sys/arm/conf/ZEDBOARD
+++ b/sys/arm/conf/ZEDBOARD
@@ -1,73 +1,86 @@
+#
# ZEDBOARD -- Custom configuration for the Xilinx Zynq-7000 based
# ZedBoard (www.zedboard.org)
-#
-# For more information on this file, please read the handbook section on
-# Kernel Configuration Files:
-#
+#
+# For more information on this file, please read the config(5) manual page,
+# and/or the handbook section on Kernel Configuration Files:
+#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
-#
+#
# The handbook is also available locally in /usr/share/doc/handbook
# if you've installed the doc distribution, otherwise always see the
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
# latest information.
-#
+#
# An exhaustive list of options and more detailed explanations of the
-# device lines is also present in the ../../conf/NOTES and NOTES files.
-# If you are in doubt as to the purpose or necessity of a line, check first
+# device lines is also present in the ../../conf/NOTES and NOTES files.
+# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
-#
+#
# $FreeBSD$
ident ZEDBOARD
-include "../xilinx/zedboard/std.zedboard"
+include "../xilinx/zedboard/std.zedboard"
makeoptions MODULES_OVERRIDE=""
makeoptions WITHOUT_MODULES="ahc"
options SCHED_4BSD # 4BSD scheduler
+options PREEMPTION # Enable kernel thread preemption
options INET # InterNETworking
options INET6 # IPv6 communications protocols
+options SCTP # Stream Control Transmission Protocol
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:mmcsd0s2a\"
-
-options NFSCL # Network Filesystem Client
-# options NFSSD # Network Filesystem Server
-# options NFSLOCKD # Network Lock Manager
-# options NFS_ROOT # NFS usable as /, requires NFSCL
-# options BOOTP_NFSROOT
-# options BOOTP
-
-options GEOM_PART_BSD # BSD partition scheme
-options GEOM_PART_MBR # MBR partition scheme
-options TMPFS # Efficient memory filesystem
+options UFS_GJOURNAL # Enable gjournal-based UFS journaling
+options QUOTA # Enable disk quotas for UFS
+options NFSCL # New Network Filesystem Client
+#options NFSSD # Network Filesystem Server
+options NFSLOCKD # Network Lock Manager
+options NFS_ROOT # NFS usable as /, requires NFSCL
options MSDOSFS # MSDOS Filesystem
options CD9660 # ISO 9660 Filesystem
options PROCFS # Process filesystem (requires PSEUDOFS)
options PSEUDOFS # Pseudo-filesystem framework
+options TMPFS # Efficient memory filesystem
+options GEOM_PART_GPT # GUID Partition Tables
+options GEOM_PART_BSD # BSD partition scheme
+options GEOM_PART_MBR # MBR partition scheme
options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI
options KTRACE # ktrace(1) support
options SYSVSHM # SYSV-style shared memory
options SYSVMSG # SYSV-style message queues
options SYSVSEM # SYSV-style semaphores
-options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B real-time extensions
-options FREEBSD_BOOT_LOADER
-options VFP # vfp/neon
-options SMP # Symmetric MultiProcessor Kernel
+options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
+options KBD_INSTALL_CDEV # install a CDEV entry in /dev
+options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
+options VFP # Enable floating point hardware support
+options SMP # Enable multiple cores
-# Debugging
+# Debugging for use in -current
makeoptions DEBUG=-g # Build kernel with gdb(1) debug symbols
-options DDB
-options KDB
-# options BREAK_TO_DEBUGGER
+#options BREAK_TO_DEBUGGER
+options KDB # Enable kernel debugger support
+# For minimum debugger support (stable branch) use:
+#options KDB_TRACE # Print a stack trace for a panic
+# For full debugger support use this instead:
+options DDB # Enable the kernel debugger
+#options INVARIANTS # Enable calls of extra sanity checking
+#options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
+#options WITNESS # Enable checks to detect deadlocks and cycles
+#options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+#options DIAGNOSTIC
+
+# NFS root from boopt/dhcp
+#options BOOTP
+#options BOOTP_NFSROOT
+#options BOOTP_COMPAT
+#options BOOTP_NFSV3
-# options INVARIANTS # Enable calls of extra sanity checking
-# options INVARIANT_SUPPORT # Extra sanity checks of internal structures, required by INVARIANTS
-# options WITNESS # Enable checks to detect deadlocks and cycles
-# options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed
+options ROOTDEVNAME=\"ufs:mmcsd0s2a\"
device loop
device random
@@ -98,7 +111,7 @@ device axe # USB-Ethernet
# Flattened Device Tree
-options FDT
-# options FDT_DTB_STATIC
-# makeoptions FDT_DTS_FILE=zedboard.dts
+options FDT # Configure using FDT/DTB data
+#options FDT_DTB_STATIC
+#makeoptions FDT_DTS_FILE=zedboard.dts
diff --git a/sys/arm/freescale/imx/imx51_machdep.c b/sys/arm/freescale/imx/imx51_machdep.c
index 8ab6541..5d8f380 100644
--- a/sys/arm/freescale/imx/imx51_machdep.c
+++ b/sys/arm/freescale/imx/imx51_machdep.c
@@ -39,36 +39,28 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
-#include <machine/platform.h>
+#include <machine/platformvar.h>
#include <arm/freescale/imx/imx_machdep.h>
-vm_offset_t
-platform_lastaddr(void)
+#include "platform_if.h"
+
+static vm_offset_t
+imx51_lastaddr(platform_t plat)
{
return (arm_devmap_lastaddr());
}
-void
-platform_probe_and_attach(void)
+static int
+imx51_attach(platform_t plat)
{
/* XXX - Get rid of this stuff soon. */
boothowto |= RB_VERBOSE|RB_MULTIPLE;
bootverbose = 1;
-}
-
-void
-platform_gpio_init(void)
-{
-
-}
-
-void
-platform_late_init(void)
-{
+ return (0);
}
/*
@@ -78,8 +70,8 @@ platform_late_init(void)
*
* Notably missing are entries for GPU, IPU, in general anything video related.
*/
-int
-platform_devmap_init(void)
+static int
+imx51_devmap_init(platform_t plat)
{
arm_devmap_add_entry(0x70000000, 0x00100000);
@@ -101,3 +93,12 @@ u_int imx_soc_type()
return (IMXSOC_51);
}
+static platform_method_t imx51_methods[] = {
+ PLATFORMMETHOD(platform_attach, imx51_attach),
+ PLATFORMMETHOD(platform_devmap_init, imx51_devmap_init),
+ PLATFORMMETHOD(platform_lastaddr, imx51_lastaddr),
+
+ PLATFORMMETHOD_END,
+};
+
+FDT_PLATFORM_DEF(imx51, "i.MX51", 0, "fsl,imx51");
diff --git a/sys/arm/freescale/imx/imx53_machdep.c b/sys/arm/freescale/imx/imx53_machdep.c
index ebf09d9..92b59e4 100644
--- a/sys/arm/freescale/imx/imx53_machdep.c
+++ b/sys/arm/freescale/imx/imx53_machdep.c
@@ -39,36 +39,28 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
-#include <machine/platform.h>
+#include <machine/platformvar.h>
#include <arm/freescale/imx/imx_machdep.h>
-vm_offset_t
-platform_lastaddr(void)
+#include "platform_if.h"
+
+static vm_offset_t
+imx53_lastaddr(platform_t plat)
{
return (arm_devmap_lastaddr());
}
-void
-platform_probe_and_attach(void)
+static int
+imx53_attach(platform_t plat)
{
/* XXX - Get rid of this stuff soon. */
boothowto |= RB_VERBOSE|RB_MULTIPLE;
bootverbose = 1;
-}
-
-void
-platform_gpio_init(void)
-{
-
-}
-
-void
-platform_late_init(void)
-{
+ return (0);
}
/*
@@ -78,8 +70,8 @@ platform_late_init(void)
*
* Notably missing are entries for GPU, IPU, in general anything video related.
*/
-int
-platform_devmap_init(void)
+static int
+imx53_devmap_init(platform_t plat)
{
arm_devmap_add_entry(0x50000000, 0x00100000);
@@ -101,4 +93,13 @@ u_int imx_soc_type()
return (IMXSOC_53);
}
+static platform_method_t imx53_methods[] = {
+ PLATFORMMETHOD(platform_attach, imx53_attach),
+ PLATFORMMETHOD(platform_devmap_init, imx53_devmap_init),
+ PLATFORMMETHOD(platform_lastaddr, imx53_lastaddr),
+
+ PLATFORMMETHOD_END,
+};
+
+FDT_PLATFORM_DEF(imx53, "i.MX53", 0, "fsl,imx53");
diff --git a/sys/arm/freescale/imx/imx6_machdep.c b/sys/arm/freescale/imx/imx6_machdep.c
index 510a09b..2322cff 100644
--- a/sys/arm/freescale/imx/imx6_machdep.c
+++ b/sys/arm/freescale/imx/imx6_machdep.c
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#include <machine/devmap.h>
#include <machine/intr.h>
#include <machine/machdep.h>
-#include <machine/platform.h>
+#include <machine/platformvar.h>
#include <arm/arm/mpcore_timervar.h>
#include <arm/freescale/imx/imx6_anatopreg.h>
@@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$");
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
+#include "platform_if.h"
+
struct fdt_fixup_entry fdt_fixup_table[] = {
{ NULL, NULL }
};
@@ -90,29 +92,25 @@ fdt_pic_decode_t fdt_pic_table[] = {
NULL
};
-vm_offset_t
-platform_lastaddr(void)
+static vm_offset_t
+imx6_lastaddr(platform_t plat)
{
return (arm_devmap_lastaddr());
}
-void
-platform_probe_and_attach(void)
+static int
+imx6_attach(platform_t plat)
{
/* Inform the MPCore timer driver that its clock is variable. */
arm_tmr_change_frequency(ARM_TMR_FREQUENCY_VARIES);
-}
-
-void
-platform_gpio_init(void)
-{
+ return (0);
}
-void
-platform_late_init(void)
+static void
+imx6_late_init(platform_t plat)
{
/* Cache the gpio1 node handle for imx6_decode_fdt() workaround code. */
@@ -136,8 +134,8 @@ platform_late_init(void)
* static map some of that area. Be careful with other things in that area such
* as OCRAM that probably shouldn't be mapped as PTE_DEVICE memory.
*/
-int
-platform_devmap_init(void)
+static int
+imx6_devmap_init(platform_t plat)
{
const uint32_t IMX6_ARMMP_PHYS = 0x00a00000;
const uint32_t IMX6_ARMMP_SIZE = 0x00100000;
@@ -271,3 +269,15 @@ imx6_early_putc(int c)
early_putc_t *early_putc = imx6_early_putc;
#endif
+static platform_method_t imx6_methods[] = {
+ PLATFORMMETHOD(platform_attach, imx6_attach),
+ PLATFORMMETHOD(platform_lastaddr, imx6_lastaddr),
+ PLATFORMMETHOD(platform_devmap_init, imx6_devmap_init),
+ PLATFORMMETHOD(platform_late_init, imx6_late_init),
+
+ PLATFORMMETHOD_END,
+};
+
+FDT_PLATFORM_DEF2(imx6, imx6s, "i.MX6 Solo", 0, "fsl,imx6s");
+FDT_PLATFORM_DEF2(imx6, imx6d, "i.MX6 Dual", 0, "fsl,imx6d");
+FDT_PLATFORM_DEF2(imx6, imx6q, "i.MX6 Quad", 0, "fsl,imx6q");
diff --git a/sys/arm/freescale/imx/std.imx51 b/sys/arm/freescale/imx/std.imx51
index ce9d7d2..4ffcac7 100644
--- a/sys/arm/freescale/imx/std.imx51
+++ b/sys/arm/freescale/imx/std.imx51
@@ -1,6 +1,7 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
makeoptions ARM_LITTLE_ENDIAN
options ARM_L2_PIPT
diff --git a/sys/arm/freescale/imx/std.imx53 b/sys/arm/freescale/imx/std.imx53
index 09bdb2d..6bc96cf 100644
--- a/sys/arm/freescale/imx/std.imx53
+++ b/sys/arm/freescale/imx/std.imx53
@@ -1,6 +1,7 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
makeoptions ARM_LITTLE_ENDIAN
options ARM_L2_PIPT
diff --git a/sys/arm/freescale/imx/std.imx6 b/sys/arm/freescale/imx/std.imx6
index a559f17..4249f9e 100644
--- a/sys/arm/freescale/imx/std.imx6
+++ b/sys/arm/freescale/imx/std.imx6
@@ -1,6 +1,7 @@
# $FreeBSD$
machine arm armv6
cpu CPU_CORTEXA
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
makeoptions ARM_LITTLE_ENDIAN
options ARM_L2_PIPT
diff --git a/sys/arm/freescale/vybrid/std.vybrid b/sys/arm/freescale/vybrid/std.vybrid
index 2fbd85c..35a2a25 100644
--- a/sys/arm/freescale/vybrid/std.vybrid
+++ b/sys/arm/freescale/vybrid/std.vybrid
@@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
options PHYSADDR=0x80000000
diff --git a/sys/arm/include/asm.h b/sys/arm/include/asm.h
index 73b7355..9122e6e 100644
--- a/sys/arm/include/asm.h
+++ b/sys/arm/include/asm.h
@@ -39,6 +39,8 @@
#ifndef _MACHINE_ASM_H_
#define _MACHINE_ASM_H_
#include <sys/cdefs.h>
+#include <machine/acle-compat.h>
+#include <machine/sysreg.h>
#define _C_LABEL(x) x
#define _ASM_LABEL(x) x
@@ -58,7 +60,24 @@
#endif
/*
+ * gas/arm uses @ as a single comment character and thus cannot be used here.
+ * It recognises the # instead of an @ symbol in .type directives.
+ */
+#define _ASM_TYPE_FUNCTION #function
+#define _ASM_TYPE_OBJECT #object
+
+/* XXX Is this still the right prologue for profiling? */
+#ifdef GPROF
+#define _PROF_PROLOGUE \
+ mov ip, lr; \
+ bl __mcount
+#else
+#define _PROF_PROLOGUE
+#endif
+
+/*
* EENTRY()/EEND() mark "extra" entry/exit points from a function.
+ * LEENTRY()/LEEND() are the the same for local symbols.
* The unwind info cannot handle the concept of a nested function, or a function
* with multiple .fnstart directives, but some of our assembler code is written
* with multiple labels to allow entry at several points. The EENTRY() macro
@@ -66,41 +85,36 @@
* basically just a label that you can jump to. The EEND() macro does nothing
* at all, except document the exit point associated with the same-named entry.
*/
-#define _EENTRY(x) .globl x; .type x,_ASM_TYPE_FUNCTION; x:
-#define _EEND(x) /* nothing */
+#define GLOBAL(x) .global x
-/*
- * gas/arm uses @ as a single comment character and thus cannot be used here
- * Instead it recognised the # instead of an @ symbols in .type directives
- * We define a couple of macros so that assembly code will not be dependent
- * on one or the other.
- */
-#define _ASM_TYPE_FUNCTION #function
-#define _ASM_TYPE_OBJECT #object
-#define GLOBAL(X) .globl x
-#define _ENTRY(x) \
- .text; _ALIGN_TEXT; _EENTRY(x) _FNSTART
-#define _END(x) .size x, . - x; _FNEND
+#define _LEENTRY(x) .type x,_ASM_TYPE_FUNCTION; x:
+#define _LEEND(x) /* nothing */
+#define _EENTRY(x) GLOBAL(x); _LEENTRY(x)
+#define _EEND(x) _LEEND(x)
-#ifdef GPROF
-# define _PROF_PROLOGUE \
- mov ip, lr; bl __mcount
-#else
-# define _PROF_PROLOGUE
-#endif
+#define _LENTRY(x) .text; _ALIGN_TEXT; _LEENTRY(x); _FNSTART
+#define _LEND(x) .size x, . - x; _FNEND
+#define _ENTRY(x) .text; _ALIGN_TEXT; _EENTRY(x); _FNSTART
+#define _END(x) _LEND(x)
#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
-#define EENTRY(y) _EENTRY(_C_LABEL(y)); _PROF_PROLOGUE
+#define EENTRY(y) _EENTRY(_C_LABEL(y));
#define ENTRY_NP(y) _ENTRY(_C_LABEL(y))
#define EENTRY_NP(y) _EENTRY(_C_LABEL(y))
#define END(y) _END(_C_LABEL(y))
-#define EEND(y)
+#define EEND(y) _EEND(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
-#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#define ASLENTRY(y) _LENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
+#define ASEENTRY(y) _EENTRY(_ASM_LABEL(y));
+#define ASLEENTRY(y) _LEENTRY(_ASM_LABEL(y));
#define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y))
+#define ASLENTRY_NP(y) _LENTRY(_ASM_LABEL(y))
#define ASEENTRY_NP(y) _EENTRY(_ASM_LABEL(y))
+#define ASLEENTRY_NP(y) _LEENTRY(_ASM_LABEL(y))
#define ASEND(y) _END(_ASM_LABEL(y))
-#define ASEEND(y)
+#define ASLEND(y) _LEND(_ASM_LABEL(y))
+#define ASEEND(y) _EEND(_ASM_LABEL(y))
+#define ASLEEND(y) _LEEND(_ASM_LABEL(y))
#define ASMSTR .asciz
@@ -209,4 +223,18 @@
# define RETc(c) mov##c pc, lr
#endif
+#if __ARM_ARCH >= 7
+#define ISB isb
+#define DSB dsb
+#define DMB dmb
+#elif __ARM_ARCH == 6
+#define ISB mcr CP15_CP15ISB
+#define DSB mcr CP15_CP15DSB
+#define DMB mcr CP15_CP15DMB
+#else
+#define ISB mcr CP15_CP15ISB
+#define DSB mcr CP15_CP15DSB /* DSB and DMB are the */
+#define DMB mcr CP15_CP15DSB /* same prior to v6.*/
+#endif
+
#endif /* !_MACHINE_ASM_H_ */
diff --git a/sys/arm/include/cpuconf.h b/sys/arm/include/cpuconf.h
index da35e57..fb02153 100644
--- a/sys/arm/include/cpuconf.h
+++ b/sys/arm/include/cpuconf.h
@@ -99,6 +99,29 @@
#endif
#define ARM_NARCH (ARM_ARCH_4 + ARM_ARCH_5 + ARM_ARCH_6 | ARM_ARCH_7A)
+
+/*
+ * Compatibility for userland builds that have no CPUTYPE defined. Use the ARCH
+ * constants predefined by the compiler to define our old-school arch constants.
+ * This is a stopgap measure to tide us over until the conversion of all code
+ * to the newer ACLE constants defined by ARM (see acle-compat.h).
+ */
+#if ARM_NARCH == 0
+#if defined(__ARM_ARCH_4T__)
+#undef ARM_ARCH_4
+#undef ARM_NARCH
+#define ARM_ARCH_4 1
+#define ARM_NARCH 1
+#define CPU_ARM9 1
+#elif defined(__ARM_ARCH_6ZK__)
+#undef ARM_ARCH_6
+#undef ARM_NARCH
+#define ARM_ARCH_6 1
+#define ARM_NARCH 1
+#define CPU_ARM1176 1
+#endif
+#endif
+
#if ARM_NARCH == 0 && !defined(KLD_MODULE) && defined(_KERNEL)
#error ARM_NARCH is 0
#endif
diff --git a/sys/arm/include/db_machdep.h b/sys/arm/include/db_machdep.h
index da3b30e..741cae9 100644
--- a/sys/arm/include/db_machdep.h
+++ b/sys/arm/include/db_machdep.h
@@ -38,7 +38,7 @@
typedef vm_offset_t db_addr_t;
typedef int db_expr_t;
-#define PC_REGS() ((db_addr_t)kdb_thrctx->un_32.pcb32_pc)
+#define PC_REGS() ((db_addr_t)kdb_thrctx->pcb_regs.sf_pc)
#define BKPT_INST (KERNEL_BREAKPOINT)
#define BKPT_SIZE (INSN_SIZE)
diff --git a/sys/arm/include/frame.h b/sys/arm/include/frame.h
index 1e6f43a..7655d89 100644
--- a/sys/arm/include/frame.h
+++ b/sys/arm/include/frame.h
@@ -86,57 +86,16 @@ struct trapframe {
#define tf_r13 tf_usr_sp
#define tf_r14 tf_usr_lr
#define tf_r15 tf_pc
-/*
- * * Scheduler activations upcall frame. Pushed onto user stack before
- * * calling an SA upcall.
- * */
-
-struct saframe {
-#if 0 /* in registers on entry to upcall */
- int sa_type;
- struct sa_t ** sa_sas;
- int sa_events;
- int sa_interrupted;
-#endif
- void * sa_arg;
-};
/*
- * * Signal frame. Pushed onto user stack before calling sigcode.
- * */
-
-/* the pointers are use in the trampoline code to locate the ucontext */
+ * Signal frame. Pushed onto user stack before calling sigcode.
+ * The pointers are used in the trampoline code to locate the ucontext.
+ */
struct sigframe {
- siginfo_t sf_si; /* actual saved siginfo */
+ siginfo_t sf_si; /* actual saved siginfo */
ucontext_t sf_uc; /* actual saved ucontext */
};
-/*
- * System stack frames.
- */
-
-
-typedef struct irqframe {
- unsigned int if_spsr;
- unsigned int if_r0;
- unsigned int if_r1;
- unsigned int if_r2;
- unsigned int if_r3;
- unsigned int if_r4;
- unsigned int if_r5;
- unsigned int if_r6;
- unsigned int if_r7;
- unsigned int if_r8;
- unsigned int if_r9;
- unsigned int if_r10;
- unsigned int if_r11;
- unsigned int if_r12;
- unsigned int if_usr_sp;
- unsigned int if_usr_lr;
- unsigned int if_svc_sp;
- unsigned int if_svc_lr;
- unsigned int if_pc;
-} irqframe_t;
/*
* Switch frame.
@@ -144,16 +103,23 @@ typedef struct irqframe {
* It is important this is a multiple of 8 bytes so the stack is correctly
* aligned when we create new threads.
*/
-
-struct switchframe {
- u_int pad; /* Used to pad the struct to a multiple of 8-bytes */
- u_int sf_r4;
- u_int sf_r5;
- u_int sf_r6;
- u_int sf_r7;
- u_int sf_pc;
+struct switchframe
+{
+ register_t sf_r4;
+ register_t sf_r5;
+ register_t sf_r6;
+ register_t sf_r7;
+ register_t sf_r8;
+ register_t sf_r9;
+ register_t sf_r10;
+ register_t sf_r11;
+ register_t sf_r12;
+ register_t sf_sp;
+ register_t sf_lr;
+ register_t sf_pc;
};
+
/*
* Stack frame. Used during stack traces (db_trace.c)
*/
diff --git a/sys/arm/include/intr.h b/sys/arm/include/intr.h
index 3509772..9ee86f3 100644
--- a/sys/arm/include/intr.h
+++ b/sys/arm/include/intr.h
@@ -39,6 +39,10 @@
#ifndef _MACHINE_INTR_H_
#define _MACHINE_INTR_H_
+#ifdef FDT
+#include <dev/ofw/openfirm.h>
+#endif
+
/* XXX move to std.* files? */
#ifdef CPU_XSCALE_81342
#define NIRQ 128
@@ -85,4 +89,8 @@ void gic_init_secondary(void);
int gic_decode_fdt(uint32_t iparentnode, uint32_t *intrcells, int *interrupt,
int *trig, int *pol);
+#ifdef FDT
+int arm_fdt_map_irq(phandle_t, pcell_t *, int);
+#endif
+
#endif /* _MACHINE_INTR_H */
diff --git a/sys/arm/include/machdep.h b/sys/arm/include/machdep.h
index 907270e..ee524a8 100644
--- a/sys/arm/include/machdep.h
+++ b/sys/arm/include/machdep.h
@@ -20,8 +20,7 @@ struct trapframe;
void arm_lock_cache_line(vm_offset_t);
void init_proc0(vm_offset_t kstack);
void halt(void);
-void data_abort_handler(struct trapframe *);
-void prefetch_abort_handler(struct trapframe *);
+void abort_handler(struct trapframe *, int );
void set_stackptrs(int cpu);
void undefinedinstruction_bounce(struct trapframe *);
diff --git a/sys/arm/include/pcb.h b/sys/arm/include/pcb.h
index 252d94e..b5ed607 100644
--- a/sys/arm/include/pcb.h
+++ b/sys/arm/include/pcb.h
@@ -39,50 +39,29 @@
#define _MACHINE_PCB_H_
#include <machine/fp.h>
+#include <machine/frame.h>
-struct trapframe;
-
-struct pcb_arm32 {
- vm_offset_t pcb32_pagedir; /* PT hooks */
- uint32_t *pcb32_pl1vec; /* PTR to vector_base L1 entry*/
- uint32_t pcb32_l1vec; /* Value to stuff on ctx sw */
- u_int pcb32_dacr; /* Domain Access Control Reg */
- /*
- * WARNING!
- * cpuswitch.S relies on pcb32_r8 being quad-aligned in struct pcb
- * (due to the use of "strd" when compiled for XSCALE)
- */
- u_int pcb32_r8; /* used */
- u_int pcb32_r9; /* used */
- u_int pcb32_r10; /* used */
- u_int pcb32_r11; /* used */
- u_int pcb32_r12; /* used */
- u_int pcb32_sp; /* used */
- u_int pcb32_lr;
- u_int pcb32_pc;
-};
-#define pcb_pagedir un_32.pcb32_pagedir
-#define pcb_pl1vec un_32.pcb32_pl1vec
-#define pcb_l1vec un_32.pcb32_l1vec
-#define pcb_dacr un_32.pcb32_dacr
-#define pcb_cstate un_32.pcb32_cstate
-
/*
* WARNING!
- * See warning for struct pcb_arm32, above, before changing struct pcb!
+ * Keep pcb_regs first for faster access in switch.S
*/
struct pcb {
+ struct switchframe pcb_regs; /* CPU state */
u_int pcb_flags;
#define PCB_OWNFPU 0x00000001
#define PCB_NOALIGNFLT 0x00000002
caddr_t pcb_onfault; /* On fault handler */
- struct pcb_arm32 un_32;
+ vm_offset_t pcb_pagedir; /* PT hooks */
+ uint32_t *pcb_pl1vec; /* PTR to vector_base L1 entry*/
+ uint32_t pcb_l1vec; /* Value to stuff on ctx sw */
+ u_int pcb_dacr; /* Domain Access Control Reg */
+
struct vfp_state pcb_vfpstate; /* VP/NEON state */
u_int pcb_vfpcpu; /* VP/NEON last cpu */
} __aligned(8); /*
* We need the PCB to be aligned on 8 bytes, as we may
- * access it using ldrd/strd, and some CPUs require it
+ * access it using ldrd/strd, and ARM ABI require it
* to by aligned on 8 bytes.
*/
diff --git a/sys/arm/include/smp.h b/sys/arm/include/smp.h
index 6301c9a..3803674 100644
--- a/sys/arm/include/smp.h
+++ b/sys/arm/include/smp.h
@@ -24,7 +24,7 @@ void ipi_selected(cpuset_t cpus, u_int ipi);
/* PIC interface */
void pic_ipi_send(cpuset_t cpus, u_int ipi);
void pic_ipi_clear(int ipi);
-int pic_ipi_get(int arg);
+int pic_ipi_read(int arg);
/* Platform interface */
void platform_mp_setmaxid(void);
diff --git a/sys/arm/include/sysreg.h b/sys/arm/include/sysreg.h
index 76b1f2b..b1c7fd3 100644
--- a/sys/arm/include/sysreg.h
+++ b/sys/arm/include/sysreg.h
@@ -99,12 +99,13 @@
#if __ARM_ARCH >= 6
/* From ARMv6: */
#define CP15_IFSR(rr) p15, 0, rr, c5, c0, 1 /* Instruction Fault Status Register */
+#endif
+#if __ARM_ARCH >= 7
/* From ARMv7: */
#define CP15_ADFSR(rr) p15, 0, rr, c5, c1, 0 /* Auxiliary Data Fault Status Register */
#define CP15_AIFSR(rr) p15, 0, rr, c5, c1, 1 /* Auxiliary Instruction Fault Status Register */
#endif
-
/*
* CP15 C6 registers
*/
@@ -118,7 +119,7 @@
/*
* CP15 C7 registers
*/
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH >= 7 && defined(SMP)
/* From ARMv7: */
#define CP15_ICIALLUIS p15, 0, r0, c7, c1, 0 /* Instruction cache invalidate all PoU, IS */
#define CP15_BPIALLIS p15, 0, r0, c7, c1, 6 /* Branch predictor invalidate all IS */
@@ -128,14 +129,14 @@
#define CP15_ICIALLU p15, 0, r0, c7, c5, 0 /* Instruction cache invalidate all PoU */
#define CP15_ICIMVAU(rr) p15, 0, rr, c7, c5, 1 /* Instruction cache invalidate */
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH == 6
/* Deprecated in ARMv7 */
#define CP15_CP15ISB p15, 0, r0, c7, c5, 4 /* ISB */
#endif
#define CP15_BPIALL p15, 0, r0, c7, c5, 6 /* Branch predictor invalidate all */
#define CP15_BPIMVA p15, 0, rr, c7, c5, 7 /* Branch predictor invalidate by MVA */
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH == 6
/* Only ARMv6: */
#define CP15_DCIALL p15, 0, r0, c7, c6, 0 /* Data cache invalidate all */
#endif
@@ -147,7 +148,7 @@
#define CP15_ATS1CUR(rr) p15, 0, rr, c7, c8, 2 /* Stage 1 Current state unprivileged read */
#define CP15_ATS1CUW(rr) p15, 0, rr, c7, c8, 3 /* Stage 1 Current state unprivileged write */
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH >= 7
/* From ARMv7: */
#define CP15_ATS12NSOPR(rr) p15, 0, rr, c7, c8, 4 /* Stages 1 and 2 Non-secure only PL1 read */
#define CP15_ATS12NSOPW(rr) p15, 0, rr, c7, c8, 5 /* Stages 1 and 2 Non-secure only PL1 write */
@@ -155,24 +156,24 @@
#define CP15_ATS12NSOUW(rr) p15, 0, rr, c7, c8, 7 /* Stages 1 and 2 Non-secure only unprivileged write */
#endif
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH == 6
/* Only ARMv6: */
#define CP15_DCCALL p15, 0, r0, c7, c10, 0 /* Data cache clean all */
#endif
#define CP15_DCCMVAC(rr) p15, 0, rr, c7, c10, 1 /* Data cache clean by MVA PoC */
#define CP15_DCCSW(rr) p15, 0, rr, c7, c10, 2 /* Data cache clean by set/way */
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH == 6
/* Only ARMv6: */
#define CP15_CP15DSB p15, 0, r0, c7, c10, 4 /* DSB */
#define CP15_CP15DMB p15, 0, r0, c7, c10, 5 /* DMB */
#endif
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH >= 7
/* From ARMv7: */
#define CP15_DCCMVAU(rr) p15, 0, rr, c7, c11, 1 /* Data cache clean by MVA PoU */
#endif
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH == 6
/* Only ARMv6: */
#define CP15_DCCIALL p15, 0, r0, c7, c14, 0 /* Data cache clean and invalidate all */
#endif
@@ -182,7 +183,7 @@
/*
* CP15 C8 registers
*/
-#if __ARM_ARCH >= 6
+#if __ARM_ARCH >= 7 && defined(SMP)
/* From ARMv7: */
#define CP15_TLBIALLIS p15, 0, r0, c8, c3, 0 /* Invalidate entire unified TLB IS */
#define CP15_TLBIMVAIS(rr) p15, 0, rr, c8, c3, 1 /* Invalidate unified TLB by MVA IS */
@@ -229,4 +230,9 @@
#define CP15_TPIDRURO(rr) p15, 0, rr, c13, c0, 3 /* User Read-Only Thread ID Register */
#define CP15_TPIDRPRW(rr) p15, 0, rr, c13, c0, 4 /* PL1 only Thread ID Register */
+/*
+ * CP15 C15 registers
+ */
+#define CP15_CBAR(rr) p15, 4, rr, c15, c0, 0 /* Configuration Base Address Register */
+
#endif /* !MACHINE_SYSREG_H */
diff --git a/sys/arm/lpc/lpc_intc.c b/sys/arm/lpc/lpc_intc.c
index 3137e89..bf26645 100644
--- a/sys/arm/lpc/lpc_intc.c
+++ b/sys/arm/lpc/lpc_intc.c
@@ -59,10 +59,10 @@ static void lpc_intc_eoi(void *);
static struct lpc_intc_softc *intc_softc = NULL;
-#define intc_read_4(reg) \
- bus_space_read_4(intc_softc->li_bst, intc_softc->li_bsh, reg)
-#define intc_write_4(reg, val) \
- bus_space_write_4(intc_softc->li_bst, intc_softc->li_bsh, reg, val)
+#define intc_read_4(_sc, _reg) \
+ bus_space_read_4((_sc)->li_bst, (_sc)->li_bsh, (_reg))
+#define intc_write_4(_sc, _reg, _val) \
+ bus_space_write_4((_sc)->li_bst, (_sc)->li_bsh, (_reg), (_val))
static int
lpc_intc_probe(device_t dev)
@@ -100,12 +100,12 @@ lpc_intc_attach(device_t dev)
arm_post_filter = lpc_intc_eoi;
/* Clear interrupt status registers and disable all interrupts */
- intc_write_4(LPC_INTC_MIC_ER, 0);
- intc_write_4(LPC_INTC_SIC1_ER, 0);
- intc_write_4(LPC_INTC_SIC2_ER, 0);
- intc_write_4(LPC_INTC_MIC_RSR, ~0);
- intc_write_4(LPC_INTC_SIC1_RSR, ~0);
- intc_write_4(LPC_INTC_SIC2_RSR, ~0);
+ intc_write_4(sc, LPC_INTC_MIC_ER, 0);
+ intc_write_4(sc, LPC_INTC_SIC1_ER, 0);
+ intc_write_4(sc, LPC_INTC_SIC2_ER, 0);
+ intc_write_4(sc, LPC_INTC_MIC_RSR, ~0);
+ intc_write_4(sc, LPC_INTC_SIC1_RSR, ~0);
+ intc_write_4(sc, LPC_INTC_SIC2_RSR, ~0);
return (0);
}
@@ -128,25 +128,26 @@ DRIVER_MODULE(pic, simplebus, lpc_intc_driver, lpc_intc_devclass, 0, 0);
int
arm_get_next_irq(int last)
{
+ struct lpc_intc_softc *sc = intc_softc;
uint32_t value;
int i;
/* IRQs 0-31 are mapped to LPC_INTC_MIC_SR */
- value = intc_read_4(LPC_INTC_MIC_SR);
+ value = intc_read_4(sc, LPC_INTC_MIC_SR);
for (i = 0; i < 32; i++) {
if (value & (1 << i))
return (i);
}
/* IRQs 32-63 are mapped to LPC_INTC_SIC1_SR */
- value = intc_read_4(LPC_INTC_SIC1_SR);
+ value = intc_read_4(sc, LPC_INTC_SIC1_SR);
for (i = 0; i < 32; i++) {
if (value & (1 << i))
return (i + 32);
}
/* IRQs 64-95 are mapped to LPC_INTC_SIC2_SR */
- value = intc_read_4(LPC_INTC_SIC2_SR);
+ value = intc_read_4(sc, LPC_INTC_SIC2_SR);
for (i = 0; i < 32; i++) {
if (value & (1 << i))
return (i + 64);
@@ -158,6 +159,7 @@ arm_get_next_irq(int last)
void
arm_mask_irq(uintptr_t nb)
{
+ struct lpc_intc_softc *sc = intc_softc;
int reg;
uint32_t value;
@@ -174,14 +176,15 @@ arm_mask_irq(uintptr_t nb)
reg = LPC_INTC_MIC_ER;
/* Clear bit in ER register */
- value = intc_read_4(reg);
+ value = intc_read_4(sc, reg);
value &= ~(1 << nb);
- intc_write_4(reg, value);
+ intc_write_4(sc, reg, value);
}
void
arm_unmask_irq(uintptr_t nb)
{
+ struct lpc_intc_softc *sc = intc_softc;
int reg;
uint32_t value;
@@ -195,14 +198,15 @@ arm_unmask_irq(uintptr_t nb)
reg = LPC_INTC_MIC_ER;
/* Set bit in ER register */
- value = intc_read_4(reg);
+ value = intc_read_4(sc, reg);
value |= (1 << nb);
- intc_write_4(reg, value);
+ intc_write_4(sc, reg, value);
}
static void
lpc_intc_eoi(void *data)
{
+ struct lpc_intc_softc *sc = intc_softc;
int reg;
int nb = (int)data;
uint32_t value;
@@ -217,9 +221,9 @@ lpc_intc_eoi(void *data)
reg = LPC_INTC_MIC_RSR;
/* Set bit in RSR register */
- value = intc_read_4(reg);
+ value = intc_read_4(sc, reg);
value |= (1 << nb);
- intc_write_4(reg, value);
+ intc_write_4(sc, reg, value);
}
diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c
index 813caf4..bfb5554 100644
--- a/sys/arm/mv/mpic.c
+++ b/sys/arm/mv/mpic.c
@@ -375,7 +375,7 @@ pic_ipi_send(cpuset_t cpus, u_int ipi)
}
int
-pic_ipi_get(int i __unused)
+pic_ipi_read(int i __unused)
{
uint32_t val;
diff --git a/sys/arm/mv/std-pj4b.mv b/sys/arm/mv/std-pj4b.mv
index 7d779c2..1053ff0 100644
--- a/sys/arm/mv/std-pj4b.mv
+++ b/sys/arm/mv/std-pj4b.mv
@@ -3,5 +3,6 @@
files "../mv/files.mv"
cpu CPU_MV_PJ4B
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
options VM_MAXUSER_ADDRESS="(KERNBASE-(1024*1024*1024))"
diff --git a/sys/arm/rockchip/std.rk30xx b/sys/arm/rockchip/std.rk30xx
index 79ddcc6..b62b77a 100644
--- a/sys/arm/rockchip/std.rk30xx
+++ b/sys/arm/rockchip/std.rk30xx
@@ -3,6 +3,7 @@
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
makeoption ARM_LITTLE_ENDIAN
# Physical memory starts at 0x60400000. We assume images are loaded at
diff --git a/sys/arm/samsung/exynos/std.exynos5250 b/sys/arm/samsung/exynos/std.exynos5250
index 5f59adc..39c378b 100644
--- a/sys/arm/samsung/exynos/std.exynos5250
+++ b/sys/arm/samsung/exynos/std.exynos5250
@@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
options PHYSADDR=0x40000000
diff --git a/sys/arm/samsung/exynos/std.exynos5420 b/sys/arm/samsung/exynos/std.exynos5420
index c6468e7..b70537d 100644
--- a/sys/arm/samsung/exynos/std.exynos5420
+++ b/sys/arm/samsung/exynos/std.exynos5420
@@ -4,6 +4,7 @@ makeoption ARM_LITTLE_ENDIAN
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
options PHYSADDR=0x20000000
diff --git a/sys/arm/ti/aintc.c b/sys/arm/ti/aintc.c
index 213a1d3..675a5f3 100644
--- a/sys/arm/ti/aintc.c
+++ b/sys/arm/ti/aintc.c
@@ -72,10 +72,10 @@ static struct resource_spec ti_aintc_spec[] = {
static struct ti_aintc_softc *ti_aintc_sc = NULL;
-#define aintc_read_4(reg) \
- bus_space_read_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg)
-#define aintc_write_4(reg, val) \
- bus_space_write_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg, val)
+#define aintc_read_4(_sc, reg) \
+ bus_space_read_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg))
+#define aintc_write_4(_sc, reg, val) \
+ bus_space_write_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg), (val))
static int
@@ -112,17 +112,17 @@ ti_aintc_attach(device_t dev)
ti_aintc_sc = sc;
- x = aintc_read_4(INTC_REVISION);
+ x = aintc_read_4(sc, INTC_REVISION);
device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF);
/* SoftReset */
- aintc_write_4(INTC_SYSCONFIG, 2);
+ aintc_write_4(sc, INTC_SYSCONFIG, 2);
/* Wait for reset to complete */
- while(!(aintc_read_4(INTC_SYSSTATUS) & 1));
+ while(!(aintc_read_4(sc, INTC_SYSSTATUS) & 1));
/*Set Priority Threshold */
- aintc_write_4(INTC_THRESHOLD, 0xFF);
+ aintc_write_4(sc, INTC_THRESHOLD, 0xFF);
return (0);
}
@@ -146,22 +146,23 @@ DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0);
int
arm_get_next_irq(int last_irq)
{
+ struct ti_aintc_softc *sc = ti_aintc_sc;
uint32_t active_irq;
if (last_irq != -1) {
- aintc_write_4(INTC_ISR_CLEAR(last_irq >> 5),
+ aintc_write_4(sc, INTC_ISR_CLEAR(last_irq >> 5),
1UL << (last_irq & 0x1F));
- aintc_write_4(INTC_CONTROL,1);
+ aintc_write_4(sc, INTC_CONTROL, 1);
}
/* Get the next active interrupt */
- active_irq = aintc_read_4(INTC_SIR_IRQ);
+ active_irq = aintc_read_4(sc, INTC_SIR_IRQ);
/* Check for spurious interrupt */
if ((active_irq & 0xffffff80)) {
- device_printf(ti_aintc_sc->sc_dev,
- "Spurious interrupt detected (0x%08x)\n", active_irq);
- aintc_write_4(INTC_SIR_IRQ, 0);
+ device_printf(sc->sc_dev,
+ "Spurious interrupt detected (0x%08x)\n", active_irq);
+ aintc_write_4(sc, INTC_SIR_IRQ, 0);
return -1;
}
@@ -174,13 +175,16 @@ arm_get_next_irq(int last_irq)
void
arm_mask_irq(uintptr_t nb)
{
- aintc_write_4(INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F)));
+ struct ti_aintc_softc *sc = ti_aintc_sc;
+
+ aintc_write_4(sc, INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F)));
}
void
arm_unmask_irq(uintptr_t nb)
{
+ struct ti_aintc_softc *sc = ti_aintc_sc;
arm_irq_memory_barrier(nb);
- aintc_write_4(INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F)));
+ aintc_write_4(sc, INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F)));
}
diff --git a/sys/arm/ti/am335x/am335x_usbss.c b/sys/arm/ti/am335x/am335x_usbss.c
index f1204f3..0173922 100644
--- a/sys/arm/ti/am335x/am335x_usbss.c
+++ b/sys/arm/ti/am335x/am335x_usbss.c
@@ -288,21 +288,30 @@ musbotg_attach(device_t dev)
return (ENXIO);
}
+ /* Enable device clocks. */
+ ti_prcm_clk_enable(MUSB0_CLK);
+
/*
- * Reset USBSS, USB0 and USB1
+ * Reset USBSS, USB0 and USB1.
+ * The registers of USB subsystem must not be accessed while the
+ * reset pulse is active (200ns).
*/
+ USBSS_WRITE4(sc, USBSS_SYSCONFIG, USBSS_SYSCONFIG_SRESET);
+ DELAY(100);
+ i = 10;
+ while (USBSS_READ4(sc, USBSS_SYSCONFIG) & USBSS_SYSCONFIG_SRESET) {
+ DELAY(100);
+ if (i-- == 0) {
+ device_printf(dev, "reset timeout.\n");
+ return (ENXIO);
+ }
+ }
+
+ /* Read the module revision. */
rev = USBSS_READ4(sc, USBSS_REVREG);
device_printf(dev, "TI AM335X USBSS v%d.%d.%d\n",
(rev >> 8) & 7, (rev >> 6) & 3, rev & 63);
- ti_prcm_clk_enable(MUSB0_CLK);
-
- USBSS_WRITE4(sc, USBSS_SYSCONFIG,
- USBSS_SYSCONFIG_SRESET);
- while (USBSS_READ4(sc, USBSS_SYSCONFIG) &
- USBSS_SYSCONFIG_SRESET)
- ;
-
err = bus_setup_intr(dev, sc->sc_irq_res[0],
INTR_TYPE_BIO | INTR_MPSAFE,
NULL, (driver_intr_t *)musbotg_usbss_interrupt, sc,
diff --git a/sys/arm/ti/std.ti b/sys/arm/ti/std.ti
index 218d731..5e859b6 100644
--- a/sys/arm/ti/std.ti
+++ b/sys/arm/ti/std.ti
@@ -2,5 +2,6 @@
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
files "../ti/files.ti"
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c
index 612ceb9..5fe8094 100644
--- a/sys/arm/ti/ti_gpio.c
+++ b/sys/arm/ti/ti_gpio.c
@@ -1,6 +1,6 @@
/*-
- * Copyright (c) 2011
- * Ben Gray <ben.r.gray@gmail.com>.
+ * Copyright (c) 2011 Ben Gray <ben.r.gray@gmail.com>.
+ * Copyright (c) 2014 Luiz Otavio O Souza <loos@FreeBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,17 +26,8 @@
*/
/**
- * Very simple GPIO (general purpose IO) driver module for TI OMAP SoC's.
- *
- * Currently this driver only does the basics, get a value on a pin & set a
- * value on a pin. Hopefully over time I'll expand this to be a bit more generic
- * and support interrupts and other various bits on the SoC can do ... in the
- * meantime this is all you get.
- *
- * Beware the OMA datasheet(s) lists GPIO banks 1-6, whereas I've used 0-5 here
- * in the code.
- *
- *
+ * Beware that the OMAP4 datasheet(s) lists GPIO banks 1-6, whereas the code
+ * here uses 0-5.
*/
#include <sys/cdefs.h>
@@ -52,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/gpio.h>
+#include <sys/interrupt.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -69,10 +61,13 @@ __FBSDID("$FreeBSD$");
#include "gpio_if.h"
#include "ti_gpio_if.h"
+#if !defined(SOC_OMAP4) && !defined(SOC_TI_AM335X)
+#error "Unknown SoC"
+#endif
+
/* Register definitions */
#define TI_GPIO_REVISION 0x0000
#define TI_GPIO_SYSCONFIG 0x0010
-#if defined(SOC_OMAP4) || defined(SOC_TI_AM335X)
#define TI_GPIO_IRQSTATUS_RAW_0 0x0024
#define TI_GPIO_IRQSTATUS_RAW_1 0x0028
#define TI_GPIO_IRQSTATUS_0 0x002C
@@ -103,9 +98,6 @@ __FBSDID("$FreeBSD$");
#define TI_GPIO_SETWKUENA 0x0184
#define TI_GPIO_CLEARDATAOUT 0x0190
#define TI_GPIO_SETDATAOUT 0x0194
-#else
-#error "Unknown SoC"
-#endif
/* Other SoC Specific definitions */
#define OMAP4_MAX_GPIO_BANKS 6
@@ -117,6 +109,10 @@ __FBSDID("$FreeBSD$");
#define AM335X_INTR_PER_BANK 2
#define AM335X_GPIO_REV 0x50600801
#define PINS_PER_BANK 32
+#define TI_GPIO_BANK(p) ((p) / PINS_PER_BANK)
+#define TI_GPIO_MASK(p) (1U << ((p) % PINS_PER_BANK))
+
+static struct ti_gpio_softc *ti_gpio_sc = NULL;
static u_int
ti_max_gpio_banks(void)
@@ -226,17 +222,17 @@ static struct resource_spec ti_gpio_irq_spec[] = {
/**
* Macros for driver mutex locking
*/
-#define TI_GPIO_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
-#define TI_GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
+#define TI_GPIO_LOCK(_sc) mtx_lock_spin(&(_sc)->sc_mtx)
+#define TI_GPIO_UNLOCK(_sc) mtx_unlock_spin(&(_sc)->sc_mtx)
#define TI_GPIO_LOCK_INIT(_sc) \
- mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \
- "ti_gpio", MTX_DEF)
-#define TI_GPIO_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx)
-#define TI_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED)
-#define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED)
+ mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \
+ "ti_gpio", MTX_SPIN)
+#define TI_GPIO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx)
+#define TI_GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
+#define TI_GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
/**
- * ti_gpio_read_4 - reads a 16-bit value from one of the PADCONFS registers
+ * ti_gpio_read_4 - reads a 32-bit value from one of the GPIO registers
* @sc: GPIO device context
* @bank: The bank to read from
* @off: The offset of a register from the GPIO register address range
@@ -252,7 +248,7 @@ ti_gpio_read_4(struct ti_gpio_softc *sc, unsigned int bank, bus_size_t off)
}
/**
- * ti_gpio_write_4 - writes a 32-bit value to one of the PADCONFS registers
+ * ti_gpio_write_4 - writes a 32-bit value to one of the GPIO registers
* @sc: GPIO device context
* @bank: The bank to write to
* @off: The offset of a register from the GPIO register address range
@@ -273,13 +269,43 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
{
/* We clear both set of registers. */
-#if defined(SOC_OMAP4) || defined(SOC_TI_AM335X)
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_0, mask);
ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_CLR_1, mask);
-#else
- ti_gpio_write_4(sc, bank, TI_GPIO_CLEARIRQENABLE1, mask);
- ti_gpio_write_4(sc, bank, TI_GPIO_CLEARIRQENABLE2, mask);
-#endif
+}
+
+static inline void
+ti_gpio_intr_set(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
+{
+
+ /*
+ * On OMAP4 we unmask only the MPU interrupt and on AM335x we
+ * also activate only the first interrupt.
+ */
+ ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_SET_0, mask);
+}
+
+static inline void
+ti_gpio_intr_ack(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
+{
+
+ /*
+ * Acknowledge the interrupt on both registers even if we use only
+ * the first one.
+ */
+ ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_0, mask);
+ ti_gpio_write_4(sc, bank, TI_GPIO_IRQSTATUS_1, mask);
+}
+
+static inline uint32_t
+ti_gpio_intr_status(struct ti_gpio_softc *sc, unsigned int bank)
+{
+ uint32_t reg;
+
+ /* Get the status from both registers. */
+ reg = ti_gpio_read_4(sc, bank, TI_GPIO_IRQSTATUS_0);
+ reg |= ti_gpio_read_4(sc, bank, TI_GPIO_IRQSTATUS_1);
+
+ return (reg);
}
/**
@@ -290,7 +316,7 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
*
*
* LOCKING:
- * Internally locks the context
+ * No locking required, returns static data.
*
* RETURNS:
* Returns 0 on success otherwise an error code
@@ -298,23 +324,21 @@ ti_gpio_intr_clr(struct ti_gpio_softc *sc, unsigned int bank, uint32_t mask)
static int
ti_gpio_pin_max(device_t dev, int *maxpin)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- unsigned int i;
- unsigned int banks = 0;
- TI_GPIO_LOCK(sc);
+ *maxpin = ti_max_gpio_banks() * PINS_PER_BANK - 1;
- /* Calculate how many valid banks we have and then multiply that by 32 to
- * give use the total number of pins.
- */
- for (i = 0; i < ti_max_gpio_banks(); i++) {
- if (sc->sc_mem_res[i] != NULL)
- banks++;
- }
+ return (0);
+}
- *maxpin = (banks * PINS_PER_BANK) - 1;
+static int
+ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin)
+{
- TI_GPIO_UNLOCK(sc);
+ if (pin > sc->sc_maxpin ||
+ TI_GPIO_BANK(pin) >= ti_max_gpio_banks() ||
+ sc->sc_mem_res[TI_GPIO_BANK(pin)] == NULL) {
+ return (EINVAL);
+ }
return (0);
}
@@ -332,7 +356,7 @@ ti_gpio_pin_max(device_t dev, int *maxpin)
* - GPIO_PIN_PULLDOWN
*
* LOCKING:
- * Internally locks the context
+ * No locking required, returns static data.
*
* RETURNS:
* Returns 0 on success otherwise an error code
@@ -340,22 +364,15 @@ ti_gpio_pin_max(device_t dev, int *maxpin)
static int
ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
- *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |GPIO_PIN_PULLUP |
+ *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
GPIO_PIN_PULLDOWN);
- TI_GPIO_UNLOCK(sc);
-
return (0);
}
@@ -378,20 +395,15 @@ ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
static int
ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
/* Get the current pin state */
+ TI_GPIO_LOCK(sc);
TI_GPIO_GET_FLAGS(dev, pin, flags);
-
TI_GPIO_UNLOCK(sc);
return (0);
@@ -407,7 +419,7 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
* of the pin.
*
* LOCKING:
- * Internally locks the context
+ * No locking required, returns static data.
*
* RETURNS:
* Returns 0 on success otherwise an error code
@@ -415,23 +427,16 @@ ti_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
static int
ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
/* Set a very simple name */
snprintf(name, GPIOMAXNAME, "gpio_%u", pin);
name[GPIOMAXNAME - 1] = '\0';
- TI_GPIO_UNLOCK(sc);
-
return (0);
}
@@ -457,33 +462,27 @@ ti_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
static int
ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
- uint32_t mask = (1UL << (pin % PINS_PER_BANK));
- uint32_t reg_val;
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
+ uint32_t oe;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
/* Set the GPIO mode and state */
+ TI_GPIO_LOCK(sc);
if (TI_GPIO_SET_FLAGS(dev, pin, flags) != 0) {
TI_GPIO_UNLOCK(sc);
return (EINVAL);
}
/* If configuring as an output set the "output enable" bit */
- reg_val = ti_gpio_read_4(sc, bank, TI_GPIO_OE);
+ oe = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE);
if (flags & GPIO_PIN_INPUT)
- reg_val |= mask;
+ oe |= TI_GPIO_MASK(pin);
else
- reg_val &= ~mask;
- ti_gpio_write_4(sc, bank, TI_GPIO_OE, reg_val);
-
+ oe &= ~TI_GPIO_MASK(pin);
+ ti_gpio_write_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE, oe);
TI_GPIO_UNLOCK(sc);
return (0);
@@ -506,21 +505,19 @@ ti_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
static int
ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
- uint32_t mask = (1UL << (pin % PINS_PER_BANK));
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
+ uint32_t reg;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
-
- ti_gpio_write_4(sc, bank, (value == GPIO_PIN_LOW) ? TI_GPIO_CLEARDATAOUT
- : TI_GPIO_SETDATAOUT, mask);
+ TI_GPIO_LOCK(sc);
+ if (value == GPIO_PIN_LOW)
+ reg = TI_GPIO_CLEARDATAOUT;
+ else
+ reg = TI_GPIO_SETDATAOUT;
+ ti_gpio_write_4(sc, TI_GPIO_BANK(pin), reg, TI_GPIO_MASK(pin));
TI_GPIO_UNLOCK(sc);
return (0);
@@ -544,28 +541,25 @@ ti_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
static int
ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
- uint32_t mask = (1UL << (pin % PINS_PER_BANK));
- uint32_t val = 0;
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
+ uint32_t oe, reg, val;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
-
- /* Sanity check the pin is not configured as an output */
- val = ti_gpio_read_4(sc, bank, TI_GPIO_OE);
- /* Read the value on the pin */
- if (val & mask)
- *value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAIN) & mask) ? 1 : 0;
+ /*
+ * Return data from output latch when set as output and from the
+ * input register otherwise.
+ */
+ TI_GPIO_LOCK(sc);
+ oe = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_OE);
+ if (oe & TI_GPIO_MASK(pin))
+ reg = TI_GPIO_DATAIN;
else
- *value = (ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT) & mask) ? 1 : 0;
-
+ reg = TI_GPIO_DATAOUT;
+ val = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), reg);
+ *value = (val & TI_GPIO_MASK(pin)) ? 1 : 0;
TI_GPIO_UNLOCK(sc);
return (0);
@@ -586,26 +580,21 @@ ti_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *value)
static int
ti_gpio_pin_toggle(device_t dev, uint32_t pin)
{
- struct ti_gpio_softc *sc = device_get_softc(dev);
- uint32_t bank = (pin / PINS_PER_BANK);
- uint32_t mask = (1UL << (pin % PINS_PER_BANK));
- uint32_t val;
-
- TI_GPIO_LOCK(sc);
+ struct ti_gpio_softc *sc;
+ uint32_t reg, val;
- /* Sanity check the pin number is valid */
- if ((bank >= ti_max_gpio_banks()) || (sc->sc_mem_res[bank] == NULL)) {
- TI_GPIO_UNLOCK(sc);
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
- }
/* Toggle the pin */
- val = ti_gpio_read_4(sc, bank, TI_GPIO_DATAOUT);
- if (val & mask)
- ti_gpio_write_4(sc, bank, TI_GPIO_CLEARDATAOUT, mask);
+ TI_GPIO_LOCK(sc);
+ val = ti_gpio_read_4(sc, TI_GPIO_BANK(pin), TI_GPIO_DATAOUT);
+ if (val & TI_GPIO_MASK(pin))
+ reg = TI_GPIO_CLEARDATAOUT;
else
- ti_gpio_write_4(sc, bank, TI_GPIO_SETDATAOUT, mask);
-
+ reg = TI_GPIO_SETDATAOUT;
+ ti_gpio_write_4(sc, TI_GPIO_BANK(pin), reg, TI_GPIO_MASK(pin));
TI_GPIO_UNLOCK(sc);
return (0);
@@ -615,20 +604,40 @@ ti_gpio_pin_toggle(device_t dev, uint32_t pin)
* ti_gpio_intr - ISR for all GPIO modules
* @arg: the soft context pointer
*
- * Unsused
- *
* LOCKING:
* Internally locks the context
*
*/
-static void
+static int
ti_gpio_intr(void *arg)
{
- struct ti_gpio_softc *sc = arg;
+ int bank_last, irq;
+ struct intr_event *event;
+ struct ti_gpio_softc *sc;
+ uint32_t reg;
- TI_GPIO_LOCK(sc);
- /* TODO: something useful */
- TI_GPIO_UNLOCK(sc);
+ sc = (struct ti_gpio_softc *)arg;
+ bank_last = -1;
+ reg = 0; /* squelch bogus gcc warning */
+ for (irq = 0; irq < sc->sc_maxpin; irq++) {
+
+ /* Read interrupt status only once for each bank. */
+ if (TI_GPIO_BANK(irq) != bank_last) {
+ reg = ti_gpio_intr_status(sc, TI_GPIO_BANK(irq));
+ bank_last = TI_GPIO_BANK(irq);
+ }
+ if ((reg & TI_GPIO_MASK(irq)) == 0)
+ continue;
+ event = sc->sc_events[irq];
+ if (event != NULL && !TAILQ_EMPTY(&event->ie_handlers))
+ intr_event_handle(event, NULL);
+ else
+ device_printf(sc->sc_dev, "Stray IRQ %d\n", irq);
+ /* Ack the IRQ Status bit. */
+ ti_gpio_intr_ack(sc, TI_GPIO_BANK(irq), TI_GPIO_MASK(irq));
+ }
+
+ return (FILTER_HANDLED);
}
static int
@@ -643,13 +652,13 @@ ti_gpio_attach_intr(device_t dev)
break;
/*
- * Register our interrupt handler for each of the IRQ resources.
+ * Register our interrupt filter for each of the IRQ resources.
*/
if (bus_setup_intr(dev, sc->sc_irq_res[i],
- INTR_TYPE_MISC | INTR_MPSAFE, NULL, ti_gpio_intr, sc,
+ INTR_TYPE_MISC | INTR_MPSAFE, ti_gpio_intr, NULL, sc,
&sc->sc_irq_hdl[i]) != 0) {
device_printf(dev,
- "WARNING: unable to register interrupt handler\n");
+ "WARNING: unable to register interrupt filter\n");
return (-1);
}
}
@@ -663,7 +672,7 @@ ti_gpio_detach_intr(device_t dev)
int i;
struct ti_gpio_softc *sc;
- /* Teardown our interrupt handlers. */
+ /* Teardown our interrupt filters. */
sc = device_get_softc(dev);
for (i = 0; i < ti_max_gpio_intrs(); i++) {
if (sc->sc_irq_res[i] == NULL)
@@ -683,7 +692,7 @@ ti_gpio_bank_init(device_t dev, int bank)
{
int pin;
struct ti_gpio_softc *sc;
- uint32_t flags, reg_oe;
+ uint32_t flags, reg_oe, rev;
sc = device_get_softc(dev);
@@ -695,13 +704,12 @@ ti_gpio_bank_init(device_t dev, int bank)
* actual revision numbers, so instead the values have been
* determined by experimentation.
*/
- sc->sc_revision[bank] = ti_gpio_read_4(sc, bank, TI_GPIO_REVISION);
+ rev = ti_gpio_read_4(sc, bank, TI_GPIO_REVISION);
/* Check the revision. */
- if (sc->sc_revision[bank] != ti_gpio_rev()) {
+ if (rev != ti_gpio_rev()) {
device_printf(dev, "Warning: could not determine the revision "
- "of %u GPIO module (revision:0x%08x)\n",
- bank, sc->sc_revision[bank]);
+ "of GPIO module %d (revision:0x%08x)\n", bank, rev);
return (EINVAL);
}
@@ -740,10 +748,13 @@ ti_gpio_attach(device_t dev)
unsigned int i;
int err;
- sc = device_get_softc(dev);
- sc->sc_dev = dev;
+ if (ti_gpio_sc != NULL)
+ return (ENXIO);
+ ti_gpio_sc = sc = device_get_softc(dev);
+ sc->sc_dev = dev;
TI_GPIO_LOCK_INIT(sc);
+ ti_gpio_pin_max(dev, &sc->sc_maxpin);
/* There are up to 6 different GPIO register sets located in different
* memory areas on the chip. The memory range should have been set for
@@ -769,6 +780,24 @@ ti_gpio_attach(device_t dev)
return (ENXIO);
}
+ /*
+ * Initialize the interrupt settings. The default is active-low
+ * interrupts.
+ */
+ sc->sc_irq_trigger = malloc(
+ sizeof(*sc->sc_irq_trigger) * sc->sc_maxpin,
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ sc->sc_irq_polarity = malloc(
+ sizeof(*sc->sc_irq_polarity) * sc->sc_maxpin,
+ M_DEVBUF, M_WAITOK | M_ZERO);
+ for (i = 0; i < sc->sc_maxpin; i++) {
+ sc->sc_irq_trigger[i] = INTR_TRIGGER_LEVEL;
+ sc->sc_irq_polarity[i] = INTR_POLARITY_LOW;
+ }
+
+ sc->sc_events = malloc(sizeof(struct intr_event *) * sc->sc_maxpin,
+ M_DEVBUF, M_WAITOK | M_ZERO);
+
/* We need to go through each block and ensure the clocks are running and
* the module is enabled. It might be better to do this only when the
* pins are configured which would result in less power used if the GPIO
@@ -825,6 +854,10 @@ ti_gpio_detach(device_t dev)
bus_generic_detach(dev);
+ free(sc->sc_events, M_DEVBUF);
+ free(sc->sc_irq_polarity, M_DEVBUF);
+ free(sc->sc_irq_trigger, M_DEVBUF);
+
/* Release the memory and IRQ resources. */
ti_gpio_detach_intr(dev);
bus_release_resources(dev, ti_gpio_irq_spec, sc->sc_irq_res);
@@ -835,6 +868,193 @@ ti_gpio_detach(device_t dev)
return (0);
}
+static uint32_t
+ti_gpio_intr_reg(struct ti_gpio_softc *sc, int irq)
+{
+
+ if (ti_gpio_valid_pin(sc, irq) != 0)
+ return (0);
+
+ if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_LEVEL) {
+ if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
+ return (TI_GPIO_LEVELDETECT0);
+ else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
+ return (TI_GPIO_LEVELDETECT1);
+ } else if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_EDGE) {
+ if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
+ return (TI_GPIO_FALLINGDETECT);
+ else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
+ return (TI_GPIO_RISINGDETECT);
+ }
+
+ return (0);
+}
+
+static void
+ti_gpio_mask_irq(void *source)
+{
+ int irq;
+ uint32_t reg, val;
+
+ irq = (int)source;
+ if (ti_gpio_valid_pin(ti_gpio_sc, irq) != 0)
+ return;
+
+ TI_GPIO_LOCK(ti_gpio_sc);
+ ti_gpio_intr_clr(ti_gpio_sc, TI_GPIO_BANK(irq), TI_GPIO_MASK(irq));
+ reg = ti_gpio_intr_reg(ti_gpio_sc, irq);
+ if (reg != 0) {
+ val = ti_gpio_read_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg);
+ val &= ~TI_GPIO_MASK(irq);
+ ti_gpio_write_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg, val);
+ }
+ TI_GPIO_UNLOCK(ti_gpio_sc);
+}
+
+static void
+ti_gpio_unmask_irq(void *source)
+{
+ int irq;
+ uint32_t reg, val;
+
+ irq = (int)source;
+ if (ti_gpio_valid_pin(ti_gpio_sc, irq) != 0)
+ return;
+
+ TI_GPIO_LOCK(ti_gpio_sc);
+ reg = ti_gpio_intr_reg(ti_gpio_sc, irq);
+ if (reg != 0) {
+ val = ti_gpio_read_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg);
+ val |= TI_GPIO_MASK(irq);
+ ti_gpio_write_4(ti_gpio_sc, TI_GPIO_BANK(irq), reg, val);
+ ti_gpio_intr_set(ti_gpio_sc, TI_GPIO_BANK(irq),
+ TI_GPIO_MASK(irq));
+ }
+ TI_GPIO_UNLOCK(ti_gpio_sc);
+}
+
+static int
+ti_gpio_activate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *res)
+{
+ int pin;
+
+ if (type != SYS_RES_IRQ)
+ return (ENXIO);
+
+ /* Unmask the interrupt. */
+ pin = rman_get_start(res);
+ ti_gpio_unmask_irq((void *)(uintptr_t)pin);
+
+ return (0);
+}
+
+static int
+ti_gpio_deactivate_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *res)
+{
+ int pin;
+
+ if (type != SYS_RES_IRQ)
+ return (ENXIO);
+
+ /* Mask the interrupt. */
+ pin = rman_get_start(res);
+ ti_gpio_mask_irq((void *)(uintptr_t)pin);
+
+ return (0);
+}
+
+static int
+ti_gpio_config_intr(device_t dev, int irq, enum intr_trigger trig,
+ enum intr_polarity pol)
+{
+ struct ti_gpio_softc *sc;
+ uint32_t oldreg, reg, val;
+
+ sc = device_get_softc(dev);
+ if (ti_gpio_valid_pin(sc, irq) != 0)
+ return (EINVAL);
+
+ /* There is no standard trigger or polarity. */
+ if (trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM)
+ return (EINVAL);
+
+ TI_GPIO_LOCK(sc);
+ /*
+ * TRM recommends add the new event before remove the old one to
+ * avoid losing interrupts.
+ */
+ oldreg = ti_gpio_intr_reg(sc, irq);
+ sc->sc_irq_trigger[irq] = trig;
+ sc->sc_irq_polarity[irq] = pol;
+ reg = ti_gpio_intr_reg(sc, irq);
+ if (reg != 0) {
+ /* Apply the new settings. */
+ val = ti_gpio_read_4(sc, TI_GPIO_BANK(irq), reg);
+ val |= TI_GPIO_MASK(irq);
+ ti_gpio_write_4(sc, TI_GPIO_BANK(irq), reg, val);
+ }
+ if (oldreg != 0) {
+ /* Remove the old settings. */
+ val = ti_gpio_read_4(sc, TI_GPIO_BANK(irq), oldreg);
+ val &= ~TI_GPIO_MASK(irq);
+ ti_gpio_write_4(sc, TI_GPIO_BANK(irq), oldreg, val);
+ }
+ TI_GPIO_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
+ti_gpio_setup_intr(device_t dev, device_t child, struct resource *ires,
+ int flags, driver_filter_t *filt, driver_intr_t *handler,
+ void *arg, void **cookiep)
+{
+ struct ti_gpio_softc *sc;
+ struct intr_event *event;
+ int pin, error;
+
+ sc = device_get_softc(dev);
+ pin = rman_get_start(ires);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
+ panic("%s: bad pin %d", __func__, pin);
+
+ event = sc->sc_events[pin];
+ if (event == NULL) {
+ error = intr_event_create(&event, (void *)(uintptr_t)pin, 0,
+ pin, ti_gpio_mask_irq, ti_gpio_unmask_irq, NULL, NULL,
+ "gpio%d pin%d:", device_get_unit(dev), pin);
+ if (error != 0)
+ return (error);
+ sc->sc_events[pin] = event;
+ }
+ intr_event_add_handler(event, device_get_nameunit(child), filt,
+ handler, arg, intr_priority(flags), flags, cookiep);
+
+ return (0);
+}
+
+static int
+ti_gpio_teardown_intr(device_t dev, device_t child, struct resource *ires,
+ void *cookie)
+{
+ struct ti_gpio_softc *sc;
+ int pin, err;
+
+ sc = device_get_softc(dev);
+ pin = rman_get_start(ires);
+ if (ti_gpio_valid_pin(sc, pin) != 0)
+ panic("%s: bad pin %d", __func__, pin);
+ if (sc->sc_events[pin] == NULL)
+ panic("Trying to teardown unoccupied IRQ");
+ err = intr_event_remove_handler(cookie);
+ if (!err)
+ sc->sc_events[pin] = NULL;
+
+ return (err);
+}
+
static phandle_t
ti_gpio_get_node(device_t bus, device_t dev)
{
@@ -857,6 +1077,13 @@ static device_method_t ti_gpio_methods[] = {
DEVMETHOD(gpio_pin_set, ti_gpio_pin_set),
DEVMETHOD(gpio_pin_toggle, ti_gpio_pin_toggle),
+ /* Bus interface */
+ DEVMETHOD(bus_activate_resource, ti_gpio_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, ti_gpio_deactivate_resource),
+ DEVMETHOD(bus_config_intr, ti_gpio_config_intr),
+ DEVMETHOD(bus_setup_intr, ti_gpio_setup_intr),
+ DEVMETHOD(bus_teardown_intr, ti_gpio_teardown_intr),
+
/* ofw_bus interface */
DEVMETHOD(ofw_bus_get_node, ti_gpio_get_node),
diff --git a/sys/arm/ti/ti_gpio.h b/sys/arm/ti/ti_gpio.h
index 0e1199f..763fc8a 100644
--- a/sys/arm/ti/ti_gpio.h
+++ b/sys/arm/ti/ti_gpio.h
@@ -47,6 +47,13 @@
struct ti_gpio_softc {
device_t sc_dev;
+ /* Interrupt trigger type and level. */
+ enum intr_trigger *sc_irq_trigger;
+ enum intr_polarity *sc_irq_polarity;
+
+ int sc_maxpin;
+ struct mtx sc_mtx;
+
/*
* The memory resource(s) for the PRCM register set, when the device is
* created the caller can assign up to 6 memory regions depending on
@@ -55,15 +62,11 @@ struct ti_gpio_softc {
struct resource *sc_mem_res[MAX_GPIO_BANKS];
struct resource *sc_irq_res[MAX_GPIO_INTRS];
+ /* Interrupt events. */
+ struct intr_event **sc_events;
+
/* The handle for the register IRQ handlers. */
void *sc_irq_hdl[MAX_GPIO_INTRS];
-
- /*
- * The following describes the H/W revision of each of the GPIO banks.
- */
- uint32_t sc_revision[MAX_GPIO_BANKS];
-
- struct mtx sc_mtx;
};
#endif /* TI_GPIO_H */
diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c
index 8f9af0c..d304827 100644
--- a/sys/arm/ti/ti_i2c.c
+++ b/sys/arm/ti/ti_i2c.c
@@ -119,7 +119,7 @@ struct ti_i2c_clock_config
static struct ti_i2c_clock_config ti_omap4_i2c_clock_configs[] = {
{ 100000, 23, 13, 15, 0, 0},
{ 400000, 9, 5, 7, 0, 0},
- { 1000000, 5, 1, 3, 0, 0},
+ { 1000000, 3, 5, 7, 0, 0},
/* { 3200000, 1, 113, 115, 7, 10}, - HS mode */
{ 0 /* Table terminator */ }
};
diff --git a/sys/arm/ti/ti_sdhci.c b/sys/arm/ti/ti_sdhci.c
index 024c830..380a40e 100644
--- a/sys/arm/ti/ti_sdhci.c
+++ b/sys/arm/ti/ti_sdhci.c
@@ -112,6 +112,7 @@ static struct ofw_compat_data compat_data[] = {
#define MMCHS_CON 0x02C
#define MMCHS_CON_DW8 (1 << 5)
#define MMCHS_CON_DVAL_8_4MS (3 << 9)
+#define MMCHS_CON_OD (1 << 0)
#define MMCHS_SYSCTL 0x12C
#define MMCHS_SYSCTL_CLKD_MASK 0x3FF
#define MMCHS_SYSCTL_CLKD_SHIFT 6
@@ -327,7 +328,7 @@ ti_sdhci_update_ios(device_t brdev, device_t reqdev)
struct ti_sdhci_softc *sc = device_get_softc(brdev);
struct sdhci_slot *slot;
struct mmc_ios *ios;
- uint32_t val32;
+ uint32_t val32, newval32;
slot = device_get_ivars(reqdev);
ios = &slot->host.ios;
@@ -339,10 +340,20 @@ ti_sdhci_update_ios(device_t brdev, device_t reqdev)
* requested, then let the standard driver handle everything else.
*/
val32 = ti_mmchs_read_4(sc, MMCHS_CON);
+ newval32 = val32;
+
if (ios->bus_width == bus_width_8)
- ti_mmchs_write_4(sc, MMCHS_CON, val32 | MMCHS_CON_DW8);
+ newval32 |= MMCHS_CON_DW8;
else
- ti_mmchs_write_4(sc, MMCHS_CON, val32 & ~MMCHS_CON_DW8);
+ newval32 &= ~MMCHS_CON_DW8;
+
+ if (ios->bus_mode == opendrain)
+ newval32 |= MMCHS_CON_OD;
+ else /* if (ios->bus_mode == pushpull) */
+ newval32 &= ~MMCHS_CON_OD;
+
+ if (newval32 != val32)
+ ti_mmchs_write_4(sc, MMCHS_CON, newval32);
return (sdhci_generic_update_ios(brdev, reqdev));
}
@@ -392,20 +403,42 @@ ti_sdhci_hw_init(device_t dev)
/* Issue a softreset to the controller */
ti_mmchs_write_4(sc, MMCHS_SYSCONFIG, MMCHS_SYSCONFIG_RESET);
timeout = 1000;
- while (!(ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) & MMCHS_SYSSTATUS_RESETDONE)) {
+ while (!(ti_mmchs_read_4(sc, MMCHS_SYSSTATUS) &
+ MMCHS_SYSSTATUS_RESETDONE)) {
if (--timeout == 0) {
- device_printf(dev, "Error: Controller reset operation timed out\n");
+ device_printf(dev,
+ "Error: Controller reset operation timed out\n");
break;
}
DELAY(100);
}
- /* Reset both the command and data state machines */
+ /*
+ * Reset the command and data state machines and also other aspects of
+ * the controller such as bus clock and power.
+ *
+ * If we read the software reset register too fast after writing it we
+ * can get back a zero that means the reset hasn't started yet rather
+ * than that the reset is complete. Per TI recommendations, work around
+ * it by reading until we see the reset bit asserted, then read until
+ * it's clear. We also set the SDHCI_QUIRK_WAITFOR_RESET_ASSERTED quirk
+ * so that the main sdhci driver uses this same logic in its resets.
+ */
ti_sdhci_write_1(dev, NULL, SDHCI_SOFTWARE_RESET, SDHCI_RESET_ALL);
- timeout = 1000;
- while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL)) {
+ timeout = 10000;
+ while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) &
+ SDHCI_RESET_ALL) != SDHCI_RESET_ALL) {
if (--timeout == 0) {
- device_printf(dev, "Error: Software reset operation timed out\n");
+ break;
+ }
+ DELAY(1);
+ }
+ timeout = 10000;
+ while ((ti_sdhci_read_1(dev, NULL, SDHCI_SOFTWARE_RESET) &
+ SDHCI_RESET_ALL)) {
+ if (--timeout == 0) {
+ device_printf(dev,
+ "Error: Software reset operation timed out\n");
break;
}
DELAY(100);
@@ -568,6 +601,12 @@ ti_sdhci_attach(device_t dev)
sc->slot.quirks |= SDHCI_QUIRK_DONT_SHIFT_RESPONSE;
/*
+ * Reset bits are broken, have to wait to see the bits asserted
+ * before waiting to see them de-asserted.
+ */
+ sc->slot.quirks |= SDHCI_QUIRK_WAITFOR_RESET_ASSERTED;
+
+ /*
* DMA is not really broken, I just haven't implemented it yet.
*/
sc->slot.quirks |= SDHCI_QUIRK_BROKEN_DMA;
diff --git a/sys/arm/ti/ti_wdt.c b/sys/arm/ti/ti_wdt.c
index 7f50a61..7e8e5ae 100644
--- a/sys/arm/ti/ti_wdt.c
+++ b/sys/arm/ti/ti_wdt.c
@@ -95,7 +95,7 @@ static devclass_t ti_wdt_devclass;
DRIVER_MODULE(ti_wdt, simplebus, ti_wdt_driver, ti_wdt_devclass, 0, 0);
-static volatile __inline uint32_t
+static __inline uint32_t
ti_wdt_reg_read(struct ti_wdt_softc *sc, uint32_t reg)
{
diff --git a/sys/arm/xilinx/std.zynq7 b/sys/arm/xilinx/std.zynq7
index 1cee32d..34e6739 100644
--- a/sys/arm/xilinx/std.zynq7
+++ b/sys/arm/xilinx/std.zynq7
@@ -5,6 +5,7 @@
cpu CPU_CORTEXA
machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a -Wa,-march=armv7a"
files "../xilinx/files.zynq7"
diff --git a/sys/boot/amd64/boot1.efi/Makefile b/sys/boot/amd64/boot1.efi/Makefile
index 3e3bc9f..dd8eaf9 100644
--- a/sys/boot/amd64/boot1.efi/Makefile
+++ b/sys/boot/amd64/boot1.efi/Makefile
@@ -51,7 +51,7 @@ boot1.efi: loader.sym
${OBJCOPY} -j .text -j .sdata -j .data \
-j .dynamic -j .dynsym -j .rel.dyn \
-j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
- --target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
+ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
CFLAGS+= -I${.CURDIR}/../../common
diff --git a/sys/boot/amd64/boot1.efi/generate-fat.sh b/sys/boot/amd64/boot1.efi/generate-fat.sh
index eafd3e0..e8f9cde 100755
--- a/sys/boot/amd64/boot1.efi/generate-fat.sh
+++ b/sys/boot/amd64/boot1.efi/generate-fat.sh
@@ -34,10 +34,10 @@ umount stub
mdconfig -d -u $DEVICE
rmdir stub
-# Locate the offsets of the two fake files
+# Locate the offset of the fake file
BOOT1_OFFSET=$(hd $OUTPUT_FILE | grep 'Boot1 START' | cut -f 1 -d ' ')
-# Convert to numbers of blocks
+# Convert to number of blocks
BOOT1_OFFSET=$(echo 0x$BOOT1_OFFSET | awk '{printf("%x\n",$1/512);}')
echo '# This file autogenerated by generate-fat.sh - DO NOT EDIT' > Makefile.fat
diff --git a/sys/boot/amd64/efi/Makefile b/sys/boot/amd64/efi/Makefile
index a9a2132..66b8cf8 100644
--- a/sys/boot/amd64/efi/Makefile
+++ b/sys/boot/amd64/efi/Makefile
@@ -81,7 +81,7 @@ loader.efi: loader.sym
${OBJCOPY} -j .text -j .sdata -j .data \
-j .dynamic -j .dynsym -j .rel.dyn \
-j .rela.dyn -j .reloc -j .eh_frame -j set_Xcommand_set \
- --target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
+ --output-target=${EFI_TARGET} ${.ALLSRC} ${.TARGET}
LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a
CFLAGS+= -I${.CURDIR}/../../common
diff --git a/sys/boot/arm/uboot/Makefile b/sys/boot/arm/uboot/Makefile
index 743f189..c69d8aa 100644
--- a/sys/boot/arm/uboot/Makefile
+++ b/sys/boot/arm/uboot/Makefile
@@ -76,7 +76,7 @@ LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a
LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
.endif
-.if !defined(NO_FORTH)
+.if ${MK_FORTH} != "no"
# Enable BootForth
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/arm
diff --git a/sys/boot/common/console.c b/sys/boot/common/console.c
index 6c1fdab..6656eab 100644
--- a/sys/boot/common/console.c
+++ b/sys/boot/common/console.c
@@ -39,6 +39,7 @@ static int cons_set(struct env_var *ev, int flags, const void *value);
static int cons_find(const char *name);
static int cons_check(const char *string);
static void cons_change(const char *string);
+static int twiddle_set(struct env_var *ev, int flags, const void *value);
/*
* Detect possible console(s) to use. If preferred console(s) have been
@@ -52,6 +53,9 @@ cons_probe(void)
int active;
char *prefconsole;
+ /* We want a callback to install the new value when this var changes. */
+ env_setenv("twiddle_divisor", EV_VOLATILE, "1", twiddle_set, env_nounset);
+
/* Do all console probes */
for (cons = 0; consoles[cons] != NULL; cons++) {
consoles[cons]->c_flags = 0;
@@ -232,3 +236,28 @@ cons_change(const char *string)
free(dup);
}
+
+/*
+ * Change the twiddle divisor.
+ *
+ * The user can set the twiddle_divisor variable to directly control how fast
+ * the progress twiddle spins, useful for folks with slow serial consoles. The
+ * code to monitor changes to the variable and propagate them to the twiddle
+ * routines has to live somewhere. Twiddling is console-related so it's here.
+ */
+static int
+twiddle_set(struct env_var *ev, int flags, const void *value)
+{
+ u_long tdiv;
+ char * eptr;
+
+ tdiv = strtoul(value, &eptr, 0);
+ if (*(const char *)value == 0 || *eptr != 0) {
+ printf("invalid twiddle_divisor '%s'\n", (const char *)value);
+ return (CMD_ERROR);
+ }
+ twiddle_divisor((u_int)tdiv);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+
+ return(CMD_OK);
+}
diff --git a/sys/boot/common/loader.8 b/sys/boot/common/loader.8
index fe247ac..cac5674 100644
--- a/sys/boot/common/loader.8
+++ b/sys/boot/common/loader.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 1, 2013
+.Dd December 22, 2014
.Dt LOADER 8
.Os
.Sh NAME
@@ -670,6 +670,12 @@ Overrides the compile-time set value of
.Dv TCBHASHSIZE
or the preset default of 512.
Must be a power of 2.
+.It Va twiddle_divisor
+Throttles the output of the `twiddle' I/O progress indicator displayed
+while loading the kernel and modules.
+This is useful on slow serial consoles where the time spent waiting for
+these characters to be written can add up to many seconds.
+The default is 1 (full speed); a value of 2 spins half as fast, and so on.
.It Va vm.kmem_size
Sets the size of kernel memory (bytes).
This overrides the value determined when the kernel was compiled.
diff --git a/sys/boot/fdt/dts/arm/am335x.dtsi b/sys/boot/fdt/dts/arm/am335x.dtsi
index 9378f34..feb32f2 100644
--- a/sys/boot/fdt/dts/arm/am335x.dtsi
+++ b/sys/boot/fdt/dts/arm/am335x.dtsi
@@ -99,6 +99,8 @@
0x481AE000 0x1000 >;
interrupts = < 96 97 98 99 32 33 62 63 >;
interrupt-parent = <&AINTC>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
};
uart0: serial@44E09000 {
diff --git a/sys/boot/fdt/dts/arm/rpi.dts b/sys/boot/fdt/dts/arm/rpi.dts
index 58ceaa4..08d9d24 100644
--- a/sys/boot/fdt/dts/arm/rpi.dts
+++ b/sys/boot/fdt/dts/arm/rpi.dts
@@ -35,6 +35,17 @@
memreserve = <0x08000000 0x08000000>; /* Set by VideoCore */
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ compatible = "arm,1176jzf-s";
+ device_type = "cpu";
+ reg = <0>; /* CPU ID=0 */
+ clock-frequency = <700000000>; /* 700MHz */
+ };
+ };
+
memory {
device_type = "memory";
reg = <0 0x8000000>; /* 128MB, Set by VideoCore */
diff --git a/sys/boot/forth/brand.4th.8 b/sys/boot/forth/brand.4th.8
index 64e6854..dfd188d 100644
--- a/sys/boot/forth/brand.4th.8
+++ b/sys/boot/forth/brand.4th.8
@@ -111,7 +111,7 @@ loader_brand="fbsd"
.Ed
.Sh SEE ALSO
.Xr loader.conf 5 ,
-.Xr loader 8 ,
+.Xr loader 8
.Sh HISTORY
The
.Nm
diff --git a/sys/boot/forth/delay.4th.8 b/sys/boot/forth/delay.4th.8
index dd1680e..af31fd0 100644
--- a/sys/boot/forth/delay.4th.8
+++ b/sys/boot/forth/delay.4th.8
@@ -110,8 +110,8 @@ delay_execute
.Ed
.Sh SEE ALSO
.Xr loader.conf 5 ,
-.Xr loader 8 ,
.Xr beastie.4th 8 ,
+.Xr loader 8 ,
.Xr loader.4th 8
.Sh HISTORY
The
diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf
index bd7d296..fd0b0de 100644
--- a/sys/boot/forth/loader.conf
+++ b/sys/boot/forth/loader.conf
@@ -75,6 +75,7 @@ module_path="/boot/modules" # Set the module search path
# the block size is set to 512. If the value
# is out of range ( < 8 || > 9008 ) an error is
# returned.
+#twiddle_divisor="1" # >1 means slow down the progress indicator.
##############################################################
diff --git a/sys/boot/forth/menu.4th.8 b/sys/boot/forth/menu.4th.8
index ab67d73..3673eec 100644
--- a/sys/boot/forth/menu.4th.8
+++ b/sys/boot/forth/menu.4th.8
@@ -336,9 +336,9 @@ menu-display
.Ed
.Sh SEE ALSO
.Xr loader.conf 5 ,
+.Xr beastie.4th 8 ,
.Xr loader 8 ,
-.Xr loader.4th 8 ,
-.Xr beastie.4th 8
+.Xr loader.4th 8
.Sh HISTORY
The
.Nm
diff --git a/sys/boot/forth/menusets.4th.8 b/sys/boot/forth/menusets.4th.8
index e05e4a7..f785ae1 100644
--- a/sys/boot/forth/menusets.4th.8
+++ b/sys/boot/forth/menusets.4th.8
@@ -355,10 +355,10 @@ set submenu_command[1]="1 goto_menu"
.Ed
.Sh SEE ALSO
.Xr loader.conf 5 ,
+.Xr beastie.4th 8 ,
.Xr loader 8 ,
.Xr loader.4th 8 ,
-.Xr menu.4th 8 ,
-.Xr beastie.4th 8
+.Xr menu.4th 8
.Sh HISTORY
The
.Nm
diff --git a/sys/boot/forth/version.4th.8 b/sys/boot/forth/version.4th.8
index fe8b618..256df1e 100644
--- a/sys/boot/forth/version.4th.8
+++ b/sys/boot/forth/version.4th.8
@@ -113,8 +113,8 @@ loader_version="loader 1.1"
.Ed
.Sh SEE ALSO
.Xr loader.conf 5 ,
-.Xr loader 8 ,
-.Xr color.4th 8
+.Xr color.4th 8 ,
+.Xr loader 8
.Sh HISTORY
The
.Nm
diff --git a/sys/boot/i386/libi386/spinconsole.c b/sys/boot/i386/libi386/spinconsole.c
index 752c29f..161d810 100644
--- a/sys/boot/i386/libi386/spinconsole.c
+++ b/sys/boot/i386/libi386/spinconsole.c
@@ -86,9 +86,11 @@ spinc_putchar(int c)
if (now < (lasttime + 1))
return;
lasttime = now;
+#ifdef TERM_EMU
get_pos(&curx, &cury);
if (curx > 0)
curs_move(&curx, &cury, curx - 1, cury);
+#endif
vidc_biosputchar((char)tw_chars);
tw_chars = (tw_chars >> 8) | ((tw_chars & (unsigned long)0xFF) << 24);
}
diff --git a/sys/boot/powerpc/uboot/Makefile b/sys/boot/powerpc/uboot/Makefile
index a5a06a9..681249a 100644
--- a/sys/boot/powerpc/uboot/Makefile
+++ b/sys/boot/powerpc/uboot/Makefile
@@ -66,7 +66,7 @@ LIBUBOOT_FDT= ${.OBJDIR}/../../uboot/fdt/libuboot_fdt.a
LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
.endif
-.if !defined(NO_FORTH)
+.if ${MK_FORTH} != "no"
# Enable BootForth
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/powerpc
diff --git a/sys/boot/uboot/common/main.c b/sys/boot/uboot/common/main.c
index ae77766..f58d0c4 100644
--- a/sys/boot/uboot/common/main.c
+++ b/sys/boot/uboot/common/main.c
@@ -212,10 +212,11 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
p = get_device_type(devstr, type);
- /*
- * Empty device string, or unknown device name, or a bare, known
- * device name.
- */
+ /* Ignore optional spaces after the device name. */
+ while (*p == ' ')
+ p++;
+
+ /* Unknown device name, or a known name without unit number. */
if ((*type == -1) || (*p == '\0')) {
return;
}
diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 8fccd02..e90a029 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -111,7 +111,7 @@ struct ctl_softc *control_softc = NULL;
* Note that these are default values only. The actual values will be
* filled in when the user does a mode sense.
*/
-static struct copan_debugconf_subpage debugconf_page_default = {
+const static struct copan_debugconf_subpage debugconf_page_default = {
DBGCNF_PAGE_CODE | SMPH_SPF, /* page_code */
DBGCNF_SUBPAGE_CODE, /* subpage */
{(sizeof(struct copan_debugconf_subpage) - 4) >> 8,
@@ -121,7 +121,7 @@ static struct copan_debugconf_subpage debugconf_page_default = {
CTL_TIME_IO_DEFAULT_SECS>>0}, /* ctl_time_io_secs */
};
-static struct copan_debugconf_subpage debugconf_page_changeable = {
+const static struct copan_debugconf_subpage debugconf_page_changeable = {
DBGCNF_PAGE_CODE | SMPH_SPF, /* page_code */
DBGCNF_SUBPAGE_CODE, /* subpage */
{(sizeof(struct copan_debugconf_subpage) - 4) >> 8,
@@ -130,7 +130,7 @@ static struct copan_debugconf_subpage debugconf_page_changeable = {
{0xff,0xff}, /* ctl_time_io_secs */
};
-static struct scsi_da_rw_recovery_page rw_er_page_default = {
+const static struct scsi_da_rw_recovery_page rw_er_page_default = {
/*page_code*/SMS_RW_ERROR_RECOVERY_PAGE,
/*page_length*/sizeof(struct scsi_da_rw_recovery_page) - 2,
/*byte3*/SMS_RWER_AWRE|SMS_RWER_ARRE,
@@ -144,7 +144,7 @@ static struct scsi_da_rw_recovery_page rw_er_page_default = {
/*recovery_time_limit*/{0, 0},
};
-static struct scsi_da_rw_recovery_page rw_er_page_changeable = {
+const static struct scsi_da_rw_recovery_page rw_er_page_changeable = {
/*page_code*/SMS_RW_ERROR_RECOVERY_PAGE,
/*page_length*/sizeof(struct scsi_da_rw_recovery_page) - 2,
/*byte3*/0,
@@ -158,7 +158,7 @@ static struct scsi_da_rw_recovery_page rw_er_page_changeable = {
/*recovery_time_limit*/{0, 0},
};
-static struct scsi_format_page format_page_default = {
+const static struct scsi_format_page format_page_default = {
/*page_code*/SMS_FORMAT_DEVICE_PAGE,
/*page_length*/sizeof(struct scsi_format_page) - 2,
/*tracks_per_zone*/ {0, 0},
@@ -175,7 +175,7 @@ static struct scsi_format_page format_page_default = {
/*reserved*/ {0, 0, 0}
};
-static struct scsi_format_page format_page_changeable = {
+const static struct scsi_format_page format_page_changeable = {
/*page_code*/SMS_FORMAT_DEVICE_PAGE,
/*page_length*/sizeof(struct scsi_format_page) - 2,
/*tracks_per_zone*/ {0, 0},
@@ -191,7 +191,7 @@ static struct scsi_format_page format_page_changeable = {
/*reserved*/ {0, 0, 0}
};
-static struct scsi_rigid_disk_page rigid_disk_page_default = {
+const static struct scsi_rigid_disk_page rigid_disk_page_default = {
/*page_code*/SMS_RIGID_DISK_PAGE,
/*page_length*/sizeof(struct scsi_rigid_disk_page) - 2,
/*cylinders*/ {0, 0, 0},
@@ -208,7 +208,7 @@ static struct scsi_rigid_disk_page rigid_disk_page_default = {
/*reserved2*/ {0, 0}
};
-static struct scsi_rigid_disk_page rigid_disk_page_changeable = {
+const static struct scsi_rigid_disk_page rigid_disk_page_changeable = {
/*page_code*/SMS_RIGID_DISK_PAGE,
/*page_length*/sizeof(struct scsi_rigid_disk_page) - 2,
/*cylinders*/ {0, 0, 0},
@@ -224,7 +224,7 @@ static struct scsi_rigid_disk_page rigid_disk_page_changeable = {
/*reserved2*/ {0, 0}
};
-static struct scsi_caching_page caching_page_default = {
+const static struct scsi_caching_page caching_page_default = {
/*page_code*/SMS_CACHING_PAGE,
/*page_length*/sizeof(struct scsi_caching_page) - 2,
/*flags1*/ SCP_DISC | SCP_WCE,
@@ -240,7 +240,7 @@ static struct scsi_caching_page caching_page_default = {
/*non_cache_seg_size*/ {0, 0, 0}
};
-static struct scsi_caching_page caching_page_changeable = {
+const static struct scsi_caching_page caching_page_changeable = {
/*page_code*/SMS_CACHING_PAGE,
/*page_length*/sizeof(struct scsi_caching_page) - 2,
/*flags1*/ SCP_WCE | SCP_RCD,
@@ -256,7 +256,7 @@ static struct scsi_caching_page caching_page_changeable = {
/*non_cache_seg_size*/ {0, 0, 0}
};
-static struct scsi_control_page control_page_default = {
+const static struct scsi_control_page control_page_default = {
/*page_code*/SMS_CONTROL_MODE_PAGE,
/*page_length*/sizeof(struct scsi_control_page) - 2,
/*rlec*/0,
@@ -268,7 +268,7 @@ static struct scsi_control_page control_page_default = {
/*extended_selftest_completion_time*/{0, 0}
};
-static struct scsi_control_page control_page_changeable = {
+const static struct scsi_control_page control_page_changeable = {
/*page_code*/SMS_CONTROL_MODE_PAGE,
/*page_length*/sizeof(struct scsi_control_page) - 2,
/*rlec*/SCP_DSENSE,
@@ -280,7 +280,7 @@ static struct scsi_control_page control_page_changeable = {
/*extended_selftest_completion_time*/{0, 0}
};
-static struct scsi_info_exceptions_page ie_page_default = {
+const static struct scsi_info_exceptions_page ie_page_default = {
/*page_code*/SMS_INFO_EXCEPTIONS_PAGE,
/*page_length*/sizeof(struct scsi_info_exceptions_page) - 2,
/*info_flags*/SIEP_FLAGS_DEXCPT,
@@ -289,7 +289,7 @@ static struct scsi_info_exceptions_page ie_page_default = {
/*report_count*/{0, 0, 0, 0}
};
-static struct scsi_info_exceptions_page ie_page_changeable = {
+const static struct scsi_info_exceptions_page ie_page_changeable = {
/*page_code*/SMS_INFO_EXCEPTIONS_PAGE,
/*page_length*/sizeof(struct scsi_info_exceptions_page) - 2,
/*info_flags*/0,
@@ -300,7 +300,7 @@ static struct scsi_info_exceptions_page ie_page_changeable = {
#define CTL_LBPM_LEN (sizeof(struct ctl_logical_block_provisioning_page) - 4)
-static struct ctl_logical_block_provisioning_page lbp_page_default = {{
+const static struct ctl_logical_block_provisioning_page lbp_page_default = {{
/*page_code*/SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF,
/*subpage_code*/0x02,
/*page_length*/{CTL_LBPM_LEN >> 8, CTL_LBPM_LEN},
@@ -326,7 +326,7 @@ static struct ctl_logical_block_provisioning_page lbp_page_default = {{
}
};
-static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{
+const static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{
/*page_code*/SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF,
/*subpage_code*/0x02,
/*page_length*/{CTL_LBPM_LEN >> 8, CTL_LBPM_LEN},
@@ -398,8 +398,8 @@ static int ctl_ioctl_fill_ooa(struct ctl_lun *lun, uint32_t *cur_fill_num,
struct ctl_ooa_entry *kern_entries);
static int ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
struct thread *td);
-static uint32_t ctl_map_lun(int port_num, uint32_t lun);
-static uint32_t ctl_map_lun_back(int port_num, uint32_t lun);
+static uint32_t ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun);
+static uint32_t ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun);
static int ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
struct ctl_be_lun *be_lun, struct ctl_id target_id);
static int ctl_free_lun(struct ctl_lun *lun);
@@ -441,8 +441,7 @@ static ctl_action ctl_check_for_blockage(struct ctl_lun *lun,
static ctl_action ctl_check_ooa(struct ctl_lun *lun, union ctl_io *pending_io,
union ctl_io *starting_io);
static int ctl_check_blocked(struct ctl_lun *lun);
-static int ctl_scsiio_lun_check(struct ctl_softc *ctl_softc,
- struct ctl_lun *lun,
+static int ctl_scsiio_lun_check(struct ctl_lun *lun,
const struct ctl_cmd_entry *entry,
struct ctl_scsiio *ctsio);
//static int ctl_check_rtr(union ctl_io *pending_io, struct ctl_softc *softc);
@@ -609,12 +608,12 @@ ctl_isc_handler_finish_ser_only(struct ctl_softc *ctl_softc,
static void
ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
union ctl_io *io;
struct ctl_prio *presio;
ctl_ha_status isc_status;
- ctl_softc = control_softc;
+ softc = control_softc;
io = NULL;
@@ -640,7 +639,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
#if 0
printf("Serialize\n");
#endif
- io = ctl_alloc_io_nowait(ctl_softc->othersc_pool);
+ io = ctl_alloc_io_nowait(softc->othersc_pool);
if (io == NULL) {
printf("ctl_isc_event_handler: can't allocate "
"ctl_io!\n");
@@ -672,7 +671,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
*
* XXX KDM add another flag that is more specific.
*/
- if (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY)
+ if (softc->ha_mode == CTL_HA_MODE_SER_ONLY)
io->io_hdr.flags |= CTL_FLAG_INT_COPY;
io->io_hdr.nexus = msg_info.hdr.nexus;
#if 0
@@ -686,7 +685,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
io->scsiio.tag_type = msg_info.scsi.tag_type;
memcpy(io->scsiio.cdb, msg_info.scsi.cdb,
CTL_MAX_CDBLEN);
- if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) {
+ if (softc->ha_mode == CTL_HA_MODE_XFER) {
const struct ctl_cmd_entry *entry;
entry = ctl_get_cmd_entry(&io->scsiio, NULL);
@@ -852,11 +851,11 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
* mode
*/
case CTL_MSG_FINISH_IO:
- if (ctl_softc->ha_mode == CTL_HA_MODE_XFER)
- ctl_isc_handler_finish_xfer(ctl_softc,
+ if (softc->ha_mode == CTL_HA_MODE_XFER)
+ ctl_isc_handler_finish_xfer(softc,
&msg_info);
else
- ctl_isc_handler_finish_ser_only(ctl_softc,
+ ctl_isc_handler_finish_ser_only(softc,
&msg_info);
break;
@@ -886,7 +885,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
case CTL_MSG_MANAGE_TASKS: {
struct ctl_taskio *taskio;
taskio = (struct ctl_taskio *)ctl_alloc_io_nowait(
- ctl_softc->othersc_pool);
+ softc->othersc_pool);
if (taskio == NULL) {
printf("ctl_isc_event_handler: can't allocate "
"ctl_io!\n");
@@ -915,7 +914,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
/* Persistent Reserve action which needs attention */
case CTL_MSG_PERS_ACTION:
presio = (struct ctl_prio *)ctl_alloc_io_nowait(
- ctl_softc->othersc_pool);
+ softc->othersc_pool);
if (presio == NULL) {
printf("ctl_isc_event_handler: can't allocate "
"ctl_io!\n");
@@ -1744,8 +1743,8 @@ ctl_ioctl_do_datamove(struct ctl_scsiio *ctsio)
i < ext_sg_entries && j < kern_sg_entries;) {
uint8_t *ext_ptr, *kern_ptr;
- len_to_copy = ctl_min(ext_sglist[i].len - ext_watermark,
- kern_sglist[j].len - kern_watermark);
+ len_to_copy = MIN(ext_sglist[i].len - ext_watermark,
+ kern_sglist[j].len - kern_watermark);
ext_ptr = (uint8_t *)ext_sglist[i].addr;
ext_ptr = ext_ptr + ext_watermark;
@@ -1832,16 +1831,16 @@ bailout:
static int
ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
union ctl_ha_msg msg_info;
struct ctl_lun *lun;
int retval = 0;
uint32_t targ_lun;
- ctl_softc = control_softc;
+ softc = control_softc;
targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun;
- lun = ctl_softc->ctl_luns[targ_lun];
+ lun = softc->ctl_luns[targ_lun];
if (lun==NULL)
{
/*
@@ -1886,7 +1885,7 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
break;
case CTL_ACTION_PASS:
case CTL_ACTION_SKIP:
- if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) {
+ if (softc->ha_mode == CTL_HA_MODE_XFER) {
ctsio->io_hdr.flags |= CTL_FLAG_IS_WAS_ON_RTR;
ctl_enqueue_rtr((union ctl_io *)ctsio);
} else {
@@ -2835,8 +2834,8 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
bbr_info->scsi_status = metatask->taskinfo.bbrread.scsi_status;
memcpy(&bbr_info->sense_data,
&metatask->taskinfo.bbrread.sense_data,
- ctl_min(sizeof(bbr_info->sense_data),
- sizeof(metatask->taskinfo.bbrread.sense_data)));
+ MIN(sizeof(bbr_info->sense_data),
+ sizeof(metatask->taskinfo.bbrread.sense_data)));
cfi_free_metatask(metatask);
@@ -3498,11 +3497,11 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
if (port->wwpn_iid[j].name != NULL)
retval = sbuf_printf(sb,
- "\t<initiator>%u %s</initiator>\n",
+ "\t<initiator id=\"%u\">%s</initiator>\n",
j, port->wwpn_iid[j].name);
else
retval = sbuf_printf(sb,
- "\t<initiator>%u naa.%08jx</initiator>\n",
+ "\t<initiator id=\"%u\">naa.%08jx</initiator>\n",
j, port->wwpn_iid[j].wwpn);
if (retval != 0)
break;
@@ -3602,11 +3601,11 @@ ctl_port_idx(int port_num)
}
static uint32_t
-ctl_map_lun(int port_num, uint32_t lun_id)
+ctl_map_lun(struct ctl_softc *softc, int port_num, uint32_t lun_id)
{
struct ctl_port *port;
- port = control_softc->ctl_ports[ctl_port_idx(port_num)];
+ port = softc->ctl_ports[ctl_port_idx(port_num)];
if (port == NULL)
return (UINT32_MAX);
if (port->lun_map == NULL)
@@ -3615,12 +3614,12 @@ ctl_map_lun(int port_num, uint32_t lun_id)
}
static uint32_t
-ctl_map_lun_back(int port_num, uint32_t lun_id)
+ctl_map_lun_back(struct ctl_softc *softc, int port_num, uint32_t lun_id)
{
struct ctl_port *port;
uint32_t i;
- port = control_softc->ctl_ports[ctl_port_idx(port_num)];
+ port = softc->ctl_ports[ctl_port_idx(port_num)];
if (port->lun_map == NULL)
return (lun_id);
for (i = 0; i < CTL_MAX_LUNS; i++) {
@@ -3643,7 +3642,7 @@ ctl_ffz(uint32_t *mask, uint32_t size)
num_chunks = (size >> 5);
if (num_chunks == 0)
num_chunks++;
- num_pieces = ctl_min((sizeof(uint32_t) * 8), size);
+ num_pieces = MIN((sizeof(uint32_t) * 8), size);
for (i = 0; i < num_chunks; i++) {
for (j = 0; j < num_pieces; j++) {
@@ -3890,7 +3889,7 @@ ctl_copy_io(union ctl_io *src, union ctl_io *dest)
*/
pool_ref = dest->io_hdr.pool;
- memcpy(dest, src, ctl_min(sizeof(*src), sizeof(*dest)));
+ memcpy(dest, src, MIN(sizeof(*src), sizeof(*dest)));
dest->io_hdr.pool = pool_ref;
/*
@@ -4777,25 +4776,25 @@ ctl_free_lun(struct ctl_lun *lun)
static void
ctl_create_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
- ctl_softc = control_softc;
+ softc = control_softc;
/*
* ctl_alloc_lun() should handle all potential failure cases.
*/
- ctl_alloc_lun(ctl_softc, NULL, be_lun, ctl_softc->target);
+ ctl_alloc_lun(softc, NULL, be_lun, softc->target);
}
int
ctl_add_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc = control_softc;
+ struct ctl_softc *softc = control_softc;
- mtx_lock(&ctl_softc->ctl_lock);
- STAILQ_INSERT_TAIL(&ctl_softc->pending_lun_queue, be_lun, links);
- mtx_unlock(&ctl_softc->ctl_lock);
- wakeup(&ctl_softc->pending_lun_queue);
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_INSERT_TAIL(&softc->pending_lun_queue, be_lun, links);
+ mtx_unlock(&softc->ctl_lock);
+ wakeup(&softc->pending_lun_queue);
return (0);
}
@@ -4803,16 +4802,15 @@ ctl_add_lun(struct ctl_be_lun *be_lun)
int
ctl_enable_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_port *port, *nport;
struct ctl_lun *lun;
int retval;
- ctl_softc = control_softc;
-
lun = (struct ctl_lun *)be_lun->ctl_lun;
+ softc = lun->ctl_softc;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
mtx_lock(&lun->lun_lock);
if ((lun->flags & CTL_LUN_DISABLED) == 0) {
/*
@@ -4820,13 +4818,13 @@ ctl_enable_lun(struct ctl_be_lun *be_lun)
* enabled?
*/
mtx_unlock(&lun->lun_lock);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
lun->flags &= ~CTL_LUN_DISABLED;
mtx_unlock(&lun->lun_lock);
- for (port = STAILQ_FIRST(&ctl_softc->port_list); port != NULL; port = nport) {
+ for (port = STAILQ_FIRST(&softc->port_list); port != NULL; port = nport) {
nport = STAILQ_NEXT(port, links);
/*
@@ -4834,9 +4832,9 @@ ctl_enable_lun(struct ctl_be_lun *be_lun)
* This can lead to a callback into CTL (at least in the
* case of the internal initiator frontend.
*/
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
retval = port->lun_enable(port->targ_lun_arg, lun->target,lun->lun);
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
if (retval != 0) {
printf("%s: FETD %s port %d returned error "
"%d for lun_enable on target %ju lun %jd\n",
@@ -4851,7 +4849,7 @@ ctl_enable_lun(struct ctl_be_lun *be_lun)
#endif
}
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
@@ -4859,27 +4857,26 @@ ctl_enable_lun(struct ctl_be_lun *be_lun)
int
ctl_disable_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_port *port;
struct ctl_lun *lun;
int retval;
- ctl_softc = control_softc;
-
lun = (struct ctl_lun *)be_lun->ctl_lun;
+ softc = lun->ctl_softc;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
mtx_lock(&lun->lun_lock);
if (lun->flags & CTL_LUN_DISABLED) {
mtx_unlock(&lun->lun_lock);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
lun->flags |= CTL_LUN_DISABLED;
mtx_unlock(&lun->lun_lock);
- STAILQ_FOREACH(port, &ctl_softc->port_list, links) {
- mtx_unlock(&ctl_softc->ctl_lock);
+ STAILQ_FOREACH(port, &softc->port_list, links) {
+ mtx_unlock(&softc->ctl_lock);
/*
* Drop the lock before we call the frontend's disable
* routine, to avoid lock order reversals.
@@ -4889,7 +4886,7 @@ ctl_disable_lun(struct ctl_be_lun *be_lun)
*/
retval = port->lun_disable(port->targ_lun_arg, lun->target,
lun->lun);
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
if (retval != 0) {
printf("ctl_alloc_lun: FETD %s port %d returned error "
"%d for lun_disable on target %ju lun %jd\n",
@@ -4898,7 +4895,7 @@ ctl_disable_lun(struct ctl_be_lun *be_lun)
}
}
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
@@ -4906,80 +4903,55 @@ ctl_disable_lun(struct ctl_be_lun *be_lun)
int
ctl_start_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
- struct ctl_lun *lun;
-
- ctl_softc = control_softc;
-
- lun = (struct ctl_lun *)be_lun->ctl_lun;
+ struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
mtx_lock(&lun->lun_lock);
lun->flags &= ~CTL_LUN_STOPPED;
mtx_unlock(&lun->lun_lock);
-
return (0);
}
int
ctl_stop_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
- struct ctl_lun *lun;
-
- ctl_softc = control_softc;
-
- lun = (struct ctl_lun *)be_lun->ctl_lun;
+ struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
mtx_lock(&lun->lun_lock);
lun->flags |= CTL_LUN_STOPPED;
mtx_unlock(&lun->lun_lock);
-
return (0);
}
int
ctl_lun_offline(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
- struct ctl_lun *lun;
-
- ctl_softc = control_softc;
-
- lun = (struct ctl_lun *)be_lun->ctl_lun;
+ struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
mtx_lock(&lun->lun_lock);
lun->flags |= CTL_LUN_OFFLINE;
mtx_unlock(&lun->lun_lock);
-
return (0);
}
int
ctl_lun_online(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
- struct ctl_lun *lun;
-
- ctl_softc = control_softc;
-
- lun = (struct ctl_lun *)be_lun->ctl_lun;
+ struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
mtx_lock(&lun->lun_lock);
lun->flags &= ~CTL_LUN_OFFLINE;
mtx_unlock(&lun->lun_lock);
-
return (0);
}
int
ctl_invalidate_lun(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_lun *lun;
- ctl_softc = control_softc;
-
lun = (struct ctl_lun *)be_lun->ctl_lun;
+ softc = lun->ctl_softc;
mtx_lock(&lun->lun_lock);
@@ -5002,9 +4974,9 @@ ctl_invalidate_lun(struct ctl_be_lun *be_lun)
*/
if (TAILQ_EMPTY(&lun->ooa_queue)) {
mtx_unlock(&lun->lun_lock);
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
ctl_free_lun(lun);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
} else
mtx_unlock(&lun->lun_lock);
@@ -5014,32 +4986,22 @@ ctl_invalidate_lun(struct ctl_be_lun *be_lun)
int
ctl_lun_inoperable(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
- struct ctl_lun *lun;
-
- ctl_softc = control_softc;
- lun = (struct ctl_lun *)be_lun->ctl_lun;
+ struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
mtx_lock(&lun->lun_lock);
lun->flags |= CTL_LUN_INOPERABLE;
mtx_unlock(&lun->lun_lock);
-
return (0);
}
int
ctl_lun_operable(struct ctl_be_lun *be_lun)
{
- struct ctl_softc *ctl_softc;
- struct ctl_lun *lun;
-
- ctl_softc = control_softc;
- lun = (struct ctl_lun *)be_lun->ctl_lun;
+ struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
mtx_lock(&lun->lun_lock);
lun->flags &= ~CTL_LUN_INOPERABLE;
mtx_unlock(&lun->lun_lock);
-
return (0);
}
@@ -5225,7 +5187,6 @@ int
ctl_scsi_release(struct ctl_scsiio *ctsio)
{
int length, longid, thirdparty_id, resv_id;
- struct ctl_softc *ctl_softc;
struct ctl_lun *lun;
uint32_t residx;
@@ -5236,7 +5197,6 @@ ctl_scsi_release(struct ctl_scsiio *ctsio)
residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- ctl_softc = control_softc;
switch (ctsio->cdb[0]) {
case RELEASE_10: {
@@ -5313,7 +5273,6 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio)
int extent, thirdparty, longid;
int resv_id, length;
uint64_t thirdparty_id;
- struct ctl_softc *ctl_softc;
struct ctl_lun *lun;
uint32_t residx;
@@ -5328,7 +5287,6 @@ ctl_scsi_reserve(struct ctl_scsiio *ctsio)
residx = ctl_get_resindex(&ctsio->io_hdr.nexus);
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- ctl_softc = control_softc;
switch (ctsio->cdb[0]) {
case RESERVE_10: {
@@ -5402,13 +5360,11 @@ ctl_start_stop(struct ctl_scsiio *ctsio)
{
struct scsi_start_stop_unit *cdb;
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
int retval;
CTL_DEBUG_PRINT(("ctl_start_stop\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- ctl_softc = control_softc;
retval = 0;
cdb = (struct scsi_start_stop_unit *)ctsio->cdb;
@@ -5529,7 +5485,7 @@ int
ctl_sync_cache(struct ctl_scsiio *ctsio)
{
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
uint64_t starting_lba;
uint32_t block_count;
int retval;
@@ -5537,7 +5493,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_sync_cache\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- ctl_softc = control_softc;
+ softc = lun->ctl_softc;
retval = 0;
switch (ctsio->cdb[0]) {
@@ -5590,7 +5546,7 @@ ctl_sync_cache(struct ctl_scsiio *ctsio)
* CACHE command directly to the back end.
*/
mtx_lock(&lun->lun_lock);
- if ((ctl_softc->flags & CTL_FLAG_REAL_SYNC)
+ if ((softc->flags & CTL_FLAG_REAL_SYNC)
&& (++(lun->sync_count) >= lun->sync_interval)) {
lun->sync_count = 0;
mtx_unlock(&lun->lun_lock);
@@ -5611,13 +5567,11 @@ ctl_format(struct ctl_scsiio *ctsio)
{
struct scsi_format *cdb;
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
int length, defect_list_len;
CTL_DEBUG_PRINT(("ctl_format\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- ctl_softc = control_softc;
cdb = (struct scsi_format *)ctsio->cdb;
@@ -6075,7 +6029,6 @@ ctl_control_page_handler(struct ctl_scsiio *ctsio,
{
struct scsi_control_page *current_cp, *saved_cp, *user_cp;
struct ctl_lun *lun;
- struct ctl_softc *softc;
int set_ua;
uint32_t initidx;
@@ -6091,8 +6044,6 @@ ctl_control_page_handler(struct ctl_scsiio *ctsio,
(page_index->page_data + (page_index->page_len *
CTL_PAGE_SAVED));
- softc = control_softc;
-
mtx_lock(&lun->lun_lock);
if (((current_cp->rlec & SCP_DSENSE) == 0)
&& ((user_cp->rlec & SCP_DSENSE) != 0)) {
@@ -6801,7 +6752,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
header = (struct scsi_mode_hdr_6 *)ctsio->kern_data_ptr;
- header->datalen = ctl_min(total_len - 1, 254);
+ header->datalen = MIN(total_len - 1, 254);
if (control_dev == 0) {
header->dev_specific = 0x10; /* DPOFUA */
if ((lun->flags & CTL_LUN_READONLY) ||
@@ -6823,7 +6774,7 @@ ctl_mode_sense(struct ctl_scsiio *ctsio)
header = (struct scsi_mode_hdr_10 *)ctsio->kern_data_ptr;
- datalen = ctl_min(total_len - 2, 65533);
+ datalen = MIN(total_len - 2, 65533);
scsi_ulto2b(datalen, header->datalen);
if (control_dev == 0) {
header->dev_specific = 0x10; /* DPOFUA */
@@ -7358,8 +7309,8 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_report_tagret_port_groups\n"));
cdb = (struct scsi_maintenance_in *)ctsio->cdb;
- softc = control_softc;
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ softc = lun->ctl_softc;
retval = CTL_RETVAL_COMPLETE;
@@ -7390,7 +7341,8 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
STAILQ_FOREACH(port, &softc->port_list, links) {
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
- if (ctl_map_lun_back(port->targ_port, lun->lun) >= CTL_MAX_LUNS)
+ if (ctl_map_lun_back(softc, port->targ_port, lun->lun) >=
+ CTL_MAX_LUNS)
continue;
num_target_ports++;
}
@@ -7463,8 +7415,8 @@ ctl_report_tagret_port_groups(struct ctl_scsiio *ctsio)
STAILQ_FOREACH(port, &softc->port_list, links) {
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
- if (ctl_map_lun_back(port->targ_port, lun->lun) >=
- CTL_MAX_LUNS)
+ if (ctl_map_lun_back(softc, port->targ_port, lun->lun)
+ >= CTL_MAX_LUNS)
continue;
p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
scsi_ulto2b(p, tpg_desc->descriptors[pc].
@@ -7756,13 +7708,12 @@ ctl_persistent_reserve_in(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_persistent_reserve_in\n"));
- softc = control_softc;
-
cdb = (struct scsi_per_res_in *)ctsio->cdb;
alloc_len = scsi_2btoul(cdb->length);
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ softc = lun->ctl_softc;
retry:
mtx_lock(&lun->lun_lock);
@@ -8385,10 +8336,9 @@ ctl_persistent_reserve_out(struct ctl_scsiio *ctsio)
retval = CTL_RETVAL_COMPLETE;
- softc = control_softc;
-
cdb = (struct scsi_per_res_out *)ctsio->cdb;
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ softc = lun->ctl_softc;
/*
* We only support whole-LUN scope. The scope & type are ignored for
@@ -9304,6 +9254,7 @@ ctl_verify(struct ctl_scsiio *ctsio)
int
ctl_report_luns(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = control_softc;
struct scsi_report_luns *cdb;
struct scsi_report_luns_data *lun_data;
struct ctl_lun *lun, *request_lun;
@@ -9319,9 +9270,9 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_report_luns\n"));
- mtx_lock(&control_softc->ctl_lock);
- num_luns = control_softc->num_luns;
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
+ num_luns = softc->num_luns;
+ mtx_unlock(&softc->ctl_lock);
switch (cdb->select_report) {
case RPL_REPORT_DEFAULT:
@@ -9373,12 +9324,13 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
initidx = ctl_get_initindex(&ctsio->io_hdr.nexus);
- mtx_lock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
for (targ_lun_id = 0, num_filled = 0; targ_lun_id < CTL_MAX_LUNS && num_filled < num_luns; targ_lun_id++) {
- lun_id = ctl_map_lun(ctsio->io_hdr.nexus.targ_port, targ_lun_id);
+ lun_id = ctl_map_lun(softc, ctsio->io_hdr.nexus.targ_port,
+ targ_lun_id);
if (lun_id >= CTL_MAX_LUNS)
continue;
- lun = control_softc->ctl_luns[lun_id];
+ lun = softc->ctl_luns[lun_id];
if (lun == NULL)
continue;
@@ -9434,7 +9386,7 @@ ctl_report_luns(struct ctl_scsiio *ctsio)
mtx_unlock(&lun->lun_lock);
}
}
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
/*
* It's quite possible that we've returned fewer LUNs than we allocated
@@ -9563,7 +9515,7 @@ ctl_request_sense(struct ctl_scsiio *ctsio)
(struct scsi_sense_data_fixed *)sense_ptr);
else
memcpy(sense_ptr, &lun->pending_sense[initidx],
- ctl_min(sizeof(*sense_ptr),
+ MIN(sizeof(*sense_ptr),
sizeof(lun->pending_sense[initidx])));
ctl_clear_mask(lun->have_ca, initidx);
@@ -9647,6 +9599,7 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
struct scsi_vpd_supported_pages *pages;
int sup_page_size;
struct ctl_lun *lun;
+ int p;
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
@@ -9680,27 +9633,30 @@ ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len)
else
pages->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
- pages->length = SCSI_EVPD_NUM_SUPPORTED_PAGES;
+ p = 0;
/* Supported VPD pages */
- pages->page_list[0] = SVPD_SUPPORTED_PAGES;
+ pages->page_list[p++] = SVPD_SUPPORTED_PAGES;
/* Serial Number */
- pages->page_list[1] = SVPD_UNIT_SERIAL_NUMBER;
+ pages->page_list[p++] = SVPD_UNIT_SERIAL_NUMBER;
/* Device Identification */
- pages->page_list[2] = SVPD_DEVICE_ID;
+ pages->page_list[p++] = SVPD_DEVICE_ID;
/* Extended INQUIRY Data */
- pages->page_list[3] = SVPD_EXTENDED_INQUIRY_DATA;
+ pages->page_list[p++] = SVPD_EXTENDED_INQUIRY_DATA;
/* Mode Page Policy */
- pages->page_list[4] = SVPD_MODE_PAGE_POLICY;
+ pages->page_list[p++] = SVPD_MODE_PAGE_POLICY;
/* SCSI Ports */
- pages->page_list[5] = SVPD_SCSI_PORTS;
+ pages->page_list[p++] = SVPD_SCSI_PORTS;
/* Third-party Copy */
- pages->page_list[6] = SVPD_SCSI_TPC;
- /* Block limits */
- pages->page_list[7] = SVPD_BLOCK_LIMITS;
- /* Block Device Characteristics */
- pages->page_list[8] = SVPD_BDC;
- /* Logical Block Provisioning */
- pages->page_list[9] = SVPD_LBP;
+ pages->page_list[p++] = SVPD_SCSI_TPC;
+ if (lun != NULL && lun->be_lun->lun_type == T_DIRECT) {
+ /* Block limits */
+ pages->page_list[p++] = SVPD_BLOCK_LIMITS;
+ /* Block Device Characteristics */
+ pages->page_list[p++] = SVPD_BDC;
+ /* Logical Block Provisioning */
+ pages->page_list[p++] = SVPD_LBP;
+ }
+ pages->length = p;
ctl_set_success(ctsio);
ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
@@ -9869,15 +9825,15 @@ ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len)
{
struct scsi_vpd_device_id *devid_ptr;
struct scsi_vpd_id_descriptor *desc;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_lun *lun;
struct ctl_port *port;
int data_len;
uint8_t proto;
- ctl_softc = control_softc;
+ softc = control_softc;
- port = ctl_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
+ port = softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
data_len = sizeof(struct scsi_vpd_device_id) +
@@ -10011,7 +9967,7 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
if (lun != NULL &&
- ctl_map_lun_back(port->targ_port, lun->lun) >=
+ ctl_map_lun_back(softc, port->targ_port, lun->lun) >=
CTL_MAX_LUNS)
continue;
num_target_ports++;
@@ -10065,8 +10021,8 @@ ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, int alloc_len)
if ((port->status & CTL_PORT_STATUS_ONLINE) == 0)
continue;
if (lun != NULL &&
- ctl_map_lun_back(port->targ_port, lun->lun) >=
- CTL_MAX_LUNS)
+ ctl_map_lun_back(softc, port->targ_port, lun->lun)
+ >= CTL_MAX_LUNS)
continue;
p = port->targ_port % CTL_MAX_PORTS + g * CTL_MAX_PORTS;
scsi_ulto2b(p, pd->relative_port_id);
@@ -10142,7 +10098,7 @@ ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, int alloc_len)
scsi_ulto4b(0xffffffff, bl_ptr->max_txfer_len);
if (lun != NULL) {
bs = lun->be_lun->blocksize;
- scsi_ulto4b(MAXPHYS / bs, bl_ptr->opt_txfer_len);
+ scsi_ulto4b(lun->be_lun->opttxferlen, bl_ptr->opt_txfer_len);
if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) {
scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt);
scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt);
@@ -10282,13 +10238,12 @@ ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len)
static int
ctl_inquiry_evpd(struct ctl_scsiio *ctsio)
{
+ struct ctl_lun *lun;
struct scsi_inquiry *cdb;
int alloc_len, retval;
+ lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
cdb = (struct scsi_inquiry *)ctsio->cdb;
-
- retval = CTL_RETVAL_COMPLETE;
-
alloc_len = scsi_2btoul(cdb->length);
switch (cdb->page_code) {
@@ -10314,15 +10269,22 @@ ctl_inquiry_evpd(struct ctl_scsiio *ctsio)
retval = ctl_inquiry_evpd_tpc(ctsio, alloc_len);
break;
case SVPD_BLOCK_LIMITS:
+ if (lun == NULL || lun->be_lun->lun_type != T_DIRECT)
+ goto err;
retval = ctl_inquiry_evpd_block_limits(ctsio, alloc_len);
break;
case SVPD_BDC:
+ if (lun == NULL || lun->be_lun->lun_type != T_DIRECT)
+ goto err;
retval = ctl_inquiry_evpd_bdc(ctsio, alloc_len);
break;
case SVPD_LBP:
+ if (lun == NULL || lun->be_lun->lun_type != T_DIRECT)
+ goto err;
retval = ctl_inquiry_evpd_lbp(ctsio, alloc_len);
break;
default:
+err:
ctl_set_invalid_field(ctsio,
/*sks_valid*/ 1,
/*command*/ 1,
@@ -10342,20 +10304,20 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
{
struct scsi_inquiry_data *inq_ptr;
struct scsi_inquiry *cdb;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_lun *lun;
char *val;
uint32_t alloc_len, data_len;
ctl_port_type port_type;
- ctl_softc = control_softc;
+ softc = control_softc;
/*
* Figure out whether we're talking to a Fibre Channel port or not.
* We treat the ioctl front end, and any SCSI adapters, as packetized
* SCSI front ends.
*/
- port_type = ctl_softc->ctl_ports[
+ port_type = softc->ctl_ports[
ctl_port_idx(ctsio->io_hdr.nexus.targ_port)]->port_type;
if (port_type == CTL_PORT_IOCTL || port_type == CTL_PORT_INTERNAL)
port_type = CTL_PORT_SCSI;
@@ -10432,7 +10394,7 @@ ctl_inquiry_std(struct ctl_scsiio *ctsio)
if (lun != NULL)
inq_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
lun->be_lun->lun_type;
- else if (ctl_softc->inquiry_pq_no_lun == 0)
+ else if (softc->inquiry_pq_no_lun == 0)
inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT;
else
inq_ptr->device = (SID_QUAL_BAD_LU << 5) | T_NODEVICE;
@@ -11065,7 +11027,6 @@ ctl_check_blocked(struct ctl_lun *lun)
break;
case CTL_ACTION_PASS:
case CTL_ACTION_SKIP: {
- struct ctl_softc *softc;
const struct ctl_cmd_entry *entry;
int isc_retval;
@@ -11104,7 +11065,6 @@ ctl_check_blocked(struct ctl_lun *lun)
break;
}
entry = ctl_get_cmd_entry(&cur_blocked->scsiio, NULL);
- softc = control_softc;
/*
* Check this I/O for LUN state changes that may
@@ -11114,7 +11074,7 @@ ctl_check_blocked(struct ctl_lun *lun)
* for any states that can be caused by SCSI
* commands.
*/
- if (ctl_scsiio_lun_check(softc, lun, entry,
+ if (ctl_scsiio_lun_check(lun, entry,
&cur_blocked->scsiio) == 0) {
cur_blocked->io_hdr.flags |=
CTL_FLAG_IS_WAS_ON_RTR;
@@ -11148,9 +11108,10 @@ ctl_check_blocked(struct ctl_lun *lun)
* careful attention to the placement of any new checks.
*/
static int
-ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
+ctl_scsiio_lun_check(struct ctl_lun *lun,
const struct ctl_cmd_entry *entry, struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc = lun->ctl_softc;
int retval;
uint32_t residx;
@@ -11162,7 +11123,7 @@ ctl_scsiio_lun_check(struct ctl_softc *ctl_softc, struct ctl_lun *lun,
* If this shelf is a secondary shelf controller, we have to reject
* any media access commands.
*/
- if ((ctl_softc->flags & CTL_FLAG_ACTIVE_SHELF) == 0 &&
+ if ((softc->flags & CTL_FLAG_ACTIVE_SHELF) == 0 &&
(entry->flags & CTL_CMD_FLAG_OK_ON_SECONDARY) == 0) {
ctl_set_lun_standby(ctsio);
retval = 1;
@@ -11268,14 +11229,14 @@ static void
ctl_failover(void)
{
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
union ctl_io *next_io, *pending_io;
union ctl_io *io;
int lun_idx;
- ctl_softc = control_softc;
+ softc = control_softc;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
/*
* Remove any cmds from the other SC from the rtr queue. These
* will obviously only be for LUNs for which we're the primary.
@@ -11285,19 +11246,19 @@ ctl_failover(void)
* which HA mode we're in.
*/
#ifdef notyet
- mtx_lock(&ctl_softc->queue_lock);
- for (io = (union ctl_io *)STAILQ_FIRST(&ctl_softc->rtr_queue);
+ mtx_lock(&softc->queue_lock);
+ for (io = (union ctl_io *)STAILQ_FIRST(&softc->rtr_queue);
io != NULL; io = next_io) {
next_io = (union ctl_io *)STAILQ_NEXT(&io->io_hdr, links);
if (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)
- STAILQ_REMOVE(&ctl_softc->rtr_queue, &io->io_hdr,
+ STAILQ_REMOVE(&softc->rtr_queue, &io->io_hdr,
ctl_io_hdr, links);
}
- mtx_unlock(&ctl_softc->queue_lock);
+ mtx_unlock(&softc->queue_lock);
#endif
- for (lun_idx=0; lun_idx < ctl_softc->num_luns; lun_idx++) {
- lun = ctl_softc->ctl_luns[lun_idx];
+ for (lun_idx=0; lun_idx < softc->num_luns; lun_idx++) {
+ lun = softc->ctl_luns[lun_idx];
if (lun==NULL)
continue;
@@ -11309,7 +11270,7 @@ ctl_failover(void)
continue;
if ((lun->flags & CTL_LUN_PRIMARY_SC)
- && (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY)) {
+ && (softc->ha_mode == CTL_HA_MODE_SER_ONLY)) {
printf("FAILOVER: primary lun %d\n", lun_idx);
/*
* Remove all commands from the other SC. First from the
@@ -11351,7 +11312,7 @@ ctl_failover(void)
}
ctl_check_blocked(lun);
} else if ((lun->flags & CTL_LUN_PRIMARY_SC)
- && (ctl_softc->ha_mode == CTL_HA_MODE_XFER)) {
+ && (softc->ha_mode == CTL_HA_MODE_XFER)) {
printf("FAILOVER: primary lun %d\n", lun_idx);
/*
@@ -11369,7 +11330,7 @@ ctl_failover(void)
io->io_hdr.flags |= CTL_FLAG_ABORT;
}
} else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0)
- && (ctl_softc->ha_mode == CTL_HA_MODE_XFER)) {
+ && (softc->ha_mode == CTL_HA_MODE_XFER)) {
printf("FAILOVER: secondary lun %d\n", lun_idx);
@@ -11408,7 +11369,7 @@ ctl_failover(void)
ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
} else if (((lun->flags & CTL_LUN_PRIMARY_SC) == 0)
- && (ctl_softc->ha_mode == CTL_HA_MODE_SER_ONLY)) {
+ && (softc->ha_mode == CTL_HA_MODE_SER_ONLY)) {
printf("FAILOVER: secondary lun %d\n", lun_idx);
/*
* if the first io on the OOA is not on the RtR queue
@@ -11498,15 +11459,15 @@ ctl_failover(void)
ctl_est_ua_all(lun, -1, CTL_UA_ASYM_ACC_CHANGE);
} else {
panic("Unhandled HA mode failover, LUN flags = %#x, "
- "ha_mode = #%x", lun->flags, ctl_softc->ha_mode);
+ "ha_mode = #%x", lun->flags, softc->ha_mode);
}
}
ctl_pause_rtr = 0;
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
}
static int
-ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
+ctl_scsiio_precheck(struct ctl_softc *softc, struct ctl_scsiio *ctsio)
{
struct ctl_lun *lun;
const struct ctl_cmd_entry *entry;
@@ -11519,7 +11480,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
targ_lun = ctsio->io_hdr.nexus.targ_mapped_lun;
if ((targ_lun < CTL_MAX_LUNS)
- && ((lun = ctl_softc->ctl_luns[targ_lun]) != NULL)) {
+ && ((lun = softc->ctl_luns[targ_lun]) != NULL)) {
/*
* If the LUN is invalid, pretend that it doesn't exist.
* It will go away as soon as all pending I/O has been
@@ -11651,7 +11612,7 @@ ctl_scsiio_precheck(struct ctl_softc *ctl_softc, struct ctl_scsiio *ctsio)
}
- if (ctl_scsiio_lun_check(ctl_softc, lun, entry, ctsio) != 0) {
+ if (ctl_scsiio_lun_check(lun, entry, ctsio) != 0) {
mtx_unlock(&lun->lun_lock);
ctl_done((union ctl_io *)ctsio);
return (retval);
@@ -11859,13 +11820,13 @@ bailout:
* our single target.
*/
static int
-ctl_bus_reset(struct ctl_softc *ctl_softc, union ctl_io *io)
+ctl_bus_reset(struct ctl_softc *softc, union ctl_io *io)
{
- return(ctl_target_reset(ctl_softc, io, CTL_UA_BUS_RESET));
+ return(ctl_target_reset(softc, io, CTL_UA_BUS_RESET));
}
static int
-ctl_target_reset(struct ctl_softc *ctl_softc, union ctl_io *io,
+ctl_target_reset(struct ctl_softc *softc, union ctl_io *io,
ctl_ua_type ua_type)
{
struct ctl_lun *lun;
@@ -11889,10 +11850,10 @@ ctl_target_reset(struct ctl_softc *ctl_softc, union ctl_io *io,
}
retval = 0;
- mtx_lock(&ctl_softc->ctl_lock);
- STAILQ_FOREACH(lun, &ctl_softc->lun_list, links)
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_FOREACH(lun, &softc->lun_list, links)
retval += ctl_lun_reset(lun, io, ua_type);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (retval);
}
@@ -12078,7 +12039,7 @@ ctl_abort_task(union ctl_io *io)
{
union ctl_io *xio;
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
#if 0
struct sbuf sb;
char printbuf[128];
@@ -12086,19 +12047,19 @@ ctl_abort_task(union ctl_io *io)
int found;
uint32_t targ_lun;
- ctl_softc = control_softc;
+ softc = control_softc;
found = 0;
/*
* Look up the LUN.
*/
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
if ((targ_lun < CTL_MAX_LUNS)
- && (ctl_softc->ctl_luns[targ_lun] != NULL))
- lun = ctl_softc->ctl_luns[targ_lun];
+ && (softc->ctl_luns[targ_lun] != NULL))
+ lun = softc->ctl_luns[targ_lun];
else {
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (1);
}
@@ -12108,7 +12069,7 @@ ctl_abort_task(union ctl_io *io)
#endif
mtx_lock(&lun->lun_lock);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
/*
* Run through the OOA queue and attempt to find the given I/O.
* The target port, initiator ID, tag type and tag number have to
@@ -12224,7 +12185,7 @@ ctl_abort_task(union ctl_io *io)
static void
ctl_run_task(union ctl_io *io)
{
- struct ctl_softc *ctl_softc = control_softc;
+ struct ctl_softc *softc = control_softc;
int retval = 1;
const char *task_desc;
@@ -12279,12 +12240,12 @@ ctl_run_task(union ctl_io *io)
uint32_t targ_lun;
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
if ((targ_lun < CTL_MAX_LUNS)
- && (ctl_softc->ctl_luns[targ_lun] != NULL))
- lun = ctl_softc->ctl_luns[targ_lun];
+ && (softc->ctl_luns[targ_lun] != NULL))
+ lun = softc->ctl_luns[targ_lun];
else {
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
retval = 1;
break;
}
@@ -12311,14 +12272,14 @@ ctl_run_task(union ctl_io *io)
retval = ctl_lun_reset(lun, io,
CTL_UA_LUN_RESET);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
break;
}
case CTL_TASK_TARGET_RESET:
- retval = ctl_target_reset(ctl_softc, io, CTL_UA_TARG_RESET);
+ retval = ctl_target_reset(softc, io, CTL_UA_TARG_RESET);
break;
case CTL_TASK_BUS_RESET:
- retval = ctl_bus_reset(ctl_softc, io);
+ retval = ctl_bus_reset(softc, io);
break;
case CTL_TASK_PORT_LOGIN:
break;
@@ -12345,13 +12306,13 @@ ctl_handle_isc(union ctl_io *io)
{
int free_io;
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
uint32_t targ_lun;
- ctl_softc = control_softc;
+ softc = control_softc;
targ_lun = io->io_hdr.nexus.targ_mapped_lun;
- lun = ctl_softc->ctl_luns[targ_lun];
+ lun = softc->ctl_luns[targ_lun];
switch (io->io_hdr.msg_type) {
case CTL_MSG_SERIALIZE:
@@ -12366,7 +12327,7 @@ ctl_handle_isc(union ctl_io *io)
free_io = 0;
entry = ctl_get_cmd_entry(&io->scsiio, NULL);
mtx_lock(&lun->lun_lock);
- if (ctl_scsiio_lun_check(ctl_softc, lun,
+ if (ctl_scsiio_lun_check(lun,
entry, (struct ctl_scsiio *)io) != 0) {
mtx_unlock(&lun->lun_lock);
ctl_done(io);
@@ -12378,7 +12339,7 @@ ctl_handle_isc(union ctl_io *io)
break;
}
case CTL_MSG_FINISH_IO:
- if (ctl_softc->ha_mode == CTL_HA_MODE_XFER) {
+ if (softc->ha_mode == CTL_HA_MODE_XFER) {
free_io = 0;
ctl_done(io);
} else {
@@ -12523,8 +12484,8 @@ ctl_inject_error(struct ctl_lun *lun, union ctl_io *io)
* checks.
*/
bcopy(&desc->custom_sense, &io->scsiio.sense_data,
- ctl_min(sizeof(desc->custom_sense),
- sizeof(io->scsiio.sense_data)));
+ MIN(sizeof(desc->custom_sense),
+ sizeof(io->scsiio.sense_data)));
io->scsiio.scsi_status = SCSI_STATUS_CHECK_COND;
io->scsiio.sense_len = SSD_FULL_SIZE;
io->io_hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE;
@@ -12753,7 +12714,7 @@ ctl_datamove(union ctl_io *io)
*/
for (sg_entries_sent = 0; sg_entries_sent <
msg.dt.kern_sg_entries; msg.dt.sg_sequence++) {
- msg.dt.cur_sg_entries = ctl_min((sizeof(msg.dt.sg_list)/
+ msg.dt.cur_sg_entries = MIN((sizeof(msg.dt.sg_list)/
sizeof(msg.dt.sg_list[0])),
msg.dt.kern_sg_entries - sg_entries_sent);
@@ -13116,7 +13077,7 @@ ctl_datamove_remote_sgl_setup(union ctl_io *io)
for (i = 0; (i < sizeof(io->io_hdr.remote_sglist) /
sizeof(io->io_hdr.remote_sglist[0])) &&
(len_to_go > 0); i++) {
- local_sglist[i].len = ctl_min(len_to_go, 131072);
+ local_sglist[i].len = MIN(len_to_go, 131072);
CTL_SIZE_8B(local_dma_sglist[i].len,
local_sglist[i].len);
local_sglist[i].addr =
@@ -13252,8 +13213,8 @@ ctl_datamove_remote_xfer(union ctl_io *io, unsigned command,
* also have enough slack left over at the end, though,
* to round up to the next 8 byte boundary.
*/
- cur_len = ctl_min(local_sglist[i].len - local_used,
- remote_sglist[j].len - remote_used);
+ cur_len = MIN(local_sglist[i].len - local_used,
+ remote_sglist[j].len - remote_used);
/*
* In this case, we have a size issue and need to decrease
@@ -13477,14 +13438,13 @@ static int
ctl_process_done(union ctl_io *io)
{
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc = control_softc;
+ struct ctl_softc *softc = control_softc;
void (*fe_done)(union ctl_io *io);
uint32_t targ_port = ctl_port_idx(io->io_hdr.nexus.targ_port);
CTL_DEBUG_PRINT(("ctl_process_done\n"));
- fe_done =
- control_softc->ctl_ports[targ_port]->fe_done;
+ fe_done = softc->ctl_ports[targ_port]->fe_done;
#ifdef CTL_TIME_IO
if ((time_uptime - io->io_hdr.start_time) > ctl_time_io_secs) {
@@ -13611,9 +13571,9 @@ ctl_process_done(union ctl_io *io)
if ((lun->flags & CTL_LUN_INVALID)
&& TAILQ_EMPTY(&lun->ooa_queue)) {
mtx_unlock(&lun->lun_lock);
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
ctl_free_lun(lun);
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
} else
mtx_unlock(&lun->lun_lock);
@@ -13665,7 +13625,7 @@ bailout:
* if the frontend comes back in in this context to queue
* something.
*/
- if ((ctl_softc->ha_mode == CTL_HA_MODE_XFER)
+ if ((softc->ha_mode == CTL_HA_MODE_XFER)
&& (io->io_hdr.flags & CTL_FLAG_FROM_OTHER_SC)) {
union ctl_ha_msg msg;
@@ -13713,10 +13673,10 @@ int
ctl_queue_sense(union ctl_io *io)
{
struct ctl_lun *lun;
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
uint32_t initidx, targ_lun;
- ctl_softc = control_softc;
+ softc = control_softc;
CTL_DEBUG_PRINT(("ctl_queue_sense\n"));
@@ -13727,17 +13687,17 @@ ctl_queue_sense(union ctl_io *io)
* things like an INQUIRY to a LUN that we don't have enabled. We
* can't deal with that right now.
*/
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
/*
* If we don't have a LUN for this, just toss the sense
* information.
*/
targ_lun = io->io_hdr.nexus.targ_lun;
- targ_lun = ctl_map_lun(io->io_hdr.nexus.targ_port, targ_lun);
+ targ_lun = ctl_map_lun(softc, io->io_hdr.nexus.targ_port, targ_lun);
if ((targ_lun < CTL_MAX_LUNS)
- && (ctl_softc->ctl_luns[targ_lun] != NULL))
- lun = ctl_softc->ctl_luns[targ_lun];
+ && (softc->ctl_luns[targ_lun] != NULL))
+ lun = softc->ctl_luns[targ_lun];
else
goto bailout;
@@ -13753,13 +13713,13 @@ ctl_queue_sense(union ctl_io *io)
}
memcpy(&lun->pending_sense[initidx], &io->scsiio.sense_data,
- ctl_min(sizeof(lun->pending_sense[initidx]),
+ MIN(sizeof(lun->pending_sense[initidx]),
sizeof(io->scsiio.sense_data)));
ctl_set_mask(lun->have_ca, initidx);
mtx_unlock(&lun->lun_lock);
bailout:
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
ctl_free_io(io);
@@ -13774,12 +13734,9 @@ bailout:
int
ctl_queue(union ctl_io *io)
{
- struct ctl_softc *ctl_softc;
CTL_DEBUG_PRINT(("ctl_queue cdb[0]=%02X\n", io->scsiio.cdb[0]));
- ctl_softc = control_softc;
-
#ifdef CTL_TIME_IO
io->io_hdr.start_time = time_uptime;
getbintime(&io->io_hdr.start_bt);
@@ -13787,7 +13744,8 @@ ctl_queue(union ctl_io *io)
/* Map FE-specific LUN ID into global one. */
io->io_hdr.nexus.targ_mapped_lun =
- ctl_map_lun(io->io_hdr.nexus.targ_port, io->io_hdr.nexus.targ_lun);
+ ctl_map_lun(control_softc, io->io_hdr.nexus.targ_port,
+ io->io_hdr.nexus.targ_lun);
switch (io->io_hdr.io_type) {
case CTL_IO_SCSI:
@@ -13818,9 +13776,6 @@ ctl_done_timer_wakeup(void *arg)
void
ctl_done(union ctl_io *io)
{
- struct ctl_softc *ctl_softc;
-
- ctl_softc = control_softc;
/*
* Enable this to catch duplicate completion issues.
diff --git a/sys/cam/ctl/ctl.h b/sys/cam/ctl/ctl.h
index ae6c583..9cf967c 100644
--- a/sys/cam/ctl/ctl.h
+++ b/sys/cam/ctl/ctl.h
@@ -40,7 +40,6 @@
#ifndef _CTL_H_
#define _CTL_H_
-#define ctl_min(x,y) (((x) < (y)) ? (x) : (y))
#define CTL_RETVAL_COMPLETE 0
#define CTL_RETVAL_QUEUED 1
#define CTL_RETVAL_ALLOCATED 2
diff --git a/sys/cam/ctl/ctl_backend.c b/sys/cam/ctl/ctl_backend.c
index 0e1a76c..cabecb7 100644
--- a/sys/cam/ctl/ctl_backend.c
+++ b/sys/cam/ctl/ctl_backend.c
@@ -66,33 +66,33 @@ extern struct ctl_softc *control_softc;
int
ctl_backend_register(struct ctl_backend_driver *be)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_backend_driver *be_tmp;
- ctl_softc = control_softc;
+ softc = control_softc;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
/*
* Sanity check, make sure this isn't a duplicate registration.
*/
- STAILQ_FOREACH(be_tmp, &ctl_softc->be_list, links) {
+ STAILQ_FOREACH(be_tmp, &softc->be_list, links) {
if (strcmp(be_tmp->name, be->name) == 0) {
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (-1);
}
}
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
/*
* Call the backend's initialization routine.
*/
be->init();
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
- STAILQ_INSERT_TAIL(&ctl_softc->be_list, be, links);
+ STAILQ_INSERT_TAIL(&softc->be_list, be, links);
- ctl_softc->num_backends++;
+ softc->num_backends++;
/*
* Don't want to increment the usage count for internal consumers,
@@ -113,7 +113,7 @@ ctl_backend_register(struct ctl_backend_driver *be)
atomic_set(&be->num_luns, 0);
#endif
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
@@ -121,24 +121,24 @@ ctl_backend_register(struct ctl_backend_driver *be)
int
ctl_backend_deregister(struct ctl_backend_driver *be)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
- ctl_softc = control_softc;
+ softc = control_softc;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
#if 0
if (atomic_read(&be->num_luns) != 0) {
#endif
/* XXX KDM fix this! */
if (be->num_luns != 0) {
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (-1);
}
- STAILQ_REMOVE(&ctl_softc->be_list, be, ctl_backend_driver, links);
+ STAILQ_REMOVE(&softc->be_list, be, ctl_backend_driver, links);
- ctl_softc->num_backends--;
+ softc->num_backends--;
/* XXX KDM find a substitute for this? */
#if 0
@@ -146,7 +146,7 @@ ctl_backend_deregister(struct ctl_backend_driver *be)
MOD_DEC_USE_COUNT;
#endif
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
@@ -154,21 +154,21 @@ ctl_backend_deregister(struct ctl_backend_driver *be)
struct ctl_backend_driver *
ctl_backend_find(char *backend_name)
{
- struct ctl_softc *ctl_softc;
+ struct ctl_softc *softc;
struct ctl_backend_driver *be_tmp;
- ctl_softc = control_softc;
+ softc = control_softc;
- mtx_lock(&ctl_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
- STAILQ_FOREACH(be_tmp, &ctl_softc->be_list, links) {
+ STAILQ_FOREACH(be_tmp, &softc->be_list, links) {
if (strcmp(be_tmp->name, backend_name) == 0) {
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (be_tmp);
}
}
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (NULL);
}
diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h
index 5e0af5c..93a530c 100644
--- a/sys/cam/ctl/ctl_backend.h
+++ b/sys/cam/ctl/ctl_backend.h
@@ -146,10 +146,16 @@ typedef void (*be_lun_config_t)(void *be_lun,
*
* pblockexp is the log2() of number of LBAs on the LUN per physical sector.
*
- * pblockoff is the lowest LBA on the LUN aligned ot physical sector.
+ * pblockoff is the lowest LBA on the LUN aligned to physical sector.
+ *
+ * ublockexp is the log2() of number of LBAs on the LUN per UNMAP block.
+ *
+ * ublockoff is the lowest LBA on the LUN aligned to UNMAP block.
*
* atomicblock is the number of blocks that can be written atomically.
*
+ * opttxferlen is the number of blocks that can be written in one operation.
+ *
* req_lun_id is the requested LUN ID. CTL only pays attention to this
* field if the CTL_LUN_FLAG_ID_REQ flag is set. If the requested LUN ID is
* not available, the LUN addition will fail. If a particular LUN ID isn't
@@ -197,6 +203,7 @@ struct ctl_be_lun {
uint16_t ublockexp; /* passed to CTL */
uint16_t ublockoff; /* passed to CTL */
uint32_t atomicblock; /* passed to CTL */
+ uint32_t opttxferlen; /* passed to CTL */
uint32_t req_lun_id; /* passed to CTL */
uint32_t lun_id; /* returned from CTL */
uint8_t serial_num[CTL_SN_LEN]; /* passed to CTL */
diff --git a/sys/cam/ctl/ctl_backend_block.c b/sys/cam/ctl/ctl_backend_block.c
index 9c3e8fd..a5e45024 100644
--- a/sys/cam/ctl/ctl_backend_block.c
+++ b/sys/cam/ctl/ctl_backend_block.c
@@ -175,6 +175,8 @@ struct ctl_be_block_lun {
uint16_t pblockoff;
uint16_t ublockexp;
uint16_t ublockoff;
+ uint32_t atomicblock;
+ uint32_t opttxferlen;
struct ctl_be_block_softc *softc;
struct devstat *disk_stats;
ctl_be_block_lun_flags flags;
@@ -1845,6 +1847,8 @@ ctl_be_block_open_file(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
"file %s size %ju < block size %u", be_lun->dev_path,
(uintmax_t)be_lun->size_bytes, be_lun->blocksize);
}
+
+ be_lun->opttxferlen = CTLBLK_MAX_IO_SIZE / be_lun->blocksize;
return (error);
}
@@ -1856,7 +1860,7 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
struct cdev *dev;
struct cdevsw *devsw;
char *value;
- int error;
+ int error, atomic, maxio;
off_t ps, pss, po, pos, us, uss, uo, uos;
params = &be_lun->params;
@@ -1870,8 +1874,16 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
if (strcmp(be_lun->backend.dev.csw->d_name, "zvol") == 0) {
be_lun->dispatch = ctl_be_block_dispatch_zvol;
be_lun->get_lba_status = ctl_be_block_gls_zvol;
- } else
+ atomic = maxio = CTLBLK_MAX_IO_SIZE;
+ } else {
be_lun->dispatch = ctl_be_block_dispatch_dev;
+ atomic = 0;
+ maxio = be_lun->backend.dev.cdev->si_iosize_max;
+ if (maxio <= 0)
+ maxio = DFLTPHYS;
+ if (maxio > CTLBLK_MAX_IO_SIZE)
+ maxio = CTLBLK_MAX_IO_SIZE;
+ }
be_lun->lun_flush = ctl_be_block_flush_dev;
be_lun->unmap = ctl_be_block_unmap_dev;
be_lun->getattr = ctl_be_block_getattr_dev;
@@ -2002,6 +2014,8 @@ ctl_be_block_open_dev(struct ctl_be_block_lun *be_lun, struct ctl_lun_req *req)
be_lun->ublockoff = (uss - uos) % uss;
}
+ be_lun->atomicblock = atomic / be_lun->blocksize;
+ be_lun->opttxferlen = maxio / be_lun->blocksize;
return (0);
}
@@ -2268,10 +2282,8 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp;
be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff;
- if (be_lun->dispatch == ctl_be_block_dispatch_zvol &&
- be_lun->blocksize != 0)
- be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /
- be_lun->blocksize;
+ be_lun->ctl_be_lun.atomicblock = be_lun->atomicblock;
+ be_lun->ctl_be_lun.opttxferlen = be_lun->opttxferlen;
/* Tell the user the blocksize we ended up using */
params->lun_size_bytes = be_lun->size_bytes;
params->blocksize_bytes = be_lun->blocksize;
@@ -2290,32 +2302,32 @@ ctl_be_block_create(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d",
softc->num_luns);
strncpy((char *)be_lun->ctl_be_lun.serial_num, tmpstr,
- ctl_min(sizeof(be_lun->ctl_be_lun.serial_num),
+ MIN(sizeof(be_lun->ctl_be_lun.serial_num),
sizeof(tmpstr)));
/* Tell the user what we used for a serial number */
strncpy((char *)params->serial_num, tmpstr,
- ctl_min(sizeof(params->serial_num), sizeof(tmpstr)));
+ MIN(sizeof(params->serial_num), sizeof(tmpstr)));
} else {
strncpy((char *)be_lun->ctl_be_lun.serial_num,
params->serial_num,
- ctl_min(sizeof(be_lun->ctl_be_lun.serial_num),
+ MIN(sizeof(be_lun->ctl_be_lun.serial_num),
sizeof(params->serial_num)));
}
if ((params->flags & CTL_LUN_FLAG_DEVID) == 0) {
snprintf(tmpstr, sizeof(tmpstr), "MYDEVID%4d", softc->num_luns);
strncpy((char *)be_lun->ctl_be_lun.device_id, tmpstr,
- ctl_min(sizeof(be_lun->ctl_be_lun.device_id),
+ MIN(sizeof(be_lun->ctl_be_lun.device_id),
sizeof(tmpstr)));
/* Tell the user what we used for a device ID */
strncpy((char *)params->device_id, tmpstr,
- ctl_min(sizeof(params->device_id), sizeof(tmpstr)));
+ MIN(sizeof(params->device_id), sizeof(tmpstr)));
} else {
strncpy((char *)be_lun->ctl_be_lun.device_id,
params->device_id,
- ctl_min(sizeof(be_lun->ctl_be_lun.device_id),
- sizeof(params->device_id)));
+ MIN(sizeof(be_lun->ctl_be_lun.device_id),
+ sizeof(params->device_id)));
}
TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_be_block_worker, be_lun);
@@ -2649,10 +2661,8 @@ ctl_be_block_modify(struct ctl_be_block_softc *softc, struct ctl_lun_req *req)
be_lun->ctl_be_lun.pblockoff = be_lun->pblockoff;
be_lun->ctl_be_lun.ublockexp = be_lun->ublockexp;
be_lun->ctl_be_lun.ublockoff = be_lun->ublockoff;
- if (be_lun->dispatch == ctl_be_block_dispatch_zvol &&
- be_lun->blocksize != 0)
- be_lun->ctl_be_lun.atomicblock = CTLBLK_MAX_IO_SIZE /
- be_lun->blocksize;
+ be_lun->ctl_be_lun.atomicblock = be_lun->atomicblock;
+ be_lun->ctl_be_lun.opttxferlen = be_lun->opttxferlen;
ctl_lun_capacity_changed(&be_lun->ctl_be_lun);
if (oldsize == 0 && be_lun->size_blocks != 0)
ctl_lun_online(&be_lun->ctl_be_lun);
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c
index adace4f..d43cb60 100644
--- a/sys/cam/ctl/ctl_backend_ramdisk.c
+++ b/sys/cam/ctl/ctl_backend_ramdisk.c
@@ -313,8 +313,7 @@ ctl_backend_ramdisk_continue(union ctl_io *io)
sg_entries = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
for (i = 0, len_filled = 0; i < sg_filled; i++) {
sg_entries[i].addr = softc->ramdisk_pages[i];
- sg_entries[i].len = ctl_min(PAGE_SIZE,
- len - len_filled);
+ sg_entries[i].len = MIN(PAGE_SIZE, len - len_filled);
len_filled += sg_entries[i].len;
}
io->io_hdr.flags |= CTL_FLAG_KDPTR_SGLIST;
@@ -570,6 +569,8 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
be_lun->size_bytes = be_lun->size_blocks * blocksize;
be_lun->ctl_be_lun.maxlba = be_lun->size_blocks - 1;
+ be_lun->ctl_be_lun.atomicblock = UINT32_MAX;
+ be_lun->ctl_be_lun.opttxferlen = softc->rd_size / blocksize;
} else {
be_lun->ctl_be_lun.maxlba = 0;
blocksize = 0;
@@ -596,7 +597,6 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
be_lun->ctl_be_lun.flags = CTL_LUN_FLAG_PRIMARY;
if (unmap)
be_lun->ctl_be_lun.flags |= CTL_LUN_FLAG_UNMAP;
- be_lun->ctl_be_lun.atomicblock = UINT32_MAX;
be_lun->ctl_be_lun.be_lun = be_lun;
if (params->flags & CTL_LUN_FLAG_ID_REQ) {
@@ -613,32 +613,32 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%4d",
softc->num_luns);
strncpy((char *)be_lun->ctl_be_lun.serial_num, tmpstr,
- ctl_min(sizeof(be_lun->ctl_be_lun.serial_num),
- sizeof(tmpstr)));
+ MIN(sizeof(be_lun->ctl_be_lun.serial_num),
+ sizeof(tmpstr)));
/* Tell the user what we used for a serial number */
strncpy((char *)params->serial_num, tmpstr,
- ctl_min(sizeof(params->serial_num), sizeof(tmpstr)));
+ MIN(sizeof(params->serial_num), sizeof(tmpstr)));
} else {
strncpy((char *)be_lun->ctl_be_lun.serial_num,
params->serial_num,
- ctl_min(sizeof(be_lun->ctl_be_lun.serial_num),
- sizeof(params->serial_num)));
+ MIN(sizeof(be_lun->ctl_be_lun.serial_num),
+ sizeof(params->serial_num)));
}
if ((params->flags & CTL_LUN_FLAG_DEVID) == 0) {
snprintf(tmpstr, sizeof(tmpstr), "MYDEVID%4d", softc->num_luns);
strncpy((char *)be_lun->ctl_be_lun.device_id, tmpstr,
- ctl_min(sizeof(be_lun->ctl_be_lun.device_id),
- sizeof(tmpstr)));
+ MIN(sizeof(be_lun->ctl_be_lun.device_id),
+ sizeof(tmpstr)));
/* Tell the user what we used for a device ID */
strncpy((char *)params->device_id, tmpstr,
- ctl_min(sizeof(params->device_id), sizeof(tmpstr)));
+ MIN(sizeof(params->device_id), sizeof(tmpstr)));
} else {
strncpy((char *)be_lun->ctl_be_lun.device_id,
params->device_id,
- ctl_min(sizeof(be_lun->ctl_be_lun.device_id),
- sizeof(params->device_id)));
+ MIN(sizeof(be_lun->ctl_be_lun.device_id),
+ sizeof(params->device_id)));
}
STAILQ_INIT(&be_lun->cont_queue);
diff --git a/sys/cam/ctl/ctl_frontend.c b/sys/cam/ctl/ctl_frontend.c
index 52dc31c..982675e 100644
--- a/sys/cam/ctl/ctl_frontend.c
+++ b/sys/cam/ctl/ctl_frontend.c
@@ -68,21 +68,22 @@ extern struct ctl_softc *control_softc;
int
ctl_frontend_register(struct ctl_frontend *fe)
{
+ struct ctl_softc *softc = control_softc;
struct ctl_frontend *fe_tmp;
- KASSERT(control_softc != NULL, ("CTL is not initialized"));
+ KASSERT(softc != NULL, ("CTL is not initialized"));
/*
* Sanity check, make sure this isn't a duplicate registration.
*/
- mtx_lock(&control_softc->ctl_lock);
- STAILQ_FOREACH(fe_tmp, &control_softc->fe_list, links) {
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_FOREACH(fe_tmp, &softc->fe_list, links) {
if (strcmp(fe_tmp->name, fe->name) == 0) {
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (-1);
}
}
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
STAILQ_INIT(&fe->port_list);
/*
@@ -91,24 +92,25 @@ ctl_frontend_register(struct ctl_frontend *fe)
if (fe->init != NULL)
fe->init();
- mtx_lock(&control_softc->ctl_lock);
- control_softc->num_frontends++;
- STAILQ_INSERT_TAIL(&control_softc->fe_list, fe, links);
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
+ softc->num_frontends++;
+ STAILQ_INSERT_TAIL(&softc->fe_list, fe, links);
+ mtx_unlock(&softc->ctl_lock);
return (0);
}
int
ctl_frontend_deregister(struct ctl_frontend *fe)
{
+ struct ctl_softc *softc = control_softc;
if (!STAILQ_EMPTY(&fe->port_list))
return (-1);
- mtx_lock(&control_softc->ctl_lock);
- STAILQ_REMOVE(&control_softc->fe_list, fe, ctl_frontend, links);
- control_softc->num_frontends--;
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_REMOVE(&softc->fe_list, fe, ctl_frontend, links);
+ softc->num_frontends--;
+ mtx_unlock(&softc->ctl_lock);
/*
* Call the frontend's shutdown routine.
@@ -121,41 +123,42 @@ ctl_frontend_deregister(struct ctl_frontend *fe)
struct ctl_frontend *
ctl_frontend_find(char *frontend_name)
{
- struct ctl_softc *ctl_softc = control_softc;
+ struct ctl_softc *softc = control_softc;
struct ctl_frontend *fe;
- mtx_lock(&ctl_softc->ctl_lock);
- STAILQ_FOREACH(fe, &ctl_softc->fe_list, links) {
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_FOREACH(fe, &softc->fe_list, links) {
if (strcmp(fe->name, frontend_name) == 0) {
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (fe);
}
}
- mtx_unlock(&ctl_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (NULL);
}
int
ctl_port_register(struct ctl_port *port)
{
+ struct ctl_softc *softc = control_softc;
void *pool;
int port_num;
int retval;
retval = 0;
- KASSERT(control_softc != NULL, ("CTL is not initialized"));
+ KASSERT(softc != NULL, ("CTL is not initialized"));
- mtx_lock(&control_softc->ctl_lock);
- port_num = ctl_ffz(control_softc->ctl_port_mask, CTL_MAX_PORTS);
+ mtx_lock(&softc->ctl_lock);
+ port_num = ctl_ffz(softc->ctl_port_mask, CTL_MAX_PORTS);
if ((port_num == -1)
- || (ctl_set_mask(control_softc->ctl_port_mask, port_num) == -1)) {
+ || (ctl_set_mask(softc->ctl_port_mask, port_num) == -1)) {
port->targ_port = -1;
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
return (1);
}
- control_softc->num_ports++;
- mtx_unlock(&control_softc->ctl_lock);
+ softc->num_ports++;
+ mtx_unlock(&softc->ctl_lock);
/*
* Initialize the initiator and portname mappings
@@ -176,15 +179,15 @@ ctl_port_register(struct ctl_port *port)
* pending sense queue on the next command, whether or not it is
* a REQUEST SENSE.
*/
- retval = ctl_pool_create(control_softc, port->port_name,
+ retval = ctl_pool_create(softc, port->port_name,
port->num_requested_ctl_io + 20, &pool);
if (retval != 0) {
free(port->wwpn_iid, M_CTL);
error:
port->targ_port = -1;
- mtx_lock(&control_softc->ctl_lock);
- ctl_clear_mask(control_softc->ctl_port_mask, port_num);
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
+ ctl_clear_mask(softc->ctl_port_mask, port_num);
+ mtx_unlock(&softc->ctl_lock);
return (retval);
}
port->ctl_pool_ref = pool;
@@ -192,12 +195,12 @@ error:
if (port->options.stqh_first == NULL)
STAILQ_INIT(&port->options);
- mtx_lock(&control_softc->ctl_lock);
- port->targ_port = port_num + control_softc->port_offset;
+ mtx_lock(&softc->ctl_lock);
+ port->targ_port = port_num + softc->port_offset;
STAILQ_INSERT_TAIL(&port->frontend->port_list, port, fe_links);
- STAILQ_INSERT_TAIL(&control_softc->port_list, port, links);
- control_softc->ctl_ports[port_num] = port;
- mtx_unlock(&control_softc->ctl_lock);
+ STAILQ_INSERT_TAIL(&softc->port_list, port, links);
+ softc->ctl_ports[port_num] = port;
+ mtx_unlock(&softc->ctl_lock);
return (retval);
}
@@ -205,6 +208,7 @@ error:
int
ctl_port_deregister(struct ctl_port *port)
{
+ struct ctl_softc *softc = control_softc;
struct ctl_io_pool *pool;
int port_num, retval, i;
@@ -217,15 +221,15 @@ ctl_port_deregister(struct ctl_port *port)
goto bailout;
}
- mtx_lock(&control_softc->ctl_lock);
- STAILQ_REMOVE(&control_softc->port_list, port, ctl_port, links);
+ mtx_lock(&softc->ctl_lock);
+ STAILQ_REMOVE(&softc->port_list, port, ctl_port, links);
STAILQ_REMOVE(&port->frontend->port_list, port, ctl_port, fe_links);
- control_softc->num_ports--;
+ softc->num_ports--;
port_num = (port->targ_port < CTL_MAX_PORTS) ? port->targ_port :
port->targ_port - CTL_MAX_PORTS;
- ctl_clear_mask(control_softc->ctl_port_mask, port_num);
- control_softc->ctl_ports[port_num] = NULL;
- mtx_unlock(&control_softc->ctl_lock);
+ ctl_clear_mask(softc->ctl_port_mask, port_num);
+ softc->ctl_ports[port_num] = NULL;
+ mtx_unlock(&softc->ctl_lock);
ctl_pool_free(pool);
ctl_free_opts(&port->options);
diff --git a/sys/cam/ctl/ctl_frontend_cam_sim.c b/sys/cam/ctl/ctl_frontend_cam_sim.c
index cb17aec..e779e48 100644
--- a/sys/cam/ctl/ctl_frontend_cam_sim.c
+++ b/sys/cam/ctl/ctl_frontend_cam_sim.c
@@ -401,8 +401,8 @@ cfcs_datamove(union ctl_io *io)
i < cam_sg_count && j < ctl_sg_count;) {
uint8_t *cam_ptr, *ctl_ptr;
- len_to_copy = ctl_min(cam_sglist[i].ds_len - cam_watermark,
- ctl_sglist[j].len - ctl_watermark);
+ len_to_copy = MIN(cam_sglist[i].ds_len - cam_watermark,
+ ctl_sglist[j].len - ctl_watermark);
cam_ptr = (uint8_t *)cam_sglist[i].ds_addr;
cam_ptr = cam_ptr + cam_watermark;
diff --git a/sys/cam/ctl/ctl_frontend_internal.c b/sys/cam/ctl/ctl_frontend_internal.c
index 7e7adda..23bd0cf 100644
--- a/sys/cam/ctl/ctl_frontend_internal.c
+++ b/sys/cam/ctl/ctl_frontend_internal.c
@@ -499,8 +499,8 @@ cfi_datamove(union ctl_io *io)
i < ext_sg_entries && j < kern_sg_entries;) {
uint8_t *ext_ptr, *kern_ptr;
- len_to_copy = ctl_min(ext_sglist[i].len - ext_watermark,
- kern_sglist[j].len - kern_watermark);
+ len_to_copy = MIN(ext_sglist[i].len - ext_watermark,
+ kern_sglist[j].len - kern_watermark);
ext_ptr = (uint8_t *)ext_sglist[i].addr;
ext_ptr = ext_ptr + ext_watermark;
@@ -1103,8 +1103,8 @@ cfi_metatask_bbr_errorparse(struct cfi_metatask *metatask, union ctl_io *io)
metatask->taskinfo.bbrread.scsi_status = io->scsiio.scsi_status;
memcpy(&metatask->taskinfo.bbrread.sense_data, &io->scsiio.sense_data,
- ctl_min(sizeof(metatask->taskinfo.bbrread.sense_data),
- sizeof(io->scsiio.sense_data)));
+ MIN(sizeof(metatask->taskinfo.bbrread.sense_data),
+ sizeof(io->scsiio.sense_data)));
if (io->scsiio.scsi_status == SCSI_STATUS_RESERV_CONFLICT) {
metatask->status = CFI_MT_ERROR;
diff --git a/sys/cam/ctl/ctl_tpc.c b/sys/cam/ctl/ctl_tpc.c
index 90a31ae..4e67ce1 100644
--- a/sys/cam/ctl/ctl_tpc.c
+++ b/sys/cam/ctl/ctl_tpc.c
@@ -145,8 +145,6 @@ struct tpc_list {
TAILQ_ENTRY(tpc_list) links;
};
-extern struct ctl_softc *control_softc;
-
static void
tpc_timeout(void *arg)
{
@@ -216,6 +214,7 @@ ctl_tpc_lun_init(struct ctl_lun *lun)
void
ctl_tpc_lun_shutdown(struct ctl_lun *lun)
{
+ struct ctl_softc *softc = lun->ctl_softc;
struct tpc_list *list;
struct tpc_token *token, *ttoken;
@@ -228,11 +227,11 @@ ctl_tpc_lun_shutdown(struct ctl_lun *lun)
}
/* Free ROD tokens for this LUN. */
- mtx_assert(&control_softc->ctl_lock, MA_OWNED);
- TAILQ_FOREACH_SAFE(token, &control_softc->tpc_tokens, links, ttoken) {
+ mtx_assert(&softc->ctl_lock, MA_OWNED);
+ TAILQ_FOREACH_SAFE(token, &softc->tpc_tokens, links, ttoken) {
if (token->lun != lun->lun || token->active)
continue;
- TAILQ_REMOVE(&control_softc->tpc_tokens, token, links);
+ TAILQ_REMOVE(&softc->tpc_tokens, token, links);
free(token->params, M_CTL);
free(token, M_CTL);
}
@@ -796,7 +795,8 @@ tpc_resolve(struct tpc_list *list, uint16_t idx, uint32_t *ss)
}
if (idx >= list->ncscd)
return (UINT64_MAX);
- return (tpcl_resolve(list->init_port, &list->cscd[idx], ss));
+ return (tpcl_resolve(list->lun->ctl_softc,
+ list->init_port, &list->cscd[idx], ss));
}
static int
@@ -1296,6 +1296,7 @@ static void
tpc_process(struct tpc_list *list)
{
struct ctl_lun *lun = list->lun;
+ struct ctl_softc *softc = lun->ctl_softc;
struct scsi_ec_segment *seg;
struct ctl_scsiio *ctsio = list->ctsio;
int retval = CTL_RETVAL_COMPLETE;
@@ -1349,10 +1350,10 @@ done:
free(list->params, M_CTL);
list->params = NULL;
if (list->token) {
- mtx_lock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
if (--list->token->active == 0)
list->token->last_active = time_uptime;
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
list->token = NULL;
}
mtx_lock(&lun->lun_lock);
@@ -1831,6 +1832,7 @@ ctl_populate_token(struct ctl_scsiio *ctsio)
{
struct scsi_populate_token *cdb;
struct scsi_populate_token_data *data;
+ struct ctl_softc *softc;
struct ctl_lun *lun;
struct ctl_port *port;
struct tpc_list *list, *tlist;
@@ -1840,7 +1842,8 @@ ctl_populate_token(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_populate_token\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
- port = control_softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
+ softc = lun->ctl_softc;
+ port = softc->ctl_ports[ctl_port_idx(ctsio->io_hdr.nexus.targ_port)];
cdb = (struct scsi_populate_token *)ctsio->cdb;
len = scsi_4btoul(cdb->length);
@@ -1944,9 +1947,9 @@ ctl_populate_token(struct ctl_scsiio *ctsio)
list->curseg = 0;
list->completed = 1;
list->last_active = time_uptime;
- mtx_lock(&control_softc->ctl_lock);
- TAILQ_INSERT_TAIL(&control_softc->tpc_tokens, token, links);
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_lock(&softc->ctl_lock);
+ TAILQ_INSERT_TAIL(&softc->tpc_tokens, token, links);
+ mtx_unlock(&softc->ctl_lock);
ctl_set_success(ctsio);
ctl_done((union ctl_io *)ctsio);
return (CTL_RETVAL_COMPLETE);
@@ -1965,6 +1968,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio)
{
struct scsi_write_using_token *cdb;
struct scsi_write_using_token_data *data;
+ struct ctl_softc *softc;
struct ctl_lun *lun;
struct tpc_list *list, *tlist;
struct tpc_token *token;
@@ -1973,6 +1977,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio)
CTL_DEBUG_PRINT(("ctl_write_using_token\n"));
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ softc = lun->ctl_softc;
cdb = (struct scsi_write_using_token *)ctsio->cdb;
len = scsi_4btoul(cdb->length);
@@ -2051,8 +2056,8 @@ ctl_write_using_token(struct ctl_scsiio *ctsio)
return (CTL_RETVAL_COMPLETE);
}
- mtx_lock(&control_softc->ctl_lock);
- TAILQ_FOREACH(token, &control_softc->tpc_tokens, links) {
+ mtx_lock(&softc->ctl_lock);
+ TAILQ_FOREACH(token, &softc->tpc_tokens, links) {
if (memcmp(token->token, data->rod_token,
sizeof(data->rod_token)) == 0)
break;
@@ -2063,7 +2068,7 @@ ctl_write_using_token(struct ctl_scsiio *ctsio)
if (data->flags & EC_WUT_DEL_TKN)
token->timeout = 0;
}
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
if (token == NULL) {
mtx_lock(&lun->lun_lock);
TAILQ_REMOVE(&lun->tpc_lists, list, links);
@@ -2188,6 +2193,7 @@ ctl_receive_rod_token_information(struct ctl_scsiio *ctsio)
int
ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
{
+ struct ctl_softc *softc;
struct ctl_lun *lun;
struct scsi_report_all_rod_tokens *cdb;
struct scsi_report_all_rod_tokens_data *data;
@@ -2199,14 +2205,15 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
cdb = (struct scsi_report_all_rod_tokens *)ctsio->cdb;
lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
+ softc = lun->ctl_softc;
retval = CTL_RETVAL_COMPLETE;
tokens = 0;
- mtx_lock(&control_softc->ctl_lock);
- TAILQ_FOREACH(token, &control_softc->tpc_tokens, links)
+ mtx_lock(&softc->ctl_lock);
+ TAILQ_FOREACH(token, &softc->tpc_tokens, links)
tokens++;
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
if (tokens > 512)
tokens = 512;
@@ -2231,15 +2238,15 @@ ctl_report_all_rod_tokens(struct ctl_scsiio *ctsio)
data = (struct scsi_report_all_rod_tokens_data *)ctsio->kern_data_ptr;
i = 0;
- mtx_lock(&control_softc->ctl_lock);
- TAILQ_FOREACH(token, &control_softc->tpc_tokens, links) {
+ mtx_lock(&softc->ctl_lock);
+ TAILQ_FOREACH(token, &softc->tpc_tokens, links) {
if (i >= tokens)
break;
memcpy(&data->rod_management_token_list[i * 96],
token->token, 96);
i++;
}
- mtx_unlock(&control_softc->ctl_lock);
+ mtx_unlock(&softc->ctl_lock);
scsi_ulto4b(sizeof(*data) - 4 + i * 96, data->available_data);
/*
printf("RART tokens=%d\n", i);
diff --git a/sys/cam/ctl/ctl_tpc.h b/sys/cam/ctl/ctl_tpc.h
index ecbaec1..ffdab5a 100644
--- a/sys/cam/ctl/ctl_tpc.h
+++ b/sys/cam/ctl/ctl_tpc.h
@@ -31,7 +31,8 @@
void tpc_done(union ctl_io *io);
-uint64_t tpcl_resolve(int init_port, struct scsi_ec_cscd *cscd, uint32_t *ss);
+uint64_t tpcl_resolve(struct ctl_softc *softc, int init_port,
+ struct scsi_ec_cscd *cscd, uint32_t *ss);
union ctl_io * tpcl_alloc_io(void);
int tpcl_queue(union ctl_io *io, uint64_t lun);
diff --git a/sys/cam/ctl/ctl_tpc_local.c b/sys/cam/ctl/ctl_tpc_local.c
index 97a5f98..63360fe 100644
--- a/sys/cam/ctl/ctl_tpc_local.c
+++ b/sys/cam/ctl/ctl_tpc_local.c
@@ -63,7 +63,6 @@ struct tpcl_softc {
int cur_tag_num;
};
-extern struct ctl_softc *control_softc;
static struct tpcl_softc tpcl_softc;
static int tpcl_init(void);
@@ -309,9 +308,9 @@ tpcl_done(union ctl_io *io)
}
uint64_t
-tpcl_resolve(int init_port, struct scsi_ec_cscd *cscd, uint32_t *ss)
+tpcl_resolve(struct ctl_softc *softc, int init_port,
+ struct scsi_ec_cscd *cscd, uint32_t *ss)
{
- struct ctl_softc *softc = control_softc;
struct scsi_ec_cscd_id *cscdid;
struct ctl_port *port;
struct ctl_lun *lun;
diff --git a/sys/cam/ctl/scsi_ctl.c b/sys/cam/ctl/scsi_ctl.c
index a1f39d2..b1dba8c 100644
--- a/sys/cam/ctl/scsi_ctl.c
+++ b/sys/cam/ctl/scsi_ctl.c
@@ -228,8 +228,6 @@ static struct ctl_frontend ctlfe_frontend =
};
CTL_FRONTEND_DECLARE(ctlfe, ctlfe_frontend);
-extern struct ctl_softc *control_softc;
-
void
ctlfeshutdown(void)
{
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 66552c3..665165a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c
@@ -81,16 +81,14 @@ dbuf_compare(const void *x1, const void *x2)
return (1);
}
- if (d1->db_state < d2->db_state) {
+ if (d1->db_state == DB_SEARCH) {
+ ASSERT3S(d2->db_state, !=, DB_SEARCH);
return (-1);
- }
- if (d1->db_state > d2->db_state) {
+ } else if (d2->db_state == DB_SEARCH) {
+ ASSERT3S(d1->db_state, !=, DB_SEARCH);
return (1);
}
- ASSERT3S(d1->db_state, !=, DB_SEARCH);
- ASSERT3S(d2->db_state, !=, DB_SEARCH);
-
if ((uintptr_t)d1 < (uintptr_t)d2) {
return (-1);
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
index 2d0cf23..c4ee741 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c
@@ -536,8 +536,7 @@ spa_config_update(spa_t *spa, int what)
/*
* Update the global config cache to reflect the new mosconfig.
*/
- if (!spa->spa_is_root)
- spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL);
+ spa_config_sync(spa, B_FALSE, what != SPA_CONFIG_UPDATE_POOL);
if (what == SPA_CONFIG_UPDATE_POOL)
spa_config_update(spa, SPA_CONFIG_UPDATE_VDEVS);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
index 52b8f30..75c6b37 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zvol.h
@@ -43,7 +43,7 @@ extern void zvol_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
extern int zvol_create_minor(const char *);
extern int zvol_remove_minor(const char *);
extern void zvol_remove_minors(const char *);
-extern int zvol_set_volsize(const char *, major_t, uint64_t);
+extern int zvol_set_volsize(const char *, uint64_t);
#ifdef sun
extern int zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr);
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 d730083..383b789 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
@@ -2482,8 +2482,7 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
err = dsl_dataset_set_refreservation(dsname, source, intval);
break;
case ZFS_PROP_VOLSIZE:
- err = zvol_set_volsize(dsname, ddi_driver_major(zfs_dip),
- intval);
+ err = zvol_set_volsize(dsname, intval);
break;
case ZFS_PROP_VERSION:
{
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 5d7fa70..9b11652 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
@@ -6180,15 +6180,20 @@ zfs_freebsd_create(ap)
{
struct componentname *cnp = ap->a_cnp;
vattr_t *vap = ap->a_vap;
- int mode;
+ int error, mode;
ASSERT(cnp->cn_flags & SAVENAME);
vattr_init_mask(vap);
mode = vap->va_mode & ALLPERMS;
- return (zfs_create(ap->a_dvp, cnp->cn_nameptr, vap, !EXCL, mode,
- ap->a_vpp, cnp->cn_cred, cnp->cn_thread));
+ error = zfs_create(ap->a_dvp, cnp->cn_nameptr, vap, !EXCL, mode,
+ ap->a_vpp, cnp->cn_cred, cnp->cn_thread);
+#ifdef FREEBSD_NAMECACHE
+ if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0)
+ cache_enter(ap->a_dvp, *ap->a_vpp, cnp);
+#endif
+ return (error);
}
static int
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 3925e90..afda3e4 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
@@ -704,18 +704,20 @@ zfs_blkptr_verify(spa_t *spa, const blkptr_t *bp)
zfs_panic_recover("blkptr at %p DVA %u has invalid "
"VDEV %llu",
bp, i, (longlong_t)vdevid);
+ continue;
}
vdev_t *vd = spa->spa_root_vdev->vdev_child[vdevid];
if (vd == NULL) {
zfs_panic_recover("blkptr at %p DVA %u has invalid "
"VDEV %llu",
bp, i, (longlong_t)vdevid);
+ continue;
}
if (vd->vdev_ops == &vdev_hole_ops) {
zfs_panic_recover("blkptr at %p DVA %u has hole "
"VDEV %llu",
bp, i, (longlong_t)vdevid);
-
+ continue;
}
if (vd->vdev_ops == &vdev_missing_ops) {
/*
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 260822c..f9cc3eb 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -97,6 +97,7 @@
#include "zfs_namecheck.h"
+#ifndef illumos
struct g_class zfs_zvol_class = {
.name = "ZFS::ZVOL",
.version = G_VERSION,
@@ -104,25 +105,37 @@ struct g_class zfs_zvol_class = {
DECLARE_GEOM_CLASS(zfs_zvol_class, zfs_zvol);
+#endif
void *zfsdev_state;
static char *zvol_tag = "zvol_tag";
#define ZVOL_DUMPSIZE "dumpsize"
/*
- * The spa_namespace_lock protects the zfsdev_state structure from being
- * modified while it's being used, e.g. an open that comes in before a
- * create finishes. It also protects temporary opens of the dataset so that,
+ * This lock protects the zfsdev_state structure from being modified
+ * while it's being used, e.g. an open that comes in before a create
+ * finishes. It also protects temporary opens of the dataset so that,
* e.g., an open doesn't get a spurious EBUSY.
*/
+#ifdef illumos
+kmutex_t zfsdev_state_lock;
+#else
+/*
+ * In FreeBSD we've replaced the upstream zfsdev_state_lock with the
+ * spa_namespace_lock in the ZVOL code.
+ */
+#define zfsdev_state_lock spa_namespace_lock
+#endif
static uint32_t zvol_minors;
+#ifndef illumos
SYSCTL_DECL(_vfs_zfs);
SYSCTL_NODE(_vfs_zfs, OID_AUTO, vol, CTLFLAG_RW, 0, "ZFS VOLUME");
static int volmode = ZFS_VOLMODE_GEOM;
SYSCTL_INT(_vfs_zfs_vol, OID_AUTO, mode, CTLFLAG_RWTUN, &volmode, 0,
"Expose as GEOM providers (1), device files (2) or neither");
+#endif
typedef struct zvol_extent {
list_node_t ze_node;
dva_t ze_dva; /* dva associated with this extent */
@@ -133,28 +146,40 @@ typedef struct zvol_extent {
* The in-core state of each volume.
*/
typedef struct zvol_state {
+#ifndef illumos
LIST_ENTRY(zvol_state) zv_links;
+#endif
char zv_name[MAXPATHLEN]; /* pool/dd name */
uint64_t zv_volsize; /* amount of space we advertise */
uint64_t zv_volblocksize; /* volume block size */
+#ifdef illumos
+ minor_t zv_minor; /* minor number */
+#else
struct cdev *zv_dev; /* non-GEOM device */
struct g_provider *zv_provider; /* GEOM provider */
+#endif
uint8_t zv_min_bs; /* minimum addressable block shift */
uint8_t zv_flags; /* readonly, dumpified, etc. */
objset_t *zv_objset; /* objset handle */
+#ifdef illumos
+ uint32_t zv_open_count[OTYPCNT]; /* open counts */
+#endif
uint32_t zv_total_opens; /* total open count */
zilog_t *zv_zilog; /* ZIL handle */
list_t zv_extents; /* List of extents for dump */
znode_t zv_znode; /* for range locking */
dmu_buf_t *zv_dbuf; /* bonus handle */
+#ifndef illumos
int zv_state;
int zv_volmode; /* Provide GEOM or cdev */
struct bio_queue_head zv_queue;
struct mtx zv_queue_mtx; /* zv_queue mutex */
+#endif
} zvol_state_t;
+#ifndef illumos
static LIST_HEAD(, zvol_state) all_zvols;
-
+#endif
/*
* zvol specific flags
*/
@@ -172,6 +197,7 @@ int zvol_maxphys = DMU_MAX_ACCESS/2;
* Toggle unmap functionality.
*/
boolean_t zvol_unmap_enabled = B_TRUE;
+#ifndef illumos
SYSCTL_INT(_vfs_zfs_vol, OID_AUTO, unmap_enabled, CTLFLAG_RWTUN,
&zvol_unmap_enabled, 0,
"Enable UNMAP functionality");
@@ -195,28 +221,30 @@ static struct cdevsw zvol_cdevsw = {
.d_flags = D_DISK | D_TRACKCLOSE,
};
-extern int zfs_set_prop_nvlist(const char *, zprop_source_t,
- nvlist_t *, nvlist_t *);
+static void zvol_geom_run(zvol_state_t *zv);
+static void zvol_geom_destroy(zvol_state_t *zv);
+static int zvol_geom_access(struct g_provider *pp, int acr, int acw, int ace);
+static void zvol_geom_start(struct bio *bp);
+static void zvol_geom_worker(void *arg);
static void zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off,
uint64_t len, boolean_t sync);
+#endif /* !illumos */
+
+extern int zfs_set_prop_nvlist(const char *, zprop_source_t,
+ nvlist_t *, nvlist_t *);
static int zvol_remove_zv(zvol_state_t *);
static int zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio);
static int zvol_dumpify(zvol_state_t *zv);
static int zvol_dump_fini(zvol_state_t *zv);
static int zvol_dump_init(zvol_state_t *zv, boolean_t resize);
-static void zvol_geom_run(zvol_state_t *zv);
-static void zvol_geom_destroy(zvol_state_t *zv);
-static int zvol_geom_access(struct g_provider *pp, int acr, int acw, int ace);
-static void zvol_geom_start(struct bio *bp);
-static void zvol_geom_worker(void *arg);
-
static void
-zvol_size_changed(zvol_state_t *zv)
+zvol_size_changed(zvol_state_t *zv, uint64_t volsize)
{
-#ifdef sun
- dev_t dev = makedevice(maj, min);
+#ifdef illumos
+ dev_t dev = makedevice(ddi_driver_major(zfs_dip), zv->zv_minor);
+ zv->zv_volsize = volsize;
VERIFY(ddi_prop_update_int64(dev, zfs_dip,
"Size", volsize) == DDI_SUCCESS);
VERIFY(ddi_prop_update_int64(dev, zfs_dip,
@@ -225,7 +253,8 @@ zvol_size_changed(zvol_state_t *zv)
/* Notify specfs to invalidate the cached size */
spec_size_invalidate(dev, VBLK);
spec_size_invalidate(dev, VCHR);
-#else /* !sun */
+#else /* !illumos */
+ zv->zv_volsize = volsize;
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) {
struct g_provider *pp;
@@ -236,7 +265,7 @@ zvol_size_changed(zvol_state_t *zv)
g_resize_provider(pp, zv->zv_volsize);
g_topology_unlock();
}
-#endif /* !sun */
+#endif /* illumos */
}
int
@@ -292,16 +321,26 @@ zvol_get_stats(objset_t *os, nvlist_t *nv)
static zvol_state_t *
zvol_minor_lookup(const char *name)
{
+#ifdef illumos
+ minor_t minor;
+#endif
zvol_state_t *zv;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
+#ifdef illumos
+ for (minor = 1; minor <= ZFSDEV_MAX_MINOR; minor++) {
+ zv = zfsdev_get_soft_state(minor, ZSST_ZVOL);
+ if (zv == NULL)
+ continue;
+#else
LIST_FOREACH(zv, &all_zvols, zv_links) {
+#endif
if (strcmp(zv->zv_name, name) == 0)
- break;
+ return (zv);
}
- return (zv);
+ return (NULL);
}
/* extent mapping arg */
@@ -517,20 +556,20 @@ zil_replay_func_t *zvol_replay_vector[TX_MAX_TYPE] = {
zvol_replay_err, /* TX_WRITE2 */
};
-#ifdef sun
+#ifdef illumos
int
zvol_name2minor(const char *name, minor_t *minor)
{
zvol_state_t *zv;
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
zv = zvol_minor_lookup(name);
if (minor && zv)
*minor = zv->zv_minor;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (zv ? 0 : -1);
}
-#endif /* sun */
+#endif /* illumos */
/*
* Create a minor node (plus a whole lot more) for the specified volume.
@@ -541,19 +580,26 @@ zvol_create_minor(const char *name)
zfs_soft_state_t *zs;
zvol_state_t *zv;
objset_t *os;
+ dmu_object_info_t doi;
+#ifdef illumos
+ minor_t minor = 0;
+ char chrbuf[30], blkbuf[30];
+#else
struct cdev *dev;
struct g_provider *pp;
struct g_geom *gp;
- dmu_object_info_t doi;
uint64_t volsize, mode;
+#endif
int error;
+#ifndef illumos
ZFS_LOG(1, "Creating ZVOL %s...", name);
+#endif
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
if (zvol_minor_lookup(name) != NULL) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(EEXIST));
}
@@ -561,20 +607,20 @@ zvol_create_minor(const char *name)
error = dmu_objset_own(name, DMU_OST_ZVOL, B_TRUE, FTAG, &os);
if (error) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (error);
}
-#ifdef sun
+#ifdef illumos
if ((minor = zfsdev_minor_alloc()) == 0) {
dmu_objset_disown(os, FTAG);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(ENXIO));
}
if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS) {
dmu_objset_disown(os, FTAG);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(EAGAIN));
}
(void) ddi_prop_update_string(minor, zfs_dip, ZVOL_PROP_NAME,
@@ -586,7 +632,7 @@ zvol_create_minor(const char *name)
minor, DDI_PSEUDO, 0) == DDI_FAILURE) {
ddi_soft_state_free(zfsdev_state, minor);
dmu_objset_disown(os, FTAG);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(EAGAIN));
}
@@ -597,14 +643,14 @@ zvol_create_minor(const char *name)
ddi_remove_minor_node(zfs_dip, chrbuf);
ddi_soft_state_free(zfsdev_state, minor);
dmu_objset_disown(os, FTAG);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(EAGAIN));
}
zs = ddi_get_soft_state(zfsdev_state, minor);
zs->zss_type = ZSST_ZVOL;
zv = zs->zss_data = kmem_zalloc(sizeof (zvol_state_t), KM_SLEEP);
-#else /* !sun */
+#else /* !illumos */
zv = kmem_zalloc(sizeof(*zv), KM_SLEEP);
zv->zv_state = 0;
@@ -612,7 +658,7 @@ zvol_create_minor(const char *name)
if (error) {
kmem_free(zv, sizeof(*zv));
dmu_objset_disown(os, zvol_tag);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (error);
}
error = dsl_prop_get_integer(name,
@@ -643,7 +689,7 @@ zvol_create_minor(const char *name)
0640, "%s/%s", ZVOL_DRIVER, name) != 0) {
kmem_free(zv, sizeof(*zv));
dmu_objset_disown(os, FTAG);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(ENXIO));
}
zv->zv_dev = dev;
@@ -651,10 +697,13 @@ zvol_create_minor(const char *name)
dev->si_drv2 = zv;
}
LIST_INSERT_HEAD(&all_zvols, zv, zv_links);
-#endif /* !sun */
+#endif /* illumos */
(void) strlcpy(zv->zv_name, name, MAXPATHLEN);
zv->zv_min_bs = DEV_BSHIFT;
+#ifdef illumos
+ zv->zv_minor = minor;
+#endif
zv->zv_objset = os;
if (dmu_objset_is_snapshot(os) || !spa_writeable(dmu_objset_spa(os)))
zv->zv_flags |= ZVOL_RDONLY;
@@ -679,17 +728,16 @@ zvol_create_minor(const char *name)
zvol_minors++;
- mutex_exit(&spa_namespace_lock);
-
-#ifndef sun
+ mutex_exit(&zfsdev_state_lock);
+#ifndef illumos
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) {
zvol_geom_run(zv);
g_topology_unlock();
}
PICKUP_GIANT();
-#endif
ZFS_LOG(1, "ZVOL %s created.", name);
+#endif
return (0);
}
@@ -700,20 +748,24 @@ zvol_create_minor(const char *name)
static int
zvol_remove_zv(zvol_state_t *zv)
{
-#ifdef sun
+#ifdef illumos
+ char nmbuf[20];
minor_t minor = zv->zv_minor;
#endif
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
if (zv->zv_total_opens != 0)
return (SET_ERROR(EBUSY));
- ZFS_LOG(1, "ZVOL %s destroyed.", zv->zv_name);
-
-#ifdef sun
+#ifdef illumos
(void) snprintf(nmbuf, sizeof (nmbuf), "%u,raw", minor);
ddi_remove_minor_node(zfs_dip, nmbuf);
+
+ (void) snprintf(nmbuf, sizeof (nmbuf), "%u", minor);
+ ddi_remove_minor_node(zfs_dip, nmbuf);
#else
+ ZFS_LOG(1, "ZVOL %s destroyed.", zv->zv_name);
+
LIST_REMOVE(zv, zv_links);
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) {
g_topology_lock();
@@ -721,13 +773,15 @@ zvol_remove_zv(zvol_state_t *zv)
g_topology_unlock();
} else if (zv->zv_volmode == ZFS_VOLMODE_DEV)
destroy_dev(zv->zv_dev);
-#endif /* sun */
+#endif
avl_destroy(&zv->zv_znode.z_range_avl);
mutex_destroy(&zv->zv_znode.z_range_lock);
- kmem_free(zv, sizeof(*zv));
-
+ kmem_free(zv, sizeof (zvol_state_t));
+#ifdef illumos
+ ddi_soft_state_free(zfsdev_state, minor);
+#endif
zvol_minors--;
return (0);
}
@@ -738,13 +792,13 @@ zvol_remove_minor(const char *name)
zvol_state_t *zv;
int rc;
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
if ((zv = zvol_minor_lookup(name)) == NULL) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(ENXIO));
}
rc = zvol_remove_zv(zv);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (rc);
}
@@ -762,21 +816,22 @@ zvol_first_open(zvol_state_t *zv)
if (error)
return (error);
+ zv->zv_objset = os;
error = zap_lookup(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize);
if (error) {
ASSERT(error == 0);
dmu_objset_disown(os, zvol_tag);
return (error);
}
- zv->zv_objset = os;
+
error = dmu_bonus_hold(os, ZVOL_OBJ, zvol_tag, &zv->zv_dbuf);
if (error) {
dmu_objset_disown(os, zvol_tag);
return (error);
}
- zv->zv_volsize = volsize;
+
+ zvol_size_changed(zv, volsize);
zv->zv_zilog = zil_open(os, zvol_get_data);
- zvol_size_changed(zv);
VERIFY(dsl_prop_get_integer(zv->zv_name, "readonly", &readonly,
NULL) == 0);
@@ -809,7 +864,7 @@ zvol_last_close(zvol_state_t *zv)
zv->zv_objset = NULL;
}
-#ifdef sun
+#ifdef illumos
int
zvol_prealloc(zvol_state_t *zv)
{
@@ -848,7 +903,7 @@ zvol_prealloc(zvol_state_t *zv)
return (0);
}
-#endif /* sun */
+#endif /* illumos */
static int
zvol_update_volsize(objset_t *os, uint64_t volsize)
@@ -856,7 +911,7 @@ zvol_update_volsize(objset_t *os, uint64_t volsize)
dmu_tx_t *tx;
int error;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
tx = dmu_tx_create(os);
dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL);
@@ -880,13 +935,34 @@ zvol_update_volsize(objset_t *os, uint64_t volsize)
void
zvol_remove_minors(const char *name)
{
+#ifdef illumos
+ zvol_state_t *zv;
+ char *namebuf;
+ minor_t minor;
+
+ namebuf = kmem_zalloc(strlen(name) + 2, KM_SLEEP);
+ (void) strncpy(namebuf, name, strlen(name));
+ (void) strcat(namebuf, "/");
+ mutex_enter(&zfsdev_state_lock);
+ for (minor = 1; minor <= ZFSDEV_MAX_MINOR; minor++) {
+
+ zv = zfsdev_get_soft_state(minor, ZSST_ZVOL);
+ if (zv == NULL)
+ continue;
+ if (strncmp(namebuf, zv->zv_name, strlen(namebuf)) == 0)
+ (void) zvol_remove_zv(zv);
+ }
+ kmem_free(namebuf, strlen(name) + 2);
+
+ mutex_exit(&zfsdev_state_lock);
+#else /* !illumos */
zvol_state_t *zv, *tzv;
size_t namelen;
namelen = strlen(name);
DROP_GIANT();
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
LIST_FOREACH_SAFE(zv, &all_zvols, zv_links, tzv) {
if (strcmp(zv->zv_name, name) == 0 ||
@@ -897,69 +973,48 @@ zvol_remove_minors(const char *name)
}
}
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
PICKUP_GIANT();
+#endif /* illumos */
}
-int
-zvol_set_volsize(const char *name, major_t maj, uint64_t volsize)
+static int
+zvol_update_live_volsize(zvol_state_t *zv, uint64_t volsize)
{
- zvol_state_t *zv = NULL;
- objset_t *os;
- int error;
- dmu_object_info_t doi;
uint64_t old_volsize = 0ULL;
- uint64_t readonly;
-
- mutex_enter(&spa_namespace_lock);
- zv = zvol_minor_lookup(name);
- if ((error = dmu_objset_hold(name, FTAG, &os)) != 0) {
- mutex_exit(&spa_namespace_lock);
- return (error);
- }
+ int error = 0;
- if ((error = dmu_object_info(os, ZVOL_OBJ, &doi)) != 0 ||
- (error = zvol_check_volsize(volsize,
- doi.doi_data_block_size)) != 0)
- goto out;
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
- VERIFY(dsl_prop_get_integer(name, "readonly", &readonly,
- NULL) == 0);
- if (readonly) {
- error = EROFS;
- goto out;
- }
-
- error = zvol_update_volsize(os, volsize);
/*
* Reinitialize the dump area to the new size. If we
* failed to resize the dump area then restore it back to
- * its original size.
+ * its original size. We must set the new volsize prior
+ * to calling dumpvp_resize() to ensure that the devices'
+ * size(9P) is not visible by the dump subsystem.
*/
- if (zv && error == 0) {
+ old_volsize = zv->zv_volsize;
+ zvol_size_changed(zv, volsize);
+
#ifdef ZVOL_DUMP
- if (zv->zv_flags & ZVOL_DUMPIFIED) {
- old_volsize = zv->zv_volsize;
- zv->zv_volsize = volsize;
- if ((error = zvol_dumpify(zv)) != 0 ||
- (error = dumpvp_resize()) != 0) {
- (void) zvol_update_volsize(os, old_volsize);
- zv->zv_volsize = old_volsize;
- error = zvol_dumpify(zv);
- }
- }
-#endif /* ZVOL_DUMP */
- if (error == 0) {
- zv->zv_volsize = volsize;
- zvol_size_changed(zv);
+ if (zv->zv_flags & ZVOL_DUMPIFIED) {
+ if ((error = zvol_dumpify(zv)) != 0 ||
+ (error = dumpvp_resize()) != 0) {
+ int dumpify_error;
+
+ (void) zvol_update_volsize(zv->zv_objset, old_volsize);
+ zvol_size_changed(zv, old_volsize);
+ dumpify_error = zvol_dumpify(zv);
+ error = dumpify_error ? dumpify_error : error;
}
}
+#endif /* ZVOL_DUMP */
-#ifdef sun
+#ifdef illumos
/*
* Generate a LUN expansion event.
*/
- if (zv && error == 0) {
+ if (error == 0) {
sysevent_id_t eid;
nvlist_t *attr;
char *physpath = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
@@ -976,22 +1031,89 @@ zvol_set_volsize(const char *name, major_t maj, uint64_t volsize)
nvlist_free(attr);
kmem_free(physpath, MAXPATHLEN);
}
-#endif /* sun */
+#endif /* illumos */
+ return (error);
+}
-out:
- dmu_objset_rele(os, FTAG);
+int
+zvol_set_volsize(const char *name, uint64_t volsize)
+{
+ zvol_state_t *zv = NULL;
+ objset_t *os;
+ int error;
+ dmu_object_info_t doi;
+ uint64_t readonly;
+ boolean_t owned = B_FALSE;
+
+ error = dsl_prop_get_integer(name,
+ zfs_prop_to_name(ZFS_PROP_READONLY), &readonly, NULL);
+ if (error != 0)
+ return (error);
+ if (readonly)
+ return (SET_ERROR(EROFS));
+
+ mutex_enter(&zfsdev_state_lock);
+ zv = zvol_minor_lookup(name);
+
+ if (zv == NULL || zv->zv_objset == NULL) {
+ if ((error = dmu_objset_own(name, DMU_OST_ZVOL, B_FALSE,
+ FTAG, &os)) != 0) {
+ mutex_exit(&zfsdev_state_lock);
+ return (error);
+ }
+ owned = B_TRUE;
+ if (zv != NULL)
+ zv->zv_objset = os;
+ } else {
+ os = zv->zv_objset;
+ }
+
+ if ((error = dmu_object_info(os, ZVOL_OBJ, &doi)) != 0 ||
+ (error = zvol_check_volsize(volsize, doi.doi_data_block_size)) != 0)
+ goto out;
- mutex_exit(&spa_namespace_lock);
+ error = zvol_update_volsize(os, volsize);
+ if (error == 0 && zv != NULL)
+ error = zvol_update_live_volsize(zv, volsize);
+out:
+ if (owned) {
+ dmu_objset_disown(os, FTAG);
+ if (zv != NULL)
+ zv->zv_objset = NULL;
+ }
+ mutex_exit(&zfsdev_state_lock);
return (error);
}
/*ARGSUSED*/
+#ifdef illumos
+int
+zvol_open(dev_t *devp, int flag, int otyp, cred_t *cr)
+#else
static int
zvol_open(struct g_provider *pp, int flag, int count)
+#endif
{
zvol_state_t *zv;
int err = 0;
+#ifdef illumos
+
+ mutex_enter(&zfsdev_state_lock);
+
+ zv = zfsdev_get_soft_state(getminor(*devp), ZSST_ZVOL);
+ if (zv == NULL) {
+ mutex_exit(&zfsdev_state_lock);
+ return (SET_ERROR(ENXIO));
+ }
+
+ if (zv->zv_total_opens == 0)
+ err = zvol_first_open(zv);
+ if (err) {
+ mutex_exit(&zfsdev_state_lock);
+ return (err);
+ }
+#else /* !illumos */
boolean_t locked = B_FALSE;
/*
@@ -1005,15 +1127,15 @@ zvol_open(struct g_provider *pp, int flag, int count)
* recursively, but that function already has all the
* necessary protection.
*/
- if (!MUTEX_HELD(&spa_namespace_lock)) {
- mutex_enter(&spa_namespace_lock);
+ if (!MUTEX_HELD(&zfsdev_state_lock)) {
+ mutex_enter(&zfsdev_state_lock);
locked = B_TRUE;
}
zv = pp->private;
if (zv == NULL) {
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(ENXIO));
}
@@ -1021,13 +1143,14 @@ zvol_open(struct g_provider *pp, int flag, int count)
err = zvol_first_open(zv);
if (err) {
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (err);
}
pp->mediasize = zv->zv_volsize;
pp->stripeoffset = 0;
pp->stripesize = zv->zv_volblocksize;
}
+#endif /* illumos */
if ((flag & FWRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
err = SET_ERROR(EROFS);
goto out;
@@ -1046,20 +1169,46 @@ zvol_open(struct g_provider *pp, int flag, int count)
}
#endif
+#ifdef illumos
+ if (zv->zv_open_count[otyp] == 0 || otyp == OTYP_LYR) {
+ zv->zv_open_count[otyp]++;
+ zv->zv_total_opens++;
+ }
+ mutex_exit(&zfsdev_state_lock);
+#else
zv->zv_total_opens += count;
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
+#endif
return (err);
out:
if (zv->zv_total_opens == 0)
zvol_last_close(zv);
+#ifdef illumos
+ mutex_exit(&zfsdev_state_lock);
+#else
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
+#endif
return (err);
}
/*ARGSUSED*/
+#ifdef illumos
+int
+zvol_close(dev_t dev, int flag, int otyp, cred_t *cr)
+{
+ minor_t minor = getminor(dev);
+ zvol_state_t *zv;
+ int error = 0;
+
+ mutex_enter(&zfsdev_state_lock);
+
+ zv = zfsdev_get_soft_state(minor, ZSST_ZVOL);
+ if (zv == NULL) {
+ mutex_exit(&zfsdev_state_lock);
+#else /* !illumos */
static int
zvol_close(struct g_provider *pp, int flag, int count)
{
@@ -1068,15 +1217,16 @@ zvol_close(struct g_provider *pp, int flag, int count)
boolean_t locked = B_FALSE;
/* See comment in zvol_open(). */
- if (!MUTEX_HELD(&spa_namespace_lock)) {
- mutex_enter(&spa_namespace_lock);
+ if (!MUTEX_HELD(&zfsdev_state_lock)) {
+ mutex_enter(&zfsdev_state_lock);
locked = B_TRUE;
}
zv = pp->private;
if (zv == NULL) {
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
+#endif /* illumos */
return (SET_ERROR(ENXIO));
}
@@ -1089,18 +1239,30 @@ zvol_close(struct g_provider *pp, int flag, int count)
* If the open count is zero, this is a spurious close.
* That indicates a bug in the kernel / DDI framework.
*/
+#ifdef illumos
+ ASSERT(zv->zv_open_count[otyp] != 0);
+#endif
ASSERT(zv->zv_total_opens != 0);
/*
* You may get multiple opens, but only one close.
*/
+#ifdef illumos
+ zv->zv_open_count[otyp]--;
+ zv->zv_total_opens--;
+#else
zv->zv_total_opens -= count;
+#endif
if (zv->zv_total_opens == 0)
zvol_last_close(zv);
+#ifdef illumos
+ mutex_exit(&zfsdev_state_lock);
+#else
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
+#endif
return (error);
}
@@ -1260,7 +1422,7 @@ zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid,
}
}
-#ifdef sun
+#ifdef illumos
static int
zvol_dumpio_vdev(vdev_t *vd, void *addr, uint64_t offset, uint64_t origoffset,
uint64_t size, boolean_t doread, boolean_t isdump)
@@ -1353,11 +1515,16 @@ zvol_dumpio(zvol_state_t *zv, void *addr, uint64_t offset, uint64_t size,
return (error);
}
-#endif /* sun */
+int
+zvol_strategy(buf_t *bp)
+{
+ zfs_soft_state_t *zs = NULL;
+#else /* !illumos */
void
zvol_strategy(struct bio *bp)
{
+#endif /* illumos */
zvol_state_t *zv;
uint64_t off, volsize;
size_t resid;
@@ -1365,22 +1532,53 @@ zvol_strategy(struct bio *bp)
objset_t *os;
rl_t *rl;
int error = 0;
+#ifdef illumos
+ boolean_t doread = bp->b_flags & B_READ;
+#else
boolean_t doread = 0;
+#endif
boolean_t is_dumpified;
boolean_t sync;
+#ifdef illumos
+ if (getminor(bp->b_edev) == 0) {
+ error = SET_ERROR(EINVAL);
+ } else {
+ zs = ddi_get_soft_state(zfsdev_state, getminor(bp->b_edev));
+ if (zs == NULL)
+ error = SET_ERROR(ENXIO);
+ else if (zs->zss_type != ZSST_ZVOL)
+ error = SET_ERROR(EINVAL);
+ }
+
+ if (error) {
+ bioerror(bp, error);
+ biodone(bp);
+ return (0);
+ }
+
+ zv = zs->zss_data;
+
+ if (!(bp->b_flags & B_READ) && (zv->zv_flags & ZVOL_RDONLY)) {
+ bioerror(bp, EROFS);
+ biodone(bp);
+ return (0);
+ }
+
+ off = ldbtob(bp->b_blkno);
+#else /* !illumos */
if (bp->bio_to)
zv = bp->bio_to->private;
else
zv = bp->bio_dev->si_drv2;
if (zv == NULL) {
- error = ENXIO;
+ error = SET_ERROR(ENXIO);
goto out;
}
if (bp->bio_cmd != BIO_READ && (zv->zv_flags & ZVOL_RDONLY)) {
- error = EROFS;
+ error = SET_ERROR(EROFS);
goto out;
}
@@ -1398,26 +1596,41 @@ zvol_strategy(struct bio *bp)
}
off = bp->bio_offset;
+#endif /* illumos */
volsize = zv->zv_volsize;
os = zv->zv_objset;
ASSERT(os != NULL);
+#ifdef illumos
+ bp_mapin(bp);
+ addr = bp->b_un.b_addr;
+ resid = bp->b_bcount;
+
+ if (resid > 0 && (off < 0 || off >= volsize)) {
+ bioerror(bp, EIO);
+ biodone(bp);
+ return (0);
+ }
+
+ is_dumpified = zv->zv_flags & ZVOL_DUMPIFIED;
+ sync = ((!(bp->b_flags & B_ASYNC) &&
+ !(zv->zv_flags & ZVOL_WCE)) ||
+ (zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS)) &&
+ !doread && !is_dumpified;
+#else /* !illumos */
addr = bp->bio_data;
resid = bp->bio_length;
if (resid > 0 && (off < 0 || off >= volsize)) {
- error = EIO;
+ error = SET_ERROR(EIO);
goto out;
}
-#ifdef illumos
- is_dumpified = zv->zv_flags & ZVOL_DUMPIFIED;
-#else
is_dumpified = B_FALSE;
-#endif
- sync = !doread && !is_dumpified &&
+ sync = !doread && !is_dumpified &&
zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS;
+#endif /* illumos */
/*
* There must be no buffer changes when doing a dmu_sync() because
@@ -1426,6 +1639,7 @@ zvol_strategy(struct bio *bp)
rl = zfs_range_lock(&zv->zv_znode, off, resid,
doread ? RL_READER : RL_WRITER);
+#ifndef illumos
if (bp->bio_cmd == BIO_DELETE) {
dmu_tx_t *tx = dmu_tx_create(zv->zv_objset);
error = dmu_tx_assign(tx, TXG_WAIT);
@@ -1440,7 +1654,7 @@ zvol_strategy(struct bio *bp)
}
goto unlock;
}
-
+#endif
while (resid != 0 && off < volsize) {
size_t size = MIN(resid, zvol_maxphys);
#ifdef illumos
@@ -1476,9 +1690,21 @@ zvol_strategy(struct bio *bp)
addr += size;
resid -= size;
}
+#ifndef illumos
unlock:
+#endif
zfs_range_unlock(rl);
+#ifdef illumos
+ if ((bp->b_resid = resid) == bp->b_bcount)
+ bioerror(bp, off > volsize ? EINVAL : error);
+
+ if (sync)
+ zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ biodone(bp);
+
+ return (0);
+#else /* !illumos */
bp->bio_completed = bp->bio_length - resid;
if (bp->bio_completed < bp->bio_length && off > volsize)
error = EINVAL;
@@ -1492,9 +1718,10 @@ out:
g_io_deliver(bp, error);
else
biofinish(bp, NULL, error);
+#endif /* illumos */
}
-#ifdef sun
+#ifdef illumos
/*
* Set the buffer count to the zvol maximum transfer.
* Using our own routine instead of the default minphys()
@@ -1550,17 +1777,17 @@ int
zvol_read(dev_t dev, uio_t *uio, cred_t *cr)
{
minor_t minor = getminor(dev);
-#else
+#else /* !illumos */
int
zvol_read(struct cdev *dev, struct uio *uio, int ioflag)
{
-#endif
+#endif /* illumos */
zvol_state_t *zv;
uint64_t volsize;
rl_t *rl;
int error = 0;
-#ifdef sun
+#ifdef illumos
zv = zfsdev_get_soft_state(minor, ZSST_ZVOL);
if (zv == NULL)
return (SET_ERROR(ENXIO));
@@ -1569,6 +1796,7 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag)
#endif
volsize = zv->zv_volsize;
+ /* uio_loffset == volsize isn't an error as its required for EOF processing. */
if (uio->uio_resid > 0 &&
(uio->uio_loffset < 0 || uio->uio_loffset > volsize))
return (SET_ERROR(EIO));
@@ -1602,24 +1830,24 @@ zvol_read(struct cdev *dev, struct uio *uio, int ioflag)
return (error);
}
-#ifdef sun
+#ifdef illumos
/*ARGSUSED*/
int
zvol_write(dev_t dev, uio_t *uio, cred_t *cr)
{
minor_t minor = getminor(dev);
-#else
+#else /* !illumos */
int
zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
{
-#endif
+#endif /* illumos */
zvol_state_t *zv;
uint64_t volsize;
rl_t *rl;
int error = 0;
boolean_t sync;
-#ifdef sun
+#ifdef illumos
zv = zfsdev_get_soft_state(minor, ZSST_ZVOL);
if (zv == NULL)
return (SET_ERROR(ENXIO));
@@ -1628,6 +1856,7 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
#endif
volsize = zv->zv_volsize;
+ /* uio_loffset == volsize isn't an error as its required for EOF processing. */
if (uio->uio_resid > 0 &&
(uio->uio_loffset < 0 || uio->uio_loffset > volsize))
return (SET_ERROR(EIO));
@@ -1638,9 +1867,7 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
zvol_minphys, uio);
return (error);
}
-#endif
-#ifdef sun
sync = !(zv->zv_flags & ZVOL_WCE) ||
#else
sync = (ioflag & IO_SYNC) ||
@@ -1677,7 +1904,7 @@ zvol_write(struct cdev *dev, struct uio *uio, int ioflag)
return (error);
}
-#ifdef sun
+#ifdef illumos
int
zvol_getefi(void *arg, int flag, uint64_t vs, uint8_t bs)
{
@@ -1806,7 +2033,7 @@ zvol_log_write_minor(void *minor_hdl, dmu_tx_t *tx, offset_t off, ssize_t resid,
/*
* END entry points to allow external callers access to the volume.
*/
-#endif /* sun */
+#endif /* illumos */
/*
* Log a DKIOCFREE/free-long-range to the ZIL with TX_TRUNCATE.
@@ -1832,7 +2059,7 @@ zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off, uint64_t len,
zil_itx_assign(zilog, itx, tx);
}
-#ifdef sun
+#ifdef illumos
/*
* Dirtbag ioctls to support mkfs(1M) for UFS filesystems. See dkio(7I).
* Also a dirtbag dkio ioctl for unmap/free-block functionality.
@@ -1846,12 +2073,12 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
int error = 0;
rl_t *rl;
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
zv = zfsdev_get_soft_state(getminor(dev), ZSST_ZVOL);
if (zv == NULL) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (SET_ERROR(ENXIO));
}
ASSERT(zv->zv_total_opens > 0);
@@ -1869,7 +2096,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
dki.dki_unit = getminor(dev);
dki.dki_maxtransfer =
1 << (SPA_OLD_MAXBLOCKSHIFT - zv->zv_min_bs);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
if (ddi_copyout(&dki, (void *)arg, sizeof (dki), flag))
error = SET_ERROR(EFAULT);
return (error);
@@ -1883,7 +2110,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
dkm.dki_lbsize = 1U << zv->zv_min_bs;
dkm.dki_capacity = zv->zv_volsize >> zv->zv_min_bs;
dkm.dki_media_type = DK_UNKNOWN;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
if (ddi_copyout(&dkm, (void *)arg, sizeof (dkm), flag))
error = SET_ERROR(EFAULT);
return (error);
@@ -1898,7 +2125,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
dkmext.dki_pbsize = zv->zv_volblocksize;
dkmext.dki_capacity = zv->zv_volsize >> zv->zv_min_bs;
dkmext.dki_media_type = DK_UNKNOWN;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
if (ddi_copyout(&dkmext, (void *)arg, sizeof (dkmext), flag))
error = SET_ERROR(EFAULT);
return (error);
@@ -1909,14 +2136,14 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
uint64_t vs = zv->zv_volsize;
uint8_t bs = zv->zv_min_bs;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
error = zvol_getefi((void *)arg, flag, vs, bs);
return (error);
}
case DKIOCFLUSHWRITECACHE:
dkc = (struct dk_callback *)arg;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
zil_commit(zv->zv_zilog, ZVOL_OBJ);
if ((flag & FKIOCTL) && dkc != NULL && dkc->dkc_callback) {
(*dkc->dkc_callback)(dkc->dkc_cookie, error);
@@ -1942,10 +2169,10 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
}
if (wce) {
zv->zv_flags |= ZVOL_WCE;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
} else {
zv->zv_flags &= ~ZVOL_WCE;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
zil_commit(zv->zv_zilog, ZVOL_OBJ);
}
return (0);
@@ -1997,7 +2224,7 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
if (df.df_start >= zv->zv_volsize)
break; /* No need to do anything... */
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
rl = zfs_range_lock(&zv->zv_znode, df.df_start, df.df_length,
RL_WRITER);
@@ -2044,10 +2271,10 @@ zvol_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
break;
}
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (error);
}
-#endif /* sun */
+#endif /* illumos */
int
zvol_busy(void)
@@ -2060,17 +2287,24 @@ zvol_init(void)
{
VERIFY(ddi_soft_state_init(&zfsdev_state, sizeof (zfs_soft_state_t),
1) == 0);
+#ifdef illumos
+ mutex_init(&zfsdev_state_lock, NULL, MUTEX_DEFAULT, NULL);
+#else
ZFS_LOG(1, "ZVOL Initialized.");
+#endif
}
void
zvol_fini(void)
{
+#ifdef illumos
+ mutex_destroy(&zfsdev_state_lock);
+#endif
ddi_soft_state_fini(&zfsdev_state);
ZFS_LOG(1, "ZVOL Deinitialized.");
}
-#ifdef sun
+#ifdef illumos
/*ARGSUSED*/
static int
zfs_mvdev_dump_feature_check(void *arg, dmu_tx_t *tx)
@@ -2103,7 +2337,7 @@ zvol_dump_init(zvol_state_t *zv, boolean_t resize)
uint64_t version = spa_version(spa);
enum zio_checksum checksum;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
ASSERT(vd->vdev_ops == &vdev_root_ops);
error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, 0,
@@ -2355,7 +2589,7 @@ zvol_dump_fini(zvol_state_t *zv)
return (0);
}
-#endif /* sun */
+#else /* !illumos */
static void
zvol_geom_run(zvol_state_t *zv)
@@ -2670,7 +2904,7 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname)
struct g_provider *pp;
struct cdev *dev;
- ASSERT(MUTEX_HELD(&spa_namespace_lock));
+ ASSERT(MUTEX_HELD(&zfsdev_state_lock));
if (zv->zv_volmode == ZFS_VOLMODE_GEOM) {
g_topology_lock();
@@ -2723,8 +2957,8 @@ zvol_rename_minors(const char *oldname, const char *newname)
DROP_GIANT();
/* See comment in zvol_open(). */
- if (!MUTEX_HELD(&spa_namespace_lock)) {
- mutex_enter(&spa_namespace_lock);
+ if (!MUTEX_HELD(&zfsdev_state_lock)) {
+ mutex_enter(&zfsdev_state_lock);
locked = B_TRUE;
}
@@ -2742,7 +2976,7 @@ zvol_rename_minors(const char *oldname, const char *newname)
}
if (locked)
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
PICKUP_GIANT();
}
@@ -2752,17 +2986,17 @@ zvol_d_open(struct cdev *dev, int flags, int fmt, struct thread *td)
zvol_state_t *zv;
int err = 0;
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
zv = dev->si_drv2;
if (zv == NULL) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return(ENXIO); /* zvol_create_minor() not done yet */
}
if (zv->zv_total_opens == 0)
err = zvol_first_open(zv);
if (err) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (err);
}
if ((flags & FWRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
@@ -2784,12 +3018,12 @@ zvol_d_open(struct cdev *dev, int flags, int fmt, struct thread *td)
#endif
zv->zv_total_opens++;
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (err);
out:
if (zv->zv_total_opens == 0)
zvol_last_close(zv);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (err);
}
@@ -2799,10 +3033,10 @@ zvol_d_close(struct cdev *dev, int flags, int fmt, struct thread *td)
zvol_state_t *zv;
int err = 0;
- mutex_enter(&spa_namespace_lock);
+ mutex_enter(&zfsdev_state_lock);
zv = dev->si_drv2;
if (zv == NULL) {
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return(ENXIO);
}
@@ -2825,7 +3059,7 @@ zvol_d_close(struct cdev *dev, int flags, int fmt, struct thread *td)
if (zv->zv_total_opens == 0)
zvol_last_close(zv);
- mutex_exit(&spa_namespace_lock);
+ mutex_exit(&zfsdev_state_lock);
return (0);
}
@@ -2933,3 +3167,4 @@ zvol_d_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct threa
return (error);
}
+#endif /* illumos */
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
index c123cc6..805add2 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c
@@ -464,7 +464,7 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c. */
int
-dtrace_trap(struct trapframe *frame)
+dtrace_trap(struct trapframe *frame, u_int type)
{
/*
* A trap can occur while DTrace executes a probe. Before
@@ -480,7 +480,7 @@ dtrace_trap(struct trapframe *frame)
* There are only a couple of trap types that are expected.
* All the rest will be handled in the usual way.
*/
- switch (frame->tf_trapno) {
+ switch (type) {
/* General protection fault. */
case T_PROTFLT:
/* Flag an illegal operation. */
diff --git a/sys/cddl/dev/dtrace/i386/dtrace_subr.c b/sys/cddl/dev/dtrace/i386/dtrace_subr.c
index e620a8f..4073317 100644
--- a/sys/cddl/dev/dtrace/i386/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/i386/dtrace_subr.c
@@ -473,7 +473,7 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See i386/i386/trap.c */
int
-dtrace_trap(struct trapframe *frame)
+dtrace_trap(struct trapframe *frame, u_int type)
{
/*
* A trap can occur while DTrace executes a probe. Before
@@ -489,7 +489,7 @@ dtrace_trap(struct trapframe *frame)
* There are only a couple of trap types that are expected.
* All the rest will be handled in the usual way.
*/
- switch (frame->tf_trapno) {
+ switch (type) {
/* General protection fault. */
case T_PROTFLT:
/* Flag an illegal operation. */
diff --git a/sys/cddl/dev/dtrace/mips/dtrace_subr.c b/sys/cddl/dev/dtrace/mips/dtrace_subr.c
index 5565a61..4f13b98 100644
--- a/sys/cddl/dev/dtrace/mips/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/mips/dtrace_subr.c
@@ -137,11 +137,8 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See amd64/amd64/trap.c */
int
-dtrace_trap(struct trapframe *frame)
+dtrace_trap(struct trapframe *frame, u_int type)
{
- u_int type;
-
- type = (trapframe->cause & MIPS_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
/*
* A trap can occur while DTrace executes a probe. Before
diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
index 5411ece..a89f1d3 100644
--- a/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/powerpc/dtrace_subr.c
@@ -262,8 +262,9 @@ dtrace_gethrestime(void)
/* Function to handle DTrace traps during probes. See powerpc/powerpc/trap.c */
int
-dtrace_trap(struct trapframe *frame)
+dtrace_trap(struct trapframe *frame, u_int type)
{
+
/*
* A trap can occur while DTrace executes a probe. Before
* executing the probe, DTrace blocks re-scheduling and sets
@@ -278,7 +279,7 @@ dtrace_trap(struct trapframe *frame)
* There are only a couple of trap types that are expected.
* All the rest will be handled in the usual way.
*/
- switch (frame->exc) {
+ switch (type) {
/* Page fault. */
case EXC_DSI:
case EXC_DSE:
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 1436a3b..66c1dbc 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1019,7 +1019,7 @@ options DUMMYNET
# One of these is mandatory:
options FFS #Fast filesystem
-options NFSCLIENT #Network File System client
+options NFSCL #Network File System client
# The rest are optional:
options AUTOFS #Automounter filesystem
@@ -1027,7 +1027,6 @@ options CD9660 #ISO 9660 filesystem
options FDESCFS #File descriptor filesystem
options FUSE #FUSE support module
options MSDOSFS #MS DOS File System (FAT, FAT32)
-options NFSSERVER #Network File System server
options NFSLOCKD #Network Lock Manager
options NFSCL #New Network Filesystem Client
options NFSD #New Network Filesystem Server
@@ -1099,8 +1098,6 @@ options NFS_MINATTRTIMO=3 # VREG attrib cache timeout in sec
options NFS_MAXATTRTIMO=60
options NFS_MINDIRATTRTIMO=30 # VDIR attrib cache timeout in sec
options NFS_MAXDIRATTRTIMO=60
-options NFS_GATHERDELAY=10 # Default write gather delay (msec)
-options NFS_WDELAYHASHSIZ=16 # and with this
options NFS_DEBUG # Enable NFS Debugging
#
@@ -2357,19 +2354,6 @@ options SND_PCM_64
options SND_OLDSTEREO
#
-# IEEE-488 hardware:
-# pcii: PCIIA cards (uPD7210 based isa cards)
-# tnt4882: National Instruments PCI-GPIB card.
-
-device pcii
-hint.pcii.0.at="isa"
-hint.pcii.0.port="0x2e1"
-hint.pcii.0.irq="5"
-hint.pcii.0.drq="1"
-
-device tnt4882
-
-#
# Miscellaneous hardware:
#
# scd: Sony CD-ROM using proprietary (non-ATAPI) interface
@@ -2596,7 +2580,7 @@ device pcfclock
# Kernel BOOTP support
options BOOTP # Use BOOTP to obtain IP address/hostname
- # Requires NFSCLIENT and NFS_ROOT
+ # Requires NFSCL and NFS_ROOT
options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info
options BOOTP_NFSV3 # Use NFS v3 to NFS mount root
options BOOTP_COMPAT # Workaround for broken bootp daemons.
@@ -2788,7 +2772,7 @@ options U3G_DEBUG
# options for ukbd:
options UKBD_DFLT_KEYMAP # specify the built-in keymap
-makeoptions UKBD_DFLT_KEYMAP=it.iso
+makeoptions UKBD_DFLT_KEYMAP=jp.pc98
# options for uplcom:
options UPLCOM_INTR_INTERVAL=100 # interrupt pipe interval
diff --git a/sys/conf/files b/sys/conf/files
index 939b635..237390f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1448,10 +1448,6 @@ dev/ida/ida_eisa.c optional ida eisa
dev/ida/ida_pci.c optional ida pci
dev/ie/if_ie.c optional ie isa nowerror
dev/ie/if_ie_isa.c optional ie isa
-dev/ieee488/ibfoo.c optional pcii | tnt4882
-dev/ieee488/pcii.c optional pcii
-dev/ieee488/tnt4882.c optional tnt4882
-dev/ieee488/upd7210.c optional pcii | tnt4882
dev/iicbus/ad7418.c optional ad7418
dev/iicbus/ds133x.c optional ds133x
dev/iicbus/ds1374.c optional ds1374
@@ -3559,24 +3555,12 @@ netsmb/smb_smb.c optional netsmb
netsmb/smb_subr.c optional netsmb
netsmb/smb_trantcp.c optional netsmb
netsmb/smb_usr.c optional netsmb
-nfs/bootp_subr.c optional bootp nfsclient | bootp nfscl
-nfs/krpc_subr.c optional bootp nfsclient | bootp nfscl
-nfs/nfs_common.c optional nfsclient | nfsserver
-nfs/nfs_diskless.c optional nfsclient nfs_root | nfscl nfs_root
-nfs/nfs_fha.c optional nfsserver | nfsd
-nfs/nfs_lock.c optional nfsclient | nfscl | nfslockd | nfsd
-nfsclient/nfs_bio.c optional nfsclient
-nfsclient/nfs_node.c optional nfsclient
-nfsclient/nfs_krpc.c optional nfsclient
-nfsclient/nfs_subs.c optional nfsclient
-nfsclient/nfs_nfsiod.c optional nfsclient
-nfsclient/nfs_vfsops.c optional nfsclient
-nfsclient/nfs_vnops.c optional nfsclient
-nfsserver/nfs_fha_old.c optional nfsserver
-nfsserver/nfs_serv.c optional nfsserver
-nfsserver/nfs_srvkrpc.c optional nfsserver
-nfsserver/nfs_srvsubs.c optional nfsserver
-nfs/nfs_nfssvc.c optional nfsserver | nfscl | nfsd
+nfs/bootp_subr.c optional bootp nfscl
+nfs/krpc_subr.c optional bootp nfscl
+nfs/nfs_diskless.c optional nfscl nfs_root
+nfs/nfs_fha.c optional nfsd
+nfs/nfs_lock.c optional nfscl | nfslockd | nfsd
+nfs/nfs_nfssvc.c optional nfscl | nfsd
nlm/nlm_advlock.c optional nfslockd | nfsd
nlm/nlm_prot_clnt.c optional nfslockd | nfsd
nlm/nlm_prot_impl.c optional nfslockd | nfsd
@@ -3887,26 +3871,26 @@ opencrypto/gfmult.c optional crypto
opencrypto/rmd160.c optional crypto | ipsec
opencrypto/skipjack.c optional crypto
opencrypto/xform.c optional crypto
-rpc/auth_none.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/auth_unix.c optional krpc | nfslockd | nfsclient | nfscl | nfsd
-rpc/authunix_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/clnt_bck.c optional krpc | nfslockd | nfsserver | nfscl | nfsd
-rpc/clnt_dg.c optional krpc | nfslockd | nfsclient | nfscl | nfsd
-rpc/clnt_rc.c optional krpc | nfslockd | nfsclient | nfscl | nfsd
-rpc/clnt_vc.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/getnetconfig.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/replay.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/rpc_callmsg.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/rpc_generic.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/rpc_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/rpcb_clnt.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/rpcb_prot.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/svc.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/svc_auth.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/svc_auth_unix.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-rpc/svc_dg.c optional krpc | nfslockd | nfsserver | nfscl | nfsd
-rpc/svc_generic.c optional krpc | nfslockd | nfsserver | nfscl | nfsd
-rpc/svc_vc.c optional krpc | nfslockd | nfsserver | nfscl | nfsd
+rpc/auth_none.c optional krpc | nfslockd | nfscl | nfsd
+rpc/auth_unix.c optional krpc | nfslockd | nfscl | nfsd
+rpc/authunix_prot.c optional krpc | nfslockd | nfscl | nfsd
+rpc/clnt_bck.c optional krpc | nfslockd | nfscl | nfsd
+rpc/clnt_dg.c optional krpc | nfslockd | nfscl | nfsd
+rpc/clnt_rc.c optional krpc | nfslockd | nfscl | nfsd
+rpc/clnt_vc.c optional krpc | nfslockd | nfscl | nfsd
+rpc/getnetconfig.c optional krpc | nfslockd | nfscl | nfsd
+rpc/replay.c optional krpc | nfslockd | nfscl | nfsd
+rpc/rpc_callmsg.c optional krpc | nfslockd | nfscl | nfsd
+rpc/rpc_generic.c optional krpc | nfslockd | nfscl | nfsd
+rpc/rpc_prot.c optional krpc | nfslockd | nfscl | nfsd
+rpc/rpcb_clnt.c optional krpc | nfslockd | nfscl | nfsd
+rpc/rpcb_prot.c optional krpc | nfslockd | nfscl | nfsd
+rpc/svc.c optional krpc | nfslockd | nfscl | nfsd
+rpc/svc_auth.c optional krpc | nfslockd | nfscl | nfsd
+rpc/svc_auth_unix.c optional krpc | nfslockd | nfscl | nfsd
+rpc/svc_dg.c optional krpc | nfslockd | nfscl | nfsd
+rpc/svc_generic.c optional krpc | nfslockd | nfscl | nfsd
+rpc/svc_vc.c optional krpc | nfslockd | nfscl | nfsd
rpc/rpcsec_gss/rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi
rpc/rpcsec_gss/rpcsec_gss_conf.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi
rpc/rpcsec_gss/rpcsec_gss_misc.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi
@@ -4012,9 +3996,9 @@ xen/xenbus/xenbusb_if.m optional xen | xenhvm
xen/xenbus/xenbusb.c optional xen | xenhvm
xen/xenbus/xenbusb_front.c optional xen | xenhvm
xen/xenbus/xenbusb_back.c optional xen | xenhvm
-xdr/xdr.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-xdr/xdr_array.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-xdr/xdr_mbuf.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-xdr/xdr_mem.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-xdr/xdr_reference.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
-xdr/xdr_sizeof.c optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
+xdr/xdr.c optional krpc | nfslockd | nfscl | nfsd
+xdr/xdr_array.c optional krpc | nfslockd | nfscl | nfsd
+xdr/xdr_mbuf.c optional krpc | nfslockd | nfscl | nfsd
+xdr/xdr_mem.c optional krpc | nfslockd | nfscl | nfsd
+xdr/xdr_reference.c optional krpc | nfslockd | nfscl | nfsd
+xdr/xdr_sizeof.c optional krpc | nfslockd | nfscl | nfsd
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 9b3b84b..c06eeaf 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -52,7 +52,11 @@ else
fi
b=share/examples/etc/bsd-style-copyright
-year=$(sed -Ee '/^Copyright .* The FreeBSD Project/!d;s/^.*1992-([0-9]*) .*$/\1/g' ${SYSDIR}/../COPYRIGHT)
+if [ -r "${SYSDIR}/../COPYRIGHT" ]; then
+ year=$(sed -Ee '/^Copyright .* The FreeBSD Project/!d;s/^.*1992-([0-9]*) .*$/\1/g' ${SYSDIR}/../COPYRIGHT)
+else
+ year=$(date +%Y)
+fi
# look for copyright template
for bsd_copyright in ../$b ../../$b ../../../$b /usr/src/$b /usr/$b
do
diff --git a/sys/conf/options b/sys/conf/options
index ae0f852..52c44a1 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -253,11 +253,6 @@ KGSSAPI_DEBUG opt_kgssapi.h
# sys/i386/i386/autoconf.c. If any of these filesystems are
# statically compiled into the kernel, code for mounting them as root
# filesystems will be enabled - but look below.
-NFSCLIENT opt_nfs.h
-NFSSERVER opt_nfs.h
-
-# Use these options to compile the experimental nfs client and/or
-# server that supports NFSv4 into a kernel.
# NFSCL - client
# NFSD - server
NFSCL opt_nfs.h
@@ -624,8 +619,6 @@ NFS_MINATTRTIMO opt_nfs.h
NFS_MAXATTRTIMO opt_nfs.h
NFS_MINDIRATTRTIMO opt_nfs.h
NFS_MAXDIRATTRTIMO opt_nfs.h
-NFS_GATHERDELAY opt_nfs.h
-NFS_WDELAYHASHSIZ opt_nfs.h
NFS_DEBUG opt_nfs.h
# For the Bt848/Bt848A/Bt849/Bt878/Bt879 driver
diff --git a/sys/dev/ahci/ahci.c b/sys/dev/ahci/ahci.c
index 583983b..31aab5d 100644
--- a/sys/dev/ahci/ahci.c
+++ b/sys/dev/ahci/ahci.c
@@ -142,7 +142,7 @@ ahci_ctlr_reset(device_t dev)
}
if (timeout == 0) {
device_printf(dev, "AHCI controller reset failure\n");
- return ENXIO;
+ return (ENXIO);
}
/* Reenable AHCI mode */
ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
@@ -225,18 +225,18 @@ ahci_attach(device_t dev)
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
ctlr->r_mem);
rman_fini(&ctlr->sc_iomem);
- return ENXIO;
+ return (ENXIO);
}
ahci_ctlr_setup(dev);
/* Setup interrupts. */
- if (ahci_setup_interrupt(dev)) {
+ if ((error = ahci_setup_interrupt(dev)) != 0) {
bus_dma_tag_destroy(ctlr->dma_tag);
bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid,
ctlr->r_mem);
rman_fini(&ctlr->sc_iomem);
- return ENXIO;
+ return (error);
}
i = 0;
@@ -315,7 +315,7 @@ ahci_attach(device_t dev)
device_set_ivars(child, (void *)(intptr_t)-1);
}
bus_generic_attach(dev);
- return 0;
+ return (0);
}
int
@@ -356,6 +356,14 @@ ahci_setup_interrupt(device_t dev)
device_printf(dev, "Falling back to one MSI\n");
ctlr->numirqs = 1;
}
+
+ /* Ensure we don't overrun irqs. */
+ if (ctlr->numirqs > AHCI_MAX_IRQS) {
+ device_printf(dev, "Too many irqs %d > %d (clamping)\n",
+ ctlr->numirqs, AHCI_MAX_IRQS);
+ ctlr->numirqs = AHCI_MAX_IRQS;
+ }
+
/* Allocate all IRQs. */
for (i = 0; i < ctlr->numirqs; i++) {
ctlr->irqs[i].ctlr = ctlr;
@@ -372,7 +380,7 @@ ahci_setup_interrupt(device_t dev)
if (!(ctlr->irqs[i].r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&ctlr->irqs[i].r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) {
device_printf(dev, "unable to map interrupt\n");
- return ENXIO;
+ return (ENXIO);
}
if ((bus_setup_intr(dev, ctlr->irqs[i].r_irq, ATA_INTR_FLAGS, NULL,
(ctlr->irqs[i].mode != AHCI_IRQ_MODE_ONE) ? ahci_intr :
@@ -381,7 +389,7 @@ ahci_setup_interrupt(device_t dev)
&ctlr->irqs[i], &ctlr->irqs[i].handle))) {
/* SOS XXX release r_irq */
device_printf(dev, "unable to setup interrupt\n");
- return ENXIO;
+ return (ENXIO);
}
if (ctlr->numirqs > 1) {
bus_describe_intr(dev, ctlr->irqs[i].r_irq,
@@ -529,7 +537,7 @@ ahci_release_resource(device_t dev, device_t child, int type, int rid,
return (0);
case SYS_RES_IRQ:
if (rid != ATA_IRQ_RID)
- return ENOENT;
+ return (ENOENT);
return (0);
}
return (EINVAL);
diff --git a/sys/dev/ahci/ahci.h b/sys/dev/ahci/ahci.h
index f5a3ca8..462f204 100644
--- a/sys/dev/ahci/ahci.h
+++ b/sys/dev/ahci/ahci.h
@@ -143,6 +143,7 @@
#define AHCI_MAX_PORTS 32
#define AHCI_MAX_SLOTS 32
+#define AHCI_MAX_IRQS 16
/* SATA AHCI v1.0 register defines */
#define AHCI_CAP 0x00
@@ -494,7 +495,7 @@ struct ahci_controller {
#define AHCI_IRQ_MODE_ALL 0
#define AHCI_IRQ_MODE_AFTER 1
#define AHCI_IRQ_MODE_ONE 2
- } irqs[16];
+ } irqs[AHCI_MAX_IRQS];
uint32_t caps; /* Controller capabilities */
uint32_t caps2; /* Controller capabilities */
uint32_t capsem; /* Controller capabilities */
diff --git a/sys/dev/ath/if_ath_sysctl.c b/sys/dev/ath/if_ath_sysctl.c
index 40a34d4..45c8ae4 100644
--- a/sys/dev/ath/if_ath_sysctl.c
+++ b/sys/dev/ath/if_ath_sysctl.c
@@ -446,7 +446,15 @@ ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS)
return error;
if (!ath_hal_setrfsilent(sc->sc_ah, rfsilent))
return EINVAL;
- sc->sc_rfsilentpin = rfsilent & 0x1c;
+ /*
+ * Earlier chips (< AR5212) have up to 8 GPIO
+ * pins exposed.
+ *
+ * AR5416 and later chips have many more GPIO
+ * pins (up to 16) so the mask is expanded to
+ * four bits.
+ */
+ sc->sc_rfsilentpin = rfsilent & 0x3c;
sc->sc_rfsilentpol = (rfsilent & 0x2) != 0;
return 0;
}
diff --git a/sys/dev/beri/virtio/virtio.c b/sys/dev/beri/virtio/virtio.c
index 4cc25c2..cb7c293 100644
--- a/sys/dev/beri/virtio/virtio.c
+++ b/sys/dev/beri/virtio/virtio.c
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/cdefs.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/malloc.h>
@@ -156,7 +157,7 @@ vq_getchain(uint32_t offs, struct vqueue_info *vq,
break;
next = be16toh(vp->next);
}
- paddr_unmap((void *)vindir, be32toh(vdir->len));
+ paddr_unmap(__DEVOLATILE(void *, vindir), be32toh(vdir->len));
}
if ((be16toh(vdir->flags) & VRING_DESC_F_NEXT) == 0)
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 838be4f..58f529d 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -1946,11 +1946,9 @@ bge_chipinit(struct bge_softc *sc)
/*
* Disable memory write invalidate. Apparently it is not supported
- * properly by these devices. Also ensure that INTx isn't disabled,
- * as these chips need it even when using MSI.
+ * properly by these devices.
*/
- PCI_CLRBIT(sc->bge_dev, BGE_PCI_CMD,
- PCIM_CMD_INTxDIS | PCIM_CMD_MWIEN, 4);
+ PCI_CLRBIT(sc->bge_dev, BGE_PCI_CMD, PCIM_CMD_MWIEN, 4);
/* Set the timer prescaler (always 66 MHz). */
CSR_WRITE_4(sc, BGE_MISC_CFG, BGE_32BITTIME_66MHZ);
diff --git a/sys/dev/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c
index 96ceb0d..ec41a2e 100644
--- a/sys/dev/cpuctl/cpuctl.c
+++ b/sys/dev/cpuctl/cpuctl.c
@@ -63,7 +63,7 @@ static d_ioctl_t cpuctl_ioctl;
# define DPRINTF(...)
#endif
-#define UCODE_SIZE_MAX (16 * 1024)
+#define UCODE_SIZE_MAX (32 * 1024)
static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd,
struct thread *td);
diff --git a/sys/dev/fdt/fdt_common.c b/sys/dev/fdt/fdt_common.c
index d99fdf2..f00519e 100644
--- a/sys/dev/fdt/fdt_common.c
+++ b/sys/dev/fdt/fdt_common.c
@@ -75,6 +75,12 @@ fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base,
u_long bus_addr, par_bus_addr, pbase, psize;
int err, i, len, tuple_size, tuples;
+ if (node == 0) {
+ *base = 0;
+ *size = ULONG_MAX;
+ return (0);
+ }
+
if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0)
return (ENXIO);
/*
@@ -91,9 +97,8 @@ fdt_get_range_by_busaddr(phandle_t node, u_long addr, u_long *base,
if (len > sizeof(ranges))
return (ENOMEM);
if (len == 0) {
- *base = 0;
- *size = ULONG_MAX;
- return (0);
+ return (fdt_get_range_by_busaddr(OF_parent(node), addr,
+ base, size));
}
if (OF_getprop(node, "ranges", ranges, sizeof(ranges)) <= 0)
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 947f057..cf0e6a2 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -157,52 +157,52 @@ static const u_char fxp_cb_config_template[] = {
* them.
*/
static const struct fxp_ident fxp_ident_table[] = {
- { 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" },
- { 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" },
- { 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
- { 0x1032, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
- { 0x1033, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" },
- { 0x1034, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" },
- { 0x1035, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" },
- { 0x1036, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" },
- { 0x1037, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" },
- { 0x1038, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" },
- { 0x1039, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" },
- { 0x103A, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" },
- { 0x103B, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" },
- { 0x103C, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" },
- { 0x103D, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" },
- { 0x103E, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" },
- { 0x1050, -1, 5, "Intel 82801BA (D865) Pro/100 VE Ethernet" },
- { 0x1051, -1, 5, "Intel 82562ET (ICH5/ICH5R) Pro/100 VE Ethernet" },
- { 0x1059, -1, 0, "Intel 82551QM Pro/100 M Mobile Connection" },
- { 0x1064, -1, 6, "Intel 82562EZ (ICH6)" },
- { 0x1065, -1, 6, "Intel 82562ET/EZ/GT/GZ PRO/100 VE Ethernet" },
- { 0x1068, -1, 6, "Intel 82801FBM (ICH6-M) Pro/100 VE Ethernet" },
- { 0x1069, -1, 6, "Intel 82562EM/EX/GX Pro/100 Ethernet" },
- { 0x1091, -1, 7, "Intel 82562GX Pro/100 Ethernet" },
- { 0x1092, -1, 7, "Intel Pro/100 VE Network Connection" },
- { 0x1093, -1, 7, "Intel Pro/100 VM Network Connection" },
- { 0x1094, -1, 7, "Intel Pro/100 946GZ (ICH7) Network Connection" },
- { 0x1209, -1, 0, "Intel 82559ER Embedded 10/100 Ethernet" },
- { 0x1229, 0x01, 0, "Intel 82557 Pro/100 Ethernet" },
- { 0x1229, 0x02, 0, "Intel 82557 Pro/100 Ethernet" },
- { 0x1229, 0x03, 0, "Intel 82557 Pro/100 Ethernet" },
- { 0x1229, 0x04, 0, "Intel 82558 Pro/100 Ethernet" },
- { 0x1229, 0x05, 0, "Intel 82558 Pro/100 Ethernet" },
- { 0x1229, 0x06, 0, "Intel 82559 Pro/100 Ethernet" },
- { 0x1229, 0x07, 0, "Intel 82559 Pro/100 Ethernet" },
- { 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" },
- { 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" },
- { 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" },
- { 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" },
- { 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" },
- { 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" },
- { 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" },
- { 0x1229, -1, 0, "Intel 82557/8/9 Pro/100 Ethernet" },
- { 0x2449, -1, 2, "Intel 82801BA/CAM (ICH2/3) Pro/100 Ethernet" },
- { 0x27dc, -1, 7, "Intel 82801GB (ICH7) 10/100 Ethernet" },
- { 0, -1, 0, NULL },
+ { 0x8086, 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" },
+ { 0x8086, 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" },
+ { 0x8086, 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
+ { 0x8086, 0x1032, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
+ { 0x8086, 0x1033, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" },
+ { 0x8086, 0x1034, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" },
+ { 0x8086, 0x1035, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" },
+ { 0x8086, 0x1036, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" },
+ { 0x8086, 0x1037, -1, 3, "Intel 82801CAM (ICH3) Pro/100 Ethernet" },
+ { 0x8086, 0x1038, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VM Ethernet" },
+ { 0x8086, 0x1039, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" },
+ { 0x8086, 0x103A, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" },
+ { 0x8086, 0x103B, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" },
+ { 0x8086, 0x103C, -1, 4, "Intel 82801DB (ICH4) Pro/100 Ethernet" },
+ { 0x8086, 0x103D, -1, 4, "Intel 82801DB (ICH4) Pro/100 VE Ethernet" },
+ { 0x8086, 0x103E, -1, 4, "Intel 82801DB (ICH4) Pro/100 VM Ethernet" },
+ { 0x8086, 0x1050, -1, 5, "Intel 82801BA (D865) Pro/100 VE Ethernet" },
+ { 0x8086, 0x1051, -1, 5, "Intel 82562ET (ICH5/ICH5R) Pro/100 VE Ethernet" },
+ { 0x8086, 0x1059, -1, 0, "Intel 82551QM Pro/100 M Mobile Connection" },
+ { 0x8086, 0x1064, -1, 6, "Intel 82562EZ (ICH6)" },
+ { 0x8086, 0x1065, -1, 6, "Intel 82562ET/EZ/GT/GZ PRO/100 VE Ethernet" },
+ { 0x8086, 0x1068, -1, 6, "Intel 82801FBM (ICH6-M) Pro/100 VE Ethernet" },
+ { 0x8086, 0x1069, -1, 6, "Intel 82562EM/EX/GX Pro/100 Ethernet" },
+ { 0x8086, 0x1091, -1, 7, "Intel 82562GX Pro/100 Ethernet" },
+ { 0x8086, 0x1092, -1, 7, "Intel Pro/100 VE Network Connection" },
+ { 0x8086, 0x1093, -1, 7, "Intel Pro/100 VM Network Connection" },
+ { 0x8086, 0x1094, -1, 7, "Intel Pro/100 946GZ (ICH7) Network Connection" },
+ { 0x8086, 0x1209, -1, 0, "Intel 82559ER Embedded 10/100 Ethernet" },
+ { 0x8086, 0x1229, 0x01, 0, "Intel 82557 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x02, 0, "Intel 82557 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x03, 0, "Intel 82557 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x04, 0, "Intel 82558 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x05, 0, "Intel 82558 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x06, 0, "Intel 82559 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x07, 0, "Intel 82559 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" },
+ { 0x8086, 0x1229, -1, 0, "Intel 82557/8/9 Pro/100 Ethernet" },
+ { 0x8086, 0x2449, -1, 2, "Intel 82801BA/CAM (ICH2/3) Pro/100 Ethernet" },
+ { 0x8086, 0x27dc, -1, 7, "Intel 82801GB (ICH7) 10/100 Ethernet" },
+ { 0, 0, -1, 0, NULL },
};
#ifdef FXP_IP_CSUM_WAR
@@ -374,18 +374,18 @@ fxp_dma_wait(struct fxp_softc *sc, volatile uint16_t *status,
static const struct fxp_ident *
fxp_find_ident(device_t dev)
{
- uint16_t devid;
+ uint16_t vendor;
+ uint16_t device;
uint8_t revid;
const struct fxp_ident *ident;
- if (pci_get_vendor(dev) == FXP_VENDORID_INTEL) {
- devid = pci_get_device(dev);
- revid = pci_get_revid(dev);
- for (ident = fxp_ident_table; ident->name != NULL; ident++) {
- if (ident->devid == devid &&
- (ident->revid == revid || ident->revid == -1)) {
- return (ident);
- }
+ vendor = pci_get_vendor(dev);
+ device = pci_get_device(dev);
+ revid = pci_get_revid(dev);
+ for (ident = fxp_ident_table; ident->name != NULL; ident++) {
+ if (ident->vendor == vendor && ident->device == device &&
+ (ident->revid == revid || ident->revid == -1)) {
+ return (ident);
}
}
return (NULL);
@@ -628,7 +628,7 @@ fxp_attach(device_t dev)
/* For 82559 or later chips, Rx checksum offload is supported. */
if (sc->revision >= FXP_REV_82559_A0) {
/* 82559ER does not support Rx checksum offloading. */
- if (sc->ident->devid != 0x1209)
+ if (sc->ident->device != 0x1209)
sc->flags |= FXP_FLAG_82559_RXCSUM;
}
/*
diff --git a/sys/dev/fxp/if_fxpreg.h b/sys/dev/fxp/if_fxpreg.h
index 7fd60af..7ee8588 100644
--- a/sys/dev/fxp/if_fxpreg.h
+++ b/sys/dev/fxp/if_fxpreg.h
@@ -28,8 +28,6 @@
* $FreeBSD$
*/
-#define FXP_VENDORID_INTEL 0x8086
-
#define FXP_PCI_MMBA 0x10
#define FXP_PCI_IOBA 0x14
diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h
index e0097a1..78200ce 100644
--- a/sys/dev/fxp/if_fxpvar.h
+++ b/sys/dev/fxp/if_fxpvar.h
@@ -143,7 +143,8 @@ struct fxp_desc_list {
};
struct fxp_ident {
- uint16_t devid;
+ uint16_t vendor;
+ uint16_t device;
int16_t revid; /* -1 matches anything */
uint8_t ich;
const char *name;
diff --git a/sys/dev/gpio/gpio_if.m b/sys/dev/gpio/gpio_if.m
index f0ead65..adc119e 100644
--- a/sys/dev/gpio/gpio_if.m
+++ b/sys/dev/gpio/gpio_if.m
@@ -56,11 +56,11 @@ HEADER {
};
#
-# Get total number of pins
+# Get maximum pin number
#
METHOD int pin_max {
device_t dev;
- int *npins;
+ int *maxpin;
};
#
diff --git a/sys/dev/ieee488/ibfoo.c b/sys/dev/ieee488/ibfoo.c
deleted file mode 100644
index 2fe72dc..0000000
--- a/sys/dev/ieee488/ibfoo.c
+++ /dev/null
@@ -1,1127 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
- * Copyright (c) 2010 Joerg Wunsch <joerg@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * High-level driver for µPD7210 based GPIB cards.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-# define IBDEBUG
-# undef IBDEBUG
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/uio.h>
-#include <sys/time.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <isa/isavar.h>
-
-#include <dev/ieee488/ugpib.h>
-
-#define UPD7210_SW_DRIVER
-#include <dev/ieee488/upd7210.h>
-#include <dev/ieee488/tnt4882.h>
-
-static MALLOC_DEFINE(M_IBFOO, "IBFOO", "IBFOO");
-
-
-/* ibfoo API */
-
-#include <dev/ieee488/ibfoo_int.h>
-
-/* XXX: This is really a bitmap */
-enum h_kind {
- H_DEV = 1,
- H_BOARD = 2,
- H_EITHER = 3
-};
-
-struct handle {
- LIST_ENTRY(handle) list;
- int handle;
- enum h_kind kind;
- int pad;
- int sad;
- struct timeval timeout;
- int eot;
- int eos;
- int dma;
-};
-
-struct ibfoo {
- struct upd7210 *u;
- LIST_HEAD(,handle) handles;
- struct unrhdr *unrhdr;
- struct callout callout;
- struct handle *h;
- struct ibarg *ap;
-
- enum {
- IDLE,
- BUSY,
- PIO_IDATA,
- PIO_ODATA,
- PIO_CMD,
- DMA_IDATA,
- FIFO_IDATA,
- FIFO_ODATA,
- FIFO_CMD
- } mode;
-
- struct timeval deadline;
-
- struct handle *rdh; /* addressed for read */
- struct handle *wrh; /* addressed for write */
-
- int doeoi;
-
- u_char *buf;
- u_int buflen;
-};
-
-typedef int ibhandler_t(struct ibfoo *ib);
-
-static struct timeval timeouts[] = {
- [TNONE] = { 0, 0},
- [T10us] = { 0, 10},
- [T30us] = { 0, 30},
- [T100us] = { 0, 100},
- [T300us] = { 0, 300},
- [T1ms] = { 0, 1000},
- [T3ms] = { 0, 3000},
- [T10ms] = { 0, 10000},
- [T30ms] = { 0, 30000},
- [T100ms] = { 0, 100000},
- [T300ms] = { 0, 300000},
- [T1s] = { 1, 0},
- [T3s] = { 3, 0},
- [T10s] = { 10, 0},
- [T30s] = { 30, 0},
- [T100s] = { 100, 0},
- [T300s] = { 300, 0},
- [T1000s] = { 1000, 0}
-};
-
-static const u_int max_timeouts = sizeof timeouts / sizeof timeouts[0];
-
-static int ibdebug;
-
-static int
-ib_set_error(struct ibarg *ap, int error)
-{
-
- if (ap->__iberr == 0)
- ap->__iberr = error;
- ap->__ibsta |= ERR;
- ap->__retval = ap->__ibsta;
- return (0);
-}
-
-static int
-ib_had_timeout(struct ibarg *ap)
-{
-
- ib_set_error(ap, EABO);
- ap->__ibsta |= TIMO;
- ap->__retval = ap->__ibsta;
- return (0);
-}
-
-static int
-ib_set_errno(struct ibarg *ap, int errno)
-{
-
- if (ap->__iberr == 0) {
- ap->__iberr = EDVR;
- ap->__ibcnt = errno;
- }
- ap->__ibsta |= ERR;
- ap->__retval = ap->__ibsta;
- return (0);
-}
-
-static int
-gpib_ib_irq(struct upd7210 *u, int isr_3)
-{
- struct ibfoo *ib;
-
- ib = u->ibfoo;
-
- mtx_assert(&u->mutex, MA_OWNED);
- switch (ib->mode) {
- case PIO_CMD:
- if (!(u->rreg[ISR2] & IXR2_CO))
- return (0);
- if (ib->buflen == 0)
- break;
- upd7210_wr(u, CDOR, *ib->buf);
- ib->buf++;
- ib->buflen--;
- return (1);
- case PIO_IDATA:
- if (!(u->rreg[ISR1] & IXR1_DI))
- return (0);
- *ib->buf = upd7210_rd(u, DIR);
- ib->buf++;
- ib->buflen--;
- if (ib->buflen == 0 || (u->rreg[ISR1] & IXR1_ENDRX))
- break;
- return (1);
- case PIO_ODATA:
- if (!(u->rreg[ISR1] & IXR1_DO))
- return (0);
- if (ib->buflen == 0)
- break;
- if (ib->buflen == 1 && ib->doeoi)
- upd7210_wr(u, AUXMR, AUXMR_SEOI);
- upd7210_wr(u, CDOR, *ib->buf);
- ib->buf++;
- ib->buflen--;
- return (1);
- case DMA_IDATA:
- if (!(u->rreg[ISR1] & IXR1_ENDRX))
- return (0);
- break;
- case FIFO_IDATA:
- if (!(isr_3 & 0x15))
- return (0);
- while (ib->buflen != 0 && (isr_3 & 0x04 /* NEF */) != 0) {
- *ib->buf = bus_read_1(u->reg_res[0], fifob);
- ib->buf++;
- ib->buflen--;
- isr_3 = bus_read_1(u->reg_res[0], isr3);
- }
- if ((isr_3 & 0x01) != 0 /* xfr done */ ||
- (u->rreg[ISR1] & IXR1_ENDRX) != 0 ||
- ib->buflen == 0)
- break;
- if (isr_3 & 0x10)
- /* xfr stopped */
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- upd7210_wr(u, AUXMR, AUXMR_RFD);
- return (1);
- case FIFO_CMD:
- case FIFO_ODATA:
- if (!(isr_3 & 0x19))
- return (0);
- if (ib->buflen == 0)
- /* xfr DONE */
- break;
- while (ib->buflen != 0 && (isr_3 & 0x08 /* NFF */) != 0) {
- bus_write_1(u->reg_res[0], fifob, *ib->buf);
- ib->buf++;
- ib->buflen--;
- isr_3 = bus_read_1(u->reg_res[0], isr3);
- }
- if (isr_3 & 0x10)
- /* xfr stopped */
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- if (ib->buflen == 0)
- /* no more NFF interrupts wanted */
- bus_write_1(u->reg_res[0], imr3, 0x11); /* STOP IE, DONE IE */
- return (1);
- default:
- return (0);
- }
- upd7210_wr(u, IMR1, 0);
- upd7210_wr(u, IMR2, 0);
- if (u->use_fifo) {
- bus_write_1(u->reg_res[0], imr3, 0x00);
- bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */
- }
- ib->mode = BUSY;
- wakeup(&ib->buflen);
- return (1);
-}
-
-static void
-gpib_ib_timeout(void *arg)
-{
- struct upd7210 *u;
- struct ibfoo *ib;
- struct timeval tv;
- u_int isr_3;
-
- u = arg;
- ib = u->ibfoo;
- mtx_lock(&u->mutex);
- if (ib->mode == DMA_IDATA && isa_dmatc(u->dmachan)) {
- KASSERT(u->dmachan >= 0, ("Bogus dmachan = %d", u->dmachan));
- upd7210_wr(u, IMR1, 0);
- upd7210_wr(u, IMR2, 0);
- ib->mode = BUSY;
- wakeup(&ib->buflen);
- }
- if (ib->mode > BUSY) {
- upd7210_rd(u, ISR1);
- upd7210_rd(u, ISR2);
- if (u->use_fifo)
- isr_3 = bus_read_1(u->reg_res[0], isr3);
- else
- isr_3 = 0;
- gpib_ib_irq(u, isr_3);
- }
- if (ib->mode != IDLE && timevalisset(&ib->deadline)) {
- getmicrouptime(&tv);
- if (timevalcmp(&ib->deadline, &tv, <)) {
- ib_had_timeout(ib->ap);
- upd7210_wr(u, IMR1, 0);
- upd7210_wr(u, IMR2, 0);
- if (u->use_fifo) {
- bus_write_1(u->reg_res[0], imr3, 0x00);
- bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */
- }
- ib->mode = BUSY;
- wakeup(&ib->buflen);
- }
- }
- if (ib->mode != IDLE)
- callout_reset(&ib->callout, hz / 5, gpib_ib_timeout, arg);
- mtx_unlock(&u->mutex);
-}
-
-static void
-gpib_ib_wait_xfer(struct upd7210 *u, struct ibfoo *ib)
-{
- int i;
-
- mtx_assert(&u->mutex, MA_OWNED);
- while (ib->mode > BUSY) {
- i = msleep(&ib->buflen, &u->mutex,
- PZERO | PCATCH, "ibwxfr", 0);
- if (i == EINTR) {
- ib_set_errno(ib->ap, i);
- break;
- }
- if (u->rreg[ISR1] & IXR1_ERR) {
- ib_set_error(ib->ap, EABO); /* XXX ? */
- break;
- }
- }
- if ((u->rreg[ISR1] & IXR1_ENDRX) != 0) {
- ib->ap->__retval |= END;
- ib->ap->__ibsta |= END;
- }
- if ((u->rreg[ISR2] & IXR2_SRQI) != 0) {
- ib->ap->__retval |= SRQI;
- ib->ap->__ibsta |= SRQI;
- }
- ib->mode = BUSY;
- ib->buf = NULL;
- upd7210_wr(u, IMR1, 0);
- upd7210_wr(u, IMR2, 0);
- if (u->use_fifo)
- bus_write_1(u->reg_res[0], imr3, 0x00);
-}
-
-static void
-config_eos(struct upd7210 *u, struct handle *h)
-{
- int i;
-
- i = 0;
- if (h->eos & REOS) {
- upd7210_wr(u, EOSR, h->eos & 0xff);
- i |= AUXA_REOS;
- }
- if (h->eos & XEOS) {
- upd7210_wr(u, EOSR, h->eos & 0xff);
- i |= AUXA_XEOS;
- }
- if (h->eos & BIN)
- i |= AUXA_BIN;
- upd7210_wr(u, AUXRA, C_AUXA | i);
-}
-
-/*
- * Look up the handle, and set the deadline if the handle has a timeout.
- */
-static int
-gethandle(struct upd7210 *u, struct ibarg *ap, struct handle **hp)
-{
- struct ibfoo *ib;
- struct handle *h;
-
- KASSERT(ap->__field & __F_HANDLE, ("gethandle without __F_HANDLE"));
- ib = u->ibfoo;
- LIST_FOREACH(h, &ib->handles, list) {
- if (h->handle == ap->handle) {
- *hp = h;
- return (0);
- }
- }
- ib_set_error(ap, EARG);
- return (1);
-}
-
-static int
-pio_cmd(struct upd7210 *u, u_char *cmd, int len)
-{
- struct ibfoo *ib;
-
- ib = u->ibfoo;
-
- if (ib->rdh != NULL || ib->wrh != NULL) {
- upd7210_take_ctrl_async(u);
- ib->rdh = NULL;
- ib->wrh = NULL;
- }
- mtx_lock(&u->mutex);
- ib->buf = cmd;
- ib->buflen = len;
- if (u->use_fifo) {
- /* TNT5004 or TNT4882 in FIFO mode */
- ib->mode = FIFO_CMD;
- upd7210_wr(u, AUXMR, 0x51); /* holdoff immediately */
- bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
- bus_write_1(u->reg_res[0], cfg, 0x80); /* CMD, xfer OUT, 8-bit FIFO */
- bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */
- bus_write_1(u->reg_res[0], cnt0, -len);
- bus_write_1(u->reg_res[0], cnt1, (-len) >> 8);
- bus_write_1(u->reg_res[0], cnt2, (-len) >> 16);
- bus_write_1(u->reg_res[0], cnt3, (-len) >> 24);
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- } else {
- ib->mode = PIO_CMD;
- upd7210_wr(u, IMR2, IXR2_CO);
- gpib_ib_irq(u, 0);
- }
-
- gpib_ib_wait_xfer(u, ib);
-
- if (u->use_fifo)
- bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */
-
- mtx_unlock(&u->mutex);
- return (len - ib->buflen);
-}
-
-static int
-pio_odata(struct upd7210 *u, u_char *data, int len)
-{
- struct ibfoo *ib;
-
- ib = u->ibfoo;
-
- if (len == 0)
- return (0);
- mtx_lock(&u->mutex);
- ib->buf = data;
- ib->buflen = len;
- if (u->use_fifo) {
- /* TNT5004 or TNT4882 in FIFO mode */
- ib->mode = FIFO_ODATA;
- bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
- if (ib->doeoi)
- bus_write_1(u->reg_res[0], cfg, 0x08); /* CCEN */
- else
- bus_write_1(u->reg_res[0], cfg, 0x00); /* xfer OUT, 8-bit FIFO */
- bus_write_1(u->reg_res[0], imr3, 0x19); /* STOP IE, NFF IE, DONE IE */
- bus_write_1(u->reg_res[0], cnt0, -len);
- bus_write_1(u->reg_res[0], cnt1, (-len) >> 8);
- bus_write_1(u->reg_res[0], cnt2, (-len) >> 16);
- bus_write_1(u->reg_res[0], cnt3, (-len) >> 24);
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- } else {
- ib->mode = PIO_ODATA;
- upd7210_wr(u, IMR1, IXR1_DO);
- }
-
- gpib_ib_wait_xfer(u, ib);
-
- if (u->use_fifo)
- bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */
-
- mtx_unlock(&u->mutex);
- return (len - ib->buflen);
-}
-
-static int
-pio_idata(struct upd7210 *u, u_char *data, int len)
-{
- struct ibfoo *ib;
-
- ib = u->ibfoo;
-
- mtx_lock(&u->mutex);
- ib->buf = data;
- ib->buflen = len;
- if (u->use_fifo) {
- /* TNT5004 or TNT4882 in FIFO mode */
- ib->mode = FIFO_IDATA;
- bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
- bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */
- bus_write_1(u->reg_res[0], cnt0, -len);
- bus_write_1(u->reg_res[0], cnt1, (-len) >> 8);
- bus_write_1(u->reg_res[0], cnt2, (-len) >> 16);
- bus_write_1(u->reg_res[0], cnt3, (-len) >> 24);
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- upd7210_wr(u, AUXMR, AUXMR_RFD);
- bus_write_1(u->reg_res[0], imr3, 0x15); /* STOP IE, NEF IE, DONE IE */
- } else {
- ib->mode = PIO_IDATA;
- upd7210_wr(u, IMR1, IXR1_DI);
- }
-
- gpib_ib_wait_xfer(u, ib);
-
- if (u->use_fifo)
- bus_write_1(u->reg_res[0], cmdr, 0x08); /* STOP */
-
- mtx_unlock(&u->mutex);
- return (len - ib->buflen);
-}
-
-static int
-dma_idata(struct upd7210 *u, u_char *data, int len)
-{
- int j;
- struct ibfoo *ib;
-
- KASSERT(u->dmachan >= 0, ("Bogus dmachan %d", u->dmachan));
- ib = u->ibfoo;
- ib->mode = DMA_IDATA;
- isa_dmastart(ISADMA_READ, data, len, u->dmachan);
- mtx_lock(&u->mutex);
- upd7210_wr(u, IMR1, IXR1_ENDRX);
- upd7210_wr(u, IMR2, IMR2_DMAI);
- gpib_ib_wait_xfer(u, ib);
- mtx_unlock(&u->mutex);
- j = isa_dmastatus(u->dmachan);
- isa_dmadone(ISADMA_READ, data, len, u->dmachan);
- return (len - j);
-}
-
-static int
-ib_send_msg(struct ibfoo *ib, int msg)
-{
- u_char buf[10];
- int i, j;
-
- i = 0;
- buf[i++] = UNT;
- buf[i++] = UNL;
- buf[i++] = LAD | ib->h->pad;
- if (ib->h->sad)
- buf[i++] = LAD | TAD | ib->h->sad;
- buf[i++] = TAD | 0;
- buf[i++] = msg;
- j = pio_cmd(ib->u, buf, i);
- if (i != j)
- ib_set_error(ib->ap, EABO); /* XXX ? */
- return (0);
-}
-
-static int
-ibask(struct ibfoo *ib)
-{ /* XXX */
-
- ibdebug = ib->ap->option;
- return (0);
-}
-
-#define ibbna NULL
-#define ibcac NULL
-
-static int
-ibclr(struct ibfoo *ib)
-{
-
- return (ib_send_msg(ib, SDC));
-}
-
-#define ibcmd NULL
-#define ibcmda NULL
-#define ibconfig NULL
-
-static int
-ibdev(struct ibfoo *ib)
-{ /* TBD */
- struct handle *h;
-
- h = malloc(sizeof *h, M_IBFOO, M_ZERO | M_WAITOK);
- h->handle = alloc_unr(ib->unrhdr);
- h->kind = H_DEV;
- h->pad = ib->ap->pad;
- h->sad = ib->ap->sad;
- h->timeout = timeouts[ib->ap->tmo];
- h->eot = ib->ap->eot;
- h->eos = ib->ap->eos;
- mtx_lock(&ib->u->mutex);
- LIST_INSERT_HEAD(&ib->handles, h, list);
- mtx_unlock(&ib->u->mutex);
- ib->ap->__retval = h->handle;
- return (0);
-}
-
-#define ibdiag NULL
-
-static int
-ibdma(struct ibfoo *ib)
-{
-
- if (ib->u->dmachan < 0 && ib->ap->v)
- return (ib_set_error(ib->ap, EARG));
- ib->h->dma = ib->ap->v;
- return (0);
-}
-
-static int
-ibeos(struct ibfoo *ib)
-{
-
- ib->ap->__iberr = ib->h->eos;
- ib->h->eos = ib->ap->eos;
- if (ib->rdh == ib->h)
- config_eos(ib->u, ib->h);
- return (0);
-}
-
-static int
-ibeot(struct ibfoo *ib)
-{
-
- ib->h->eot = ib->ap->eot;
- return (0);
-}
-
-#define ibevent NULL
-#define ibfind NULL
-#define ibgts NULL
-#define ibist NULL
-#define iblines NULL
-#define ibllo NULL
-#define ibln NULL
-
-static int
-ibloc(struct ibfoo *ib)
-{ /* XXX */
-
- if (ib->h->kind == H_BOARD)
- return (EOPNOTSUPP); /* XXX */
- return (ib_send_msg(ib, GTL));
-}
-
-static int
-ibonl(struct ibfoo *ib)
-{ /* XXX */
-
- if (ib->ap->v)
- return (EOPNOTSUPP); /* XXX */
- mtx_lock(&ib->u->mutex);
- LIST_REMOVE(ib->h, list);
- mtx_unlock(&ib->u->mutex);
- free(ib->h, M_IBFOO);
- ib->h = NULL;
- return (0);
-}
-
-static int
-ibpad(struct ibfoo *ib)
-{
-
- ib->h->pad = ib->ap->pad;
- return (0);
-}
-
-#define ibpct NULL
-#define ibpoke NULL
-#define ibppc NULL
-
-static int
-ibrd(struct ibfoo *ib)
-{ /* TBD */
- u_char buf[10], *bp;
- int i, j, error, bl, bc;
- u_char *dp;
-
- if (ib->h->kind == H_BOARD)
- return (EOPNOTSUPP); /* XXX */
- bl = ib->ap->cnt;
- if (bl > PAGE_SIZE)
- bl = PAGE_SIZE;
- bp = malloc(bl, M_IBFOO, M_WAITOK);
-
- if (ib->rdh != ib->h) {
- i = 0;
- buf[i++] = UNT;
- buf[i++] = UNL;
- buf[i++] = LAD | 0;
- buf[i++] = TAD | ib->h->pad;
- if (ib->h->sad)
- buf[i++] = ib->h->sad;
- i = pio_cmd(ib->u, buf, i);
- config_eos(ib->u, ib->h);
- ib->rdh = ib->h;
- ib->wrh = NULL;
- }
- upd7210_goto_standby(ib->u);
- dp = ib->ap->buffer;
- bc = ib->ap->cnt;
- error = 0;
- while (bc > 0 && ib->ap->__iberr == 0) {
- j = imin(bc, PAGE_SIZE);
- if (ib->h->dma)
- i = dma_idata(ib->u, bp, j);
- else
- i = pio_idata(ib->u, bp, j);
- error = copyout(bp, dp , i);
- if (error)
- break;
- ib->ap->__ibcnt += i;
- if (i != j)
- break;
- bc -= i;
- dp += i;
- }
- upd7210_take_ctrl_async(ib->u);
- free(bp, M_IBFOO);
- return (error);
-}
-
-#define ibrda NULL
-#define ibrdf NULL
-#define ibrdkey NULL
-#define ibrpp NULL
-#define ibrsc NULL
-#define ibrsp NULL
-#define ibrsv NULL
-
-static int
-ibsad(struct ibfoo *ib)
-{
-
- ib->h->sad = ib->ap->sad;
- return (0);
-}
-
-#define ibsgnl NULL
-
-static int
-ibsic(struct ibfoo *ib)
-{ /* TBD */
-
- upd7210_wr(ib->u, AUXMR, AUXMR_SIFC);
- DELAY(100);
- upd7210_wr(ib->u, AUXMR, AUXMR_CIFC);
- return (0);
-}
-
-#define ibsre NULL
-#define ibsrq NULL
-#define ibstop NULL
-
-static int
-ibtmo(struct ibfoo *ib)
-{
-
- ib->h->timeout = timeouts[ib->ap->tmo];
- return (0);
-}
-
-#define ibtrap NULL
-
-static int
-ibtrg(struct ibfoo *ib)
-{
-
- return (ib_send_msg(ib, GET));
-}
-
-#define ibwait NULL
-
-static int
-ibwrt(struct ibfoo *ib)
-{ /* XXX */
- u_char buf[10], *bp;
- int i;
-
- if (ib->h->kind == H_BOARD)
- return (EOPNOTSUPP);
- bp = malloc(ib->ap->cnt, M_IBFOO, M_WAITOK);
- /* XXX: bigger than PAGE_SIZE handling */
- i = copyin(ib->ap->buffer, bp, ib->ap->cnt);
- if (i) {
- free(bp, M_IBFOO);
- return (i);
- }
- if (ib->wrh != ib->h) {
- i = 0;
- buf[i++] = UNT;
- buf[i++] = UNL;
- buf[i++] = LAD | ib->h->pad;
- if (ib->h->sad)
- buf[i++] = LAD | TAD | ib->h->sad;
- buf[i++] = TAD | 0;
- i = pio_cmd(ib->u, buf, i);
- ib->rdh = NULL;
- ib->wrh = ib->h;
- config_eos(ib->u, ib->h);
- }
- upd7210_goto_standby(ib->u);
- ib->doeoi = ib->h->eot;
- i = pio_odata(ib->u, bp, ib->ap->cnt);
- upd7210_take_ctrl_async(ib->u);
- ib->ap->__ibcnt = i;
- free(bp, M_IBFOO);
- return (0);
-}
-
-#define ibwrta NULL
-#define ibwrtf NULL
-#define ibwrtkey NULL
-#define ibxtrc NULL
-
-static struct ibhandler {
- const char *name;
- enum h_kind kind;
- ibhandler_t *func;
- u_int args;
-} ibhandlers[] = {
- [__ID_IBASK] = { "ibask", H_EITHER, ibask, __F_HANDLE | __F_OPTION | __F_RETVAL },
- [__ID_IBBNA] = { "ibbna", H_DEV, ibbna, __F_HANDLE | __F_BDNAME },
- [__ID_IBCAC] = { "ibcac", H_BOARD, ibcac, __F_HANDLE | __F_V },
- [__ID_IBCLR] = { "ibclr", H_DEV, ibclr, __F_HANDLE },
- [__ID_IBCMD] = { "ibcmd", H_BOARD, ibcmd, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBCMDA] = { "ibcmda", H_BOARD, ibcmda, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBCONFIG] = { "ibconfig", H_EITHER, ibconfig, __F_HANDLE | __F_OPTION | __F_VALUE },
- [__ID_IBDEV] = { "ibdev", 0, ibdev, __F_BOARDID | __F_PAD | __F_SAD | __F_TMO | __F_EOT | __F_EOS },
- [__ID_IBDIAG] = { "ibdiag", H_EITHER, ibdiag, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBDMA] = { "ibdma", H_EITHER, ibdma, __F_HANDLE | __F_V },
- [__ID_IBEOS] = { "ibeos", H_EITHER, ibeos, __F_HANDLE | __F_EOS },
- [__ID_IBEOT] = { "ibeot", H_EITHER, ibeot, __F_HANDLE | __F_EOT },
- [__ID_IBEVENT] = { "ibevent", H_BOARD, ibevent, __F_HANDLE | __F_EVENT },
- [__ID_IBFIND] = { "ibfind", 0, ibfind, __F_BDNAME },
- [__ID_IBGTS] = { "ibgts", H_BOARD, ibgts, __F_HANDLE | __F_V },
- [__ID_IBIST] = { "ibist", H_BOARD, ibist, __F_HANDLE | __F_V },
- [__ID_IBLINES] = { "iblines", H_BOARD, iblines, __F_HANDLE | __F_LINES },
- [__ID_IBLLO] = { "ibllo", H_EITHER, ibllo, __F_HANDLE },
- [__ID_IBLN] = { "ibln", H_BOARD, ibln, __F_HANDLE | __F_PADVAL | __F_SADVAL | __F_LISTENFLAG },
- [__ID_IBLOC] = { "ibloc", H_EITHER, ibloc, __F_HANDLE },
- [__ID_IBONL] = { "ibonl", H_EITHER, ibonl, __F_HANDLE | __F_V },
- [__ID_IBPAD] = { "ibpad", H_EITHER, ibpad, __F_HANDLE | __F_PAD },
- [__ID_IBPCT] = { "ibpct", H_DEV, ibpct, __F_HANDLE },
- [__ID_IBPOKE] = { "ibpoke", H_EITHER, ibpoke, __F_HANDLE | __F_OPTION | __F_VALUE },
- [__ID_IBPPC] = { "ibppc", H_EITHER, ibppc, __F_HANDLE | __F_V },
- [__ID_IBRD] = { "ibrd", H_EITHER, ibrd, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBRDA] = { "ibrda", H_EITHER, ibrda, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBRDF] = { "ibrdf", H_EITHER, ibrdf, __F_HANDLE | __F_FLNAME },
- [__ID_IBRDKEY] = { "ibrdkey", H_EITHER, ibrdkey, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBRPP] = { "ibrpp", H_EITHER, ibrpp, __F_HANDLE | __F_PPR },
- [__ID_IBRSC] = { "ibrsc", H_BOARD, ibrsc, __F_HANDLE | __F_V },
- [__ID_IBRSP] = { "ibrsp", H_DEV, ibrsp, __F_HANDLE | __F_SPR },
- [__ID_IBRSV] = { "ibrsv", H_EITHER, ibrsv, __F_HANDLE | __F_V },
- [__ID_IBSAD] = { "ibsad", H_EITHER, ibsad, __F_HANDLE | __F_SAD },
- [__ID_IBSGNL] = { "ibsgnl", H_EITHER, ibsgnl, __F_HANDLE | __F_V },
- [__ID_IBSIC] = { "ibsic", H_BOARD, ibsic, __F_HANDLE },
- [__ID_IBSRE] = { "ibsre", H_BOARD, ibsre, __F_HANDLE | __F_V },
- [__ID_IBSRQ] = { "ibsrq", H_EITHER, ibsrq, __F_FUNC },
- [__ID_IBSTOP] = { "ibstop", H_EITHER, ibstop, __F_HANDLE },
- [__ID_IBTMO] = { "ibtmo", H_EITHER, ibtmo, __F_HANDLE | __F_TMO },
- [__ID_IBTRAP] = { "ibtrap", H_EITHER, ibtrap, __F_MASK | __F_MODE },
- [__ID_IBTRG] = { "ibtrg", H_DEV, ibtrg, __F_HANDLE },
- [__ID_IBWAIT] = { "ibwait", H_EITHER, ibwait, __F_HANDLE | __F_MASK },
- [__ID_IBWRT] = { "ibwrt", H_EITHER, ibwrt, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBWRTA] = { "ibwrta", H_EITHER, ibwrta, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBWRTF] = { "ibwrtf", H_EITHER, ibwrtf, __F_HANDLE | __F_FLNAME },
- [__ID_IBWRTKEY] = { "ibwrtkey", H_EITHER, ibwrtkey, __F_HANDLE | __F_BUFFER | __F_CNT },
- [__ID_IBXTRC] = { "ibxtrc", H_EITHER, ibxtrc, __F_HANDLE | __F_BUFFER | __F_CNT },
-};
-
-static const u_int max_ibhandler = sizeof ibhandlers / sizeof ibhandlers[0];
-
-static void
-ib_dump_args(struct ibhandler *ih, struct ibarg *ap)
-{
-
- if (ih->name != NULL)
- printf("%s(", ih->name);
- else
- printf("ibinvalid(");
- printf("[0x%x]", ap->__field);
- if (ap->__field & __F_HANDLE) printf(" handle=%d", ap->handle);
- if (ap->__field & __F_EOS) printf(" eos=0x%x", ap->eos);
- if (ap->__field & __F_EOT) printf(" eot=%d", ap->eot);
- if (ap->__field & __F_TMO) printf(" tmo=%d", ap->tmo);
- if (ap->__field & __F_PAD) printf(" pad=0x%x", ap->pad);
- if (ap->__field & __F_SAD) printf(" sad=0x%x", ap->sad);
- if (ap->__field & __F_BUFFER) printf(" buffer=%p", ap->buffer);
- if (ap->__field & __F_CNT) printf(" cnt=%ld", ap->cnt);
- if (ap->__field & __F_V) printf(" v=%d/0x%x", ap->v, ap->v);
- /* XXX more ... */
- printf(")\n");
-}
-
-static int
-gpib_ib_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
- struct upd7210 *u;
- struct ibfoo *ib;
- int error = 0;
-
- u = dev->si_drv1;
-
- mtx_lock(&u->mutex);
- if (u->busy) {
- mtx_unlock(&u->mutex);
- return (EBUSY);
- }
- u->busy = 1;
- mtx_unlock(&u->mutex);
-
- if (u->dmachan >= 0) {
- error = isa_dma_acquire(u->dmachan);
- if (!error) {
- error = isa_dma_init(u->dmachan, PAGE_SIZE, M_WAITOK);
- if (error)
- isa_dma_release(u->dmachan);
- }
- }
-
- if (error) {
- mtx_lock(&u->mutex);
- u->busy = 0;
- mtx_unlock(&u->mutex);
- return (error);
- }
-
- ib = malloc(sizeof *ib, M_IBFOO, M_WAITOK | M_ZERO);
- LIST_INIT(&ib->handles);
- callout_init(&ib->callout, CALLOUT_MPSAFE);
- ib->unrhdr = new_unrhdr(0, INT_MAX, NULL);
- dev->si_drv2 = ib;
- ib->u = u;
- u->ibfoo = ib;
- u->irq = gpib_ib_irq;
-
- upd7210_wr(u, AUXMR, AUXMR_CRST);
- DELAY(10000);
- DELAY(1000);
- upd7210_wr(u, IMR1, 0x00);
- upd7210_wr(u, IMR2, 0x00);
- upd7210_wr(u, SPMR, 0x00);
- upd7210_wr(u, ADR, 0x00);
- upd7210_wr(u, ADR, ADR_ARS | ADR_DL | ADR_DT);
- upd7210_wr(u, ADMR, ADMR_ADM0 | ADMR_TRM0 | ADMR_TRM1);
- upd7210_wr(u, EOSR, 0x00);
- upd7210_wr(u, AUXMR, C_ICR | 8);
- upd7210_wr(u, AUXMR, C_PPR | PPR_U);
- upd7210_wr(u, AUXMR, C_AUXA);
- upd7210_wr(u, AUXMR, C_AUXB + 3);
- upd7210_wr(u, AUXMR, C_AUXE + 0);
- upd7210_wr(u, AUXMR, AUXMR_PON);
- if (u->use_fifo) {
- bus_write_1(u->reg_res[0], imr3, 0x00);
- bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft reset */
- bus_write_1(u->reg_res[0], cmdr, 0x03); /* set system
- * controller bit */
- }
- upd7210_wr(u, AUXMR, AUXMR_CIFC);
- DELAY(100);
- upd7210_wr(u, AUXMR, AUXMR_SIFC);
- upd7210_wr(u, AUXMR, AUXMR_SREN);
- return (0);
-}
-
-static int
-gpib_ib_close(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
- struct upd7210 *u;
- struct ibfoo *ib;
-
- u = dev->si_drv1;
- ib = dev->si_drv2;
- /* XXX: assert pointer consistency */
-
- u->ibfoo = NULL;
- /* XXX: free handles */
- dev->si_drv2 = NULL;
- free(ib, M_IBFOO);
-
- if (u->dmachan >= 0) {
- isa_dma_release(u->dmachan);
- }
- mtx_lock(&u->mutex);
- u->busy = 0;
- ibdebug = 0;
- upd7210_wr(u, IMR1, 0x00);
- upd7210_wr(u, IMR2, 0x00);
- if (u->use_fifo) {
- bus_write_1(u->reg_res[0], imr3, 0x00);
- bus_write_1(u->reg_res[0], cmdr, 0x02); /* clear system
- * controller bit */
- }
- upd7210_wr(u, AUXMR, AUXMR_CRST);
- DELAY(10000);
- mtx_unlock(&u->mutex);
- return (0);
-}
-
-static int
-gpib_ib_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
-{
- struct ibarg *ap;
- struct ibhandler *ih;
- struct handle *h;
- struct upd7210 *u;
- struct ibfoo *ib;
- int error;
- struct timeval deadline, tv;
-
- u = dev->si_drv1;
- ib = u->ibfoo;
-
- /* We only support a single ioctl, everything else is a mistake */
- if (cmd != GPIB_IBFOO)
- return (ENOIOCTL);
-
- /* Check the identifier and field-bitmap in the arguments. */
- ap = (void *)data;
- if (ap->__ident < 0 || ap->__ident >= max_ibhandler)
- return (EINVAL);
- ih = &ibhandlers[ap->__ident];
- if (ap->__field != ih->args)
- return (EINVAL);
-
- if (ibdebug)
- ib_dump_args(ih, ap);
-
- if (ih->func == NULL)
- return (EOPNOTSUPP);
-
- ap->__iberr = 0;
- ap->__ibsta = 0;
- ap->__ibcnt = 0;
- ap->__retval = 0;
-
- if (ap->__field & __F_TMO) {
- if (ap->tmo < 0 || ap->tmo >= max_timeouts)
- return (ib_set_error(ap, EARG));
- }
-
- if (ap->__field & __F_EOS) {
- if ((ap->eos & ~(REOS | XEOS | BIN | 0xff)) ||
- ((ap->eos & (BIN | 0x80)) == 0x80))
- return (ib_set_error(ap, EARG));
- }
- if (ap->__field & __F_PAD) {
- if (ap->pad < 0 || ap->pad > 30)
- return (ib_set_error(ap, EARG));
- }
- if (ap->__field & __F_SAD) {
- if (ap->sad != 0 && (ap->sad < 0x60 || ap->sad > 126))
- return (ib_set_error(ap, EARG));
- }
-
-
- mtx_lock(&u->mutex);
-
-
- /* Find the handle, if any */
- h = NULL;
- if ((ap->__field & __F_HANDLE) && gethandle(u, ap, &h)) {
- mtx_unlock(&u->mutex);
- return (0);
- }
-
- /* Check that the handle is the right kind */
- if (h != NULL && !(h->kind & ih->kind)) {
- mtx_unlock(&u->mutex);
- return (ib_set_error(ap, EARG));
- }
-
- /* Set up handle and deadline */
- if (h != NULL && timevalisset(&h->timeout)) {
- getmicrouptime(&deadline);
- timevaladd(&deadline, &h->timeout);
- } else {
- timevalclear(&deadline);
- }
-
- /* Wait for the card to be(come) available, respect deadline */
- while(u->busy != 1) {
- error = msleep(ib, &u->mutex,
- PZERO | PCATCH, "gpib_ibioctl", hz / 10);
- if (error == 0)
- continue;
- mtx_unlock(&u->mutex);
- if (error == EINTR)
- return(ib_set_error(ap, EABO));
- if (error == EWOULDBLOCK && timevalisset(&deadline)) {
- getmicrouptime(&tv);
- if (timevalcmp(&deadline, &tv, <))
- return(ib_had_timeout(ap));
- }
- mtx_lock(&u->mutex);
- }
- u->busy = 2;
- mtx_unlock(&u->mutex);
-
- /* Hand over deadline handling to the callout routine */
- ib->ap = ap;
- ib->h = h;
- ib->mode = BUSY;
- ib->deadline = deadline;
- callout_reset(&ib->callout, hz / 5, gpib_ib_timeout, u);
-
- error = ih->func(ib);
-
- /* Release card */
- ib->mode = IDLE;
- ib->ap = NULL;
- ib->h = NULL;
- timevalclear(&deadline);
- callout_stop(&ib->callout);
-
- mtx_lock(&u->mutex);
- u->busy = 1;
- wakeup(ib);
- mtx_unlock(&u->mutex);
-
- if (error)
- return(ib_set_errno(ap, error));
- return (0);
-}
-
-struct cdevsw gpib_ib_cdevsw = {
- .d_version = D_VERSION,
- .d_name = "gpib_ib",
- .d_open = gpib_ib_open,
- .d_ioctl = gpib_ib_ioctl,
- .d_close = gpib_ib_close,
-};
diff --git a/sys/dev/ieee488/ibfoo_int.h b/sys/dev/ieee488/ibfoo_int.h
deleted file mode 100644
index 28f7289..0000000
--- a/sys/dev/ieee488/ibfoo_int.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp
- * 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.
- *
- * This file defines the ABI between the userland gpib library and the
- * kernel. This file should not be used anywhere else.
- *
- * $FreeBSD$
- */
-
-#include <sys/ioccom.h>
-
-typedef void ibsrq_t(void);
-enum ibfoo_id {
- __ID_INVALID = 0,
- __ID_IBASK,
- __ID_IBBNA,
- __ID_IBCAC,
- __ID_IBCLR,
- __ID_IBCMD,
- __ID_IBCMDA,
- __ID_IBCONFIG,
- __ID_IBDEV,
- __ID_IBDIAG,
- __ID_IBDMA,
- __ID_IBEOS,
- __ID_IBEOT,
- __ID_IBEVENT,
- __ID_IBFIND,
- __ID_IBGTS,
- __ID_IBIST,
- __ID_IBLINES,
- __ID_IBLLO,
- __ID_IBLN,
- __ID_IBLOC,
- __ID_IBONL,
- __ID_IBPAD,
- __ID_IBPCT,
- __ID_IBPOKE,
- __ID_IBPPC,
- __ID_IBRD,
- __ID_IBRDA,
- __ID_IBRDF,
- __ID_IBRDKEY,
- __ID_IBRPP,
- __ID_IBRSC,
- __ID_IBRSP,
- __ID_IBRSV,
- __ID_IBSAD,
- __ID_IBSGNL,
- __ID_IBSIC,
- __ID_IBSRE,
- __ID_IBSRQ,
- __ID_IBSTOP,
- __ID_IBTMO,
- __ID_IBTRAP,
- __ID_IBTRG,
- __ID_IBWAIT,
- __ID_IBWRT,
- __ID_IBWRTA,
- __ID_IBWRTF,
- __ID_IBWRTKEY,
- __ID_IBXTRC
-};
-
-#define __F_HANDLE (1 << 0)
-#define __F_SPR (1 << 1)
-#define __F_BUFFER (1 << 2)
-#define __F_RETVAL (1 << 3)
-#define __F_BDNAME (1 << 4)
-#define __F_MASK (1 << 5)
-#define __F_PADVAL (1 << 6)
-#define __F_SADVAL (1 << 7)
-#define __F_CNT (1 << 8)
-#define __F_TMO (1 << 9)
-#define __F_EOS (1 << 10)
-#define __F_PPR (1 << 11)
-#define __F_EOT (1 << 12)
-#define __F_V (1 << 13)
-#define __F_VALUE (1 << 14)
-#define __F_SAD (1 << 15)
-#define __F_BOARDID (1 << 16)
-#define __F_OPTION (1 << 17)
-#define __F_FLNAME (1 << 18)
-#define __F_FUNC (1 << 19)
-#define __F_LINES (1 << 20)
-#define __F_PAD (1 << 21)
-#define __F_MODE (1 << 22)
-#define __F_LISTENFLAG (1 << 23)
-#define __F_EVENT (1 << 24)
-
-struct ibarg {
- enum ibfoo_id __ident;
- unsigned int __field;
- int __retval;
- int __ibsta;
- int __iberr;
- int __ibcnt;
- int handle;
- char * spr;
- void * buffer;
- int * retval;
- char * bdname;
- int mask;
- int padval;
- int sadval;
- long cnt;
- int tmo;
- int eos;
- char * ppr;
- int eot;
- int v;
- int value;
- int sad;
- int boardID;
- int option;
- char * flname;
- ibsrq_t * func;
- short * lines;
- int pad;
- int mode;
- short * listenflag;
- short * event;
-};
-
-#define GPIB_IBFOO _IOWR(4, 0, struct ibarg)
diff --git a/sys/dev/ieee488/pcii.c b/sys/dev/ieee488/pcii.c
deleted file mode 100644
index 833ec91..0000000
--- a/sys/dev/ieee488/pcii.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
- * Copyright (c) 2010 Joerg Wunsch <joerg@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Driver for GPIB cards based on NEC µPD7210 and compatibles.
- *
- * This driver just hooks up to the hardware and leaves all the interesting
- * stuff to upd7210.c.
- *
- * Supported hardware:
- * PCIIA compatible cards.
- *
- * Tested and known working:
- * "B&C Microsystems PC488A-0"
- * "National Instruments GPIB-PCII/PCIIA" (in PCIIa mode)
- * "Axiom AX5488"
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/kernel.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/rman.h>
-#include <isa/isavar.h>
-
-#define UPD7210_HW_DRIVER
-#include <dev/ieee488/upd7210.h>
-
-struct pcii_softc {
- int foo;
- struct resource *res[11];
- void *intr_handler;
- struct upd7210 upd7210;
-};
-
-static devclass_t pcii_devclass;
-
-static int pcii_probe(device_t dev);
-static int pcii_attach(device_t dev);
-
-static device_method_t pcii_methods[] = {
- DEVMETHOD(device_probe, pcii_probe),
- DEVMETHOD(device_attach, pcii_attach),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- { 0, 0 }
-};
-
-static struct resource_spec pcii_res_spec[] = {
- { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE},
- { SYS_RES_DRQ, 0, RF_ACTIVE | RF_SHAREABLE | RF_OPTIONAL},
- { SYS_RES_IOPORT, 0, RF_ACTIVE},
- { SYS_RES_IOPORT, 1, RF_ACTIVE},
- { SYS_RES_IOPORT, 2, RF_ACTIVE},
- { SYS_RES_IOPORT, 3, RF_ACTIVE},
- { SYS_RES_IOPORT, 4, RF_ACTIVE},
- { SYS_RES_IOPORT, 5, RF_ACTIVE},
- { SYS_RES_IOPORT, 6, RF_ACTIVE},
- { SYS_RES_IOPORT, 7, RF_ACTIVE},
- { SYS_RES_IOPORT, 8, RF_ACTIVE | RF_SHAREABLE},
- { -1, 0, 0 }
-};
-
-static driver_t pcii_driver = {
- "pcii",
- pcii_methods,
- sizeof(struct pcii_softc),
-};
-
-static int
-pcii_probe(device_t dev)
-{
- int rid, i, j;
- u_long start, count, addr;
- int error = 0;
- struct pcii_softc *sc;
-
- device_set_desc(dev, "PCII IEEE-4888 controller");
- sc = device_get_softc(dev);
-
- rid = 0;
- if (bus_get_resource(dev, SYS_RES_IOPORT, rid, &start, &count) != 0)
- return ENXIO;
- /*
- * The PCIIA decodes a fixed pattern of 0x2e1 for the lower 10
- * address bits A0 ... A9. Bits A10 through A12 are used by
- * the µPD7210 register select lines. This makes the
- * individual 7210 register being 0x400 bytes apart in the ISA
- * bus address space. Address bits A13 and A14 are compared
- * to a DIP switch setting on the card, allowing for up to 4
- * different cards being installed (at base addresses 0x2e1,
- * 0x22e1, 0x42e1, and 0x62e1, respectively). A15 has been
- * used to select an optional on-board time-of-day clock chip
- * (MM58167A) on the original PCIIA rather than the µPD7210
- * (which is not implemented on later boards). The
- * documentation states the respective addresses for that chip
- * should be handled as reserved addresses, which we don't do
- * (right now). Finally, the IO addresses 0x2f0 ... 0x2f7 for
- * a "special interrupt handling feature" (re-enable
- * interrupts so the IRQ can be shared).
- *
- * Usually, the user will only set the base address in the
- * device hints, so we handle the rest here.
- *
- * (Source: GPIB-PCIIA Technical Reference Manual, September
- * 1989 Edition, National Instruments.)
- */
- if ((start & 0x3ff) != 0x2e1) {
- if (bootverbose)
- printf("pcii_probe: PCIIA base address 0x%lx not "
- "0x2e1/0x22e1/0x42e1/0x62e1\n",
- start);
- return (ENXIO);
- }
-
- for (rid = 0, addr = start; rid < 8; rid++, addr += 0x400) {
- if (bus_set_resource(dev, SYS_RES_IOPORT, rid, addr, 1) != 0) {
- printf("pcii_probe: could not set IO port 0x%lx\n",
- addr);
- return (ENXIO);
- }
- }
- if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) {
- printf("pcii_probe: cannot obtain IRQ level\n");
- return ENXIO;
- }
- if (start > 7) {
- printf("pcii_probe: IRQ level %lu too high\n", start);
- return ENXIO;
- }
-
- if (bus_set_resource(dev, SYS_RES_IOPORT, 8, 0x2f0 + start, 1) != 0) {
- printf("pcii_probe: could not set IO port 0x%3lx\n",
- 0x2f0 + start);
- return (ENXIO);
- }
-
- error = bus_alloc_resources(dev, pcii_res_spec, sc->res);
- if (error) {
- printf("pcii_probe: Could not allocate resources\n");
- return (error);
- }
- error = ENXIO;
- /*
- * Perform some basic tests on the µPD7210 registers. At
- * least *some* register must read different from 0x00 or
- * 0xff.
- */
- for (i = 0; i < 8; i++) {
- j = bus_read_1(sc->res[2 + i], 0);
- if (j != 0x00 && j != 0xff)
- error = 0;
- }
- /* SPSR/SPMR read/write test */
- if (!error) {
- bus_write_1(sc->res[2 + 3], 0, 0x55);
- if (bus_read_1(sc->res[2 + 3], 0) != 0x55)
- error = ENXIO;
- }
- if (!error) {
- bus_write_1(sc->res[2 + 3], 0, 0xaa);
- if (bus_read_1(sc->res[2 + 3], 0) != 0xaa)
- error = ENXIO;
- }
- if (error)
- printf("pcii_probe: probe failure\n");
-
- bus_release_resources(dev, pcii_res_spec, sc->res);
- return (error);
-}
-
-static int
-pcii_attach(device_t dev)
-{
- struct pcii_softc *sc;
- u_long start, count;
- int unit;
- int rid;
- int error = 0;
-
- unit = device_get_unit(dev);
- sc = device_get_softc(dev);
- memset(sc, 0, sizeof *sc);
-
- device_set_desc(dev, "PCII IEEE-4888 controller");
-
- if (bus_get_resource(dev, SYS_RES_IRQ, 0, &start, &count) != 0) {
- printf("pcii_attach: cannot obtain IRQ number\n");
- return ENXIO;
- }
-
- error = bus_alloc_resources(dev, pcii_res_spec, sc->res);
- if (error)
- return (error);
-
- error = bus_setup_intr(dev, sc->res[0],
- INTR_TYPE_MISC | INTR_MPSAFE, NULL,
- upd7210intr, &sc->upd7210, &sc->intr_handler);
- if (error) {
- bus_release_resources(dev, pcii_res_spec, sc->res);
- return (error);
- }
-
- for (rid = 0; rid < 8; rid++) {
- sc->upd7210.reg_res[rid] = sc->res[2 + rid];
- sc->upd7210.reg_offset[rid] = 0;
- }
- sc->upd7210.irq_clear_res = sc->res[10];
- sc->upd7210.use_fifo = 0;
-
- if (sc->res[1] == NULL)
- sc->upd7210.dmachan = -1;
- else
- sc->upd7210.dmachan = rman_get_start(sc->res[1]);
-
- upd7210attach(&sc->upd7210);
- device_printf(dev, "attached gpib%d\n", sc->upd7210.unit);
-
- return (0);
-}
-
-DRIVER_MODULE(pcii, isa, pcii_driver, pcii_devclass, 0, 0);
-DRIVER_MODULE(pcii, acpi, pcii_driver, pcii_devclass, 0, 0);
diff --git a/sys/dev/ieee488/tnt4882.c b/sys/dev/ieee488/tnt4882.c
deleted file mode 100644
index 4b69d0d..0000000
--- a/sys/dev/ieee488/tnt4882.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp
- * Copyright (c) 2010 Joerg Wunsch
- * 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 <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/module.h>
-#include <sys/bus.h>
-#include <dev/pci/pcireg.h>
-#include <dev/pci/pcivar.h>
-
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <machine/stdarg.h>
-#include <sys/rman.h>
-
-/* vtophys */
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <machine/pmap.h>
-
-#define UPD7210_HW_DRIVER 1
-#include <dev/ieee488/upd7210.h>
-#include <dev/ieee488/tnt4882.h>
-
-struct tnt_softc {
- int foo;
- struct upd7210 upd7210;
-
- struct resource *res[3];
- void *intr_handler;
-};
-
-static struct resource_spec tnt_res_spec[] = {
- { SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE},
- { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE},
- { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE},
- { -1, 0 }
-};
-
-struct tst {
- enum {RD, WT, xDELAY, END}
- action;
- enum tnt4882reg reg;
- uint8_t val;
-};
-
-/*
- * From NI Application note 095:
- * Writing Functional Self-Tests for the TNT4882 GPIB Interface Chip
- * XXX: fill in the rest ?
- */
-static struct tst tst_reset[] = {
- {WT, tauxcr, 0x80}, /* chip reset if in 9914 mode */
- {WT, auxmr, 0x80}, /* swrst if swapped */
- {WT, tauxcr, 0x99}, /* switch to 7210 mode */
- {WT, auxmr, 0x99}, /* switch to 7210 mode if swapped */
- {WT, auxmr, 0x02}, /* execute chip reset */
- {WT, keyreg, 0x00}, /* important! clear the swap bit */
- {WT, eosr, 0x00}, /* clear EOS register */
- {WT, cdor, 0x00}, /* clear data lines */
- {WT, imr1, 0x00}, /* disable all interrupts */
- {WT, imr2, 0x00},
- {WT, imr0, 0x80},
- {WT, adr, 0x80},
- {WT, adr, 0x00},
- {WT, admr, 0x00}, /* clear addressing modes */
- {WT, auxmr, 0x00}, /* release from idle state with pon */
- {WT, auxmr, 0x60}, /* reset ppr */
- {WT, bcr, 0x00}, /* reset bcr */
- {WT, misc, 0x04}, /* set wrap plug bit */
- {WT, cmdr, 0xB2}, /* issue soft reset */
- {WT, hssel, 0x00}, /* select two-chip mode */
- {END, 0, 0}
-};
-
-static struct tst tst_read_reg[] = {
- {RD, isr1, 0x00}, /* Verify mask registers are clear */
- {RD, isr2, 0x00},
- {RD, adsr, 0x40}, /* Verify ATN is not asserted */
- {RD, adr0, 0x00}, /* Verify Primary address not set */
- {RD, adr1, 0x00}, /* Verify Secondary address not set */
- {RD, sts1, 0x8B}, /* Verify DONE, STOP, HALT, and GSYNC set */
- {RD, isr3, 0x19}, /* Verify STOP, Not Full FIFO, & DONE set */
- {RD, sts2, 0x9A}, /* Verify FIFO A/B is empty */
- {RD, sasr, 0x00}, /* Verify clear */
- {RD, isr0, 0x01}, /* Verify SYNC bit is set */
- {END, 0, 0}
-};
-
-static struct tst tst_bsr_dcr[] = {
- {WT, bcr, 0x55}, /* Set DAV, NRFD, SRQ, and REN */
- {WT, dcr, 0xAA}, /* Write pattern to GPIB data lines */
- {RD, bsr, 0x55}, /* Verify DAV, NRFD, SRQ, and REN are set */
- {RD, dsr, 0xAA}, /* Verify data pattern written previously */
- {WT, bcr, 0xAA}, /* Set ATN, NDAC, EOI, & IFC */
- {WT, dcr, 0x55}, /* Write pattern to GPIB data lines */
- {RD, bsr, 0xAA}, /* Verify ATN, NDAC, EOI, & IFC are set */
- {RD, dsr, 0x55}, /* Verify data pattern written previously */
- {WT, bcr, 0x00}, /* Clear control lines */
- {WT, dcr, 0x00}, /* Clear data lines */
- {RD, bsr, 0x00}, /* Verify control lines are clear */
- {RD, dsr, 0x00}, /* Verify data lines are clear */
- {END, 0, 0}
-};
-
-static struct tst tst_adr0_1[] = {
- {WT, adr, 0x55}, /* Set Primary talk address */
- {WT, adr, 0xAA}, /* Set Secondary listen address */
- {RD, adr0, 0x55}, /* Read Primary address */
- {RD, adr1, 0x2A}, /* Read Secondary address */
- {WT, adr, 0x2A}, /* Set Primay listen address */
- {WT, adr, 0xD5}, /* Set Secondary talk address */
- {RD, adr0, 0x2A}, /* Read Primary address */
- {RD, adr1, 0x55}, /* Read Secondary address */
- {END, 0, 0}
-};
-
-static struct tst tst_cdor_dir[] = {
- {WT, admr, 0xF0}, /* program AT-GPIB as talker only and
- * listener only */
- {RD, isr1, 0x02}, /* check DO bit set */
- {RD, adsr, 0x46}, /* check AT-GPIB is both talker active
- * and listener active */
- {WT, cdor, 0xAA}, /* write out data byte */
- {xDELAY, 0, 1}, /* One ISA I/O Cycle (500-ns) */
- {RD, isr1, 0x03}, /* check DO and DI bits set */
- {RD, dir, 0xAA}, /* verify data received */
- {WT, cdor, 0x55}, /* write out data byte */
- {xDELAY, 0, 1}, /* One ISA I/O Cycle (500-ns) */
- {RD, dir, 0x55}, /* verify data received */
- {END, 0, 0}
-};
-
-static struct tst tst_spmr_spsr[] = {
- {WT, spsr, 0x00}, /* Write pattern to SPSR register */
- {RD, spmr, 0x00}, /* Read back previously written pattern */
- {WT, spsr, 0xBF}, /* Write pattern to SPSR register */
- {RD, spmr, 0xBF}, /* Read back previously written pattern */
- {END, 0, 0}
-};
-
-static struct tst tst_count0_1[] = {
- {WT, cnt0, 0x55}, /* Verify every other bit can be set */
- {WT, cnt1, 0xAA},
- {RD, cnt0, 0x55}, /* Read back previously written pattern */
- {RD, cnt1, 0xAA},
- {WT, cnt0, 0xAA}, /* Verify every other bit can be set */
- {WT, cnt1, 0x55},
- {RD, cnt0, 0xAA}, /* Read back previously written pattern */
- {RD, cnt1, 0x55},
- {END, 0, 0}
-};
-
-static int
-tst_exec(struct tnt_softc *sc, struct tst *tp, const char *name)
-{
- uint8_t u;
- int step;
-
- for (step = 0; tp->action != END; tp++, step++) {
- switch (tp->action) {
- case WT:
- bus_write_1(sc->res[1], tp->reg, tp->val);
- break;
- case RD:
- u = bus_read_1(sc->res[1], tp->reg);
- if (u != tp->val) {
- printf(
- "Test %s, step %d: reg(%02x) = %02x",
- name, step, tp->reg, u);
- printf( "should have been %02x\n", tp->val);
- return (1);
- }
- break;
- case xDELAY:
- DELAY(tp->val);
- break;
- default:
- printf("Unknown action in test %s, step %d: %d\n",
- name, step, tp->action);
- return (1);
- }
- }
- if (bootverbose)
- printf("Test %s passed\n", name);
- return (0);
-}
-
-static int
-tnt_probe(device_t dev)
-{
-
- if (pci_get_vendor(dev) == 0x1093 && pci_get_device(dev) == 0xc801) {
- device_set_desc(dev, "NI PCI-GPIB");
- return (BUS_PROBE_DEFAULT);
- }
- return (ENXIO);
-}
-
-static int
-tnt_attach(device_t dev)
-{
- struct tnt_softc *sc;
- int error, i;
- uint8_t version;
-
- sc = device_get_softc(dev);
-
- error = bus_alloc_resources(dev, tnt_res_spec, sc->res);
- if (error)
- return (error);
-
- error = bus_setup_intr(dev, sc->res[2], INTR_TYPE_MISC | INTR_MPSAFE,
- NULL, upd7210intr, &sc->upd7210, &sc->intr_handler);
-
- /* IO Device Window Base Size Register (IODWBSR) */
- bus_write_4(sc->res[0], 0xc0, rman_get_start(sc->res[1]) | 0x80);
-
- tst_exec(sc, tst_reset, "Reset");
- tst_exec(sc, tst_read_reg, "Read registers");
- tst_exec(sc, tst_bsr_dcr, "BSR & DCR");
- tst_exec(sc, tst_adr0_1, "ADR0,1");
- tst_exec(sc, tst_cdor_dir, "CDOR/DIR");
- tst_exec(sc, tst_spmr_spsr, "CPMR/SPSR");
- tst_exec(sc, tst_count0_1, "COUNT0:1");
- tst_exec(sc, tst_reset, "Reset");
-
- version = bus_read_1(sc->res[1], csr);
- version = (version >> 4) & 0x0f;
- device_printf(dev, "Chip version 0x%02x (TNT%s)\n",
- version,
- version >= 4? "5004 or above": "4882");
- if (version >= 4) {
- device_printf(dev, "Forcing FIFO mode\n");
- sc->upd7210.use_fifo = 1;
- } else {
- sc->upd7210.use_fifo = 0;
- }
-
- /* pass 7210 interrupts through */
- bus_write_1(sc->res[1], imr3, 0x02);
-
- for (i = 0; i < 8; i++) {
- sc->upd7210.reg_res[i] = sc->res[1];
- sc->upd7210.reg_offset[i] = i * 2;
- }
-
- /* No DMA help */
- sc->upd7210.dmachan = -1;
-
- /* No "special interrupt handling" needed here. */
- sc->upd7210.irq_clear_res = NULL;
-
- upd7210attach(&sc->upd7210);
- device_printf(dev, "attached gpib%d\n", sc->upd7210.unit);
-
- if (sc->upd7210.use_fifo)
- bus_write_1(sc->res[0], hssel, 0x01); /* one-chip mode */
-
-
- return (0);
-}
-
-static int
-tnt_detach(device_t dev)
-{
- struct tnt_softc *sc;
-
- sc = device_get_softc(dev);
- bus_teardown_intr(dev, sc->res[2], sc->intr_handler);
- upd7210detach(&sc->upd7210);
-
- bus_release_resources(dev, tnt_res_spec, sc->res);
-
- return (0);
-}
-
-static device_method_t tnt4882_methods[] = {
- DEVMETHOD(device_probe, tnt_probe),
- DEVMETHOD(device_attach, tnt_attach),
- DEVMETHOD(device_detach, tnt_detach),
- { 0, 0 }
-};
-
-static driver_t pci_gpib_driver = {
- "tnt4882",
- tnt4882_methods,
- sizeof(struct tnt_softc)
-};
-
-static devclass_t pci_gpib_devclass;
-
-DRIVER_MODULE(pci_gpib, pci, pci_gpib_driver, pci_gpib_devclass, 0, 0);
diff --git a/sys/dev/ieee488/tnt4882.h b/sys/dev/ieee488/tnt4882.h
deleted file mode 100644
index 221cfd9..0000000
--- a/sys/dev/ieee488/tnt4882.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * Copyright (c) 2010 Joerg Wunsch
- * 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$
- */
-
-enum tnt4882reg {
- dir = 0x00,
- cdor = 0x00,
- isr1 = 0x02,
- imr1 = 0x02,
- isr2 = 0x04,
- imr2 = 0x04,
- accwr = 0x05,
- spsr = 0x06,
- spmr = 0x06,
- intr = 0x07,
- adsr = 0x08,
- admr = 0x08,
- cnt2 = 0x09,
- cptr = 0x0a,
- auxmr = 0x0a,
- tauxcr = 0x0a, /* 9914 mode register */
- cnt3 = 0x0b,
- adr0 = 0x0c,
- adr = 0x0c,
- hssel = 0x0d,
- adr1 = 0x0e,
- eosr = 0x0e,
- sts1 = 0x10,
- cfg = 0x10,
- dsr = 0x11,
- sh_cnt = 0x11,
- imr3 = 0x12,
- hier = 0x13,
- cnt0 = 0x14,
- misc = 0x15,
- cnt1 = 0x16,
- csr = 0x17,
- keyreg = 0x17,
- fifob = 0x18,
- fifoa = 0x19,
- isr3 = 0x1a,
- ccr = 0x1a,
- sasr = 0x1b,
- dcr = 0x1b,
- sts2 = 0x1c,
- cmdr = 0x1c,
- isr0 = 0x1d,
- imr0 = 0x1d,
- timer = 0x1e,
- bsr = 0x1f,
- bcr = 0x1f
-};
-
diff --git a/sys/dev/ieee488/ugpib.h b/sys/dev/ieee488/ugpib.h
deleted file mode 100644
index 726a702..0000000
--- a/sys/dev/ieee488/ugpib.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- */
-
-#ifndef _DEV_IEEE488_UGPIB_H_
-#define _DEV_IEEE488_UGPIB_H_
-
-/* ibfoo() return values */
-#define EDVR 0 /* System error */
-#define ECIC 1 /* Not Active Controller */
-#define ENOL 2 /* Nobody listening */
-#define EADR 3 /* Controller not addressed */
-#define EARG 4 /* Invalid argument */
-#define ESAC 5 /* Not System Controller */
-#define EABO 6 /* I/O Aborted/Time out */
-#define ENEB 7 /* No such controller */
-#define EOIP 10 /* Async I/O in progress */
-#define ECAP 11 /* No such capability */
-#define EFSO 12 /* File system error */
-#define EBUS 14 /* Command byte xfer error */
-#define ESTB 15 /* Serial poll status byte lost */
-#define ESRQ 16 /* SRQ line stuck */
-#define ETAB 20 /* Table problem */
-
-/* ibsta bits */
-#define ERR (1<<15) /* Error */
-#define TIMO (1<<14) /* Timeout */
-#define END (1<<13) /* EOI/EOS */
-#define SRQI (1<<12) /* SRQ */
-#define RQS (1<<11) /* Device requests service */
-#define SPOLL (1<<10) /* Serial Poll */
-#define EVENT (1<<9) /* Event occured */
-#define CMPL (1<<8) /* I/O complete */
-#define LOK (1<<7) /* Lockout */
-#define REM (1<<6) /* Remote */
-#define CIC (1<<5) /* CIC */
-#define ATN (1<<4) /* ATN */
-#define TACS (1<<3) /* Talker */
-#define LACS (1<<2) /* Listener */
-#define DTAS (1<<1) /* Device trigger status */
-#define DCAS (1<<0) /* Device clear state */
-
-/* Timeouts */
-#define TNONE 0
-#define T10us 1
-#define T30us 2
-#define T100us 3
-#define T300us 4
-#define T1ms 5
-#define T3ms 6
-#define T10ms 7
-#define T30ms 8
-#define T100ms 9
-#define T300ms 10
-#define T1s 11
-#define T3s 12
-#define T10s 13
-#define T30s 14
-#define T100s 15
-#define T300s 16
-#define T1000s 17
-
-/* EOS bits */
-#define REOS (1 << 10)
-#define XEOS (1 << 11)
-#define BIN (1 << 12)
-
-/* Bus commands */
-#define GTL 0x01 /* Go To Local */
-#define SDC 0x04 /* Selected Device Clear */
-#define GET 0x08 /* Group Execute Trigger */
-#define LAD 0x20 /* Listen address */
-#define UNL 0x3F /* Unlisten */
-#define TAD 0x40 /* Talk address */
-#define UNT 0x5F /* Untalk */
-
-#ifndef _KERNEL
-
-extern int ibcnt, iberr, ibsta;
-
-int ibask(int handle, int option, int *retval);
-int ibbna(int handle, char *bdname);
-int ibcac(int handle, int v);
-int ibclr(int handle);
-int ibcmd(int handle, void *buffer, long cnt);
-int ibcmda(int handle, void *buffer, long cnt);
-int ibconfig(int handle, int option, int value);
-int ibdev(int boardID, int pad, int sad, int tmo, int eot, int eos);
-int ibdiag(int handle, void *buffer, long cnt);
-int ibdma(int handle, int v);
-int ibeos(int handle, int eos);
-int ibeot(int handle, int eot);
-int ibevent(int handle, short *event);
-int ibfind(char *bdname);
-int ibgts(int handle, int v);
-int ibist(int handle, int v);
-int iblines(int handle, short *lines);
-int ibllo(int handle);
-int ibln(int handle, int padval, int sadval, short *listenflag);
-int ibloc(int handle);
-int ibonl(int handle, int v);
-int ibpad(int handle, int pad);
-int ibpct(int handle);
-int ibpoke(int handle, int option, int value);
-int ibppc(int handle, int v);
-int ibrd(int handle, void *buffer, long cnt);
-int ibrda(int handle, void *buffer, long cnt);
-int ibrdf(int handle, char *flname);
-int ibrdkey(int handle, void *buffer, int cnt);
-int ibrpp(int handle, char *ppr);
-int ibrsc(int handle, int v);
-int ibrsp(int handle, char *spr);
-int ibrsv(int handle, int v);
-int ibsad(int handle, int sad);
-int ibsgnl(int handle, int v);
-int ibsic(int handle);
-int ibsre(int handle, int v);
-int ibsrq(void (*func)(void));
-int ibstop(int handle);
-int ibtmo(int handle, int tmo);
-int ibtrap(int mask, int mode);
-int ibtrg(int handle);
-int ibwait(int handle, int mask);
-int ibwrt(int handle, const void *buffer, long cnt);
-int ibwrta(int handle, const void *buffer, long cnt);
-int ibwrtf(int handle, const char *flname);
-int ibwrtkey(int handle, const void *buffer, int cnt);
-int ibxtrc(int handle, void *buffer, long cnt);
-#endif /* _KERNEL */
-#endif /* _DEV_IEEE488_UGPIB_H_ */
diff --git a/sys/dev/ieee488/upd7210.c b/sys/dev/ieee488/upd7210.c
deleted file mode 100644
index 0e76c83..0000000
--- a/sys/dev/ieee488/upd7210.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
- * Copyright (c) 2010 Joerg Wunsch <joerg@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * High-level driver for µPD7210 based GPIB cards.
- *
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-# define GPIB_DEBUG
-# undef GPIB_DEBUG
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/module.h>
-#include <sys/rman.h>
-#include <sys/bus.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/uio.h>
-#include <sys/time.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <isa/isavar.h>
-
-#define UPD7210_HW_DRIVER
-#define UPD7210_SW_DRIVER
-#include <dev/ieee488/upd7210.h>
-#include <dev/ieee488/tnt4882.h>
-
-static MALLOC_DEFINE(M_GPIB, "GPIB", "GPIB");
-
-/* upd7210 generic stuff */
-
-void
-upd7210_print_isr(u_int isr1, u_int isr2)
-{
- printf("isr1=0x%b isr2=0x%b",
- isr1, "\20\10CPT\7APT\6DET\5ENDRX\4DEC\3ERR\2DO\1DI",
- isr2, "\20\10INT\7SRQI\6LOK\5REM\4CO\3LOKC\2REMC\1ADSC");
-}
-
-u_int
-upd7210_rd(struct upd7210 *u, enum upd7210_rreg reg)
-{
- u_int r;
-
- r = bus_read_1(u->reg_res[reg], u->reg_offset[reg]);
- u->rreg[reg] = r;
- return (r);
-}
-
-void
-upd7210_wr(struct upd7210 *u, enum upd7210_wreg reg, u_int val)
-{
-
- bus_write_1(u->reg_res[reg], u->reg_offset[reg], val);
- u->wreg[reg] = val;
- if (reg == AUXMR)
- u->wreg[8 + (val >> 5)] = val & 0x1f;
-}
-
-void
-upd7210intr(void *arg)
-{
- u_int isr_1, isr_2, isr_3;
- struct upd7210 *u;
-
- u = arg;
- mtx_lock(&u->mutex);
- isr_1 = upd7210_rd(u, ISR1);
- isr_2 = upd7210_rd(u, ISR2);
- if (u->use_fifo) {
- isr_3 = bus_read_1(u->reg_res[0], isr3);
- } else {
- isr_3 = 0;
- }
- if (isr_1 != 0 || isr_2 != 0 || isr_3 != 0) {
- if (u->busy == 0 || u->irq == NULL || !u->irq(u, isr_3)) {
-#if 0
- printf("upd7210intr [%02x %02x %02x",
- upd7210_rd(u, DIR), isr1, isr2);
- printf(" %02x %02x %02x %02x %02x] ",
- upd7210_rd(u, SPSR),
- upd7210_rd(u, ADSR),
- upd7210_rd(u, CPTR),
- upd7210_rd(u, ADR0),
- upd7210_rd(u, ADR1));
- upd7210_print_isr(isr1, isr2);
- printf("\n");
-#endif
- }
- /*
- * "special interrupt handling"
- *
- * In order to implement shared IRQs, the original
- * PCIIa uses IO locations 0x2f0 + (IRQ#) as an output
- * location. If an ISR for a particular card has
- * detected this card triggered the IRQ, it must reset
- * the card's IRQ by writing (anything) to that IO
- * location.
- *
- * Some clones apparently don't implement this
- * feature, but National Instrument cards do.
- */
- if (u->irq_clear_res != NULL)
- bus_write_1(u->irq_clear_res, 0, 42);
- }
- mtx_unlock(&u->mutex);
-}
-
-int
-upd7210_take_ctrl_async(struct upd7210 *u)
-{
- int i;
-
- upd7210_wr(u, AUXMR, AUXMR_TCA);
-
- if (!(upd7210_rd(u, ADSR) & ADSR_ATN))
- return (0);
- for (i = 0; i < 20; i++) {
- DELAY(1);
- if (!(upd7210_rd(u, ADSR) & ADSR_ATN))
- return (0);
- }
- return (1);
-}
-
-int
-upd7210_goto_standby(struct upd7210 *u)
-{
- int i;
-
- upd7210_wr(u, AUXMR, AUXMR_GTS);
-
- if (upd7210_rd(u, ADSR) & ADSR_ATN)
- return (0);
- for (i = 0; i < 20; i++) {
- DELAY(1);
- if (upd7210_rd(u, ADSR) & ADSR_ATN)
- return (0);
- }
- return (1);
-}
-
-/* Unaddressed Listen Only mode */
-
-static int
-gpib_l_irq(struct upd7210 *u, int isr_3)
-{
- int i;
- int have_data = 0;
-
- if (u->use_fifo) {
- /* TNT5004 or TNT4882 in FIFO mode */
- if (isr_3 & 0x04) {
- /* FIFO not empty */
- i = bus_read_1(u->reg_res[0], fifob);
- have_data = 1;
- bus_write_1(u->reg_res[0], cnt0, -1);
- bus_write_1(u->reg_res[0], cnt1, (-1) >> 8);
- bus_write_1(u->reg_res[0], cnt2, (-1) >> 16);
- bus_write_1(u->reg_res[0], cnt3, (-1) >> 24);
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- }
- } else if (u->rreg[ISR1] & 1) {
- i = upd7210_rd(u, DIR);
- have_data = 1;
- }
-
- if (have_data) {
- u->buf[u->buf_wp++] = i;
- u->buf_wp &= (u->bufsize - 1);
- i = (u->buf_rp + u->bufsize - u->buf_wp) & (u->bufsize - 1);
- if (i < 8) {
- if (u->use_fifo)
- bus_write_1(u->reg_res[0], imr3, 0x00);
- else
- upd7210_wr(u, IMR1, 0);
- }
- wakeup(u->buf);
- return (1);
- }
- return (0);
-}
-
-static int
-gpib_l_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
- struct upd7210 *u;
-
- u = dev->si_drv1;
-
- mtx_lock(&u->mutex);
- if (u->busy) {
- mtx_unlock(&u->mutex);
- return (EBUSY);
- }
- u->busy = 1;
- u->irq = gpib_l_irq;
- mtx_unlock(&u->mutex);
-
- u->buf = malloc(PAGE_SIZE, M_GPIB, M_WAITOK);
- u->bufsize = PAGE_SIZE;
- u->buf_wp = 0;
- u->buf_rp = 0;
-
- upd7210_wr(u, AUXMR, AUXMR_CRST); /* chip reset */
- DELAY(10000);
- upd7210_wr(u, AUXMR, C_ICR | 8); /* 8 MHz clock */
- DELAY(1000);
- upd7210_wr(u, ADR, 0x60); /* ADR0: disable listener and talker 0 */
- upd7210_wr(u, ADR, 0xe0); /* ADR1: disable listener and talker 1 */
- upd7210_wr(u, ADMR, 0x70); /* listen-only (lon) */
- upd7210_wr(u, AUXMR, AUXMR_PON); /* immediate execute power-on (pon) */
- if (u->use_fifo) {
- /* TNT5004 or TNT4882 in FIFO mode */
- bus_write_1(u->reg_res[0], cmdr, 0x10); /* reset FIFO */
- bus_write_1(u->reg_res[0], cfg, 0x20); /* xfer IN, 8-bit FIFO */
- bus_write_1(u->reg_res[0], cnt0, -1);
- bus_write_1(u->reg_res[0], cnt1, (-1) >> 8);
- bus_write_1(u->reg_res[0], cnt2, (-1) >> 16);
- bus_write_1(u->reg_res[0], cnt3, (-1) >> 24);
- bus_write_1(u->reg_res[0], cmdr, 0x04); /* GO */
- bus_write_1(u->reg_res[0], imr3, 0x04); /* NEF IE */
- } else {
- /* µPD7210/NAT7210, or TNT4882 in non-FIFO mode */
- upd7210_wr(u, IMR1, 0x01); /* data in interrupt enable */
- }
- return (0);
-}
-
-static int
-gpib_l_close(struct cdev *dev, int oflags, int devtype, struct thread *td)
-{
- struct upd7210 *u;
-
- u = dev->si_drv1;
-
- mtx_lock(&u->mutex);
- u->busy = 0;
- if (u->use_fifo) {
- /* TNT5004 or TNT4882 in FIFO mode */
- bus_write_1(u->reg_res[0], cmdr, 0x22); /* soft RESET */
- bus_write_1(u->reg_res[0], imr3, 0x00);
- }
- upd7210_wr(u, AUXMR, AUXMR_CRST);
- DELAY(10000);
- upd7210_wr(u, IMR1, 0x00);
- upd7210_wr(u, IMR2, 0x00);
- free(u->buf, M_GPIB);
- u->buf = NULL;
- mtx_unlock(&u->mutex);
- return (0);
-}
-
-static int
-gpib_l_read(struct cdev *dev, struct uio *uio, int ioflag)
-{
- struct upd7210 *u;
- int error;
- size_t z;
-
- u = dev->si_drv1;
- error = 0;
-
- mtx_lock(&u->mutex);
- while (u->buf_wp == u->buf_rp) {
- error = msleep(u->buf, &u->mutex, PZERO | PCATCH,
- "gpibrd", hz);
- if (error && error != EWOULDBLOCK) {
- mtx_unlock(&u->mutex);
- return (error);
- }
- }
- while (uio->uio_resid > 0 && u->buf_wp != u->buf_rp) {
- if (u->buf_wp < u->buf_rp)
- z = u->bufsize - u->buf_rp;
- else
- z = u->buf_wp - u->buf_rp;
- if (z > uio->uio_resid)
- z = uio->uio_resid;
- mtx_unlock(&u->mutex);
- error = uiomove(u->buf + u->buf_rp, z, uio);
- mtx_lock(&u->mutex);
- if (error)
- break;
- u->buf_rp += z;
- u->buf_rp &= (u->bufsize - 1);
- }
- if (u->use_fifo) {
- bus_write_1(u->reg_res[0], imr3, 0x04); /* NFF IE */
- } else {
- if (u->wreg[IMR1] == 0)
- upd7210_wr(u, IMR1, 0x01);
- }
- mtx_unlock(&u->mutex);
- return (error);
-}
-
-static struct cdevsw gpib_l_cdevsw = {
- .d_version = D_VERSION,
- .d_name = "gpib_l",
- .d_open = gpib_l_open,
- .d_close = gpib_l_close,
- .d_read = gpib_l_read,
-};
-
-/* Housekeeping */
-
-static struct unrhdr *units;
-
-void
-upd7210attach(struct upd7210 *u)
-{
- struct cdev *dev;
-
- if (units == NULL)
- units = new_unrhdr(0, INT_MAX, NULL);
- u->unit = alloc_unr(units);
- mtx_init(&u->mutex, "gpib", NULL, MTX_DEF);
- u->cdev = make_dev(&gpib_l_cdevsw, u->unit,
- UID_ROOT, GID_WHEEL, 0444,
- "gpib%ul", u->unit);
- u->cdev->si_drv1 = u;
-
- dev = make_dev(&gpib_ib_cdevsw, u->unit,
- UID_ROOT, GID_WHEEL, 0444,
- "gpib%uib", u->unit);
- dev->si_drv1 = u;
- dev_depends(u->cdev, dev);
-}
-
-void
-upd7210detach(struct upd7210 *u)
-{
-
- destroy_dev(u->cdev);
- mtx_destroy(&u->mutex);
- free_unr(units, u->unit);
-}
diff --git a/sys/dev/ieee488/upd7210.h b/sys/dev/ieee488/upd7210.h
deleted file mode 100644
index 27e3a7a..0000000
--- a/sys/dev/ieee488/upd7210.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/*-
- * Copyright (c) 2005 Poul-Henning Kamp <phk@FreeBSD.org>
- * Copyright (c) 2010 Joerg Wunsch <joerg@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- *
- * Locating an actual µPD7210 data book has proven quite impossible for me.
- * There are a fair number of newer chips which are supersets of the µPD7210
- * but they are particular eager to comprehensively mark what the extensions
- * are and what is in the base set. Some even give the registers and their
- * bits new names.
- *
- * The following information is based on a description of the µPD7210 found
- * in an old manual for a VME board which used the chip.
- */
-
-#ifndef _DEV_IEEE488_UPD7210_H_
-#define _DEV_IEEE488_UPD7210_H_
-#ifdef _KERNEL
-
-struct upd7210;
-struct ibfoo;
-
-/* upd7210 interface definitions for HW drivers */
-
-typedef int upd7210_irq_t(struct upd7210 *, int);
-
-struct upd7210 {
- struct resource *reg_res[8];
- struct resource *irq_clear_res;
- u_int reg_offset[8];
- int dmachan;
- int unit;
- int use_fifo;
-
- /* private stuff */
- struct mtx mutex;
- uint8_t rreg[8];
- uint8_t wreg[8 + 8];
-
- upd7210_irq_t *irq;
-
- int busy;
- u_char *buf;
- size_t bufsize;
- u_int buf_wp;
- u_int buf_rp;
- struct cdev *cdev;
-
- struct ibfoo *ibfoo;
-};
-
-#ifdef UPD7210_HW_DRIVER
-void upd7210intr(void *);
-void upd7210attach(struct upd7210 *);
-void upd7210detach(struct upd7210 *);
-#endif
-
-#ifdef UPD7210_SW_DRIVER
-
-/* upd7210 hardware definitions. */
-
-/* Write registers */
-enum upd7210_wreg {
- CDOR = 0, /* Command/Data Out Register */
- IMR1 = 1, /* Interrupt Mask Register 1 */
- IMR2 = 2, /* Interrupt Mask Register 2 */
- SPMR = 3, /* Serial Poll Mode Register */
- ADMR = 4, /* ADdress Mode Register */
- AUXMR = 5, /* AUXilliary Mode Register */
- ICR = 5, /* Internal Counter Register */
- PPR = 5, /* Parallel Poll Register */
- AUXRA = 5, /* AUXilliary Register A */
- AUXRB = 5, /* AUXilliary Register B */
- AUXRE = 5, /* AUXilliary Register E */
- ADR = 6, /* ADdress Register */
- EOSR = 7, /* End-Of-String Register */
-};
-
-/* Read registers */
-enum upd7210_rreg {
- DIR = 0, /* Data In Register */
- ISR1 = 1, /* Interrupt Status Register 1 */
- ISR2 = 2, /* Interrupt Status Register 2 */
- SPSR = 3, /* Serial Poll Status Register */
- ADSR = 4, /* ADdress Status Register */
- CPTR = 5, /* Command Pass Though Register */
- ADR0 = 6, /* ADdress Register 0 */
- ADR1 = 7, /* ADdress Register 1 */
-};
-
-/* Bits for ISR1 and IMR1 */
-#define IXR1_DI (1 << 0) /* Data In */
-#define IXR1_DO (1 << 1) /* Data Out */
-#define IXR1_ERR (1 << 2) /* Error */
-#define IXR1_DEC (1 << 3) /* Device Clear */
-#define IXR1_ENDRX (1 << 4) /* End Received */
-#define IXR1_DET (1 << 5) /* Device Execute Trigger */
-#define IXR1_APT (1 << 6) /* Address Pass-Through */
-#define IXR1_CPT (1 << 7) /* Command Pass-Through */
-
-/* Bits for ISR2 and IMR2 */
-#define IXR2_ADSC (1 << 0) /* Addressed Status Change */
-#define IXR2_REMC (1 << 1) /* Remote Change */
-#define IXR2_LOKC (1 << 2) /* Lockout Change */
-#define IXR2_CO (1 << 3) /* Command Out */
-#define ISR2_REM (1 << 4) /* Remove */
-#define IMR2_DMAI (1 << 4) /* DMA In Enable */
-#define ISR2_LOK (1 << 5) /* Lockout */
-#define IMR2_DMAO (1 << 5) /* DMA Out Enable */
-#define IXR2_SRQI (1 << 6) /* Service Request Input */
-#define ISR2_INT (1 << 7) /* Interrupt */
-
-#define SPSR_PEND (1 << 6) /* Pending */
-#define SPMR_RSV (1 << 6) /* Request SerVice */
-
-#define ADSR_MJMN (1 << 0) /* MaJor MiNor */
-#define ADSR_TA (1 << 1) /* Talker Active */
-#define ADSR_LA (1 << 2) /* Listener Active */
-#define ADSR_TPAS (1 << 3) /* Talker Primary Addr. State */
-#define ADSR_LPAS (1 << 4) /* Listener Primary Addr. State */
-#define ADSR_SPMS (1 << 5) /* Serial Poll Mode State */
-#define ADSR_ATN (1 << 6) /* Attention */
-#define ADSR_CIC (1 << 7) /* Controller In Charge */
-
-#define ADMR_ADM0 (1 << 0) /* Address Mode 0 */
-#define ADMR_ADM1 (1 << 1) /* Address Mode 1 */
-#define ADMR_TRM0 (1 << 4) /* Transmit/Receive Mode 0 */
-#define ADMR_TRM1 (1 << 5) /* Transmit/Receive Mode 1 */
-#define ADMR_LON (1 << 6) /* Listen Only */
-#define ADMR_TON (1 << 7) /* Talk Only */
-
-/* Constant part of overloaded write registers */
-#define C_ICR 0x20
-#define C_PPR 0x60
-#define C_AUXA 0x80
-#define C_AUXB 0xa0
-#define C_AUXE 0xc0
-
-#define AUXMR_PON 0x00 /* Immediate Execute pon */
-#define AUXMR_CPP 0x01 /* Clear Parallel Poll */
-#define AUXMR_CRST 0x02 /* Chip Reset */
-#define AUXMR_RFD 0x03 /* Finish Handshake */
-#define AUXMR_TRIG 0x04 /* Trigger */
-#define AUXMR_RTL 0x05 /* Return to local */
-#define AUXMR_SEOI 0x06 /* Send EOI */
-#define AUXMR_NVSA 0x07 /* Non-Valid Secondary cmd/addr */
- /* 0x08 undefined/unknown */
-#define AUXMR_SPP 0x09 /* Set Parallel Poll */
- /* 0x0a undefined/unknown */
- /* 0x0b undefined/unknown */
- /* 0x0c undefined/unknown */
- /* 0x0d undefined/unknown */
- /* 0x0e undefined/unknown */
-#define AUXMR_VSA 0x0f /* Valid Secondary cmd/addr */
-#define AUXMR_GTS 0x10 /* Go to Standby */
-#define AUXMR_TCA 0x11 /* Take Control Async (pulsed) */
-#define AUXMR_TCS 0x12 /* Take Control Synchronously */
-#define AUXMR_LISTEN 0x13 /* Listen */
-#define AUXMR_DSC 0x14 /* Disable System Control */
- /* 0x15 undefined/unknown */
-#define AUXMR_SIFC 0x16 /* Set IFC */
-#define AUXMR_CREN 0x17 /* Clear REN */
- /* 0x18 undefined/unknown */
- /* 0x19 undefined/unknown */
-#define AUXMR_TCSE 0x1a /* Take Control Sync on End */
-#define AUXMR_LCM 0x1b /* Listen Continuously Mode */
-#define AUXMR_LUNL 0x1c /* Local Unlisten */
-#define AUXMR_EPP 0x1d /* Execute Parallel Poll */
-#define AUXMR_CIFC 0x1e /* Clear IFC */
-#define AUXMR_SREN 0x1f /* Set REN */
-
-#define PPR_U (1 << 4) /* Unconfigure */
-#define PPR_S (1 << 3) /* Status Polarity */
-
-#define AUXA_HLDA (1 << 0) /* Holdoff on All */
-#define AUXA_HLDE (1 << 1) /* Holdoff on END */
-#define AUXA_REOS (1 << 2) /* End on EOS received */
-#define AUXA_XEOS (1 << 3) /* Transmit END with EOS */
-#define AUXA_BIN (1 << 4) /* Binary */
-
-#define AUXB_CPTE (1 << 0) /* Cmd Pass Through Enable */
-#define AUXB_SPEOI (1 << 1) /* Send Serial Poll EOI */
-#define AUXB_TRI (1 << 2) /* Three-State Timing */
-#define AUXB_INV (1 << 3) /* Invert */
-#define AUXB_ISS (1 << 4) /* Individual Status Select */
-
-#define AUXE_DHDT (1 << 0) /* DAC Holdoff on DTAS */
-#define AUXE_DHDC (1 << 1) /* DAC Holdoff on DCAS */
-
-#define ADR0_DL0 (1 << 5) /* Disable Listener 0 */
-#define ADR0_DT0 (1 << 6) /* Disable Talker 0 */
-
-#define ADR_DL (1 << 5) /* Disable Listener */
-#define ADR_DT (1 << 6) /* Disable Talker */
-#define ADR_ARS (1 << 7) /* Address Register Select */
-
-#define ADR1_DL1 (1 << 5) /* Disable Listener 1 */
-#define ADR1_DT1 (1 << 6) /* Disable Talker 1 */
-#define ADR1_EOI (1 << 7) /* End or Identify */
-
-/* Stuff from software drivers */
-extern struct cdevsw gpib_ib_cdevsw;
-
-/* Stuff from upd7210.c */
-void upd7210_print_isr(u_int isr1, u_int isr2);
-u_int upd7210_rd(struct upd7210 *u, enum upd7210_rreg reg);
-void upd7210_wr(struct upd7210 *u, enum upd7210_wreg reg, u_int val);
-int upd7210_take_ctrl_async(struct upd7210 *u);
-int upd7210_goto_standby(struct upd7210 *u);
-
-#endif /* UPD7210_SW_DRIVER */
-
-#endif /* _KERNEL */
-#endif /* _DEV_IEEE488_UPD7210_H_ */
diff --git a/sys/dev/ipmi/ipmi_kcs.c b/sys/dev/ipmi/ipmi_kcs.c
index 76adf8c..eb5884a 100644
--- a/sys/dev/ipmi/ipmi_kcs.c
+++ b/sys/dev/ipmi/ipmi_kcs.c
@@ -184,6 +184,8 @@ kcs_start_write(struct ipmi_softc *sc)
for (retry = 0; retry < 10; retry++) {
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
/* Clear OBF */
kcs_clear_obf(sc, status);
@@ -193,6 +195,9 @@ kcs_start_write(struct ipmi_softc *sc)
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
+
if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_WRITE)
break;
DELAY(1000000);
@@ -222,6 +227,8 @@ kcs_write_byte(struct ipmi_softc *sc, u_char data)
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
return (0);
@@ -244,6 +251,8 @@ kcs_write_last_byte(struct ipmi_softc *sc, u_char data)
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
/* error state */
@@ -274,6 +283,8 @@ kcs_read_byte(struct ipmi_softc *sc, u_char *data)
/* Wait for OBF = 1 */
status = kcs_wait_for_obf(sc, 1);
+ if ((status & KCS_STATUS_OBF) == 0)
+ return (0);
/* Read Data_out */
*data = INB(sc, KCS_DATA);
@@ -288,6 +299,8 @@ kcs_read_byte(struct ipmi_softc *sc, u_char *data)
/* Wait for OBF = 1*/
status = kcs_wait_for_obf(sc, 1);
+ if ((status & KCS_STATUS_OBF) == 0)
+ return (0);
/* Read Dummy */
dummy = INB(sc, KCS_DATA);
diff --git a/sys/dev/isci/isci_controller.c b/sys/dev/isci/isci_controller.c
index f3ff082..b0f4285 100644
--- a/sys/dev/isci/isci_controller.c
+++ b/sys/dev/isci/isci_controller.c
@@ -373,6 +373,8 @@ SCI_STATUS isci_controller_initialize(struct ISCI_CONTROLLER *controller)
fail_on_timeout = 1;
TUNABLE_INT_FETCH("hw.isci.fail_on_task_timeout", &fail_on_timeout);
+ controller->fail_on_task_timeout = fail_on_timeout;
+
/* Attach to CAM using xpt_bus_register now, then immediately freeze
* the simq. It will get released later when initial domain discovery
* is complete.
diff --git a/sys/dev/isci/isci_sysctl.c b/sys/dev/isci/isci_sysctl.c
index 62a10b9..a7c56c6 100644
--- a/sys/dev/isci/isci_sysctl.c
+++ b/sys/dev/isci/isci_sysctl.c
@@ -226,12 +226,13 @@ static int
isci_sysctl_fail_on_task_timeout(SYSCTL_HANDLER_ARGS)
{
struct isci_softc *isci = (struct isci_softc *)arg1;
- int32_t fail_on_timeout = 0;
+ int32_t fail_on_timeout;
int error, i;
+ fail_on_timeout = isci->controllers[0].fail_on_task_timeout;
error = sysctl_handle_int(oidp, &fail_on_timeout, 0, req);
- if (error || fail_on_timeout == 0)
+ if (error || req->newptr == NULL)
return (error);
for (i = 0; i < isci->controller_count; i++)
diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c
index f9edc82..0d762aa 100644
--- a/sys/dev/iscsi/iscsi.c
+++ b/sys/dev/iscsi/iscsi.c
@@ -2157,6 +2157,10 @@ iscsi_action_scsiio(struct iscsi_session *is, union ccb *ccb)
ISCSI_SESSION_DEBUG(is, "len %zd -> %zd", len, is->is_first_burst_length);
len = is->is_first_burst_length;
}
+ if (len > is->is_max_data_segment_length) {
+ ISCSI_SESSION_DEBUG(is, "len %zd -> %zd", len, is->is_max_data_segment_length);
+ len = is->is_max_data_segment_length;
+ }
error = icl_pdu_append_data(request, csio->data_ptr, len, M_NOWAIT);
if (error != 0) {
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c
index bf8c98d..b287c6c 100644
--- a/sys/dev/iwn/if_iwn.c
+++ b/sys/dev/iwn/if_iwn.c
@@ -279,7 +279,6 @@ static int iwn_send_btcoex(struct iwn_softc *);
static int iwn_send_advanced_btcoex(struct iwn_softc *);
static int iwn5000_runtime_calib(struct iwn_softc *);
static int iwn_config(struct iwn_softc *);
-static uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int);
static int iwn_scan(struct iwn_softc *, struct ieee80211vap *,
struct ieee80211_scan_state *, struct ieee80211_channel *);
static int iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
@@ -6527,18 +6526,6 @@ iwn_config(struct iwn_softc *sc)
return 0;
}
-/*
- * Add an ssid element to a frame.
- */
-static uint8_t *
-ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len)
-{
- *frm++ = IEEE80211_ELEMID_SSID;
- *frm++ = len;
- memcpy(frm, ssid, len);
- return frm + len;
-}
-
static uint16_t
iwn_get_active_dwell_time(struct iwn_softc *sc,
struct ieee80211_channel *c, uint8_t n_probes)
diff --git a/sys/dev/mmc/mmc.c b/sys/dev/mmc/mmc.c
index a3b9744..ec4d358 100644
--- a/sys/dev/mmc/mmc.c
+++ b/sys/dev/mmc/mmc.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/endian.h>
#include <sys/sysctl.h>
+#include <sys/time.h>
#include <dev/mmc/mmcreg.h>
#include <dev/mmc/mmcbrvar.h>
@@ -76,8 +77,13 @@ struct mmc_softc {
struct intr_config_hook config_intrhook;
device_t owner;
uint32_t last_rca;
+ int squelched; /* suppress reporting of (expected) errors */
+ int log_count;
+ struct timeval log_time;
};
+#define LOG_PPS 5 /* Log no more than 5 errors per second. */
+
/*
* Per-card data
*/
@@ -426,6 +432,13 @@ mmc_wait_for_cmd(struct mmc_softc *sc, struct mmc_command *cmd, int retries)
err = cmd->error;
} while (err != MMC_ERR_NONE && retries-- > 0);
+ if (err != MMC_ERR_NONE && sc->squelched == 0) {
+ if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) {
+ device_printf(sc->dev, "CMD%d failed, RESULT: %d\n",
+ cmd->opcode, err);
+ }
+ }
+
return (err);
}
@@ -436,6 +449,8 @@ mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
struct mmc_command appcmd;
int err;
+ /* Squelch error reporting at lower levels, we report below. */
+ sc->squelched++;
do {
memset(&appcmd, 0, sizeof(appcmd));
appcmd.opcode = MMC_APP_CMD;
@@ -455,6 +470,14 @@ mmc_wait_for_app_cmd(struct mmc_softc *sc, uint32_t rca,
err = cmd->error;
}
} while (err != MMC_ERR_NONE && retries-- > 0);
+ sc->squelched--;
+
+ if (err != MMC_ERR_NONE && sc->squelched == 0) {
+ if (ppsratecheck(&sc->log_time, &sc->log_count, LOG_PPS)) {
+ device_printf(sc->dev, "ACMD%d failed, RESULT: %d\n",
+ cmd->opcode, err);
+ }
+ }
return (err);
}
@@ -760,6 +783,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
mmcbr_set_bus_width(sc->dev, bus_width_8);
mmcbr_update_ios(sc->dev);
+ sc->squelched++; /* Errors are expected, squelch reporting. */
memset(&cmd, 0, sizeof(cmd));
memset(&data, 0, sizeof(data));
cmd.opcode = MMC_BUSTEST_W;
@@ -783,6 +807,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
data.len = 8;
data.flags = MMC_DATA_READ;
err = mmc_wait_for_cmd(sc, &cmd, 0);
+ sc->squelched--;
mmcbr_set_bus_width(sc->dev, bus_width_1);
mmcbr_update_ios(sc->dev);
@@ -795,6 +820,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
mmcbr_set_bus_width(sc->dev, bus_width_4);
mmcbr_update_ios(sc->dev);
+ sc->squelched++; /* Errors are expected, squelch reporting. */
memset(&cmd, 0, sizeof(cmd));
memset(&data, 0, sizeof(data));
cmd.opcode = MMC_BUSTEST_W;
@@ -818,6 +844,7 @@ mmc_test_bus_width(struct mmc_softc *sc)
data.len = 4;
data.flags = MMC_DATA_READ;
err = mmc_wait_for_cmd(sc, &cmd, 0);
+ sc->squelched--;
mmcbr_set_bus_width(sc->dev, bus_width_1);
mmcbr_update_ios(sc->dev);
@@ -1270,7 +1297,9 @@ mmc_discover_cards(struct mmc_softc *sc)
if (bootverbose || mmc_debug)
device_printf(sc->dev, "Probing cards\n");
while (1) {
+ sc->squelched++; /* Errors are expected, squelch reporting. */
err = mmc_all_send_cid(sc, raw_cid);
+ sc->squelched--;
if (err == MMC_ERR_TIMEOUT)
break;
if (err != MMC_ERR_NONE) {
@@ -1417,10 +1446,10 @@ mmc_discover_cards(struct mmc_softc *sc)
break;
}
+ mmc_select_card(sc, ivar->rca);
+
/* Only MMC >= 4.x cards support EXT_CSD. */
if (ivar->csd.spec_vers >= 4) {
- /* Card must be selected to fetch EXT_CSD. */
- mmc_select_card(sc, ivar->rca);
mmc_send_ext_csd(sc, ivar->raw_ext_csd);
/* Handle extended capacity from EXT_CSD */
sec_count = ivar->raw_ext_csd[EXT_CSD_SEC_CNT] +
@@ -1450,7 +1479,6 @@ mmc_discover_cards(struct mmc_softc *sc)
mmc_switch(sc, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_ERASE_GRP_DEF, 1);
}
- mmc_select_card(sc, 0);
} else {
ivar->bus_width = bus_width_1;
ivar->timing = bus_timing_normal;
@@ -1477,6 +1505,7 @@ mmc_discover_cards(struct mmc_softc *sc)
child = device_add_child(sc->dev, NULL, -1);
device_set_ivars(child, ivar);
}
+ mmc_select_card(sc, 0);
}
}
@@ -1536,6 +1565,7 @@ mmc_go_discovery(struct mmc_softc *sc)
/*
* First, try SD modes
*/
+ sc->squelched++; /* Errors are expected, squelch reporting. */
mmcbr_set_mode(dev, mode_sd);
mmc_power_up(sc);
mmcbr_set_bus_mode(dev, pushpull);
@@ -1561,6 +1591,7 @@ mmc_go_discovery(struct mmc_softc *sc)
"MMC probe: OK (OCR: 0x%08x)\n", ocr);
} else if (bootverbose || mmc_debug)
device_printf(sc->dev, "SD probe: OK (OCR: 0x%08x)\n", ocr);
+ sc->squelched--;
mmcbr_set_ocr(dev, mmc_select_vdd(sc, ocr));
if (mmcbr_get_ocr(dev) != 0)
diff --git a/sys/dev/ofw/ofw_cpu.c b/sys/dev/ofw/ofw_cpu.c
index 2265140..1d01b63 100644
--- a/sys/dev/ofw/ofw_cpu.c
+++ b/sys/dev/ofw/ofw_cpu.c
@@ -171,7 +171,7 @@ ofw_cpu_probe(device_t dev)
{
const char *type = ofw_bus_get_type(dev);
- if (strcmp(type, "cpu") != 0)
+ if (type == NULL || strcmp(type, "cpu") != 0)
return (ENXIO);
device_set_desc(dev, "Open Firmware CPU");
@@ -182,12 +182,20 @@ static int
ofw_cpu_attach(device_t dev)
{
struct ofw_cpu_softc *sc;
+ phandle_t node;
uint32_t cell;
sc = device_get_softc(dev);
- OF_getprop(ofw_bus_get_node(dev), "reg", &cell, sizeof(cell));
+ node = ofw_bus_get_node(dev);
+ if (OF_getencprop(node, "reg", &cell, sizeof(cell)) < 0) {
+ cell = device_get_unit(dev);
+ device_printf(dev, "missing 'reg' property, using %u\n", cell);
+ }
sc->sc_cpu_pcpu = pcpu_find(cell);
- OF_getprop(ofw_bus_get_node(dev), "clock-frequency", &cell, sizeof(cell));
+ if (OF_getencprop(node, "clock-frequency", &cell, sizeof(cell)) < 0) {
+ device_printf(dev, "missing 'clock-frequency' property\n");
+ return (ENXIO);
+ }
sc->sc_nominal_mhz = cell / 1000000; /* convert to MHz */
bus_generic_probe(dev);
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index d2ac111..8f87851 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -268,7 +268,7 @@ static const struct pci_quirk pci_quirks[] = {
{ 0x43851002, PCI_QUIRK_UNMAP_REG, 0x14, 0 },
/*
- * Atheros AR8161/AR8162/E2200 ethernet controller has a bug that
+ * Atheros AR8161/AR8162/E2200 Ethernet controllers have a bug that
* MSI interrupt does not assert if PCIM_CMD_INTxDIS bit of the
* command register is set.
*/
@@ -276,6 +276,17 @@ static const struct pci_quirk pci_quirks[] = {
{ 0xE0911969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 },
{ 0x10901969, PCI_QUIRK_MSI_INTX_BUG, 0, 0 },
+ /*
+ * Broadcom BCM5714(S)/BCM5715(S)/BCM5780(S) Ethernet MACs don't
+ * issue MSI interrupts with PCIM_CMD_INTxDIS set either.
+ */
+ { 0x166814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714 */
+ { 0x166914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5714S */
+ { 0x166a14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780 */
+ { 0x166b14e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5780S */
+ { 0x167814e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715 */
+ { 0x167914e4, PCI_QUIRK_MSI_INTX_BUG, 0, 0 }, /* BCM5715S */
+
{ 0 }
};
@@ -3866,14 +3877,16 @@ pci_setup_intr(device_t dev, device_t child, struct resource *irq, int flags,
mte->mte_handlers++;
}
- if (!pci_has_quirk(pci_get_devid(dev),
- PCI_QUIRK_MSI_INTX_BUG)) {
- /*
- * Make sure that INTx is disabled if we are
- * using MSI/MSIX
- */
+ /*
+ * Make sure that INTx is disabled if we are using MSI/MSI-X,
+ * unless the device is affected by PCI_QUIRK_MSI_INTX_BUG,
+ * in which case we "enable" INTx so MSI/MSI-X actually works.
+ */
+ if (!pci_has_quirk(pci_get_devid(child),
+ PCI_QUIRK_MSI_INTX_BUG))
pci_set_command_bit(dev, child, PCIM_CMD_INTxDIS);
- }
+ else
+ pci_clear_command_bit(dev, child, PCIM_CMD_INTxDIS);
bad:
if (error) {
(void)bus_generic_teardown_intr(dev, child, irq,
diff --git a/sys/dev/sdhci/sdhci.c b/sys/dev/sdhci/sdhci.c
index f92d42b..98861ab6 100644
--- a/sys/dev/sdhci/sdhci.c
+++ b/sys/dev/sdhci/sdhci.c
@@ -149,7 +149,6 @@ static void
sdhci_reset(struct sdhci_slot *slot, uint8_t mask)
{
int timeout;
- uint8_t res;
if (slot->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
if (!(RD4(slot, SDHCI_PRESENT_STATE) &
@@ -168,26 +167,43 @@ sdhci_reset(struct sdhci_slot *slot, uint8_t mask)
sdhci_set_clock(slot, clock);
}
- WR1(slot, SDHCI_SOFTWARE_RESET, mask);
-
if (mask & SDHCI_RESET_ALL) {
slot->clock = 0;
slot->power = 0;
}
+ WR1(slot, SDHCI_SOFTWARE_RESET, mask);
+
+ if (slot->quirks & SDHCI_QUIRK_WAITFOR_RESET_ASSERTED) {
+ /*
+ * Resets on TI OMAPs and AM335x are incompatible with SDHCI
+ * specification. The reset bit has internal propagation delay,
+ * so a fast read after write returns 0 even if reset process is
+ * in progress. The workaround is to poll for 1 before polling
+ * for 0. In the worst case, if we miss seeing it asserted the
+ * time we spent waiting is enough to ensure the reset finishes.
+ */
+ timeout = 10000;
+ while ((RD1(slot, SDHCI_SOFTWARE_RESET) & mask) != mask) {
+ if (timeout <= 0)
+ break;
+ timeout--;
+ DELAY(1);
+ }
+ }
+
/* Wait max 100 ms */
- timeout = 100;
+ timeout = 10000;
/* Controller clears the bits when it's done */
- while ((res = RD1(slot, SDHCI_SOFTWARE_RESET)) & mask) {
- if (timeout == 0) {
- slot_printf(slot,
- "Reset 0x%x never completed - 0x%x.\n",
- (int)mask, (int)res);
+ while (RD1(slot, SDHCI_SOFTWARE_RESET) & mask) {
+ if (timeout <= 0) {
+ slot_printf(slot, "Reset 0x%x never completed.\n",
+ mask);
sdhci_dumpregs(slot);
return;
}
timeout--;
- DELAY(1000);
+ DELAY(10);
}
}
@@ -713,9 +729,13 @@ sdhci_timeout(void *arg)
struct sdhci_slot *slot = arg;
if (slot->curcmd != NULL) {
+ slot_printf(slot, " Controller timeout\n");
+ sdhci_dumpregs(slot);
sdhci_reset(slot, SDHCI_RESET_CMD|SDHCI_RESET_DATA);
slot->curcmd->error = MMC_ERR_TIMEOUT;
sdhci_req_done(slot);
+ } else {
+ slot_printf(slot, " Spurious timeout - no active command\n");
}
}
@@ -1274,7 +1294,9 @@ sdhci_generic_intr(struct sdhci_slot *slot)
/* Handle data interrupts. */
if (intmask & SDHCI_INT_DATA_MASK) {
WR4(slot, SDHCI_INT_STATUS, intmask & SDHCI_INT_DATA_MASK);
- sdhci_data_irq(slot, intmask & SDHCI_INT_DATA_MASK);
+ /* Dont call data_irq in case of errored command */
+ if ((intmask & SDHCI_INT_CMD_ERROR_MASK) == 0)
+ sdhci_data_irq(slot, intmask & SDHCI_INT_DATA_MASK);
}
/* Handle AutoCMD12 error interrupt. */
if (intmask & SDHCI_INT_ACMD12ERR) {
diff --git a/sys/dev/sdhci/sdhci.h b/sys/dev/sdhci/sdhci.h
index 5cde2b0..ff1576e 100644
--- a/sys/dev/sdhci/sdhci.h
+++ b/sys/dev/sdhci/sdhci.h
@@ -59,6 +59,8 @@
#define SDHCI_QUIRK_MISSING_CAPS (1<<12)
/* Hardware shifts the 136-bit response, don't do it in software. */
#define SDHCI_QUIRK_DONT_SHIFT_RESPONSE (1<<13)
+/* Wait to see reset bit asserted before waiting for de-asserted */
+#define SDHCI_QUIRK_WAITFOR_RESET_ASSERTED (1<<14)
/*
* Controller registers
@@ -182,8 +184,11 @@
#define SDHCI_INT_NORMAL_MASK 0x00007FFF
#define SDHCI_INT_ERROR_MASK 0xFFFF8000
-#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
+#define SDHCI_INT_CMD_ERROR_MASK (SDHCI_INT_TIMEOUT | \
SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
+
+#define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_CMD_ERROR_MASK)
+
#define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c
index 1799d47..6b2f6b8 100644
--- a/sys/dev/usb/quirk/usb_quirk.c
+++ b/sys/dev/usb/quirk/usb_quirk.c
@@ -449,6 +449,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = {
USB_QUIRK(WESTERN, MYPASSPORT_08, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(WESTERN, MYPASSPORT_09, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(WESTERN, MYPASSPORT_10, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
+ USB_QUIRK(WESTERN, MYPASSPORT_11, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(WESTERN, MYPASSPORTES_00, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(WESTERN, MYPASSPORTES_01, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
USB_QUIRK(WESTERN, MYPASSPORTES_02, 0x0000, 0xffff, UQ_MSC_NO_SYNC_CACHE),
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
index 2d86d1b..b9ea927 100644
--- a/sys/dev/usb/usbdevs
+++ b/sys/dev/usb/usbdevs
@@ -2411,6 +2411,8 @@ product INTEL EASYPC_CAMERA 0x0110 Easy PC Camera
product INTEL TESTBOARD 0x9890 82930 test board
product INTEL2 IRMH 0x0020 Integrated Rate Matching Hub
product INTEL2 IRMH2 0x0024 Integrated Rate Matching Hub
+product INTEL2 IRMH3 0x8000 Integrated Rate Matching Hub
+product INTEL2 IRMH4 0x8008 Integrated Rate Matching Hub
/* Interbiometric products */
product INTERBIOMETRICS IOBOARD 0x1002 FTDI compatible adapter
@@ -4492,6 +4494,7 @@ product WESTERN EXTHDD 0x0400 External HDD
product WESTERN HUB 0x0500 USB HUB
product WESTERN MYBOOK 0x0901 MyBook External HDD
product WESTERN MYPASSPORT_00 0x0704 MyPassport External HDD
+product WESTERN MYPASSPORT_11 0x0741 MyPassport External HDD
product WESTERN MYPASSPORT_01 0x0746 MyPassport External HDD
product WESTERN MYPASSPORT_02 0x0748 MyPassport External HDD
product WESTERN MYPASSPORT_03 0x074A MyPassport External HDD
diff --git a/sys/dev/vt/hw/efifb/efifb.c b/sys/dev/vt/hw/efifb/efifb.c
index 05b2d79..7695547 100644
--- a/sys/dev/vt/hw/efifb/efifb.c
+++ b/sys/dev/vt/hw/efifb/efifb.c
@@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/fbio.h>
#include <sys/linker.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/rman.h>
#include "opt_platform.h"
@@ -179,3 +182,53 @@ vt_efifb_remap(void *xinfo)
info->fb_size, VM_MEMATTR_WRITE_COMBINING);
}
+/* Dummy NewBus functions to reserve the resources used by the efifb driver */
+static void
+vtefifb_identify(driver_t *driver, device_t parent)
+{
+
+ if (local_info.fb_pbase == 0 || local_info.fb_size == 0)
+ return;
+
+ if (BUS_ADD_CHILD(parent, 0, driver->name, 0) == NULL)
+ panic("Unable to attach vt_efifb console");
+}
+
+static int
+vtefifb_probe(device_t dev)
+{
+
+ device_set_desc(dev, "vt_efifb driver");
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+vtefifb_attach(device_t dev)
+{
+ struct resource *pseudo_phys_res;
+ int res_id;
+
+ res_id = 0;
+ pseudo_phys_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &res_id, local_info.fb_pbase,
+ local_info.fb_pbase + local_info.fb_size,
+ local_info.fb_size, RF_ACTIVE);
+ if (pseudo_phys_res == NULL)
+ panic("Unable to reserve vt_efifb memory");
+ return (0);
+}
+
+/*-------------------- Private Device Attachment Data -----------------------*/
+static device_method_t vtefifb_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, vtefifb_identify),
+ DEVMETHOD(device_probe, vtefifb_probe),
+ DEVMETHOD(device_attach, vtefifb_attach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(vtefifb, vtefifb_driver, vtefifb_methods, 0);
+devclass_t vtefifb_devclass;
+
+DRIVER_MODULE(vtefifb, nexus, vtefifb_driver, vtefifb_devclass, NULL, NULL);
diff --git a/sys/dev/vt/hw/vga/vt_vga.c b/sys/dev/vt/hw/vga/vt_vga.c
index abddbf5..7f35053 100644
--- a/sys/dev/vt/hw/vga/vt_vga.c
+++ b/sys/dev/vt/hw/vga/vt_vga.c
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/module.h>
+#include <sys/rman.h>
#include <dev/vt/vt.h>
#include <dev/vt/hw/vga/vt_vga_reg.h>
@@ -56,6 +59,7 @@ struct vga_softc {
bus_space_handle_t vga_reg_handle;
int vga_wmode;
term_color_t vga_curfg, vga_curbg;
+ boolean_t vga_enabled;
};
/* Convenience macros. */
@@ -1228,6 +1232,7 @@ vga_init(struct vt_device *vd)
vd->vd_height = VT_VGA_HEIGHT;
}
vga_initialize(vd, textmode);
+ sc->vga_enabled = true;
return (CN_INTERNAL);
}
@@ -1241,3 +1246,53 @@ vga_postswitch(struct vt_device *vd)
/* Ask vt(9) to update chars on visible area. */
vd->vd_flags |= VDF_INVALID;
}
+
+/* Dummy NewBus functions to reserve the resources used by the vt_vga driver */
+static void
+vtvga_identify(driver_t *driver, device_t parent)
+{
+
+ if (!vga_conssoftc.vga_enabled)
+ return;
+
+ if (BUS_ADD_CHILD(parent, 0, driver->name, 0) == NULL)
+ panic("Unable to attach vt_vga console");
+}
+
+static int
+vtvga_probe(device_t dev)
+{
+
+ device_set_desc(dev, "vt_vga driver");
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+vtvga_attach(device_t dev)
+{
+ struct resource *pseudo_phys_res;
+ int res_id;
+
+ res_id = 0;
+ pseudo_phys_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &res_id, VGA_MEM_BASE, VGA_MEM_BASE + VGA_MEM_SIZE,
+ VGA_MEM_SIZE, RF_ACTIVE);
+ if (pseudo_phys_res == NULL)
+ panic("Unable to reserve vt_vga memory");
+ return (0);
+}
+
+/*-------------------- Private Device Attachment Data -----------------------*/
+static device_method_t vtvga_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, vtvga_identify),
+ DEVMETHOD(device_probe, vtvga_probe),
+ DEVMETHOD(device_attach, vtvga_attach),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(vtvga, vtvga_driver, vtvga_methods, 0);
+devclass_t vtvga_devclass;
+
+DRIVER_MODULE(vtvga, nexus, vtvga_driver, vtvga_devclass, NULL, NULL);
diff --git a/sys/dev/vt/vt.h b/sys/dev/vt/vt.h
index 262ffaf..67fcf1e 100644
--- a/sys/dev/vt/vt.h
+++ b/sys/dev/vt/vt.h
@@ -155,6 +155,7 @@ struct vt_device {
int vd_keyboard; /* (G) Keyboard index. */
unsigned int vd_kbstate; /* (?) Device unit. */
unsigned int vd_unit; /* (c) Device unit. */
+ int vd_altbrk; /* (?) Alt break seq. state */
};
#define VD_PASTEBUF(vd) ((vd)->vd_pastebuf.vpb_buf)
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 6d31fae..51c4623 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -825,7 +825,9 @@ vt_processkey(keyboard_t *kbd, struct vt_device *vd, int c)
terminal_input_char(vw->vw_terminal, 0x1b);
}
#endif
-
+#if defined(KDB)
+ kdb_alt_break(c, &vd->vd_altbrk);
+#endif
terminal_input_char(vw->vw_terminal, KEYCHAR(c));
} else
terminal_input_raw(vw->vw_terminal, c);
diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c
index e94fa74..accb46c 100644
--- a/sys/dev/wpi/if_wpi.c
+++ b/sys/dev/wpi/if_wpi.c
@@ -2564,7 +2564,7 @@ wpi_scan(struct wpi_softc *sc)
struct ieee80211_channel *c;
enum ieee80211_phymode mode;
uint8_t *frm;
- int nrates, pktlen, error, i, nssid;
+ int pktlen, error, i, nssid;
bus_addr_t physaddr;
desc = &ring->desc[ring->cur];
@@ -2613,7 +2613,7 @@ wpi_scan(struct wpi_softc *sc)
nssid = MIN(ss->ss_nssid, WPI_SCAN_MAX_ESSIDS);
for (i = 0; i < nssid; i++) {
hdr->scan_essids[i].id = IEEE80211_ELEMID_SSID;
- hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, 32);
+ hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, IEEE80211_NWID_LEN);
memcpy(hdr->scan_essids[i].essid, ss->ss_ssid[i].ssid,
hdr->scan_essids[i].esslen);
#ifdef WPI_DEBUG
@@ -2630,7 +2630,7 @@ wpi_scan(struct wpi_softc *sc)
* Build a probe request frame. Most of the following code is a
* copy & paste of what is done in net80211.
*/
- wh = (struct ieee80211_frame *)&hdr->scan_essids[4];
+ wh = (struct ieee80211_frame *)&hdr->scan_essids[WPI_SCAN_MAX_ESSIDS];
wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
IEEE80211_FC0_SUBTYPE_PROBE_REQ;
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
@@ -2642,30 +2642,12 @@ wpi_scan(struct wpi_softc *sc)
frm = (uint8_t *)(wh + 1);
- /* add essid IE, the hardware will fill this in for us */
- *frm++ = IEEE80211_ELEMID_SSID;
- *frm++ = 0;
-
mode = ieee80211_chan2mode(ic->ic_curchan);
rs = &ic->ic_sup_rates[mode];
- /* add supported rates IE */
- *frm++ = IEEE80211_ELEMID_RATES;
- nrates = rs->rs_nrates;
- if (nrates > IEEE80211_RATE_SIZE)
- nrates = IEEE80211_RATE_SIZE;
- *frm++ = nrates;
- memcpy(frm, rs->rs_rates, nrates);
- frm += nrates;
-
- /* add supported xrates IE */
- if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
- nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
- *frm++ = IEEE80211_ELEMID_XRATES;
- *frm++ = nrates;
- memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
- frm += nrates;
- }
+ frm = ieee80211_add_ssid(frm, NULL, 0);
+ frm = ieee80211_add_rates(frm, rs);
+ frm = ieee80211_add_xrates(frm, rs);
/* setup length of probe request */
hdr->tx.len = htole16(frm - (uint8_t *)wh);
diff --git a/sys/dev/wpi/if_wpireg.h b/sys/dev/wpi/if_wpireg.h
index df71b3d..60d183a 100644
--- a/sys/dev/wpi/if_wpireg.h
+++ b/sys/dev/wpi/if_wpireg.h
@@ -511,7 +511,7 @@ struct {
struct {
uint8_t id;
uint8_t esslen;
- uint8_t essid[32];
+ uint8_t essid[IEEE80211_NWID_LEN];
}scan_essids[WPI_SCAN_MAX_ESSIDS];
/* followed by probe request body */
/* followed by nchan x wpi_scan_chan */
diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index 899ae79..5baca5a 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -239,8 +239,10 @@ ext2_create(struct vop_create_args *ap)
error =
ext2_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
ap->a_dvp, ap->a_vpp, ap->a_cnp);
- if (error)
+ if (error != 0)
return (error);
+ if ((ap->a_cnp->cn_flags & MAKEENTRY) != 0)
+ cache_enter(ap->a_dvp, *ap->a_vpp, ap->a_cnp);
return (0);
}
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index a60fa13..3294656 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -184,6 +184,8 @@ msdosfs_create(ap)
if (error)
goto bad;
*ap->a_vpp = DETOV(dep);
+ if ((cnp->cn_flags & MAKEENTRY) != 0)
+ cache_enter(ap->a_dvp, *ap->a_vpp, cnp);
return (0);
bad:
diff --git a/sys/fs/nandfs/nandfs_vnops.c b/sys/fs/nandfs/nandfs_vnops.c
index 65dcf64..40dd855 100644
--- a/sys/fs/nandfs/nandfs_vnops.c
+++ b/sys/fs/nandfs/nandfs_vnops.c
@@ -1411,6 +1411,8 @@ nandfs_create(struct vop_create_args *ap)
return (error);
}
*vpp = NTOV(node);
+ if ((cnp->cn_flags & MAKEENTRY) != 0)
+ cache_enter(dvp, *vpp, cnp);
DPRINTF(VNCALL, ("created file vp %p nandnode %p ino %jx\n", *vpp, node,
(uintmax_t)node->nn_ino));
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 363ff89..c1d50f4 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -260,7 +260,7 @@ newnfs_connect(struct nfsmount *nmp, struct nfssockreq *nrp,
client = clnt_reconnect_create(nconf, saddr, nrp->nr_prog,
nrp->nr_vers, sndreserve, rcvreserve);
- CLNT_CONTROL(client, CLSET_WAITCHAN, "newnfsreq");
+ CLNT_CONTROL(client, CLSET_WAITCHAN, "nfsreq");
if (nmp != NULL) {
if ((nmp->nm_flag & NFSMNT_INT))
CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one);
@@ -1166,10 +1166,10 @@ nfs_msg(struct thread *td, const char *server, const char *msg, int error)
p = td ? td->td_proc : NULL;
if (error) {
- tprintf(p, LOG_INFO, "newnfs server %s: %s, error %d\n",
+ tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n",
server, msg, error);
} else {
- tprintf(p, LOG_INFO, "newnfs server %s: %s\n", server, msg);
+ tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg);
}
return (0);
}
diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c
index d9f8436..0f6db32 100644
--- a/sys/fs/nfs/nfs_commonsubs.c
+++ b/sys/fs/nfs/nfs_commonsubs.c
@@ -219,7 +219,8 @@ nfsm_mbufuio(struct nfsrv_descript *nd, struct uio *uiop, int siz)
}
mbufcp = NFSMTOD(mp, caddr_t);
len = mbuf_len(mp);
- KASSERT(len > 0, ("len %d", len));
+ KASSERT(len >= 0,
+ ("len %d, corrupted mbuf?", len));
}
xfer = (left > len) ? len : left;
#ifdef notdef
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index 88c7a34..9f08854 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -930,24 +930,6 @@ void nfsd_mntinit(void);
int newnfs_iosize(struct nfsmount *);
-#ifdef NFS_DEBUG
-
-extern int nfs_debug;
-#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */
-#define NFS_DEBUG_WG 2 /* server write gathering */
-#define NFS_DEBUG_RC 4 /* server request caching */
-
-#define NFS_DPF(cat, args) \
- do { \
- if (nfs_debug & NFS_DEBUG_##cat) printf args; \
- } while (0)
-
-#else
-
-#define NFS_DPF(cat, args)
-
-#endif
-
int newnfs_vncmpf(struct vnode *, void *);
#ifndef NFS_MINDIRATTRTIMO
diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h
index 183515c..e05e553 100644
--- a/sys/fs/nfsclient/nfs.h
+++ b/sys/fs/nfsclient/nfs.h
@@ -55,6 +55,24 @@
#define NFS_ISV34(v) \
(VFSTONFS((v)->v_mount)->nm_flag & (NFSMNT_NFSV3 | NFSMNT_NFSV4))
+#ifdef NFS_DEBUG
+
+extern int nfs_debug;
+#define NFS_DEBUG_ASYNCIO 1 /* asynchronous i/o */
+#define NFS_DEBUG_WG 2 /* server write gathering */
+#define NFS_DEBUG_RC 4 /* server request caching */
+
+#define NFS_DPF(cat, args) \
+ do { \
+ if (nfs_debug & NFS_DEBUG_##cat) printf args; \
+ } while (0)
+
+#else
+
+#define NFS_DPF(cat, args)
+
+#endif
+
/*
* NFS iod threads can be in one of these three states once spawned.
* NFSIOD_NOT_AVAILABLE - Cannot be assigned an I/O operation at this time.
diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c
index 5052261..b1a3451 100644
--- a/sys/fs/nfsclient/nfs_clnode.c
+++ b/sys/fs/nfsclient/nfs_clnode.c
@@ -122,7 +122,7 @@ ncl_nget(struct mount *mntp, u_int8_t *fhp, int fhsize, struct nfsnode **npp,
}
np = uma_zalloc(newnfsnode_zone, M_WAITOK | M_ZERO);
- error = getnewvnode("newnfs", mntp, &newnfs_vnodeops, &nvp);
+ error = getnewvnode("nfs", mntp, &newnfs_vnodeops, &nvp);
if (error) {
uma_zfree(newnfsnode_zone, np);
return (error);
diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c
index 8529c76..efdc812 100644
--- a/sys/fs/nfsclient/nfs_clport.c
+++ b/sys/fs/nfsclient/nfs_clport.c
@@ -198,7 +198,7 @@ nfscl_nget(struct mount *mntp, struct vnode *dvp, struct nfsfh *nfhp,
}
np = uma_zalloc(newnfsnode_zone, M_WAITOK | M_ZERO);
- error = getnewvnode("newnfs", mntp, &newnfs_vnodeops, &nvp);
+ error = getnewvnode("nfs", mntp, &newnfs_vnodeops, &nvp);
if (error) {
uma_zfree(newnfsnode_zone, np);
FREE((caddr_t)nfhp, M_NFSFH);
diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c
index 33f92c6..9758b4c 100644
--- a/sys/fs/nfsclient/nfs_clvfsops.c
+++ b/sys/fs/nfsclient/nfs_clvfsops.c
@@ -100,6 +100,11 @@ SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_INITIAL_DELAY,
static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
SYSCTL_INT(_vfs_nfs, NFS_TPRINTF_DELAY,
downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, "");
+#ifdef NFS_DEBUG
+int nfs_debug;
+SYSCTL_INT(_vfs_nfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
+ "Toggle debug flag");
+#endif
static int nfs_mountroot(struct mount *);
static void nfs_sec_name(char *, int *);
@@ -152,7 +157,7 @@ MODULE_DEPEND(nfs, nfslock, 1, 1, 1);
* will be defined for kernels built without NFS_ROOT, although it
* isn't used in that case.
*/
-#if !defined(NFS_ROOT) && !defined(NFSCLIENT)
+#if !defined(NFS_ROOT)
struct nfs_diskless nfs_diskless = { { { 0 } } };
struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
int nfs_diskless_valid = 0;
@@ -704,7 +709,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
while (newnfs_connect(nmp, &nmp->nm_sockreq,
cred, td, 0)) {
printf("newnfs_args: retrying connect\n");
- (void) nfs_catnap(PSOCK, 0, "newnfscon");
+ (void) nfs_catnap(PSOCK, 0, "nfscon");
}
}
} else {
@@ -1063,7 +1068,7 @@ nfs_mount(struct mount *mp)
* greater than NFS_MAXDGRAMDATA, those thread(s) will be
* hung, retrying the RPC(s) forever. Usually these threads
* will be seen doing an uninterruptible sleep on wait channel
- * "newnfsreq" (truncated to "newnfsre" by procstat).
+ * "nfsreq".
*/
if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
tprintf(td->td_proc, LOG_WARNING,
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index 818551f..513abf4 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -1606,20 +1606,6 @@ again:
}
} else if (NFS_ISV34(dvp) && (fmode & O_EXCL)) {
if (nfscl_checksattr(vap, &nfsva)) {
- /*
- * We are normally called with only a partially
- * initialized VAP. Since the NFSv3 spec says that
- * the server may use the file attributes to
- * store the verifier, the spec requires us to do a
- * SETATTR RPC. FreeBSD servers store the verifier in
- * atime, but we can't really assume that all servers
- * will so we ensure that our SETATTR sets both atime
- * and mtime.
- */
- if (vap->va_mtime.tv_sec == VNOVAL)
- vfs_timestamp(&vap->va_mtime);
- if (vap->va_atime.tv_sec == VNOVAL)
- vap->va_atime = vap->va_mtime;
error = nfsrpc_setattr(newvp, vap, NULL, cnp->cn_cred,
cnp->cn_thread, &nfsva, &attrflag, NULL);
if (error && (vap->va_uid != (uid_t)VNOVAL ||
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index 5bd4538..17ca5a6 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2970,12 +2970,7 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first,
if (nfsrv_dolocallocks == 0)
goto out;
-
- /* Check for VI_DOOMED here, so that VOP_ADVLOCK() isn't performed. */
- if ((vp->v_iflag & VI_DOOMED) != 0) {
- error = EPERM;
- goto out;
- }
+ ASSERT_VOP_UNLOCKED(vp, "nfsvno_advlock: vp locked");
fl.l_whence = SEEK_SET;
fl.l_type = ftype;
@@ -2999,14 +2994,12 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first,
fl.l_pid = (pid_t)0;
fl.l_sysid = (int)nfsv4_sysid;
- NFSVOPUNLOCK(vp, 0);
if (ftype == F_UNLCK)
error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_UNLCK, &fl,
(F_POSIX | F_REMOTE));
else
error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_SETLK, &fl,
(F_POSIX | F_REMOTE));
- NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
out:
NFSEXITCODE(error);
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index 97f8fff..5e9beeb 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -1344,6 +1344,8 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
vnode_t tvp = NULL;
uint64_t first, end;
+ if (vp != NULL)
+ ASSERT_VOP_UNLOCKED(vp, "nfsrv_freeallnfslocks: vnode locked");
lop = LIST_FIRST(&stp->ls_lock);
while (lop != LIST_END(&stp->ls_lock)) {
nlop = LIST_NEXT(lop, lo_lckowner);
@@ -1363,9 +1365,10 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
if (gottvp == 0) {
if (nfsrv_dolocallocks == 0)
tvp = NULL;
- else if (vp == NULL && cansleep != 0)
+ else if (vp == NULL && cansleep != 0) {
tvp = nfsvno_getvp(&lfp->lf_fh);
- else
+ NFSVOPUNLOCK(tvp, 0);
+ } else
tvp = vp;
gottvp = 1;
}
@@ -1386,7 +1389,7 @@ nfsrv_freeallnfslocks(struct nfsstate *stp, vnode_t vp, int cansleep,
lop = nlop;
}
if (vp == NULL && tvp != NULL)
- vput(tvp);
+ vrele(tvp);
}
/*
@@ -1497,7 +1500,7 @@ nfsrv_lockctrl(vnode_t vp, struct nfsstate **new_stpp,
struct nfsclient *clp = NULL;
u_int32_t bits;
int error = 0, haslock = 0, ret, reterr;
- int getlckret, delegation = 0, filestruct_locked;
+ int getlckret, delegation = 0, filestruct_locked, vnode_unlocked = 0;
fhandle_t nfh;
uint64_t first, end;
uint32_t lock_flags;
@@ -1587,6 +1590,11 @@ tryagain:
* locking rolled back.
*/
NFSUNLOCKSTATE();
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl1");
+ vnode_unlocked = 1;
+ NFSVOPUNLOCK(vp, 0);
+ }
reterr = nfsrv_locallock(vp, lfp,
(new_lop->lo_flags & (NFSLCK_READ | NFSLCK_WRITE)),
new_lop->lo_first, new_lop->lo_end, cfp, p);
@@ -1756,6 +1764,11 @@ tryagain:
if (filestruct_locked != 0) {
/* Roll back local locks. */
NFSUNLOCKSTATE();
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl2");
+ vnode_unlocked = 1;
+ NFSVOPUNLOCK(vp, 0);
+ }
nfsrv_locallock_rollback(vp, lfp, p);
NFSLOCKSTATE();
nfsrv_unlocklf(lfp);
@@ -1833,6 +1846,12 @@ tryagain:
if (filestruct_locked != 0) {
/* Roll back local locks. */
NFSUNLOCKSTATE();
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp,
+ "nfsrv_lockctrl3");
+ vnode_unlocked = 1;
+ NFSVOPUNLOCK(vp, 0);
+ }
nfsrv_locallock_rollback(vp, lfp, p);
NFSLOCKSTATE();
nfsrv_unlocklf(lfp);
@@ -1852,6 +1871,8 @@ tryagain:
bits = tstp->ls_flags;
bits >>= NFSLCK_SHIFT;
if (new_stp->ls_flags & bits & NFSLCK_ACCESSBITS) {
+ KASSERT(vnode_unlocked == 0,
+ ("nfsrv_lockctrl: vnode unlocked1"));
ret = nfsrv_clientconflict(tstp->ls_clp, &haslock,
vp, p);
if (ret == 1) {
@@ -1883,6 +1904,8 @@ tryagain:
* For setattr, just get rid of all the Delegations for other clients.
*/
if (new_stp->ls_flags & NFSLCK_SETATTR) {
+ KASSERT(vnode_unlocked == 0,
+ ("nfsrv_lockctrl: vnode unlocked2"));
ret = nfsrv_cleandeleg(vp, lfp, clp, &haslock, p);
if (ret) {
/*
@@ -1933,14 +1956,26 @@ tryagain:
(new_lop->lo_flags & NFSLCK_WRITE) &&
(clp != tstp->ls_clp ||
(tstp->ls_flags & NFSLCK_DELEGREAD)))) {
+ ret = 0;
if (filestruct_locked != 0) {
/* Roll back local locks. */
NFSUNLOCKSTATE();
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl4");
+ NFSVOPUNLOCK(vp, 0);
+ }
nfsrv_locallock_rollback(vp, lfp, p);
NFSLOCKSTATE();
nfsrv_unlocklf(lfp);
+ NFSUNLOCKSTATE();
+ NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
+ vnode_unlocked = 0;
+ if ((vp->v_iflag & VI_DOOMED) != 0)
+ ret = NFSERR_SERVERFAULT;
+ NFSLOCKSTATE();
}
- ret = nfsrv_delegconflict(tstp, &haslock, p, vp);
+ if (ret == 0)
+ ret = nfsrv_delegconflict(tstp, &haslock, p, vp);
if (ret) {
/*
* nfsrv_delegconflict unlocks state when it
@@ -1979,6 +2014,11 @@ tryagain:
stateidp->other[2] = stp->ls_stateid.other[2];
if (filestruct_locked != 0) {
NFSUNLOCKSTATE();
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl5");
+ vnode_unlocked = 1;
+ NFSVOPUNLOCK(vp, 0);
+ }
/* Update the local locks. */
nfsrv_localunlock(vp, lfp, first, end, p);
NFSLOCKSTATE();
@@ -2009,14 +2049,29 @@ tryagain:
FREE((caddr_t)other_lop, M_NFSDLOCK);
other_lop = NULL;
}
- ret = nfsrv_clientconflict(lop->lo_stp->ls_clp,&haslock,vp,p);
+ if (vnode_unlocked != 0)
+ ret = nfsrv_clientconflict(lop->lo_stp->ls_clp, &haslock,
+ NULL, p);
+ else
+ ret = nfsrv_clientconflict(lop->lo_stp->ls_clp, &haslock,
+ vp, p);
if (ret == 1) {
if (filestruct_locked != 0) {
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl6");
+ NFSVOPUNLOCK(vp, 0);
+ }
/* Roll back local locks. */
nfsrv_locallock_rollback(vp, lfp, p);
NFSLOCKSTATE();
nfsrv_unlocklf(lfp);
NFSUNLOCKSTATE();
+ NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
+ vnode_unlocked = 0;
+ if ((vp->v_iflag & VI_DOOMED) != 0) {
+ error = NFSERR_SERVERFAULT;
+ goto out;
+ }
}
/*
* nfsrv_clientconflict() unlocks state when it
@@ -2050,6 +2105,11 @@ tryagain:
if (filestruct_locked != 0 && ret == 0) {
/* Roll back local locks. */
NFSUNLOCKSTATE();
+ if (vnode_unlocked == 0) {
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_lockctrl7");
+ vnode_unlocked = 1;
+ NFSVOPUNLOCK(vp, 0);
+ }
nfsrv_locallock_rollback(vp, lfp, p);
NFSLOCKSTATE();
nfsrv_unlocklf(lfp);
@@ -2128,6 +2188,11 @@ out:
nfsv4_unlock(&nfsv4rootfs_lock, 1);
NFSUNLOCKV4ROOTMUTEX();
}
+ if (vnode_unlocked != 0) {
+ NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
+ if (error == 0 && (vp->v_iflag & VI_DOOMED) != 0)
+ error = NFSERR_SERVERFAULT;
+ }
if (other_lop)
FREE((caddr_t)other_lop, M_NFSDLOCK);
NFSEXITCODE2(error, nd);
@@ -3235,11 +3300,14 @@ nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp, nfsquad_t clientid,
/* Get the lf lock */
nfsrv_locklf(lfp);
NFSUNLOCKSTATE();
+ ASSERT_VOP_ELOCKED(vp, "nfsrv_openupdate");
+ NFSVOPUNLOCK(vp, 0);
if (nfsrv_freeopen(stp, vp, 1, p) == 0) {
NFSLOCKSTATE();
nfsrv_unlocklf(lfp);
NFSUNLOCKSTATE();
}
+ NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY);
} else {
(void) nfsrv_freeopen(stp, NULL, 0, p);
NFSUNLOCKSTATE();
@@ -4627,7 +4695,7 @@ static int
nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp,
NFSPROC_T *p)
{
- int gotlock, lktype;
+ int gotlock, lktype = 0;
/*
* If lease hasn't expired, we can't fix it.
@@ -4637,8 +4705,10 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp,
return (0);
if (*haslockp == 0) {
NFSUNLOCKSTATE();
- lktype = NFSVOPISLOCKED(vp);
- NFSVOPUNLOCK(vp, 0);
+ if (vp != NULL) {
+ lktype = NFSVOPISLOCKED(vp);
+ NFSVOPUNLOCK(vp, 0);
+ }
NFSLOCKV4ROOTMUTEX();
nfsv4_relref(&nfsv4rootfs_lock);
do {
@@ -4647,11 +4717,12 @@ nfsrv_clientconflict(struct nfsclient *clp, int *haslockp, vnode_t vp,
} while (!gotlock);
NFSUNLOCKV4ROOTMUTEX();
*haslockp = 1;
- NFSVOPLOCK(vp, lktype | LK_RETRY);
- if ((vp->v_iflag & VI_DOOMED) != 0)
- return (2);
- else
- return (1);
+ if (vp != NULL) {
+ NFSVOPLOCK(vp, lktype | LK_RETRY);
+ if ((vp->v_iflag & VI_DOOMED) != 0)
+ return (2);
+ }
+ return (1);
}
NFSUNLOCKSTATE();
@@ -4692,7 +4763,7 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
vnode_t vp)
{
struct nfsclient *clp = stp->ls_clp;
- int gotlock, error, lktype, retrycnt, zapped_clp;
+ int gotlock, error, lktype = 0, retrycnt, zapped_clp;
nfsv4stateid_t tstateid;
fhandle_t tfh;
@@ -4809,8 +4880,10 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
*/
if (*haslockp == 0) {
NFSUNLOCKSTATE();
- lktype = NFSVOPISLOCKED(vp);
- NFSVOPUNLOCK(vp, 0);
+ if (vp != NULL) {
+ lktype = NFSVOPISLOCKED(vp);
+ NFSVOPUNLOCK(vp, 0);
+ }
NFSLOCKV4ROOTMUTEX();
nfsv4_relref(&nfsv4rootfs_lock);
do {
@@ -4819,14 +4892,16 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
} while (!gotlock);
NFSUNLOCKV4ROOTMUTEX();
*haslockp = 1;
- NFSVOPLOCK(vp, lktype | LK_RETRY);
- if ((vp->v_iflag & VI_DOOMED) != 0) {
- *haslockp = 0;
- NFSLOCKV4ROOTMUTEX();
- nfsv4_unlock(&nfsv4rootfs_lock, 1);
- NFSUNLOCKV4ROOTMUTEX();
- error = NFSERR_PERM;
- goto out;
+ if (vp != NULL) {
+ NFSVOPLOCK(vp, lktype | LK_RETRY);
+ if ((vp->v_iflag & VI_DOOMED) != 0) {
+ *haslockp = 0;
+ NFSLOCKV4ROOTMUTEX();
+ nfsv4_unlock(&nfsv4rootfs_lock, 1);
+ NFSUNLOCKV4ROOTMUTEX();
+ error = NFSERR_PERM;
+ goto out;
+ }
}
error = -1;
goto out;
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
index 29ee389..c811b9a 100644
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -213,10 +213,14 @@ tmpfs_create(struct vop_create_args *v)
struct vnode **vpp = v->a_vpp;
struct componentname *cnp = v->a_cnp;
struct vattr *vap = v->a_vap;
+ int error;
MPASS(vap->va_type == VREG || vap->va_type == VSOCK);
- return tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
+ error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
+ if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0)
+ cache_enter(dvp, *vpp, cnp);
+ return (error);
}
static int
diff --git a/sys/geom/sched/README b/sys/geom/sched/README
index 1b52d90..b62d468 100644
--- a/sys/geom/sched/README
+++ b/sys/geom/sched/README
@@ -39,37 +39,17 @@ with cvs, and lets cvs progress when competing with a writer.
To try it out:
-1. USERS OF FREEBSD 7, PLEASE READ CAREFULLY THE FOLLOWING:
-
- On loading, this module patches one kernel function (g_io_request())
- so that I/O requests ("bio's") carry a classification tag, useful
- for scheduling purposes.
-
- ON FREEBSD 7, the tag is stored in an existing (though rarely used)
- field of the "struct bio", a solution which makes this module
- incompatible with other modules using it, such as ZFS and gjournal.
- Additionally, g_io_request() is patched in-memory to add a call
- to the function that initializes this field (i386/amd64 only;
- for other architectures you need to manually patch sys/geom/geom_io.c).
- See details in the file g_sched.c.
-
- On FreeBSD 8.0 and above, the above trick is not necessary,
- as the struct bio contains dedicated fields for the classifier,
- and hooks for request classifiers.
-
- If you don't like the above, don't run this code.
-
-2. PLEASE MAKE SURE THAT THE DISK THAT YOU WILL BE USING FOR TESTS
+1. PLEASE MAKE SURE THAT THE DISK THAT YOU WILL BE USING FOR TESTS
DOES NOT CONTAIN PRECIOUS DATA.
This is experimental code, so we make no guarantees, though
I am routinely using it on my desktop and laptop.
-3. EXTRACT AND BUILD THE PROGRAMS
+2. EXTRACT AND BUILD THE PROGRAMS
A 'make install' in the directory should work (with root privs),
or you can even try the binary modules.
If you want to build the modules yourself, look at the Makefile.
-4. LOAD THE MODULE, CREATE A GEOM NODE, RUN TESTS
+3. LOAD THE MODULE, CREATE A GEOM NODE, RUN TESTS
The scheduler's module must be loaded first:
diff --git a/sys/geom/sched/g_sched.c b/sys/geom/sched/g_sched.c
index 009a58c..f1c9a3d 100644
--- a/sys/geom/sched/g_sched.c
+++ b/sys/geom/sched/g_sched.c
@@ -346,17 +346,8 @@ static inline u_long
g_sched_classify(struct bio *bp)
{
-#if __FreeBSD_version > 800098
/* we have classifier fields in the struct bio */
-#define HAVE_BIO_CLASSIFIER
return ((u_long)bp->bio_classifier1);
-#else
-#warning old version!!!
- while (bp->bio_parent != NULL)
- bp = bp->bio_parent;
-
- return ((u_long)bp->bio_caller1);
-#endif
}
/* Return the hash chain for the given key. */
@@ -705,7 +696,7 @@ g_gsched_global_init(void)
G_SCHED_DEBUG(0, "Initializing global data.");
mtx_init(&me.gs_mtx, "gsched", NULL, MTX_DEF);
LIST_INIT(&me.gs_scheds);
- gs_bioq_init(&me.gs_pending);
+ bioq_init(&me.gs_pending);
me.gs_initialized = 1;
}
}
@@ -914,7 +905,7 @@ g_sched_temporary_start(struct bio *bio)
mtx_lock(&me.gs_mtx);
me.gs_npending++;
- gs_bioq_disksort(&me.gs_pending, bio);
+ bioq_disksort(&me.gs_pending, bio);
mtx_unlock(&me.gs_mtx);
}
@@ -923,7 +914,7 @@ g_sched_flush_pending(g_start_t *start)
{
struct bio *bp;
- while ((bp = gs_bioq_takefirst(&me.gs_pending)))
+ while ((bp = bioq_takefirst(&me.gs_pending)))
start(bp);
}
@@ -1365,161 +1356,7 @@ g_sched_destroy_geom(struct gctl_req *req, struct g_class *mp,
* to the issuer of a request in bp->bio_classifier1 as soon
* as the bio is posted to the geom queue (and not later, because
* requests are managed by the g_down thread afterwards).
- *
- * On older versions of the system (but this code is not used
- * in any existing release), we [ab]use the caller1 field in the
- * root element of the bio tree to store the classification info.
- * The marking is done at the beginning of g_io_request()
- * and only if we find that the field is NULL.
- *
- * To avoid rebuilding the kernel, this module will patch the
- * initial part of g_io_request() so it jumps to some hand-coded
- * assembly that does the marking and then executes the original
- * body of g_io_request().
- *
- * fake_ioreq[] is architecture-specific machine code
- * that implements the above. CODE_SIZE, STORE_SIZE etc.
- * are constants used in the patching routine. Look at the
- * code in g_ioreq_patch() for the details.
- */
-
-#ifndef HAVE_BIO_CLASSIFIER
-/*
- * Support for old FreeBSD versions
*/
-#if defined(__i386__)
-#define CODE_SIZE 29
-#define STORE_SIZE 5
-#define EPILOGUE 5
-#define SIZE (CODE_SIZE + STORE_SIZE + EPILOGUE)
-
-static u_char fake_ioreq[SIZE] = {
- 0x8b, 0x44, 0x24, 0x04, /* mov bp, %eax */
- /* 1: */
- 0x89, 0xc2, /* mov %eax, %edx # edx = bp */
- 0x8b, 0x40, 0x64, /* mov bp->bio_parent, %eax */
- 0x85, 0xc0, /* test %eax, %eax */
- 0x75, 0xf7, /* jne 1b */
- 0x8b, 0x42, 0x30, /* mov bp->bp_caller1, %eax */
- 0x85, 0xc0, /* test %eax, %eax */
- 0x75, 0x09, /* jne 2f */
- 0x64, 0xa1, 0x00, 0x00, /* mov %fs:0, %eax */
- 0x00, 0x00,
- 0x89, 0x42, 0x30, /* mov %eax, bp->bio_caller1 */
- /* 2: */
- 0x55, 0x89, 0xe5, 0x57, 0x56,
- 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp back... */
-};
-#elif defined(__amd64)
-#define CODE_SIZE 38
-#define STORE_SIZE 6
-#define EPILOGUE 5
-#define SIZE (CODE_SIZE + STORE_SIZE + EPILOGUE)
-
-static u_char fake_ioreq[SIZE] = {
- 0x48, 0x89, 0xf8, /* mov bp, %rax */
- /* 1: */
- 0x48, 0x89, 0xc2, /* mov %rax, %rdx # rdx = bp */
- 0x48, 0x8b, 0x82, 0xa8, /* mov bp->bio_parent, %rax */
- 0x00, 0x00, 0x00,
- 0x48, 0x85, 0xc0, /* test %rax, %rax */
- 0x75, 0xf1, /* jne 1b */
- 0x48, 0x83, 0x7a, 0x58, /* cmp $0, bp->bp_caller1 */
- 0x00,
- 0x75, 0x0d, /* jne 2f */
- 0x65, 0x48, 0x8b, 0x04, /* mov %gs:0, %rax */
- 0x25, 0x00, 0x00, 0x00,
- 0x00,
- 0x48, 0x89, 0x42, 0x58, /* mov %rax, bp->bio_caller1 */
- /* 2: */
- 0x55, 0x48, 0x89, 0xe5, 0x41, 0x56,
- 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp back... */
-};
-#else /* neither x86 nor amd64 */
-static void
-g_new_io_request(struct bio *bp, struct g_consumer *cp)
-{
- struct bio *top = bp;
-
- /*
- * bio classification: if bio_caller1 is available in the
- * root of the 'struct bio' tree, store there the thread id
- * of the thread that originated the request.
- * More sophisticated classification schemes can be used.
- */
- while (top->bio_parent)
- top = top->bio_parent;
-
- if (top->bio_caller1 == NULL)
- top->bio_caller1 = curthread;
-}
-
-#error please add the code above in g_new_io_request() to the beginning of \
- /sys/geom/geom_io.c::g_io_request(), and remove this line.
-#endif /* end of arch-specific code */
-
-static int
-g_ioreq_patch(void)
-{
- u_char *original;
- u_long ofs;
- int found;
-
- if (me.gs_patched)
- return (-1);
-
- original = (u_char *)g_io_request;
-
- found = !bcmp(original, fake_ioreq + CODE_SIZE, STORE_SIZE);
- if (!found)
- return (-1);
-
- /* Jump back to the original + STORE_SIZE. */
- ofs = (original + STORE_SIZE) - (fake_ioreq + SIZE);
- bcopy(&ofs, fake_ioreq + CODE_SIZE + STORE_SIZE + 1, 4);
-
- /* Patch the original address with a jump to the trampoline. */
- *original = 0xe9; /* jump opcode */
- ofs = fake_ioreq - (original + 5);
- bcopy(&ofs, original + 1, 4);
-
- me.gs_patched = 1;
-
- return (0);
-}
-
-/*
- * Restore the original code, this is easy.
- */
-static void
-g_ioreq_restore(void)
-{
- u_char *original;
-
- if (me.gs_patched) {
- original = (u_char *)g_io_request;
- bcopy(fake_ioreq + CODE_SIZE, original, STORE_SIZE);
- me.gs_patched = 0;
- }
-}
-
-static inline void
-g_classifier_ini(void)
-{
-
- g_ioreq_patch();
-}
-
-static inline void
-g_classifier_fini(void)
-{
-
- g_ioreq_restore();
-}
-
-/*--- end of support code for older FreeBSD versions */
-
-#else /* HAVE_BIO_CLASSIFIER */
/*
* Classifier support for recent FreeBSD versions: we use
@@ -1552,7 +1389,6 @@ g_classifier_fini(void)
g_unregister_classifier(&g_sched_classifier);
}
-#endif /* HAVE_BIO_CLASSIFIER */
static void
g_sched_init(struct g_class *mp)
diff --git a/sys/geom/sched/g_sched.h b/sys/geom/sched/g_sched.h
index 3a34e29..9fdadc4 100644
--- a/sys/geom/sched/g_sched.h
+++ b/sys/geom/sched/g_sched.h
@@ -120,19 +120,6 @@ struct g_sched_softc {
#define G_SCHED_PROXYING 1
#define G_SCHED_FLUSHING 2
-/*
- * Temporary- our own version of the disksort, because the
- * version in 7.x and 8.x before march 2009 is buggy.
- */
-void gs_bioq_init(struct bio_queue_head *);
-void gs_bioq_remove(struct bio_queue_head *, struct bio *);
-void gs_bioq_flush(struct bio_queue_head *, struct devstat *, int);
-void gs_bioq_insert_head(struct bio_queue_head *, struct bio *);
-void gs_bioq_insert_tail(struct bio_queue_head *, struct bio *);
-struct bio *gs_bioq_first(struct bio_queue_head *);
-struct bio *gs_bioq_takefirst(struct bio_queue_head *);
-void gs_bioq_disksort(struct bio_queue_head *, struct bio *);
-
#endif /* _KERNEL */
#endif /* _G_SCHED_H_ */
diff --git a/sys/geom/sched/gs_rr.c b/sys/geom/sched/gs_rr.c
index 6f26879..b9d5d1b 100644
--- a/sys/geom/sched/gs_rr.c
+++ b/sys/geom/sched/gs_rr.c
@@ -315,7 +315,7 @@ g_rr_init_class(void *data, void *priv)
struct g_rr_softc *sc = data;
struct g_rr_queue *qp = priv;
- gs_bioq_init(&qp->q_bioq);
+ bioq_init(&qp->q_bioq);
/*
* Set the initial parameters for the client:
@@ -350,7 +350,7 @@ g_rr_fini_class(void *data, void *priv)
{
struct g_rr_queue *qp = priv;
- KASSERT(gs_bioq_first(&qp->q_bioq) == NULL,
+ KASSERT(bioq_first(&qp->q_bioq) == NULL,
("released nonempty queue"));
qp->q_sc->sc_nqueues--;
me.queues--;
@@ -438,7 +438,7 @@ g_rr_next(void *data, int force)
qp->q_flags &= ~G_FLAG_COMPLETED;
}
- bp = gs_bioq_takefirst(&qp->q_bioq); /* surely not NULL */
+ bp = bioq_takefirst(&qp->q_bioq); /* surely not NULL */
qp->q_service += bp->bio_length; /* charge the service */
/*
@@ -456,7 +456,7 @@ g_rr_next(void *data, int force)
* on read or writes (e.g., anticipate only on reads).
*/
expired = g_rr_queue_expired(qp); /* are we expired ? */
- next = gs_bioq_first(&qp->q_bioq); /* do we have one more ? */
+ next = bioq_first(&qp->q_bioq); /* do we have one more ? */
if (expired) {
sc->sc_active = NULL;
/* Either requeue or release reference. */
@@ -538,7 +538,7 @@ g_rr_start(void *data, struct bio *bp)
if (qp == NULL)
return (-1); /* allocation failed, tell upstream */
- if (gs_bioq_first(&qp->q_bioq) == NULL) {
+ if (bioq_first(&qp->q_bioq) == NULL) {
/*
* We are inserting into an empty queue.
* Reset its state if it is sc_active,
@@ -560,7 +560,7 @@ g_rr_start(void *data, struct bio *bp)
/* Inherit the reference returned by g_rr_queue_get(). */
bp->bio_caller1 = qp;
- gs_bioq_disksort(&qp->q_bioq, bp);
+ bioq_disksort(&qp->q_bioq, bp);
return (0);
}
diff --git a/sys/geom/sched/subr_disk.c b/sys/geom/sched/subr_disk.c
deleted file mode 100644
index db2a9ef..0000000
--- a/sys/geom/sched/subr_disk.c
+++ /dev/null
@@ -1,226 +0,0 @@
-/*-
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- *
- * The bioq_disksort() (and the specification of the bioq API)
- * have been written by Luigi Rizzo and Fabio Checconi under the same
- * license as above.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-//#include "opt_geom.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/conf.h>
-#include <sys/disk.h>
-#include <geom/geom_disk.h>
-#include "g_sched.h"
-
-/*
- * BIO queue implementation
- *
- * Please read carefully the description below before making any change
- * to the code, or you might change the behaviour of the data structure
- * in undesirable ways.
- *
- * A bioq stores disk I/O request (bio), normally sorted according to
- * the distance of the requested position (bio->bio_offset) from the
- * current head position (bioq->last_offset) in the scan direction, i.e.
- *
- * (uoff_t)(bio_offset - last_offset)
- *
- * Note that the cast to unsigned (uoff_t) is fundamental to insure
- * that the distance is computed in the scan direction.
- *
- * The main methods for manipulating the bioq are:
- *
- * bioq_disksort() performs an ordered insertion;
- *
- * bioq_first() return the head of the queue, without removing;
- *
- * bioq_takefirst() return and remove the head of the queue,
- * updating the 'current head position' as
- * bioq->last_offset = bio->bio_offset + bio->bio_length;
- *
- * When updating the 'current head position', we assume that the result of
- * bioq_takefirst() is dispatched to the device, so bioq->last_offset
- * represents the head position once the request is complete.
- *
- * If the bioq is manipulated using only the above calls, it starts
- * with a sorted sequence of requests with bio_offset >= last_offset,
- * possibly followed by another sorted sequence of requests with
- * 0 <= bio_offset < bioq->last_offset
- *
- * NOTE: historical behaviour was to ignore bio->bio_length in the
- * update, but its use tracks the head position in a better way.
- * Historical behaviour was also to update the head position when
- * the request under service is complete, rather than when the
- * request is extracted from the queue. However, the current API
- * has no method to update the head position; secondly, once
- * a request has been submitted to the disk, we have no idea of
- * the actual head position, so the final one is our best guess.
- *
- * --- Direct queue manipulation ---
- *
- * A bioq uses an underlying TAILQ to store requests, so we also
- * export methods to manipulate the TAILQ, in particular:
- *
- * bioq_insert_tail() insert an entry at the end.
- * It also creates a 'barrier' so all subsequent
- * insertions through bioq_disksort() will end up
- * after this entry;
- *
- * bioq_insert_head() insert an entry at the head, update
- * bioq->last_offset = bio->bio_offset so that
- * all subsequent insertions through bioq_disksort()
- * will end up after this entry;
- *
- * bioq_remove() remove a generic element from the queue, act as
- * bioq_takefirst() if invoked on the head of the queue.
- *
- * The semantic of these methods is the same as the operations
- * on the underlying TAILQ, but with additional guarantees on
- * subsequent bioq_disksort() calls. E.g. bioq_insert_tail()
- * can be useful for making sure that all previous ops are flushed
- * to disk before continuing.
- *
- * Updating bioq->last_offset on a bioq_insert_head() guarantees
- * that the bio inserted with the last bioq_insert_head() will stay
- * at the head of the queue even after subsequent bioq_disksort().
- *
- * Note that when the direct queue manipulation functions are used,
- * the queue may contain multiple inversion points (i.e. more than
- * two sorted sequences of requests).
- *
- */
-
-void
-gs_bioq_init(struct bio_queue_head *head)
-{
-
- TAILQ_INIT(&head->queue);
- head->last_offset = 0;
- head->insert_point = NULL;
-}
-
-void
-gs_bioq_remove(struct bio_queue_head *head, struct bio *bp)
-{
-
- if (head->insert_point == NULL) {
- if (bp == TAILQ_FIRST(&head->queue))
- head->last_offset = bp->bio_offset + bp->bio_length;
- } else if (bp == head->insert_point)
- head->insert_point = NULL;
-
- TAILQ_REMOVE(&head->queue, bp, bio_queue);
-}
-
-void
-gs_bioq_flush(struct bio_queue_head *head, struct devstat *stp, int error)
-{
- struct bio *bp;
-
- while ((bp = gs_bioq_takefirst(head)) != NULL)
- biofinish(bp, stp, error);
-}
-
-void
-gs_bioq_insert_head(struct bio_queue_head *head, struct bio *bp)
-{
-
- if (head->insert_point == NULL)
- head->last_offset = bp->bio_offset;
- TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
-}
-
-void
-gs_bioq_insert_tail(struct bio_queue_head *head, struct bio *bp)
-{
-
- TAILQ_INSERT_TAIL(&head->queue, bp, bio_queue);
- head->insert_point = bp;
- head->last_offset = bp->bio_offset;
-}
-
-struct bio *
-gs_bioq_first(struct bio_queue_head *head)
-{
-
- return (TAILQ_FIRST(&head->queue));
-}
-
-struct bio *
-gs_bioq_takefirst(struct bio_queue_head *head)
-{
- struct bio *bp;
-
- bp = TAILQ_FIRST(&head->queue);
- if (bp != NULL)
- gs_bioq_remove(head, bp);
- return (bp);
-}
-
-/*
- * Compute the sorting key. The cast to unsigned is
- * fundamental for correctness, see the description
- * near the beginning of the file.
- */
-static inline uoff_t
-gs_bioq_bio_key(struct bio_queue_head *head, struct bio *bp)
-{
-
- return ((uoff_t)(bp->bio_offset - head->last_offset));
-}
-
-/*
- * Seek sort for disks.
- *
- * Sort all requests in a single queue while keeping
- * track of the current position of the disk with last_offset.
- * See above for details.
- */
-void
-gs_bioq_disksort(struct bio_queue_head *head, struct bio *bp)
-{
- struct bio *cur, *prev;
- uoff_t key;
-
- if ((bp->bio_flags & BIO_ORDERED) != 0) {
- /*
- * Ordered transactions can only be dispatched
- * after any currently queued transactions. They
- * also have barrier semantics - no transactions
- * queued in the future can pass them.
- */
- gs_bioq_insert_tail(head, bp);
- return;
- }
-
- prev = NULL;
- key = gs_bioq_bio_key(head, bp);
- cur = TAILQ_FIRST(&head->queue);
-
- if (head->insert_point) {
- prev = head->insert_point;
- cur = TAILQ_NEXT(head->insert_point, bio_queue);
- }
-
- while (cur != NULL && key >= gs_bioq_bio_key(head, cur)) {
- prev = cur;
- cur = TAILQ_NEXT(cur, bio_queue);
- }
-
- if (prev == NULL)
- TAILQ_INSERT_HEAD(&head->queue, bp, bio_queue);
- else
- TAILQ_INSERT_AFTER(&head->queue, prev, bp, bio_queue);
-}
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 490d481..6d35c3a 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -246,7 +246,7 @@ trap(struct trapframe *frame)
* flag is cleared and finally re-scheduling is enabled.
*/
if ((type == T_PROTFLT || type == T_PAGEFLT) &&
- dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
+ dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type))
goto out;
#endif
diff --git a/sys/i386/xen/clock.c b/sys/i386/xen/clock.c
index 0f5b0e5..26fafee 100644
--- a/sys/i386/xen/clock.c
+++ b/sys/i386/xen/clock.c
@@ -118,7 +118,7 @@ struct mtx clock_lock;
#define RTC_UNLOCK mtx_unlock_spin(&clock_lock)
#define NS_PER_TICK (1000000000ULL/hz)
-int adjkerntz; /* local offset from GMT in seconds */
+int adjkerntz; /* local offset from UTC in seconds */
int clkintr_pending;
int pscnt = 1;
int psdiv = 1;
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index b34eb62..a4f0f88 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3167,7 +3167,8 @@ corefile_open(const char *comm, uid_t uid, pid_t pid, struct thread *td,
sbuf_delete(&sb);
cmode = S_IRUSR | S_IWUSR;
- oflags = VN_OPEN_NOAUDIT | (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
+ oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0);
/*
* If the core format has a %I in it, then we need to check
diff --git a/sys/kern/subr_fattime.c b/sys/kern/subr_fattime.c
index e2a2195..099479c 100644
--- a/sys/kern/subr_fattime.c
+++ b/sys/kern/subr_fattime.c
@@ -45,7 +45,7 @@
* Later on again, in Windows NT, timestamps were defined relative to GMT.
*
* Purists will point out that UTC replaced GMT for such uses around
- * a century ago, already then. Ironically "NT" was an abbreviation of
+ * half a century ago, already then. Ironically "NT" was an abbreviation of
* "New Technology". Anyway...
*
* The 'utc' argument determines if the resulting FATTIME timestamp
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 537f9c8..88952ed 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -579,7 +579,7 @@ sbappend_locked(struct sockbuf *sb, struct mbuf *m)
if (m == 0)
return;
-
+ m_clrprotoflags(m);
SBLASTRECORDCHK(sb);
n = sb->sb_mb;
if (n) {
@@ -732,6 +732,7 @@ sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0)
if (m0 == 0)
return;
+ m_clrprotoflags(m0);
/*
* Put the first mbuf on the queue. Note this permits zero length
* records.
@@ -777,6 +778,8 @@ sbappendaddr_locked_internal(struct sockbuf *sb, const struct sockaddr *asa,
return (0);
m->m_len = asa->sa_len;
bcopy(asa, mtod(m, caddr_t), asa->sa_len);
+ if (m0)
+ m_clrprotoflags(m0);
if (ctrl_last)
ctrl_last->m_next = m0; /* concatenate data to control */
else
@@ -872,6 +875,7 @@ sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
if (space > sbspace(sb))
return (0);
+ m_clrprotoflags(m0);
n->m_next = m0; /* concatenate data to control */
SBLASTRECORDCHK(sb);
@@ -1062,6 +1066,21 @@ sbcut_internal(struct sockbuf *sb, int len)
m = n;
}
}
+ /*
+ * Free any zero-length mbufs from the buffer.
+ * For SOCK_DGRAM sockets such mbufs represent empty records.
+ * XXX: For SOCK_STREAM sockets such mbufs can appear in the buffer,
+ * when sosend_generic() needs to send only control data.
+ */
+ while (m && m->m_len == 0) {
+ struct mbuf *n;
+
+ 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 f08036d..189a30f 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1310,11 +1310,14 @@ restart:
resid = 0;
if (flags & MSG_EOR)
top->m_flags |= M_EOR;
- } else if (resid > 0) {
+ } else {
/*
* Copy the data from userland into a mbuf
- * chain. If no data is to be copied in,
- * a single empty mbuf is returned.
+ * chain. If resid is 0, which can happen
+ * only if we have control to send, then
+ * a single empty mbuf is returned. This
+ * is a workaround to prevent protocol send
+ * methods to panic.
*/
top = m_uiotombuf(uio, M_WAITOK, space,
(atomic ? max_hdr : 0),
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index a34be50..d6b3765 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -401,17 +401,24 @@ int
vop_stdadvlock(struct vop_advlock_args *ap)
{
struct vnode *vp;
- struct ucred *cred;
struct vattr vattr;
int error;
vp = ap->a_vp;
- cred = curthread->td_ucred;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp, 0);
- if (error)
- return (error);
+ if (ap->a_fl->l_whence == SEEK_END) {
+ /*
+ * The NFSv4 server must avoid doing a vn_lock() here, since it
+ * can deadlock the nfsd threads, due to a LOR. Fortunately
+ * the NFSv4 server always uses SEEK_SET and this code is
+ * only required for the SEEK_END case.
+ */
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
+ VOP_UNLOCK(vp, 0);
+ if (error)
+ return (error);
+ } else
+ vattr.va_size = 0;
return (lf_advlock(ap, &(vp->v_lockf), vattr.va_size));
}
@@ -420,17 +427,19 @@ int
vop_stdadvlockasync(struct vop_advlockasync_args *ap)
{
struct vnode *vp;
- struct ucred *cred;
struct vattr vattr;
int error;
vp = ap->a_vp;
- cred = curthread->td_ucred;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_GETATTR(vp, &vattr, cred);
- VOP_UNLOCK(vp, 0);
- if (error)
- return (error);
+ if (ap->a_fl->l_whence == SEEK_END) {
+ /* The size argument is only needed for SEEK_END. */
+ vn_lock(vp, LK_SHARED | LK_RETRY);
+ error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
+ VOP_UNLOCK(vp, 0);
+ if (error)
+ return (error);
+ } else
+ vattr.va_size = 0;
return (lf_advlockasync(ap, &(vp->v_lockf), vattr.va_size));
}
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 40a69bb..ed4ad4d 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -217,6 +217,8 @@ restart:
return (error);
goto restart;
}
+ if ((vn_open_flags & VN_OPEN_NAMECACHE) != 0)
+ ndp->ni_cnd.cn_flags |= MAKEENTRY;
#ifdef MAC
error = mac_vnode_check_create(cred, ndp->ni_dvp,
&ndp->ni_cnd, vap);
diff --git a/sys/mips/beri/beri_machdep.c b/sys/mips/beri/beri_machdep.c
index 714ee3d..e3cca28 100644
--- a/sys/mips/beri/beri_machdep.c
+++ b/sys/mips/beri/beri_machdep.c
@@ -117,13 +117,13 @@ mips_init(void)
("First region is not within FDT memory range"));
/* Limit size of the first region */
- phys_avail[1] = MIN(mr[0].mr_size, ctob(realmem));
+ phys_avail[1] = (mr[0].mr_start + MIN(mr[0].mr_size, ctob(realmem)));
dump_avail[1] = phys_avail[1];
/* Add the rest of regions */
for (i = 1, j = 2; i < mr_cnt; i++, j+=2) {
phys_avail[j] = mr[i].mr_start;
- phys_avail[j+1] = mr[i].mr_size;
+ phys_avail[j+1] = (mr[i].mr_start + mr[i].mr_size);
dump_avail[j] = phys_avail[j];
dump_avail[j+1] = phys_avail[j+1];
}
diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c
index a4405ae..98fe812 100644
--- a/sys/mips/mips/trap.c
+++ b/sys/mips/mips/trap.c
@@ -617,7 +617,8 @@ trap(struct trapframe *trapframe)
* XXXDTRACE: add pid probe handler here (if ever)
*/
if (!usermode) {
- if (dtrace_trap_func != NULL && (*dtrace_trap_func)(trapframe))
+ if (dtrace_trap_func != NULL &&
+ (*dtrace_trap_func)(trapframe, type) != 0)
return (trapframe->pc);
}
#endif
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index 54533f2..0b1252d 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -248,14 +248,11 @@ SUBDIR= \
netfpga10g \
${_netgraph} \
${_nfe} \
- nfs_common \
nfscl \
- nfsclient \
nfscommon \
nfsd \
nfslock \
nfslockd \
- nfsserver \
nfssvc \
nge \
nmdm \
diff --git a/sys/modules/cryptodev/Makefile b/sys/modules/cryptodev/Makefile
index a82517d..cc5ca12 100644
--- a/sys/modules/cryptodev/Makefile
+++ b/sys/modules/cryptodev/Makefile
@@ -3,6 +3,6 @@
.PATH: ${.CURDIR}/../../opencrypto
KMOD = cryptodev
SRCS = cryptodev.c
-SRCS += bus_if.h device_if.h opt_compat.h
+SRCS += bus_if.h device_if.h opt_compat.h opt_kdtrace.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/dtrace/Makefile b/sys/modules/dtrace/Makefile
index b84c632..08b6937 100644
--- a/sys/modules/dtrace/Makefile
+++ b/sys/modules/dtrace/Makefile
@@ -4,7 +4,6 @@
SUBDIR= dtmalloc \
dtnfscl \
- dtnfsclient \
dtrace \
dtraceall \
dtrace_test \
diff --git a/sys/modules/dtrace/dtnfsclient/Makefile b/sys/modules/dtrace/dtnfsclient/Makefile
deleted file mode 100644
index 1c5208f..0000000
--- a/sys/modules/dtrace/dtnfsclient/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# $FreeBSD$
-
-SYSDIR?= ${.CURDIR}/../../..
-
-.PATH: ${SYSDIR}/nfsclient
-
-KMOD= dtnfsclient
-SRCS= nfs_kdtrace.c
-SRCS+= vnode_if.h
-
-CFLAGS+= -I${SYSDIR}/cddl/compat/opensolaris \
- -I${SYSDIR}/cddl/contrib/opensolaris/uts/common \
- -I${SYSDIR}
-
-.include <bsd.kmod.mk>
-
-CFLAGS+= -include ${SYSDIR}/cddl/compat/opensolaris/sys/debug_compat.h
diff --git a/sys/modules/dtrace/dtraceall/dtraceall.c b/sys/modules/dtrace/dtraceall/dtraceall.c
index eda740e..c144d06 100644
--- a/sys/modules/dtrace/dtraceall/dtraceall.c
+++ b/sys/modules/dtrace/dtraceall/dtraceall.c
@@ -69,9 +69,6 @@ MODULE_DEPEND(dtraceall, dtmalloc, 1, 1, 1);
#if defined(NFSCLIENT)
MODULE_DEPEND(dtraceall, dtnfscl, 1, 1, 1);
#endif
-#if defined(NFSCLIENT)
-MODULE_DEPEND(dtraceall, dtnfsclient, 1, 1, 1);
-#endif
#if defined(__amd64__) || defined(__i386__) || defined(__powerpc__)
MODULE_DEPEND(dtraceall, fbt, 1, 1, 1);
#endif
diff --git a/sys/modules/geom/geom_sched/gs_sched/Makefile b/sys/modules/geom/geom_sched/gs_sched/Makefile
index 5739365..13bb91b 100644
--- a/sys/modules/geom/geom_sched/gs_sched/Makefile
+++ b/sys/modules/geom/geom_sched/gs_sched/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
KMOD= geom_sched
-SRCS= g_sched.c subr_disk.c
+SRCS= g_sched.c
# ../Makefile.inc automatically included
.include <bsd.kmod.mk>
diff --git a/sys/modules/geom/geom_sched/gsched_rr/Makefile b/sys/modules/geom/geom_sched/gsched_rr/Makefile
index 4209277..44cc566 100644
--- a/sys/modules/geom/geom_sched/gsched_rr/Makefile
+++ b/sys/modules/geom/geom_sched/gsched_rr/Makefile
@@ -2,8 +2,6 @@
KMOD= gsched_rr
SRCS= gs_rr.c
-# hash.h on 6.x has a (char *) cast on a const pointer
-#CWARNFLAGS=
# ../Makefile.inc automatically included
.include <bsd.kmod.mk>
diff --git a/sys/modules/if_gif/Makefile b/sys/modules/if_gif/Makefile
index 663c679..3b3a172 100644
--- a/sys/modules/if_gif/Makefile
+++ b/sys/modules/if_gif/Makefile
@@ -6,7 +6,11 @@ SYSDIR?=${.CURDIR}/../..
.PATH: ${SYSDIR}/net ${SYSDIR}/netinet ${SYSDIR}/netinet6
KMOD= if_gif
-SRCS= if_gif.c in_gif.c opt_inet.h opt_inet6.h
+SRCS= if_gif.c opt_inet.h opt_inet6.h
+
+.if ${MK_INET_SUPPORT} != "no"
+SRCS+= in_gif.c
+.endif
.if ${MK_INET6_SUPPORT} != "no"
SRCS+= in6_gif.c
diff --git a/sys/modules/nfs_common/Makefile b/sys/modules/nfs_common/Makefile
deleted file mode 100644
index 8f51f18..0000000
--- a/sys/modules/nfs_common/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../nfs
-
-KMOD= nfs_common
-SRCS= nfs_common.c opt_nfs.h vnode_if.h
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile
deleted file mode 100644
index a015f34..0000000
--- a/sys/modules/nfsclient/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc
-
-KMOD= nfsclient
-SRCS= vnode_if.h \
- nfs_bio.c nfs_node.c nfs_subs.c nfs_nfsiod.c \
- nfs_vfsops.c nfs_vnops.c nfs_krpc.c \
- opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h
-SRCS+= opt_inet6.h opt_kgssapi.h
-
-.if !defined(KERNBUILDDIR)
-NFS_ROOT?= 1 # 0/1 - requires NFS_ROOT to be configured in kernel
-
-.if ${NFS_ROOT} > 0
-opt_nfsroot.h:
- echo "#define NFS_ROOT 1" > ${.TARGET}
-.endif
-.else
-OPT_NFS_ROOT!= cat ${KERNBUILDDIR}/opt_nfsroot.h
-.if empty(OPT_NFS_ROOT)
-NFS_ROOT= 0
-.else
-NFS_ROOT= 1
-.endif
-.endif
-
-.if ${NFS_ROOT} > 0
-SRCS+= nfs_diskless.c
-.endif
-
-.include <bsd.kmod.mk>
diff --git a/sys/modules/nfsserver/Makefile b/sys/modules/nfsserver/Makefile
deleted file mode 100644
index d00fe47..0000000
--- a/sys/modules/nfsserver/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../nfsserver ${.CURDIR}/../../nfs
-KMOD= nfsserver
-SRCS= vnode_if.h \
- nfs_fha.c nfs_fha_old.c nfs_serv.c nfs_srvkrpc.c nfs_srvsubs.c \
- opt_mac.h \
- opt_kgssapi.h \
- opt_nfs.h
-SRCS+= opt_inet6.h
-
-.include <bsd.kmod.mk>
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 674060dd..0a4139f 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -72,7 +72,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_ecn.h>
#ifdef INET
#include <netinet/in_var.h>
-#include <netinet/in_gif.h>
#include <netinet/ip_var.h>
#endif /* INET */
@@ -85,7 +84,6 @@ __FBSDID("$FreeBSD$");
#include <netinet6/ip6_ecn.h>
#include <netinet6/ip6_var.h>
#include <netinet6/scope6_var.h>
-#include <netinet6/in6_gif.h>
#include <netinet6/ip6protosw.h>
#endif /* INET6 */
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h
index b5ebf15..b263850 100644
--- a/sys/net/if_gif.h
+++ b/sys/net/if_gif.h
@@ -114,6 +114,16 @@ void gif_input(struct mbuf *, struct ifnet *, int, uint8_t);
int gif_output(struct ifnet *, struct mbuf *, const struct sockaddr *,
struct route *);
int gif_encapcheck(const struct mbuf *, int, int, void *);
+#ifdef INET
+int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t);
+int in_gif_encapcheck(const struct mbuf *, int, int, void *);
+int in_gif_attach(struct gif_softc *);
+#endif
+#ifdef INET6
+int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t);
+int in6_gif_encapcheck(const struct mbuf *, int, int, void *);
+int in6_gif_attach(struct gif_softc *);
+#endif
#endif /* _KERNEL */
#define GIFGOPTS _IOWR('i', 150, struct ifreq)
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 4d00ca2..23e55e2 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -119,16 +119,6 @@ static int gre_set_tunnel(struct ifnet *, struct sockaddr *,
struct sockaddr *);
static void gre_delete_tunnel(struct ifnet *);
-int gre_input(struct mbuf **, int *, int);
-#ifdef INET
-extern int in_gre_attach(struct gre_softc *);
-extern int in_gre_output(struct mbuf *, int, int);
-#endif
-#ifdef INET6
-extern int in6_gre_attach(struct gre_softc *);
-extern int in6_gre_output(struct mbuf *, int, int);
-#endif
-
SYSCTL_DECL(_net_link);
static SYSCTL_NODE(_net_link, IFT_TUNNEL, gre, CTLFLAG_RW, 0,
"Generic Routing Encapsulation");
diff --git a/sys/net/if_gre.h b/sys/net/if_gre.h
index 3a48efe..806b0cb 100644
--- a/sys/net/if_gre.h
+++ b/sys/net/if_gre.h
@@ -100,6 +100,15 @@ struct gre_softc {
#define gre_oip gre_gihdr->gi_ip
#define gre_oip6 gre_gi6hdr->gi6_ip6
+int gre_input(struct mbuf **, int *, int);
+#ifdef INET
+int in_gre_attach(struct gre_softc *);
+int in_gre_output(struct mbuf *, int, int);
+#endif
+#ifdef INET6
+int in6_gre_attach(struct gre_softc *);
+int in6_gre_output(struct mbuf *, int, int);
+#endif
/*
* CISCO uses special type for GRE tunnel created as part of WCCP
* connection, while in fact those packets are just IPv4 encapsulated
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c
index f3a6042..aed2a37 100644
--- a/sys/net/if_stf.c
+++ b/sys/net/if_stf.c
@@ -99,7 +99,6 @@
#include <net/route.h>
#include <net/netisr.h>
#include <net/if_types.h>
-#include <net/if_stf.h>
#include <net/vnet.h>
#include <netinet/in.h>
@@ -156,7 +155,8 @@ static MALLOC_DEFINE(M_STF, stfname, "6to4 Tunnel Interface");
static const int ip_stf_ttl = 40;
extern struct domain inetdomain;
-struct protosw in_stf_protosw = {
+static int in_stf_input(struct mbuf **, int *, int);
+static struct protosw in_stf_protosw = {
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_IPV6,
@@ -620,7 +620,7 @@ stf_checkaddr6(sc, in6, inifp)
return 0;
}
-int
+static int
in_stf_input(struct mbuf **mp, int *offp, int proto)
{
struct stf_softc *sc;
diff --git a/sys/net/if_stf.h b/sys/net/if_stf.h
deleted file mode 100644
index 07f585b..0000000
--- a/sys/net/if_stf.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: if_stf.h,v 1.5 2001/10/12 10:09:17 keiichi Exp $ */
-
-/*-
- * 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.
- */
-
-#ifndef _NET_IF_STF_H_
-#define _NET_IF_STF_H_
-
-int in_stf_input(struct mbuf **, int *, int);
-
-#endif /* _NET_IF_STF_H_ */
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index a8d92f9..8cb1f51 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1702,7 +1702,7 @@ ieee80211_add_xrates(uint8_t *frm, const struct ieee80211_rateset *rs)
/*
* Add an ssid element to a frame.
*/
-static uint8_t *
+uint8_t *
ieee80211_add_ssid(uint8_t *frm, const uint8_t *ssid, u_int len)
{
*frm++ = IEEE80211_ELEMID_SSID;
diff --git a/sys/net80211/ieee80211_power.c b/sys/net80211/ieee80211_power.c
index 04b3c3a..812cd70 100644
--- a/sys/net80211/ieee80211_power.c
+++ b/sys/net80211/ieee80211_power.c
@@ -560,10 +560,15 @@ ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable)
* Handle being notified that we have data available for us in a TIM/ATIM.
*
* This may schedule a transition from _SLEEP -> _RUN if it's appropriate.
+ *
+ * In STA mode, we may have put to sleep during scan and need to be dragged
+ * back out of powersave mode.
*/
void
ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set)
{
+ struct ieee80211com *ic = vap->iv_ic;
+
/*
* Schedule the driver state change. It'll happen at some point soon.
* Since the hardware shouldn't know that we're running just yet
@@ -574,10 +579,24 @@ ieee80211_sta_tim_notify(struct ieee80211vap *vap, int set)
* XXX TODO: verify that the transition to RUN will wake up the
* BSS node!
*/
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER, "%s: TIM=%d\n", __func__, set);
IEEE80211_LOCK(vap->iv_ic);
if (set == 1 && vap->iv_state == IEEE80211_S_SLEEP) {
ieee80211_new_state_locked(vap, IEEE80211_S_RUN, 0);
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
+ "%s: TIM=%d; wakeup\n", __func__, set);
+ } else if ((set == 1) && (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)) {
+ /*
+ * XXX only do this if we're in RUN state?
+ */
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_POWER,
+ "%s: wake up from bgscan vap sleep\n",
+ __func__);
+ /*
+ * We may be in BGSCAN mode - this means the VAP is is in STA
+ * mode powersave. If it is, we need to wake it up so we
+ * can process outbound traffic.
+ */
+ vap->iv_sta_ps(vap, 0);
}
IEEE80211_UNLOCK(vap->iv_ic);
}
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 8df5116..3b46ac4 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -149,6 +149,7 @@ struct mbuf *ieee80211_alloc_cts(struct ieee80211com *,
uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset *);
uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset *);
+uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int);
uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap *);
uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap *);
uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node *);
diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c
index 66e8430..d81ba7c 100644
--- a/sys/net80211/ieee80211_scan.c
+++ b/sys/net80211/ieee80211_scan.c
@@ -698,6 +698,13 @@ ieee80211_cancel_scan(struct ieee80211vap *vap)
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
/* wake up the scan task */
scan_signal(ss);
+ } else {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n",
+ __func__,
+ !! (ic->ic_flags & IEEE80211_F_SCAN),
+ (ss->ss_vap == vap ? "match" : "nomatch"),
+ !! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL));
}
IEEE80211_UNLOCK(ic);
}
@@ -724,6 +731,13 @@ ieee80211_cancel_anyscan(struct ieee80211vap *vap)
SCAN_PRIVATE(ss)->ss_iflags |= ISCAN_CANCEL;
/* wake up the scan task */
scan_signal(ss);
+ } else {
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: called; F_SCAN=%d, vap=%s, CANCEL=%d\n",
+ __func__,
+ !! (ic->ic_flags & IEEE80211_F_SCAN),
+ (ss->ss_vap == vap ? "match" : "nomatch"),
+ !! (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL));
}
IEEE80211_UNLOCK(ic);
}
@@ -738,6 +752,8 @@ ieee80211_scan_next(struct ieee80211vap *vap)
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_scan_state *ss = ic->ic_scan;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__);
+
/* wake up the scan task */
IEEE80211_LOCK(ic);
scan_signal(ss);
@@ -754,6 +770,8 @@ ieee80211_scan_done(struct ieee80211vap *vap)
struct ieee80211com *ic = vap->iv_ic;
struct ieee80211_scan_state *ss;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__);
+
IEEE80211_LOCK(ic);
ss = ic->ic_scan;
ss->ss_next = ss->ss_last; /* all channels are complete */
@@ -807,6 +825,10 @@ scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell)
{
struct ieee80211vap *vap = ss->ss_vap;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: calling; maxdwell=%lu\n",
+ __func__,
+ maxdwell);
IEEE80211_LOCK(vap->iv_ic);
if (ss->ss_flags & IEEE80211_SCAN_ACTIVE)
ieee80211_probe_curchan(vap, 0);
@@ -821,7 +843,6 @@ scan_signal(void *arg)
struct ieee80211_scan_state *ss = (struct ieee80211_scan_state *) arg;
IEEE80211_LOCK_ASSERT(ss->ss_ic);
-
cv_signal(&SCAN_PRIVATE(ss)->ss_scan_cv);
}
@@ -834,6 +855,8 @@ scan_mindwell(struct ieee80211_scan_state *ss)
{
struct ieee80211com *ic = ss->ss_ic;
+ IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, "%s: called\n", __func__);
+
IEEE80211_LOCK(ic);
scan_signal(ss);
IEEE80211_UNLOCK(ic);
@@ -882,13 +905,23 @@ scan_task(void *arg, int pending)
}
scanend = ticks + SCAN_PRIVATE(ss)->ss_duration;
+
+ /* XXX scan state can change! Re-validate scan state! */
+
IEEE80211_UNLOCK(ic);
ic->ic_scan_start(ic); /* notify driver */
IEEE80211_LOCK(ic);
for (;;) {
+
scandone = (ss->ss_next >= ss->ss_last) ||
(SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0;
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN,
+ "%s: loop start; scandone=%d\n",
+ __func__,
+ scandone);
+
if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) ||
(SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT) ||
time_after(ticks + ss->ss_mindwell, scanend))
@@ -944,6 +977,8 @@ scan_task(void *arg, int pending)
ic->ic_scan_curchan(ss, maxdwell);
IEEE80211_LOCK(ic);
+ /* XXX scan state can change! Re-validate scan state! */
+
SCAN_PRIVATE(ss)->ss_chanmindwell = ticks + ss->ss_mindwell;
/* clear mindwell lock and initial channel change flush */
SCAN_PRIVATE(ss)->ss_iflags &= ~ISCAN_REP;
@@ -951,15 +986,20 @@ scan_task(void *arg, int pending)
if ((SCAN_PRIVATE(ss)->ss_iflags & (ISCAN_CANCEL|ISCAN_ABORT)))
continue;
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: waiting\n", __func__);
/* Wait to be signalled to scan the next channel */
cv_wait(&SCAN_PRIVATE(ss)->ss_scan_cv, IEEE80211_LOCK_OBJ(ic));
}
+
+ IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, "%s: out\n", __func__);
+
if (SCAN_PRIVATE(ss)->ss_iflags & ISCAN_ABORT)
goto done;
IEEE80211_UNLOCK(ic);
ic->ic_scan_end(ic); /* notify driver */
IEEE80211_LOCK(ic);
+ /* XXX scan state can change! Re-validate scan state! */
/*
* Since a cancellation may have occured during one of the
@@ -969,10 +1009,10 @@ scan_task(void *arg, int pending)
((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0)) {
/* XXX printf? */
if_printf(vap->iv_ifp,
- "%s: OOPS! scan cancelled during driver call!\n",
+ "%s: OOPS! scan cancelled during driver call (1)!\n",
__func__);
+ scandone = 1;
}
- scandone |= ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0);
/*
* Record scan complete time. Note that we also do
@@ -1032,6 +1072,19 @@ scan_task(void *arg, int pending)
ticks, ss->ss_mindwell, scanend);
/*
+ * Since a cancellation may have occured during one of the
+ * driver calls (whilst unlocked), update scandone.
+ */
+ if (scandone == 0 &&
+ ((SCAN_PRIVATE(ss)->ss_iflags & ISCAN_CANCEL) != 0)) {
+ /* XXX printf? */
+ if_printf(vap->iv_ifp,
+ "%s: OOPS! scan cancelled during driver call (2)!\n",
+ __func__);
+ scandone = 1;
+ }
+
+ /*
* Clear the SCAN bit first in case frames are
* pending on the station power save queue. If
* we defer this then the dispatch of the frames
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 89ed856..c3c2bc9 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -1405,6 +1405,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
int ix = aid / NBBY;
int min = tim->tim_bitctl &~ 1;
int max = tim->tim_len + min - 4;
+ int tim_ucast = 0, tim_mcast = 0;
/*
* Only do this for unicast traffic in the TIM
@@ -1414,20 +1415,42 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
*/
if (min <= ix && ix <= max &&
isset(tim->tim_bitmap - min, aid)) {
- ieee80211_sta_tim_notify(vap, 1);
- ic->ic_lastdata = ticks;
+ tim_ucast = 1;
}
/*
- * XXX TODO: do a separate notification
+ * Do a separate notification
* for the multicast bit being set.
*/
-#if 0
if (tim->tim_bitctl & 1) {
+ tim_mcast = 1;
+ }
+
+ /*
+ * If the TIM indicates there's traffic for
+ * us then get us out of STA mode powersave.
+ */
+ if (tim_ucast == 1) {
+
+ /*
+ * Wake us out of SLEEP state if we're
+ * in it; and if we're doing bgscan
+ * then wake us out of STA powersave.
+ */
ieee80211_sta_tim_notify(vap, 1);
+
+ /*
+ * This is preventing us from
+ * continuing a bgscan; because it
+ * tricks the contbgscan()
+ * routine to think there's always
+ * traffic for us.
+ *
+ * I think we need both an RX and
+ * TX ic_lastdata field.
+ */
ic->ic_lastdata = ticks;
}
-#endif
ni->ni_dtim_count = tim->tim_count;
ni->ni_dtim_period = tim->tim_period;
diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c
index 46f68f5..cd412ad 100644
--- a/sys/netinet/in_gif.c
+++ b/sys/netinet/in_gif.c
@@ -57,7 +57,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
-#include <netinet/in_gif.h>
#include <netinet/in_var.h>
#include <netinet/ip_encap.h>
#include <netinet/ip_ecn.h>
@@ -70,9 +69,10 @@ __FBSDID("$FreeBSD$");
static int gif_validate4(const struct ip *, struct gif_softc *,
struct ifnet *);
+static int in_gif_input(struct mbuf **, int *, int);
extern struct domain inetdomain;
-struct protosw in_gif_protosw = {
+static struct protosw in_gif_protosw = {
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
.pr_protocol = 0/* IPPROTO_IPV[46] */,
@@ -83,7 +83,8 @@ struct protosw in_gif_protosw = {
.pr_usrreqs = &rip_usrreqs
};
-VNET_DEFINE(int, ip_gif_ttl) = GIF_TTL;
+#define GIF_TTL 30
+static VNET_DEFINE(int, ip_gif_ttl) = GIF_TTL;
#define V_ip_gif_ttl VNET(ip_gif_ttl)
SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_VNET | CTLFLAG_RW,
&VNET_NAME(ip_gif_ttl), 0, "");
@@ -133,7 +134,7 @@ in_gif_output(struct ifnet *ifp, struct mbuf *m, int proto, uint8_t ecn)
return (ip_output(m, NULL, NULL, 0, NULL, NULL));
}
-int
+static int
in_gif_input(struct mbuf **mp, int *offp, int proto)
{
struct mbuf *m = *mp;
diff --git a/sys/netinet/in_gif.h b/sys/netinet/in_gif.h
deleted file mode 100644
index d48d881..0000000
--- a/sys/netinet/in_gif.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* $FreeBSD$ */
-/* $KAME: in_gif.h,v 1.5 2000/04/14 08:36:02 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.
- */
-
-#ifndef _NETINET_IN_GIF_H_
-#define _NETINET_IN_GIF_H_
-
-#define GIF_TTL 30
-
-struct gif_softc;
-int in_gif_input(struct mbuf **, int *, int);
-int in_gif_output(struct ifnet *, struct mbuf *, int, uint8_t);
-int in_gif_encapcheck(const struct mbuf *, int, int, void *);
-int in_gif_attach(struct gif_softc *);
-
-#endif /*_NETINET_IN_GIF_H_*/
diff --git a/sys/netinet/in_systm.h b/sys/netinet/in_systm.h
index 4b34aa0..acd2e62 100644
--- a/sys/netinet/in_systm.h
+++ b/sys/netinet/in_systm.h
@@ -44,12 +44,15 @@
* Internally the system keeps counters in the headers with the bytes
* swapped so that VAX instructions will work on them. It reverses
* the bytes before transmission at each protocol level. The n_ types
- * represent the types with the bytes in ``high-ender'' order.
+ * represent the types with the bytes in ``high-ender'' order. Network
+ * byte order is usually referered to as big-endian these days rather
+ * than high-ender, which sadly invokes an Orson Scott Card novel, or
+ * worse, the movie.
*/
typedef u_int16_t n_short; /* short as received from the net */
typedef u_int32_t n_long; /* long as received from the net */
-typedef u_int32_t n_time; /* ms since 00:00 GMT, byte rev */
+typedef u_int32_t n_time; /* ms since 00:00 UTC, byte rev */
#ifdef _KERNEL
uint32_t iptime(void);
diff --git a/sys/netinet/ip_gre.c b/sys/netinet/ip_gre.c
index 9f28191..5942364 100644
--- a/sys/netinet/ip_gre.c
+++ b/sys/netinet/ip_gre.c
@@ -68,11 +68,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_gre.h>
extern struct domain inetdomain;
-extern int gre_input(struct mbuf **, int *, int);
-
-int in_gre_attach(struct gre_softc *);
-int in_gre_output(struct mbuf *, int, int);
-
static const struct protosw in_gre_protosw = {
.pr_type = SOCK_RAW,
.pr_domain = &inetdomain,
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index d134a2e..b6b967f 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -861,7 +861,7 @@ icmp_send(struct mbuf *m, struct mbuf *opts)
}
/*
- * Return milliseconds since 00:00 GMT in network format.
+ * Return milliseconds since 00:00 UTC in network format.
*/
uint32_t
iptime(void)
diff --git a/sys/netinet/ip_icmp.h b/sys/netinet/ip_icmp.h
index ca1e963..38d44d7 100644
--- a/sys/netinet/ip_icmp.h
+++ b/sys/netinet/ip_icmp.h
@@ -99,7 +99,7 @@ struct icmp {
struct id_ts { /* ICMP Timestamp */
/*
* The next 3 fields are in network format,
- * milliseconds since 00:00 GMT
+ * milliseconds since 00:00 UTC
*/
uint32_t its_otime; /* Originate */
uint32_t its_rtime; /* Receive */
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 617e480..95955de 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -3639,16 +3639,10 @@ flags_out:
policy = sprstat->sprstat_policy;
#if defined(SCTP_DETAILED_STR_STATS)
if ((stcb != NULL) &&
- (policy != SCTP_PR_SCTP_NONE) &&
(sid < stcb->asoc.streamoutcnt) &&
- ((policy == SCTP_PR_SCTP_ALL) ||
- (PR_SCTP_VALID_POLICY(policy)))) {
-#else
- if ((stcb != NULL) &&
(policy != SCTP_PR_SCTP_NONE) &&
- (sid < stcb->asoc.streamoutcnt) &&
- (policy == SCTP_PR_SCTP_ALL)) {
-#endif
+ ((policy <= SCTP_PR_SCTP_MAX) ||
+ (policy == SCTP_PR_SCTP_ALL))) {
if (policy == SCTP_PR_SCTP_ALL) {
sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
@@ -3656,6 +3650,13 @@ flags_out:
sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy];
sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy];
}
+#else
+ if ((stcb != NULL) &&
+ (sid < stcb->asoc.streamoutcnt) &&
+ (policy == SCTP_PR_SCTP_ALL)) {
+ sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
+ sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
+#endif
SCTP_TCB_UNLOCK(stcb);
*optsize = sizeof(struct sctp_prstatus);
} else {
@@ -3675,8 +3676,8 @@ flags_out:
policy = sprstat->sprstat_policy;
if ((stcb != NULL) &&
(policy != SCTP_PR_SCTP_NONE) &&
- ((policy == SCTP_PR_SCTP_ALL) ||
- (PR_SCTP_VALID_POLICY(policy)))) {
+ ((policy <= SCTP_PR_SCTP_MAX) ||
+ (policy == SCTP_PR_SCTP_ALL))) {
if (policy == SCTP_PR_SCTP_ALL) {
sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0];
sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0];
@@ -6037,7 +6038,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize);
SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
- if (PR_SCTP_INVALID_POLICY(info->pr_policy)) {
+ if (info->pr_policy > SCTP_PR_SCTP_MAX) {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
error = EINVAL;
break;
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index d066c74..edf6ae8 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1949,7 +1949,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* though we use a different timer. We also add the HB timer
* PLUS a random jitter.
*/
- if ((inp == NULL) || (stcb == NULL) || (net == NULL)) {
+ if ((stcb == NULL) || (net == NULL)) {
return;
} else {
uint32_t rndval;
@@ -2004,9 +2004,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* nothing needed but the endpoint here ususually about 60
* minutes.
*/
- if (inp == NULL) {
- return;
- }
tmr = &inp->sctp_ep.signature_change;
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_SIGNATURE];
break;
@@ -2023,9 +2020,6 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* timer since that has stopped and we are in the GONE
* state.
*/
- if (inp == NULL) {
- return;
- }
tmr = &inp->sctp_ep.signature_change;
to_ticks = MSEC_TO_TICKS(SCTP_INP_KILL_TIMEOUT);
break;
@@ -2034,10 +2028,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* Here we use the value found in the EP for PMTU ususually
* about 10 minutes.
*/
- if ((stcb == NULL) || (inp == NULL)) {
- return;
- }
- if (net == NULL) {
+ if ((stcb == NULL) || (net == NULL)) {
return;
}
if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
@@ -2063,7 +2054,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* Here we use the endpoints shutdown guard timer usually
* about 3 minutes.
*/
- if ((inp == NULL) || (stcb == NULL)) {
+ if (stcb == NULL) {
return;
}
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_MAXSHUTDOWN];
diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c
index 10d5d7b..3db4b4f 100644
--- a/sys/netinet6/in6_gif.c
+++ b/sys/netinet6/in6_gif.c
@@ -64,7 +64,6 @@ __FBSDID("$FreeBSD$");
#ifdef INET6
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
-#include <netinet6/in6_gif.h>
#include <netinet6/in6_var.h>
#endif
#include <netinet/ip_ecn.h>
@@ -74,7 +73,8 @@ __FBSDID("$FreeBSD$");
#include <net/if_gif.h>
-VNET_DEFINE(int, ip6_gif_hlim) = GIF_HLIM;
+#define GIF_HLIM 30
+static VNET_DEFINE(int, ip6_gif_hlim) = GIF_HLIM;
#define V_ip6_gif_hlim VNET(ip6_gif_hlim)
SYSCTL_DECL(_net_inet6_ip6);
@@ -83,9 +83,10 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_GIF_HLIM, gifhlim, CTLFLAG_VNET | CTLFLAG_RW,
static int gif_validate6(const struct ip6_hdr *, struct gif_softc *,
struct ifnet *);
+static int in6_gif_input(struct mbuf **, int *, int);
extern struct domain inet6domain;
-struct protosw in6_gif_protosw = {
+static struct protosw in6_gif_protosw = {
.pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
.pr_protocol = 0, /* IPPROTO_IPV[46] */
@@ -144,7 +145,7 @@ in6_gif_output(struct ifnet *ifp, struct mbuf *m, int proto, uint8_t ecn)
return (ip6_output(m, 0, NULL, IPV6_MINMTU, 0, NULL, NULL));
}
-int
+static int
in6_gif_input(struct mbuf **mp, int *offp, int proto)
{
struct mbuf *m = *mp;
diff --git a/sys/netinet6/in6_gif.h b/sys/netinet6/in6_gif.h
deleted file mode 100644
index 1246171..0000000
--- a/sys/netinet6/in6_gif.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * 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.
- *
- * $KAME: in6_gif.h,v 1.5 2000/04/14 08:36:03 itojun Exp $
- * $FreeBSD$
- */
-
-#ifndef _NETINET6_IN6_GIF_H_
-#define _NETINET6_IN6_GIF_H_
-
-#define GIF_HLIM 30
-
-struct gif_softc;
-int in6_gif_input(struct mbuf **, int *, int);
-int in6_gif_output(struct ifnet *, struct mbuf *, int, uint8_t);
-int in6_gif_encapcheck(const struct mbuf *, int, int, void *);
-int in6_gif_attach(struct gif_softc *);
-
-#endif /* _NETINET6_IN6_GIF_H_ */
diff --git a/sys/netinet6/ip6_gre.c b/sys/netinet6/ip6_gre.c
index 29a0725..095a1de 100644
--- a/sys/netinet6/ip6_gre.c
+++ b/sys/netinet6/ip6_gre.c
@@ -62,11 +62,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_gre.h>
extern struct domain inet6domain;
-extern int gre_input(struct mbuf **, int *, int);
-
-int in6_gre_attach(struct gre_softc *);
-int in6_gre_output(struct mbuf *, int, int);
-
struct protosw in6_gre_protosw = {
.pr_type = SOCK_RAW,
.pr_domain = &inet6domain,
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c
index 5e0cdbf..8a79052 100644
--- a/sys/netipsec/ipsec.c
+++ b/sys/netipsec/ipsec.c
@@ -118,11 +118,12 @@ VNET_DEFINE(int, ip4_esp_trans_deflev) = IPSEC_LEVEL_USE;
VNET_DEFINE(int, ip4_esp_net_deflev) = IPSEC_LEVEL_USE;
VNET_DEFINE(int, ip4_ah_trans_deflev) = IPSEC_LEVEL_USE;
VNET_DEFINE(int, ip4_ah_net_deflev) = IPSEC_LEVEL_USE;
-VNET_DEFINE(struct secpolicy, ip4_def_policy);
/* ECN ignore(-1)/forbidden(0)/allowed(1) */
VNET_DEFINE(int, ip4_ipsec_ecn) = 0;
VNET_DEFINE(int, ip4_esp_randpad) = -1;
+static VNET_DEFINE(struct secpolicy, def_policy);
+#define V_def_policy VNET(def_policy)
/*
* Crypto support requirements:
*
@@ -141,7 +142,7 @@ SYSCTL_DECL(_net_inet_ipsec);
/* net.inet.ipsec */
SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_def_policy).policy, 0,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0,
"IPsec default policy.");
SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_trans_deflev), 0,
@@ -213,7 +214,7 @@ SYSCTL_DECL(_net_inet6_ipsec6);
/* net.inet6.ipsec6 */
SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy,
- CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_def_policy).policy, 0,
+ CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(def_policy).policy, 0,
"IPsec default policy.");
SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_trans_deflev), 0,
@@ -262,7 +263,7 @@ key_allocsp_default(const char* where, int tag)
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP key_allocsp_default from %s:%u\n", where, tag));
- sp = &V_ip4_def_policy;
+ sp = &V_def_policy;
if (sp->policy != IPSEC_POLICY_DISCARD &&
sp->policy != IPSEC_POLICY_NONE) {
ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
@@ -828,17 +829,13 @@ ipsec_init_policy(struct socket *so, struct inpcbpolicy **pcb_sp)
ipsec_delpcbpolicy(new);
return (ENOBUFS);
}
- new->sp_in->state = IPSEC_SPSTATE_ALIVE;
new->sp_in->policy = IPSEC_POLICY_ENTRUST;
-
if ((new->sp_out = KEY_NEWSP()) == NULL) {
KEY_FREESP(&new->sp_in);
ipsec_delpcbpolicy(new);
return (ENOBUFS);
}
- new->sp_out->state = IPSEC_SPSTATE_ALIVE;
new->sp_out->policy = IPSEC_POLICY_ENTRUST;
-
*pcb_sp = new;
return (0);
@@ -927,7 +924,6 @@ ipsec_deepcopy_policy(struct secpolicy *src)
}
dst->req = newchain;
- dst->state = src->state;
dst->policy = src->policy;
/* Do not touch the refcnt fields. */
@@ -979,8 +975,6 @@ ipsec_set_policy_internal(struct secpolicy **pcb_sp, int optname,
if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
return (error);
- newsp->state = IPSEC_SPSTATE_ALIVE;
-
/* Clear old SP and set new SP. */
KEY_FREESP(pcb_sp);
*pcb_sp = newsp;
@@ -1693,14 +1687,15 @@ ipsec_dumpmbuf(struct mbuf *m)
}
static void
-ipsec_init(const void *unused __unused)
+def_policy_init(const void *unused __unused)
{
- SECPOLICY_LOCK_INIT(&V_ip4_def_policy);
- V_ip4_def_policy.refcnt = 1; /* NB: disallow free. */
+ bzero(&V_def_policy, sizeof(struct secpolicy));
+ V_def_policy.policy = IPSEC_POLICY_NONE;
+ V_def_policy.refcnt = 1;
}
-VNET_SYSINIT(ipsec_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY, ipsec_init,
- NULL);
+VNET_SYSINIT(def_policy_init, SI_SUB_PROTO_DOMAININIT, SI_ORDER_ANY,
+ def_policy_init, NULL);
/* XXX This stuff doesn't belong here... */
diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h
index 8ed39fb..5e3e1c3 100644
--- a/sys/netipsec/ipsec.h
+++ b/sys/netipsec/ipsec.h
@@ -81,21 +81,15 @@ struct secpolicyindex {
/* Security Policy Data Base */
struct secpolicy {
- LIST_ENTRY(secpolicy) chain;
- struct mtx lock;
+ TAILQ_ENTRY(secpolicy) chain;
- u_int refcnt; /* reference count */
struct secpolicyindex spidx; /* selector */
- u_int32_t id; /* It's unique number on the system. */
- u_int state; /* 0: dead, others: alive */
-#define IPSEC_SPSTATE_DEAD 0
-#define IPSEC_SPSTATE_ALIVE 1
- u_int policy; /* policy_type per pfkeyv2.h */
- u_int16_t scangen; /* scan generation # */
struct ipsecrequest *req;
/* pointer to the ipsec request tree, */
/* if policy == IPSEC else this value == NULL.*/
-
+ u_int refcnt; /* reference count */
+ u_int policy; /* policy_type per pfkeyv2.h */
+ u_int32_t id; /* It's unique number on the system. */
/*
* lifetime handler.
* the policy can be used without limitiation if both lifetime and
@@ -109,13 +103,6 @@ struct secpolicy {
long validtime; /* duration this policy is valid without use */
};
-#define SECPOLICY_LOCK_INIT(_sp) \
- mtx_init(&(_sp)->lock, "ipsec policy", NULL, MTX_DEF)
-#define SECPOLICY_LOCK(_sp) mtx_lock(&(_sp)->lock)
-#define SECPOLICY_UNLOCK(_sp) mtx_unlock(&(_sp)->lock)
-#define SECPOLICY_LOCK_DESTROY(_sp) mtx_destroy(&(_sp)->lock)
-#define SECPOLICY_LOCK_ASSERT(_sp) mtx_assert(&(_sp)->lock, MA_OWNED)
-
/* Request for IPsec */
struct ipsecrequest {
struct ipsecrequest *next;
@@ -279,7 +266,6 @@ VNET_DECLARE(int, ipsec_integrity);
#endif
VNET_PCPUSTAT_DECLARE(struct ipsecstat, ipsec4stat);
-VNET_DECLARE(struct secpolicy, ip4_def_policy);
VNET_DECLARE(int, ip4_esp_trans_deflev);
VNET_DECLARE(int, ip4_esp_net_deflev);
VNET_DECLARE(int, ip4_ah_trans_deflev);
@@ -292,7 +278,6 @@ VNET_DECLARE(int, crypto_support);
#define IPSECSTAT_INC(name) \
VNET_PCPUSTAT_ADD(struct ipsecstat, ipsec4stat, name, 1)
-#define V_ip4_def_policy VNET(ip4_def_policy)
#define V_ip4_esp_trans_deflev VNET(ip4_esp_trans_deflev)
#define V_ip4_esp_net_deflev VNET(ip4_esp_net_deflev)
#define V_ip4_ah_trans_deflev VNET(ip4_ah_trans_deflev)
diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c
index 953f453..b9bcd59 100644
--- a/sys/netipsec/key.c
+++ b/sys/netipsec/key.c
@@ -48,6 +48,7 @@
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/malloc.h>
+#include <sys/rmlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
@@ -141,16 +142,19 @@ static VNET_DEFINE(u_int32_t, acq_seq) = 0;
#define V_acq_seq VNET(acq_seq)
/* SPD */
-static VNET_DEFINE(LIST_HEAD(_sptree, secpolicy), sptree[IPSEC_DIR_MAX]);
+static VNET_DEFINE(TAILQ_HEAD(_sptree, secpolicy), sptree[IPSEC_DIR_MAX]);
+static struct rmlock sptree_lock;
#define V_sptree VNET(sptree)
-static struct mtx sptree_lock;
-#define SPTREE_LOCK_INIT() \
- mtx_init(&sptree_lock, "sptree", \
- "fast ipsec security policy database", MTX_DEF)
-#define SPTREE_LOCK_DESTROY() mtx_destroy(&sptree_lock)
-#define SPTREE_LOCK() mtx_lock(&sptree_lock)
-#define SPTREE_UNLOCK() mtx_unlock(&sptree_lock)
-#define SPTREE_LOCK_ASSERT() mtx_assert(&sptree_lock, MA_OWNED)
+#define SPTREE_LOCK_INIT() rm_init(&sptree_lock, "sptree")
+#define SPTREE_LOCK_DESTROY() rm_destroy(&sptree_lock)
+#define SPTREE_RLOCK_TRACKER struct rm_priotracker sptree_tracker
+#define SPTREE_RLOCK() rm_rlock(&sptree_lock, &sptree_tracker)
+#define SPTREE_RUNLOCK() rm_runlock(&sptree_lock, &sptree_tracker)
+#define SPTREE_RLOCK_ASSERT() rm_assert(&sptree_lock, RA_RLOCKED)
+#define SPTREE_WLOCK() rm_wlock(&sptree_lock)
+#define SPTREE_WUNLOCK() rm_wunlock(&sptree_lock)
+#define SPTREE_WLOCK_ASSERT() rm_assert(&sptree_lock, RA_WLOCKED)
+#define SPTREE_UNLOCK_ASSERT() rm_assert(&sptree_lock, RA_UNLOCKED)
static VNET_DEFINE(LIST_HEAD(_sahtree, secashead), sahtree); /* SAD */
#define V_sahtree VNET(sahtree)
@@ -416,9 +420,8 @@ static struct callout key_timer;
static struct secasvar *key_allocsa_policy(const struct secasindex *);
static void key_freesp_so(struct secpolicy **);
static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int);
-static void key_delsp(struct secpolicy *);
+static void key_unlink(struct secpolicy *);
static struct secpolicy *key_getsp(struct secpolicyindex *);
-static void _key_delsp(struct secpolicy *sp);
static struct secpolicy *key_getspbyid(u_int32_t);
static u_int32_t key_newreqid(void);
static struct mbuf *key_gather_mbuf(struct mbuf *,
@@ -575,15 +578,8 @@ sa_delref(struct secasvar *sav)
return (refcount_release(&sav->refcnt));
}
-#define SP_ADDREF(p) do { \
- (p)->refcnt++; \
- IPSEC_ASSERT((p)->refcnt != 0, ("SP refcnt overflow")); \
-} while (0)
-#define SP_DELREF(p) do { \
- IPSEC_ASSERT((p)->refcnt > 0, ("SP refcnt underflow")); \
- (p)->refcnt--; \
-} while (0)
-
+#define SP_ADDREF(p) refcount_acquire(&(p)->refcnt)
+#define SP_DELREF(p) refcount_release(&(p)->refcnt)
/*
* Update the refcnt while holding the SPTREE lock.
@@ -591,9 +587,8 @@ sa_delref(struct secasvar *sav)
void
key_addref(struct secpolicy *sp)
{
- SPTREE_LOCK();
+
SP_ADDREF(sp);
- SPTREE_UNLOCK();
}
/*
@@ -606,7 +601,7 @@ key_havesp(u_int dir)
{
return (dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND ?
- LIST_FIRST(&V_sptree[dir]) != NULL : 1);
+ TAILQ_FIRST(&V_sptree[dir]) != NULL : 1);
}
/* %%% IPsec policy management */
@@ -620,6 +615,7 @@ struct secpolicy *
key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where,
int tag)
{
+ SPTREE_RLOCK_TRACKER;
struct secpolicy *sp;
IPSEC_ASSERT(spidx != NULL, ("null spidx"));
@@ -634,14 +630,11 @@ key_allocsp(struct secpolicyindex *spidx, u_int dir, const char* where,
printf("*** objects\n");
kdebug_secpolicyindex(spidx));
- SPTREE_LOCK();
- LIST_FOREACH(sp, &V_sptree[dir], chain) {
+ SPTREE_RLOCK();
+ TAILQ_FOREACH(sp, &V_sptree[dir], chain) {
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** in SPD\n");
kdebug_secpolicyindex(&sp->spidx));
-
- if (sp->state == IPSEC_SPSTATE_DEAD)
- continue;
if (key_cmpspidx_withmask(&sp->spidx, spidx))
goto found;
}
@@ -655,7 +648,7 @@ found:
sp->lastused = time_second;
SP_ADDREF(sp);
}
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__,
@@ -673,6 +666,7 @@ struct secpolicy *
key_allocsp2(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto,
u_int dir, const char* where, int tag)
{
+ SPTREE_RLOCK_TRACKER;
struct secpolicy *sp;
IPSEC_ASSERT(dst != NULL, ("null dst"));
@@ -688,14 +682,11 @@ key_allocsp2(u_int32_t spi, union sockaddr_union *dst, u_int8_t proto,
printf("spi %u proto %u dir %u\n", spi, proto, dir);
kdebug_sockaddr(&dst->sa));
- SPTREE_LOCK();
- LIST_FOREACH(sp, &V_sptree[dir], chain) {
+ SPTREE_RLOCK();
+ TAILQ_FOREACH(sp, &V_sptree[dir], chain) {
KEYDEBUG(KEYDEBUG_IPSEC_DATA,
printf("*** in SPD\n");
kdebug_secpolicyindex(&sp->spidx));
-
- if (sp->state == IPSEC_SPSTATE_DEAD)
- continue;
/* compare simple values, then dst address */
if (sp->spidx.ul_proto != proto)
continue;
@@ -715,7 +706,7 @@ found:
sp->lastused = time_second;
SP_ADDREF(sp);
}
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s return SP:%p (ID=%u) refcnt %u\n", __func__,
@@ -1174,22 +1165,41 @@ done:
void
_key_freesp(struct secpolicy **spp, const char* where, int tag)
{
+ struct ipsecrequest *isr, *nextisr;
struct secpolicy *sp = *spp;
IPSEC_ASSERT(sp != NULL, ("null sp"));
-
- SPTREE_LOCK();
- SP_DELREF(sp);
-
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s SP:%p (ID=%u) from %s:%u; refcnt now %u\n",
__func__, sp, sp->id, where, tag, sp->refcnt));
- if (sp->refcnt == 0) {
- *spp = NULL;
- key_delsp(sp);
+ if (SP_DELREF(sp) == 0)
+ return;
+ *spp = NULL;
+ for (isr = sp->req; isr != NULL; isr = nextisr) {
+ if (isr->sav != NULL) {
+ KEY_FREESAV(&isr->sav);
+ isr->sav = NULL;
+ }
+ nextisr = isr->next;
+ ipsec_delisr(isr);
}
- SPTREE_UNLOCK();
+ free(sp, M_IPSEC_SP);
+}
+
+static void
+key_unlink(struct secpolicy *sp)
+{
+
+ IPSEC_ASSERT(sp != NULL, ("null sp"));
+ IPSEC_ASSERT(sp->spidx.dir == IPSEC_DIR_INBOUND ||
+ sp->spidx.dir == IPSEC_DIR_OUTBOUND,
+ ("invalid direction %u", sp->spidx.dir));
+ SPTREE_UNLOCK_ASSERT();
+
+ SPTREE_WLOCK();
+ TAILQ_REMOVE(&V_sptree[sp->spidx.dir], sp, chain);
+ SPTREE_WUNLOCK();
}
/*
@@ -1278,38 +1288,6 @@ key_freesav(struct secasvar **psav, const char* where, int tag)
/* %%% SPD management */
/*
- * free security policy entry.
- */
-static void
-key_delsp(struct secpolicy *sp)
-{
- struct ipsecrequest *isr, *nextisr;
-
- IPSEC_ASSERT(sp != NULL, ("null sp"));
- SPTREE_LOCK_ASSERT();
-
- sp->state = IPSEC_SPSTATE_DEAD;
-
- IPSEC_ASSERT(sp->refcnt == 0,
- ("SP with references deleted (refcnt %u)", sp->refcnt));
-
- /* remove from SP index */
- if (__LIST_CHAINED(sp))
- LIST_REMOVE(sp, chain);
-
- for (isr = sp->req; isr != NULL; isr = nextisr) {
- if (isr->sav != NULL) {
- KEY_FREESAV(&isr->sav);
- isr->sav = NULL;
- }
-
- nextisr = isr->next;
- ipsec_delisr(isr);
- }
- _key_delsp(sp);
-}
-
-/*
* search SPD
* OUT: NULL : not found
* others : found, pointer to a SP.
@@ -1317,20 +1295,19 @@ key_delsp(struct secpolicy *sp)
static struct secpolicy *
key_getsp(struct secpolicyindex *spidx)
{
+ SPTREE_RLOCK_TRACKER;
struct secpolicy *sp;
IPSEC_ASSERT(spidx != NULL, ("null spidx"));
- SPTREE_LOCK();
- LIST_FOREACH(sp, &V_sptree[spidx->dir], chain) {
- if (sp->state == IPSEC_SPSTATE_DEAD)
- continue;
+ SPTREE_RLOCK();
+ TAILQ_FOREACH(sp, &V_sptree[spidx->dir], chain) {
if (key_cmpspidx_exactly(spidx, &sp->spidx)) {
SP_ADDREF(sp);
break;
}
}
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
return sp;
}
@@ -1343,28 +1320,25 @@ key_getsp(struct secpolicyindex *spidx)
static struct secpolicy *
key_getspbyid(u_int32_t id)
{
+ SPTREE_RLOCK_TRACKER;
struct secpolicy *sp;
- SPTREE_LOCK();
- LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_INBOUND], chain) {
- if (sp->state == IPSEC_SPSTATE_DEAD)
- continue;
+ SPTREE_RLOCK();
+ TAILQ_FOREACH(sp, &V_sptree[IPSEC_DIR_INBOUND], chain) {
if (sp->id == id) {
SP_ADDREF(sp);
goto done;
}
}
- LIST_FOREACH(sp, &V_sptree[IPSEC_DIR_OUTBOUND], chain) {
- if (sp->state == IPSEC_SPSTATE_DEAD)
- continue;
+ TAILQ_FOREACH(sp, &V_sptree[IPSEC_DIR_OUTBOUND], chain) {
if (sp->id == id) {
SP_ADDREF(sp);
goto done;
}
}
done:
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
return sp;
}
@@ -1376,11 +1350,8 @@ key_newsp(const char* where, int tag)
newsp = (struct secpolicy *)
malloc(sizeof(struct secpolicy), M_IPSEC_SP, M_NOWAIT|M_ZERO);
- if (newsp) {
- SECPOLICY_LOCK_INIT(newsp);
- newsp->refcnt = 1;
- newsp->req = NULL;
- }
+ if (newsp)
+ refcount_init(&newsp->refcnt, 1);
KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
printf("DP %s from %s:%u return SP:%p\n", __func__,
@@ -1388,13 +1359,6 @@ key_newsp(const char* where, int tag)
return newsp;
}
-static void
-_key_delsp(struct secpolicy *sp)
-{
- SECPOLICY_LOCK_DESTROY(sp);
- free(sp, M_IPSEC_SP);
-}
-
/*
* create secpolicy structure from sadb_x_policy structure.
* NOTE: `state', `secpolicyindex' in secpolicy structure are not set,
@@ -1874,9 +1838,7 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
newsp = key_getsp(&spidx);
if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
if (newsp) {
- SPTREE_LOCK();
- newsp->state = IPSEC_SPSTATE_DEAD;
- SPTREE_UNLOCK();
+ key_unlink(newsp);
KEY_FREESP(&newsp);
}
} else {
@@ -1888,13 +1850,15 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
}
}
+ /* XXX: there is race between key_getsp and key_msg2sp. */
+
/* allocation new SP entry */
if ((newsp = key_msg2sp(xpl0, PFKEY_EXTLEN(xpl0), &error)) == NULL) {
return key_senderror(so, m, error);
}
if ((newsp->id = key_getnewspid()) == 0) {
- _key_delsp(newsp);
+ KEY_FREESP(&newsp);
return key_senderror(so, m, ENOBUFS);
}
@@ -1910,18 +1874,20 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
/* sanity check on addr pair */
if (((struct sockaddr *)(src0 + 1))->sa_family !=
((struct sockaddr *)(dst0+ 1))->sa_family) {
- _key_delsp(newsp);
+ KEY_FREESP(&newsp);
return key_senderror(so, m, EINVAL);
}
if (((struct sockaddr *)(src0 + 1))->sa_len !=
((struct sockaddr *)(dst0+ 1))->sa_len) {
- _key_delsp(newsp);
+ KEY_FREESP(&newsp);
return key_senderror(so, m, EINVAL);
}
#if 1
- if (newsp->req && newsp->req->saidx.src.sa.sa_family && newsp->req->saidx.dst.sa.sa_family) {
- if (newsp->req->saidx.src.sa.sa_family != newsp->req->saidx.dst.sa.sa_family) {
- _key_delsp(newsp);
+ if (newsp->req && newsp->req->saidx.src.sa.sa_family &&
+ newsp->req->saidx.dst.sa.sa_family) {
+ if (newsp->req->saidx.src.sa.sa_family !=
+ newsp->req->saidx.dst.sa.sa_family) {
+ KEY_FREESP(&newsp);
return key_senderror(so, m, EINVAL);
}
}
@@ -1932,9 +1898,9 @@ key_spdadd(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
- newsp->refcnt = 1; /* do not reclaim until I say I do */
- newsp->state = IPSEC_SPSTATE_ALIVE;
- LIST_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, secpolicy, chain);
+ SPTREE_WLOCK();
+ TAILQ_INSERT_TAIL(&V_sptree[newsp->spidx.dir], newsp, chain);
+ SPTREE_WUNLOCK();
/* delete the entry in spacqtree */
if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
@@ -2109,9 +2075,7 @@ key_spddelete(struct socket *so, struct mbuf *m,
/* save policy id to buffer to be returned. */
xpl0->sadb_x_policy_id = sp->id;
- SPTREE_LOCK();
- sp->state = IPSEC_SPSTATE_DEAD;
- SPTREE_UNLOCK();
+ key_unlink(sp);
KEY_FREESP(&sp);
{
@@ -2176,9 +2140,7 @@ key_spddelete2(struct socket *so, struct mbuf *m,
return key_senderror(so, m, EINVAL);
}
- SPTREE_LOCK();
- sp->state = IPSEC_SPSTATE_DEAD;
- SPTREE_UNLOCK();
+ key_unlink(sp);
KEY_FREESP(&sp);
{
@@ -2356,8 +2318,9 @@ key_spdacquire(struct secpolicy *sp)
static int
key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
{
+ TAILQ_HEAD(, secpolicy) drainq;
struct sadb_msg *newmsg;
- struct secpolicy *sp;
+ struct secpolicy *sp, *nextsp;
u_int dir;
IPSEC_ASSERT(so != NULL, ("null socket"));
@@ -2368,11 +2331,17 @@ key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg)))
return key_senderror(so, m, EINVAL);
+ TAILQ_INIT(&drainq);
+ SPTREE_WLOCK();
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
- SPTREE_LOCK();
- LIST_FOREACH(sp, &V_sptree[dir], chain)
- sp->state = IPSEC_SPSTATE_DEAD;
- SPTREE_UNLOCK();
+ TAILQ_CONCAT(&drainq, &V_sptree[dir], chain);
+ }
+ SPTREE_WUNLOCK();
+ sp = TAILQ_FIRST(&drainq);
+ while (sp != NULL) {
+ nextsp = TAILQ_NEXT(sp, chain);
+ KEY_FREESP(&sp);
+ sp = nextsp;
}
if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
@@ -2405,6 +2374,7 @@ key_spdflush(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
static int
key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
{
+ SPTREE_RLOCK_TRACKER;
struct secpolicy *sp;
int cnt;
u_int dir;
@@ -2417,20 +2387,20 @@ key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
/* search SPD entry and get buffer size. */
cnt = 0;
- SPTREE_LOCK();
+ SPTREE_RLOCK();
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
- LIST_FOREACH(sp, &V_sptree[dir], chain) {
+ TAILQ_FOREACH(sp, &V_sptree[dir], chain) {
cnt++;
}
}
if (cnt == 0) {
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
return key_senderror(so, m, ENOENT);
}
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
- LIST_FOREACH(sp, &V_sptree[dir], chain) {
+ TAILQ_FOREACH(sp, &V_sptree[dir], chain) {
--cnt;
n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt,
mhp->msg->sadb_msg_pid);
@@ -2440,7 +2410,7 @@ key_spddump(struct socket *so, struct mbuf *m, const struct sadb_msghdr *mhp)
}
}
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
m_freem(m);
return 0;
}
@@ -2452,6 +2422,8 @@ key_setdumpsp(struct secpolicy *sp, u_int8_t type, u_int32_t seq,
struct mbuf *result = NULL, *m;
struct seclifetime lt;
+ SPTREE_RLOCK_ASSERT();
+
m = key_setsadbmsg(type, 0, SADB_SATYPE_UNSPEC, seq, pid, sp->refcnt);
if (!m)
goto fail;
@@ -4226,47 +4198,29 @@ key_bbcmp(const void *a1, const void *a2, u_int bits)
static void
key_flush_spd(time_t now)
{
- static u_int16_t sptree_scangen = 0;
- u_int16_t gen = sptree_scangen++;
+ SPTREE_RLOCK_TRACKER;
struct secpolicy *sp;
u_int dir;
/* SPD */
for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
restart:
- SPTREE_LOCK();
- LIST_FOREACH(sp, &V_sptree[dir], chain) {
- if (sp->scangen == gen) /* previously handled */
- continue;
- sp->scangen = gen;
- if (sp->state == IPSEC_SPSTATE_DEAD &&
- sp->refcnt == 1) {
- /*
- * Ensure that we only decrease refcnt once,
- * when we're the last consumer.
- * Directly call SP_DELREF/key_delsp instead
- * of KEY_FREESP to avoid unlocking/relocking
- * SPTREE_LOCK before key_delsp: may refcnt
- * be increased again during that time ?
- * NB: also clean entries created by
- * key_spdflush
- */
- SP_DELREF(sp);
- key_delsp(sp);
- SPTREE_UNLOCK();
- goto restart;
- }
+ SPTREE_RLOCK();
+ TAILQ_FOREACH(sp, &V_sptree[dir], chain) {
if (sp->lifetime == 0 && sp->validtime == 0)
continue;
- if ((sp->lifetime && now - sp->created > sp->lifetime)
- || (sp->validtime && now - sp->lastused > sp->validtime)) {
- sp->state = IPSEC_SPSTATE_DEAD;
- SPTREE_UNLOCK();
+ if ((sp->lifetime &&
+ now - sp->created > sp->lifetime) ||
+ (sp->validtime &&
+ now - sp->lastused > sp->validtime)) {
+ SPTREE_RUNLOCK();
+ key_unlink(sp);
key_spdexpire(sp);
+ KEY_FREESP(&sp);
goto restart;
}
}
- SPTREE_UNLOCK();
+ SPTREE_RUNLOCK();
}
}
@@ -7609,7 +7563,7 @@ key_init(void)
int i;
for (i = 0; i < IPSEC_DIR_MAX; i++)
- LIST_INIT(&V_sptree[i]);
+ TAILQ_INIT(&V_sptree[i]);
LIST_INIT(&V_sahtree);
@@ -7619,10 +7573,6 @@ key_init(void)
LIST_INIT(&V_acqtree);
LIST_INIT(&V_spacqtree);
- /* system default */
- V_ip4_def_policy.policy = IPSEC_POLICY_NONE;
- V_ip4_def_policy.refcnt++; /*never reclaim this*/
-
if (!IS_DEFAULT_VNET(curvnet))
return;
@@ -7647,6 +7597,7 @@ key_init(void)
void
key_destroy(void)
{
+ TAILQ_HEAD(, secpolicy) drainq;
struct secpolicy *sp, *nextsp;
struct secacq *acq, *nextacq;
struct secspacq *spacq, *nextspacq;
@@ -7654,18 +7605,18 @@ key_destroy(void)
struct secreg *reg;
int i;
- SPTREE_LOCK();
+ TAILQ_INIT(&drainq);
+ SPTREE_WLOCK();
for (i = 0; i < IPSEC_DIR_MAX; i++) {
- for (sp = LIST_FIRST(&V_sptree[i]);
- sp != NULL; sp = nextsp) {
- nextsp = LIST_NEXT(sp, chain);
- if (__LIST_CHAINED(sp)) {
- LIST_REMOVE(sp, chain);
- free(sp, M_IPSEC_SP);
- }
- }
+ TAILQ_CONCAT(&drainq, &V_sptree[i], chain);
+ }
+ SPTREE_WUNLOCK();
+ sp = TAILQ_FIRST(&drainq);
+ while (sp != NULL) {
+ nextsp = TAILQ_NEXT(sp, chain);
+ KEY_FREESP(&sp);
+ sp = nextsp;
}
- SPTREE_UNLOCK();
SAHTREE_LOCK();
for (sah = LIST_FIRST(&V_sahtree); sah != NULL; sah = nextsah) {
diff --git a/sys/netipsec/key_debug.c b/sys/netipsec/key_debug.c
index 5cbc1db..97ac061 100644
--- a/sys/netipsec/key_debug.c
+++ b/sys/netipsec/key_debug.c
@@ -463,8 +463,8 @@ kdebug_secpolicy(struct secpolicy *sp)
if (sp == NULL)
panic("%s: NULL pointer was passed.\n", __func__);
- printf("secpolicy{ refcnt=%u state=%u policy=%u\n",
- sp->refcnt, sp->state, sp->policy);
+ printf("secpolicy{ refcnt=%u policy=%u\n",
+ sp->refcnt, sp->policy);
kdebug_secpolicyindex(&sp->spidx);
diff --git a/sys/nfs/bootp_subr.c b/sys/nfs/bootp_subr.c
index 5e3145e..c5bd4cb 100644
--- a/sys/nfs/bootp_subr.c
+++ b/sys/nfs/bootp_subr.c
@@ -1735,9 +1735,6 @@ retry:
goto out;
}
rootdevnames[0] = "nfs:";
-#ifdef NFSCLIENT
- rootdevnames[1] = "oldnfs:";
-#endif
nfs_diskless_valid = 3;
}
diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c
deleted file mode 100644
index ad9e7a1..0000000
--- a/sys/nfs/nfs_common.c
+++ /dev/null
@@ -1,407 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * These functions support the macros and help fiddle mbuf chains for
- * the nfs op functions. They do things like create the rpc header and
- * copy data between mbuf chains and uio lists.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/sysent.h>
-#include <sys/syscall.h>
-#include <sys/sysctl.h>
-
-#include <vm/vm.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsserver/nfs.h>
-#include <nfs/xdr_subs.h>
-#include <nfs/nfs_common.h>
-
-#include <netinet/in.h>
-
-enum vtype nv3tov_type[8]= {
- VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO
-};
-nfstype nfsv3_type[9] = {
- NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFSOCK, NFFIFO, NFNON
-};
-
-static void *nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos,
- int how);
-
-SYSCTL_NODE(_vfs, OID_AUTO, nfs_common, CTLFLAG_RD, 0, "NFS common support");
-
-static int nfs_realign_test;
-SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_test, CTLFLAG_RD,
- &nfs_realign_test, 0, "Number of realign tests done");
-
-static int nfs_realign_count;
-SYSCTL_INT(_vfs_nfs_common, OID_AUTO, realign_count, CTLFLAG_RD,
- &nfs_realign_count, 0, "Number of mbuf realignments done");
-
-/*
- * copies mbuf chain to the uio scatter/gather list
- */
-int
-nfsm_mbuftouio(struct mbuf **mrep, struct uio *uiop, int siz, caddr_t *dpos)
-{
- char *mbufcp, *uiocp;
- int xfer, left, len;
- struct mbuf *mp;
- long uiosiz, rem;
- int error = 0;
-
- mp = *mrep;
- mbufcp = *dpos;
- len = mtod(mp, caddr_t)+mp->m_len-mbufcp;
- rem = nfsm_rndup(siz)-siz;
- while (siz > 0) {
- if (uiop->uio_iovcnt <= 0 || uiop->uio_iov == NULL)
- return (EFBIG);
- left = uiop->uio_iov->iov_len;
- uiocp = uiop->uio_iov->iov_base;
- if (left > siz)
- left = siz;
- uiosiz = left;
- while (left > 0) {
- while (len == 0) {
- mp = mp->m_next;
- if (mp == NULL)
- return (EBADRPC);
- mbufcp = mtod(mp, caddr_t);
- len = mp->m_len;
- }
- xfer = (left > len) ? len : left;
-#ifdef notdef
- /* Not Yet.. */
- if (uiop->uio_iov->iov_op != NULL)
- (*(uiop->uio_iov->iov_op))
- (mbufcp, uiocp, xfer);
- else
-#endif
- if (uiop->uio_segflg == UIO_SYSSPACE)
- bcopy(mbufcp, uiocp, xfer);
- else
- copyout(mbufcp, uiocp, xfer);
- left -= xfer;
- len -= xfer;
- mbufcp += xfer;
- uiocp += xfer;
- uiop->uio_offset += xfer;
- uiop->uio_resid -= xfer;
- }
- if (uiop->uio_iov->iov_len <= siz) {
- uiop->uio_iovcnt--;
- uiop->uio_iov++;
- } else {
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- }
- siz -= uiosiz;
- }
- *dpos = mbufcp;
- *mrep = mp;
- if (rem > 0) {
- if (len < rem)
- error = nfs_adv(mrep, dpos, rem, len);
- else
- *dpos += rem;
- }
- return (error);
-}
-
-/*
- * Help break down an mbuf chain by setting the first siz bytes contiguous
- * pointed to by returned val.
- * This is used by the macros nfsm_dissect for tough
- * cases. (The macros use the vars. dpos and dpos2)
- */
-void *
-nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, int how)
-{
- struct mbuf *mp, *mp2;
- int siz2, xfer;
- caddr_t ptr, npos = NULL;
- void *ret;
-
- mp = *mdp;
- while (left == 0) {
- *mdp = mp = mp->m_next;
- if (mp == NULL)
- return (NULL);
- left = mp->m_len;
- *dposp = mtod(mp, caddr_t);
- }
- if (left >= siz) {
- ret = *dposp;
- *dposp += siz;
- } else if (mp->m_next == NULL) {
- return (NULL);
- } else if (siz > MHLEN) {
- panic("nfs S too big");
- } else {
- mp2 = m_get(how, MT_DATA);
- if (mp2 == NULL)
- return (NULL);
- mp2->m_len = siz;
- mp2->m_next = mp->m_next;
- mp->m_next = mp2;
- mp->m_len -= left;
- mp = mp2;
- ptr = mtod(mp, caddr_t);
- ret = ptr;
- bcopy(*dposp, ptr, left); /* Copy what was left */
- siz2 = siz-left;
- ptr += left;
- mp2 = mp->m_next;
- npos = mtod(mp2, caddr_t);
- /* Loop around copying up the siz2 bytes */
- while (siz2 > 0) {
- if (mp2 == NULL)
- return (NULL);
- xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2;
- if (xfer > 0) {
- bcopy(mtod(mp2, caddr_t), ptr, xfer);
- mp2->m_data += xfer;
- mp2->m_len -= xfer;
- ptr += xfer;
- siz2 -= xfer;
- }
- if (siz2 > 0) {
- mp2 = mp2->m_next;
- if (mp2 != NULL)
- npos = mtod(mp2, caddr_t);
- }
- }
- *mdp = mp2;
- *dposp = mtod(mp2, caddr_t);
- if (!nfsm_aligned(*dposp, u_int32_t)) {
- bcopy(*dposp, npos, mp2->m_len);
- mp2->m_data = npos;
- *dposp = npos;
- }
- }
- return (ret);
-}
-
-/*
- * Advance the position in the mbuf chain.
- */
-int
-nfs_adv(struct mbuf **mdp, caddr_t *dposp, int offs, int left)
-{
- struct mbuf *m;
- int s;
-
- m = *mdp;
- s = left;
- while (s < offs) {
- offs -= s;
- m = m->m_next;
- if (m == NULL)
- return (EBADRPC);
- s = m->m_len;
- }
- *mdp = m;
- *dposp = mtod(m, caddr_t)+offs;
- return (0);
-}
-
-void *
-nfsm_build_xx(int s, struct mbuf **mb, caddr_t *bpos)
-{
- struct mbuf *mb2;
- void *ret;
-
- if (s > M_TRAILINGSPACE(*mb)) {
- mb2 = m_get(M_WAITOK, MT_DATA);
- if (s > MLEN)
- panic("build > MLEN");
- (*mb)->m_next = mb2;
- *mb = mb2;
- (*mb)->m_len = 0;
- *bpos = mtod(*mb, caddr_t);
- }
- ret = *bpos;
- (*mb)->m_len += s;
- *bpos += s;
- return (ret);
-}
-
-void *
-nfsm_dissect_xx(int s, struct mbuf **md, caddr_t *dpos)
-{
-
- return (nfsm_dissect_xx_sub(s, md, dpos, M_WAITOK));
-}
-
-void *
-nfsm_dissect_xx_nonblock(int s, struct mbuf **md, caddr_t *dpos)
-{
-
- return (nfsm_dissect_xx_sub(s, md, dpos, M_NOWAIT));
-}
-
-static void *
-nfsm_dissect_xx_sub(int s, struct mbuf **md, caddr_t *dpos, int how)
-{
- int t1;
- char *cp2;
- void *ret;
-
- t1 = mtod(*md, caddr_t) + (*md)->m_len - *dpos;
- if (t1 >= s) {
- ret = *dpos;
- *dpos += s;
- return (ret);
- }
- cp2 = nfsm_disct(md, dpos, s, t1, how);
- return (cp2);
-}
-
-int
-nfsm_strsiz_xx(int *s, int m, struct mbuf **mb, caddr_t *bpos)
-{
- u_int32_t *tl;
-
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, mb, bpos);
- if (tl == NULL)
- return (EBADRPC);
- *s = fxdr_unsigned(int32_t, *tl);
- if (*s > m)
- return (EBADRPC);
- return (0);
-}
-
-int
-nfsm_adv_xx(int s, struct mbuf **md, caddr_t *dpos)
-{
- int t1;
-
- t1 = mtod(*md, caddr_t) + (*md)->m_len - *dpos;
- if (t1 >= s) {
- *dpos += s;
- return (0);
- }
- t1 = nfs_adv(md, dpos, s, t1);
- if (t1)
- return (t1);
- return (0);
-}
-
-/*
- * Check for badly aligned mbuf data and realign by copying the unaligned
- * portion of the data into a new mbuf chain and freeing the portions of the
- * old chain that were replaced.
- *
- * We cannot simply realign the data within the existing mbuf chain because
- * the underlying buffers may contain other rpc commands and we cannot afford
- * to overwrite them.
- *
- * We would prefer to avoid this situation entirely. The situation does not
- * occur with NFS/UDP and is supposed to only occassionally occur with TCP.
- * Use vfs.nfs_common.realign_count and realign_test to check this.
- */
-int
-nfs_realign(struct mbuf **pm, int how)
-{
- struct mbuf *m, *n;
- int off;
-
- ++nfs_realign_test;
- while ((m = *pm) != NULL) {
- if (!nfsm_aligned(m->m_len, u_int32_t) ||
- !nfsm_aligned(mtod(m, intptr_t), u_int32_t)) {
- /*
- * NB: we can't depend on m_pkthdr.len to help us
- * decide what to do here. May not be worth doing
- * the m_length calculation as m_copyback will
- * expand the mbuf chain below as needed.
- */
- if (m_length(m, NULL) >= MINCLSIZE) {
- /* NB: m_copyback handles space > MCLBYTES */
- n = m_getcl(how, MT_DATA, 0);
- } else
- n = m_get(how, MT_DATA);
- if (n == NULL)
- return (ENOMEM);
- /*
- * Align the remainder of the mbuf chain.
- */
- n->m_len = 0;
- off = 0;
- while (m != NULL) {
- m_copyback(n, off, m->m_len, mtod(m, caddr_t));
- off += m->m_len;
- m = m->m_next;
- }
- m_freem(*pm);
- *pm = n;
- ++nfs_realign_count;
- break;
- }
- pm = &m->m_next;
- }
- return (0);
-}
-
-static moduledata_t nfs_common_mod = {
- "nfs_common",
- NULL,
- NULL
-};
-
-DECLARE_MODULE(nfs_common, nfs_common_mod, SI_SUB_VFS, SI_ORDER_ANY);
-MODULE_VERSION(nfs_common, 1);
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
deleted file mode 100644
index 1a5b156..0000000
--- a/sys/nfsclient/nfs_bio.c
+++ /dev/null
@@ -1,1794 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/mount.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/vmmeter.h>
-#include <sys/vnode.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_page.h>
-#include <vm/vm_object.h>
-#include <vm/vm_pager.h>
-#include <vm/vnode_pager.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsmount.h>
-#include <nfsclient/nfsnode.h>
-#include <nfs/nfs_kdtrace.h>
-
-static struct buf *nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size,
- struct thread *td);
-static int nfs_directio_write(struct vnode *vp, struct uio *uiop,
- struct ucred *cred, int ioflag);
-
-extern int nfs_directio_enable;
-extern int nfs_directio_allow_mmap;
-
-/*
- * Vnode op for VM getpages.
- */
-int
-nfs_getpages(struct vop_getpages_args *ap)
-{
- int i, error, nextoff, size, toff, count, npages;
- struct uio uio;
- struct iovec iov;
- vm_offset_t kva;
- struct buf *bp;
- struct vnode *vp;
- struct thread *td;
- struct ucred *cred;
- struct nfsmount *nmp;
- vm_object_t object;
- vm_page_t *pages;
- struct nfsnode *np;
-
- vp = ap->a_vp;
- np = VTONFS(vp);
- td = curthread; /* XXX */
- cred = curthread->td_ucred; /* XXX */
- nmp = VFSTONFS(vp->v_mount);
- pages = ap->a_m;
- count = ap->a_count;
-
- if ((object = vp->v_object) == NULL) {
- nfs_printf("nfs_getpages: called with non-merged cache vnode??\n");
- return (VM_PAGER_ERROR);
- }
-
- if (nfs_directio_enable && !nfs_directio_allow_mmap) {
- mtx_lock(&np->n_mtx);
- if ((np->n_flag & NNONCACHE) && (vp->v_type == VREG)) {
- mtx_unlock(&np->n_mtx);
- nfs_printf("nfs_getpages: called on non-cacheable vnode??\n");
- return (VM_PAGER_ERROR);
- } else
- mtx_unlock(&np->n_mtx);
- }
-
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 &&
- (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
- mtx_unlock(&nmp->nm_mtx);
- /* We'll never get here for v4, because we always have fsinfo */
- (void)nfs_fsinfo(nmp, vp, cred, td);
- } else
- mtx_unlock(&nmp->nm_mtx);
-
- npages = btoc(count);
-
- /*
- * Since the caller has busied the requested page, that page's valid
- * field will not be changed by other threads.
- */
- vm_page_assert_xbusied(pages[ap->a_reqpage]);
-
- /*
- * If the requested page is partially valid, just return it and
- * allow the pager to zero-out the blanks. Partially valid pages
- * can only occur at the file EOF.
- */
- if (pages[ap->a_reqpage]->valid != 0) {
- vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages);
- return (VM_PAGER_OK);
- }
-
- /*
- * We use only the kva address for the buffer, but this is extremely
- * convienient and fast.
- */
- bp = getpbuf(&nfs_pbuf_freecnt);
-
- kva = (vm_offset_t) bp->b_data;
- pmap_qenter(kva, pages, npages);
- PCPU_INC(cnt.v_vnodein);
- PCPU_ADD(cnt.v_vnodepgsin, npages);
-
- iov.iov_base = (caddr_t) kva;
- iov.iov_len = count;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = IDX_TO_OFF(pages[0]->pindex);
- uio.uio_resid = count;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_READ;
- uio.uio_td = td;
-
- error = (nmp->nm_rpcops->nr_readrpc)(vp, &uio, cred);
- pmap_qremove(kva, npages);
-
- relpbuf(bp, &nfs_pbuf_freecnt);
-
- if (error && (uio.uio_resid == count)) {
- nfs_printf("nfs_getpages: error %d\n", error);
- vm_pager_free_nonreq(object, pages, ap->a_reqpage, npages);
- return (VM_PAGER_ERROR);
- }
-
- /*
- * Calculate the number of bytes read and validate only that number
- * of bytes. Note that due to pending writes, size may be 0. This
- * does not mean that the remaining data is invalid!
- */
-
- size = count - uio.uio_resid;
- VM_OBJECT_WLOCK(object);
- for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
- vm_page_t m;
- nextoff = toff + PAGE_SIZE;
- m = pages[i];
-
- if (nextoff <= size) {
- /*
- * Read operation filled an entire page
- */
- m->valid = VM_PAGE_BITS_ALL;
- KASSERT(m->dirty == 0,
- ("nfs_getpages: page %p is dirty", m));
- } else if (size > toff) {
- /*
- * Read operation filled a partial page.
- */
- m->valid = 0;
- vm_page_set_valid_range(m, 0, size - toff);
- KASSERT(m->dirty == 0,
- ("nfs_getpages: page %p is dirty", m));
- } else {
- /*
- * Read operation was short. If no error
- * occured we may have hit a zero-fill
- * section. We leave valid set to 0, and page
- * is freed by vm_page_readahead_finish() if
- * its index is not equal to requested, or
- * page is zeroed and set valid by
- * vm_pager_get_pages() for requested page.
- */
- ;
- }
- if (i != ap->a_reqpage)
- vm_page_readahead_finish(m);
- }
- VM_OBJECT_WUNLOCK(object);
- return (0);
-}
-
-/*
- * Vnode op for VM putpages.
- */
-int
-nfs_putpages(struct vop_putpages_args *ap)
-{
- struct uio uio;
- struct iovec iov;
- vm_offset_t kva;
- struct buf *bp;
- int iomode, must_commit, i, error, npages, count;
- off_t offset;
- int *rtvals;
- struct vnode *vp;
- struct thread *td;
- struct ucred *cred;
- struct nfsmount *nmp;
- struct nfsnode *np;
- vm_page_t *pages;
-
- vp = ap->a_vp;
- np = VTONFS(vp);
- td = curthread; /* XXX */
- /* Set the cred to n_writecred for the write rpcs. */
- if (np->n_writecred != NULL)
- cred = crhold(np->n_writecred);
- else
- cred = crhold(curthread->td_ucred); /* XXX */
- nmp = VFSTONFS(vp->v_mount);
- pages = ap->a_m;
- count = ap->a_count;
- rtvals = ap->a_rtvals;
- npages = btoc(count);
- offset = IDX_TO_OFF(pages[0]->pindex);
-
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 &&
- (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
- mtx_unlock(&nmp->nm_mtx);
- (void)nfs_fsinfo(nmp, vp, cred, td);
- } else
- mtx_unlock(&nmp->nm_mtx);
-
- mtx_lock(&np->n_mtx);
- if (nfs_directio_enable && !nfs_directio_allow_mmap &&
- (np->n_flag & NNONCACHE) && (vp->v_type == VREG)) {
- mtx_unlock(&np->n_mtx);
- nfs_printf("nfs_putpages: called on noncache-able vnode??\n");
- mtx_lock(&np->n_mtx);
- }
-
- for (i = 0; i < npages; i++)
- rtvals[i] = VM_PAGER_ERROR;
-
- /*
- * When putting pages, do not extend file past EOF.
- */
- if (offset + count > np->n_size) {
- count = np->n_size - offset;
- if (count < 0)
- count = 0;
- }
- mtx_unlock(&np->n_mtx);
-
- /*
- * We use only the kva address for the buffer, but this is extremely
- * convienient and fast.
- */
- bp = getpbuf(&nfs_pbuf_freecnt);
-
- kva = (vm_offset_t) bp->b_data;
- pmap_qenter(kva, pages, npages);
- PCPU_INC(cnt.v_vnodeout);
- PCPU_ADD(cnt.v_vnodepgsout, count);
-
- iov.iov_base = (caddr_t) kva;
- iov.iov_len = count;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = offset;
- uio.uio_resid = count;
- uio.uio_segflg = UIO_SYSSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_td = td;
-
- if ((ap->a_sync & VM_PAGER_PUT_SYNC) == 0)
- iomode = NFSV3WRITE_UNSTABLE;
- else
- iomode = NFSV3WRITE_FILESYNC;
-
- error = (nmp->nm_rpcops->nr_writerpc)(vp, &uio, cred, &iomode, &must_commit);
- crfree(cred);
-
- pmap_qremove(kva, npages);
- relpbuf(bp, &nfs_pbuf_freecnt);
-
- if (!error) {
- vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid);
- if (must_commit) {
- nfs_clearcommit(vp->v_mount);
- }
- }
- return rtvals[0];
-}
-
-/*
- * For nfs, cache consistency can only be maintained approximately.
- * Although RFC1094 does not specify the criteria, the following is
- * believed to be compatible with the reference port.
- * For nfs:
- * If the file's modify time on the server has changed since the
- * last read rpc or you have written to the file,
- * you may have lost data cache consistency with the
- * server, so flush all of the file's data out of the cache.
- * Then force a getattr rpc to ensure that you have up to date
- * attributes.
- * NB: This implies that cache data can be read when up to
- * NFS_ATTRTIMEO seconds out of date. If you find that you need current
- * attributes this could be forced by setting n_attrstamp to 0 before
- * the VOP_GETATTR() call.
- */
-static inline int
-nfs_bioread_check_cons(struct vnode *vp, struct thread *td, struct ucred *cred)
-{
- int error = 0;
- struct vattr vattr;
- struct nfsnode *np = VTONFS(vp);
- int old_lock;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
-
- /*
- * Grab the exclusive lock before checking whether the cache is
- * consistent.
- * XXX - We can make this cheaper later (by acquiring cheaper locks).
- * But for now, this suffices.
- */
- old_lock = nfs_upgrade_vnlock(vp);
- if (vp->v_iflag & VI_DOOMED) {
- nfs_downgrade_vnlock(vp, old_lock);
- return (EBADF);
- }
-
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NMODIFIED) {
- mtx_unlock(&np->n_mtx);
- if (vp->v_type != VREG) {
- if (vp->v_type != VDIR)
- panic("nfs: bioread, not dir");
- (nmp->nm_rpcops->nr_invaldir)(vp);
- error = nfs_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
- goto out;
- }
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- error = VOP_GETATTR(vp, &vattr, cred);
- if (error)
- goto out;
- mtx_lock(&np->n_mtx);
- np->n_mtime = vattr.va_mtime;
- mtx_unlock(&np->n_mtx);
- } else {
- mtx_unlock(&np->n_mtx);
- error = VOP_GETATTR(vp, &vattr, cred);
- if (error)
- return (error);
- mtx_lock(&np->n_mtx);
- if ((np->n_flag & NSIZECHANGED)
- || (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime))) {
- mtx_unlock(&np->n_mtx);
- if (vp->v_type == VDIR)
- (nmp->nm_rpcops->nr_invaldir)(vp);
- error = nfs_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
- goto out;
- mtx_lock(&np->n_mtx);
- np->n_mtime = vattr.va_mtime;
- np->n_flag &= ~NSIZECHANGED;
- }
- mtx_unlock(&np->n_mtx);
- }
-out:
- nfs_downgrade_vnlock(vp, old_lock);
- return error;
-}
-
-/*
- * Vnode op for read using bio
- */
-int
-nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
-{
- struct nfsnode *np = VTONFS(vp);
- int biosize, i;
- struct buf *bp, *rabp;
- struct thread *td;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- daddr_t lbn, rabn;
- off_t end;
- int bcount;
- int seqcount;
- int nra, error = 0, n = 0, on = 0;
-
- KASSERT(uio->uio_rw == UIO_READ, ("nfs_read mode"));
- if (uio->uio_resid == 0)
- return (0);
- if (uio->uio_offset < 0) /* XXX VDIR cookies can be negative */
- return (EINVAL);
- td = uio->uio_td;
-
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 &&
- (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
- mtx_unlock(&nmp->nm_mtx);
- (void)nfs_fsinfo(nmp, vp, cred, td);
- } else
- mtx_unlock(&nmp->nm_mtx);
-
- end = uio->uio_offset + uio->uio_resid;
- if (vp->v_type != VDIR &&
- (end > nmp->nm_maxfilesize || end < uio->uio_offset))
- return (EFBIG);
-
- if (nfs_directio_enable && (ioflag & IO_DIRECT) && (vp->v_type == VREG))
- /* No caching/ no readaheads. Just read data into the user buffer */
- return nfs_readrpc(vp, uio, cred);
-
- biosize = vp->v_bufobj.bo_bsize;
- seqcount = (int)((off_t)(ioflag >> IO_SEQSHIFT) * biosize / BKVASIZE);
-
- error = nfs_bioread_check_cons(vp, td, cred);
- if (error)
- return error;
-
- do {
- u_quad_t nsize;
-
- mtx_lock(&np->n_mtx);
- nsize = np->n_size;
- mtx_unlock(&np->n_mtx);
-
- switch (vp->v_type) {
- case VREG:
- nfsstats.biocache_reads++;
- lbn = uio->uio_offset / biosize;
- on = uio->uio_offset - (lbn * biosize);
-
- /*
- * Start the read ahead(s), as required.
- */
- if (nmp->nm_readahead > 0) {
- for (nra = 0; nra < nmp->nm_readahead && nra < seqcount &&
- (off_t)(lbn + 1 + nra) * biosize < nsize; nra++) {
- rabn = lbn + 1 + nra;
- if (incore(&vp->v_bufobj, rabn) == NULL) {
- rabp = nfs_getcacheblk(vp, rabn, biosize, td);
- if (!rabp) {
- error = nfs_sigintr(nmp, td);
- return (error ? error : EINTR);
- }
- if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
- rabp->b_flags |= B_ASYNC;
- rabp->b_iocmd = BIO_READ;
- vfs_busy_pages(rabp, 0);
- if (nfs_asyncio(nmp, rabp, cred, td)) {
- rabp->b_flags |= B_INVAL;
- rabp->b_ioflags |= BIO_ERROR;
- vfs_unbusy_pages(rabp);
- brelse(rabp);
- break;
- }
- } else {
- brelse(rabp);
- }
- }
- }
- }
-
- /* Note that bcount is *not* DEV_BSIZE aligned. */
- bcount = biosize;
- if ((off_t)lbn * biosize >= nsize) {
- bcount = 0;
- } else if ((off_t)(lbn + 1) * biosize > nsize) {
- bcount = nsize - (off_t)lbn * biosize;
- }
- bp = nfs_getcacheblk(vp, lbn, bcount, td);
-
- if (!bp) {
- error = nfs_sigintr(nmp, td);
- return (error ? error : EINTR);
- }
-
- /*
- * If B_CACHE is not set, we must issue the read. If this
- * fails, we return an error.
- */
-
- if ((bp->b_flags & B_CACHE) == 0) {
- bp->b_iocmd = BIO_READ;
- vfs_busy_pages(bp, 0);
- error = nfs_doio(vp, bp, cred, td);
- if (error) {
- brelse(bp);
- return (error);
- }
- }
-
- /*
- * on is the offset into the current bp. Figure out how many
- * bytes we can copy out of the bp. Note that bcount is
- * NOT DEV_BSIZE aligned.
- *
- * Then figure out how many bytes we can copy into the uio.
- */
-
- n = 0;
- if (on < bcount)
- n = MIN((unsigned)(bcount - on), uio->uio_resid);
- break;
- case VLNK:
- nfsstats.biocache_readlinks++;
- bp = nfs_getcacheblk(vp, (daddr_t)0, NFS_MAXPATHLEN, td);
- if (!bp) {
- error = nfs_sigintr(nmp, td);
- return (error ? error : EINTR);
- }
- if ((bp->b_flags & B_CACHE) == 0) {
- bp->b_iocmd = BIO_READ;
- vfs_busy_pages(bp, 0);
- error = nfs_doio(vp, bp, cred, td);
- if (error) {
- bp->b_ioflags |= BIO_ERROR;
- brelse(bp);
- return (error);
- }
- }
- n = MIN(uio->uio_resid, NFS_MAXPATHLEN - bp->b_resid);
- on = 0;
- break;
- case VDIR:
- nfsstats.biocache_readdirs++;
- if (np->n_direofoffset
- && uio->uio_offset >= np->n_direofoffset) {
- return (0);
- }
- lbn = (uoff_t)uio->uio_offset / NFS_DIRBLKSIZ;
- on = uio->uio_offset & (NFS_DIRBLKSIZ - 1);
- bp = nfs_getcacheblk(vp, lbn, NFS_DIRBLKSIZ, td);
- if (!bp) {
- error = nfs_sigintr(nmp, td);
- return (error ? error : EINTR);
- }
- if ((bp->b_flags & B_CACHE) == 0) {
- bp->b_iocmd = BIO_READ;
- vfs_busy_pages(bp, 0);
- error = nfs_doio(vp, bp, cred, td);
- if (error) {
- brelse(bp);
- }
- while (error == NFSERR_BAD_COOKIE) {
- (nmp->nm_rpcops->nr_invaldir)(vp);
- error = nfs_vinvalbuf(vp, 0, td, 1);
- /*
- * Yuck! The directory has been modified on the
- * server. The only way to get the block is by
- * reading from the beginning to get all the
- * offset cookies.
- *
- * Leave the last bp intact unless there is an error.
- * Loop back up to the while if the error is another
- * NFSERR_BAD_COOKIE (double yuch!).
- */
- for (i = 0; i <= lbn && !error; i++) {
- if (np->n_direofoffset
- && (i * NFS_DIRBLKSIZ) >= np->n_direofoffset)
- return (0);
- bp = nfs_getcacheblk(vp, i, NFS_DIRBLKSIZ, td);
- if (!bp) {
- error = nfs_sigintr(nmp, td);
- return (error ? error : EINTR);
- }
- if ((bp->b_flags & B_CACHE) == 0) {
- bp->b_iocmd = BIO_READ;
- vfs_busy_pages(bp, 0);
- error = nfs_doio(vp, bp, cred, td);
- /*
- * no error + B_INVAL == directory EOF,
- * use the block.
- */
- if (error == 0 && (bp->b_flags & B_INVAL))
- break;
- }
- /*
- * An error will throw away the block and the
- * for loop will break out. If no error and this
- * is not the block we want, we throw away the
- * block and go for the next one via the for loop.
- */
- if (error || i < lbn)
- brelse(bp);
- }
- }
- /*
- * The above while is repeated if we hit another cookie
- * error. If we hit an error and it wasn't a cookie error,
- * we give up.
- */
- if (error)
- return (error);
- }
-
- /*
- * If not eof and read aheads are enabled, start one.
- * (You need the current block first, so that you have the
- * directory offset cookie of the next block.)
- */
- if (nmp->nm_readahead > 0 &&
- (bp->b_flags & B_INVAL) == 0 &&
- (np->n_direofoffset == 0 ||
- (lbn + 1) * NFS_DIRBLKSIZ < np->n_direofoffset) &&
- incore(&vp->v_bufobj, lbn + 1) == NULL) {
- rabp = nfs_getcacheblk(vp, lbn + 1, NFS_DIRBLKSIZ, td);
- if (rabp) {
- if ((rabp->b_flags & (B_CACHE|B_DELWRI)) == 0) {
- rabp->b_flags |= B_ASYNC;
- rabp->b_iocmd = BIO_READ;
- vfs_busy_pages(rabp, 0);
- if (nfs_asyncio(nmp, rabp, cred, td)) {
- rabp->b_flags |= B_INVAL;
- rabp->b_ioflags |= BIO_ERROR;
- vfs_unbusy_pages(rabp);
- brelse(rabp);
- }
- } else {
- brelse(rabp);
- }
- }
- }
- /*
- * Unlike VREG files, whos buffer size ( bp->b_bcount ) is
- * chopped for the EOF condition, we cannot tell how large
- * NFS directories are going to be until we hit EOF. So
- * an NFS directory buffer is *not* chopped to its EOF. Now,
- * it just so happens that b_resid will effectively chop it
- * to EOF. *BUT* this information is lost if the buffer goes
- * away and is reconstituted into a B_CACHE state ( due to
- * being VMIO ) later. So we keep track of the directory eof
- * in np->n_direofoffset and chop it off as an extra step
- * right here.
- */
- n = lmin(uio->uio_resid, NFS_DIRBLKSIZ - bp->b_resid - on);
- if (np->n_direofoffset && n > np->n_direofoffset - uio->uio_offset)
- n = np->n_direofoffset - uio->uio_offset;
- break;
- default:
- nfs_printf(" nfs_bioread: type %x unexpected\n", vp->v_type);
- bp = NULL;
- break;
- };
-
- if (n > 0) {
- error = uiomove(bp->b_data + on, (int)n, uio);
- }
- if (vp->v_type == VLNK)
- n = 0;
- if (bp != NULL)
- brelse(bp);
- } while (error == 0 && uio->uio_resid > 0 && n > 0);
- return (error);
-}
-
-/*
- * The NFS write path cannot handle iovecs with len > 1. So we need to
- * break up iovecs accordingly (restricting them to wsize).
- * For the SYNC case, we can do this with 1 copy (user buffer -> mbuf).
- * For the ASYNC case, 2 copies are needed. The first a copy from the
- * user buffer to a staging buffer and then a second copy from the staging
- * buffer to mbufs. This can be optimized by copying from the user buffer
- * directly into mbufs and passing the chain down, but that requires a
- * fair amount of re-working of the relevant codepaths (and can be done
- * later).
- */
-static int
-nfs_directio_write(vp, uiop, cred, ioflag)
- struct vnode *vp;
- struct uio *uiop;
- struct ucred *cred;
- int ioflag;
-{
- int error;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- struct thread *td = uiop->uio_td;
- int size;
- int wsize;
-
- mtx_lock(&nmp->nm_mtx);
- wsize = nmp->nm_wsize;
- mtx_unlock(&nmp->nm_mtx);
- if (ioflag & IO_SYNC) {
- int iomode, must_commit;
- struct uio uio;
- struct iovec iov;
-do_sync:
- while (uiop->uio_resid > 0) {
- size = MIN(uiop->uio_resid, wsize);
- size = MIN(uiop->uio_iov->iov_len, size);
- iov.iov_base = uiop->uio_iov->iov_base;
- iov.iov_len = size;
- uio.uio_iov = &iov;
- uio.uio_iovcnt = 1;
- uio.uio_offset = uiop->uio_offset;
- uio.uio_resid = size;
- uio.uio_segflg = UIO_USERSPACE;
- uio.uio_rw = UIO_WRITE;
- uio.uio_td = td;
- iomode = NFSV3WRITE_FILESYNC;
- error = (nmp->nm_rpcops->nr_writerpc)(vp, &uio, cred,
- &iomode, &must_commit);
- KASSERT((must_commit == 0),
- ("nfs_directio_write: Did not commit write"));
- if (error)
- return (error);
- uiop->uio_offset += size;
- uiop->uio_resid -= size;
- if (uiop->uio_iov->iov_len <= size) {
- uiop->uio_iovcnt--;
- uiop->uio_iov++;
- } else {
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + size;
- uiop->uio_iov->iov_len -= size;
- }
- }
- } else {
- struct uio *t_uio;
- struct iovec *t_iov;
- struct buf *bp;
-
- /*
- * Break up the write into blocksize chunks and hand these
- * over to nfsiod's for write back.
- * Unfortunately, this incurs a copy of the data. Since
- * the user could modify the buffer before the write is
- * initiated.
- *
- * The obvious optimization here is that one of the 2 copies
- * in the async write path can be eliminated by copying the
- * data here directly into mbufs and passing the mbuf chain
- * down. But that will require a fair amount of re-working
- * of the code and can be done if there's enough interest
- * in NFS directio access.
- */
- while (uiop->uio_resid > 0) {
- size = MIN(uiop->uio_resid, wsize);
- size = MIN(uiop->uio_iov->iov_len, size);
- bp = getpbuf(&nfs_pbuf_freecnt);
- t_uio = malloc(sizeof(struct uio), M_NFSDIRECTIO, M_WAITOK);
- t_iov = malloc(sizeof(struct iovec), M_NFSDIRECTIO, M_WAITOK);
- t_iov->iov_base = malloc(size, M_NFSDIRECTIO, M_WAITOK);
- t_iov->iov_len = size;
- t_uio->uio_iov = t_iov;
- t_uio->uio_iovcnt = 1;
- t_uio->uio_offset = uiop->uio_offset;
- t_uio->uio_resid = size;
- t_uio->uio_segflg = UIO_SYSSPACE;
- t_uio->uio_rw = UIO_WRITE;
- t_uio->uio_td = td;
- KASSERT(uiop->uio_segflg == UIO_USERSPACE ||
- uiop->uio_segflg == UIO_SYSSPACE,
- ("nfs_directio_write: Bad uio_segflg"));
- if (uiop->uio_segflg == UIO_USERSPACE) {
- error = copyin(uiop->uio_iov->iov_base,
- t_iov->iov_base, size);
- if (error != 0)
- goto err_free;
- } else
- /*
- * UIO_SYSSPACE may never happen, but handle
- * it just in case it does.
- */
- bcopy(uiop->uio_iov->iov_base, t_iov->iov_base,
- size);
- bp->b_flags |= B_DIRECT;
- bp->b_iocmd = BIO_WRITE;
- if (cred != NOCRED) {
- crhold(cred);
- bp->b_wcred = cred;
- } else
- bp->b_wcred = NOCRED;
- bp->b_caller1 = (void *)t_uio;
- bp->b_vp = vp;
- error = nfs_asyncio(nmp, bp, NOCRED, td);
-err_free:
- if (error) {
- free(t_iov->iov_base, M_NFSDIRECTIO);
- free(t_iov, M_NFSDIRECTIO);
- free(t_uio, M_NFSDIRECTIO);
- bp->b_vp = NULL;
- relpbuf(bp, &nfs_pbuf_freecnt);
- if (error == EINTR)
- return (error);
- goto do_sync;
- }
- uiop->uio_offset += size;
- uiop->uio_resid -= size;
- if (uiop->uio_iov->iov_len <= size) {
- uiop->uio_iovcnt--;
- uiop->uio_iov++;
- } else {
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + size;
- uiop->uio_iov->iov_len -= size;
- }
- }
- }
- return (0);
-}
-
-/*
- * Vnode op for write using bio
- */
-int
-nfs_write(struct vop_write_args *ap)
-{
- int biosize;
- struct uio *uio = ap->a_uio;
- struct thread *td = uio->uio_td;
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct ucred *cred = ap->a_cred;
- int ioflag = ap->a_ioflag;
- struct buf *bp;
- struct vattr vattr;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- daddr_t lbn;
- off_t end;
- int bcount;
- int n, on, error = 0;
-
- KASSERT(uio->uio_rw == UIO_WRITE, ("nfs_write mode"));
- KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
- ("nfs_write proc"));
- if (vp->v_type != VREG)
- return (EIO);
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NWRITEERR) {
- np->n_flag &= ~NWRITEERR;
- mtx_unlock(&np->n_mtx);
- return (np->n_error);
- } else
- mtx_unlock(&np->n_mtx);
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_flag & NFSMNT_NFSV3) != 0 &&
- (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
- mtx_unlock(&nmp->nm_mtx);
- (void)nfs_fsinfo(nmp, vp, cred, td);
- } else
- mtx_unlock(&nmp->nm_mtx);
-
- /*
- * Synchronously flush pending buffers if we are in synchronous
- * mode or if we are appending.
- */
- if (ioflag & (IO_APPEND | IO_SYNC)) {
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NMODIFIED) {
- mtx_unlock(&np->n_mtx);
-#ifdef notyet /* Needs matching nonblock semantics elsewhere, too. */
- /*
- * Require non-blocking, synchronous writes to
- * dirty files to inform the program it needs
- * to fsync(2) explicitly.
- */
- if (ioflag & IO_NDELAY)
- return (EAGAIN);
-#endif
-flush_and_restart:
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- error = nfs_vinvalbuf(vp, V_SAVE, td, 1);
- if (error)
- return (error);
- } else
- mtx_unlock(&np->n_mtx);
- }
-
- /*
- * If IO_APPEND then load uio_offset. We restart here if we cannot
- * get the append lock.
- */
- if (ioflag & IO_APPEND) {
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- error = VOP_GETATTR(vp, &vattr, cred);
- if (error)
- return (error);
- mtx_lock(&np->n_mtx);
- uio->uio_offset = np->n_size;
- mtx_unlock(&np->n_mtx);
- }
-
- if (uio->uio_offset < 0)
- return (EINVAL);
- end = uio->uio_offset + uio->uio_resid;
- if (end > nmp->nm_maxfilesize || end < uio->uio_offset)
- return (EFBIG);
- if (uio->uio_resid == 0)
- return (0);
-
- if (nfs_directio_enable && (ioflag & IO_DIRECT) && vp->v_type == VREG)
- return nfs_directio_write(vp, uio, cred, ioflag);
-
- /*
- * Maybe this should be above the vnode op call, but so long as
- * file servers have no limits, i don't think it matters
- */
- if (vn_rlimit_fsize(vp, uio, td))
- return (EFBIG);
-
- biosize = vp->v_bufobj.bo_bsize;
- /*
- * Find all of this file's B_NEEDCOMMIT buffers. If our writes
- * would exceed the local maximum per-file write commit size when
- * combined with those, we must decide whether to flush,
- * go synchronous, or return error. We don't bother checking
- * IO_UNIT -- we just make all writes atomic anyway, as there's
- * no point optimizing for something that really won't ever happen.
- */
- if (!(ioflag & IO_SYNC)) {
- int nflag;
-
- mtx_lock(&np->n_mtx);
- nflag = np->n_flag;
- mtx_unlock(&np->n_mtx);
- int needrestart = 0;
- if (nmp->nm_wcommitsize < uio->uio_resid) {
- /*
- * If this request could not possibly be completed
- * without exceeding the maximum outstanding write
- * commit size, see if we can convert it into a
- * synchronous write operation.
- */
- if (ioflag & IO_NDELAY)
- return (EAGAIN);
- ioflag |= IO_SYNC;
- if (nflag & NMODIFIED)
- needrestart = 1;
- } else if (nflag & NMODIFIED) {
- int wouldcommit = 0;
- BO_LOCK(&vp->v_bufobj);
- if (vp->v_bufobj.bo_dirty.bv_cnt != 0) {
- TAILQ_FOREACH(bp, &vp->v_bufobj.bo_dirty.bv_hd,
- b_bobufs) {
- if (bp->b_flags & B_NEEDCOMMIT)
- wouldcommit += bp->b_bcount;
- }
- }
- BO_UNLOCK(&vp->v_bufobj);
- /*
- * Since we're not operating synchronously and
- * bypassing the buffer cache, we are in a commit
- * and holding all of these buffers whether
- * transmitted or not. If not limited, this
- * will lead to the buffer cache deadlocking,
- * as no one else can flush our uncommitted buffers.
- */
- wouldcommit += uio->uio_resid;
- /*
- * If we would initially exceed the maximum
- * outstanding write commit size, flush and restart.
- */
- if (wouldcommit > nmp->nm_wcommitsize)
- needrestart = 1;
- }
- if (needrestart)
- goto flush_and_restart;
- }
-
- do {
- nfsstats.biocache_writes++;
- lbn = uio->uio_offset / biosize;
- on = uio->uio_offset - (lbn * biosize);
- n = MIN((unsigned)(biosize - on), uio->uio_resid);
-again:
- /*
- * Handle direct append and file extension cases, calculate
- * unaligned buffer size.
- */
- mtx_lock(&np->n_mtx);
- if (uio->uio_offset == np->n_size && n) {
- mtx_unlock(&np->n_mtx);
- /*
- * Get the buffer (in its pre-append state to maintain
- * B_CACHE if it was previously set). Resize the
- * nfsnode after we have locked the buffer to prevent
- * readers from reading garbage.
- */
- bcount = on;
- bp = nfs_getcacheblk(vp, lbn, bcount, td);
-
- if (bp != NULL) {
- long save;
-
- mtx_lock(&np->n_mtx);
- np->n_size = uio->uio_offset + n;
- np->n_flag |= NMODIFIED;
- vnode_pager_setsize(vp, np->n_size);
- mtx_unlock(&np->n_mtx);
-
- save = bp->b_flags & B_CACHE;
- bcount += n;
- allocbuf(bp, bcount);
- bp->b_flags |= save;
- }
- } else {
- /*
- * Obtain the locked cache block first, and then
- * adjust the file's size as appropriate.
- */
- bcount = on + n;
- if ((off_t)lbn * biosize + bcount < np->n_size) {
- if ((off_t)(lbn + 1) * biosize < np->n_size)
- bcount = biosize;
- else
- bcount = np->n_size - (off_t)lbn * biosize;
- }
- mtx_unlock(&np->n_mtx);
- bp = nfs_getcacheblk(vp, lbn, bcount, td);
- mtx_lock(&np->n_mtx);
- if (uio->uio_offset + n > np->n_size) {
- np->n_size = uio->uio_offset + n;
- np->n_flag |= NMODIFIED;
- vnode_pager_setsize(vp, np->n_size);
- }
- mtx_unlock(&np->n_mtx);
- }
-
- if (!bp) {
- error = nfs_sigintr(nmp, td);
- if (!error)
- error = EINTR;
- break;
- }
-
- /*
- * Issue a READ if B_CACHE is not set. In special-append
- * mode, B_CACHE is based on the buffer prior to the write
- * op and is typically set, avoiding the read. If a read
- * is required in special append mode, the server will
- * probably send us a short-read since we extended the file
- * on our end, resulting in b_resid == 0 and, thusly,
- * B_CACHE getting set.
- *
- * We can also avoid issuing the read if the write covers
- * the entire buffer. We have to make sure the buffer state
- * is reasonable in this case since we will not be initiating
- * I/O. See the comments in kern/vfs_bio.c's getblk() for
- * more information.
- *
- * B_CACHE may also be set due to the buffer being cached
- * normally.
- */
-
- if (on == 0 && n == bcount) {
- bp->b_flags |= B_CACHE;
- bp->b_flags &= ~B_INVAL;
- bp->b_ioflags &= ~BIO_ERROR;
- }
-
- if ((bp->b_flags & B_CACHE) == 0) {
- bp->b_iocmd = BIO_READ;
- vfs_busy_pages(bp, 0);
- error = nfs_doio(vp, bp, cred, td);
- if (error) {
- brelse(bp);
- break;
- }
- }
- if (bp->b_wcred == NOCRED)
- bp->b_wcred = crhold(cred);
- mtx_lock(&np->n_mtx);
- np->n_flag |= NMODIFIED;
- mtx_unlock(&np->n_mtx);
-
- /*
- * If dirtyend exceeds file size, chop it down. This should
- * not normally occur but there is an append race where it
- * might occur XXX, so we log it.
- *
- * If the chopping creates a reverse-indexed or degenerate
- * situation with dirtyoff/end, we 0 both of them.
- */
-
- if (bp->b_dirtyend > bcount) {
- nfs_printf("NFS append race @%lx:%d\n",
- (long)bp->b_blkno * DEV_BSIZE,
- bp->b_dirtyend - bcount);
- bp->b_dirtyend = bcount;
- }
-
- if (bp->b_dirtyoff >= bp->b_dirtyend)
- bp->b_dirtyoff = bp->b_dirtyend = 0;
-
- /*
- * If the new write will leave a contiguous dirty
- * area, just update the b_dirtyoff and b_dirtyend,
- * otherwise force a write rpc of the old dirty area.
- *
- * While it is possible to merge discontiguous writes due to
- * our having a B_CACHE buffer ( and thus valid read data
- * for the hole), we don't because it could lead to
- * significant cache coherency problems with multiple clients,
- * especially if locking is implemented later on.
- *
- * as an optimization we could theoretically maintain
- * a linked list of discontinuous areas, but we would still
- * have to commit them separately so there isn't much
- * advantage to it except perhaps a bit of asynchronization.
- */
-
- if (bp->b_dirtyend > 0 &&
- (on > bp->b_dirtyend || (on + n) < bp->b_dirtyoff)) {
- if (bwrite(bp) == EINTR) {
- error = EINTR;
- break;
- }
- goto again;
- }
-
- error = uiomove((char *)bp->b_data + on, n, uio);
-
- /*
- * Since this block is being modified, it must be written
- * again and not just committed. Since write clustering does
- * not work for the stage 1 data write, only the stage 2
- * commit rpc, we have to clear B_CLUSTEROK as well.
- */
- bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
-
- if (error) {
- bp->b_ioflags |= BIO_ERROR;
- brelse(bp);
- break;
- }
-
- /*
- * Only update dirtyoff/dirtyend if not a degenerate
- * condition.
- */
- if (n) {
- if (bp->b_dirtyend > 0) {
- bp->b_dirtyoff = min(on, bp->b_dirtyoff);
- bp->b_dirtyend = max((on + n), bp->b_dirtyend);
- } else {
- bp->b_dirtyoff = on;
- bp->b_dirtyend = on + n;
- }
- vfs_bio_set_valid(bp, on, n);
- }
-
- /*
- * If IO_SYNC do bwrite().
- *
- * IO_INVAL appears to be unused. The idea appears to be
- * to turn off caching in this case. Very odd. XXX
- */
- if ((ioflag & IO_SYNC)) {
- if (ioflag & IO_INVAL)
- bp->b_flags |= B_NOCACHE;
- error = bwrite(bp);
- if (error)
- break;
- } else if ((n + on) == biosize) {
- bp->b_flags |= B_ASYNC;
- (void) (nmp->nm_rpcops->nr_writebp)(bp, 0, NULL);
- } else {
- bdwrite(bp);
- }
- } while (uio->uio_resid > 0 && n > 0);
-
- return (error);
-}
-
-/*
- * Get an nfs cache block.
- *
- * Allocate a new one if the block isn't currently in the cache
- * and return the block marked busy. If the calling process is
- * interrupted by a signal for an interruptible mount point, return
- * NULL.
- *
- * The caller must carefully deal with the possible B_INVAL state of
- * the buffer. nfs_doio() clears B_INVAL (and nfs_asyncio() clears it
- * indirectly), so synchronous reads can be issued without worrying about
- * the B_INVAL state. We have to be a little more careful when dealing
- * with writes (see comments in nfs_write()) when extending a file past
- * its EOF.
- */
-static struct buf *
-nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td)
-{
- struct buf *bp;
- struct mount *mp;
- struct nfsmount *nmp;
-
- mp = vp->v_mount;
- nmp = VFSTONFS(mp);
-
- if (nmp->nm_flag & NFSMNT_INT) {
- sigset_t oldset;
-
- nfs_set_sigmask(td, &oldset);
- bp = getblk(vp, bn, size, PCATCH, 0, 0);
- nfs_restore_sigmask(td, &oldset);
- while (bp == NULL) {
- if (nfs_sigintr(nmp, td))
- return (NULL);
- bp = getblk(vp, bn, size, 0, 2 * hz, 0);
- }
- } else {
- bp = getblk(vp, bn, size, 0, 0, 0);
- }
-
- if (vp->v_type == VREG)
- bp->b_blkno = bn * (vp->v_bufobj.bo_bsize / DEV_BSIZE);
- return (bp);
-}
-
-/*
- * Flush and invalidate all dirty buffers. If another process is already
- * doing the flush, just wait for completion.
- */
-int
-nfs_vinvalbuf(struct vnode *vp, int flags, struct thread *td, int intrflg)
-{
- struct nfsnode *np = VTONFS(vp);
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- int error = 0, slpflag, slptimeo;
- int old_lock = 0;
-
- ASSERT_VOP_LOCKED(vp, "nfs_vinvalbuf");
-
- if ((nmp->nm_flag & NFSMNT_INT) == 0)
- intrflg = 0;
- if (intrflg) {
- slpflag = PCATCH;
- slptimeo = 2 * hz;
- } else {
- slpflag = 0;
- slptimeo = 0;
- }
-
- old_lock = nfs_upgrade_vnlock(vp);
- if (vp->v_iflag & VI_DOOMED) {
- /*
- * Since vgonel() uses the generic vinvalbuf() to flush
- * dirty buffers and it does not call this function, it
- * is safe to just return OK when VI_DOOMED is set.
- */
- nfs_downgrade_vnlock(vp, old_lock);
- return (0);
- }
-
- /*
- * Now, flush as required.
- */
- if ((flags & V_SAVE) && (vp->v_bufobj.bo_object != NULL)) {
- VM_OBJECT_WLOCK(vp->v_bufobj.bo_object);
- vm_object_page_clean(vp->v_bufobj.bo_object, 0, 0, OBJPC_SYNC);
- VM_OBJECT_WUNLOCK(vp->v_bufobj.bo_object);
- /*
- * If the page clean was interrupted, fail the invalidation.
- * Not doing so, we run the risk of losing dirty pages in the
- * vinvalbuf() call below.
- */
- if (intrflg && (error = nfs_sigintr(nmp, td)))
- goto out;
- }
-
- error = vinvalbuf(vp, flags, slpflag, 0);
- while (error) {
- if (intrflg && (error = nfs_sigintr(nmp, td)))
- goto out;
- error = vinvalbuf(vp, flags, 0, slptimeo);
- }
- mtx_lock(&np->n_mtx);
- if (np->n_directio_asyncwr == 0)
- np->n_flag &= ~NMODIFIED;
- mtx_unlock(&np->n_mtx);
-out:
- nfs_downgrade_vnlock(vp, old_lock);
- return error;
-}
-
-/*
- * Initiate asynchronous I/O. Return an error if no nfsiods are available.
- * This is mainly to avoid queueing async I/O requests when the nfsiods
- * are all hung on a dead server.
- *
- * Note: nfs_asyncio() does not clear (BIO_ERROR|B_INVAL) but when the bp
- * is eventually dequeued by the async daemon, nfs_doio() *will*.
- */
-int
-nfs_asyncio(struct nfsmount *nmp, struct buf *bp, struct ucred *cred, struct thread *td)
-{
- int iod;
- int gotiod;
- int slpflag = 0;
- int slptimeo = 0;
- int error, error2;
-
- /*
- * Commits are usually short and sweet so lets save some cpu and
- * leave the async daemons for more important rpc's (such as reads
- * and writes).
- *
- * Readdirplus RPCs do vget()s to acquire the vnodes for entries
- * in the directory in order to update attributes. This can deadlock
- * with another thread that is waiting for async I/O to be done by
- * an nfsiod thread while holding a lock on one of these vnodes.
- * To avoid this deadlock, don't allow the async nfsiod threads to
- * perform Readdirplus RPCs.
- */
- mtx_lock(&nfs_iod_mtx);
- if ((bp->b_iocmd == BIO_WRITE && (bp->b_flags & B_NEEDCOMMIT) &&
- (nmp->nm_bufqiods > nfs_numasync / 2)) ||
- (bp->b_vp->v_type == VDIR && (nmp->nm_flag & NFSMNT_RDIRPLUS))) {
- mtx_unlock(&nfs_iod_mtx);
- return(EIO);
- }
-again:
- if (nmp->nm_flag & NFSMNT_INT)
- slpflag = PCATCH;
- gotiod = FALSE;
-
- /*
- * Find a free iod to process this request.
- */
- for (iod = 0; iod < nfs_numasync; iod++)
- if (nfs_iodwant[iod] == NFSIOD_AVAILABLE) {
- gotiod = TRUE;
- break;
- }
-
- /*
- * Try to create one if none are free.
- */
- if (!gotiod)
- nfs_nfsiodnew();
- else {
- /*
- * Found one, so wake it up and tell it which
- * mount to process.
- */
- NFS_DPF(ASYNCIO, ("nfs_asyncio: waking iod %d for mount %p\n",
- iod, nmp));
- nfs_iodwant[iod] = NFSIOD_NOT_AVAILABLE;
- nfs_iodmount[iod] = nmp;
- nmp->nm_bufqiods++;
- wakeup(&nfs_iodwant[iod]);
- }
-
- /*
- * If none are free, we may already have an iod working on this mount
- * point. If so, it will process our request.
- */
- if (!gotiod) {
- if (nmp->nm_bufqiods > 0) {
- NFS_DPF(ASYNCIO,
- ("nfs_asyncio: %d iods are already processing mount %p\n",
- nmp->nm_bufqiods, nmp));
- gotiod = TRUE;
- }
- }
-
- /*
- * If we have an iod which can process the request, then queue
- * the buffer.
- */
- if (gotiod) {
- /*
- * Ensure that the queue never grows too large. We still want
- * to asynchronize so we block rather then return EIO.
- */
- while (nmp->nm_bufqlen >= 2 * nfs_numasync) {
- NFS_DPF(ASYNCIO,
- ("nfs_asyncio: waiting for mount %p queue to drain\n", nmp));
- nmp->nm_bufqwant = TRUE;
- error = nfs_msleep(td, &nmp->nm_bufq, &nfs_iod_mtx,
- slpflag | PRIBIO,
- "nfsaio", slptimeo);
- if (error) {
- error2 = nfs_sigintr(nmp, td);
- if (error2) {
- mtx_unlock(&nfs_iod_mtx);
- return (error2);
- }
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- }
- /*
- * We might have lost our iod while sleeping,
- * so check and loop if nescessary.
- */
- goto again;
- }
-
- /* We might have lost our nfsiod */
- if (nmp->nm_bufqiods == 0) {
- NFS_DPF(ASYNCIO,
-("nfs_asyncio: no iods after mount %p queue was drained, looping\n", nmp));
- goto again;
- }
-
- if (bp->b_iocmd == BIO_READ) {
- if (bp->b_rcred == NOCRED && cred != NOCRED)
- bp->b_rcred = crhold(cred);
- } else {
- if (bp->b_wcred == NOCRED && cred != NOCRED)
- bp->b_wcred = crhold(cred);
- }
-
- if (bp->b_flags & B_REMFREE)
- bremfreef(bp);
- BUF_KERNPROC(bp);
- TAILQ_INSERT_TAIL(&nmp->nm_bufq, bp, b_freelist);
- nmp->nm_bufqlen++;
- if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) {
- mtx_lock(&(VTONFS(bp->b_vp))->n_mtx);
- VTONFS(bp->b_vp)->n_flag |= NMODIFIED;
- VTONFS(bp->b_vp)->n_directio_asyncwr++;
- mtx_unlock(&(VTONFS(bp->b_vp))->n_mtx);
- }
- mtx_unlock(&nfs_iod_mtx);
- return (0);
- }
-
- mtx_unlock(&nfs_iod_mtx);
-
- /*
- * All the iods are busy on other mounts, so return EIO to
- * force the caller to process the i/o synchronously.
- */
- NFS_DPF(ASYNCIO, ("nfs_asyncio: no iods available, i/o is synchronous\n"));
- return (EIO);
-}
-
-void
-nfs_doio_directwrite(struct buf *bp)
-{
- int iomode, must_commit;
- struct uio *uiop = (struct uio *)bp->b_caller1;
- char *iov_base = uiop->uio_iov->iov_base;
- struct nfsmount *nmp = VFSTONFS(bp->b_vp->v_mount);
-
- iomode = NFSV3WRITE_FILESYNC;
- uiop->uio_td = NULL; /* NULL since we're in nfsiod */
- (nmp->nm_rpcops->nr_writerpc)(bp->b_vp, uiop, bp->b_wcred, &iomode, &must_commit);
- KASSERT((must_commit == 0), ("nfs_doio_directwrite: Did not commit write"));
- free(iov_base, M_NFSDIRECTIO);
- free(uiop->uio_iov, M_NFSDIRECTIO);
- free(uiop, M_NFSDIRECTIO);
- if ((bp->b_flags & B_DIRECT) && bp->b_iocmd == BIO_WRITE) {
- struct nfsnode *np = VTONFS(bp->b_vp);
- mtx_lock(&np->n_mtx);
- np->n_directio_asyncwr--;
- if (np->n_directio_asyncwr == 0) {
- VTONFS(bp->b_vp)->n_flag &= ~NMODIFIED;
- if ((np->n_flag & NFSYNCWAIT)) {
- np->n_flag &= ~NFSYNCWAIT;
- wakeup((caddr_t)&np->n_directio_asyncwr);
- }
- }
- mtx_unlock(&np->n_mtx);
- }
- bp->b_vp = NULL;
- relpbuf(bp, &nfs_pbuf_freecnt);
-}
-
-/*
- * Do an I/O operation to/from a cache block. This may be called
- * synchronously or from an nfsiod.
- */
-int
-nfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
-{
- struct uio *uiop;
- struct nfsnode *np;
- struct nfsmount *nmp;
- int error = 0, iomode, must_commit = 0;
- struct uio uio;
- struct iovec io;
- struct proc *p = td ? td->td_proc : NULL;
- uint8_t iocmd;
-
- np = VTONFS(vp);
- nmp = VFSTONFS(vp->v_mount);
- uiop = &uio;
- uiop->uio_iov = &io;
- uiop->uio_iovcnt = 1;
- uiop->uio_segflg = UIO_SYSSPACE;
- uiop->uio_td = td;
-
- /*
- * clear BIO_ERROR and B_INVAL state prior to initiating the I/O. We
- * do this here so we do not have to do it in all the code that
- * calls us.
- */
- bp->b_flags &= ~B_INVAL;
- bp->b_ioflags &= ~BIO_ERROR;
-
- KASSERT(!(bp->b_flags & B_DONE), ("nfs_doio: bp %p already marked done", bp));
- iocmd = bp->b_iocmd;
- if (iocmd == BIO_READ) {
- io.iov_len = uiop->uio_resid = bp->b_bcount;
- io.iov_base = bp->b_data;
- uiop->uio_rw = UIO_READ;
-
- switch (vp->v_type) {
- case VREG:
- uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
- nfsstats.read_bios++;
- error = (nmp->nm_rpcops->nr_readrpc)(vp, uiop, cr);
-
- if (!error) {
- if (uiop->uio_resid) {
- /*
- * If we had a short read with no error, we must have
- * hit a file hole. We should zero-fill the remainder.
- * This can also occur if the server hits the file EOF.
- *
- * Holes used to be able to occur due to pending
- * writes, but that is not possible any longer.
- */
- int nread = bp->b_bcount - uiop->uio_resid;
- int left = uiop->uio_resid;
-
- if (left > 0)
- bzero((char *)bp->b_data + nread, left);
- uiop->uio_resid = 0;
- }
- }
- /* ASSERT_VOP_LOCKED(vp, "nfs_doio"); */
- if (p && (vp->v_vflag & VV_TEXT)) {
- mtx_lock(&np->n_mtx);
- if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &np->n_vattr.va_mtime)) {
- mtx_unlock(&np->n_mtx);
- PROC_LOCK(p);
- killproc(p, "text file modification");
- PROC_UNLOCK(p);
- } else
- mtx_unlock(&np->n_mtx);
- }
- break;
- case VLNK:
- uiop->uio_offset = (off_t)0;
- nfsstats.readlink_bios++;
- error = (nmp->nm_rpcops->nr_readlinkrpc)(vp, uiop, cr);
- break;
- case VDIR:
- nfsstats.readdir_bios++;
- uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ;
- if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) {
- error = nfs_readdirplusrpc(vp, uiop, cr);
- if (error == NFSERR_NOTSUPP)
- nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
- }
- if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0)
- error = nfs_readdirrpc(vp, uiop, cr);
- /*
- * end-of-directory sets B_INVAL but does not generate an
- * error.
- */
- if (error == 0 && uiop->uio_resid == bp->b_bcount)
- bp->b_flags |= B_INVAL;
- break;
- default:
- nfs_printf("nfs_doio: type %x unexpected\n", vp->v_type);
- break;
- };
- if (error) {
- bp->b_ioflags |= BIO_ERROR;
- bp->b_error = error;
- }
- } else {
- /*
- * If we only need to commit, try to commit
- */
- if (bp->b_flags & B_NEEDCOMMIT) {
- int retv;
- off_t off;
-
- off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
- retv = (nmp->nm_rpcops->nr_commit)(
- vp, off, bp->b_dirtyend-bp->b_dirtyoff,
- bp->b_wcred, td);
- if (retv == 0) {
- bp->b_dirtyoff = bp->b_dirtyend = 0;
- bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
- bp->b_resid = 0;
- bufdone(bp);
- return (0);
- }
- if (retv == NFSERR_STALEWRITEVERF) {
- nfs_clearcommit(vp->v_mount);
- }
- }
-
- /*
- * Setup for actual write
- */
- mtx_lock(&np->n_mtx);
- if ((off_t)bp->b_blkno * DEV_BSIZE + bp->b_dirtyend > np->n_size)
- bp->b_dirtyend = np->n_size - (off_t)bp->b_blkno * DEV_BSIZE;
- mtx_unlock(&np->n_mtx);
-
- if (bp->b_dirtyend > bp->b_dirtyoff) {
- io.iov_len = uiop->uio_resid = bp->b_dirtyend
- - bp->b_dirtyoff;
- uiop->uio_offset = (off_t)bp->b_blkno * DEV_BSIZE
- + bp->b_dirtyoff;
- io.iov_base = (char *)bp->b_data + bp->b_dirtyoff;
- uiop->uio_rw = UIO_WRITE;
- nfsstats.write_bios++;
-
- if ((bp->b_flags & (B_ASYNC | B_NEEDCOMMIT | B_NOCACHE | B_CLUSTER)) == B_ASYNC)
- iomode = NFSV3WRITE_UNSTABLE;
- else
- iomode = NFSV3WRITE_FILESYNC;
-
- error = (nmp->nm_rpcops->nr_writerpc)(vp, uiop, cr, &iomode, &must_commit);
-
- /*
- * When setting B_NEEDCOMMIT also set B_CLUSTEROK to try
- * to cluster the buffers needing commit. This will allow
- * the system to submit a single commit rpc for the whole
- * cluster. We can do this even if the buffer is not 100%
- * dirty (relative to the NFS blocksize), so we optimize the
- * append-to-file-case.
- *
- * (when clearing B_NEEDCOMMIT, B_CLUSTEROK must also be
- * cleared because write clustering only works for commit
- * rpc's, not for the data portion of the write).
- */
-
- if (!error && iomode == NFSV3WRITE_UNSTABLE) {
- bp->b_flags |= B_NEEDCOMMIT;
- if (bp->b_dirtyoff == 0
- && bp->b_dirtyend == bp->b_bcount)
- bp->b_flags |= B_CLUSTEROK;
- } else {
- bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
- }
-
- /*
- * For an interrupted write, the buffer is still valid
- * and the write hasn't been pushed to the server yet,
- * so we can't set BIO_ERROR and report the interruption
- * by setting B_EINTR. For the B_ASYNC case, B_EINTR
- * is not relevant, so the rpc attempt is essentially
- * a noop. For the case of a V3 write rpc not being
- * committed to stable storage, the block is still
- * dirty and requires either a commit rpc or another
- * write rpc with iomode == NFSV3WRITE_FILESYNC before
- * the block is reused. This is indicated by setting
- * the B_DELWRI and B_NEEDCOMMIT flags.
- *
- * If the buffer is marked B_PAGING, it does not reside on
- * the vp's paging queues so we cannot call bdirty(). The
- * bp in this case is not an NFS cache block so we should
- * be safe. XXX
- *
- * The logic below breaks up errors into recoverable and
- * unrecoverable. For the former, we clear B_INVAL|B_NOCACHE
- * and keep the buffer around for potential write retries.
- * For the latter (eg ESTALE), we toss the buffer away (B_INVAL)
- * and save the error in the nfsnode. This is less than ideal
- * but necessary. Keeping such buffers around could potentially
- * cause buffer exhaustion eventually (they can never be written
- * out, so will get constantly be re-dirtied). It also causes
- * all sorts of vfs panics. For non-recoverable write errors,
- * also invalidate the attrcache, so we'll be forced to go over
- * the wire for this object, returning an error to user on next
- * call (most of the time).
- */
- if (error == EINTR || error == EIO || error == ETIMEDOUT
- || (!error && (bp->b_flags & B_NEEDCOMMIT))) {
- int s;
-
- s = splbio();
- bp->b_flags &= ~(B_INVAL|B_NOCACHE);
- if ((bp->b_flags & B_PAGING) == 0) {
- bdirty(bp);
- bp->b_flags &= ~B_DONE;
- }
- if (error && (bp->b_flags & B_ASYNC) == 0)
- bp->b_flags |= B_EINTR;
- splx(s);
- } else {
- if (error) {
- bp->b_ioflags |= BIO_ERROR;
- bp->b_flags |= B_INVAL;
- bp->b_error = np->n_error = error;
- mtx_lock(&np->n_mtx);
- np->n_flag |= NWRITEERR;
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- mtx_unlock(&np->n_mtx);
- }
- bp->b_dirtyoff = bp->b_dirtyend = 0;
- }
- } else {
- bp->b_resid = 0;
- bufdone(bp);
- return (0);
- }
- }
- bp->b_resid = uiop->uio_resid;
- if (must_commit)
- nfs_clearcommit(vp->v_mount);
- bufdone(bp);
- return (error);
-}
-
-/*
- * Used to aid in handling ftruncate() operations on the NFS client side.
- * Truncation creates a number of special problems for NFS. We have to
- * throw away VM pages and buffer cache buffers that are beyond EOF, and
- * we have to properly handle VM pages or (potentially dirty) buffers
- * that straddle the truncation point.
- */
-
-int
-nfs_meta_setsize(struct vnode *vp, struct ucred *cred, struct thread *td, u_quad_t nsize)
-{
- struct nfsnode *np = VTONFS(vp);
- u_quad_t tsize;
- int biosize = vp->v_bufobj.bo_bsize;
- int error = 0;
-
- mtx_lock(&np->n_mtx);
- tsize = np->n_size;
- np->n_size = nsize;
- mtx_unlock(&np->n_mtx);
-
- if (nsize < tsize) {
- struct buf *bp;
- daddr_t lbn;
- int bufsize;
-
- /*
- * vtruncbuf() doesn't get the buffer overlapping the
- * truncation point. We may have a B_DELWRI and/or B_CACHE
- * buffer that now needs to be truncated.
- */
- error = vtruncbuf(vp, cred, nsize, biosize);
- lbn = nsize / biosize;
- bufsize = nsize - (lbn * biosize);
- bp = nfs_getcacheblk(vp, lbn, bufsize, td);
- if (!bp)
- return EINTR;
- if (bp->b_dirtyoff > bp->b_bcount)
- bp->b_dirtyoff = bp->b_bcount;
- if (bp->b_dirtyend > bp->b_bcount)
- bp->b_dirtyend = bp->b_bcount;
- bp->b_flags |= B_RELBUF; /* don't leave garbage around */
- brelse(bp);
- } else {
- vnode_pager_setsize(vp, nsize);
- }
- return(error);
-}
-
diff --git a/sys/nfsclient/nfs_kdtrace.c b/sys/nfsclient/nfs_kdtrace.c
deleted file mode 100644
index 429dbc3..0000000
--- a/sys/nfsclient/nfs_kdtrace.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*-
- * Copyright (c) 2009 Robert N. M. Watson
- * All rights reserved.
- *
- * This software was developed at the University of Cambridge Computer
- * Laboratory with support from a grant from Google, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-
-#include <sys/dtrace.h>
-#include <sys/dtrace_bsd.h>
-
-#include <nfs/nfsproto.h>
-
-/*
- * dtnfsclient is a DTrace provider that tracks the intent to perform RPCs
- * in the NFS client, as well as acess to and maintenance of the access and
- * attribute caches. This is not quite the same as RPCs, because NFS may
- * issue multiple RPC transactions in the event that authentication fails,
- * there's a jukebox error, or none at all if the access or attribute cache
- * hits. However, it cleanly represents the logical layer between RPC
- * transmission and vnode/vfs operations, providing access to state linking
- * the two.
- */
-
-static int dtnfsclient_unload(void);
-static void dtnfsclient_getargdesc(void *, dtrace_id_t, void *,
- dtrace_argdesc_t *);
-static void dtnfsclient_provide(void *, dtrace_probedesc_t *);
-static void dtnfsclient_destroy(void *, dtrace_id_t, void *);
-static void dtnfsclient_enable(void *, dtrace_id_t, void *);
-static void dtnfsclient_disable(void *, dtrace_id_t, void *);
-static void dtnfsclient_load(void *);
-
-static dtrace_pattr_t dtnfsclient_attr = {
-{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
-{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
-{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
-{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
-};
-
-/*
- * Description of NFSv3 and (optional) NFSv2 probes for a procedure.
- */
-struct dtnfsclient_rpc {
- char *nr_v3_name;
- char *nr_v2_name; /* Or NULL if none. */
-
- /*
- * IDs for the start and done cases, for both NFSv2 and NFSv3.
- */
- uint32_t nr_v2_id_start, nr_v2_id_done;
- uint32_t nr_v3_id_start, nr_v3_id_done;
-};
-
-/*
- * This table is indexed by NFSv3 procedure number, but also used for NFSv2
- * procedure names.
- */
-static struct dtnfsclient_rpc dtnfsclient_rpcs[NFS_NPROCS] = {
- { "null", "null" },
- { "getattr", "getattr" },
- { "setattr", "setattr" },
- { "lookup", "lookup" },
- { "access" },
- { "readlink", "readlink" },
- { "read", "read" },
- { "write", "write" },
- { "create", "create" },
- { "mkdir", "mkdir" },
- { "symlink", "symlink" },
- { "mknod" },
- { "remove", "remove" },
- { "rmdir", "rmdir" },
- { "rename", "rename" },
- { "link", "link" },
- { "readdir", "readdir" },
- { "readdirplus" },
- { "fsstat", "statfs" },
- { "fsinfo" },
- { "pathconf" },
- { "commit" },
- { "noop" },
-};
-
-/*
- * Module name strings.
- */
-static char *dtnfsclient_accesscache_str = "accesscache";
-static char *dtnfsclient_attrcache_str = "attrcache";
-static char *dtnfsclient_nfs2_str = "nfs2";
-static char *dtnfsclient_nfs3_str = "nfs3";
-
-/*
- * Function name strings.
- */
-static char *dtnfsclient_flush_str = "flush";
-static char *dtnfsclient_load_str = "load";
-static char *dtnfsclient_get_str = "get";
-
-/*
- * Name strings.
- */
-static char *dtnfsclient_done_str = "done";
-static char *dtnfsclient_hit_str = "hit";
-static char *dtnfsclient_miss_str = "miss";
-static char *dtnfsclient_start_str = "start";
-
-static dtrace_pops_t dtnfsclient_pops = {
- dtnfsclient_provide,
- NULL,
- dtnfsclient_enable,
- dtnfsclient_disable,
- NULL,
- NULL,
- dtnfsclient_getargdesc,
- NULL,
- NULL,
- dtnfsclient_destroy
-};
-
-static dtrace_provider_id_t dtnfsclient_id;
-
-/*
- * Most probes are generated from the above RPC table, but for access and
- * attribute caches, we have specific IDs we recognize and handle specially
- * in various spots.
- */
-extern uint32_t nfsclient_accesscache_flush_done_id;
-extern uint32_t nfsclient_accesscache_get_hit_id;
-extern uint32_t nfsclient_accesscache_get_miss_id;
-extern uint32_t nfsclient_accesscache_load_done_id;
-
-extern uint32_t nfsclient_attrcache_flush_done_id;
-extern uint32_t nfsclient_attrcache_get_hit_id;
-extern uint32_t nfsclient_attrcache_get_miss_id;
-extern uint32_t nfsclient_attrcache_load_done_id;
-
-/*
- * When tracing on a procedure is enabled, the DTrace ID for an RPC event is
- * stored in one of these two NFS client-allocated arrays; 0 indicates that
- * the event is not being traced so probes should not be called.
- *
- * For simplicity, we allocate both v2 and v3 arrays as NFS_NPROCS, and the
- * v2 array is simply sparse.
- */
-extern uint32_t nfsclient_nfs2_start_probes[NFS_NPROCS];
-extern uint32_t nfsclient_nfs2_done_probes[NFS_NPROCS];
-
-extern uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS];
-extern uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS];
-
-/*
- * Look up a DTrace probe ID to see if it's associated with a "done" event --
- * if so, we will return a fourth argument type of "int".
- */
-static int
-dtnfs23_isdoneprobe(dtrace_id_t id)
-{
- int i;
-
- for (i = 0; i < NFS_NPROCS; i++) {
- if (dtnfsclient_rpcs[i].nr_v3_id_done == id ||
- dtnfsclient_rpcs[i].nr_v2_id_done == id)
- return (1);
- }
- return (0);
-}
-
-static void
-dtnfsclient_getargdesc(void *arg, dtrace_id_t id, void *parg,
- dtrace_argdesc_t *desc)
-{
- const char *p = NULL;
-
- if (id == nfsclient_accesscache_flush_done_id ||
- id == nfsclient_attrcache_flush_done_id ||
- id == nfsclient_attrcache_get_miss_id) {
- switch (desc->dtargd_ndx) {
- case 0:
- p = "struct vnode *";
- break;
- default:
- desc->dtargd_ndx = DTRACE_ARGNONE;
- break;
- }
- } else if (id == nfsclient_accesscache_get_hit_id ||
- id == nfsclient_accesscache_get_miss_id) {
- switch (desc->dtargd_ndx) {
- case 0:
- p = "struct vnode *";
- break;
- case 1:
- p = "uid_t";
- break;
- case 2:
- p = "uint32_t";
- break;
- default:
- desc->dtargd_ndx = DTRACE_ARGNONE;
- break;
- }
- } else if (id == nfsclient_accesscache_load_done_id) {
- switch (desc->dtargd_ndx) {
- case 0:
- p = "struct vnode *";
- break;
- case 1:
- p = "uid_t";
- break;
- case 2:
- p = "uint32_t";
- break;
- case 3:
- p = "int";
- break;
- default:
- desc->dtargd_ndx = DTRACE_ARGNONE;
- break;
- }
- } else if (id == nfsclient_attrcache_get_hit_id) {
- switch (desc->dtargd_ndx) {
- case 0:
- p = "struct vnode *";
- break;
- case 1:
- p = "struct vattr *";
- break;
- default:
- desc->dtargd_ndx = DTRACE_ARGNONE;
- break;
- }
- } else if (id == nfsclient_attrcache_load_done_id) {
- switch (desc->dtargd_ndx) {
- case 0:
- p = "struct vnode *";
- break;
- case 1:
- p = "struct vattr *";
- break;
- case 2:
- p = "int";
- break;
- default:
- desc->dtargd_ndx = DTRACE_ARGNONE;
- break;
- }
- } else {
- switch (desc->dtargd_ndx) {
- case 0:
- p = "struct vnode *";
- break;
- case 1:
- p = "struct mbuf *";
- break;
- case 2:
- p = "struct ucred *";
- break;
- case 3:
- p = "int";
- break;
- case 4:
- if (dtnfs23_isdoneprobe(id)) {
- p = "int";
- break;
- }
- /* FALLSTHROUGH */
- default:
- desc->dtargd_ndx = DTRACE_ARGNONE;
- break;
- }
- }
- if (p != NULL)
- strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
-}
-
-static void
-dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc)
-{
- int i;
-
- if (desc != NULL)
- return;
-
- /*
- * Register access cache probes.
- */
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
- nfsclient_accesscache_flush_done_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
- nfsclient_accesscache_get_hit_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
- nfsclient_accesscache_get_miss_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
- nfsclient_accesscache_load_done_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_accesscache_str,
- dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
- }
-
- /*
- * Register attribute cache probes.
- */
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
- nfsclient_attrcache_flush_done_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
- nfsclient_attrcache_get_hit_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
- nfsclient_attrcache_get_miss_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
- nfsclient_attrcache_load_done_id = dtrace_probe_create(
- dtnfsclient_id, dtnfsclient_attrcache_str,
- dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
- }
-
- /*
- * Register NFSv2 RPC procedures; note sparseness check for each slot
- * in the NFSv3 procnum-indexed array.
- */
- for (i = 0; i < NFS_NPROCS; i++) {
- if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
- dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
- dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) ==
- 0) {
- dtnfsclient_rpcs[i].nr_v2_id_start =
- dtrace_probe_create(dtnfsclient_id,
- dtnfsclient_nfs2_str,
- dtnfsclient_rpcs[i].nr_v2_name,
- dtnfsclient_start_str, 0,
- &nfsclient_nfs2_start_probes[i]);
- }
- if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
- dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
- dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) ==
- 0) {
- dtnfsclient_rpcs[i].nr_v2_id_done =
- dtrace_probe_create(dtnfsclient_id,
- dtnfsclient_nfs2_str,
- dtnfsclient_rpcs[i].nr_v2_name,
- dtnfsclient_done_str, 0,
- &nfsclient_nfs2_done_probes[i]);
- }
- }
-
- /*
- * Register NFSv3 RPC procedures.
- */
- for (i = 0; i < NFS_NPROCS; i++) {
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
- dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) ==
- 0) {
- dtnfsclient_rpcs[i].nr_v3_id_start =
- dtrace_probe_create(dtnfsclient_id,
- dtnfsclient_nfs3_str,
- dtnfsclient_rpcs[i].nr_v3_name,
- dtnfsclient_start_str, 0,
- &nfsclient_nfs3_start_probes[i]);
- }
- if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
- dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) ==
- 0) {
- dtnfsclient_rpcs[i].nr_v3_id_done =
- dtrace_probe_create(dtnfsclient_id,
- dtnfsclient_nfs3_str,
- dtnfsclient_rpcs[i].nr_v3_name,
- dtnfsclient_done_str, 0,
- &nfsclient_nfs3_done_probes[i]);
- }
- }
-}
-
-static void
-dtnfsclient_destroy(void *arg, dtrace_id_t id, void *parg)
-{
-}
-
-static void
-dtnfsclient_enable(void *arg, dtrace_id_t id, void *parg)
-{
- uint32_t *p = parg;
- void *f = dtrace_probe;
-
- if (id == nfsclient_accesscache_flush_done_id)
- dtrace_nfsclient_accesscache_flush_done_probe = f;
- else if (id == nfsclient_accesscache_get_hit_id)
- dtrace_nfsclient_accesscache_get_hit_probe = f;
- else if (id == nfsclient_accesscache_get_miss_id)
- dtrace_nfsclient_accesscache_get_miss_probe = f;
- else if (id == nfsclient_accesscache_load_done_id)
- dtrace_nfsclient_accesscache_load_done_probe = f;
- else if (id == nfsclient_attrcache_flush_done_id)
- dtrace_nfsclient_attrcache_flush_done_probe = f;
- else if (id == nfsclient_attrcache_get_hit_id)
- dtrace_nfsclient_attrcache_get_hit_probe = f;
- else if (id == nfsclient_attrcache_get_miss_id)
- dtrace_nfsclient_attrcache_get_miss_probe = f;
- else if (id == nfsclient_attrcache_load_done_id)
- dtrace_nfsclient_attrcache_load_done_probe = f;
- else
- *p = id;
-}
-
-static void
-dtnfsclient_disable(void *arg, dtrace_id_t id, void *parg)
-{
- uint32_t *p = parg;
-
- if (id == nfsclient_accesscache_flush_done_id)
- dtrace_nfsclient_accesscache_flush_done_probe = NULL;
- else if (id == nfsclient_accesscache_get_hit_id)
- dtrace_nfsclient_accesscache_get_hit_probe = NULL;
- else if (id == nfsclient_accesscache_get_miss_id)
- dtrace_nfsclient_accesscache_get_miss_probe = NULL;
- else if (id == nfsclient_accesscache_load_done_id)
- dtrace_nfsclient_accesscache_load_done_probe = NULL;
- else if (id == nfsclient_attrcache_flush_done_id)
- dtrace_nfsclient_attrcache_flush_done_probe = NULL;
- else if (id == nfsclient_attrcache_get_hit_id)
- dtrace_nfsclient_attrcache_get_hit_probe = NULL;
- else if (id == nfsclient_attrcache_get_miss_id)
- dtrace_nfsclient_attrcache_get_miss_probe = NULL;
- else if (id == nfsclient_attrcache_load_done_id)
- dtrace_nfsclient_attrcache_load_done_probe = NULL;
- else
- *p = 0;
-}
-
-static void
-dtnfsclient_load(void *dummy)
-{
-
- if (dtrace_register("nfsclient", &dtnfsclient_attr,
- DTRACE_PRIV_USER, NULL, &dtnfsclient_pops, NULL,
- &dtnfsclient_id) != 0)
- return;
-
- dtrace_nfsclient_nfs23_start_probe =
- (dtrace_nfsclient_nfs23_start_probe_func_t)dtrace_probe;
- dtrace_nfsclient_nfs23_done_probe =
- (dtrace_nfsclient_nfs23_done_probe_func_t)dtrace_probe;
-}
-
-
-static int
-dtnfsclient_unload()
-{
-
- dtrace_nfsclient_nfs23_start_probe = NULL;
- dtrace_nfsclient_nfs23_done_probe = NULL;
-
- return (dtrace_unregister(dtnfsclient_id));
-}
-
-static int
-dtnfsclient_modevent(module_t mod __unused, int type, void *data __unused)
-{
- int error = 0;
-
- switch (type) {
- case MOD_LOAD:
- break;
-
- case MOD_UNLOAD:
- break;
-
- case MOD_SHUTDOWN:
- break;
-
- default:
- error = EOPNOTSUPP;
- break;
- }
-
- return (error);
-}
-
-SYSINIT(dtnfsclient_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
- dtnfsclient_load, NULL);
-SYSUNINIT(dtnfsclient_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
- dtnfsclient_unload, NULL);
-
-DEV_MODULE(dtnfsclient, dtnfsclient_modevent, NULL);
-MODULE_VERSION(dtnfsclient, 1);
-MODULE_DEPEND(dtnfsclient, dtrace, 1, 1, 1);
-MODULE_DEPEND(dtnfsclient, opensolaris, 1, 1, 1);
-MODULE_DEPEND(dtnfsclient, oldnfs, 1, 1, 1);
diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c
deleted file mode 100644
index f88e47f..0000000
--- a/sys/nfsclient/nfs_krpc.c
+++ /dev/null
@@ -1,887 +0,0 @@
-/*-
- * Copyright (c) 1989, 1991, 1993, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Socket operations for use by nfs
- */
-
-#include "opt_inet6.h"
-#include "opt_kgssapi.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/mount.h>
-#include <sys/mutex.h>
-#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/syscallsubr.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <sys/vnode.h>
-
-#include <rpc/rpc.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfs/xdr_subs.h>
-#include <nfsclient/nfsm_subs.h>
-#include <nfsclient/nfsmount.h>
-#include <nfsclient/nfsnode.h>
-
-#ifdef KDTRACE_HOOKS
-#include <sys/dtrace_bsd.h>
-
-dtrace_nfsclient_nfs23_start_probe_func_t
- dtrace_nfsclient_nfs23_start_probe;
-
-dtrace_nfsclient_nfs23_done_probe_func_t
- dtrace_nfsclient_nfs23_done_probe;
-
-/*
- * Registered probes by RPC type.
- */
-uint32_t nfsclient_nfs2_start_probes[NFS_NPROCS];
-uint32_t nfsclient_nfs2_done_probes[NFS_NPROCS];
-
-uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS];
-uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS];
-#endif
-
-static int nfs_bufpackets = 4;
-static int nfs_reconnects;
-static int nfs3_jukebox_delay = 10;
-static int nfs_skip_wcc_data_onerr = 1;
-static int fake_wchan;
-
-SYSCTL_DECL(_vfs_oldnfs);
-
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, bufpackets, CTLFLAG_RW, &nfs_bufpackets, 0,
- "Buffer reservation size 2 < x < 64");
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, reconnects, CTLFLAG_RD, &nfs_reconnects, 0,
- "Number of times the nfs client has had to reconnect");
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs3_jukebox_delay, CTLFLAG_RW,
- &nfs3_jukebox_delay, 0,
- "Number of seconds to delay a retry after receiving EJUKEBOX");
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, skip_wcc_data_onerr, CTLFLAG_RW,
- &nfs_skip_wcc_data_onerr, 0,
- "Disable weak cache consistency checking when server returns an error");
-
-static void nfs_down(struct nfsmount *, struct thread *, const char *,
- int, int);
-static void nfs_up(struct nfsmount *, struct thread *, const char *,
- int, int);
-static int nfs_msg(struct thread *, const char *, const char *, int);
-
-extern int nfsv2_procid[];
-
-struct nfs_cached_auth {
- int ca_refs; /* refcount, including 1 from the cache */
- uid_t ca_uid; /* uid that corresponds to this auth */
- AUTH *ca_auth; /* RPC auth handle */
-};
-
-/*
- * RTT estimator
- */
-
-static enum nfs_rto_timer_t nfs_proct[NFS_NPROCS] = {
- NFS_DEFAULT_TIMER, /* NULL */
- NFS_GETATTR_TIMER, /* GETATTR */
- NFS_DEFAULT_TIMER, /* SETATTR */
- NFS_LOOKUP_TIMER, /* LOOKUP */
- NFS_GETATTR_TIMER, /* ACCESS */
- NFS_READ_TIMER, /* READLINK */
- NFS_READ_TIMER, /* READ */
- NFS_WRITE_TIMER, /* WRITE */
- NFS_DEFAULT_TIMER, /* CREATE */
- NFS_DEFAULT_TIMER, /* MKDIR */
- NFS_DEFAULT_TIMER, /* SYMLINK */
- NFS_DEFAULT_TIMER, /* MKNOD */
- NFS_DEFAULT_TIMER, /* REMOVE */
- NFS_DEFAULT_TIMER, /* RMDIR */
- NFS_DEFAULT_TIMER, /* RENAME */
- NFS_DEFAULT_TIMER, /* LINK */
- NFS_READ_TIMER, /* READDIR */
- NFS_READ_TIMER, /* READDIRPLUS */
- NFS_DEFAULT_TIMER, /* FSSTAT */
- NFS_DEFAULT_TIMER, /* FSINFO */
- NFS_DEFAULT_TIMER, /* PATHCONF */
- NFS_DEFAULT_TIMER, /* COMMIT */
- NFS_DEFAULT_TIMER, /* NOOP */
-};
-
-/*
- * Choose the correct RTT timer for this NFS procedure.
- */
-static inline enum nfs_rto_timer_t
-nfs_rto_timer(u_int32_t procnum)
-{
-
- return (nfs_proct[procnum]);
-}
-
-/*
- * Initialize the RTT estimator state for a new mount point.
- */
-static void
-nfs_init_rtt(struct nfsmount *nmp)
-{
- int i;
-
- for (i = 0; i < NFS_MAX_TIMER; i++) {
- nmp->nm_timers[i].rt_srtt = hz;
- nmp->nm_timers[i].rt_deviate = 0;
- nmp->nm_timers[i].rt_rtxcur = hz;
- }
-}
-
-/*
- * Initialize sockets and congestion for a new NFS connection.
- * We do not free the sockaddr if error.
- */
-int
-nfs_connect(struct nfsmount *nmp)
-{
- int rcvreserve, sndreserve;
- int pktscale;
- struct sockaddr *saddr;
- struct ucred *origcred;
- struct thread *td = curthread;
- CLIENT *client;
- struct netconfig *nconf;
- rpcvers_t vers;
- int one = 1, retries;
- struct timeval timo;
-
- /*
- * We need to establish the socket using the credentials of
- * the mountpoint. Some parts of this process (such as
- * sobind() and soconnect()) will use the curent thread's
- * credential instead of the socket credential. To work
- * around this, temporarily change the current thread's
- * credential to that of the mountpoint.
- *
- * XXX: It would be better to explicitly pass the correct
- * credential to sobind() and soconnect().
- */
- origcred = td->td_ucred;
- td->td_ucred = nmp->nm_mountp->mnt_cred;
- saddr = nmp->nm_nam;
-
- vers = NFS_VER2;
- if (nmp->nm_flag & NFSMNT_NFSV3)
- vers = NFS_VER3;
- else if (nmp->nm_flag & NFSMNT_NFSV4)
- vers = NFS_VER4;
- if (saddr->sa_family == AF_INET)
- if (nmp->nm_sotype == SOCK_DGRAM)
- nconf = getnetconfigent("udp");
- else
- nconf = getnetconfigent("tcp");
- else
- if (nmp->nm_sotype == SOCK_DGRAM)
- nconf = getnetconfigent("udp6");
- else
- nconf = getnetconfigent("tcp6");
-
- /*
- * Get buffer reservation size from sysctl, but impose reasonable
- * limits.
- */
- pktscale = nfs_bufpackets;
- if (pktscale < 2)
- pktscale = 2;
- if (pktscale > 64)
- pktscale = 64;
- mtx_lock(&nmp->nm_mtx);
- if (nmp->nm_sotype == SOCK_DGRAM) {
- sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale;
- rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
- NFS_MAXPKTHDR) * pktscale;
- } else if (nmp->nm_sotype == SOCK_SEQPACKET) {
- sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR) * pktscale;
- rcvreserve = (max(nmp->nm_rsize, nmp->nm_readdirsize) +
- NFS_MAXPKTHDR) * pktscale;
- } else {
- if (nmp->nm_sotype != SOCK_STREAM)
- panic("nfscon sotype");
- sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR +
- sizeof (u_int32_t)) * pktscale;
- rcvreserve = (nmp->nm_rsize + NFS_MAXPKTHDR +
- sizeof (u_int32_t)) * pktscale;
- }
- mtx_unlock(&nmp->nm_mtx);
-
- client = clnt_reconnect_create(nconf, saddr, NFS_PROG, vers,
- sndreserve, rcvreserve);
- CLNT_CONTROL(client, CLSET_WAITCHAN, "nfsreq");
- if (nmp->nm_flag & NFSMNT_INT)
- CLNT_CONTROL(client, CLSET_INTERRUPTIBLE, &one);
- if (nmp->nm_flag & NFSMNT_RESVPORT)
- CLNT_CONTROL(client, CLSET_PRIVPORT, &one);
- if ((nmp->nm_flag & NFSMNT_SOFT) != 0) {
- if (nmp->nm_sotype == SOCK_DGRAM)
- /*
- * For UDP, the large timeout for a reconnect will
- * be set to "nm_retry * nm_timeo / 2", so we only
- * want to do 2 reconnect timeout retries.
- */
- retries = 2;
- else
- retries = nmp->nm_retry;
- } else
- retries = INT_MAX;
- CLNT_CONTROL(client, CLSET_RETRIES, &retries);
-
- /*
- * For UDP, there are 2 timeouts:
- * - CLSET_RETRY_TIMEOUT sets the initial timeout for the timer
- * that does a retransmit of an RPC request using the same socket
- * and xid. This is what you normally want to do, since NFS
- * servers depend on "same xid" for their Duplicate Request Cache.
- * - timeout specified in CLNT_CALL_MBUF(), which specifies when
- * retransmits on the same socket should fail and a fresh socket
- * created. Each of these timeouts counts as one CLSET_RETRIES,
- * as set above.
- * Set the initial retransmit timeout for UDP. This timeout doesn't
- * exist for TCP and the following call just fails, which is ok.
- */
- timo.tv_sec = nmp->nm_timeo / NFS_HZ;
- timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ;
- CLNT_CONTROL(client, CLSET_RETRY_TIMEOUT, &timo);
-
- mtx_lock(&nmp->nm_mtx);
- if (nmp->nm_client) {
- /*
- * Someone else already connected.
- */
- CLNT_RELEASE(client);
- } else
- nmp->nm_client = client;
-
- /*
- * Protocols that do not require connections may be optionally left
- * unconnected for servers that reply from a port other than NFS_PORT.
- */
- if (!(nmp->nm_flag & NFSMNT_NOCONN)) {
- mtx_unlock(&nmp->nm_mtx);
- CLNT_CONTROL(client, CLSET_CONNECT, &one);
- } else
- mtx_unlock(&nmp->nm_mtx);
-
- /* Restore current thread's credentials. */
- td->td_ucred = origcred;
-
- mtx_lock(&nmp->nm_mtx);
- /* Initialize other non-zero congestion variables. */
- nfs_init_rtt(nmp);
- mtx_unlock(&nmp->nm_mtx);
- return (0);
-}
-
-/*
- * NFS disconnect. Clean up and unlink.
- */
-void
-nfs_disconnect(struct nfsmount *nmp)
-{
- CLIENT *client;
-
- mtx_lock(&nmp->nm_mtx);
- if (nmp->nm_client) {
- client = nmp->nm_client;
- nmp->nm_client = NULL;
- mtx_unlock(&nmp->nm_mtx);
- rpc_gss_secpurge_call(client);
- CLNT_CLOSE(client);
- CLNT_RELEASE(client);
- } else
- mtx_unlock(&nmp->nm_mtx);
-}
-
-void
-nfs_safedisconnect(struct nfsmount *nmp)
-{
-
- nfs_disconnect(nmp);
-}
-
-static AUTH *
-nfs_getauth(struct nfsmount *nmp, struct ucred *cred)
-{
- rpc_gss_service_t svc;
- AUTH *auth;
-
- switch (nmp->nm_secflavor) {
- case RPCSEC_GSS_KRB5:
- case RPCSEC_GSS_KRB5I:
- case RPCSEC_GSS_KRB5P:
- if (!nmp->nm_mech_oid)
- if (!rpc_gss_mech_to_oid_call("kerberosv5",
- &nmp->nm_mech_oid))
- return (NULL);
- if (nmp->nm_secflavor == RPCSEC_GSS_KRB5)
- svc = rpc_gss_svc_none;
- else if (nmp->nm_secflavor == RPCSEC_GSS_KRB5I)
- svc = rpc_gss_svc_integrity;
- else
- svc = rpc_gss_svc_privacy;
- auth = rpc_gss_secfind_call(nmp->nm_client, cred,
- nmp->nm_principal, nmp->nm_mech_oid, svc);
- if (auth)
- return (auth);
- /* fallthrough */
- case AUTH_SYS:
- default:
- return (authunix_create(cred));
-
- }
-}
-
-/*
- * Callback from the RPC code to generate up/down notifications.
- */
-
-struct nfs_feedback_arg {
- struct nfsmount *nf_mount;
- int nf_lastmsg; /* last tprintf */
- int nf_tprintfmsg;
- struct thread *nf_td;
-};
-
-static void
-nfs_feedback(int type, int proc, void *arg)
-{
- struct nfs_feedback_arg *nf = (struct nfs_feedback_arg *) arg;
- struct nfsmount *nmp = nf->nf_mount;
- time_t now;
-
- switch (type) {
- case FEEDBACK_REXMIT2:
- case FEEDBACK_RECONNECT:
- now = time_uptime;
- if (nf->nf_lastmsg + nmp->nm_tprintf_delay < now) {
- nfs_down(nmp, nf->nf_td,
- "not responding", 0, NFSSTA_TIMEO);
- nf->nf_tprintfmsg = TRUE;
- nf->nf_lastmsg = now;
- }
- break;
-
- case FEEDBACK_OK:
- nfs_up(nf->nf_mount, nf->nf_td,
- "is alive again", NFSSTA_TIMEO, nf->nf_tprintfmsg);
- break;
- }
-}
-
-/*
- * nfs_request - goes something like this
- * - fill in request struct
- * - links it into list
- * - calls nfs_send() for first transmit
- * - calls nfs_receive() to get reply
- * - break down rpc header and return with nfs reply pointed to
- * by mrep or error
- * nb: always frees up mreq mbuf list
- */
-int
-nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum,
- struct thread *td, struct ucred *cred, struct mbuf **mrp,
- struct mbuf **mdp, caddr_t *dposp)
-{
- struct mbuf *mrep;
- u_int32_t *tl;
- struct nfsmount *nmp;
- struct mbuf *md;
- time_t waituntil;
- caddr_t dpos;
- int error = 0, timeo;
- AUTH *auth = NULL;
- enum nfs_rto_timer_t timer;
- struct nfs_feedback_arg nf;
- struct rpc_callextra ext;
- enum clnt_stat stat;
- struct timeval timo;
-
- /* Reject requests while attempting a forced unmount. */
- if (vp->v_mount->mnt_kern_flag & MNTK_UNMOUNTF) {
- m_freem(mreq);
- return (ESTALE);
- }
- nmp = VFSTONFS(vp->v_mount);
- bzero(&nf, sizeof(struct nfs_feedback_arg));
- nf.nf_mount = nmp;
- nf.nf_td = td;
- nf.nf_lastmsg = time_uptime -
- ((nmp->nm_tprintf_delay) - (nmp->nm_tprintf_initial_delay));
-
- /*
- * XXX if not already connected call nfs_connect now. Longer
- * term, change nfs_mount to call nfs_connect unconditionally
- * and let clnt_reconnect_create handle reconnects.
- */
- if (!nmp->nm_client)
- nfs_connect(nmp);
-
- auth = nfs_getauth(nmp, cred);
- if (!auth) {
- m_freem(mreq);
- return (EACCES);
- }
- bzero(&ext, sizeof(ext));
- ext.rc_auth = auth;
-
- ext.rc_feedback = nfs_feedback;
- ext.rc_feedback_arg = &nf;
-
- /*
- * Use a conservative timeout for RPCs other than getattr,
- * lookup, read or write. The justification for doing "other"
- * this way is that these RPCs happen so infrequently that
- * timer est. would probably be stale. Also, since many of
- * these RPCs are non-idempotent, a conservative timeout is
- * desired.
- */
- timer = nfs_rto_timer(procnum);
- if (timer != NFS_DEFAULT_TIMER)
- ext.rc_timers = &nmp->nm_timers[timer - 1];
- else
- ext.rc_timers = NULL;
-
-#ifdef KDTRACE_HOOKS
- if (dtrace_nfsclient_nfs23_start_probe != NULL) {
- uint32_t probe_id;
- int probe_procnum;
-
- if (nmp->nm_flag & NFSMNT_NFSV3) {
- probe_id = nfsclient_nfs3_start_probes[procnum];
- probe_procnum = procnum;
- } else {
- probe_id = nfsclient_nfs2_start_probes[procnum];
- probe_procnum = nfsv2_procid[procnum];
- }
- if (probe_id != 0)
- (dtrace_nfsclient_nfs23_start_probe)(probe_id, vp,
- mreq, cred, probe_procnum);
- }
-#endif
-
- nfsstats.rpcrequests++;
-tryagain:
- /*
- * This timeout specifies when a new socket should be created,
- * along with new xid values. For UDP, this should be done
- * infrequently, since retransmits of RPC requests should normally
- * use the same xid.
- */
- if (nmp->nm_sotype == SOCK_DGRAM) {
- if ((nmp->nm_flag & NFSMNT_SOFT) != 0) {
- /*
- * CLSET_RETRIES is set to 2, so this should be half
- * of the total timeout required.
- */
- timeo = nmp->nm_retry * nmp->nm_timeo / 2;
- if (timeo < 1)
- timeo = 1;
- timo.tv_sec = timeo / NFS_HZ;
- timo.tv_usec = (timeo % NFS_HZ) * 1000000 / NFS_HZ;
- } else {
- /* For UDP hard mounts, use a large value. */
- timo.tv_sec = NFS_MAXTIMEO / NFS_HZ;
- timo.tv_usec = 0;
- }
- } else {
- timo.tv_sec = nmp->nm_timeo / NFS_HZ;
- timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * 1000000 / NFS_HZ;
- }
- mrep = NULL;
- stat = CLNT_CALL_MBUF(nmp->nm_client, &ext,
- (nmp->nm_flag & NFSMNT_NFSV3) ? procnum : nfsv2_procid[procnum],
- mreq, &mrep, timo);
-
- /*
- * If there was a successful reply and a tprintf msg.
- * tprintf a response.
- */
- if (stat == RPC_SUCCESS)
- error = 0;
- else if (stat == RPC_TIMEDOUT) {
- nfsstats.rpctimeouts++;
- error = ETIMEDOUT;
- } else if (stat == RPC_VERSMISMATCH) {
- nfsstats.rpcinvalid++;
- error = EOPNOTSUPP;
- } else if (stat == RPC_PROGVERSMISMATCH) {
- nfsstats.rpcinvalid++;
- error = EPROTONOSUPPORT;
- } else if (stat == RPC_INTR) {
- error = EINTR;
- } else {
- nfsstats.rpcinvalid++;
- error = EACCES;
- }
- if (error)
- goto nfsmout;
-
- KASSERT(mrep != NULL, ("mrep shouldn't be NULL if no error\n"));
-
- /*
- * Search for any mbufs that are not a multiple of 4 bytes long
- * or with m_data not longword aligned.
- * These could cause pointer alignment problems, so copy them to
- * well aligned mbufs.
- */
- error = nfs_realign(&mrep, M_NOWAIT);
- if (error == ENOMEM) {
- m_freem(mrep);
- AUTH_DESTROY(auth);
- nfsstats.rpcinvalid++;
- return (error);
- }
-
- md = mrep;
- dpos = mtod(mrep, caddr_t);
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- if (*tl != 0) {
- error = fxdr_unsigned(int, *tl);
- if ((nmp->nm_flag & NFSMNT_NFSV3) &&
- error == NFSERR_TRYLATER) {
- m_freem(mrep);
- error = 0;
- waituntil = time_second + nfs3_jukebox_delay;
- while (time_second < waituntil)
- (void)tsleep(&fake_wchan, PSOCK, "nqnfstry",
- hz);
- goto tryagain;
- }
- /*
- * Make sure NFSERR_RETERR isn't bogusly set by a server
- * such as amd. (No actual NFS error has bit 31 set.)
- */
- error &= ~NFSERR_RETERR;
-
- /*
- * If the File Handle was stale, invalidate the lookup
- * cache, just in case.
- */
- if (error == ESTALE)
- nfs_purgecache(vp);
- /*
- * Skip wcc data on non-ENOENT NFS errors for now.
- * NetApp filers return corrupt postop attrs in the
- * wcc data for NFS err EROFS. Not sure if they could
- * return corrupt postop attrs for others errors.
- * Blocking ENOENT post-op attributes breaks negative
- * name caching, so always allow it through.
- */
- if ((nmp->nm_flag & NFSMNT_NFSV3) &&
- (!nfs_skip_wcc_data_onerr || error == ENOENT)) {
- *mrp = mrep;
- *mdp = md;
- *dposp = dpos;
- error |= NFSERR_RETERR;
- } else
- m_freem(mrep);
- goto nfsmout;
- }
-
-#ifdef KDTRACE_HOOKS
- if (dtrace_nfsclient_nfs23_done_probe != NULL) {
- uint32_t probe_id;
- int probe_procnum;
-
- if (nmp->nm_flag & NFSMNT_NFSV3) {
- probe_id = nfsclient_nfs3_done_probes[procnum];
- probe_procnum = procnum;
- } else {
- probe_id = nfsclient_nfs2_done_probes[procnum];
- probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ?
- procnum : nfsv2_procid[procnum];
- }
- if (probe_id != 0)
- (dtrace_nfsclient_nfs23_done_probe)(probe_id, vp,
- mreq, cred, probe_procnum, 0);
- }
-#endif
- m_freem(mreq);
- *mrp = mrep;
- *mdp = md;
- *dposp = dpos;
- AUTH_DESTROY(auth);
- return (0);
-
-nfsmout:
-#ifdef KDTRACE_HOOKS
- if (dtrace_nfsclient_nfs23_done_probe != NULL) {
- uint32_t probe_id;
- int probe_procnum;
-
- if (nmp->nm_flag & NFSMNT_NFSV3) {
- probe_id = nfsclient_nfs3_done_probes[procnum];
- probe_procnum = procnum;
- } else {
- probe_id = nfsclient_nfs2_done_probes[procnum];
- probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ?
- procnum : nfsv2_procid[procnum];
- }
- if (probe_id != 0)
- (dtrace_nfsclient_nfs23_done_probe)(probe_id, vp,
- mreq, cred, probe_procnum, error);
- }
-#endif
- m_freem(mreq);
- if (auth)
- AUTH_DESTROY(auth);
- return (error);
-}
-
-/*
- * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and
- * wait for all requests to complete. This is used by forced unmounts
- * to terminate any outstanding RPCs.
- */
-int
-nfs_nmcancelreqs(struct nfsmount *nmp)
-{
-
- if (nmp->nm_client)
- CLNT_CLOSE(nmp->nm_client);
- return (0);
-}
-
-/*
- * Any signal that can interrupt an NFS operation in an intr mount
- * should be added to this set. SIGSTOP and SIGKILL cannot be masked.
- */
-int nfs_sig_set[] = {
- SIGINT,
- SIGTERM,
- SIGHUP,
- SIGKILL,
- SIGQUIT
-};
-
-/*
- * Check to see if one of the signals in our subset is pending on
- * the process (in an intr mount).
- */
-static int
-nfs_sig_pending(sigset_t set)
-{
- int i;
-
- for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++)
- if (SIGISMEMBER(set, nfs_sig_set[i]))
- return (1);
- return (0);
-}
-
-/*
- * The set/restore sigmask functions are used to (temporarily) overwrite
- * the thread td_sigmask during an RPC call (for example). These are also
- * used in other places in the NFS client that might tsleep().
- */
-void
-nfs_set_sigmask(struct thread *td, sigset_t *oldset)
-{
- sigset_t newset;
- int i;
- struct proc *p;
-
- SIGFILLSET(newset);
- if (td == NULL)
- td = curthread; /* XXX */
- p = td->td_proc;
- /* Remove the NFS set of signals from newset. */
- PROC_LOCK(p);
- mtx_lock(&p->p_sigacts->ps_mtx);
- for (i = 0 ; i < sizeof(nfs_sig_set)/sizeof(int) ; i++) {
- /*
- * But make sure we leave the ones already masked
- * by the process, i.e. remove the signal from the
- * temporary signalmask only if it wasn't already
- * in p_sigmask.
- */
- if (!SIGISMEMBER(td->td_sigmask, nfs_sig_set[i]) &&
- !SIGISMEMBER(p->p_sigacts->ps_sigignore, nfs_sig_set[i]))
- SIGDELSET(newset, nfs_sig_set[i]);
- }
- mtx_unlock(&p->p_sigacts->ps_mtx);
- kern_sigprocmask(td, SIG_SETMASK, &newset, oldset,
- SIGPROCMASK_PROC_LOCKED);
- PROC_UNLOCK(p);
-}
-
-void
-nfs_restore_sigmask(struct thread *td, sigset_t *set)
-{
- if (td == NULL)
- td = curthread; /* XXX */
- kern_sigprocmask(td, SIG_SETMASK, set, NULL, 0);
-}
-
-/*
- * NFS wrapper to msleep(), that shoves a new p_sigmask and restores the
- * old one after msleep() returns.
- */
-int
-nfs_msleep(struct thread *td, void *ident, struct mtx *mtx, int priority,
- char *wmesg, int timo)
-{
- sigset_t oldset;
- int error;
- struct proc *p;
-
- if ((priority & PCATCH) == 0)
- return msleep(ident, mtx, priority, wmesg, timo);
- if (td == NULL)
- td = curthread; /* XXX */
- nfs_set_sigmask(td, &oldset);
- error = msleep(ident, mtx, priority, wmesg, timo);
- nfs_restore_sigmask(td, &oldset);
- p = td->td_proc;
- return (error);
-}
-
-/*
- * Test for a termination condition pending on the process.
- * This is used for NFSMNT_INT mounts.
- */
-int
-nfs_sigintr(struct nfsmount *nmp, struct thread *td)
-{
- struct proc *p;
- sigset_t tmpset;
-
- /* Terminate all requests while attempting a forced unmount. */
- if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
- return (EIO);
- if (!(nmp->nm_flag & NFSMNT_INT))
- return (0);
- if (td == NULL)
- return (0);
- p = td->td_proc;
- PROC_LOCK(p);
- tmpset = p->p_siglist;
- SIGSETOR(tmpset, td->td_siglist);
- SIGSETNAND(tmpset, td->td_sigmask);
- mtx_lock(&p->p_sigacts->ps_mtx);
- SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
- mtx_unlock(&p->p_sigacts->ps_mtx);
- if ((SIGNOTEMPTY(p->p_siglist) || SIGNOTEMPTY(td->td_siglist))
- && nfs_sig_pending(tmpset)) {
- PROC_UNLOCK(p);
- return (EINTR);
- }
- PROC_UNLOCK(p);
- return (0);
-}
-
-static int
-nfs_msg(struct thread *td, const char *server, const char *msg, int error)
-{
- struct proc *p;
-
- p = td ? td->td_proc : NULL;
- if (error)
- tprintf(p, LOG_INFO, "nfs server %s: %s, error %d\n", server,
- msg, error);
- else
- tprintf(p, LOG_INFO, "nfs server %s: %s\n", server, msg);
- return (0);
-}
-
-static void
-nfs_down(struct nfsmount *nmp, struct thread *td, const char *msg,
- int error, int flags)
-{
- if (nmp == NULL)
- return;
- mtx_lock(&nmp->nm_mtx);
- if ((flags & NFSSTA_TIMEO) && !(nmp->nm_state & NFSSTA_TIMEO)) {
- nmp->nm_state |= NFSSTA_TIMEO;
- mtx_unlock(&nmp->nm_mtx);
- vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
- VQ_NOTRESP, 0);
- } else
- mtx_unlock(&nmp->nm_mtx);
- mtx_lock(&nmp->nm_mtx);
- if ((flags & NFSSTA_LOCKTIMEO) &&
- !(nmp->nm_state & NFSSTA_LOCKTIMEO)) {
- nmp->nm_state |= NFSSTA_LOCKTIMEO;
- mtx_unlock(&nmp->nm_mtx);
- vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
- VQ_NOTRESPLOCK, 0);
- } else
- mtx_unlock(&nmp->nm_mtx);
- nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, error);
-}
-
-static void
-nfs_up(struct nfsmount *nmp, struct thread *td, const char *msg,
- int flags, int tprintfmsg)
-{
- if (nmp == NULL)
- return;
- if (tprintfmsg)
- nfs_msg(td, nmp->nm_mountp->mnt_stat.f_mntfromname, msg, 0);
-
- mtx_lock(&nmp->nm_mtx);
- if ((flags & NFSSTA_TIMEO) && (nmp->nm_state & NFSSTA_TIMEO)) {
- nmp->nm_state &= ~NFSSTA_TIMEO;
- mtx_unlock(&nmp->nm_mtx);
- vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
- VQ_NOTRESP, 1);
- } else
- mtx_unlock(&nmp->nm_mtx);
-
- mtx_lock(&nmp->nm_mtx);
- if ((flags & NFSSTA_LOCKTIMEO) &&
- (nmp->nm_state & NFSSTA_LOCKTIMEO)) {
- nmp->nm_state &= ~NFSSTA_LOCKTIMEO;
- mtx_unlock(&nmp->nm_mtx);
- vfs_event_signal(&nmp->nm_mountp->mnt_stat.f_fsid,
- VQ_NOTRESPLOCK, 1);
- } else
- mtx_unlock(&nmp->nm_mtx);
-}
diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c
deleted file mode 100644
index 2fb2c88..0000000
--- a/sys/nfsclient/nfs_nfsiod.c
+++ /dev/null
@@ -1,346 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/proc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/domain.h>
-#include <sys/protosw.h>
-#include <sys/namei.h>
-#include <sys/unistd.h>
-#include <sys/kthread.h>
-#include <sys/fcntl.h>
-#include <sys/lockf.h>
-#include <sys/mutex.h>
-#include <sys/taskqueue.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <nfs/xdr_subs.h>
-#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsm_subs.h>
-#include <nfsclient/nfsmount.h>
-#include <nfsclient/nfsnode.h>
-#include <nfs/nfs_lock.h>
-
-static MALLOC_DEFINE(M_NFSSVC, "nfsclient_srvsock", "Nfs server structure");
-
-static void nfssvc_iod(void *);
-
-static int nfs_asyncdaemon[NFS_MAXASYNCDAEMON];
-
-SYSCTL_DECL(_vfs_oldnfs);
-
-/* Maximum number of seconds a nfsiod kthread will sleep before exiting */
-static unsigned int nfs_iodmaxidle = 120;
-SYSCTL_UINT(_vfs_oldnfs, OID_AUTO, iodmaxidle, CTLFLAG_RW, &nfs_iodmaxidle, 0,
- "Max number of seconds an nfsiod kthread will sleep before exiting");
-
-/* Maximum number of nfsiod kthreads */
-unsigned int nfs_iodmax = 20;
-
-/* Minimum number of nfsiod kthreads to keep as spares */
-static unsigned int nfs_iodmin = 0;
-
-static int nfs_nfsiodnew_sync(void);
-
-static int
-sysctl_iodmin(SYSCTL_HANDLER_ARGS)
-{
- int error, i;
- int newmin;
-
- newmin = nfs_iodmin;
- error = sysctl_handle_int(oidp, &newmin, 0, req);
- if (error || (req->newptr == NULL))
- return (error);
- mtx_lock(&nfs_iod_mtx);
- if (newmin > nfs_iodmax) {
- error = EINVAL;
- goto out;
- }
- nfs_iodmin = newmin;
- if (nfs_numasync >= nfs_iodmin)
- goto out;
- /*
- * If the current number of nfsiod is lower
- * than the new minimum, create some more.
- */
- for (i = nfs_iodmin - nfs_numasync; i > 0; i--)
- nfs_nfsiodnew_sync();
-out:
- mtx_unlock(&nfs_iod_mtx);
- return (0);
-}
-SYSCTL_PROC(_vfs_oldnfs, OID_AUTO, iodmin, CTLTYPE_UINT | CTLFLAG_RW, 0,
- sizeof (nfs_iodmin), sysctl_iodmin, "IU",
- "Min number of nfsiod kthreads to keep as spares");
-
-
-static int
-sysctl_iodmax(SYSCTL_HANDLER_ARGS)
-{
- int error, i;
- int iod, newmax;
-
- newmax = nfs_iodmax;
- error = sysctl_handle_int(oidp, &newmax, 0, req);
- if (error || (req->newptr == NULL))
- return (error);
- if (newmax > NFS_MAXASYNCDAEMON)
- return (EINVAL);
- mtx_lock(&nfs_iod_mtx);
- nfs_iodmax = newmax;
- if (nfs_numasync <= nfs_iodmax)
- goto out;
- /*
- * If there are some asleep nfsiods that should
- * exit, wakeup() them so that they check nfs_iodmax
- * and exit. Those who are active will exit as
- * soon as they finish I/O.
- */
- iod = nfs_numasync - 1;
- for (i = 0; i < nfs_numasync - nfs_iodmax; i++) {
- if (nfs_iodwant[iod] == NFSIOD_AVAILABLE)
- wakeup(&nfs_iodwant[iod]);
- iod--;
- }
-out:
- mtx_unlock(&nfs_iod_mtx);
- return (0);
-}
-SYSCTL_PROC(_vfs_oldnfs, OID_AUTO, iodmax, CTLTYPE_UINT | CTLFLAG_RW, 0,
- sizeof (nfs_iodmax), sysctl_iodmax, "IU",
- "Max number of nfsiod kthreads");
-
-static int
-nfs_nfsiodnew_sync(void)
-{
- int error, i;
-
- mtx_assert(&nfs_iod_mtx, MA_OWNED);
- for (i = 0; i < nfs_iodmax; i++) {
- if (nfs_asyncdaemon[i] == 0) {
- nfs_asyncdaemon[i] = 1;
- break;
- }
- }
- if (i == nfs_iodmax)
- return (0);
- mtx_unlock(&nfs_iod_mtx);
- error = kproc_create(nfssvc_iod, nfs_asyncdaemon + i, NULL,
- RFHIGHPID, 0, "nfsiod %d", i);
- mtx_lock(&nfs_iod_mtx);
- if (error == 0) {
- nfs_numasync++;
- nfs_iodwant[i] = NFSIOD_AVAILABLE;
- } else
- nfs_asyncdaemon[i] = 0;
- return (error);
-}
-
-void
-nfs_nfsiodnew_tq(__unused void *arg, int pending)
-{
-
- mtx_lock(&nfs_iod_mtx);
- while (pending > 0) {
- pending--;
- nfs_nfsiodnew_sync();
- }
- mtx_unlock(&nfs_iod_mtx);
-}
-
-void
-nfs_nfsiodnew(void)
-{
-
- mtx_assert(&nfs_iod_mtx, MA_OWNED);
- taskqueue_enqueue(taskqueue_thread, &nfs_nfsiodnew_task);
-}
-
-static void
-nfsiod_setup(void *dummy)
-{
- int error;
-
- TUNABLE_INT_FETCH("vfs.oldnfs.iodmin", &nfs_iodmin);
- mtx_lock(&nfs_iod_mtx);
- /* Silently limit the start number of nfsiod's */
- if (nfs_iodmin > NFS_MAXASYNCDAEMON)
- nfs_iodmin = NFS_MAXASYNCDAEMON;
-
- while (nfs_numasync < nfs_iodmin) {
- error = nfs_nfsiodnew_sync();
- if (error == -1)
- panic("nfsiod_setup: nfs_nfsiodnew failed");
- }
- mtx_unlock(&nfs_iod_mtx);
-}
-SYSINIT(nfsiod, SI_SUB_KTHREAD_IDLE, SI_ORDER_ANY, nfsiod_setup, NULL);
-
-static int nfs_defect = 0;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, defect, CTLFLAG_RW, &nfs_defect, 0,
- "Allow nfsiods to migrate serving different mounts");
-
-/*
- * Asynchronous I/O daemons for client nfs.
- * They do read-ahead and write-behind operations on the block I/O cache.
- * Returns if we hit the timeout defined by the iodmaxidle sysctl.
- */
-static void
-nfssvc_iod(void *instance)
-{
- struct buf *bp;
- struct nfsmount *nmp;
- int myiod, timo;
- int error = 0;
-
- mtx_lock(&nfs_iod_mtx);
- myiod = (int *)instance - nfs_asyncdaemon;
- /*
- * Main loop
- */
- for (;;) {
- while (((nmp = nfs_iodmount[myiod]) == NULL)
- || !TAILQ_FIRST(&nmp->nm_bufq)) {
- if (myiod >= nfs_iodmax)
- goto finish;
- if (nmp)
- nmp->nm_bufqiods--;
- if (nfs_iodwant[myiod] == NFSIOD_NOT_AVAILABLE)
- nfs_iodwant[myiod] = NFSIOD_AVAILABLE;
- nfs_iodmount[myiod] = NULL;
- /*
- * Always keep at least nfs_iodmin kthreads.
- */
- timo = (myiod < nfs_iodmin) ? 0 : nfs_iodmaxidle * hz;
- error = msleep(&nfs_iodwant[myiod], &nfs_iod_mtx, PWAIT | PCATCH,
- "-", timo);
- if (error) {
- nmp = nfs_iodmount[myiod];
- /*
- * Rechecking the nm_bufq closes a rare race where the
- * nfsiod is woken up at the exact time the idle timeout
- * fires
- */
- if (nmp && TAILQ_FIRST(&nmp->nm_bufq))
- error = 0;
- break;
- }
- }
- if (error)
- break;
- while ((bp = TAILQ_FIRST(&nmp->nm_bufq)) != NULL) {
- int giant_locked = 0;
-
- /* Take one off the front of the list */
- TAILQ_REMOVE(&nmp->nm_bufq, bp, b_freelist);
- nmp->nm_bufqlen--;
- if (nmp->nm_bufqwant && nmp->nm_bufqlen <= nfs_numasync) {
- nmp->nm_bufqwant = 0;
- wakeup(&nmp->nm_bufq);
- }
- mtx_unlock(&nfs_iod_mtx);
- if (NFS_ISV4(bp->b_vp)) {
- giant_locked = 1;
- mtx_lock(&Giant);
- }
- if (bp->b_flags & B_DIRECT) {
- KASSERT((bp->b_iocmd == BIO_WRITE), ("nfscvs_iod: BIO_WRITE not set"));
- (void)nfs_doio_directwrite(bp);
- } else {
- if (bp->b_iocmd == BIO_READ)
- (void) nfs_doio(bp->b_vp, bp, bp->b_rcred, NULL);
- else
- (void) nfs_doio(bp->b_vp, bp, bp->b_wcred, NULL);
- }
- if (giant_locked)
- mtx_unlock(&Giant);
- mtx_lock(&nfs_iod_mtx);
- /*
- * Make sure the nmp hasn't been dismounted as soon as
- * nfs_doio() completes for the last buffer.
- */
- nmp = nfs_iodmount[myiod];
- if (nmp == NULL)
- break;
-
- /*
- * If there are more than one iod on this mount, then defect
- * so that the iods can be shared out fairly between the mounts
- */
- if (nfs_defect && nmp->nm_bufqiods > 1) {
- NFS_DPF(ASYNCIO,
- ("nfssvc_iod: iod %d defecting from mount %p\n",
- myiod, nmp));
- nfs_iodmount[myiod] = NULL;
- nmp->nm_bufqiods--;
- break;
- }
- }
- }
-finish:
- nfs_asyncdaemon[myiod] = 0;
- if (nmp)
- nmp->nm_bufqiods--;
- nfs_iodwant[myiod] = NFSIOD_NOT_AVAILABLE;
- nfs_iodmount[myiod] = NULL;
- /* Someone may be waiting for the last nfsiod to terminate. */
- if (--nfs_numasync == 0)
- wakeup(&nfs_numasync);
- mtx_unlock(&nfs_iod_mtx);
- if ((error == 0) || (error == EWOULDBLOCK))
- kproc_exit(0);
- /* Abnormal termination */
- kproc_exit(1);
-}
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
deleted file mode 100644
index cee4343..0000000
--- a/sys/nfsclient/nfs_node.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_node.c 8.6 (Berkeley) 5/22/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/fcntl.h>
-#include <sys/fnv_hash.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/mount.h>
-#include <sys/namei.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
-#include <sys/vnode.h>
-
-#include <vm/uma.h>
-
-#include <nfs/nfsproto.h>
-#include <nfs/nfs_lock.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsnode.h>
-#include <nfsclient/nfsmount.h>
-
-static uma_zone_t nfsnode_zone;
-
-static void nfs_freesillyrename(void *arg, __unused int pending);
-
-#define TRUE 1
-#define FALSE 0
-
-void
-nfs_nhinit(void)
-{
-
- nfsnode_zone = uma_zcreate("NFSNODE", sizeof(struct nfsnode), NULL,
- NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
-}
-
-void
-nfs_nhuninit(void)
-{
- uma_zdestroy(nfsnode_zone);
-}
-
-struct nfs_vncmp {
- int fhsize;
- void *fh;
-};
-
-static int
-nfs_vncmpf(struct vnode *vp, void *arg)
-{
- struct nfs_vncmp *a;
- struct nfsnode *np;
-
- a = arg;
- np = VTONFS(vp);
- return (bcmp(a->fh, np->n_fhp, a->fhsize));
-}
-
-/*
- * Look up a vnode/nfsnode by file handle.
- * Callers must check for mount points!!
- * In all cases, a pointer to a
- * nfsnode structure is returned.
- */
-int
-nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int flags)
-{
- struct thread *td = curthread; /* XXX */
- struct nfsnode *np;
- struct vnode *vp;
- struct vnode *nvp;
- int error;
- u_int hash;
- struct nfsmount *nmp;
- struct nfs_vncmp ncmp;
-
- nmp = VFSTONFS(mntp);
- *npp = NULL;
-
- hash = fnv_32_buf(fhp->fh_bytes, fhsize, FNV1_32_INIT);
- ncmp.fhsize = fhsize;
- ncmp.fh = fhp;
-
- error = vfs_hash_get(mntp, hash, flags,
- td, &nvp, nfs_vncmpf, &ncmp);
- if (error)
- return (error);
- if (nvp != NULL) {
- *npp = VTONFS(nvp);
- return (0);
- }
- np = uma_zalloc(nfsnode_zone, M_WAITOK | M_ZERO);
-
- error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp);
- if (error) {
- uma_zfree(nfsnode_zone, np);
- return (error);
- }
- vp = nvp;
- vp->v_bufobj.bo_ops = &buf_ops_nfs;
- vp->v_data = np;
- np->n_vnode = vp;
- /*
- * Initialize the mutex even if the vnode is going to be a loser.
- * This simplifies the logic in reclaim, which can then unconditionally
- * destroy the mutex (in the case of the loser, or if hash_insert happened
- * to return an error no special casing is needed).
- */
- mtx_init(&np->n_mtx, "NFSnode lock", NULL, MTX_DEF);
- /*
- * NFS supports recursive and shared locking.
- */
- lockmgr(vp->v_vnlock, LK_EXCLUSIVE | LK_NOWITNESS, NULL);
- VN_LOCK_AREC(vp);
- VN_LOCK_ASHARE(vp);
- if (fhsize > NFS_SMALLFH) {
- np->n_fhp = malloc(fhsize, M_NFSBIGFH, M_WAITOK);
- } else
- np->n_fhp = &np->n_fh;
- bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
- np->n_fhsize = fhsize;
- error = insmntque(vp, mntp);
- if (error != 0) {
- *npp = NULL;
- if (np->n_fhsize > NFS_SMALLFH) {
- free((caddr_t)np->n_fhp, M_NFSBIGFH);
- }
- mtx_destroy(&np->n_mtx);
- uma_zfree(nfsnode_zone, np);
- return (error);
- }
- error = vfs_hash_insert(vp, hash, flags,
- td, &nvp, nfs_vncmpf, &ncmp);
- if (error)
- return (error);
- if (nvp != NULL) {
- *npp = VTONFS(nvp);
- /* vfs_hash_insert() vput()'s the losing vnode */
- return (0);
- }
- *npp = np;
-
- return (0);
-}
-
-/*
- * Do the vrele(sp->s_dvp) as a separate task in order to avoid a
- * deadlock because of a LOR when vrele() locks the directory vnode.
- */
-static void
-nfs_freesillyrename(void *arg, __unused int pending)
-{
- struct sillyrename *sp;
-
- sp = arg;
- vrele(sp->s_dvp);
- free(sp, M_NFSREQ);
-}
-
-int
-nfs_inactive(struct vop_inactive_args *ap)
-{
- struct nfsnode *np;
- struct sillyrename *sp;
- struct thread *td = curthread; /* XXX */
-
- np = VTONFS(ap->a_vp);
- mtx_lock(&np->n_mtx);
- if (ap->a_vp->v_type != VDIR) {
- sp = np->n_sillyrename;
- np->n_sillyrename = NULL;
- } else
- sp = NULL;
- if (sp) {
- mtx_unlock(&np->n_mtx);
- (void)nfs_vinvalbuf(ap->a_vp, 0, td, 1);
- /*
- * Remove the silly file that was rename'd earlier
- */
- (sp->s_removeit)(sp);
- crfree(sp->s_cred);
- TASK_INIT(&sp->s_task, 0, nfs_freesillyrename, sp);
- taskqueue_enqueue(taskqueue_thread, &sp->s_task);
- mtx_lock(&np->n_mtx);
- }
- np->n_flag &= NMODIFIED;
- mtx_unlock(&np->n_mtx);
- return (0);
-}
-
-/*
- * Reclaim an nfsnode so that it can be used for other purposes.
- */
-int
-nfs_reclaim(struct vop_reclaim_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct nfsdmap *dp, *dp2;
-
- /*
- * If the NLM is running, give it a chance to abort pending
- * locks.
- */
- if (nfs_reclaim_p)
- nfs_reclaim_p(ap);
-
- /*
- * Destroy the vm object and flush associated pages.
- */
- vnode_destroy_vobject(vp);
-
- vfs_hash_remove(vp);
-
- /*
- * Free up any directory cookie structures and
- * large file handle structures that might be associated with
- * this nfs node.
- */
- if (vp->v_type == VDIR) {
- dp = LIST_FIRST(&np->n_cookies);
- while (dp) {
- dp2 = dp;
- dp = LIST_NEXT(dp, ndm_list);
- free((caddr_t)dp2, M_NFSDIROFF);
- }
- }
- if (np->n_writecred != NULL)
- crfree(np->n_writecred);
- if (np->n_fhsize > NFS_SMALLFH) {
- free((caddr_t)np->n_fhp, M_NFSBIGFH);
- }
- mtx_destroy(&np->n_mtx);
- uma_zfree(nfsnode_zone, vp->v_data);
- vp->v_data = NULL;
- return (0);
-}
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
deleted file mode 100644
index d4fd5eb..0000000
--- a/sys/nfsclient/nfs_subs.c
+++ /dev/null
@@ -1,1140 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * These functions support the macros and help fiddle mbuf chains for
- * the nfs op functions. They do things like create the rpc header and
- * copy data between mbuf chains and uio lists.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/malloc.h>
-#include <sys/rwlock.h>
-#include <sys/sysent.h>
-#include <sys/syscall.h>
-#include <sys/sysproto.h>
-#include <sys/taskqueue.h>
-
-#include <vm/vm.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-#include <vm/uma.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsnode.h>
-#include <nfs/nfs_kdtrace.h>
-#include <nfs/xdr_subs.h>
-#include <nfsclient/nfsm_subs.h>
-#include <nfsclient/nfsmount.h>
-
-#include <netinet/in.h>
-
-/*
- * Note that stdarg.h and the ANSI style va_start macro is used for both
- * ANSI and traditional C compilers.
- */
-#include <machine/stdarg.h>
-
-#ifdef KDTRACE_HOOKS
-dtrace_nfsclient_attrcache_flush_probe_func_t
- dtrace_nfsclient_attrcache_flush_done_probe;
-uint32_t nfsclient_attrcache_flush_done_id;
-
-dtrace_nfsclient_attrcache_get_hit_probe_func_t
- dtrace_nfsclient_attrcache_get_hit_probe;
-uint32_t nfsclient_attrcache_get_hit_id;
-
-dtrace_nfsclient_attrcache_get_miss_probe_func_t
- dtrace_nfsclient_attrcache_get_miss_probe;
-uint32_t nfsclient_attrcache_get_miss_id;
-
-dtrace_nfsclient_attrcache_load_probe_func_t
- dtrace_nfsclient_attrcache_load_done_probe;
-uint32_t nfsclient_attrcache_load_done_id;
-#endif /* !KDTRACE_HOOKS */
-
-/*
- * Data items converted to xdr at startup, since they are constant
- * This is kinda hokey, but may save a little time doing byte swaps
- */
-u_int32_t nfs_xdrneg1;
-u_int32_t nfs_true, nfs_false;
-
-/* And other global data */
-static u_int32_t nfs_xid = 0;
-static enum vtype nv2tov_type[8]= {
- VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON
-};
-
-int nfs_ticks;
-int nfs_pbuf_freecnt = -1; /* start out unlimited */
-
-struct nfs_bufq nfs_bufq;
-static struct mtx nfs_xid_mtx;
-struct task nfs_nfsiodnew_task;
-
-/*
- * and the reverse mapping from generic to Version 2 procedure numbers
- */
-int nfsv2_procid[NFS_NPROCS] = {
- NFSV2PROC_NULL,
- NFSV2PROC_GETATTR,
- NFSV2PROC_SETATTR,
- NFSV2PROC_LOOKUP,
- NFSV2PROC_NOOP,
- NFSV2PROC_READLINK,
- NFSV2PROC_READ,
- NFSV2PROC_WRITE,
- NFSV2PROC_CREATE,
- NFSV2PROC_MKDIR,
- NFSV2PROC_SYMLINK,
- NFSV2PROC_CREATE,
- NFSV2PROC_REMOVE,
- NFSV2PROC_RMDIR,
- NFSV2PROC_RENAME,
- NFSV2PROC_LINK,
- NFSV2PROC_READDIR,
- NFSV2PROC_NOOP,
- NFSV2PROC_STATFS,
- NFSV2PROC_NOOP,
- NFSV2PROC_NOOP,
- NFSV2PROC_NOOP,
- NFSV2PROC_NOOP,
-};
-
-LIST_HEAD(nfsnodehashhead, nfsnode);
-
-u_int32_t
-nfs_xid_gen(void)
-{
- uint32_t xid;
-
- mtx_lock(&nfs_xid_mtx);
-
- /* Get a pretty random xid to start with */
- if (!nfs_xid)
- nfs_xid = random();
- /*
- * Skip zero xid if it should ever happen.
- */
- if (++nfs_xid == 0)
- nfs_xid++;
- xid = nfs_xid;
- mtx_unlock(&nfs_xid_mtx);
- return xid;
-}
-
-/*
- * copies a uio scatter/gather list to an mbuf chain.
- * NOTE: can ony handle iovcnt == 1
- */
-int
-nfsm_uiotombuf(struct uio *uiop, struct mbuf **mq, int siz, caddr_t *bpos)
-{
- char *uiocp;
- struct mbuf *mp, *mp2;
- int xfer, left, mlen;
- int uiosiz, clflg, rem;
- char *cp;
-
- KASSERT(uiop->uio_iovcnt == 1, ("nfsm_uiotombuf: iovcnt != 1"));
-
- if (siz > MLEN) /* or should it >= MCLBYTES ?? */
- clflg = 1;
- else
- clflg = 0;
- rem = nfsm_rndup(siz)-siz;
- mp = mp2 = *mq;
- while (siz > 0) {
- left = uiop->uio_iov->iov_len;
- uiocp = uiop->uio_iov->iov_base;
- if (left > siz)
- left = siz;
- uiosiz = left;
- while (left > 0) {
- mlen = M_TRAILINGSPACE(mp);
- if (mlen == 0) {
- if (clflg)
- mp = m_getcl(M_WAITOK, MT_DATA, 0);
- else
- mp = m_get(M_WAITOK, MT_DATA);
- mp2->m_next = mp;
- mp2 = mp;
- mlen = M_TRAILINGSPACE(mp);
- }
- xfer = (left > mlen) ? mlen : left;
-#ifdef notdef
- /* Not Yet.. */
- if (uiop->uio_iov->iov_op != NULL)
- (*(uiop->uio_iov->iov_op))
- (uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
- else
-#endif
- if (uiop->uio_segflg == UIO_SYSSPACE)
- bcopy(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
- else
- copyin(uiocp, mtod(mp, caddr_t)+mp->m_len, xfer);
- mp->m_len += xfer;
- left -= xfer;
- uiocp += xfer;
- uiop->uio_offset += xfer;
- uiop->uio_resid -= xfer;
- }
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + uiosiz;
- uiop->uio_iov->iov_len -= uiosiz;
- siz -= uiosiz;
- }
- if (rem > 0) {
- if (rem > M_TRAILINGSPACE(mp)) {
- mp = m_get(M_WAITOK, MT_DATA);
- mp2->m_next = mp;
- }
- cp = mtod(mp, caddr_t)+mp->m_len;
- for (left = 0; left < rem; left++)
- *cp++ = '\0';
- mp->m_len += rem;
- *bpos = cp;
- } else
- *bpos = mtod(mp, caddr_t)+mp->m_len;
- *mq = mp;
- return (0);
-}
-
-/*
- * Copy a string into mbufs for the hard cases...
- */
-int
-nfsm_strtmbuf(struct mbuf **mb, char **bpos, const char *cp, long siz)
-{
- struct mbuf *m1 = NULL, *m2;
- long left, xfer, len, tlen;
- u_int32_t *tl;
- int putsize;
-
- putsize = 1;
- m2 = *mb;
- left = M_TRAILINGSPACE(m2);
- if (left > 0) {
- tl = ((u_int32_t *)(*bpos));
- *tl++ = txdr_unsigned(siz);
- putsize = 0;
- left -= NFSX_UNSIGNED;
- m2->m_len += NFSX_UNSIGNED;
- if (left > 0) {
- bcopy(cp, (caddr_t) tl, left);
- siz -= left;
- cp += left;
- m2->m_len += left;
- left = 0;
- }
- }
- /* Loop around adding mbufs */
- while (siz > 0) {
- if (siz > MLEN) {
- m1 = m_getcl(M_WAITOK, MT_DATA, 0);
- m1->m_len = MCLBYTES;
- } else {
- m1 = m_get(M_WAITOK, MT_DATA);
- m1->m_len = MLEN;
- }
- m2->m_next = m1;
- m2 = m1;
- tl = mtod(m1, u_int32_t *);
- tlen = 0;
- if (putsize) {
- *tl++ = txdr_unsigned(siz);
- m1->m_len -= NFSX_UNSIGNED;
- tlen = NFSX_UNSIGNED;
- putsize = 0;
- }
- if (siz < m1->m_len) {
- len = nfsm_rndup(siz);
- xfer = siz;
- if (xfer < len)
- *(tl+(xfer>>2)) = 0;
- } else {
- xfer = len = m1->m_len;
- }
- bcopy(cp, (caddr_t) tl, xfer);
- m1->m_len = len+tlen;
- siz -= xfer;
- cp += xfer;
- }
- *mb = m1;
- *bpos = mtod(m1, caddr_t)+m1->m_len;
- return (0);
-}
-
-/*
- * Called once to initialize data structures...
- */
-int
-nfs_init(struct vfsconf *vfsp)
-{
- int i;
-
- nfsmount_zone = uma_zcreate("NFSMOUNT", sizeof(struct nfsmount),
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
- nfs_true = txdr_unsigned(TRUE);
- nfs_false = txdr_unsigned(FALSE);
- nfs_xdrneg1 = txdr_unsigned(-1);
- nfs_ticks = (hz * NFS_TICKINTVL + 500) / 1000;
- if (nfs_ticks < 1)
- nfs_ticks = 1;
- /* Ensure async daemons disabled */
- for (i = 0; i < NFS_MAXASYNCDAEMON; i++) {
- nfs_iodwant[i] = NFSIOD_NOT_AVAILABLE;
- nfs_iodmount[i] = NULL;
- }
- nfs_nhinit(); /* Init the nfsnode table */
-
- /*
- * Initialize reply list and start timer
- */
- mtx_init(&nfs_iod_mtx, "NFS iod lock", NULL, MTX_DEF);
- mtx_init(&nfs_xid_mtx, "NFS xid lock", NULL, MTX_DEF);
- TASK_INIT(&nfs_nfsiodnew_task, 0, nfs_nfsiodnew_tq, NULL);
-
- nfs_pbuf_freecnt = nswbuf / 2 + 1;
-
- return (0);
-}
-
-int
-nfs_uninit(struct vfsconf *vfsp)
-{
- int i;
-
- /*
- * Tell all nfsiod processes to exit. Clear nfs_iodmax, and wakeup
- * any sleeping nfsiods so they check nfs_iodmax and exit.
- * Drain nfsiodnew task before we wait for them to finish.
- */
- mtx_lock(&nfs_iod_mtx);
- nfs_iodmax = 0;
- mtx_unlock(&nfs_iod_mtx);
- taskqueue_drain(taskqueue_thread, &nfs_nfsiodnew_task);
- mtx_lock(&nfs_iod_mtx);
- for (i = 0; i < nfs_numasync; i++)
- if (nfs_iodwant[i] == NFSIOD_AVAILABLE)
- wakeup(&nfs_iodwant[i]);
- /* The last nfsiod to exit will wake us up when nfs_numasync hits 0 */
- while (nfs_numasync)
- msleep(&nfs_numasync, &nfs_iod_mtx, PWAIT, "ioddie", 0);
- mtx_unlock(&nfs_iod_mtx);
- nfs_nhuninit();
- uma_zdestroy(nfsmount_zone);
- return (0);
-}
-
-void
-nfs_dircookie_lock(struct nfsnode *np)
-{
- mtx_lock(&np->n_mtx);
- while (np->n_flag & NDIRCOOKIELK)
- (void) msleep(&np->n_flag, &np->n_mtx, PZERO, "nfsdirlk", 0);
- np->n_flag |= NDIRCOOKIELK;
- mtx_unlock(&np->n_mtx);
-}
-
-void
-nfs_dircookie_unlock(struct nfsnode *np)
-{
- mtx_lock(&np->n_mtx);
- np->n_flag &= ~NDIRCOOKIELK;
- wakeup(&np->n_flag);
- mtx_unlock(&np->n_mtx);
-}
-
-int
-nfs_upgrade_vnlock(struct vnode *vp)
-{
- int old_lock;
-
- ASSERT_VOP_LOCKED(vp, "nfs_upgrade_vnlock");
- old_lock = VOP_ISLOCKED(vp);
- if (old_lock != LK_EXCLUSIVE) {
- KASSERT(old_lock == LK_SHARED,
- ("nfs_upgrade_vnlock: wrong old_lock %d", old_lock));
- /* Upgrade to exclusive lock, this might block */
- vn_lock(vp, LK_UPGRADE | LK_RETRY);
- }
- return (old_lock);
-}
-
-void
-nfs_downgrade_vnlock(struct vnode *vp, int old_lock)
-{
- if (old_lock != LK_EXCLUSIVE) {
- KASSERT(old_lock == LK_SHARED, ("wrong old_lock %d", old_lock));
- /* Downgrade from exclusive lock. */
- vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
- }
-}
-
-void
-nfs_printf(const char *fmt, ...)
-{
- va_list ap;
-
- mtx_lock(&Giant);
- va_start(ap, fmt);
- vprintf(fmt, ap);
- va_end(ap);
- mtx_unlock(&Giant);
-}
-
-/*
- * Attribute cache routines.
- * nfs_loadattrcache() - loads or updates the cache contents from attributes
- * that are on the mbuf list
- * nfs_getattrcache() - returns valid attributes if found in cache, returns
- * error otherwise
- */
-
-/*
- * Load the attribute cache (that lives in the nfsnode entry) with
- * the values on the mbuf list and
- * Iff vap not NULL
- * copy the attributes to *vaper
- */
-int
-nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
- struct vattr *vaper, int dontshrink)
-{
- struct vnode *vp = *vpp;
- struct vattr *vap;
- struct nfs_fattr *fp;
- struct nfsnode *np = NULL;
- int32_t t1;
- caddr_t cp2;
- int rdev;
- struct mbuf *md;
- enum vtype vtyp;
- u_short vmode;
- struct timespec mtime, mtime_save;
- int v3 = NFS_ISV3(vp);
- int error = 0;
- u_quad_t nsize;
- int setnsize;
-
- md = *mdp;
- t1 = (mtod(md, caddr_t) + md->m_len) - *dposp;
- cp2 = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, M_WAITOK);
- if (cp2 == NULL) {
- error = EBADRPC;
- goto out;
- }
- fp = (struct nfs_fattr *)cp2;
- if (v3) {
- vtyp = nfsv3tov_type(fp->fa_type);
- vmode = fxdr_unsigned(u_short, fp->fa_mode);
- rdev = makedev(fxdr_unsigned(int, fp->fa3_rdev.specdata1),
- fxdr_unsigned(int, fp->fa3_rdev.specdata2));
- fxdr_nfsv3time(&fp->fa3_mtime, &mtime);
- } else {
- vtyp = nfsv2tov_type(fp->fa_type);
- vmode = fxdr_unsigned(u_short, fp->fa_mode);
- /*
- * XXX
- *
- * The duplicate information returned in fa_type and fa_mode
- * is an ambiguity in the NFS version 2 protocol.
- *
- * VREG should be taken literally as a regular file. If a
- * server intents to return some type information differently
- * in the upper bits of the mode field (e.g. for sockets, or
- * FIFOs), NFSv2 mandates fa_type to be VNON. Anyway, we
- * leave the examination of the mode bits even in the VREG
- * case to avoid breakage for bogus servers, but we make sure
- * that there are actually type bits set in the upper part of
- * fa_mode (and failing that, trust the va_type field).
- *
- * NFSv3 cleared the issue, and requires fa_mode to not
- * contain any type information (while also introduing sockets
- * and FIFOs for fa_type).
- */
- if (vtyp == VNON || (vtyp == VREG && (vmode & S_IFMT) != 0))
- vtyp = IFTOVT(vmode);
- rdev = fxdr_unsigned(int32_t, fp->fa2_rdev);
- fxdr_nfsv2time(&fp->fa2_mtime, &mtime);
-
- /*
- * Really ugly NFSv2 kludge.
- */
- if (vtyp == VCHR && rdev == 0xffffffff)
- vtyp = VFIFO;
- }
-
- /*
- * If v_type == VNON it is a new node, so fill in the v_type,
- * n_mtime fields. Check to see if it represents a special
- * device, and if so, check for a possible alias. Once the
- * correct vnode has been obtained, fill in the rest of the
- * information.
- */
- np = VTONFS(vp);
- mtx_lock(&np->n_mtx);
- if (vp->v_type != vtyp) {
- vp->v_type = vtyp;
- if (vp->v_type == VFIFO)
- vp->v_op = &nfs_fifoops;
- np->n_mtime = mtime;
- }
- vap = &np->n_vattr;
- vap->va_type = vtyp;
- vap->va_mode = (vmode & 07777);
- vap->va_rdev = rdev;
- mtime_save = vap->va_mtime;
- vap->va_mtime = mtime;
- vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
- if (v3) {
- vap->va_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
- vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid);
- vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid);
- vap->va_size = fxdr_hyper(&fp->fa3_size);
- vap->va_blocksize = NFS_FABLKSIZE;
- vap->va_bytes = fxdr_hyper(&fp->fa3_used);
- vap->va_fileid = fxdr_unsigned(int32_t,
- fp->fa3_fileid.nfsuquad[1]);
- fxdr_nfsv3time(&fp->fa3_atime, &vap->va_atime);
- fxdr_nfsv3time(&fp->fa3_ctime, &vap->va_ctime);
- vap->va_flags = 0;
- vap->va_filerev = 0;
- } else {
- vap->va_nlink = fxdr_unsigned(u_short, fp->fa_nlink);
- vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid);
- vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid);
- vap->va_size = fxdr_unsigned(u_int32_t, fp->fa2_size);
- vap->va_blocksize = fxdr_unsigned(int32_t, fp->fa2_blocksize);
- vap->va_bytes = (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks)
- * NFS_FABLKSIZE;
- vap->va_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid);
- fxdr_nfsv2time(&fp->fa2_atime, &vap->va_atime);
- vap->va_flags = 0;
- vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t,
- fp->fa2_ctime.nfsv2_sec);
- vap->va_ctime.tv_nsec = 0;
- vap->va_gen = fxdr_unsigned(u_int32_t, fp->fa2_ctime.nfsv2_usec);
- vap->va_filerev = 0;
- }
- np->n_attrstamp = time_second;
- setnsize = 0;
- nsize = 0;
- if (vap->va_size != np->n_size) {
- if (vap->va_type == VREG) {
- if (dontshrink && vap->va_size < np->n_size) {
- /*
- * We've been told not to shrink the file;
- * zero np->n_attrstamp to indicate that
- * the attributes are stale.
- */
- vap->va_size = np->n_size;
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- vnode_pager_setsize(vp, np->n_size);
- } else if (np->n_flag & NMODIFIED) {
- /*
- * We've modified the file: Use the larger
- * of our size, and the server's size.
- */
- if (vap->va_size < np->n_size) {
- vap->va_size = np->n_size;
- } else {
- np->n_size = vap->va_size;
- np->n_flag |= NSIZECHANGED;
- }
- vnode_pager_setsize(vp, np->n_size);
- } else if (vap->va_size < np->n_size) {
- /*
- * When shrinking the size, the call to
- * vnode_pager_setsize() cannot be done
- * with the mutex held, so delay it until
- * after the mtx_unlock call.
- */
- nsize = np->n_size = vap->va_size;
- np->n_flag |= NSIZECHANGED;
- setnsize = 1;
- } else {
- np->n_size = vap->va_size;
- np->n_flag |= NSIZECHANGED;
- vnode_pager_setsize(vp, np->n_size);
- }
- } else {
- np->n_size = vap->va_size;
- }
- }
- /*
- * The following checks are added to prevent a race between (say)
- * a READDIR+ and a WRITE.
- * READDIR+, WRITE requests sent out.
- * READDIR+ resp, WRITE resp received on client.
- * However, the WRITE resp was handled before the READDIR+ resp
- * causing the post op attrs from the write to be loaded first
- * and the attrs from the READDIR+ to be loaded later. If this
- * happens, we have stale attrs loaded into the attrcache.
- * We detect this by for the mtime moving back. We invalidate the
- * attrcache when this happens.
- */
- if (timespeccmp(&mtime_save, &vap->va_mtime, >)) {
- /* Size changed or mtime went backwards */
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- }
- if (vaper != NULL) {
- bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
- if (np->n_flag & NCHG) {
- if (np->n_flag & NACC)
- vaper->va_atime = np->n_atim;
- if (np->n_flag & NUPD)
- vaper->va_mtime = np->n_mtim;
- }
- }
-
-#ifdef KDTRACE_HOOKS
- if (np->n_attrstamp != 0)
- KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, &np->n_vattr, 0);
-#endif
- mtx_unlock(&np->n_mtx);
- if (setnsize)
- vnode_pager_setsize(vp, nsize);
-out:
-#ifdef KDTRACE_HOOKS
- if (error)
- KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, NULL, error);
-#endif
- return (error);
-}
-
-#ifdef NFS_ACDEBUG
-#include <sys/sysctl.h>
-SYSCTL_DECL(_vfs_oldnfs);
-static int nfs_acdebug;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, acdebug, CTLFLAG_RW, &nfs_acdebug, 0,
- "Toggle acdebug (attribute cache debug) flag");
-#endif
-
-/*
- * Check the time stamp
- * If the cache is valid, copy contents to *vap and return 0
- * otherwise return an error
- */
-int
-nfs_getattrcache(struct vnode *vp, struct vattr *vaper)
-{
- struct nfsnode *np;
- struct vattr *vap;
- struct nfsmount *nmp;
- int timeo;
-
- np = VTONFS(vp);
- vap = &np->n_vattr;
- nmp = VFSTONFS(vp->v_mount);
-#ifdef NFS_ACDEBUG
- mtx_lock(&Giant); /* nfs_printf() */
-#endif
- mtx_lock(&np->n_mtx);
- /* XXX n_mtime doesn't seem to be updated on a miss-and-reload */
- timeo = (time_second - np->n_mtime.tv_sec) / 10;
-
-#ifdef NFS_ACDEBUG
- if (nfs_acdebug>1)
- nfs_printf("nfs_getattrcache: initial timeo = %d\n", timeo);
-#endif
-
- if (vap->va_type == VDIR) {
- if ((np->n_flag & NMODIFIED) || timeo < nmp->nm_acdirmin)
- timeo = nmp->nm_acdirmin;
- else if (timeo > nmp->nm_acdirmax)
- timeo = nmp->nm_acdirmax;
- } else {
- if ((np->n_flag & NMODIFIED) || timeo < nmp->nm_acregmin)
- timeo = nmp->nm_acregmin;
- else if (timeo > nmp->nm_acregmax)
- timeo = nmp->nm_acregmax;
- }
-
-#ifdef NFS_ACDEBUG
- if (nfs_acdebug > 2)
- nfs_printf("acregmin %d; acregmax %d; acdirmin %d; acdirmax %d\n",
- nmp->nm_acregmin, nmp->nm_acregmax,
- nmp->nm_acdirmin, nmp->nm_acdirmax);
-
- if (nfs_acdebug)
- nfs_printf("nfs_getattrcache: age = %d; final timeo = %d\n",
- (time_second - np->n_attrstamp), timeo);
-#endif
-
- if ((time_second - np->n_attrstamp) >= timeo) {
- nfsstats.attrcache_misses++;
- mtx_unlock(&np->n_mtx);
-#ifdef NFS_ACDEBUG
- mtx_unlock(&Giant); /* nfs_printf() */
-#endif
- KDTRACE_NFS_ATTRCACHE_GET_MISS(vp);
- return (ENOENT);
- }
- nfsstats.attrcache_hits++;
- if (vap->va_size != np->n_size) {
- if (vap->va_type == VREG) {
- if (np->n_flag & NMODIFIED) {
- if (vap->va_size < np->n_size)
- vap->va_size = np->n_size;
- else
- np->n_size = vap->va_size;
- } else {
- np->n_size = vap->va_size;
- }
- vnode_pager_setsize(vp, np->n_size);
- } else {
- np->n_size = vap->va_size;
- }
- }
- bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(struct vattr));
- if (np->n_flag & NCHG) {
- if (np->n_flag & NACC)
- vaper->va_atime = np->n_atim;
- if (np->n_flag & NUPD)
- vaper->va_mtime = np->n_mtim;
- }
- mtx_unlock(&np->n_mtx);
-#ifdef NFS_ACDEBUG
- mtx_unlock(&Giant); /* nfs_printf() */
-#endif
- KDTRACE_NFS_ATTRCACHE_GET_HIT(vp, vap);
- return (0);
-}
-
-/*
- * Purge all cached information about an NFS vnode including name
- * cache entries, the attribute cache, and the access cache. This is
- * called when an NFS request for a node fails with a stale
- * filehandle.
- */
-void
-nfs_purgecache(struct vnode *vp)
-{
- struct nfsnode *np;
- int i;
-
- np = VTONFS(vp);
- cache_purge(vp);
- mtx_lock(&np->n_mtx);
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- for (i = 0; i < NFS_ACCESSCACHESIZE; i++)
- np->n_accesscache[i].stamp = 0;
- KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp);
- mtx_unlock(&np->n_mtx);
-}
-
-static nfsuint64 nfs_nullcookie = { { 0, 0 } };
-/*
- * This function finds the directory cookie that corresponds to the
- * logical byte offset given.
- */
-nfsuint64 *
-nfs_getcookie(struct nfsnode *np, off_t off, int add)
-{
- struct nfsdmap *dp, *dp2;
- int pos;
- nfsuint64 *retval = NULL;
-
- pos = (uoff_t)off / NFS_DIRBLKSIZ;
- if (pos == 0 || off < 0) {
- KASSERT(!add, ("nfs getcookie add at <= 0"));
- return (&nfs_nullcookie);
- }
- pos--;
- dp = LIST_FIRST(&np->n_cookies);
- if (!dp) {
- if (add) {
- dp = malloc(sizeof (struct nfsdmap),
- M_NFSDIROFF, M_WAITOK);
- dp->ndm_eocookie = 0;
- LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
- } else
- goto out;
- }
- while (pos >= NFSNUMCOOKIES) {
- pos -= NFSNUMCOOKIES;
- if (LIST_NEXT(dp, ndm_list)) {
- if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
- pos >= dp->ndm_eocookie)
- goto out;
- dp = LIST_NEXT(dp, ndm_list);
- } else if (add) {
- dp2 = malloc(sizeof (struct nfsdmap),
- M_NFSDIROFF, M_WAITOK);
- dp2->ndm_eocookie = 0;
- LIST_INSERT_AFTER(dp, dp2, ndm_list);
- dp = dp2;
- } else
- goto out;
- }
- if (pos >= dp->ndm_eocookie) {
- if (add)
- dp->ndm_eocookie = pos + 1;
- else
- goto out;
- }
- retval = &dp->ndm_cookies[pos];
-out:
- return (retval);
-}
-
-/*
- * Invalidate cached directory information, except for the actual directory
- * blocks (which are invalidated separately).
- * Done mainly to avoid the use of stale offset cookies.
- */
-void
-nfs_invaldir(struct vnode *vp)
-{
- struct nfsnode *np = VTONFS(vp);
-
- KASSERT(vp->v_type == VDIR, ("nfs: invaldir not dir"));
- nfs_dircookie_lock(np);
- np->n_direofoffset = 0;
- np->n_cookieverf.nfsuquad[0] = 0;
- np->n_cookieverf.nfsuquad[1] = 0;
- if (LIST_FIRST(&np->n_cookies))
- LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0;
- nfs_dircookie_unlock(np);
-}
-
-/*
- * The write verifier has changed (probably due to a server reboot), so all
- * B_NEEDCOMMIT blocks will have to be written again. Since they are on the
- * dirty block list as B_DELWRI, all this takes is clearing the B_NEEDCOMMIT
- * and B_CLUSTEROK flags. Once done the new write verifier can be set for the
- * mount point.
- *
- * B_CLUSTEROK must be cleared along with B_NEEDCOMMIT because stage 1 data
- * writes are not clusterable.
- */
-void
-nfs_clearcommit(struct mount *mp)
-{
- struct vnode *vp, *nvp;
- struct buf *bp, *nbp;
- struct bufobj *bo;
-
- MNT_VNODE_FOREACH_ALL(vp, mp, nvp) {
- bo = &vp->v_bufobj;
- vholdl(vp);
- VI_UNLOCK(vp);
- BO_LOCK(bo);
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (!BUF_ISLOCKED(bp) &&
- (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT))
- == (B_DELWRI | B_NEEDCOMMIT))
- bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
- }
- BO_UNLOCK(bo);
- vdrop(vp);
- }
-}
-
-/*
- * Helper functions for former macros. Some of these should be
- * moved to their callers.
- */
-
-int
-nfsm_mtofh_xx(struct vnode *d, struct vnode **v, int v3, int *f,
- struct mbuf **md, caddr_t *dpos)
-{
- struct nfsnode *ttnp;
- struct vnode *ttvp;
- nfsfh_t *ttfhp;
- u_int32_t *tl;
- int ttfhsize;
- int t1;
-
- if (v3) {
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- *f = fxdr_unsigned(int, *tl);
- } else
- *f = 1;
- if (*f) {
- t1 = nfsm_getfh_xx(&ttfhp, &ttfhsize, (v3), md, dpos);
- if (t1 != 0)
- return t1;
- t1 = nfs_nget(d->v_mount, ttfhp, ttfhsize, &ttnp, LK_EXCLUSIVE);
- if (t1 != 0)
- return t1;
- *v = NFSTOV(ttnp);
- }
- if (v3) {
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- if (*f)
- *f = fxdr_unsigned(int, *tl);
- else if (fxdr_unsigned(int, *tl))
- nfsm_adv_xx(NFSX_V3FATTR, md, dpos);
- }
- if (*f) {
- ttvp = *v;
- t1 = nfs_loadattrcache(&ttvp, md, dpos, NULL, 0);
- if (t1)
- return t1;
- *v = ttvp;
- }
- return 0;
-}
-
-int
-nfsm_getfh_xx(nfsfh_t **f, int *s, int v3, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
-
- if (v3) {
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- *s = fxdr_unsigned(int, *tl);
- if (*s <= 0 || *s > NFSX_V3FHMAX)
- return EBADRPC;
- } else
- *s = NFSX_V2FH;
- *f = nfsm_dissect_xx(nfsm_rndup(*s), md, dpos);
- if (*f == NULL)
- return EBADRPC;
- else
- return 0;
-}
-
-
-int
-nfsm_loadattr_xx(struct vnode **v, struct vattr *va, struct mbuf **md,
- caddr_t *dpos)
-{
- int t1;
-
- struct vnode *ttvp = *v;
- t1 = nfs_loadattrcache(&ttvp, md, dpos, va, 0);
- if (t1 != 0)
- return t1;
- *v = ttvp;
- return 0;
-}
-
-int
-nfsm_postop_attr_xx(struct vnode **v, int *f, struct vattr *va,
- struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
- int t1;
-
- struct vnode *ttvp = *v;
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- *f = fxdr_unsigned(int, *tl);
- if (*f != 0) {
- t1 = nfs_loadattrcache(&ttvp, md, dpos, va, 1);
- if (t1 != 0) {
- *f = 0;
- return t1;
- }
- *v = ttvp;
- }
- return 0;
-}
-
-int
-nfsm_wcc_data_xx(struct vnode **v, int *f, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
- int ttattrf, ttretf = 0;
- int t1;
-
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- if (*tl == nfs_true) {
- tl = nfsm_dissect_xx(6 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- mtx_lock(&(VTONFS(*v))->n_mtx);
- if (*f)
- ttretf = (VTONFS(*v)->n_mtime.tv_sec == fxdr_unsigned(u_int32_t, *(tl + 2)) &&
- VTONFS(*v)->n_mtime.tv_nsec == fxdr_unsigned(u_int32_t, *(tl + 3)));
- mtx_unlock(&(VTONFS(*v))->n_mtx);
- }
- t1 = nfsm_postop_attr_xx(v, &ttattrf, NULL, md, dpos);
- if (t1)
- return t1;
- if (*f)
- *f = ttretf;
- else
- *f = ttattrf;
- return 0;
-}
-
-int
-nfsm_strtom_xx(const char *a, int s, int m, struct mbuf **mb, caddr_t *bpos)
-{
- u_int32_t *tl;
- int t1;
-
- if (s > m)
- return ENAMETOOLONG;
- t1 = nfsm_rndup(s) + NFSX_UNSIGNED;
- if (t1 <= M_TRAILINGSPACE(*mb)) {
- tl = nfsm_build_xx(t1, mb, bpos);
- *tl++ = txdr_unsigned(s);
- *(tl + ((t1 >> 2) - 2)) = 0;
- bcopy(a, tl, s);
- } else {
- t1 = nfsm_strtmbuf(mb, bpos, a, s);
- if (t1 != 0)
- return t1;
- }
- return 0;
-}
-
-int
-nfsm_fhtom_xx(struct vnode *v, int v3, struct mbuf **mb, caddr_t *bpos)
-{
- u_int32_t *tl;
- int t1;
- caddr_t cp;
-
- if (v3) {
- t1 = nfsm_rndup(VTONFS(v)->n_fhsize) + NFSX_UNSIGNED;
- if (t1 < M_TRAILINGSPACE(*mb)) {
- tl = nfsm_build_xx(t1, mb, bpos);
- *tl++ = txdr_unsigned(VTONFS(v)->n_fhsize);
- *(tl + ((t1 >> 2) - 2)) = 0;
- bcopy(VTONFS(v)->n_fhp, tl, VTONFS(v)->n_fhsize);
- } else {
- t1 = nfsm_strtmbuf(mb, bpos,
- (const char *)VTONFS(v)->n_fhp,
- VTONFS(v)->n_fhsize);
- if (t1 != 0)
- return t1;
- }
- } else {
- cp = nfsm_build_xx(NFSX_V2FH, mb, bpos);
- bcopy(VTONFS(v)->n_fhp, cp, NFSX_V2FH);
- }
- return 0;
-}
-
-void
-nfsm_v3attrbuild_xx(struct vattr *va, int full, struct mbuf **mb,
- caddr_t *bpos)
-{
- u_int32_t *tl;
-
- if (va->va_mode != (mode_t)VNOVAL) {
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = nfs_true;
- *tl = txdr_unsigned(va->va_mode);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = nfs_false;
- }
- if (full && va->va_uid != (uid_t)VNOVAL) {
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = nfs_true;
- *tl = txdr_unsigned(va->va_uid);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = nfs_false;
- }
- if (full && va->va_gid != (gid_t)VNOVAL) {
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = nfs_true;
- *tl = txdr_unsigned(va->va_gid);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = nfs_false;
- }
- if (full && va->va_size != VNOVAL) {
- tl = nfsm_build_xx(3 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = nfs_true;
- txdr_hyper(va->va_size, tl);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = nfs_false;
- }
- if (va->va_atime.tv_sec != VNOVAL) {
- if ((va->va_vaflags & VA_UTIMES_NULL) == 0) {
- tl = nfsm_build_xx(3 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
- txdr_nfsv3time(&va->va_atime, tl);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER);
- }
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);
- }
- if (va->va_mtime.tv_sec != VNOVAL) {
- if ((va->va_vaflags & VA_UTIMES_NULL) == 0) {
- tl = nfsm_build_xx(3 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = txdr_unsigned(NFSV3SATTRTIME_TOCLIENT);
- txdr_nfsv3time(&va->va_mtime, tl);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = txdr_unsigned(NFSV3SATTRTIME_TOSERVER);
- }
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- *tl = txdr_unsigned(NFSV3SATTRTIME_DONTCHANGE);
- }
-}
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
deleted file mode 100644
index 0c002d2..0000000
--- a/sys/nfsclient/nfs_vfsops.c
+++ /dev/null
@@ -1,1582 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993, 1995
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-
-#include "opt_bootp.h"
-#include "opt_nfsroot.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/jail.h>
-#include <sys/limits.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <sys/mount.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sockio.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <sys/vnode.h>
-#include <sys/signalvar.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/uma.h>
-
-#include <net/if.h>
-#include <net/if_var.h>
-#include <net/route.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-
-#include <rpc/rpc.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsnode.h>
-#include <nfsclient/nfsmount.h>
-#include <nfs/xdr_subs.h>
-#include <nfsclient/nfsm_subs.h>
-#include <nfs/nfsdiskless.h>
-
-FEATURE(nfsclient, "NFS client");
-
-MALLOC_DEFINE(M_NFSREQ, "nfsclient_req", "NFS request header");
-MALLOC_DEFINE(M_NFSBIGFH, "nfsclient_bigfh", "NFS version 3 file handle");
-MALLOC_DEFINE(M_NFSDIROFF, "nfsclient_diroff", "NFS directory offset data");
-MALLOC_DEFINE(M_NFSHASH, "nfsclient_hash", "NFS hash tables");
-MALLOC_DEFINE(M_NFSDIRECTIO, "nfsclient_directio", "NFS Direct IO async write state");
-
-uma_zone_t nfsmount_zone;
-
-struct nfsstats nfsstats;
-
-SYSCTL_NODE(_vfs, OID_AUTO, oldnfs, CTLFLAG_RW, 0, "Old NFS filesystem");
-SYSCTL_STRUCT(_vfs_oldnfs, NFS_NFSSTATS, nfsstats, CTLFLAG_RW,
- &nfsstats, nfsstats, "S,nfsstats");
-static int nfs_ip_paranoia = 1;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_ip_paranoia, CTLFLAG_RW,
- &nfs_ip_paranoia, 0,
- "Disallow accepting replies from IPs which differ from those sent");
-#ifdef NFS_DEBUG
-int nfs_debug;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, debug, CTLFLAG_RW, &nfs_debug, 0,
- "Toggle debug flag");
-#endif
-static int nfs_tprintf_initial_delay = NFS_TPRINTF_INITIAL_DELAY;
-SYSCTL_INT(_vfs_oldnfs, NFS_TPRINTF_INITIAL_DELAY,
- downdelayinitial, CTLFLAG_RW, &nfs_tprintf_initial_delay, 0,
- "Delay before printing \"nfs server not responding\" messages");
-/* how long between console messages "nfs server foo not responding" */
-static int nfs_tprintf_delay = NFS_TPRINTF_DELAY;
-SYSCTL_INT(_vfs_oldnfs, NFS_TPRINTF_DELAY,
- downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0,
- "Delay between printing \"nfs server not responding\" messages");
-
-static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
- struct nfs_args *argp, const char *hostname);
-static int mountnfs(struct nfs_args *, struct mount *,
- struct sockaddr *, char *, struct vnode **,
- struct ucred *cred, int, int);
-static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
- struct sockaddr_storage *, int *, off_t *,
- struct timeval *);
-static vfs_mount_t nfs_mount;
-static vfs_cmount_t nfs_cmount;
-static vfs_unmount_t nfs_unmount;
-static vfs_root_t nfs_root;
-static vfs_statfs_t nfs_statfs;
-static vfs_sync_t nfs_sync;
-static vfs_sysctl_t nfs_sysctl;
-
-static int fake_wchan;
-
-/*
- * nfs vfs operations.
- */
-static struct vfsops nfs_vfsops = {
- .vfs_init = nfs_init,
- .vfs_mount = nfs_mount,
- .vfs_cmount = nfs_cmount,
- .vfs_root = nfs_root,
- .vfs_statfs = nfs_statfs,
- .vfs_sync = nfs_sync,
- .vfs_uninit = nfs_uninit,
- .vfs_unmount = nfs_unmount,
- .vfs_sysctl = nfs_sysctl,
-};
-VFS_SET(nfs_vfsops, oldnfs, VFCF_NETWORK | VFCF_SBDRY);
-
-/* So that loader and kldload(2) can find us, wherever we are.. */
-MODULE_VERSION(oldnfs, 1);
-MODULE_DEPEND(oldnfs, krpc, 1, 1, 1);
-#ifdef KGSSAPI
-MODULE_DEPEND(oldnfs, kgssapi, 1, 1, 1);
-#endif
-MODULE_DEPEND(oldnfs, nfs_common, 1, 1, 1);
-MODULE_DEPEND(oldnfs, nfslock, 1, 1, 1);
-
-static struct nfs_rpcops nfs_rpcops = {
- nfs_readrpc,
- nfs_writerpc,
- nfs_writebp,
- nfs_readlinkrpc,
- nfs_invaldir,
- nfs_commit,
-};
-
-/*
- * This structure is now defined in sys/nfs/nfs_diskless.c so that it
- * can be shared by both NFS clients. It is declared here so that it
- * will be defined for kernels built without NFS_ROOT, although it
- * isn't used in that case.
- */
-#ifndef NFS_ROOT
-struct nfs_diskless nfs_diskless = { { { 0 } } };
-struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
-int nfs_diskless_valid = 0;
-#endif
-
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, diskless_valid, CTLFLAG_RD,
- &nfs_diskless_valid, 0,
- "Has the diskless struct been filled correctly");
-
-SYSCTL_STRING(_vfs_oldnfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
- nfsv3_diskless.root_hostnam, 0, "Path to nfs root");
-
-SYSCTL_OPAQUE(_vfs_oldnfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
- &nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
- "%Ssockaddr_in", "Diskless root nfs address");
-
-
-void nfsargs_ntoh(struct nfs_args *);
-static int nfs_mountdiskless(char *,
- struct sockaddr_in *, struct nfs_args *,
- struct thread *, struct vnode **, struct mount *);
-static void nfs_convert_diskless(void);
-static void nfs_convert_oargs(struct nfs_args *args,
- struct onfs_args *oargs);
-
-int
-nfs_iosize(struct nfsmount *nmp)
-{
- int iosize;
-
- /*
- * Calculate the size used for io buffers. Use the larger
- * of the two sizes to minimise nfs requests but make sure
- * that it is at least one VM page to avoid wasting buffer
- * space.
- */
- iosize = imax(nmp->nm_rsize, nmp->nm_wsize);
- iosize = imax(iosize, PAGE_SIZE);
- return (iosize);
-}
-
-static void
-nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
-{
-
- args->version = NFS_ARGSVERSION;
- args->addr = oargs->addr;
- args->addrlen = oargs->addrlen;
- args->sotype = oargs->sotype;
- args->proto = oargs->proto;
- args->fh = oargs->fh;
- args->fhsize = oargs->fhsize;
- args->flags = oargs->flags;
- args->wsize = oargs->wsize;
- args->rsize = oargs->rsize;
- args->readdirsize = oargs->readdirsize;
- args->timeo = oargs->timeo;
- args->retrans = oargs->retrans;
- args->maxgrouplist = oargs->maxgrouplist;
- args->readahead = oargs->readahead;
- args->deadthresh = oargs->deadthresh;
- args->hostname = oargs->hostname;
-}
-
-static void
-nfs_convert_diskless(void)
-{
-
- bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
- sizeof(struct ifaliasreq));
- bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
- sizeof(struct sockaddr_in));
- nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
- if (nfsv3_diskless.root_args.flags & NFSMNT_NFSV3) {
- nfsv3_diskless.root_fhsize = NFSX_V3FH;
- bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V3FH);
- } else {
- nfsv3_diskless.root_fhsize = NFSX_V2FH;
- bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
- }
- bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
- sizeof(struct sockaddr_in));
- bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
- nfsv3_diskless.root_time = nfs_diskless.root_time;
- bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
- MAXHOSTNAMELEN);
- nfs_diskless_valid = 3;
-}
-
-/*
- * nfs statfs call
- */
-static int
-nfs_statfs(struct mount *mp, struct statfs *sbp)
-{
- struct vnode *vp;
- struct thread *td;
- struct nfs_statfs *sfp;
- caddr_t bpos, dpos;
- struct nfsmount *nmp = VFSTONFS(mp);
- int error = 0, v3 = (nmp->nm_flag & NFSMNT_NFSV3), retattr;
- struct mbuf *mreq, *mrep, *md, *mb;
- struct nfsnode *np;
- u_quad_t tquad;
-
- td = curthread;
-#ifndef nolint
- sfp = NULL;
-#endif
- error = vfs_busy(mp, MBF_NOWAIT);
- if (error)
- return (error);
- error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
- if (error) {
- vfs_unbusy(mp);
- return (error);
- }
- vp = NFSTOV(np);
- mtx_lock(&nmp->nm_mtx);
- if (v3 && (nmp->nm_state & NFSSTA_GOTFSINFO) == 0) {
- mtx_unlock(&nmp->nm_mtx);
- (void)nfs_fsinfo(nmp, vp, td->td_ucred, td);
- } else
- mtx_unlock(&nmp->nm_mtx);
- nfsstats.rpccnt[NFSPROC_FSSTAT]++;
- mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- nfsm_request(vp, NFSPROC_FSSTAT, td, td->td_ucred);
- if (v3)
- nfsm_postop_attr(vp, retattr);
- if (error) {
- if (mrep != NULL)
- m_freem(mrep);
- goto nfsmout;
- }
- sfp = nfsm_dissect(struct nfs_statfs *, NFSX_STATFS(v3));
- mtx_lock(&nmp->nm_mtx);
- sbp->f_iosize = nfs_iosize(nmp);
- mtx_unlock(&nmp->nm_mtx);
- if (v3) {
- sbp->f_bsize = NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->sf_tbytes);
- sbp->f_blocks = tquad / NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->sf_fbytes);
- sbp->f_bfree = tquad / NFS_FABLKSIZE;
- tquad = fxdr_hyper(&sfp->sf_abytes);
- sbp->f_bavail = tquad / NFS_FABLKSIZE;
- sbp->f_files = (fxdr_unsigned(int32_t,
- sfp->sf_tfiles.nfsuquad[1]) & 0x7fffffff);
- sbp->f_ffree = (fxdr_unsigned(int32_t,
- sfp->sf_ffiles.nfsuquad[1]) & 0x7fffffff);
- } else {
- sbp->f_bsize = fxdr_unsigned(int32_t, sfp->sf_bsize);
- sbp->f_blocks = fxdr_unsigned(int32_t, sfp->sf_blocks);
- sbp->f_bfree = fxdr_unsigned(int32_t, sfp->sf_bfree);
- sbp->f_bavail = fxdr_unsigned(int32_t, sfp->sf_bavail);
- sbp->f_files = 0;
- sbp->f_ffree = 0;
- }
- m_freem(mrep);
-nfsmout:
- vput(vp);
- vfs_unbusy(mp);
- return (error);
-}
-
-/*
- * nfs version 3 fsinfo rpc call
- */
-int
-nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred,
- struct thread *td)
-{
- struct nfsv3_fsinfo *fsp;
- u_int32_t pref, max;
- caddr_t bpos, dpos;
- int error = 0, retattr;
- struct mbuf *mreq, *mrep, *md, *mb;
- u_int64_t maxfsize;
-
- nfsstats.rpccnt[NFSPROC_FSINFO]++;
- mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, 1);
- nfsm_request(vp, NFSPROC_FSINFO, td, cred);
- nfsm_postop_attr(vp, retattr);
- if (!error) {
- fsp = nfsm_dissect(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
- pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref);
- mtx_lock(&nmp->nm_mtx);
- if (pref < nmp->nm_wsize && pref >= NFS_FABLKSIZE)
- nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) &
- ~(NFS_FABLKSIZE - 1);
- max = fxdr_unsigned(u_int32_t, fsp->fs_wtmax);
- if (max < nmp->nm_wsize && max > 0) {
- nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_wsize == 0)
- nmp->nm_wsize = max;
- }
- pref = fxdr_unsigned(u_int32_t, fsp->fs_rtpref);
- if (pref < nmp->nm_rsize && pref >= NFS_FABLKSIZE)
- nmp->nm_rsize = (pref + NFS_FABLKSIZE - 1) &
- ~(NFS_FABLKSIZE - 1);
- max = fxdr_unsigned(u_int32_t, fsp->fs_rtmax);
- if (max < nmp->nm_rsize && max > 0) {
- nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_rsize == 0)
- nmp->nm_rsize = max;
- }
- pref = fxdr_unsigned(u_int32_t, fsp->fs_dtpref);
- if (pref < nmp->nm_readdirsize && pref >= NFS_DIRBLKSIZ)
- nmp->nm_readdirsize = (pref + NFS_DIRBLKSIZ - 1) &
- ~(NFS_DIRBLKSIZ - 1);
- if (max < nmp->nm_readdirsize && max > 0) {
- nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
- if (nmp->nm_readdirsize == 0)
- nmp->nm_readdirsize = max;
- }
- maxfsize = fxdr_hyper(&fsp->fs_maxfilesize);
- if (maxfsize > 0 && maxfsize < nmp->nm_maxfilesize)
- nmp->nm_maxfilesize = maxfsize;
- nmp->nm_mountp->mnt_stat.f_iosize = nfs_iosize(nmp);
- nmp->nm_state |= NFSSTA_GOTFSINFO;
- mtx_unlock(&nmp->nm_mtx);
- }
- m_freem(mrep);
-nfsmout:
- return (error);
-}
-
-/*
- * Mount a remote root fs via. nfs. This depends on the info in the
- * nfs_diskless structure that has been filled in properly by some primary
- * bootstrap.
- * It goes something like this:
- * - do enough of "ifconfig" by calling ifioctl() so that the system
- * can talk to the server
- * - If nfs_diskless.mygateway is filled in, use that address as
- * a default gateway.
- * - build the rootfs mount point and call mountnfs() to do the rest.
- *
- * It is assumed to be safe to read, modify, and write the nfsv3_diskless
- * structure, as well as other global NFS client variables here, as
- * nfs_mountroot() will be called once in the boot before any other NFS
- * client activity occurs.
- */
-int
-nfs_mountroot(struct mount *mp)
-{
- struct thread *td = curthread;
- struct nfsv3_diskless *nd = &nfsv3_diskless;
- struct socket *so;
- struct vnode *vp;
- struct ifreq ir;
- int error;
- u_long l;
- char buf[128];
- char *cp;
-
-
-#if defined(BOOTP_NFSROOT) && defined(BOOTP)
- bootpc_init(); /* use bootp to get nfs_diskless filled in */
-#elif defined(NFS_ROOT)
- nfs_setup_diskless();
-#endif
-
- if (nfs_diskless_valid == 0) {
- return (-1);
- }
- if (nfs_diskless_valid == 1)
- nfs_convert_diskless();
-
- /*
- * XXX splnet, so networks will receive...
- */
- splnet();
-
- /*
- * Do enough of ifconfig(8) so that the critical net interface can
- * talk to the server.
- */
- error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0,
- td->td_ucred, td);
- if (error)
- panic("nfs_mountroot: socreate(%04x): %d",
- nd->myif.ifra_addr.sa_family, error);
-
-#if 0 /* XXX Bad idea */
- /*
- * We might not have been told the right interface, so we pass
- * over the first ten interfaces of the same kind, until we get
- * one of them configured.
- */
-
- for (i = strlen(nd->myif.ifra_name) - 1;
- nd->myif.ifra_name[i] >= '0' &&
- nd->myif.ifra_name[i] <= '9';
- nd->myif.ifra_name[i] ++) {
- error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
- if(!error)
- break;
- }
-#endif
-
- error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td);
- if (error)
- panic("nfs_mountroot: SIOCAIFADDR: %d", error);
-
- if ((cp = kern_getenv("boot.netif.mtu")) != NULL) {
- ir.ifr_mtu = strtol(cp, NULL, 10);
- bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ);
- freeenv(cp);
- error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td);
- if (error)
- printf("nfs_mountroot: SIOCSIFMTU: %d", error);
- }
- soclose(so);
-
- /*
- * If the gateway field is filled in, set it as the default route.
- * Note that pxeboot will set a default route of 0 if the route
- * is not set by the DHCP server. Check also for a value of 0
- * to avoid panicking inappropriately in that situation.
- */
- if (nd->mygateway.sin_len != 0 &&
- nd->mygateway.sin_addr.s_addr != 0) {
- struct sockaddr_in mask, sin;
-
- bzero((caddr_t)&mask, sizeof(mask));
- sin = mask;
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(sin);
- /* XXX MRT use table 0 for this sort of thing */
- CURVNET_SET(TD_TO_VNET(td));
- error = rtrequest_fib(RTM_ADD, (struct sockaddr *)&sin,
- (struct sockaddr *)&nd->mygateway,
- (struct sockaddr *)&mask,
- RTF_UP | RTF_GATEWAY, NULL, RT_DEFAULT_FIB);
- CURVNET_RESTORE();
- if (error)
- panic("nfs_mountroot: RTM_ADD: %d", error);
- }
-
- /*
- * Create the rootfs mount point.
- */
- nd->root_args.fh = nd->root_fh;
- nd->root_args.fhsize = nd->root_fhsize;
- l = ntohl(nd->root_saddr.sin_addr.s_addr);
- snprintf(buf, sizeof(buf), "%ld.%ld.%ld.%ld:%s",
- (l >> 24) & 0xff, (l >> 16) & 0xff,
- (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam);
- printf("NFS ROOT: %s\n", buf);
- nd->root_args.hostname = buf;
- if ((error = nfs_mountdiskless(buf,
- &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) {
- return (error);
- }
-
- /*
- * This is not really an nfs issue, but it is much easier to
- * set hostname here and then let the "/etc/rc.xxx" files
- * mount the right /var based upon its preset value.
- */
- mtx_lock(&prison0.pr_mtx);
- strlcpy(prison0.pr_hostname, nd->my_hostnam,
- sizeof (prison0.pr_hostname));
- mtx_unlock(&prison0.pr_mtx);
- inittodr(ntohl(nd->root_time));
- return (0);
-}
-
-/*
- * Internal version of mount system call for diskless setup.
- */
-static int
-nfs_mountdiskless(char *path,
- struct sockaddr_in *sin, struct nfs_args *args, struct thread *td,
- struct vnode **vpp, struct mount *mp)
-{
- struct sockaddr *nam;
- int error;
-
- nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
- if ((error = mountnfs(args, mp, nam, path, vpp, td->td_ucred,
- NFS_DEFAULT_NAMETIMEO, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
- printf("nfs_mountroot: mount %s on /: %d\n", path, error);
- return (error);
- }
- return (0);
-}
-
-static int
-nfs_sec_name_to_num(char *sec)
-{
- if (!strcmp(sec, "krb5"))
- return (RPCSEC_GSS_KRB5);
- if (!strcmp(sec, "krb5i"))
- return (RPCSEC_GSS_KRB5I);
- if (!strcmp(sec, "krb5p"))
- return (RPCSEC_GSS_KRB5P);
- if (!strcmp(sec, "sys"))
- return (AUTH_SYS);
- /*
- * Userland should validate the string but we will try and
- * cope with unexpected values.
- */
- return (AUTH_SYS);
-}
-
-static void
-nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
- const char *hostname)
-{
- int s;
- int adjsock;
- int maxio;
- char *p;
- char *secname;
- char *principal;
-
- s = splnet();
-
- /*
- * Set read-only flag if requested; otherwise, clear it if this is
- * an update. If this is not an update, then either the read-only
- * flag is already clear, or this is a root mount and it was set
- * intentionally at some previous point.
- */
- if (vfs_getopt(mp->mnt_optnew, "ro", NULL, NULL) == 0) {
- MNT_ILOCK(mp);
- mp->mnt_flag |= MNT_RDONLY;
- MNT_IUNLOCK(mp);
- } else if (mp->mnt_flag & MNT_UPDATE) {
- MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_RDONLY;
- MNT_IUNLOCK(mp);
- }
-
- /*
- * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
- * no sense in that context. Also, set up appropriate retransmit
- * and soft timeout behavior.
- */
- if (argp->sotype == SOCK_STREAM) {
- nmp->nm_flag &= ~NFSMNT_NOCONN;
- nmp->nm_flag |= NFSMNT_DUMBTIMR;
- nmp->nm_timeo = NFS_MAXTIMEO;
- nmp->nm_retry = NFS_RETRANS_TCP;
- }
-
- /* Also clear RDIRPLUS if not NFSv3, it crashes some servers */
- if ((argp->flags & NFSMNT_NFSV3) == 0)
- nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
-
- /* Re-bind if rsrvd port requested and wasn't on one */
- adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
- && (argp->flags & NFSMNT_RESVPORT);
- /* Also re-bind if we're switching to/from a connected UDP socket */
- adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
- (argp->flags & NFSMNT_NOCONN));
-
- /* Update flags atomically. Don't change the lock bits. */
- nmp->nm_flag = argp->flags | nmp->nm_flag;
- splx(s);
-
- if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
- nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
- if (nmp->nm_timeo < NFS_MINTIMEO)
- nmp->nm_timeo = NFS_MINTIMEO;
- else if (nmp->nm_timeo > NFS_MAXTIMEO)
- nmp->nm_timeo = NFS_MAXTIMEO;
- }
-
- if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
- nmp->nm_retry = argp->retrans;
- if (nmp->nm_retry > NFS_MAXREXMIT)
- nmp->nm_retry = NFS_MAXREXMIT;
- }
-
- if (argp->flags & NFSMNT_NFSV3) {
- if (argp->sotype == SOCK_DGRAM)
- maxio = NFS_MAXDGRAMDATA;
- else
- maxio = NFS_MAXDATA;
- } else
- maxio = NFS_V2MAXDATA;
-
- if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
- nmp->nm_wsize = argp->wsize;
- /* Round down to multiple of blocksize */
- nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_wsize <= 0)
- nmp->nm_wsize = NFS_FABLKSIZE;
- }
- if (nmp->nm_wsize > maxio)
- nmp->nm_wsize = maxio;
- if (nmp->nm_wsize > MAXBSIZE)
- nmp->nm_wsize = MAXBSIZE;
-
- if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
- nmp->nm_rsize = argp->rsize;
- /* Round down to multiple of blocksize */
- nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
- if (nmp->nm_rsize <= 0)
- nmp->nm_rsize = NFS_FABLKSIZE;
- }
- if (nmp->nm_rsize > maxio)
- nmp->nm_rsize = maxio;
- if (nmp->nm_rsize > MAXBSIZE)
- nmp->nm_rsize = MAXBSIZE;
-
- if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
- nmp->nm_readdirsize = argp->readdirsize;
- }
- if (nmp->nm_readdirsize > maxio)
- nmp->nm_readdirsize = maxio;
- if (nmp->nm_readdirsize > nmp->nm_rsize)
- nmp->nm_readdirsize = nmp->nm_rsize;
-
- if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
- nmp->nm_acregmin = argp->acregmin;
- else
- nmp->nm_acregmin = NFS_MINATTRTIMO;
- if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
- nmp->nm_acregmax = argp->acregmax;
- else
- nmp->nm_acregmax = NFS_MAXATTRTIMO;
- if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
- nmp->nm_acdirmin = argp->acdirmin;
- else
- nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
- if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
- nmp->nm_acdirmax = argp->acdirmax;
- else
- nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
- if (nmp->nm_acdirmin > nmp->nm_acdirmax)
- nmp->nm_acdirmin = nmp->nm_acdirmax;
- if (nmp->nm_acregmin > nmp->nm_acregmax)
- nmp->nm_acregmin = nmp->nm_acregmax;
-
- if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
- if (argp->maxgrouplist <= NFS_MAXGRPS)
- nmp->nm_numgrps = argp->maxgrouplist;
- else
- nmp->nm_numgrps = NFS_MAXGRPS;
- }
- if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
- if (argp->readahead <= NFS_MAXRAHEAD)
- nmp->nm_readahead = argp->readahead;
- else
- nmp->nm_readahead = NFS_MAXRAHEAD;
- }
- if ((argp->flags & NFSMNT_WCOMMITSIZE) && argp->wcommitsize >= 0) {
- if (argp->wcommitsize < nmp->nm_wsize)
- nmp->nm_wcommitsize = nmp->nm_wsize;
- else
- nmp->nm_wcommitsize = argp->wcommitsize;
- }
- if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
- if (argp->deadthresh <= NFS_MAXDEADTHRESH)
- nmp->nm_deadthresh = argp->deadthresh;
- else
- nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
- }
-
- adjsock |= ((nmp->nm_sotype != argp->sotype) ||
- (nmp->nm_soproto != argp->proto));
- nmp->nm_sotype = argp->sotype;
- nmp->nm_soproto = argp->proto;
-
- if (nmp->nm_client && adjsock) {
- nfs_safedisconnect(nmp);
- if (nmp->nm_sotype == SOCK_DGRAM)
- while (nfs_connect(nmp)) {
- printf("nfs_args: retrying connect\n");
- (void) tsleep(&fake_wchan, PSOCK, "nfscon", hz);
- }
- }
-
- if (hostname) {
- strlcpy(nmp->nm_hostname, hostname,
- sizeof(nmp->nm_hostname));
- p = strchr(nmp->nm_hostname, ':');
- if (p)
- *p = '\0';
- }
-
- if (vfs_getopt(mp->mnt_optnew, "sec",
- (void **) &secname, NULL) == 0) {
- nmp->nm_secflavor = nfs_sec_name_to_num(secname);
- } else {
- nmp->nm_secflavor = AUTH_SYS;
- }
-
- if (vfs_getopt(mp->mnt_optnew, "principal",
- (void **) &principal, NULL) == 0) {
- strlcpy(nmp->nm_principal, principal,
- sizeof(nmp->nm_principal));
- } else {
- snprintf(nmp->nm_principal, sizeof(nmp->nm_principal),
- "nfs@%s", nmp->nm_hostname);
- }
-}
-
-static const char *nfs_opts[] = { "from", "nfs_args",
- "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union",
- "noclusterr", "noclusterw", "multilabel", "acls", "force", "update",
- "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport",
- "readahead", "readdirsize", "soft", "hard", "mntudp", "tcp", "udp",
- "wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin",
- "acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3",
- "sec", "maxgroups", "principal", "negnametimeo", "nocto", "wcommitsize",
- "nametimeo",
- NULL };
-
-/*
- * VFS Operations.
- *
- * mount system call
- * It seems a bit dumb to copyinstr() the host and path here and then
- * bcopy() them in mountnfs(), but I wanted to detect errors before
- * doing the sockargs() call because sockargs() allocates an mbuf and
- * an error after that means that I have to release the mbuf.
- */
-/* ARGSUSED */
-static int
-nfs_mount(struct mount *mp)
-{
- struct nfs_args args = {
- .version = NFS_ARGSVERSION,
- .addr = NULL,
- .addrlen = sizeof (struct sockaddr_in),
- .sotype = SOCK_STREAM,
- .proto = 0,
- .fh = NULL,
- .fhsize = 0,
- .flags = NFSMNT_RESVPORT,
- .wsize = NFS_WSIZE,
- .rsize = NFS_RSIZE,
- .readdirsize = NFS_READDIRSIZE,
- .timeo = 10,
- .retrans = NFS_RETRANS,
- .maxgrouplist = NFS_MAXGRPS,
- .readahead = NFS_DEFRAHEAD,
- .wcommitsize = 0, /* was: NQ_DEFLEASE */
- .deadthresh = NFS_MAXDEADTHRESH, /* was: NQ_DEADTHRESH */
- .hostname = NULL,
- /* args version 4 */
- .acregmin = NFS_MINATTRTIMO,
- .acregmax = NFS_MAXATTRTIMO,
- .acdirmin = NFS_MINDIRATTRTIMO,
- .acdirmax = NFS_MAXDIRATTRTIMO,
- };
- int error, ret, has_nfs_args_opt;
- int has_addr_opt, has_fh_opt, has_hostname_opt;
- struct sockaddr *nam;
- struct vnode *vp;
- char hst[MNAMELEN];
- size_t len;
- u_char nfh[NFSX_V3FHMAX];
- char *opt;
- int nametimeo = NFS_DEFAULT_NAMETIMEO;
- int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
-
- has_nfs_args_opt = 0;
- has_addr_opt = 0;
- has_fh_opt = 0;
- has_hostname_opt = 0;
-
- if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) {
- error = EINVAL;
- goto out;
- }
-
- if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) {
- error = nfs_mountroot(mp);
- goto out;
- }
-
- /*
- * The old mount_nfs program passed the struct nfs_args
- * from userspace to kernel. The new mount_nfs program
- * passes string options via nmount() from userspace to kernel
- * and we populate the struct nfs_args in the kernel.
- */
- if (vfs_getopt(mp->mnt_optnew, "nfs_args", NULL, NULL) == 0) {
- error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args,
- sizeof args);
- if (error)
- goto out;
-
- if (args.version != NFS_ARGSVERSION) {
- error = EPROGMISMATCH;
- goto out;
- }
- has_nfs_args_opt = 1;
- }
-
- if (vfs_getopt(mp->mnt_optnew, "dumbtimer", NULL, NULL) == 0)
- args.flags |= NFSMNT_DUMBTIMR;
- if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0)
- args.flags |= NFSMNT_NOCONN;
- if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0)
- args.flags |= NFSMNT_NOCONN;
- if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0)
- args.flags |= NFSMNT_NOLOCKD;
- if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0)
- args.flags &= ~NFSMNT_NOLOCKD;
- if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0)
- args.flags |= NFSMNT_INT;
- if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0)
- args.flags |= NFSMNT_RDIRPLUS;
- if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0)
- args.flags |= NFSMNT_RESVPORT;
- if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0)
- args.flags &= ~NFSMNT_RESVPORT;
- if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0)
- args.flags |= NFSMNT_SOFT;
- if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0)
- args.flags &= ~NFSMNT_SOFT;
- if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0)
- args.sotype = SOCK_DGRAM;
- if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0)
- args.sotype = SOCK_DGRAM;
- if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0)
- args.sotype = SOCK_STREAM;
- if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0)
- args.flags |= NFSMNT_NFSV3;
- if (vfs_getopt(mp->mnt_optnew, "nocto", NULL, NULL) == 0)
- args.flags |= NFSMNT_NOCTO;
- if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) {
- if (opt == NULL) {
- vfs_mount_error(mp, "illegal readdirsize");
- error = EINVAL;
- goto out;
- }
- ret = sscanf(opt, "%d", &args.readdirsize);
- if (ret != 1 || args.readdirsize <= 0) {
- vfs_mount_error(mp, "illegal readdirsize: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_READDIRSIZE;
- }
- if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) {
- if (opt == NULL) {
- vfs_mount_error(mp, "illegal readahead");
- error = EINVAL;
- goto out;
- }
- ret = sscanf(opt, "%d", &args.readahead);
- if (ret != 1 || args.readahead <= 0) {
- vfs_mount_error(mp, "illegal readahead: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_READAHEAD;
- }
- if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) {
- if (opt == NULL) {
- vfs_mount_error(mp, "illegal wsize");
- error = EINVAL;
- goto out;
- }
- ret = sscanf(opt, "%d", &args.wsize);
- if (ret != 1 || args.wsize <= 0) {
- vfs_mount_error(mp, "illegal wsize: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_WSIZE;
- }
- if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) {
- if (opt == NULL) {
- vfs_mount_error(mp, "illegal rsize");
- error = EINVAL;
- goto out;
- }
- ret = sscanf(opt, "%d", &args.rsize);
- if (ret != 1 || args.rsize <= 0) {
- vfs_mount_error(mp, "illegal wsize: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_RSIZE;
- }
- if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) {
- if (opt == NULL) {
- vfs_mount_error(mp, "illegal retrans");
- error = EINVAL;
- goto out;
- }
- ret = sscanf(opt, "%d", &args.retrans);
- if (ret != 1 || args.retrans <= 0) {
- vfs_mount_error(mp, "illegal retrans: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_RETRANS;
- }
- if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.acregmin);
- if (ret != 1 || args.acregmin < 0) {
- vfs_mount_error(mp, "illegal acregmin: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_ACREGMIN;
- }
- if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.acregmax);
- if (ret != 1 || args.acregmax < 0) {
- vfs_mount_error(mp, "illegal acregmax: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_ACREGMAX;
- }
- if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.acdirmin);
- if (ret != 1 || args.acdirmin < 0) {
- vfs_mount_error(mp, "illegal acdirmin: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_ACDIRMIN;
- }
- if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.acdirmax);
- if (ret != 1 || args.acdirmax < 0) {
- vfs_mount_error(mp, "illegal acdirmax: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_ACDIRMAX;
- }
- if (vfs_getopt(mp->mnt_optnew, "wcommitsize", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.wcommitsize);
- if (ret != 1 || args.wcommitsize < 0) {
- vfs_mount_error(mp, "illegal wcommitsize: %s", opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_WCOMMITSIZE;
- }
- if (vfs_getopt(mp->mnt_optnew, "deadthresh", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.deadthresh);
- if (ret != 1 || args.deadthresh <= 0) {
- vfs_mount_error(mp, "illegal deadthresh: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_DEADTHRESH;
- }
- if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.timeo);
- if (ret != 1 || args.timeo <= 0) {
- vfs_mount_error(mp, "illegal timeout: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_TIMEO;
- }
- if (vfs_getopt(mp->mnt_optnew, "maxgroups", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &args.maxgrouplist);
- if (ret != 1 || args.maxgrouplist <= 0) {
- vfs_mount_error(mp, "illegal maxgroups: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- args.flags |= NFSMNT_MAXGRPS;
- }
- if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
- ret = sscanf(opt, "%d", &nametimeo);
- if (ret != 1 || nametimeo < 0) {
- vfs_mount_error(mp, "illegal nametimeo: %s", opt);
- error = EINVAL;
- goto out;
- }
- }
- if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
- == 0) {
- ret = sscanf(opt, "%d", &negnametimeo);
- if (ret != 1 || negnametimeo < 0) {
- vfs_mount_error(mp, "illegal negnametimeo: %s",
- opt);
- error = EINVAL;
- goto out;
- }
- }
- if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr,
- &args.addrlen) == 0) {
- has_addr_opt = 1;
- if (args.addrlen > SOCK_MAXADDRLEN) {
- error = ENAMETOOLONG;
- goto out;
- }
- nam = malloc(args.addrlen, M_SONAME,
- M_WAITOK);
- bcopy(args.addr, nam, args.addrlen);
- nam->sa_len = args.addrlen;
- }
- if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh,
- &args.fhsize) == 0) {
- has_fh_opt = 1;
- }
- if (vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname,
- NULL) == 0) {
- has_hostname_opt = 1;
- }
- if (args.hostname == NULL) {
- vfs_mount_error(mp, "Invalid hostname");
- error = EINVAL;
- goto out;
- }
- if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX) {
- vfs_mount_error(mp, "Bad file handle");
- error = EINVAL;
- goto out;
- }
-
- if (mp->mnt_flag & MNT_UPDATE) {
- struct nfsmount *nmp = VFSTONFS(mp);
-
- if (nmp == NULL) {
- error = EIO;
- goto out;
- }
-
- /*
- * If a change from TCP->UDP is done and there are thread(s)
- * that have I/O RPC(s) in progress with a tranfer size
- * greater than NFS_MAXDGRAMDATA, those thread(s) will be
- * hung, retrying the RPC(s) forever. Usually these threads
- * will be seen doing an uninterruptible sleep on wait channel
- * "newnfsreq" (truncated to "newnfsre" by procstat).
- */
- if (args.sotype == SOCK_DGRAM && nmp->nm_sotype == SOCK_STREAM)
- tprintf(curthread->td_proc, LOG_WARNING,
- "Warning: mount -u that changes TCP->UDP can result in hung threads\n");
-
- /*
- * When doing an update, we can't change from or to
- * v3, switch lockd strategies or change cookie translation
- */
- args.flags = (args.flags &
- ~(NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/)) |
- (nmp->nm_flag &
- (NFSMNT_NFSV3 | NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
- nfs_decode_args(mp, nmp, &args, NULL);
- goto out;
- }
-
- /*
- * Make the nfs_ip_paranoia sysctl serve as the default connection
- * or no-connection mode for those protocols that support
- * no-connection mode (the flag will be cleared later for protocols
- * that do not support no-connection mode). This will allow a client
- * to receive replies from a different IP then the request was
- * sent to. Note: default value for nfs_ip_paranoia is 1 (paranoid),
- * not 0.
- */
- if (nfs_ip_paranoia == 0)
- args.flags |= NFSMNT_NOCONN;
-
- if (has_nfs_args_opt) {
- /*
- * In the 'nfs_args' case, the pointers in the args
- * structure are in userland - we copy them in here.
- */
- if (!has_fh_opt) {
- error = copyin((caddr_t)args.fh, (caddr_t)nfh,
- args.fhsize);
- if (error) {
- goto out;
- }
- args.fh = nfh;
- }
- if (!has_hostname_opt) {
- error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
- if (error) {
- goto out;
- }
- bzero(&hst[len], MNAMELEN - len);
- args.hostname = hst;
- }
- if (!has_addr_opt) {
- /* sockargs() call must be after above copyin() calls */
- error = getsockaddr(&nam, (caddr_t)args.addr,
- args.addrlen);
- if (error) {
- goto out;
- }
- }
- } else if (has_addr_opt == 0) {
- vfs_mount_error(mp, "No server address");
- error = EINVAL;
- goto out;
- }
- error = mountnfs(&args, mp, nam, args.hostname, &vp,
- curthread->td_ucred, nametimeo, negnametimeo);
-out:
- if (!error) {
- MNT_ILOCK(mp);
- mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
- MNT_IUNLOCK(mp);
- }
- return (error);
-}
-
-
-/*
- * VFS Operations.
- *
- * mount system call
- * It seems a bit dumb to copyinstr() the host and path here and then
- * bcopy() them in mountnfs(), but I wanted to detect errors before
- * doing the sockargs() call because sockargs() allocates an mbuf and
- * an error after that means that I have to release the mbuf.
- */
-/* ARGSUSED */
-static int
-nfs_cmount(struct mntarg *ma, void *data, uint64_t flags)
-{
- int error;
- struct nfs_args args;
-
- error = copyin(data, &args, sizeof (struct nfs_args));
- if (error)
- return error;
-
- ma = mount_arg(ma, "nfs_args", &args, sizeof args);
-
- error = kernel_mount(ma, flags);
- return (error);
-}
-
-/*
- * Common code for mount and mountroot
- */
-static int
-mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
- char *hst, struct vnode **vpp, struct ucred *cred, int nametimeo,
- int negnametimeo)
-{
- struct nfsmount *nmp;
- struct nfsnode *np;
- int error;
- struct vattr attrs;
-
- if (mp->mnt_flag & MNT_UPDATE) {
- nmp = VFSTONFS(mp);
- printf("%s: MNT_UPDATE is no longer handled here\n", __func__);
- free(nam, M_SONAME);
- return (0);
- } else {
- nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
- bzero((caddr_t)nmp, sizeof (struct nfsmount));
- TAILQ_INIT(&nmp->nm_bufq);
- mp->mnt_data = nmp;
- nmp->nm_getinfo = nfs_getnlminfo;
- nmp->nm_vinvalbuf = nfs_vinvalbuf;
- }
- vfs_getnewfsid(mp);
- nmp->nm_mountp = mp;
- mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF);
-
- /*
- * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
- * high, depending on whether we end up with negative offsets in
- * the client or server somewhere. 2GB-1 may be safer.
- *
- * For V3, nfs_fsinfo will adjust this as necessary. Assume maximum
- * that we can handle until we find out otherwise.
- */
- if ((argp->flags & NFSMNT_NFSV3) == 0)
- nmp->nm_maxfilesize = 0xffffffffLL;
- else
- nmp->nm_maxfilesize = OFF_MAX;
-
- nmp->nm_timeo = NFS_TIMEO;
- nmp->nm_retry = NFS_RETRANS;
- if ((argp->flags & NFSMNT_NFSV3) && argp->sotype == SOCK_STREAM) {
- nmp->nm_wsize = nmp->nm_rsize = NFS_MAXDATA;
- } else {
- nmp->nm_wsize = NFS_WSIZE;
- nmp->nm_rsize = NFS_RSIZE;
- }
- nmp->nm_wcommitsize = hibufspace / (desiredvnodes / 1000);
- nmp->nm_readdirsize = NFS_READDIRSIZE;
- nmp->nm_numgrps = NFS_MAXGRPS;
- nmp->nm_readahead = NFS_DEFRAHEAD;
- nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
- nmp->nm_nametimeo = nametimeo;
- nmp->nm_negnametimeo = negnametimeo;
- nmp->nm_tprintf_delay = nfs_tprintf_delay;
- if (nmp->nm_tprintf_delay < 0)
- nmp->nm_tprintf_delay = 0;
- nmp->nm_tprintf_initial_delay = nfs_tprintf_initial_delay;
- if (nmp->nm_tprintf_initial_delay < 0)
- nmp->nm_tprintf_initial_delay = 0;
- nmp->nm_fhsize = argp->fhsize;
- bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);
- bcopy(hst, mp->mnt_stat.f_mntfromname, MNAMELEN);
- nmp->nm_nam = nam;
- /* Set up the sockets and per-host congestion */
- nmp->nm_sotype = argp->sotype;
- nmp->nm_soproto = argp->proto;
- nmp->nm_rpcops = &nfs_rpcops;
-
- nfs_decode_args(mp, nmp, argp, hst);
-
- /*
- * For Connection based sockets (TCP,...) defer the connect until
- * the first request, in case the server is not responding.
- */
- if (nmp->nm_sotype == SOCK_DGRAM &&
- (error = nfs_connect(nmp)))
- goto bad;
-
- /*
- * This is silly, but it has to be set so that vinifod() works.
- * We do not want to do an nfs_statfs() here since we can get
- * stuck on a dead server and we are holding a lock on the mount
- * point.
- */
- mtx_lock(&nmp->nm_mtx);
- mp->mnt_stat.f_iosize = nfs_iosize(nmp);
- mtx_unlock(&nmp->nm_mtx);
- /*
- * A reference count is needed on the nfsnode representing the
- * remote root. If this object is not persistent, then backward
- * traversals of the mount point (i.e. "..") will not work if
- * the nfsnode gets flushed out of the cache. Ufs does not have
- * this problem, because one can identify root inodes by their
- * number == ROOTINO (2).
- */
- error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
- if (error)
- goto bad;
- *vpp = NFSTOV(np);
-
- /*
- * Get file attributes and transfer parameters for the
- * mountpoint. This has the side effect of filling in
- * (*vpp)->v_type with the correct value.
- */
- if (argp->flags & NFSMNT_NFSV3)
- nfs_fsinfo(nmp, *vpp, curthread->td_ucred, curthread);
- else
- VOP_GETATTR(*vpp, &attrs, curthread->td_ucred);
-
- /*
- * Lose the lock but keep the ref.
- */
- VOP_UNLOCK(*vpp, 0);
-
- return (0);
-bad:
- nfs_disconnect(nmp);
- mtx_destroy(&nmp->nm_mtx);
- uma_zfree(nfsmount_zone, nmp);
- free(nam, M_SONAME);
- return (error);
-}
-
-/*
- * unmount system call
- */
-static int
-nfs_unmount(struct mount *mp, int mntflags)
-{
- struct nfsmount *nmp;
- int error, flags = 0, i;
-
- if (mntflags & MNT_FORCE)
- flags |= FORCECLOSE;
- nmp = VFSTONFS(mp);
- /*
- * Goes something like this..
- * - Call vflush() to clear out vnodes for this filesystem
- * - Close the socket
- * - Free up the data structures
- */
- /* In the forced case, cancel any outstanding requests. */
- if (flags & FORCECLOSE) {
- error = nfs_nmcancelreqs(nmp);
- if (error)
- goto out;
- }
- /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */
- error = vflush(mp, 1, flags, curthread);
- if (error)
- goto out;
-
- /*
- * We are now committed to the unmount.
- */
- /* Make sure no nfsiods are assigned to this mount. */
- mtx_lock(&nfs_iod_mtx);
- for (i = 0; i < NFS_MAXASYNCDAEMON; i++)
- if (nfs_iodmount[i] == nmp) {
- nfs_iodwant[i] = NFSIOD_AVAILABLE;
- nfs_iodmount[i] = NULL;
- }
- mtx_unlock(&nfs_iod_mtx);
- nfs_disconnect(nmp);
- free(nmp->nm_nam, M_SONAME);
-
- mtx_destroy(&nmp->nm_mtx);
- uma_zfree(nfsmount_zone, nmp);
-out:
- return (error);
-}
-
-/*
- * Return root of a filesystem
- */
-static int
-nfs_root(struct mount *mp, int flags, struct vnode **vpp)
-{
- struct vnode *vp;
- struct nfsmount *nmp;
- struct nfsnode *np;
- int error;
-
- nmp = VFSTONFS(mp);
- error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, flags);
- if (error)
- return error;
- vp = NFSTOV(np);
- /*
- * Get transfer parameters and attributes for root vnode once.
- */
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_state & NFSSTA_GOTFSINFO) == 0 &&
- (nmp->nm_flag & NFSMNT_NFSV3)) {
- mtx_unlock(&nmp->nm_mtx);
- nfs_fsinfo(nmp, vp, curthread->td_ucred, curthread);
- } else
- mtx_unlock(&nmp->nm_mtx);
- if (vp->v_type == VNON)
- vp->v_type = VDIR;
- vp->v_vflag |= VV_ROOT;
- *vpp = vp;
- return (0);
-}
-
-/*
- * Flush out the buffer cache
- */
-/* ARGSUSED */
-static int
-nfs_sync(struct mount *mp, int waitfor)
-{
- struct vnode *vp, *mvp;
- struct thread *td;
- int error, allerror = 0;
-
- td = curthread;
-
- MNT_ILOCK(mp);
- /*
- * If a forced dismount is in progress, return from here so that
- * the umount(2) syscall doesn't get stuck in VFS_SYNC() before
- * calling VFS_UNMOUNT().
- */
- if ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0) {
- MNT_IUNLOCK(mp);
- return (EBADF);
- }
- MNT_IUNLOCK(mp);
-
- /*
- * Force stale buffer cache information to be flushed.
- */
-loop:
- MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
- /* XXX Racy bv_cnt check. */
- if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
- waitfor == MNT_LAZY) {
- VI_UNLOCK(vp);
- continue;
- }
- if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
- MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
- goto loop;
- }
- error = VOP_FSYNC(vp, waitfor, td);
- if (error)
- allerror = error;
- VOP_UNLOCK(vp, 0);
- vrele(vp);
- }
- return (allerror);
-}
-
-static int
-nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
-{
- struct nfsmount *nmp = VFSTONFS(mp);
- struct vfsquery vq;
- int error;
-
- bzero(&vq, sizeof(vq));
- switch (op) {
-#if 0
- case VFS_CTL_NOLOCKS:
- val = (nmp->nm_flag & NFSMNT_NOLOCKS) ? 1 : 0;
- if (req->oldptr != NULL) {
- error = SYSCTL_OUT(req, &val, sizeof(val));
- if (error)
- return (error);
- }
- if (req->newptr != NULL) {
- error = SYSCTL_IN(req, &val, sizeof(val));
- if (error)
- return (error);
- if (val)
- nmp->nm_flag |= NFSMNT_NOLOCKS;
- else
- nmp->nm_flag &= ~NFSMNT_NOLOCKS;
- }
- break;
-#endif
- case VFS_CTL_QUERY:
- mtx_lock(&nmp->nm_mtx);
- if (nmp->nm_state & NFSSTA_TIMEO)
- vq.vq_flags |= VQ_NOTRESP;
- mtx_unlock(&nmp->nm_mtx);
-#if 0
- if (!(nmp->nm_flag & NFSMNT_NOLOCKS) &&
- (nmp->nm_state & NFSSTA_LOCKTIMEO))
- vq.vq_flags |= VQ_NOTRESPLOCK;
-#endif
- error = SYSCTL_OUT(req, &vq, sizeof(vq));
- break;
- case VFS_CTL_TIMEO:
- if (req->oldptr != NULL) {
- error = SYSCTL_OUT(req, &nmp->nm_tprintf_initial_delay,
- sizeof(nmp->nm_tprintf_initial_delay));
- if (error)
- return (error);
- }
- if (req->newptr != NULL) {
- error = vfs_suser(mp, req->td);
- if (error)
- return (error);
- error = SYSCTL_IN(req, &nmp->nm_tprintf_initial_delay,
- sizeof(nmp->nm_tprintf_initial_delay));
- if (error)
- return (error);
- if (nmp->nm_tprintf_initial_delay < 0)
- nmp->nm_tprintf_initial_delay = 0;
- }
- break;
- default:
- return (ENOTSUP);
- }
- return (0);
-}
-
-/*
- * Extract the information needed by the nlm from the nfs vnode.
- */
-static void
-nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, size_t *fhlenp,
- struct sockaddr_storage *sp, int *is_v3p, off_t *sizep,
- struct timeval *timeop)
-{
- struct nfsmount *nmp;
- struct nfsnode *np = VTONFS(vp);
-
- nmp = VFSTONFS(vp->v_mount);
- if (fhlenp != NULL)
- *fhlenp = (size_t)np->n_fhsize;
- if (fhp != NULL)
- bcopy(np->n_fhp, fhp, np->n_fhsize);
- if (sp != NULL)
- bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
- if (is_v3p != NULL)
- *is_v3p = NFS_ISV3(vp);
- if (sizep != NULL)
- *sizep = np->n_size;
- if (timeop != NULL) {
- timeop->tv_sec = nmp->nm_timeo / NFS_HZ;
- timeop->tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
- }
-}
-
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
deleted file mode 100644
index 2516d7d..0000000
--- a/sys/nfsclient/nfs_vnops.c
+++ /dev/null
@@ -1,3544 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * vnode op calls for Sun NFS version 2 and 3
- */
-
-#include "opt_inet.h"
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/resourcevar.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/jail.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/namei.h>
-#include <sys/socket.h>
-#include <sys/vnode.h>
-#include <sys/dirent.h>
-#include <sys/fcntl.h>
-#include <sys/lockf.h>
-#include <sys/rwlock.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/signalvar.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsclient/nfs.h>
-#include <nfsclient/nfsnode.h>
-#include <nfsclient/nfsmount.h>
-#include <nfs/nfs_kdtrace.h>
-#include <nfs/nfs_lock.h>
-#include <nfs/xdr_subs.h>
-#include <nfsclient/nfsm_subs.h>
-
-#include <net/if.h>
-#include <net/if_var.h>
-#include <net/vnet.h>
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-
-#include <machine/stdarg.h>
-
-#ifdef KDTRACE_HOOKS
-#include <sys/dtrace_bsd.h>
-
-dtrace_nfsclient_accesscache_flush_probe_func_t
- dtrace_nfsclient_accesscache_flush_done_probe;
-uint32_t nfsclient_accesscache_flush_done_id;
-
-dtrace_nfsclient_accesscache_get_probe_func_t
- dtrace_nfsclient_accesscache_get_hit_probe,
- dtrace_nfsclient_accesscache_get_miss_probe;
-uint32_t nfsclient_accesscache_get_hit_id;
-uint32_t nfsclient_accesscache_get_miss_id;
-
-dtrace_nfsclient_accesscache_load_probe_func_t
- dtrace_nfsclient_accesscache_load_done_probe;
-uint32_t nfsclient_accesscache_load_done_id;
-#endif /* !KDTRACE_HOOKS */
-
-/* Defs */
-#define TRUE 1
-#define FALSE 0
-
-/*
- * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
- * calls are not in getblk() and brelse() so that they would not be necessary
- * here.
- */
-#ifndef B_VMIO
-#define vfs_busy_pages(bp, f)
-#endif
-
-static vop_read_t nfsfifo_read;
-static vop_write_t nfsfifo_write;
-static vop_close_t nfsfifo_close;
-static int nfs_flush(struct vnode *, int, int);
-static int nfs_setattrrpc(struct vnode *, struct vattr *, struct ucred *);
-static vop_lookup_t nfs_lookup;
-static vop_create_t nfs_create;
-static vop_mknod_t nfs_mknod;
-static vop_open_t nfs_open;
-static vop_close_t nfs_close;
-static vop_access_t nfs_access;
-static vop_getattr_t nfs_getattr;
-static vop_setattr_t nfs_setattr;
-static vop_read_t nfs_read;
-static vop_fsync_t nfs_fsync;
-static vop_remove_t nfs_remove;
-static vop_link_t nfs_link;
-static vop_rename_t nfs_rename;
-static vop_mkdir_t nfs_mkdir;
-static vop_rmdir_t nfs_rmdir;
-static vop_symlink_t nfs_symlink;
-static vop_readdir_t nfs_readdir;
-static vop_strategy_t nfs_strategy;
-static int nfs_lookitup(struct vnode *, const char *, int,
- struct ucred *, struct thread *, struct nfsnode **);
-static int nfs_sillyrename(struct vnode *, struct vnode *,
- struct componentname *);
-static vop_access_t nfsspec_access;
-static vop_readlink_t nfs_readlink;
-static vop_print_t nfs_print;
-static vop_advlock_t nfs_advlock;
-static vop_advlockasync_t nfs_advlockasync;
-
-/*
- * Global vfs data structures for nfs
- */
-struct vop_vector nfs_vnodeops = {
- .vop_default = &default_vnodeops,
- .vop_access = nfs_access,
- .vop_advlock = nfs_advlock,
- .vop_advlockasync = nfs_advlockasync,
- .vop_close = nfs_close,
- .vop_create = nfs_create,
- .vop_fsync = nfs_fsync,
- .vop_getattr = nfs_getattr,
- .vop_getpages = nfs_getpages,
- .vop_putpages = nfs_putpages,
- .vop_inactive = nfs_inactive,
- .vop_link = nfs_link,
- .vop_lookup = nfs_lookup,
- .vop_mkdir = nfs_mkdir,
- .vop_mknod = nfs_mknod,
- .vop_open = nfs_open,
- .vop_print = nfs_print,
- .vop_read = nfs_read,
- .vop_readdir = nfs_readdir,
- .vop_readlink = nfs_readlink,
- .vop_reclaim = nfs_reclaim,
- .vop_remove = nfs_remove,
- .vop_rename = nfs_rename,
- .vop_rmdir = nfs_rmdir,
- .vop_setattr = nfs_setattr,
- .vop_strategy = nfs_strategy,
- .vop_symlink = nfs_symlink,
- .vop_write = nfs_write,
-};
-
-struct vop_vector nfs_fifoops = {
- .vop_default = &fifo_specops,
- .vop_access = nfsspec_access,
- .vop_close = nfsfifo_close,
- .vop_fsync = nfs_fsync,
- .vop_getattr = nfs_getattr,
- .vop_inactive = nfs_inactive,
- .vop_print = nfs_print,
- .vop_read = nfsfifo_read,
- .vop_reclaim = nfs_reclaim,
- .vop_setattr = nfs_setattr,
- .vop_write = nfsfifo_write,
-};
-
-static int nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp,
- struct componentname *cnp, struct vattr *vap);
-static int nfs_removerpc(struct vnode *dvp, const char *name, int namelen,
- struct ucred *cred, struct thread *td);
-static int nfs_renamerpc(struct vnode *fdvp, const char *fnameptr,
- int fnamelen, struct vnode *tdvp,
- const char *tnameptr, int tnamelen,
- struct ucred *cred, struct thread *td);
-static int nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
- struct sillyrename *sp);
-
-/*
- * Global variables
- */
-struct mtx nfs_iod_mtx;
-enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON];
-struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
-int nfs_numasync = 0;
-#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
-
-SYSCTL_DECL(_vfs_oldnfs);
-
-static int nfsaccess_cache_timeout = NFS_MAXATTRTIMO;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, access_cache_timeout, CTLFLAG_RW,
- &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout");
-
-static int nfs_prime_access_cache = 0;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, prime_access_cache, CTLFLAG_RW,
- &nfs_prime_access_cache, 0,
- "Prime NFS ACCESS cache when fetching attributes");
-
-static int nfsv3_commit_on_close = 0;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW,
- &nfsv3_commit_on_close, 0, "write+commit on close, else only write");
-
-static int nfs_clean_pages_on_close = 1;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, clean_pages_on_close, CTLFLAG_RW,
- &nfs_clean_pages_on_close, 0, "NFS clean dirty pages on close");
-
-int nfs_directio_enable = 0;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_directio_enable, CTLFLAG_RW,
- &nfs_directio_enable, 0, "Enable NFS directio");
-
-/*
- * This sysctl allows other processes to mmap a file that has been opened
- * O_DIRECT by a process. In general, having processes mmap the file while
- * Direct IO is in progress can lead to Data Inconsistencies. But, we allow
- * this by default to prevent DoS attacks - to prevent a malicious user from
- * opening up files O_DIRECT preventing other users from mmap'ing these
- * files. "Protected" environments where stricter consistency guarantees are
- * required can disable this knob. The process that opened the file O_DIRECT
- * cannot mmap() the file, because mmap'ed IO on an O_DIRECT open() is not
- * meaningful.
- */
-int nfs_directio_allow_mmap = 1;
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, nfs_directio_allow_mmap, CTLFLAG_RW,
- &nfs_directio_allow_mmap, 0, "Enable mmaped IO on file with O_DIRECT opens");
-
-#if 0
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, access_cache_hits, CTLFLAG_RD,
- &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
-
-SYSCTL_INT(_vfs_oldnfs, OID_AUTO, access_cache_misses, CTLFLAG_RD,
- &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count");
-#endif
-
-#define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \
- | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \
- | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP)
-
-/*
- * SMP Locking Note :
- * The list of locks after the description of the lock is the ordering
- * of other locks acquired with the lock held.
- * np->n_mtx : Protects the fields in the nfsnode.
- VM Object Lock
- VI_MTX (acquired indirectly)
- * nmp->nm_mtx : Protects the fields in the nfsmount.
- rep->r_mtx
- * nfs_iod_mtx : Global lock, protects shared nfsiod state.
- * nfs_reqq_mtx : Global lock, protects the nfs_reqq list.
- nmp->nm_mtx
- rep->r_mtx
- * rep->r_mtx : Protects the fields in an nfsreq.
- */
-
-static int
-nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td,
- struct ucred *cred, uint32_t *retmode)
-{
- const int v3 = 1;
- u_int32_t *tl;
- int error = 0, attrflag, i, lrupos;
-
- struct mbuf *mreq, *mrep, *md, *mb;
- caddr_t bpos, dpos;
- u_int32_t rmode;
- struct nfsnode *np = VTONFS(vp);
-
- nfsstats.rpccnt[NFSPROC_ACCESS]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED, M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = txdr_unsigned(wmode);
- nfsm_request(vp, NFSPROC_ACCESS, td, cred);
- nfsm_postop_attr(vp, attrflag);
- if (!error) {
- lrupos = 0;
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- rmode = fxdr_unsigned(u_int32_t, *tl);
- mtx_lock(&np->n_mtx);
- for (i = 0; i < NFS_ACCESSCACHESIZE; i++) {
- if (np->n_accesscache[i].uid == cred->cr_uid) {
- np->n_accesscache[i].mode = rmode;
- np->n_accesscache[i].stamp = time_second;
- break;
- }
- if (i > 0 && np->n_accesscache[i].stamp <
- np->n_accesscache[lrupos].stamp)
- lrupos = i;
- }
- if (i == NFS_ACCESSCACHESIZE) {
- np->n_accesscache[lrupos].uid = cred->cr_uid;
- np->n_accesscache[lrupos].mode = rmode;
- np->n_accesscache[lrupos].stamp = time_second;
- }
- mtx_unlock(&np->n_mtx);
- if (retmode != NULL)
- *retmode = rmode;
- KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, cred->cr_uid, rmode, 0);
- }
- m_freem(mrep);
-nfsmout:
-#ifdef KDTRACE_HOOKS
- if (error) {
- KDTRACE_NFS_ACCESSCACHE_LOAD_DONE(vp, cred->cr_uid, 0,
- error);
- }
-#endif
- return (error);
-}
-
-/*
- * nfs access vnode op.
- * For nfs version 2, just return ok. File accesses may fail later.
- * For nfs version 3, use the access rpc to check accessibility. If file modes
- * are changed on the server, accesses might still fail later.
- */
-static int
-nfs_access(struct vop_access_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- int error = 0, i, gotahit;
- u_int32_t mode, rmode, wmode;
- int v3 = NFS_ISV3(vp);
- struct nfsnode *np = VTONFS(vp);
-
- /*
- * Disallow write attempts on filesystems mounted read-only;
- * unless the file is a socket, fifo, or a block or character
- * device resident on the filesystem.
- */
- if ((ap->a_accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
- switch (vp->v_type) {
- case VREG:
- case VDIR:
- case VLNK:
- return (EROFS);
- default:
- break;
- }
- }
- /*
- * For nfs v3, check to see if we have done this recently, and if
- * so return our cached result instead of making an ACCESS call.
- * If not, do an access rpc, otherwise you are stuck emulating
- * ufs_access() locally using the vattr. This may not be correct,
- * since the server may apply other access criteria such as
- * client uid-->server uid mapping that we do not know about.
- */
- if (v3) {
- if (ap->a_accmode & VREAD)
- mode = NFSV3ACCESS_READ;
- else
- mode = 0;
- if (vp->v_type != VDIR) {
- if (ap->a_accmode & VWRITE)
- mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
- if (ap->a_accmode & VEXEC)
- mode |= NFSV3ACCESS_EXECUTE;
- } else {
- if (ap->a_accmode & VWRITE)
- mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
- NFSV3ACCESS_DELETE);
- if (ap->a_accmode & VEXEC)
- mode |= NFSV3ACCESS_LOOKUP;
- }
- /* XXX safety belt, only make blanket request if caching */
- if (nfsaccess_cache_timeout > 0) {
- wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY |
- NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE |
- NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP;
- } else {
- wmode = mode;
- }
-
- /*
- * Does our cached result allow us to give a definite yes to
- * this request?
- */
- gotahit = 0;
- mtx_lock(&np->n_mtx);
- for (i = 0; i < NFS_ACCESSCACHESIZE; i++) {
- if (ap->a_cred->cr_uid == np->n_accesscache[i].uid) {
- if (time_second < (np->n_accesscache[i].stamp +
- nfsaccess_cache_timeout) &&
- (np->n_accesscache[i].mode & mode) == mode) {
- nfsstats.accesscache_hits++;
- gotahit = 1;
- }
- break;
- }
- }
- mtx_unlock(&np->n_mtx);
-#ifdef KDTRACE_HOOKS
- if (gotahit)
- KDTRACE_NFS_ACCESSCACHE_GET_HIT(vp,
- ap->a_cred->cr_uid, mode);
- else
- KDTRACE_NFS_ACCESSCACHE_GET_MISS(vp,
- ap->a_cred->cr_uid, mode);
-#endif
- if (gotahit == 0) {
- /*
- * Either a no, or a don't know. Go to the wire.
- */
- nfsstats.accesscache_misses++;
- error = nfs3_access_otw(vp, wmode, ap->a_td, ap->a_cred,
- &rmode);
- if (!error) {
- if ((rmode & mode) != mode)
- error = EACCES;
- }
- }
- return (error);
- } else {
- if ((error = nfsspec_access(ap)) != 0) {
- return (error);
- }
- /*
- * Attempt to prevent a mapped root from accessing a file
- * which it shouldn't. We try to read a byte from the file
- * if the user is root and the file is not zero length.
- * After calling nfsspec_access, we should have the correct
- * file size cached.
- */
- mtx_lock(&np->n_mtx);
- if (ap->a_cred->cr_uid == 0 && (ap->a_accmode & VREAD)
- && VTONFS(vp)->n_size > 0) {
- struct iovec aiov;
- struct uio auio;
- char buf[1];
-
- mtx_unlock(&np->n_mtx);
- aiov.iov_base = buf;
- aiov.iov_len = 1;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = 0;
- auio.uio_resid = 1;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_td = ap->a_td;
-
- if (vp->v_type == VREG)
- error = nfs_readrpc(vp, &auio, ap->a_cred);
- else if (vp->v_type == VDIR) {
- char* bp;
- bp = malloc(NFS_DIRBLKSIZ, M_TEMP, M_WAITOK);
- aiov.iov_base = bp;
- aiov.iov_len = auio.uio_resid = NFS_DIRBLKSIZ;
- error = nfs_readdirrpc(vp, &auio, ap->a_cred);
- free(bp, M_TEMP);
- } else if (vp->v_type == VLNK)
- error = nfs_readlinkrpc(vp, &auio, ap->a_cred);
- else
- error = EACCES;
- } else
- mtx_unlock(&np->n_mtx);
- return (error);
- }
-}
-
-int nfs_otw_getattr_avoid = 0;
-
-/*
- * nfs open vnode op
- * Check to see if the type is ok
- * and that deletion is not in progress.
- * For paged in text files, you will need to flush the page cache
- * if consistency is lost.
- */
-/* ARGSUSED */
-static int
-nfs_open(struct vop_open_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct vattr vattr;
- int error;
- int fmode = ap->a_mode;
- struct ucred *cred;
-
- if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
- return (EOPNOTSUPP);
-
- /*
- * Get a valid lease. If cached data is stale, flush it.
- */
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NMODIFIED) {
- mtx_unlock(&np->n_mtx);
- error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == EINTR || error == EIO)
- return (error);
- mtx_lock(&np->n_mtx);
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- if (vp->v_type == VDIR)
- np->n_direofoffset = 0;
- mtx_unlock(&np->n_mtx);
- error = VOP_GETATTR(vp, &vattr, ap->a_cred);
- if (error)
- return (error);
- mtx_lock(&np->n_mtx);
- np->n_mtime = vattr.va_mtime;
- } else {
- mtx_unlock(&np->n_mtx);
- error = VOP_GETATTR(vp, &vattr, ap->a_cred);
- if (error)
- return (error);
- mtx_lock(&np->n_mtx);
- if (NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
- if (vp->v_type == VDIR)
- np->n_direofoffset = 0;
- mtx_unlock(&np->n_mtx);
- error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error == EINTR || error == EIO) {
- return (error);
- }
- mtx_lock(&np->n_mtx);
- np->n_mtime = vattr.va_mtime;
- }
- }
- /*
- * If the object has >= 1 O_DIRECT active opens, we disable caching.
- */
- if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) {
- if (np->n_directio_opens == 0) {
- mtx_unlock(&np->n_mtx);
- error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- if (error)
- return (error);
- mtx_lock(&np->n_mtx);
- np->n_flag |= NNONCACHE;
- }
- np->n_directio_opens++;
- }
-
- /*
- * If this is an open for writing, capture a reference to the
- * credentials, so they can be used by nfs_putpages(). Using
- * these write credentials is preferable to the credentials of
- * whatever thread happens to be doing the VOP_PUTPAGES() since
- * the write RPCs are less likely to fail with EACCES.
- */
- if ((fmode & FWRITE) != 0) {
- cred = np->n_writecred;
- np->n_writecred = crhold(ap->a_cred);
- } else
- cred = NULL;
- mtx_unlock(&np->n_mtx);
- if (cred != NULL)
- crfree(cred);
- vnode_create_vobject(vp, vattr.va_size, ap->a_td);
- return (0);
-}
-
-/*
- * nfs close vnode op
- * What an NFS client should do upon close after writing is a debatable issue.
- * Most NFS clients push delayed writes to the server upon close, basically for
- * two reasons:
- * 1 - So that any write errors may be reported back to the client process
- * doing the close system call. By far the two most likely errors are
- * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
- * 2 - To put a worst case upper bound on cache inconsistency between
- * multiple clients for the file.
- * There is also a consistency problem for Version 2 of the protocol w.r.t.
- * not being able to tell if other clients are writing a file concurrently,
- * since there is no way of knowing if the changed modify time in the reply
- * is only due to the write for this client.
- * (NFS Version 3 provides weak cache consistency data in the reply that
- * should be sufficient to detect and handle this case.)
- *
- * The current code does the following:
- * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
- * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
- * or commit them (this satisfies 1 and 2 except for the
- * case where the server crashes after this close but
- * before the commit RPC, which is felt to be "good
- * enough". Changing the last argument to nfs_flush() to
- * a 1 would force a commit operation, if it is felt a
- * commit is necessary now.
- */
-/* ARGSUSED */
-static int
-nfs_close(struct vop_close_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- int error = 0;
- int fmode = ap->a_fflag;
-
- if (vp->v_type == VREG) {
- /*
- * Examine and clean dirty pages, regardless of NMODIFIED.
- * This closes a major hole in close-to-open consistency.
- * We want to push out all dirty pages (and buffers) on
- * close, regardless of whether they were dirtied by
- * mmap'ed writes or via write().
- */
- if (nfs_clean_pages_on_close && vp->v_object) {
- VM_OBJECT_WLOCK(vp->v_object);
- vm_object_page_clean(vp->v_object, 0, 0, 0);
- VM_OBJECT_WUNLOCK(vp->v_object);
- }
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NMODIFIED) {
- mtx_unlock(&np->n_mtx);
- if (NFS_ISV3(vp)) {
- /*
- * Under NFSv3 we have dirty buffers to dispose of. We
- * must flush them to the NFS server. We have the option
- * of waiting all the way through the commit rpc or just
- * waiting for the initial write. The default is to only
- * wait through the initial write so the data is in the
- * server's cache, which is roughly similar to the state
- * a standard disk subsystem leaves the file in on close().
- *
- * We cannot clear the NMODIFIED bit in np->n_flag due to
- * potential races with other processes, and certainly
- * cannot clear it if we don't commit.
- */
- int cm = nfsv3_commit_on_close ? 1 : 0;
- error = nfs_flush(vp, MNT_WAIT, cm);
- /* np->n_flag &= ~NMODIFIED; */
- } else
- error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- mtx_lock(&np->n_mtx);
- }
- if (np->n_flag & NWRITEERR) {
- np->n_flag &= ~NWRITEERR;
- error = np->n_error;
- }
- mtx_unlock(&np->n_mtx);
- }
- if (nfs_directio_enable)
- KASSERT((np->n_directio_asyncwr == 0),
- ("nfs_close: dirty unflushed (%d) directio buffers\n",
- np->n_directio_asyncwr));
- if (nfs_directio_enable && (fmode & O_DIRECT) && (vp->v_type == VREG)) {
- mtx_lock(&np->n_mtx);
- KASSERT((np->n_directio_opens > 0),
- ("nfs_close: unexpectedly value (0) of n_directio_opens\n"));
- np->n_directio_opens--;
- if (np->n_directio_opens == 0)
- np->n_flag &= ~NNONCACHE;
- mtx_unlock(&np->n_mtx);
- }
- return (error);
-}
-
-/*
- * nfs getattr call from vfs.
- */
-static int
-nfs_getattr(struct vop_getattr_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct thread *td = curthread;
- struct vattr *vap = ap->a_vap;
- struct vattr vattr;
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3 = NFS_ISV3(vp);
-
- /*
- * Update local times for special files.
- */
- mtx_lock(&np->n_mtx);
- if (np->n_flag & (NACC | NUPD))
- np->n_flag |= NCHG;
- mtx_unlock(&np->n_mtx);
- /*
- * First look in the cache.
- */
- if (nfs_getattrcache(vp, &vattr) == 0)
- goto nfsmout;
- if (v3 && nfs_prime_access_cache && nfsaccess_cache_timeout > 0) {
- nfsstats.accesscache_misses++;
- nfs3_access_otw(vp, NFSV3ACCESS_ALL, td, ap->a_cred, NULL);
- if (nfs_getattrcache(vp, &vattr) == 0)
- goto nfsmout;
- }
- nfsstats.rpccnt[NFSPROC_GETATTR]++;
- mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- nfsm_request(vp, NFSPROC_GETATTR, td, ap->a_cred);
- if (!error) {
- nfsm_loadattr(vp, &vattr);
- }
- m_freem(mrep);
-nfsmout:
- vap->va_type = vattr.va_type;
- vap->va_mode = vattr.va_mode;
- vap->va_nlink = vattr.va_nlink;
- vap->va_uid = vattr.va_uid;
- vap->va_gid = vattr.va_gid;
- vap->va_fsid = vattr.va_fsid;
- vap->va_fileid = vattr.va_fileid;
- vap->va_size = vattr.va_size;
- vap->va_blocksize = vattr.va_blocksize;
- vap->va_atime = vattr.va_atime;
- vap->va_mtime = vattr.va_mtime;
- vap->va_ctime = vattr.va_ctime;
- vap->va_gen = vattr.va_gen;
- vap->va_flags = vattr.va_flags;
- vap->va_rdev = vattr.va_rdev;
- vap->va_bytes = vattr.va_bytes;
- vap->va_filerev = vattr.va_filerev;
-
- return (error);
-}
-
-/*
- * nfs setattr call.
- */
-static int
-nfs_setattr(struct vop_setattr_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- int error = 0;
- u_quad_t tsize;
-
-#ifndef nolint
- tsize = (u_quad_t)0;
-#endif
-
- /*
- * Setting of flags is not supported.
- */
- if (vap->va_flags != VNOVAL)
- return (EOPNOTSUPP);
-
- /*
- * Disallow write attempts if the filesystem is mounted read-only.
- */
- if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
- vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
- vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
- (vp->v_mount->mnt_flag & MNT_RDONLY)) {
- error = EROFS;
- goto out;
- }
- if (vap->va_size != VNOVAL) {
- switch (vp->v_type) {
- case VDIR:
- return (EISDIR);
- case VCHR:
- case VBLK:
- case VSOCK:
- case VFIFO:
- if (vap->va_mtime.tv_sec == VNOVAL &&
- vap->va_atime.tv_sec == VNOVAL &&
- vap->va_mode == (mode_t)VNOVAL &&
- vap->va_uid == (uid_t)VNOVAL &&
- vap->va_gid == (gid_t)VNOVAL)
- return (0);
- vap->va_size = VNOVAL;
- break;
- default:
- /*
- * Disallow write attempts if the filesystem is
- * mounted read-only.
- */
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- /*
- * We run vnode_pager_setsize() early (why?),
- * we must set np->n_size now to avoid vinvalbuf
- * V_SAVE races that might setsize a lower
- * value.
- */
- mtx_lock(&np->n_mtx);
- tsize = np->n_size;
- mtx_unlock(&np->n_mtx);
- error = nfs_meta_setsize(vp, ap->a_cred, td,
- vap->va_size);
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NMODIFIED) {
- tsize = np->n_size;
- mtx_unlock(&np->n_mtx);
- if (vap->va_size == 0)
- error = nfs_vinvalbuf(vp, 0, td, 1);
- else
- error = nfs_vinvalbuf(vp, V_SAVE, td, 1);
- if (error) {
- vnode_pager_setsize(vp, tsize);
- goto out;
- }
- } else
- mtx_unlock(&np->n_mtx);
- /*
- * np->n_size has already been set to vap->va_size
- * in nfs_meta_setsize(). We must set it again since
- * nfs_loadattrcache() could be called through
- * nfs_meta_setsize() and could modify np->n_size.
- */
- mtx_lock(&np->n_mtx);
- np->n_vattr.va_size = np->n_size = vap->va_size;
- mtx_unlock(&np->n_mtx);
- };
- } else {
- mtx_lock(&np->n_mtx);
- if ((vap->va_mtime.tv_sec != VNOVAL || vap->va_atime.tv_sec != VNOVAL) &&
- (np->n_flag & NMODIFIED) && vp->v_type == VREG) {
- mtx_unlock(&np->n_mtx);
- if ((error = nfs_vinvalbuf(vp, V_SAVE, td, 1)) != 0 &&
- (error == EINTR || error == EIO))
- return error;
- } else
- mtx_unlock(&np->n_mtx);
- }
- error = nfs_setattrrpc(vp, vap, ap->a_cred);
- if (error && vap->va_size != VNOVAL) {
- mtx_lock(&np->n_mtx);
- np->n_size = np->n_vattr.va_size = tsize;
- vnode_pager_setsize(vp, tsize);
- mtx_unlock(&np->n_mtx);
- }
-out:
- return (error);
-}
-
-/*
- * Do an nfs setattr rpc.
- */
-static int
-nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred)
-{
- struct nfsv2_sattr *sp;
- struct nfsnode *np = VTONFS(vp);
- caddr_t bpos, dpos;
- u_int32_t *tl;
- int error = 0, i, wccflag = NFSV3_WCCRATTR;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3 = NFS_ISV3(vp);
-
- nfsstats.rpccnt[NFSPROC_SETATTR]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- if (v3) {
- nfsm_v3attrbuild(vap, TRUE);
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = nfs_false;
- } else {
- sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
- if (vap->va_mode == (mode_t)VNOVAL)
- sp->sa_mode = nfs_xdrneg1;
- else
- sp->sa_mode = vtonfsv2_mode(vp->v_type, vap->va_mode);
- if (vap->va_uid == (uid_t)VNOVAL)
- sp->sa_uid = nfs_xdrneg1;
- else
- sp->sa_uid = txdr_unsigned(vap->va_uid);
- if (vap->va_gid == (gid_t)VNOVAL)
- sp->sa_gid = nfs_xdrneg1;
- else
- sp->sa_gid = txdr_unsigned(vap->va_gid);
- sp->sa_size = txdr_unsigned(vap->va_size);
- txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
- txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
- }
- nfsm_request(vp, NFSPROC_SETATTR, curthread, cred);
- if (v3) {
- mtx_lock(&np->n_mtx);
- for (i = 0; i < NFS_ACCESSCACHESIZE; i++)
- np->n_accesscache[i].stamp = 0;
- mtx_unlock(&np->n_mtx);
- KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp);
- nfsm_wcc_data(vp, wccflag);
- } else
- nfsm_loadattr(vp, NULL);
- m_freem(mrep);
-nfsmout:
- return (error);
-}
-
-/*
- * nfs lookup call, one step at a time...
- * First look in cache
- * If not found, unlock the directory nfsnode and do the rpc
- */
-static int
-nfs_lookup(struct vop_lookup_args *ap)
-{
- struct componentname *cnp = ap->a_cnp;
- struct vnode *dvp = ap->a_dvp;
- struct vnode **vpp = ap->a_vpp;
- struct mount *mp = dvp->v_mount;
- struct vattr dvattr, vattr;
- struct timespec nctime;
- int flags = cnp->cn_flags;
- struct vnode *newvp;
- struct nfsmount *nmp;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep, *md, *mb;
- long len;
- nfsfh_t *fhp;
- struct nfsnode *np, *newnp;
- int error = 0, attrflag, dattrflag, fhsize, ltype, ncticks;
- int v3 = NFS_ISV3(dvp);
- struct thread *td = cnp->cn_thread;
-
- *vpp = NULLVP;
- if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) &&
- (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
- return (EROFS);
- if (dvp->v_type != VDIR)
- return (ENOTDIR);
- nmp = VFSTONFS(mp);
- np = VTONFS(dvp);
- if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) {
- *vpp = NULLVP;
- return (error);
- }
- error = cache_lookup(dvp, vpp, cnp, &nctime, &ncticks);
- if (error > 0 && error != ENOENT)
- return (error);
- if (error == -1) {
- /*
- * Lookups of "." are special and always return the
- * current directory. cache_lookup() already handles
- * associated locking bookkeeping, etc.
- */
- if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
- /* XXX: Is this really correct? */
- if (cnp->cn_nameiop != LOOKUP &&
- (flags & ISLASTCN))
- cnp->cn_flags |= SAVENAME;
- return (0);
- }
-
- /*
- * We only accept a positive hit in the cache if the
- * change time of the file matches our cached copy.
- * Otherwise, we discard the cache entry and fallback
- * to doing a lookup RPC. We also only trust cache
- * entries for less than nm_nametimeo seconds.
- *
- * To better handle stale file handles and attributes,
- * clear the attribute cache of this node if it is a
- * leaf component, part of an open() call, and not
- * locally modified before fetching the attributes.
- * This should allow stale file handles to be detected
- * here where we can fall back to a LOOKUP RPC to
- * recover rather than having nfs_open() detect the
- * stale file handle and failing open(2) with ESTALE.
- */
- newvp = *vpp;
- newnp = VTONFS(newvp);
- if (!(nmp->nm_flag & NFSMNT_NOCTO) &&
- (flags & (ISLASTCN | ISOPEN)) == (ISLASTCN | ISOPEN) &&
- !(newnp->n_flag & NMODIFIED)) {
- mtx_lock(&newnp->n_mtx);
- newnp->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp);
- mtx_unlock(&newnp->n_mtx);
- }
- if ((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) &&
- VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
- timespeccmp(&vattr.va_ctime, &nctime, ==)) {
- nfsstats.lookupcache_hits++;
- if (cnp->cn_nameiop != LOOKUP &&
- (flags & ISLASTCN))
- cnp->cn_flags |= SAVENAME;
- return (0);
- }
- cache_purge(newvp);
- if (dvp != newvp)
- vput(newvp);
- else
- vrele(newvp);
- *vpp = NULLVP;
- } else if (error == ENOENT) {
- if (dvp->v_iflag & VI_DOOMED)
- return (ENOENT);
- /*
- * We only accept a negative hit in the cache if the
- * modification time of the parent directory matches
- * the cached copy in the name cache entry.
- * Otherwise, we discard all of the negative cache
- * entries for this directory. We also only trust
- * negative cache entries for up to nm_negnametimeo
- * seconds.
- */
- if ((u_int)(ticks - ncticks) < (nmp->nm_negnametimeo * hz) &&
- VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 &&
- timespeccmp(&vattr.va_mtime, &nctime, ==)) {
- nfsstats.lookupcache_hits++;
- return (ENOENT);
- }
- cache_purge_negative(dvp);
- }
-
- attrflag = dattrflag = 0;
- error = 0;
- newvp = NULLVP;
- nfsstats.lookupcache_misses++;
- nfsstats.rpccnt[NFSPROC_LOOKUP]++;
- len = cnp->cn_namelen;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len), M_WAITOK,
- MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
- nfsm_request(dvp, NFSPROC_LOOKUP, cnp->cn_thread, cnp->cn_cred);
- if (error) {
- if (v3) {
- nfsm_postop_attr_va(dvp, dattrflag, &vattr);
- m_freem(mrep);
- }
- goto nfsmout;
- }
- nfsm_getfh(fhp, fhsize, v3);
-
- /*
- * Handle RENAME case...
- */
- if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) {
- if (NFS_CMPFH(np, fhp, fhsize)) {
- m_freem(mrep);
- return (EISDIR);
- }
- error = nfs_nget(mp, fhp, fhsize, &np, LK_EXCLUSIVE);
- if (error) {
- m_freem(mrep);
- return (error);
- }
- newvp = NFSTOV(np);
- if (v3) {
- nfsm_postop_attr(newvp, attrflag);
- nfsm_postop_attr(dvp, attrflag);
- } else
- nfsm_loadattr(newvp, NULL);
- *vpp = newvp;
- m_freem(mrep);
- cnp->cn_flags |= SAVENAME;
- return (0);
- }
-
- if (flags & ISDOTDOT) {
- ltype = VOP_ISLOCKED(dvp);
- error = vfs_busy(mp, MBF_NOWAIT);
- if (error != 0) {
- vfs_ref(mp);
- VOP_UNLOCK(dvp, 0);
- error = vfs_busy(mp, 0);
- vn_lock(dvp, ltype | LK_RETRY);
- vfs_rel(mp);
- if (error == 0 && (dvp->v_iflag & VI_DOOMED)) {
- vfs_unbusy(mp);
- error = ENOENT;
- }
- if (error != 0) {
- m_freem(mrep);
- return (error);
- }
- }
- VOP_UNLOCK(dvp, 0);
- error = nfs_nget(mp, fhp, fhsize, &np, cnp->cn_lkflags);
- if (error == 0)
- newvp = NFSTOV(np);
- vfs_unbusy(mp);
- if (newvp != dvp)
- vn_lock(dvp, ltype | LK_RETRY);
- if (dvp->v_iflag & VI_DOOMED) {
- if (error == 0) {
- if (newvp == dvp)
- vrele(newvp);
- else
- vput(newvp);
- }
- error = ENOENT;
- }
- if (error) {
- m_freem(mrep);
- return (error);
- }
- } else if (NFS_CMPFH(np, fhp, fhsize)) {
- VREF(dvp);
- newvp = dvp;
- } else {
- error = nfs_nget(mp, fhp, fhsize, &np, cnp->cn_lkflags);
- if (error) {
- m_freem(mrep);
- return (error);
- }
- newvp = NFSTOV(np);
-
- /*
- * Flush the attribute cache when opening a leaf node
- * to ensure that fresh attributes are fetched in
- * nfs_open() if we are unable to fetch attributes
- * from the LOOKUP reply.
- */
- if ((flags & (ISLASTCN | ISOPEN)) == (ISLASTCN | ISOPEN) &&
- !(np->n_flag & NMODIFIED)) {
- mtx_lock(&np->n_mtx);
- np->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp);
- mtx_unlock(&np->n_mtx);
- }
- }
- if (v3) {
- nfsm_postop_attr_va(newvp, attrflag, &vattr);
- nfsm_postop_attr_va(dvp, dattrflag, &dvattr);
- } else {
- nfsm_loadattr(newvp, &vattr);
- attrflag = 1;
- }
- if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
- cnp->cn_flags |= SAVENAME;
- if ((cnp->cn_flags & MAKEENTRY) &&
- (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) &&
- attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0))
- cache_enter_time(dvp, newvp, cnp, &vattr.va_ctime,
- newvp->v_type != VDIR ? NULL : &dvattr.va_ctime);
- *vpp = newvp;
- m_freem(mrep);
-nfsmout:
- if (error) {
- if (newvp != NULLVP) {
- vput(newvp);
- *vpp = NULLVP;
- }
-
- if (error != ENOENT)
- goto done;
-
- /* The requested file was not found. */
- if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
- (flags & ISLASTCN)) {
- /*
- * XXX: UFS does a full VOP_ACCESS(dvp,
- * VWRITE) here instead of just checking
- * MNT_RDONLY.
- */
- if (mp->mnt_flag & MNT_RDONLY)
- return (EROFS);
- cnp->cn_flags |= SAVENAME;
- return (EJUSTRETURN);
- }
-
- if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) {
- /*
- * Cache the modification time of the parent
- * directory from the post-op attributes in
- * the name cache entry. The negative cache
- * entry will be ignored once the directory
- * has changed. Don't bother adding the entry
- * if the directory has already changed.
- */
- mtx_lock(&np->n_mtx);
- if (timespeccmp(&np->n_vattr.va_mtime,
- &vattr.va_mtime, ==)) {
- mtx_unlock(&np->n_mtx);
- cache_enter_time(dvp, NULL, cnp,
- &vattr.va_mtime, NULL);
- } else
- mtx_unlock(&np->n_mtx);
- }
- return (ENOENT);
- }
-done:
- return (error);
-}
-
-/*
- * nfs read call.
- * Just call nfs_bioread() to do the work.
- */
-static int
-nfs_read(struct vop_read_args *ap)
-{
- struct vnode *vp = ap->a_vp;
-
- switch (vp->v_type) {
- case VREG:
- return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
- case VDIR:
- return (EISDIR);
- default:
- return (EOPNOTSUPP);
- }
-}
-
-/*
- * nfs readlink call
- */
-static int
-nfs_readlink(struct vop_readlink_args *ap)
-{
- struct vnode *vp = ap->a_vp;
-
- if (vp->v_type != VLNK)
- return (EINVAL);
- return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred));
-}
-
-/*
- * Do a readlink rpc.
- * Called by nfs_doio() from below the buffer cache.
- */
-int
-nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- caddr_t bpos, dpos;
- int error = 0, len, attrflag;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3 = NFS_ISV3(vp);
-
- nfsstats.rpccnt[NFSPROC_READLINK]++;
- mreq = m_get2(NFSX_FH(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- nfsm_request(vp, NFSPROC_READLINK, uiop->uio_td, cred);
- if (v3)
- nfsm_postop_attr(vp, attrflag);
- if (!error) {
- nfsm_strsiz(len, NFS_MAXPATHLEN);
- if (len == NFS_MAXPATHLEN) {
- struct nfsnode *np = VTONFS(vp);
- mtx_lock(&np->n_mtx);
- if (np->n_size && np->n_size < NFS_MAXPATHLEN)
- len = np->n_size;
- mtx_unlock(&np->n_mtx);
- }
- nfsm_mtouio(uiop, len);
- }
- m_freem(mrep);
-nfsmout:
- return (error);
-}
-
-/*
- * nfs read rpc call
- * Ditto above
- */
-int
-nfs_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- u_int32_t *tl;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep, *md, *mb;
- struct nfsmount *nmp;
- off_t end;
- int error = 0, len, retlen, tsiz, eof, attrflag;
- int v3 = NFS_ISV3(vp);
- int rsize;
-
-#ifndef nolint
- eof = 0;
-#endif
- nmp = VFSTONFS(vp->v_mount);
- tsiz = uiop->uio_resid;
- mtx_lock(&nmp->nm_mtx);
- end = uiop->uio_offset + tsiz;
- if (end > nmp->nm_maxfilesize || end < uiop->uio_offset) {
- mtx_unlock(&nmp->nm_mtx);
- return (EFBIG);
- }
- rsize = nmp->nm_rsize;
- mtx_unlock(&nmp->nm_mtx);
- while (tsiz > 0) {
- nfsstats.rpccnt[NFSPROC_READ]++;
- len = (tsiz > rsize) ? rsize : tsiz;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED * 3, M_WAITOK,
- MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED * 3);
- if (v3) {
- txdr_hyper(uiop->uio_offset, tl);
- *(tl + 2) = txdr_unsigned(len);
- } else {
- *tl++ = txdr_unsigned(uiop->uio_offset);
- *tl++ = txdr_unsigned(len);
- *tl = 0;
- }
- nfsm_request(vp, NFSPROC_READ, uiop->uio_td, cred);
- if (v3) {
- nfsm_postop_attr(vp, attrflag);
- if (error) {
- m_freem(mrep);
- goto nfsmout;
- }
- tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED);
- eof = fxdr_unsigned(int, *(tl + 1));
- } else {
- nfsm_loadattr(vp, NULL);
- }
- nfsm_strsiz(retlen, rsize);
- nfsm_mtouio(uiop, retlen);
- m_freem(mrep);
- tsiz -= retlen;
- if (v3) {
- if (eof || retlen == 0) {
- tsiz = 0;
- }
- } else if (retlen < len) {
- tsiz = 0;
- }
- }
-nfsmout:
- return (error);
-}
-
-/*
- * nfs write call
- */
-int
-nfs_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
- int *iomode, int *must_commit)
-{
- u_int32_t *tl;
- int32_t backup;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep, *md, *mb;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- off_t end;
- int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit;
- int v3 = NFS_ISV3(vp), committed = NFSV3WRITE_FILESYNC;
- int wsize;
-
- KASSERT(uiop->uio_iovcnt == 1, ("nfs: writerpc iovcnt > 1"));
- *must_commit = 0;
- tsiz = uiop->uio_resid;
- mtx_lock(&nmp->nm_mtx);
- end = uiop->uio_offset + tsiz;
- if (end > nmp->nm_maxfilesize || end < uiop->uio_offset) {
- mtx_unlock(&nmp->nm_mtx);
- return (EFBIG);
- }
- wsize = nmp->nm_wsize;
- mtx_unlock(&nmp->nm_mtx);
- while (tsiz > 0) {
- nfsstats.rpccnt[NFSPROC_WRITE]++;
- len = (tsiz > wsize) ? wsize : tsiz;
- mreq = m_get2(NFSX_FH(v3) + 5 * NFSX_UNSIGNED, M_WAITOK,
- MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- if (v3) {
- tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED);
- txdr_hyper(uiop->uio_offset, tl);
- tl += 2;
- *tl++ = txdr_unsigned(len);
- *tl++ = txdr_unsigned(*iomode);
- *tl = txdr_unsigned(len);
- } else {
- u_int32_t x;
-
- tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
- /* Set both "begin" and "current" to non-garbage. */
- x = txdr_unsigned((u_int32_t)uiop->uio_offset);
- *tl++ = x; /* "begin offset" */
- *tl++ = x; /* "current offset" */
- x = txdr_unsigned(len);
- *tl++ = x; /* total to this offset */
- *tl = x; /* size of this write */
- }
- nfsm_uiotom(uiop, len);
- nfsm_request(vp, NFSPROC_WRITE, uiop->uio_td, cred);
- if (v3) {
- wccflag = NFSV3_WCCCHK;
- nfsm_wcc_data(vp, wccflag);
- if (!error) {
- tl = nfsm_dissect(u_int32_t *, 2 * NFSX_UNSIGNED
- + NFSX_V3WRITEVERF);
- rlen = fxdr_unsigned(int, *tl++);
- if (rlen == 0) {
- error = NFSERR_IO;
- m_freem(mrep);
- break;
- } else if (rlen < len) {
- backup = len - rlen;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base -
- backup;
- uiop->uio_iov->iov_len += backup;
- uiop->uio_offset -= backup;
- uiop->uio_resid += backup;
- len = rlen;
- }
- commit = fxdr_unsigned(int, *tl++);
-
- /*
- * Return the lowest committment level
- * obtained by any of the RPCs.
- */
- if (committed == NFSV3WRITE_FILESYNC)
- committed = commit;
- else if (committed == NFSV3WRITE_DATASYNC &&
- commit == NFSV3WRITE_UNSTABLE)
- committed = commit;
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0){
- bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
- NFSX_V3WRITEVERF);
- nmp->nm_state |= NFSSTA_HASWRITEVERF;
- } else if (bcmp((caddr_t)tl,
- (caddr_t)nmp->nm_verf, NFSX_V3WRITEVERF)) {
- *must_commit = 1;
- bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
- NFSX_V3WRITEVERF);
- }
- mtx_unlock(&nmp->nm_mtx);
- }
- } else {
- nfsm_loadattr(vp, NULL);
- }
- if (wccflag) {
- mtx_lock(&(VTONFS(vp))->n_mtx);
- VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime;
- mtx_unlock(&(VTONFS(vp))->n_mtx);
- }
- m_freem(mrep);
- if (error)
- break;
- tsiz -= len;
- }
-nfsmout:
- if (DOINGASYNC(vp))
- committed = NFSV3WRITE_FILESYNC;
- *iomode = committed;
- if (error)
- uiop->uio_resid = tsiz;
- return (error);
-}
-
-/*
- * nfs mknod rpc
- * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
- * mode set to specify the file type and the size field for rdev.
- */
-static int
-nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
- struct vattr *vap)
-{
- struct nfsv2_sattr *sp;
- u_int32_t *tl;
- struct vnode *newvp = NULL;
- struct nfsnode *np = NULL;
- struct vattr vattr;
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
- struct mbuf *mreq, *mrep, *md, *mb;
- u_int32_t rdev;
- int v3 = NFS_ISV3(dvp);
-
- if (vap->va_type == VCHR || vap->va_type == VBLK)
- rdev = txdr_unsigned(vap->va_rdev);
- else if (vap->va_type == VFIFO || vap->va_type == VSOCK)
- rdev = nfs_xdrneg1;
- else {
- return (EOPNOTSUPP);
- }
- if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0)
- return (error);
- nfsstats.rpccnt[NFSPROC_MKNOD]++;
- mreq = m_get2(NFSX_FH(v3) + 4 * NFSX_UNSIGNED +
- nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
- if (v3) {
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl++ = vtonfsv3_type(vap->va_type);
- nfsm_v3attrbuild(vap, FALSE);
- if (vap->va_type == VCHR || vap->va_type == VBLK) {
- tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = txdr_unsigned(major(vap->va_rdev));
- *tl = txdr_unsigned(minor(vap->va_rdev));
- }
- } else {
- sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
- sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
- sp->sa_uid = nfs_xdrneg1;
- sp->sa_gid = nfs_xdrneg1;
- sp->sa_size = rdev;
- txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
- txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
- }
- nfsm_request(dvp, NFSPROC_MKNOD, cnp->cn_thread, cnp->cn_cred);
- if (!error) {
- nfsm_mtofh(dvp, newvp, v3, gotvp);
- if (!gotvp) {
- if (newvp) {
- vput(newvp);
- newvp = NULL;
- }
- error = nfs_lookitup(dvp, cnp->cn_nameptr,
- cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np);
- if (!error)
- newvp = NFSTOV(np);
- }
- }
- if (v3)
- nfsm_wcc_data(dvp, wccflag);
- m_freem(mrep);
-nfsmout:
- if (error) {
- if (newvp)
- vput(newvp);
- } else {
- *vpp = newvp;
- }
- mtx_lock(&(VTONFS(dvp))->n_mtx);
- VTONFS(dvp)->n_flag |= NMODIFIED;
- if (!wccflag) {
- VTONFS(dvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
- }
- mtx_unlock(&(VTONFS(dvp))->n_mtx);
- return (error);
-}
-
-/*
- * nfs mknod vop
- * just call nfs_mknodrpc() to do the work.
- */
-/* ARGSUSED */
-static int
-nfs_mknod(struct vop_mknod_args *ap)
-{
- return (nfs_mknodrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, ap->a_vap));
-}
-
-static u_long create_verf;
-/*
- * nfs file create call
- */
-static int
-nfs_create(struct vop_create_args *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct componentname *cnp = ap->a_cnp;
- struct nfsv2_sattr *sp;
- u_int32_t *tl;
- struct nfsnode *np = NULL;
- struct vnode *newvp = NULL;
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0;
- struct mbuf *mreq, *mrep, *md, *mb;
- struct vattr vattr;
- int v3 = NFS_ISV3(dvp);
-
- /*
- * Oops, not for me..
- */
- if (vap->va_type == VSOCK) {
- error = nfs_mknodrpc(dvp, ap->a_vpp, cnp, vap);
- return (error);
- }
-
- if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) {
- return (error);
- }
- if (vap->va_vaflags & VA_EXCLUSIVE)
- fmode |= O_EXCL;
-again:
- nfsstats.rpccnt[NFSPROC_CREATE]++;
- mreq = m_get2(NFSX_FH(v3) + 2 * NFSX_UNSIGNED +
- nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
- if (v3) {
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- if (fmode & O_EXCL) {
- *tl = txdr_unsigned(NFSV3CREATE_EXCLUSIVE);
- tl = nfsm_build(u_int32_t *, NFSX_V3CREATEVERF);
-#ifdef INET
- CURVNET_SET(CRED_TO_VNET(cnp->cn_cred));
- IN_IFADDR_RLOCK();
- if (!TAILQ_EMPTY(&V_in_ifaddrhead))
- *tl++ = IA_SIN(TAILQ_FIRST(&V_in_ifaddrhead))->sin_addr.s_addr;
- else
-#endif
- *tl++ = create_verf;
-#ifdef INET
- IN_IFADDR_RUNLOCK();
- CURVNET_RESTORE();
-#endif
- *tl = ++create_verf;
- } else {
- *tl = txdr_unsigned(NFSV3CREATE_UNCHECKED);
- nfsm_v3attrbuild(vap, FALSE);
- }
- } else {
- sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
- sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
- sp->sa_uid = nfs_xdrneg1;
- sp->sa_gid = nfs_xdrneg1;
- sp->sa_size = 0;
- txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
- txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
- }
- nfsm_request(dvp, NFSPROC_CREATE, cnp->cn_thread, cnp->cn_cred);
- if (!error) {
- nfsm_mtofh(dvp, newvp, v3, gotvp);
- if (!gotvp) {
- if (newvp) {
- vput(newvp);
- newvp = NULL;
- }
- error = nfs_lookitup(dvp, cnp->cn_nameptr,
- cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread, &np);
- if (!error)
- newvp = NFSTOV(np);
- }
- }
- if (v3)
- nfsm_wcc_data(dvp, wccflag);
- m_freem(mrep);
-nfsmout:
- if (error) {
- if (v3 && (fmode & O_EXCL) && error == NFSERR_NOTSUPP) {
- fmode &= ~O_EXCL;
- goto again;
- }
- if (newvp)
- vput(newvp);
- } else if (v3 && (fmode & O_EXCL)) {
- /*
- * We are normally called with only a partially initialized
- * VAP. Since the NFSv3 spec says that server may use the
- * file attributes to store the verifier, the spec requires
- * us to do a SETATTR RPC. FreeBSD servers store the verifier
- * in atime, but we can't really assume that all servers will
- * so we ensure that our SETATTR sets both atime and mtime.
- */
- if (vap->va_mtime.tv_sec == VNOVAL)
- vfs_timestamp(&vap->va_mtime);
- if (vap->va_atime.tv_sec == VNOVAL)
- vap->va_atime = vap->va_mtime;
- error = nfs_setattrrpc(newvp, vap, cnp->cn_cred);
- if (error)
- vput(newvp);
- }
- if (!error) {
- *ap->a_vpp = newvp;
- }
- mtx_lock(&(VTONFS(dvp))->n_mtx);
- VTONFS(dvp)->n_flag |= NMODIFIED;
- if (!wccflag) {
- VTONFS(dvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
- }
- mtx_unlock(&(VTONFS(dvp))->n_mtx);
- return (error);
-}
-
-/*
- * nfs file remove call
- * To try and make nfs semantics closer to ufs semantics, a file that has
- * other processes using the vnode is renamed instead of removed and then
- * removed later on the last close.
- * - If v_usecount > 1
- * If a rename is not already in the works
- * call nfs_sillyrename() to set it up
- * else
- * do the remove rpc
- */
-static int
-nfs_remove(struct vop_remove_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- struct nfsnode *np = VTONFS(vp);
- int error = 0;
- struct vattr vattr;
-
- KASSERT((cnp->cn_flags & HASBUF) != 0, ("nfs_remove: no name"));
- KASSERT(vrefcnt(vp) > 0, ("nfs_remove: bad v_usecount"));
- if (vp->v_type == VDIR)
- error = EPERM;
- else if (vrefcnt(vp) == 1 || (np->n_sillyrename &&
- !VOP_GETATTR(vp, &vattr, cnp->cn_cred) && vattr.va_nlink > 1)) {
- /*
- * Purge the name cache so that the chance of a lookup for
- * the name succeeding while the remove is in progress is
- * minimized. Without node locking it can still happen, such
- * that an I/O op returns ESTALE, but since you get this if
- * another host removes the file..
- */
- cache_purge(vp);
- /*
- * throw away biocache buffers, mainly to avoid
- * unnecessary delayed writes later.
- */
- error = nfs_vinvalbuf(vp, 0, cnp->cn_thread, 1);
- /* Do the rpc */
- if (error != EINTR && error != EIO)
- error = nfs_removerpc(dvp, cnp->cn_nameptr,
- cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread);
- /*
- * Kludge City: If the first reply to the remove rpc is lost..
- * the reply to the retransmitted request will be ENOENT
- * since the file was in fact removed
- * Therefore, we cheat and return success.
- */
- if (error == ENOENT)
- error = 0;
- } else if (!np->n_sillyrename)
- error = nfs_sillyrename(dvp, vp, cnp);
- mtx_lock(&np->n_mtx);
- np->n_attrstamp = 0;
- mtx_unlock(&np->n_mtx);
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- return (error);
-}
-
-/*
- * nfs file remove rpc called from nfs_inactive
- */
-int
-nfs_removeit(struct sillyrename *sp)
-{
- /*
- * Make sure that the directory vnode is still valid.
- * XXX we should lock sp->s_dvp here.
- */
- if (sp->s_dvp->v_type == VBAD)
- return (0);
- return (nfs_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred,
- NULL));
-}
-
-/*
- * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
- */
-static int
-nfs_removerpc(struct vnode *dvp, const char *name, int namelen,
- struct ucred *cred, struct thread *td)
-{
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3 = NFS_ISV3(dvp);
-
- nfsstats.rpccnt[NFSPROC_REMOVE]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(namelen),
- M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(name, namelen, NFS_MAXNAMLEN);
- nfsm_request(dvp, NFSPROC_REMOVE, td, cred);
- if (v3)
- nfsm_wcc_data(dvp, wccflag);
- m_freem(mrep);
-nfsmout:
- mtx_lock(&(VTONFS(dvp))->n_mtx);
- VTONFS(dvp)->n_flag |= NMODIFIED;
- if (!wccflag) {
- VTONFS(dvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
- }
- mtx_unlock(&(VTONFS(dvp))->n_mtx);
- return (error);
-}
-
-/*
- * nfs file rename call
- */
-static int
-nfs_rename(struct vop_rename_args *ap)
-{
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tvp = ap->a_tvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *tdvp = ap->a_tdvp;
- struct componentname *tcnp = ap->a_tcnp;
- struct componentname *fcnp = ap->a_fcnp;
- int error;
-
- KASSERT((tcnp->cn_flags & HASBUF) != 0 &&
- (fcnp->cn_flags & HASBUF) != 0, ("nfs_rename: no name"));
- /* Check for cross-device rename */
- if ((fvp->v_mount != tdvp->v_mount) ||
- (tvp && (fvp->v_mount != tvp->v_mount))) {
- error = EXDEV;
- goto out;
- }
-
- if (fvp == tvp) {
- nfs_printf("nfs_rename: fvp == tvp (can't happen)\n");
- error = 0;
- goto out;
- }
- if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
- goto out;
-
- /*
- * We have to flush B_DELWRI data prior to renaming
- * the file. If we don't, the delayed-write buffers
- * can be flushed out later after the file has gone stale
- * under NFSV3. NFSV2 does not have this problem because
- * ( as far as I can tell ) it flushes dirty buffers more
- * often.
- *
- * Skip the rename operation if the fsync fails, this can happen
- * due to the server's volume being full, when we pushed out data
- * that was written back to our cache earlier. Not checking for
- * this condition can result in potential (silent) data loss.
- */
- error = VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_thread);
- VOP_UNLOCK(fvp, 0);
- if (!error && tvp)
- error = VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_thread);
- if (error)
- goto out;
-
- /*
- * If the tvp exists and is in use, sillyrename it before doing the
- * rename of the new file over it.
- * XXX Can't sillyrename a directory.
- */
- if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename &&
- tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) {
- vput(tvp);
- tvp = NULL;
- }
-
- error = nfs_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
- tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
- tcnp->cn_thread);
-
- if (fvp->v_type == VDIR) {
- if (tvp != NULL && tvp->v_type == VDIR)
- cache_purge(tdvp);
- cache_purge(fdvp);
- }
-
-out:
- if (tdvp == tvp)
- vrele(tdvp);
- else
- vput(tdvp);
- if (tvp)
- vput(tvp);
- vrele(fdvp);
- vrele(fvp);
- /*
- * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
- */
- if (error == ENOENT)
- error = 0;
- return (error);
-}
-
-/*
- * nfs file rename rpc called from nfs_remove() above
- */
-static int
-nfs_renameit(struct vnode *sdvp, struct componentname *scnp,
- struct sillyrename *sp)
-{
-
- return (nfs_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp,
- sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread));
-}
-
-/*
- * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
- */
-static int
-nfs_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen,
- struct vnode *tdvp, const char *tnameptr, int tnamelen, struct ucred *cred,
- struct thread *td)
-{
- caddr_t bpos, dpos;
- int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3 = NFS_ISV3(fdvp);
-
- nfsstats.rpccnt[NFSPROC_RENAME]++;
- mreq = m_get2((NFSX_FH(v3) + NFSX_UNSIGNED)*2 + nfsm_rndup(fnamelen) +
- nfsm_rndup(tnamelen), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(fdvp, v3);
- nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN);
- nfsm_fhtom(tdvp, v3);
- nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN);
- nfsm_request(fdvp, NFSPROC_RENAME, td, cred);
- if (v3) {
- nfsm_wcc_data(fdvp, fwccflag);
- nfsm_wcc_data(tdvp, twccflag);
- }
- m_freem(mrep);
-nfsmout:
- mtx_lock(&(VTONFS(fdvp))->n_mtx);
- VTONFS(fdvp)->n_flag |= NMODIFIED;
- mtx_unlock(&(VTONFS(fdvp))->n_mtx);
- mtx_lock(&(VTONFS(tdvp))->n_mtx);
- VTONFS(tdvp)->n_flag |= NMODIFIED;
- mtx_unlock(&(VTONFS(tdvp))->n_mtx);
- if (!fwccflag) {
- VTONFS(fdvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(fdvp);
- }
- if (!twccflag) {
- VTONFS(tdvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(tdvp);
- }
- return (error);
-}
-
-/*
- * nfs hard link create call
- */
-static int
-nfs_link(struct vop_link_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *tdvp = ap->a_tdvp;
- struct componentname *cnp = ap->a_cnp;
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3;
-
- if (vp->v_mount != tdvp->v_mount) {
- return (EXDEV);
- }
-
- /*
- * Push all writes to the server, so that the attribute cache
- * doesn't get "out of sync" with the server.
- * XXX There should be a better way!
- */
- VOP_FSYNC(vp, MNT_WAIT, cnp->cn_thread);
-
- v3 = NFS_ISV3(vp);
- nfsstats.rpccnt[NFSPROC_LINK]++;
- mreq = m_get2(NFSX_FH(v3)*2 + NFSX_UNSIGNED +
- nfsm_rndup(cnp->cn_namelen), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- nfsm_fhtom(tdvp, v3);
- nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
- nfsm_request(vp, NFSPROC_LINK, cnp->cn_thread, cnp->cn_cred);
- if (v3) {
- nfsm_postop_attr(vp, attrflag);
- nfsm_wcc_data(tdvp, wccflag);
- }
- m_freem(mrep);
-nfsmout:
- mtx_lock(&(VTONFS(tdvp))->n_mtx);
- VTONFS(tdvp)->n_flag |= NMODIFIED;
- mtx_unlock(&(VTONFS(tdvp))->n_mtx);
- if (!attrflag) {
- VTONFS(vp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
- }
- if (!wccflag) {
- VTONFS(tdvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(tdvp);
- }
- return (error);
-}
-
-/*
- * nfs symbolic link create call
- */
-static int
-nfs_symlink(struct vop_symlink_args *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct componentname *cnp = ap->a_cnp;
- struct nfsv2_sattr *sp;
- caddr_t bpos, dpos;
- int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp;
- struct mbuf *mreq, *mrep, *md, *mb;
- struct vnode *newvp = NULL;
- int v3 = NFS_ISV3(dvp);
-
- nfsstats.rpccnt[NFSPROC_SYMLINK]++;
- slen = strlen(ap->a_target);
- mreq = m_get2(NFSX_FH(v3) + 2*NFSX_UNSIGNED +
- nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(v3),
- M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
- if (v3) {
- nfsm_v3attrbuild(vap, FALSE);
- }
- nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN);
- if (!v3) {
- sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
- sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode);
- sp->sa_uid = nfs_xdrneg1;
- sp->sa_gid = nfs_xdrneg1;
- sp->sa_size = nfs_xdrneg1;
- txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
- txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
- }
-
- /*
- * Issue the NFS request and get the rpc response.
- *
- * Only NFSv3 responses returning an error of 0 actually return
- * a file handle that can be converted into newvp without having
- * to do an extra lookup rpc.
- */
- nfsm_request(dvp, NFSPROC_SYMLINK, cnp->cn_thread, cnp->cn_cred);
- if (v3) {
- if (error == 0)
- nfsm_mtofh(dvp, newvp, v3, gotvp);
- nfsm_wcc_data(dvp, wccflag);
- }
-
- /*
- * out code jumps -> here, mrep is also freed.
- */
-
- m_freem(mrep);
-nfsmout:
-
- /*
- * If we do not have an error and we could not extract the newvp from
- * the response due to the request being NFSv2, we have to do a
- * lookup in order to obtain a newvp to return.
- */
- if (error == 0 && newvp == NULL) {
- struct nfsnode *np = NULL;
-
- error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
- cnp->cn_cred, cnp->cn_thread, &np);
- if (!error)
- newvp = NFSTOV(np);
- }
- if (error) {
- if (newvp)
- vput(newvp);
- } else {
- *ap->a_vpp = newvp;
- }
- mtx_lock(&(VTONFS(dvp))->n_mtx);
- VTONFS(dvp)->n_flag |= NMODIFIED;
- mtx_unlock(&(VTONFS(dvp))->n_mtx);
- if (!wccflag) {
- VTONFS(dvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
- }
- return (error);
-}
-
-/*
- * nfs make dir call
- */
-static int
-nfs_mkdir(struct vop_mkdir_args *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct componentname *cnp = ap->a_cnp;
- struct nfsv2_sattr *sp;
- int len;
- struct nfsnode *np = NULL;
- struct vnode *newvp = NULL;
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR;
- int gotvp = 0;
- struct mbuf *mreq, *mrep, *md, *mb;
- struct vattr vattr;
- int v3 = NFS_ISV3(dvp);
-
- if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0)
- return (error);
- len = cnp->cn_namelen;
- nfsstats.rpccnt[NFSPROC_MKDIR]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len) +
- NFSX_SATTR(v3), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN);
- if (v3) {
- nfsm_v3attrbuild(vap, FALSE);
- } else {
- sp = nfsm_build(struct nfsv2_sattr *, NFSX_V2SATTR);
- sp->sa_mode = vtonfsv2_mode(VDIR, vap->va_mode);
- sp->sa_uid = nfs_xdrneg1;
- sp->sa_gid = nfs_xdrneg1;
- sp->sa_size = nfs_xdrneg1;
- txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
- txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
- }
- nfsm_request(dvp, NFSPROC_MKDIR, cnp->cn_thread, cnp->cn_cred);
- if (!error)
- nfsm_mtofh(dvp, newvp, v3, gotvp);
- if (v3)
- nfsm_wcc_data(dvp, wccflag);
- m_freem(mrep);
-nfsmout:
- mtx_lock(&(VTONFS(dvp))->n_mtx);
- VTONFS(dvp)->n_flag |= NMODIFIED;
- mtx_unlock(&(VTONFS(dvp))->n_mtx);
- if (!wccflag) {
- VTONFS(dvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
- }
- if (error == 0 && newvp == NULL) {
- error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred,
- cnp->cn_thread, &np);
- if (!error) {
- newvp = NFSTOV(np);
- if (newvp->v_type != VDIR)
- error = EEXIST;
- }
- }
- if (error) {
- if (newvp)
- vput(newvp);
- } else
- *ap->a_vpp = newvp;
- return (error);
-}
-
-/*
- * nfs remove directory call
- */
-static int
-nfs_rmdir(struct vop_rmdir_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR;
- struct mbuf *mreq, *mrep, *md, *mb;
- int v3 = NFS_ISV3(dvp);
-
- if (dvp == vp)
- return (EINVAL);
- nfsstats.rpccnt[NFSPROC_RMDIR]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED +
- nfsm_rndup(cnp->cn_namelen), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN);
- nfsm_request(dvp, NFSPROC_RMDIR, cnp->cn_thread, cnp->cn_cred);
- if (v3)
- nfsm_wcc_data(dvp, wccflag);
- m_freem(mrep);
-nfsmout:
- mtx_lock(&(VTONFS(dvp))->n_mtx);
- VTONFS(dvp)->n_flag |= NMODIFIED;
- mtx_unlock(&(VTONFS(dvp))->n_mtx);
- if (!wccflag) {
- VTONFS(dvp)->n_attrstamp = 0;
- KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(dvp);
- }
- cache_purge(dvp);
- cache_purge(vp);
- /*
- * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
- */
- if (error == ENOENT)
- error = 0;
- return (error);
-}
-
-/*
- * nfs readdir call
- */
-static int
-nfs_readdir(struct vop_readdir_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct uio *uio = ap->a_uio;
- int tresid, error = 0;
- struct vattr vattr;
-
- if (vp->v_type != VDIR)
- return(EPERM);
-
- /*
- * First, check for hit on the EOF offset cache
- */
- if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset &&
- (np->n_flag & NMODIFIED) == 0) {
- if (VOP_GETATTR(vp, &vattr, ap->a_cred) == 0) {
- mtx_lock(&np->n_mtx);
- if (!NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
- mtx_unlock(&np->n_mtx);
- nfsstats.direofcache_hits++;
- goto out;
- } else
- mtx_unlock(&np->n_mtx);
- }
- }
-
- /*
- * Call nfs_bioread() to do the real work.
- */
- tresid = uio->uio_resid;
- error = nfs_bioread(vp, uio, 0, ap->a_cred);
-
- if (!error && uio->uio_resid == tresid) {
- nfsstats.direofcache_misses++;
- }
-out:
- return (error);
-}
-
-/*
- * Readdir rpc call.
- * Called from below the buffer cache by nfs_doio().
- */
-int
-nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- int len, left;
- struct dirent *dp = NULL;
- u_int32_t *tl;
- caddr_t cp;
- nfsuint64 *cookiep;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep, *md, *mb;
- nfsuint64 cookie;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- struct nfsnode *dnp = VTONFS(vp);
- u_quad_t fileno;
- int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1;
- int attrflag;
- int v3 = NFS_ISV3(vp);
-
- KASSERT(uiop->uio_iovcnt == 1 &&
- (uiop->uio_offset & (DIRBLKSIZ - 1)) == 0 &&
- (uiop->uio_resid & (DIRBLKSIZ - 1)) == 0,
- ("nfs readdirrpc bad uio"));
-
- /*
- * If there is no cookie, assume directory was stale.
- */
- nfs_dircookie_lock(dnp);
- cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
- if (cookiep) {
- cookie = *cookiep;
- nfs_dircookie_unlock(dnp);
- } else {
- nfs_dircookie_unlock(dnp);
- return (NFSERR_BAD_COOKIE);
- }
-
- /*
- * Loop around doing readdir rpc's of size nm_readdirsize
- * truncated to a multiple of DIRBLKSIZ.
- * The stopping criteria is EOF or buffer full.
- */
- while (more_dirs && bigenough) {
- nfsstats.rpccnt[NFSPROC_READDIR]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_READDIR(v3), M_WAITOK,
- MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- if (v3) {
- tl = nfsm_build(u_int32_t *, 5 * NFSX_UNSIGNED);
- *tl++ = cookie.nfsuquad[0];
- *tl++ = cookie.nfsuquad[1];
- mtx_lock(&dnp->n_mtx);
- *tl++ = dnp->n_cookieverf.nfsuquad[0];
- *tl++ = dnp->n_cookieverf.nfsuquad[1];
- mtx_unlock(&dnp->n_mtx);
- } else {
- tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = cookie.nfsuquad[0];
- }
- *tl = txdr_unsigned(nmp->nm_readdirsize);
- nfsm_request(vp, NFSPROC_READDIR, uiop->uio_td, cred);
- if (v3) {
- nfsm_postop_attr(vp, attrflag);
- if (!error) {
- tl = nfsm_dissect(u_int32_t *,
- 2 * NFSX_UNSIGNED);
- mtx_lock(&dnp->n_mtx);
- dnp->n_cookieverf.nfsuquad[0] = *tl++;
- dnp->n_cookieverf.nfsuquad[1] = *tl;
- mtx_unlock(&dnp->n_mtx);
- } else {
- m_freem(mrep);
- goto nfsmout;
- }
- }
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- more_dirs = fxdr_unsigned(int, *tl);
-
- /* loop thru the dir entries, doctoring them to 4bsd form */
- while (more_dirs && bigenough) {
- if (v3) {
- tl = nfsm_dissect(u_int32_t *,
- 3 * NFSX_UNSIGNED);
- fileno = fxdr_hyper(tl);
- len = fxdr_unsigned(int, *(tl + 2));
- } else {
- tl = nfsm_dissect(u_int32_t *,
- 2 * NFSX_UNSIGNED);
- fileno = fxdr_unsigned(u_quad_t, *tl++);
- len = fxdr_unsigned(int, *tl);
- }
- if (len <= 0 || len > NFS_MAXNAMLEN) {
- error = EBADRPC;
- m_freem(mrep);
- goto nfsmout;
- }
- tlen = nfsm_rndup(len);
- if (tlen == len)
- tlen += 4; /* To ensure null termination */
- left = DIRBLKSIZ - blksiz;
- if ((tlen + DIRHDSIZ) > left) {
- dp->d_reclen += left;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + left;
- uiop->uio_iov->iov_len -= left;
- uiop->uio_offset += left;
- uiop->uio_resid -= left;
- blksiz = 0;
- }
- if ((tlen + DIRHDSIZ) > uiop->uio_resid)
- bigenough = 0;
- if (bigenough) {
- dp = (struct dirent *)uiop->uio_iov->iov_base;
- dp->d_fileno = (int)fileno;
- dp->d_namlen = len;
- dp->d_reclen = tlen + DIRHDSIZ;
- dp->d_type = DT_UNKNOWN;
- blksiz += dp->d_reclen;
- if (blksiz == DIRBLKSIZ)
- blksiz = 0;
- uiop->uio_offset += DIRHDSIZ;
- uiop->uio_resid -= DIRHDSIZ;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + DIRHDSIZ;
- uiop->uio_iov->iov_len -= DIRHDSIZ;
- nfsm_mtouio(uiop, len);
- cp = uiop->uio_iov->iov_base;
- tlen -= len;
- *cp = '\0'; /* null terminate */
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + tlen;
- uiop->uio_iov->iov_len -= tlen;
- uiop->uio_offset += tlen;
- uiop->uio_resid -= tlen;
- } else
- nfsm_adv(nfsm_rndup(len));
- if (v3) {
- tl = nfsm_dissect(u_int32_t *,
- 3 * NFSX_UNSIGNED);
- } else {
- tl = nfsm_dissect(u_int32_t *,
- 2 * NFSX_UNSIGNED);
- }
- if (bigenough) {
- cookie.nfsuquad[0] = *tl++;
- if (v3)
- cookie.nfsuquad[1] = *tl++;
- } else if (v3)
- tl += 2;
- else
- tl++;
- more_dirs = fxdr_unsigned(int, *tl);
- }
- /*
- * If at end of rpc data, get the eof boolean
- */
- if (!more_dirs) {
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- more_dirs = (fxdr_unsigned(int, *tl) == 0);
- }
- m_freem(mrep);
- }
- /*
- * Fill last record, iff any, out to a multiple of DIRBLKSIZ
- * by increasing d_reclen for the last record.
- */
- if (blksiz > 0) {
- left = DIRBLKSIZ - blksiz;
- dp->d_reclen += left;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + left;
- uiop->uio_iov->iov_len -= left;
- uiop->uio_offset += left;
- uiop->uio_resid -= left;
- }
-
- /*
- * We are now either at the end of the directory or have filled the
- * block.
- */
- if (bigenough)
- dnp->n_direofoffset = uiop->uio_offset;
- else {
- if (uiop->uio_resid > 0)
- nfs_printf("EEK! readdirrpc resid > 0\n");
- nfs_dircookie_lock(dnp);
- cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
- *cookiep = cookie;
- nfs_dircookie_unlock(dnp);
- }
-nfsmout:
- return (error);
-}
-
-/*
- * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
- */
-int
-nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- int len, left;
- struct dirent *dp;
- u_int32_t *tl;
- caddr_t cp;
- struct vnode *newvp;
- nfsuint64 *cookiep;
- caddr_t bpos, dpos, dpossav1, dpossav2;
- struct mbuf *mreq, *mrep, *md, *mb, *mdsav1, *mdsav2;
- struct nameidata nami, *ndp = &nami;
- struct componentname *cnp = &ndp->ni_cnd;
- nfsuint64 cookie;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- struct nfsnode *dnp = VTONFS(vp), *np;
- struct vattr vattr, dvattr;
- nfsfh_t *fhp;
- u_quad_t fileno;
- int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
- int attrflag, dattrflag, fhsize;
-
-#ifndef nolint
- dp = NULL;
-#endif
- KASSERT(uiop->uio_iovcnt == 1 &&
- (uiop->uio_offset & (DIRBLKSIZ - 1)) == 0 &&
- (uiop->uio_resid & (DIRBLKSIZ - 1)) == 0,
- ("nfs readdirplusrpc bad uio"));
- ndp->ni_dvp = vp;
- newvp = NULLVP;
-
- /*
- * If there is no cookie, assume directory was stale.
- */
- nfs_dircookie_lock(dnp);
- cookiep = nfs_getcookie(dnp, uiop->uio_offset, 0);
- if (cookiep) {
- cookie = *cookiep;
- nfs_dircookie_unlock(dnp);
- } else {
- nfs_dircookie_unlock(dnp);
- return (NFSERR_BAD_COOKIE);
- }
- /*
- * Loop around doing readdir rpc's of size nm_readdirsize
- * truncated to a multiple of DIRBLKSIZ.
- * The stopping criteria is EOF or buffer full.
- */
- while (more_dirs && bigenough) {
- nfsstats.rpccnt[NFSPROC_READDIRPLUS]++;
- mreq = m_get2(NFSX_FH(1) + 6 * NFSX_UNSIGNED, M_WAITOK,
- MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, 1);
- tl = nfsm_build(u_int32_t *, 6 * NFSX_UNSIGNED);
- *tl++ = cookie.nfsuquad[0];
- *tl++ = cookie.nfsuquad[1];
- mtx_lock(&dnp->n_mtx);
- *tl++ = dnp->n_cookieverf.nfsuquad[0];
- *tl++ = dnp->n_cookieverf.nfsuquad[1];
- mtx_unlock(&dnp->n_mtx);
- *tl++ = txdr_unsigned(nmp->nm_readdirsize);
- *tl = txdr_unsigned(nmp->nm_rsize);
- nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, cred);
- nfsm_postop_attr_va(vp, dattrflag, &dvattr);
- if (error) {
- m_freem(mrep);
- goto nfsmout;
- }
- tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
- mtx_lock(&dnp->n_mtx);
- dnp->n_cookieverf.nfsuquad[0] = *tl++;
- dnp->n_cookieverf.nfsuquad[1] = *tl++;
- mtx_unlock(&dnp->n_mtx);
- more_dirs = fxdr_unsigned(int, *tl);
-
- /* loop thru the dir entries, doctoring them to 4bsd form */
- while (more_dirs && bigenough) {
- tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
- fileno = fxdr_hyper(tl);
- len = fxdr_unsigned(int, *(tl + 2));
- if (len <= 0 || len > NFS_MAXNAMLEN) {
- error = EBADRPC;
- m_freem(mrep);
- goto nfsmout;
- }
- tlen = nfsm_rndup(len);
- if (tlen == len)
- tlen += 4; /* To ensure null termination*/
- left = DIRBLKSIZ - blksiz;
- if ((tlen + DIRHDSIZ) > left) {
- dp->d_reclen += left;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + left;
- uiop->uio_iov->iov_len -= left;
- uiop->uio_offset += left;
- uiop->uio_resid -= left;
- blksiz = 0;
- }
- if ((tlen + DIRHDSIZ) > uiop->uio_resid)
- bigenough = 0;
- if (bigenough) {
- dp = (struct dirent *)uiop->uio_iov->iov_base;
- dp->d_fileno = (int)fileno;
- dp->d_namlen = len;
- dp->d_reclen = tlen + DIRHDSIZ;
- dp->d_type = DT_UNKNOWN;
- blksiz += dp->d_reclen;
- if (blksiz == DIRBLKSIZ)
- blksiz = 0;
- uiop->uio_offset += DIRHDSIZ;
- uiop->uio_resid -= DIRHDSIZ;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + DIRHDSIZ;
- uiop->uio_iov->iov_len -= DIRHDSIZ;
- cnp->cn_nameptr = uiop->uio_iov->iov_base;
- cnp->cn_namelen = len;
- nfsm_mtouio(uiop, len);
- cp = uiop->uio_iov->iov_base;
- tlen -= len;
- *cp = '\0';
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + tlen;
- uiop->uio_iov->iov_len -= tlen;
- uiop->uio_offset += tlen;
- uiop->uio_resid -= tlen;
- } else
- nfsm_adv(nfsm_rndup(len));
- tl = nfsm_dissect(u_int32_t *, 3 * NFSX_UNSIGNED);
- if (bigenough) {
- cookie.nfsuquad[0] = *tl++;
- cookie.nfsuquad[1] = *tl++;
- } else
- tl += 2;
-
- /*
- * Since the attributes are before the file handle
- * (sigh), we must skip over the attributes and then
- * come back and get them.
- */
- attrflag = fxdr_unsigned(int, *tl);
- if (attrflag) {
- dpossav1 = dpos;
- mdsav1 = md;
- nfsm_adv(NFSX_V3FATTR);
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- doit = fxdr_unsigned(int, *tl);
- /*
- * Skip loading the attrs for "..". There's a
- * race between loading the attrs here and
- * lookups that look for the directory currently
- * being read (in the parent). We try to acquire
- * the exclusive lock on ".." here, owning the
- * lock on the directory being read. Lookup will
- * hold the lock on ".." and try to acquire the
- * lock on the directory being read.
- *
- * There are other ways of fixing this, one would
- * be to do a trylock on the ".." vnode and skip
- * loading the attrs on ".." if it happens to be
- * locked by another process. But skipping the
- * attrload on ".." seems the easiest option.
- */
- if (strcmp(dp->d_name, "..") == 0) {
- doit = 0;
- /*
- * We've already skipped over the attrs,
- * skip over the filehandle. And store d_type
- * as VDIR.
- */
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- i = fxdr_unsigned(int, *tl);
- nfsm_adv(nfsm_rndup(i));
- dp->d_type = IFTODT(VTTOIF(VDIR));
- }
- if (doit) {
- nfsm_getfh(fhp, fhsize, 1);
- if (NFS_CMPFH(dnp, fhp, fhsize)) {
- VREF(vp);
- newvp = vp;
- np = dnp;
- } else {
- error = nfs_nget(vp->v_mount, fhp,
- fhsize, &np, LK_EXCLUSIVE);
- if (error)
- doit = 0;
- else
- newvp = NFSTOV(np);
- }
- }
- if (doit && bigenough) {
- dpossav2 = dpos;
- dpos = dpossav1;
- mdsav2 = md;
- md = mdsav1;
- nfsm_loadattr(newvp, &vattr);
- dpos = dpossav2;
- md = mdsav2;
- dp->d_type = IFTODT(VTTOIF(vattr.va_type));
- ndp->ni_vp = newvp;
- if (newvp->v_type != VDIR || dattrflag != 0)
- cache_enter_time(ndp->ni_dvp, ndp->ni_vp,
- cnp, &vattr.va_ctime,
- newvp->v_type != VDIR ? NULL :
- &dvattr.va_ctime);
- }
- } else {
- /* Just skip over the file handle */
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- i = fxdr_unsigned(int, *tl);
- if (i) {
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- fhsize = fxdr_unsigned(int, *tl);
- nfsm_adv(nfsm_rndup(fhsize));
- }
- }
- if (newvp != NULLVP) {
- if (newvp == vp)
- vrele(newvp);
- else
- vput(newvp);
- newvp = NULLVP;
- }
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- more_dirs = fxdr_unsigned(int, *tl);
- }
- /*
- * If at end of rpc data, get the eof boolean
- */
- if (!more_dirs) {
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- more_dirs = (fxdr_unsigned(int, *tl) == 0);
- }
- m_freem(mrep);
- }
- /*
- * Fill last record, iff any, out to a multiple of DIRBLKSIZ
- * by increasing d_reclen for the last record.
- */
- if (blksiz > 0) {
- left = DIRBLKSIZ - blksiz;
- dp->d_reclen += left;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + left;
- uiop->uio_iov->iov_len -= left;
- uiop->uio_offset += left;
- uiop->uio_resid -= left;
- }
-
- /*
- * We are now either at the end of the directory or have filled the
- * block.
- */
- if (bigenough)
- dnp->n_direofoffset = uiop->uio_offset;
- else {
- if (uiop->uio_resid > 0)
- nfs_printf("EEK! readdirplusrpc resid > 0\n");
- nfs_dircookie_lock(dnp);
- cookiep = nfs_getcookie(dnp, uiop->uio_offset, 1);
- *cookiep = cookie;
- nfs_dircookie_unlock(dnp);
- }
-nfsmout:
- if (newvp != NULLVP) {
- if (newvp == vp)
- vrele(newvp);
- else
- vput(newvp);
- newvp = NULLVP;
- }
- return (error);
-}
-
-/*
- * Silly rename. To make the NFS filesystem that is stateless look a little
- * more like the "ufs" a remove of an active vnode is translated to a rename
- * to a funny looking filename that is removed by nfs_inactive on the
- * nfsnode. There is the potential for another process on a different client
- * to create the same funny name between the nfs_lookitup() fails and the
- * nfs_rename() completes, but...
- */
-static int
-nfs_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
-{
- struct sillyrename *sp;
- struct nfsnode *np;
- int error;
- short pid;
- unsigned int lticks;
-
- cache_purge(dvp);
- np = VTONFS(vp);
- KASSERT(vp->v_type != VDIR, ("nfs: sillyrename dir"));
- sp = malloc(sizeof (struct sillyrename),
- M_NFSREQ, M_WAITOK);
- sp->s_cred = crhold(cnp->cn_cred);
- sp->s_dvp = dvp;
- sp->s_removeit = nfs_removeit;
- VREF(dvp);
-
- /*
- * Fudge together a funny name.
- * Changing the format of the funny name to accomodate more
- * sillynames per directory.
- * The name is now changed to .nfs.<ticks>.<pid>.4, where ticks is
- * CPU ticks since boot.
- */
- pid = cnp->cn_thread->td_proc->p_pid;
- lticks = (unsigned int)ticks;
- for ( ; ; ) {
- sp->s_namlen = sprintf(sp->s_name,
- ".nfs.%08x.%04x4.4", lticks,
- pid);
- if (nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
- cnp->cn_thread, NULL))
- break;
- lticks++;
- }
- error = nfs_renameit(dvp, cnp, sp);
- if (error)
- goto bad;
- error = nfs_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
- cnp->cn_thread, &np);
- np->n_sillyrename = sp;
- return (0);
-bad:
- vrele(sp->s_dvp);
- crfree(sp->s_cred);
- free((caddr_t)sp, M_NFSREQ);
- return (error);
-}
-
-/*
- * Look up a file name and optionally either update the file handle or
- * allocate an nfsnode, depending on the value of npp.
- * npp == NULL --> just do the lookup
- * *npp == NULL --> allocate a new nfsnode and make sure attributes are
- * handled too
- * *npp != NULL --> update the file handle in the vnode
- */
-static int
-nfs_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred,
- struct thread *td, struct nfsnode **npp)
-{
- struct vnode *newvp = NULL;
- struct nfsnode *np, *dnp = VTONFS(dvp);
- caddr_t bpos, dpos;
- int error = 0, fhlen, attrflag;
- struct mbuf *mreq, *mrep, *md, *mb;
- nfsfh_t *nfhp;
- int v3 = NFS_ISV3(dvp);
-
- nfsstats.rpccnt[NFSPROC_LOOKUP]++;
- mreq = m_get2(NFSX_FH(v3) + NFSX_UNSIGNED + nfsm_rndup(len),
- M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(dvp, v3);
- nfsm_strtom(name, len, NFS_MAXNAMLEN);
- nfsm_request(dvp, NFSPROC_LOOKUP, td, cred);
- if (npp && !error) {
- nfsm_getfh(nfhp, fhlen, v3);
- if (*npp) {
- np = *npp;
- if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) {
- free((caddr_t)np->n_fhp, M_NFSBIGFH);
- np->n_fhp = &np->n_fh;
- } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH)
- np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK);
- bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen);
- np->n_fhsize = fhlen;
- newvp = NFSTOV(np);
- } else if (NFS_CMPFH(dnp, nfhp, fhlen)) {
- VREF(dvp);
- newvp = dvp;
- } else {
- error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE);
- if (error) {
- m_freem(mrep);
- return (error);
- }
- newvp = NFSTOV(np);
- }
- if (v3) {
- nfsm_postop_attr(newvp, attrflag);
- if (!attrflag && *npp == NULL) {
- m_freem(mrep);
- if (newvp == dvp)
- vrele(newvp);
- else
- vput(newvp);
- return (ENOENT);
- }
- } else
- nfsm_loadattr(newvp, NULL);
- }
- m_freem(mrep);
-nfsmout:
- if (npp && *npp == NULL) {
- if (error) {
- if (newvp) {
- if (newvp == dvp)
- vrele(newvp);
- else
- vput(newvp);
- }
- } else
- *npp = np;
- }
- return (error);
-}
-
-/*
- * Nfs Version 3 commit rpc
- */
-int
-nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
- struct thread *td)
-{
- u_int32_t *tl;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- caddr_t bpos, dpos;
- int error = 0, wccflag = NFSV3_WCCRATTR;
- struct mbuf *mreq, *mrep, *md, *mb;
-
- mtx_lock(&nmp->nm_mtx);
- if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) {
- mtx_unlock(&nmp->nm_mtx);
- return (0);
- }
- mtx_unlock(&nmp->nm_mtx);
- nfsstats.rpccnt[NFSPROC_COMMIT]++;
- mreq = m_get2(NFSX_FH(1), M_WAITOK, MT_DATA, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, 1);
- tl = nfsm_build(u_int32_t *, 3 * NFSX_UNSIGNED);
- txdr_hyper(offset, tl);
- tl += 2;
- *tl = txdr_unsigned(cnt);
- nfsm_request(vp, NFSPROC_COMMIT, td, cred);
- nfsm_wcc_data(vp, wccflag);
- if (!error) {
- tl = nfsm_dissect(u_int32_t *, NFSX_V3WRITEVERF);
- if (bcmp((caddr_t)nmp->nm_verf, (caddr_t)tl,
- NFSX_V3WRITEVERF)) {
- bcopy((caddr_t)tl, (caddr_t)nmp->nm_verf,
- NFSX_V3WRITEVERF);
- error = NFSERR_STALEWRITEVERF;
- }
- }
- m_freem(mrep);
-nfsmout:
- return (error);
-}
-
-/*
- * Strategy routine.
- * For async requests when nfsiod(s) are running, queue the request by
- * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
- * request.
- */
-static int
-nfs_strategy(struct vop_strategy_args *ap)
-{
- struct buf *bp = ap->a_bp;
- struct ucred *cr;
-
- KASSERT(!(bp->b_flags & B_DONE),
- ("nfs_strategy: buffer %p unexpectedly marked B_DONE", bp));
- BUF_ASSERT_HELD(bp);
-
- if (bp->b_iocmd == BIO_READ)
- cr = bp->b_rcred;
- else
- cr = bp->b_wcred;
-
- /*
- * If the op is asynchronous and an i/o daemon is waiting
- * queue the request, wake it up and wait for completion
- * otherwise just do it ourselves.
- */
- if ((bp->b_flags & B_ASYNC) == 0 ||
- nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
- (void)nfs_doio(ap->a_vp, bp, cr, curthread);
- return (0);
-}
-
-/*
- * fsync vnode op. Just call nfs_flush() with commit == 1.
- */
-/* ARGSUSED */
-static int
-nfs_fsync(struct vop_fsync_args *ap)
-{
-
- return (nfs_flush(ap->a_vp, ap->a_waitfor, 1));
-}
-
-/*
- * Flush all the blocks associated with a vnode.
- * Walk through the buffer pool and push any dirty pages
- * associated with the vnode.
- */
-static int
-nfs_flush(struct vnode *vp, int waitfor, int commit)
-{
- struct nfsnode *np = VTONFS(vp);
- struct buf *bp;
- int i;
- struct buf *nbp;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- int error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos;
- int passone = 1;
- u_quad_t off, endoff, toff;
- struct ucred* wcred = NULL;
- struct buf **bvec = NULL;
- struct bufobj *bo;
- struct thread *td = curthread;
-#ifndef NFS_COMMITBVECSIZ
-#define NFS_COMMITBVECSIZ 20
-#endif
- struct buf *bvec_on_stack[NFS_COMMITBVECSIZ];
- int bvecsize = 0, bveccount;
-
- if (nmp->nm_flag & NFSMNT_INT)
- slpflag = PCATCH;
- if (!commit)
- passone = 0;
- bo = &vp->v_bufobj;
- /*
- * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the
- * server, but has not been committed to stable storage on the server
- * yet. On the first pass, the byte range is worked out and the commit
- * rpc is done. On the second pass, nfs_writebp() is called to do the
- * job.
- */
-again:
- off = (u_quad_t)-1;
- endoff = 0;
- bvecpos = 0;
- if (NFS_ISV3(vp) && commit) {
- if (bvec != NULL && bvec != bvec_on_stack)
- free(bvec, M_TEMP);
- /*
- * Count up how many buffers waiting for a commit.
- */
- bveccount = 0;
- BO_LOCK(bo);
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (!BUF_ISLOCKED(bp) &&
- (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT))
- == (B_DELWRI | B_NEEDCOMMIT))
- bveccount++;
- }
- /*
- * Allocate space to remember the list of bufs to commit. It is
- * important to use M_NOWAIT here to avoid a race with nfs_write.
- * If we can't get memory (for whatever reason), we will end up
- * committing the buffers one-by-one in the loop below.
- */
- if (bveccount > NFS_COMMITBVECSIZ) {
- /*
- * Release the vnode interlock to avoid a lock
- * order reversal.
- */
- BO_UNLOCK(bo);
- bvec = (struct buf **)
- malloc(bveccount * sizeof(struct buf *),
- M_TEMP, M_NOWAIT);
- BO_LOCK(bo);
- if (bvec == NULL) {
- bvec = bvec_on_stack;
- bvecsize = NFS_COMMITBVECSIZ;
- } else
- bvecsize = bveccount;
- } else {
- bvec = bvec_on_stack;
- bvecsize = NFS_COMMITBVECSIZ;
- }
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (bvecpos >= bvecsize)
- break;
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) {
- nbp = TAILQ_NEXT(bp, b_bobufs);
- continue;
- }
- if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) !=
- (B_DELWRI | B_NEEDCOMMIT)) {
- BUF_UNLOCK(bp);
- nbp = TAILQ_NEXT(bp, b_bobufs);
- continue;
- }
- BO_UNLOCK(bo);
- bremfree(bp);
- /*
- * Work out if all buffers are using the same cred
- * so we can deal with them all with one commit.
- *
- * NOTE: we are not clearing B_DONE here, so we have
- * to do it later on in this routine if we intend to
- * initiate I/O on the bp.
- *
- * Note: to avoid loopback deadlocks, we do not
- * assign b_runningbufspace.
- */
- if (wcred == NULL)
- wcred = bp->b_wcred;
- else if (wcred != bp->b_wcred)
- wcred = NOCRED;
- vfs_busy_pages(bp, 1);
-
- BO_LOCK(bo);
- /*
- * bp is protected by being locked, but nbp is not
- * and vfs_busy_pages() may sleep. We have to
- * recalculate nbp.
- */
- nbp = TAILQ_NEXT(bp, b_bobufs);
-
- /*
- * A list of these buffers is kept so that the
- * second loop knows which buffers have actually
- * been committed. This is necessary, since there
- * may be a race between the commit rpc and new
- * uncommitted writes on the file.
- */
- bvec[bvecpos++] = bp;
- toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE +
- bp->b_dirtyoff;
- if (toff < off)
- off = toff;
- toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff);
- if (toff > endoff)
- endoff = toff;
- }
- BO_UNLOCK(bo);
- }
- if (bvecpos > 0) {
- /*
- * Commit data on the server, as required.
- * If all bufs are using the same wcred, then use that with
- * one call for all of them, otherwise commit each one
- * separately.
- */
- if (wcred != NOCRED)
- retv = nfs_commit(vp, off, (int)(endoff - off),
- wcred, td);
- else {
- retv = 0;
- for (i = 0; i < bvecpos; i++) {
- off_t off, size;
- bp = bvec[i];
- off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE +
- bp->b_dirtyoff;
- size = (u_quad_t)(bp->b_dirtyend
- - bp->b_dirtyoff);
- retv = nfs_commit(vp, off, (int)size,
- bp->b_wcred, td);
- if (retv) break;
- }
- }
-
- if (retv == NFSERR_STALEWRITEVERF)
- nfs_clearcommit(vp->v_mount);
-
- /*
- * Now, either mark the blocks I/O done or mark the
- * blocks dirty, depending on whether the commit
- * succeeded.
- */
- for (i = 0; i < bvecpos; i++) {
- bp = bvec[i];
- bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
- if (retv) {
- /*
- * Error, leave B_DELWRI intact
- */
- vfs_unbusy_pages(bp);
- brelse(bp);
- } else {
- /*
- * Success, remove B_DELWRI ( bundirty() ).
- *
- * b_dirtyoff/b_dirtyend seem to be NFS
- * specific. We should probably move that
- * into bundirty(). XXX
- */
- bufobj_wref(bo);
- bp->b_flags |= B_ASYNC;
- bundirty(bp);
- bp->b_flags &= ~B_DONE;
- bp->b_ioflags &= ~BIO_ERROR;
- bp->b_dirtyoff = bp->b_dirtyend = 0;
- bufdone(bp);
- }
- }
- }
-
- /*
- * Start/do any write(s) that are required.
- */
-loop:
- BO_LOCK(bo);
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) {
- if (waitfor != MNT_WAIT || passone)
- continue;
-
- error = BUF_TIMELOCK(bp,
- LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK,
- BO_LOCKPTR(bo), "nfsfsync", slpflag, slptimeo);
- if (error == 0) {
- BUF_UNLOCK(bp);
- goto loop;
- }
- if (error == ENOLCK) {
- error = 0;
- goto loop;
- }
- if (nfs_sigintr(nmp, td)) {
- error = EINTR;
- goto done;
- }
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- goto loop;
- }
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("nfs_fsync: not dirty");
- if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) {
- BUF_UNLOCK(bp);
- continue;
- }
- BO_UNLOCK(bo);
- bremfree(bp);
- if (passone || !commit)
- bp->b_flags |= B_ASYNC;
- else
- bp->b_flags |= B_ASYNC;
- bwrite(bp);
- if (nfs_sigintr(nmp, td)) {
- error = EINTR;
- goto done;
- }
- goto loop;
- }
- if (passone) {
- passone = 0;
- BO_UNLOCK(bo);
- goto again;
- }
- if (waitfor == MNT_WAIT) {
- while (bo->bo_numoutput) {
- error = bufobj_wwait(bo, slpflag, slptimeo);
- if (error) {
- BO_UNLOCK(bo);
- error = nfs_sigintr(nmp, td);
- if (error)
- goto done;
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- BO_LOCK(bo);
- }
- }
- if (bo->bo_dirty.bv_cnt != 0 && commit) {
- BO_UNLOCK(bo);
- goto loop;
- }
- /*
- * Wait for all the async IO requests to drain
- */
- BO_UNLOCK(bo);
- mtx_lock(&np->n_mtx);
- while (np->n_directio_asyncwr > 0) {
- np->n_flag |= NFSYNCWAIT;
- error = nfs_msleep(td, (caddr_t)&np->n_directio_asyncwr,
- &np->n_mtx, slpflag | (PRIBIO + 1),
- "nfsfsync", 0);
- if (error) {
- if (nfs_sigintr(nmp, td)) {
- mtx_unlock(&np->n_mtx);
- error = EINTR;
- goto done;
- }
- }
- }
- mtx_unlock(&np->n_mtx);
- } else
- BO_UNLOCK(bo);
- mtx_lock(&np->n_mtx);
- if (np->n_flag & NWRITEERR) {
- error = np->n_error;
- np->n_flag &= ~NWRITEERR;
- }
- if (commit && bo->bo_dirty.bv_cnt == 0 &&
- bo->bo_numoutput == 0 && np->n_directio_asyncwr == 0)
- np->n_flag &= ~NMODIFIED;
- mtx_unlock(&np->n_mtx);
-done:
- if (bvec != NULL && bvec != bvec_on_stack)
- free(bvec, M_TEMP);
- return (error);
-}
-
-/*
- * NFS advisory byte-level locks.
- */
-static int
-nfs_advlock(struct vop_advlock_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- u_quad_t size;
- int error;
-
- error = vn_lock(vp, LK_SHARED);
- if (error)
- return (error);
- if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
- size = VTONFS(vp)->n_size;
- VOP_UNLOCK(vp, 0);
- error = lf_advlock(ap, &(vp->v_lockf), size);
- } else {
- if (nfs_advlock_p)
- error = nfs_advlock_p(ap);
- else
- error = ENOLCK;
- }
-
- return (error);
-}
-
-/*
- * NFS advisory byte-level locks.
- */
-static int
-nfs_advlockasync(struct vop_advlockasync_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- u_quad_t size;
- int error;
-
- error = vn_lock(vp, LK_SHARED);
- if (error)
- return (error);
- if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
- size = VTONFS(vp)->n_size;
- VOP_UNLOCK(vp, 0);
- error = lf_advlockasync(ap, &(vp->v_lockf), size);
- } else {
- VOP_UNLOCK(vp, 0);
- error = EOPNOTSUPP;
- }
- return (error);
-}
-
-/*
- * Print out the contents of an nfsnode.
- */
-static int
-nfs_print(struct vop_print_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
-
- nfs_printf("\tfileid %ld fsid 0x%x",
- np->n_vattr.va_fileid, np->n_vattr.va_fsid);
- if (vp->v_type == VFIFO)
- fifo_printinfo(vp);
- printf("\n");
- return (0);
-}
-
-/*
- * This is the "real" nfs::bwrite(struct buf*).
- * We set B_CACHE if this is a VMIO buffer.
- */
-int
-nfs_writebp(struct buf *bp, int force __unused, struct thread *td)
-{
- int s;
- int oldflags = bp->b_flags;
-#if 0
- int retv = 1;
- off_t off;
-#endif
-
- BUF_ASSERT_HELD(bp);
-
- if (bp->b_flags & B_INVAL) {
- brelse(bp);
- return(0);
- }
-
- bp->b_flags |= B_CACHE;
-
- /*
- * Undirty the bp. We will redirty it later if the I/O fails.
- */
-
- s = splbio();
- bundirty(bp);
- bp->b_flags &= ~B_DONE;
- bp->b_ioflags &= ~BIO_ERROR;
- bp->b_iocmd = BIO_WRITE;
-
- bufobj_wref(bp->b_bufobj);
- curthread->td_ru.ru_oublock++;
- splx(s);
-
- /*
- * Note: to avoid loopback deadlocks, we do not
- * assign b_runningbufspace.
- */
- vfs_busy_pages(bp, 1);
-
- BUF_KERNPROC(bp);
- bp->b_iooffset = dbtob(bp->b_blkno);
- bstrategy(bp);
-
- if( (oldflags & B_ASYNC) == 0) {
- int rtval = bufwait(bp);
-
- if (oldflags & B_DELWRI) {
- s = splbio();
- reassignbuf(bp);
- splx(s);
- }
- brelse(bp);
- return (rtval);
- }
-
- return (0);
-}
-
-/*
- * nfs special file access vnode op.
- * Essentially just get vattr and then imitate iaccess() since the device is
- * local to the client.
- */
-static int
-nfsspec_access(struct vop_access_args *ap)
-{
- struct vattr *vap;
- struct ucred *cred = ap->a_cred;
- struct vnode *vp = ap->a_vp;
- accmode_t accmode = ap->a_accmode;
- struct vattr vattr;
- int error;
-
- /*
- * Disallow write attempts on filesystems mounted read-only;
- * unless the file is a socket, fifo, or a block or character
- * device resident on the filesystem.
- */
- if ((accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
- switch (vp->v_type) {
- case VREG:
- case VDIR:
- case VLNK:
- return (EROFS);
- default:
- break;
- }
- }
- vap = &vattr;
- error = VOP_GETATTR(vp, vap, cred);
- if (error)
- goto out;
- error = vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid,
- accmode, cred, NULL);
-out:
- return error;
-}
-
-/*
- * Read wrapper for fifos.
- */
-static int
-nfsfifo_read(struct vop_read_args *ap)
-{
- struct nfsnode *np = VTONFS(ap->a_vp);
- int error;
-
- /*
- * Set access flag.
- */
- mtx_lock(&np->n_mtx);
- np->n_flag |= NACC;
- vfs_timestamp(&np->n_atim);
- mtx_unlock(&np->n_mtx);
- error = fifo_specops.vop_read(ap);
- return error;
-}
-
-/*
- * Write wrapper for fifos.
- */
-static int
-nfsfifo_write(struct vop_write_args *ap)
-{
- struct nfsnode *np = VTONFS(ap->a_vp);
-
- /*
- * Set update flag.
- */
- mtx_lock(&np->n_mtx);
- np->n_flag |= NUPD;
- vfs_timestamp(&np->n_mtim);
- mtx_unlock(&np->n_mtx);
- return(fifo_specops.vop_write(ap));
-}
-
-/*
- * Close wrapper for fifos.
- *
- * Update the times on the nfsnode then do fifo close.
- */
-static int
-nfsfifo_close(struct vop_close_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct vattr vattr;
- struct timespec ts;
-
- mtx_lock(&np->n_mtx);
- if (np->n_flag & (NACC | NUPD)) {
- vfs_timestamp(&ts);
- if (np->n_flag & NACC)
- np->n_atim = ts;
- if (np->n_flag & NUPD)
- np->n_mtim = ts;
- np->n_flag |= NCHG;
- if (vrefcnt(vp) == 1 &&
- (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
- VATTR_NULL(&vattr);
- if (np->n_flag & NACC)
- vattr.va_atime = np->n_atim;
- if (np->n_flag & NUPD)
- vattr.va_mtime = np->n_mtim;
- mtx_unlock(&np->n_mtx);
- (void)VOP_SETATTR(vp, &vattr, ap->a_cred);
- goto out;
- }
- }
- mtx_unlock(&np->n_mtx);
-out:
- return (fifo_specops.vop_close(ap));
-}
-
-/*
- * Just call nfs_writebp() with the force argument set to 1.
- *
- * NOTE: B_DONE may or may not be set in a_bp on call.
- */
-static int
-nfs_bwrite(struct buf *bp)
-{
-
- return (nfs_writebp(bp, 1, curthread));
-}
-
-struct buf_ops buf_ops_nfs = {
- .bop_name = "buf_ops_nfs",
- .bop_write = nfs_bwrite,
- .bop_strategy = bufstrategy,
- .bop_sync = bufsync,
- .bop_bdflush = bufbdflush,
-};
diff --git a/sys/nfsserver/nfs_fha_old.c b/sys/nfsserver/nfs_fha_old.c
deleted file mode 100644
index a928278..0000000
--- a/sys/nfsserver/nfs_fha_old.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*-
- * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
- * Copyright (c) 2013 Spectra Logic Corporation
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/kernel.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/mbuf.h>
-#include <sys/sysctl.h>
-
-#include <rpc/rpc.h>
-#include <nfs/xdr_subs.h>
-#include <nfs/nfsproto.h>
-#include <nfs/nfs_fha.h>
-#include <nfsserver/nfs.h>
-#include <nfsserver/nfsm_subs.h>
-#include <nfsserver/nfs_fha_old.h>
-
-static void fhaold_init(void *foo);
-static void fhaold_uninit(void *foo);
-rpcproc_t fhaold_get_procnum(rpcproc_t procnum);
-int fhaold_realign(struct mbuf **mb, int malloc_flags);
-int fhaold_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos);
-int fhaold_is_read(rpcproc_t procnum);
-int fhaold_is_write(rpcproc_t procnum);
-int fhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3,
- struct fha_info *info);
-int fhaold_no_offset(rpcproc_t procnum);
-void fhaold_set_locktype(rpcproc_t procnum, struct fha_info *info);
-static int fheold_stats_sysctl(SYSCTL_HANDLER_ARGS);
-
-static struct fha_params fhaold_softc;
-
-SYSCTL_DECL(_vfs_nfsrv);
-
-extern SVCPOOL *nfsrv_pool;
-
-SYSINIT(nfs_fhaold, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhaold_init, NULL);
-SYSUNINIT(nfs_fhaold, SI_SUB_ROOT_CONF, SI_ORDER_ANY, fhaold_uninit, NULL);
-
-static void
-fhaold_init(void *foo)
-{
- struct fha_params *softc;
-
- softc = &fhaold_softc;
-
- bzero(softc, sizeof(*softc));
-
- /*
- * Setup the callbacks for this FHA personality.
- */
- softc->callbacks.get_procnum = fhaold_get_procnum;
- softc->callbacks.realign = fhaold_realign;
- softc->callbacks.get_fh = fhaold_get_fh;
- softc->callbacks.is_read = fhaold_is_read;
- softc->callbacks.is_write = fhaold_is_write;
- softc->callbacks.get_offset = fhaold_get_offset;
- softc->callbacks.no_offset = fhaold_no_offset;
- softc->callbacks.set_locktype = fhaold_set_locktype;
- softc->callbacks.fhe_stats_sysctl = fheold_stats_sysctl;
-
- snprintf(softc->server_name, sizeof(softc->server_name),
- FHAOLD_SERVER_NAME);
-
- softc->pool = &nfsrv_pool;
-
- /*
- * Initialize the sysctl context list for the fha module.
- */
- sysctl_ctx_init(&softc->sysctl_ctx);
- softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
- SYSCTL_STATIC_CHILDREN(_vfs_nfsrv), OID_AUTO, "fha", CTLFLAG_RD,
- 0, "fha node");
- if (softc->sysctl_tree == NULL) {
- printf("%s: unable to allocate sysctl tree\n", __func__);
- return;
- }
- fha_init(softc);
-}
-
-static void
-fhaold_uninit(void *foo)
-{
- struct fha_params *softc;
-
- softc = &fhaold_softc;
-
- fha_uninit(softc);
-}
-
-
-rpcproc_t
-fhaold_get_procnum(rpcproc_t procnum)
-{
- if (procnum > NFSV2PROC_STATFS)
- return (-1);
-
- return (nfsrv_nfsv3_procid[procnum]);
-}
-
-int
-fhaold_realign(struct mbuf **mb, int malloc_flags)
-{
- return (nfs_realign(mb, malloc_flags));
-}
-
-int
-fhaold_get_fh(uint64_t *fh, int v3, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
- uint8_t *buf;
- uint64_t t;
- int fhlen, i;
-
- if (v3) {
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- fhlen = fxdr_unsigned(int, *tl);
- if (fhlen != 0 && fhlen != NFSX_V3FH)
- return EBADRPC;
- } else {
- fhlen = NFSX_V2FH;
- }
- t = 0;
- if (fhlen != 0) {
- buf = nfsm_dissect_xx_nonblock(fhlen, md, dpos);
- if (buf == NULL)
- return EBADRPC;
- for (i = 0; i < fhlen; i++)
- t ^= ((uint64_t)buf[i] << (i & 7) * 8);
- }
- *fh = t;
- return 0;
-}
-
-int
-fhaold_is_read(rpcproc_t procnum)
-{
- if (procnum == NFSPROC_READ)
- return (1);
- else
- return (0);
-}
-
-int
-fhaold_is_write(rpcproc_t procnum)
-{
- if (procnum == NFSPROC_WRITE)
- return (1);
- else
- return (0);
-}
-
-int
-fhaold_get_offset(struct mbuf **md, caddr_t *dpos, int v3,
- struct fha_info *info)
-{
- uint32_t *tl;
-
- if (v3) {
- tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- goto out;
- info->offset = fxdr_hyper(tl);
- } else {
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- goto out;
- info->offset = fxdr_unsigned(uint32_t, *tl);
- }
-
- return (0);
-out:
- return (-1);
-}
-
-int
-fhaold_no_offset(rpcproc_t procnum)
-{
- if (procnum == NFSPROC_FSSTAT ||
- procnum == NFSPROC_FSINFO ||
- procnum == NFSPROC_PATHCONF ||
- procnum == NFSPROC_NOOP ||
- procnum == NFSPROC_NULL)
- return (1);
- else
- return (0);
-}
-
-void
-fhaold_set_locktype(rpcproc_t procnum, struct fha_info *info)
-{
- switch (procnum) {
- case NFSPROC_NULL:
- case NFSPROC_GETATTR:
- case NFSPROC_LOOKUP:
- case NFSPROC_ACCESS:
- case NFSPROC_READLINK:
- case NFSPROC_READ:
- case NFSPROC_READDIR:
- case NFSPROC_READDIRPLUS:
- case NFSPROC_WRITE:
- info->locktype = LK_SHARED;
- break;
- case NFSPROC_SETATTR:
- case NFSPROC_CREATE:
- case NFSPROC_MKDIR:
- case NFSPROC_SYMLINK:
- case NFSPROC_MKNOD:
- case NFSPROC_REMOVE:
- case NFSPROC_RMDIR:
- case NFSPROC_RENAME:
- case NFSPROC_LINK:
- case NFSPROC_FSSTAT:
- case NFSPROC_FSINFO:
- case NFSPROC_PATHCONF:
- case NFSPROC_COMMIT:
- case NFSPROC_NOOP:
- info->locktype = LK_EXCLUSIVE;
- break;
- }
-}
-
-static int
-fheold_stats_sysctl(SYSCTL_HANDLER_ARGS)
-{
- return (fhe_stats_sysctl(oidp, arg1, arg2, req, &fhaold_softc));
-}
-
-SVCTHREAD *
-fhaold_assign(SVCTHREAD *this_thread, struct svc_req *req)
-{
- return (fha_assign(this_thread, req, &fhaold_softc));
-}
diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c
deleted file mode 100644
index 32fd3f5..0000000
--- a/sys/nfsserver/nfs_serv.c
+++ /dev/null
@@ -1,3767 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_serv.c 8.8 (Berkeley) 7/31/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * nfs version 2 and 3 server calls to vnode ops
- * - these routines generally have 3 phases
- * 1 - break down and validate rpc request in mbuf list
- * 2 - do the vnode ops for the request
- * (surprisingly ?? many are very similar to syscalls in vfs_syscalls.c)
- * 3 - build the rpc reply in an mbuf list
- * nb:
- * - do not mix the phases, since the nfsm_?? macros can return failures
- * on a bad rpc or similar and do not do any vrele() or vput()'s
- *
- * - the nfsm_reply() macro generates an nfs rpc reply with the nfs
- * error number iff error != 0 whereas
- * returning an error from the server function implies a fatal error
- * such as a badly constructed rpc request that should be dropped without
- * a reply.
- * For nfsm_reply(), the case where error == EBADRPC is treated
- * specially; after constructing a reply, it does an immediate
- * `goto nfsmout' to avoid getting any V3 post-op status appended.
- *
- * Other notes:
- * Warning: always pay careful attention to resource cleanup on return
- * and note that nfsm_*() macros can terminate a procedure on certain
- * errors.
- *
- * lookup() and namei()
- * may return garbage in various structural fields/return elements
- * if an error is returned, and may garbage up nd.ni_dvp even if no
- * error is returned and you did not request LOCKPARENT or WANTPARENT.
- *
- * We use the ni_cnd.cn_flags 'HASBUF' flag to track whether the name
- * buffer has been freed or not.
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/namei.h>
-#include <sys/unistd.h>
-#include <sys/vnode.h>
-#include <sys/mount.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/priv.h>
-#include <sys/dirent.h>
-#include <sys/stat.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/rwlock.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-#include <vm/vm_object.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsserver/nfs.h>
-#include <nfs/xdr_subs.h>
-#include <nfsserver/nfsm_subs.h>
-
-FEATURE(nfsserver, "NFS server");
-
-#ifdef NFSRV_DEBUG
-#define nfsdbprintf(info) printf info
-#else
-#define nfsdbprintf(info)
-#endif
-
-#define MAX_COMMIT_COUNT (1024 * 1024)
-
-#define MAX_REORDERED_RPC 16
-#define NUM_HEURISTIC 1031
-#define NHUSE_INIT 64
-#define NHUSE_INC 16
-#define NHUSE_MAX 2048
-
-static struct nfsheur {
- struct vnode *nh_vp; /* vp to match (unreferenced pointer) */
- off_t nh_nextoff; /* next offset for sequential detection */
- int nh_use; /* use count for selection */
- int nh_seqcount; /* heuristic */
-} nfsheur[NUM_HEURISTIC];
-
-/* Global vars */
-
-int nfsrvw_procrastinate = NFS_GATHERDELAY * 1000;
-int nfsrvw_procrastinate_v3 = 0;
-
-static struct timeval nfsver = { 0 };
-
-SYSCTL_NODE(_vfs, OID_AUTO, nfsrv, CTLFLAG_RW, 0, "NFS server");
-
-static int nfs_async;
-static int nfs_commit_blks;
-static int nfs_commit_miss;
-SYSCTL_INT(_vfs_nfsrv, OID_AUTO, async, CTLFLAG_RW, &nfs_async, 0,
- "Tell client that writes were synced even though they were not");
-SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks, 0,
- "Number of completed commits");
-SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, 0, "");
-
-struct nfsrvstats nfsrvstats;
-SYSCTL_STRUCT(_vfs_nfsrv, NFS_NFSRVSTATS, nfsrvstats, CTLFLAG_RW,
- &nfsrvstats, nfsrvstats, "S,nfsrvstats");
-
-static int nfsrv_access(struct vnode *, accmode_t, struct ucred *,
- int, int);
-
-/*
- * Clear nameidata fields that are tested in nsfmout cleanup code prior
- * to using first nfsm macro (that might jump to the cleanup code).
- */
-
-static __inline void
-ndclear(struct nameidata *nd)
-{
-
- nd->ni_cnd.cn_flags = 0;
- nd->ni_vp = NULL;
- nd->ni_dvp = NULL;
- nd->ni_startdir = NULL;
- nd->ni_strictrelative = 0;
-}
-
-/*
- * Heuristic to detect sequential operation.
- */
-static struct nfsheur *
-nfsrv_sequential_heuristic(struct uio *uio, struct vnode *vp)
-{
- struct nfsheur *nh;
- int hi, try;
-
- /* Locate best candidate. */
- try = 32;
- hi = ((int)(vm_offset_t)vp / sizeof(struct vnode)) % NUM_HEURISTIC;
- nh = &nfsheur[hi];
- while (try--) {
- if (nfsheur[hi].nh_vp == vp) {
- nh = &nfsheur[hi];
- break;
- }
- if (nfsheur[hi].nh_use > 0)
- --nfsheur[hi].nh_use;
- hi = (hi + 1) % NUM_HEURISTIC;
- if (nfsheur[hi].nh_use < nh->nh_use)
- nh = &nfsheur[hi];
- }
-
- /* Initialize hint if this is a new file. */
- if (nh->nh_vp != vp) {
- nh->nh_vp = vp;
- nh->nh_nextoff = uio->uio_offset;
- nh->nh_use = NHUSE_INIT;
- if (uio->uio_offset == 0)
- nh->nh_seqcount = 4;
- else
- nh->nh_seqcount = 1;
- }
-
- /* Calculate heuristic. */
- if ((uio->uio_offset == 0 && nh->nh_seqcount > 0) ||
- uio->uio_offset == nh->nh_nextoff) {
- /* See comments in vfs_vnops.c:sequential_heuristic(). */
- nh->nh_seqcount += howmany(uio->uio_resid, 16384);
- if (nh->nh_seqcount > IO_SEQMAX)
- nh->nh_seqcount = IO_SEQMAX;
- } else if (qabs(uio->uio_offset - nh->nh_nextoff) <= MAX_REORDERED_RPC *
- imax(vp->v_mount->mnt_stat.f_iosize, uio->uio_resid)) {
- /* Probably a reordered RPC, leave seqcount alone. */
- } else if (nh->nh_seqcount > 1) {
- nh->nh_seqcount /= 2;
- } else {
- nh->nh_seqcount = 0;
- }
- nh->nh_use += NHUSE_INC;
- if (nh->nh_use > NHUSE_MAX)
- nh->nh_use = NHUSE_MAX;
- return (nh);
-}
-
-/*
- * nfs v3 access service
- */
-int
-nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct vnode *vp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- u_int32_t *tl;
- caddr_t bpos;
- int error = 0, rdonly, getret;
- struct mbuf *mb, *mreq;
- struct vattr vattr, *vap = &vattr;
- u_long testmode, nfsmode;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (!v3)
- panic("nfsrv3_access: v3 proc called on a v2 connection");
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(NFSX_UNSIGNED);
- nfsm_srvpostop_attr(1, NULL);
- error = 0;
- goto nfsmout;
- }
- nfsmode = fxdr_unsigned(u_int32_t, *tl);
- if ((nfsmode & NFSV3ACCESS_READ) &&
- nfsrv_access(vp, VREAD, cred, rdonly, 0))
- nfsmode &= ~NFSV3ACCESS_READ;
- if (vp->v_type == VDIR)
- testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
- NFSV3ACCESS_DELETE);
- else
- testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
- if ((nfsmode & testmode) &&
- nfsrv_access(vp, VWRITE, cred, rdonly, 0))
- nfsmode &= ~testmode;
- if (vp->v_type == VDIR)
- testmode = NFSV3ACCESS_LOOKUP;
- else
- testmode = NFSV3ACCESS_EXECUTE;
- if ((nfsmode & testmode) &&
- nfsrv_access(vp, VEXEC, cred, rdonly, 0))
- nfsmode &= ~testmode;
- getret = VOP_GETATTR(vp, vap, cred);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED);
- nfsm_srvpostop_attr(getret, vap);
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = txdr_unsigned(nfsmode);
-nfsmout:
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * nfs getattr service
- */
-int
-nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nfs_fattr *fp;
- struct vattr va;
- struct vattr *vap = &va;
- struct vnode *vp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- caddr_t bpos;
- int error = 0, rdonly;
- struct mbuf *mb, *mreq;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(0);
- error = 0;
- goto nfsmout;
- }
- error = VOP_GETATTR(vp, vap, cred);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
- if (error) {
- error = 0;
- goto nfsmout;
- }
- fp = nfsm_build(struct nfs_fattr *,
- NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
- nfsm_srvfillattr(vap, fp);
- /* fall through */
-
-nfsmout:
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * nfs setattr service
- */
-int
-nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct vattr va, preat;
- struct vattr *vap = &va;
- struct nfsv2_sattr *sp;
- struct nfs_fattr *fp;
- struct vnode *vp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- u_int32_t *tl;
- caddr_t bpos;
- int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0;
- struct mbuf *mb, *mreq;
- struct timespec guard = { 0, 0 };
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto out;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- VATTR_NULL(vap);
- if (v3) {
- nfsm_srvsattr(vap);
- tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
- gcheck = fxdr_unsigned(int, *tl);
- if (gcheck) {
- tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
- fxdr_nfsv3time(tl, &guard);
- }
- } else {
- sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
- /*
- * Nah nah nah nah na nah
- * There is a bug in the Sun client that puts 0xffff in the mode
- * field of sattr when it should put in 0xffffffff. The u_short
- * doesn't sign extend.
- * --> check the low order 2 bytes for 0xffff
- */
- if ((fxdr_unsigned(int, sp->sa_mode) & 0xffff) != 0xffff)
- vap->va_mode = nfstov_mode(sp->sa_mode);
- if (sp->sa_uid != nfsrv_nfs_xdrneg1)
- vap->va_uid = fxdr_unsigned(uid_t, sp->sa_uid);
- if (sp->sa_gid != nfsrv_nfs_xdrneg1)
- vap->va_gid = fxdr_unsigned(gid_t, sp->sa_gid);
- if (sp->sa_size != nfsrv_nfs_xdrneg1)
- vap->va_size = fxdr_unsigned(u_quad_t, sp->sa_size);
- if (sp->sa_atime.nfsv2_sec != nfsrv_nfs_xdrneg1) {
-#ifdef notyet
- fxdr_nfsv2time(&sp->sa_atime, &vap->va_atime);
-#else
- vap->va_atime.tv_sec =
- fxdr_unsigned(int32_t, sp->sa_atime.nfsv2_sec);
- vap->va_atime.tv_nsec = 0;
-#endif
- }
- if (sp->sa_mtime.nfsv2_sec != nfsrv_nfs_xdrneg1)
- fxdr_nfsv2time(&sp->sa_mtime, &vap->va_mtime);
-
- }
-
- /*
- * Now that we have all the fields, lets do it.
- */
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(2 * NFSX_UNSIGNED);
- if (v3)
- nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
- error = 0;
- goto nfsmout;
- }
-
- /*
- * vp now an active resource, pay careful attention to cleanup
- */
- if (v3) {
- error = preat_ret = VOP_GETATTR(vp, &preat, cred);
- if (!error && gcheck &&
- (preat.va_ctime.tv_sec != guard.tv_sec ||
- preat.va_ctime.tv_nsec != guard.tv_nsec))
- error = NFSERR_NOT_SYNC;
- if (error) {
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_WCCDATA(v3));
- if (v3)
- nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
- error = 0;
- goto nfsmout;
- }
- }
-
- /*
- * If the size is being changed write acces is required, otherwise
- * just check for a read only filesystem.
- */
- if (vap->va_size == ((u_quad_t)((quad_t) -1))) {
- if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
- error = EROFS;
- goto out;
- }
- } else {
- if (vp->v_type == VDIR) {
- error = EISDIR;
- goto out;
- } else if ((error = nfsrv_access(vp, VWRITE, cred, rdonly,
- 0)) != 0)
- goto out;
- }
- error = VOP_SETATTR(vp, vap, cred);
- postat_ret = VOP_GETATTR(vp, vap, cred);
- if (!error)
- error = postat_ret;
-out:
- if (vp != NULL)
- vput(vp);
-
- vp = NULL;
- nfsm_reply(NFSX_WCCORFATTR(v3));
- if (v3) {
- nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
- } else if (!error) {
- /* v2 non-error case. */
- fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
- nfsm_srvfillattr(vap, fp);
- }
- error = 0;
- /* fall through */
-
-nfsmout:
- if (vp)
- vput(vp);
- vn_finished_write(mp);
- return(error);
-}
-
-/*
- * nfs lookup rpc
- */
-int
-nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nfs_fattr *fp;
- struct nameidata nd, ind, *ndp = &nd;
- struct vnode *vp, *dirp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- caddr_t bpos;
- int error = 0, len, dirattr_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag;
- struct mbuf *mb, *mreq;
- struct vattr va, dirattr, *vap = &va;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- nfsm_srvnamesiz(len);
-
- pubflag = nfs_ispublicfh(fhp);
-
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = LOOKUP;
- nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART;
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirattr, &dirattr_ret, pubflag);
-
- /*
- * namei failure, only dirp to cleanup. Clear out garbarge from
- * structure in case macros jump to nfsmout.
- */
-
- if (error) {
- if (dirp) {
- vrele(dirp);
- dirp = NULL;
- }
- nfsm_reply(NFSX_POSTOPATTR(v3));
- if (v3)
- nfsm_srvpostop_attr(dirattr_ret, &dirattr);
- error = 0;
- goto nfsmout;
- }
-
- /*
- * Locate index file for public filehandle
- *
- * error is 0 on entry and 0 on exit from this block.
- */
-
- if (pubflag) {
- if (nd.ni_vp->v_type == VDIR && nfs_pub.np_index != NULL) {
- /*
- * Setup call to lookup() to see if we can find
- * the index file. Arguably, this doesn't belong
- * in a kernel.. Ugh. If an error occurs, do not
- * try to install an index file and then clear the
- * error.
- *
- * When we replace nd with ind and redirect ndp,
- * maintenance of ni_startdir and ni_vp shift to
- * ind and we have to clean them up in the old nd.
- * However, the cnd resource continues to be maintained
- * via the original nd. Confused? You aren't alone!
- */
- ind = nd;
- VOP_UNLOCK(nd.ni_vp, 0);
- ind.ni_pathlen = strlen(nfs_pub.np_index);
- ind.ni_cnd.cn_nameptr = ind.ni_cnd.cn_pnbuf =
- nfs_pub.np_index;
- ind.ni_startdir = nd.ni_vp;
- VREF(ind.ni_startdir);
- error = lookup(&ind);
- ind.ni_dvp = NULL;
-
- if (error == 0) {
- /*
- * Found an index file. Get rid of
- * the old references. transfer nd.ni_vp'
- */
- if (dirp)
- vrele(dirp);
- dirp = nd.ni_vp;
- nd.ni_vp = NULL;
- vrele(nd.ni_startdir);
- nd.ni_startdir = NULL;
- ndp = &ind;
- }
- error = 0;
- }
- /*
- * If the public filehandle was used, check that this lookup
- * didn't result in a filehandle outside the publicly exported
- * filesystem. We clear the poor vp here to avoid lockups due
- * to NFS I/O.
- */
-
- if (ndp->ni_vp->v_mount != nfs_pub.np_mount) {
- vput(nd.ni_vp);
- nd.ni_vp = NULL;
- error = EPERM;
- }
- }
-
- /*
- * Resources at this point:
- * ndp->ni_vp may not be NULL
- */
-
- if (error) {
- nfsm_reply(NFSX_POSTOPATTR(v3));
- if (v3)
- nfsm_srvpostop_attr(dirattr_ret, &dirattr);
- error = 0;
- goto nfsmout;
- }
-
- /*
- * Get underlying attribute, then release remaining resources ( for
- * the same potential blocking reason ) and reply.
- */
- vp = ndp->ni_vp;
- bzero((caddr_t)fhp, sizeof(nfh));
- fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
- error = VOP_VPTOFH(vp, &fhp->fh_fid);
- if (!error)
- error = VOP_GETATTR(vp, vap, cred);
-
- vput(vp);
- vrele(ndp->ni_startdir);
- vrele(dirp);
- ndp->ni_vp = NULL;
- ndp->ni_startdir = NULL;
- dirp = NULL;
- nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
- if (error) {
- if (v3)
- nfsm_srvpostop_attr(dirattr_ret, &dirattr);
- error = 0;
- goto nfsmout;
- }
- nfsm_srvfhtom(fhp, v3);
- if (v3) {
- nfsm_srvpostop_attr(0, vap);
- nfsm_srvpostop_attr(dirattr_ret, &dirattr);
- } else {
- fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
- nfsm_srvfillattr(vap, fp);
- }
-
-nfsmout:
- if (ndp->ni_vp || dirp || ndp->ni_startdir) {
- if (ndp->ni_vp)
- vput(ndp->ni_vp);
- if (dirp)
- vrele(dirp);
- if (ndp->ni_startdir)
- vrele(ndp->ni_startdir);
- }
- NDFREE(&nd, NDF_ONLY_PNBUF);
- return (error);
-}
-
-/*
- * nfs readlink service
- */
-int
-nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN];
- struct iovec *ivp = iv;
- struct mbuf *mp;
- u_int32_t *tl;
- caddr_t bpos;
- int error = 0, rdonly, i, tlen, len, getret;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mp3, *nmp, *mreq;
- struct vnode *vp = NULL;
- struct vattr attr;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct uio io, *uiop = &io;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
-#ifndef nolint
- mp = NULL;
-#endif
- mp3 = NULL;
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- len = 0;
- i = 0;
- while (len < NFS_MAXPATHLEN) {
- MGET(nmp, M_WAITOK, MT_DATA);
- MCLGET(nmp, M_WAITOK);
- nmp->m_len = NFSMSIZ(nmp);
- if (len == 0)
- mp3 = mp = nmp;
- else {
- mp->m_next = nmp;
- mp = nmp;
- }
- if ((len + mp->m_len) > NFS_MAXPATHLEN) {
- mp->m_len = NFS_MAXPATHLEN - len;
- len = NFS_MAXPATHLEN;
- } else
- len += mp->m_len;
- ivp->iov_base = mtod(mp, caddr_t);
- ivp->iov_len = mp->m_len;
- i++;
- ivp++;
- }
- uiop->uio_iov = iv;
- uiop->uio_iovcnt = i;
- uiop->uio_offset = 0;
- uiop->uio_resid = len;
- uiop->uio_rw = UIO_READ;
- uiop->uio_segflg = UIO_SYSSPACE;
- uiop->uio_td = NULL;
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(2 * NFSX_UNSIGNED);
- if (v3)
- nfsm_srvpostop_attr(1, NULL);
- error = 0;
- goto nfsmout;
- }
- if (vp->v_type != VLNK) {
- if (v3)
- error = EINVAL;
- else
- error = ENXIO;
- } else
- error = VOP_READLINK(vp, uiop, cred);
- getret = VOP_GETATTR(vp, &attr, cred);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED);
- if (v3)
- nfsm_srvpostop_attr(getret, &attr);
- if (error) {
- error = 0;
- goto nfsmout;
- }
- if (uiop->uio_resid > 0) {
- len -= uiop->uio_resid;
- tlen = nfsm_rndup(len);
- nfsm_adj(mp3, NFS_MAXPATHLEN-tlen, tlen-len);
- }
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = txdr_unsigned(len);
- mb->m_next = mp3;
- mp3 = NULL;
-nfsmout:
- if (mp3)
- m_freem(mp3);
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * nfs read service
- */
-int
-nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct iovec *iv;
- struct iovec *iv2;
- struct mbuf *m;
- struct nfs_fattr *fp;
- u_int32_t *tl;
- int i;
- caddr_t bpos;
- int error = 0, rdonly, cnt, len, left, siz, tlen, getret;
- int v3 = (nfsd->nd_flag & ND_NFSV3), reqlen;
- struct mbuf *mb, *mreq;
- struct mbuf *m2;
- struct vnode *vp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct uio io, *uiop = &io;
- struct vattr va, *vap = &va;
- struct nfsheur *nh;
- off_t off;
- int ioflag = 0;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if (v3) {
- tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
- off = fxdr_hyper(tl);
- } else {
- tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
- off = (off_t)fxdr_unsigned(u_int32_t, *tl);
- }
- nfsm_srvstrsiz(reqlen, NFS_SRVMAXDATA(nfsd));
-
- /*
- * Reference vp. If an error occurs, vp will be invalid, but we
- * have to NULL it just in case. The macros might goto nfsmout
- * as well.
- */
-
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- vp = NULL;
- nfsm_reply(2 * NFSX_UNSIGNED);
- if (v3)
- nfsm_srvpostop_attr(1, NULL);
- error = 0;
- goto nfsmout;
- }
-
- if (vp->v_type != VREG) {
- if (v3)
- error = EINVAL;
- else
- error = (vp->v_type == VDIR) ? EISDIR : EACCES;
- }
- if (!error) {
- if ((error = nfsrv_access(vp, VREAD, cred, rdonly, 1)) != 0)
- error = nfsrv_access(vp, VEXEC, cred, rdonly, 1);
- }
- getret = VOP_GETATTR(vp, vap, cred);
- if (!error)
- error = getret;
- if (error) {
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(v3));
- if (v3)
- nfsm_srvpostop_attr(getret, vap);
- error = 0;
- goto nfsmout;
- }
-
- /*
- * Calculate byte count to read
- */
- if (off >= vap->va_size)
- cnt = 0;
- else if ((off + reqlen) > vap->va_size)
- cnt = vap->va_size - off;
- else
- cnt = reqlen;
-
- nfsm_reply(NFSX_POSTOPORFATTR(v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt));
- if (v3) {
- tl = nfsm_build(u_int32_t *, NFSX_V3FATTR + 4 * NFSX_UNSIGNED);
- *tl++ = nfsrv_nfs_true;
- fp = (struct nfs_fattr *)tl;
- tl += (NFSX_V3FATTR / sizeof (u_int32_t));
- } else {
- tl = nfsm_build(u_int32_t *, NFSX_V2FATTR + NFSX_UNSIGNED);
- fp = (struct nfs_fattr *)tl;
- tl += (NFSX_V2FATTR / sizeof (u_int32_t));
- }
- len = left = nfsm_rndup(cnt);
- if (cnt > 0) {
- /*
- * Generate the mbuf list with the uio_iov ref. to it.
- */
- i = 0;
- m = m2 = mb;
- while (left > 0) {
- siz = min(M_TRAILINGSPACE(m), left);
- if (siz > 0) {
- left -= siz;
- i++;
- }
- if (left > 0) {
- MGET(m, M_WAITOK, MT_DATA);
- MCLGET(m, M_WAITOK);
- m->m_len = 0;
- m2->m_next = m;
- m2 = m;
- }
- }
- iv = malloc(i * sizeof (struct iovec),
- M_TEMP, M_WAITOK);
- uiop->uio_iov = iv2 = iv;
- m = mb;
- left = len;
- i = 0;
- while (left > 0) {
- if (m == NULL)
- panic("nfsrv_read iov");
- siz = min(M_TRAILINGSPACE(m), left);
- if (siz > 0) {
- iv->iov_base = mtod(m, caddr_t) + m->m_len;
- iv->iov_len = siz;
- m->m_len += siz;
- left -= siz;
- iv++;
- i++;
- }
- m = m->m_next;
- }
- uiop->uio_iovcnt = i;
- uiop->uio_offset = off;
- uiop->uio_resid = len;
- uiop->uio_rw = UIO_READ;
- uiop->uio_segflg = UIO_SYSSPACE;
- uiop->uio_td = NULL;
- nh = nfsrv_sequential_heuristic(uiop, vp);
- ioflag |= nh->nh_seqcount << IO_SEQSHIFT;
- error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred);
- if (error == 0)
- nh->nh_nextoff = uiop->uio_offset;
- free((caddr_t)iv2, M_TEMP);
- if (error || (getret = VOP_GETATTR(vp, vap, cred))) {
- if (!error)
- error = getret;
- m_freem(mreq);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(v3));
- if (v3)
- nfsm_srvpostop_attr(getret, vap);
- error = 0;
- goto nfsmout;
- }
- } else
- uiop->uio_resid = 0;
- vput(vp);
- vp = NULL;
- nfsm_srvfillattr(vap, fp);
- tlen = len - uiop->uio_resid;
- cnt = cnt < tlen ? cnt : tlen;
- tlen = nfsm_rndup(cnt);
- if (len != tlen || tlen != cnt)
- nfsm_adj(mb, len - tlen, tlen - cnt);
- if (v3) {
- *tl++ = txdr_unsigned(cnt);
- if (cnt < reqlen)
- *tl++ = nfsrv_nfs_true;
- else
- *tl++ = nfsrv_nfs_false;
- }
- *tl = txdr_unsigned(cnt);
-nfsmout:
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * nfs write service
- */
-int
-nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct iovec *ivp;
- int i, cnt;
- struct mbuf *mp;
- struct nfs_fattr *fp;
- struct iovec *iv;
- struct vattr va, forat;
- struct vattr *vap = &va;
- u_int32_t *tl;
- caddr_t bpos;
- int error = 0, rdonly, len, forat_ret = 1;
- int ioflags, aftat_ret = 1, retlen = 0, zeroing, adjust;
- int stable = NFSV3WRITE_FILESYNC;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *vp = NULL;
- struct nfsheur *nh;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct uio io, *uiop = &io;
- off_t off;
- struct mount *mntp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (mrep == NULL) {
- *mrq = NULL;
- error = 0;
- goto nfsmout;
- }
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mntp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto ereply;
- }
- (void) vn_start_write(NULL, &mntp, V_WAIT);
- vfs_rel(mntp); /* The write holds a ref. */
- if (v3) {
- tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
- off = fxdr_hyper(tl);
- tl += 3;
- stable = fxdr_unsigned(int, *tl++);
- } else {
- tl = nfsm_dissect_nonblock(u_int32_t *, 4 * NFSX_UNSIGNED);
- off = (off_t)fxdr_unsigned(u_int32_t, *++tl);
- tl += 2;
- if (nfs_async)
- stable = NFSV3WRITE_UNSTABLE;
- }
- retlen = len = fxdr_unsigned(int32_t, *tl);
- cnt = i = 0;
-
- /*
- * For NFS Version 2, it is not obvious what a write of zero length
- * should do, but I might as well be consistent with Version 3,
- * which is to return ok so long as there are no permission problems.
- */
- if (len > 0) {
- zeroing = 1;
- mp = mrep;
- while (mp) {
- if (mp == md) {
- zeroing = 0;
- adjust = dpos - mtod(mp, caddr_t);
- mp->m_len -= adjust;
- if (mp->m_len > 0 && adjust > 0)
- mp->m_data += adjust;
- }
- if (zeroing)
- mp->m_len = 0;
- else if (mp->m_len > 0) {
- i += mp->m_len;
- if (i > len) {
- mp->m_len -= (i - len);
- zeroing = 1;
- }
- if (mp->m_len > 0)
- cnt++;
- }
- mp = mp->m_next;
- }
- }
- if (len > NFS_MAXDATA || len < 0 || i < len) {
- error = EIO;
- nfsm_reply(2 * NFSX_UNSIGNED);
- if (v3)
- nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
- error = 0;
- goto nfsmout;
- }
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- vp = NULL;
- nfsm_reply(2 * NFSX_UNSIGNED);
- if (v3)
- nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
- error = 0;
- goto nfsmout;
- }
- if (v3)
- forat_ret = VOP_GETATTR(vp, &forat, cred);
- if (vp->v_type != VREG) {
- if (v3)
- error = EINVAL;
- else
- error = (vp->v_type == VDIR) ? EISDIR : EACCES;
- }
- if (!error)
- error = nfsrv_access(vp, VWRITE, cred, rdonly, 1);
- if (error) {
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_WCCDATA(v3));
- if (v3)
- nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
- error = 0;
- goto nfsmout;
- }
-
- if (len > 0) {
- ivp = malloc(cnt * sizeof (struct iovec), M_TEMP,
- M_WAITOK);
- uiop->uio_iov = iv = ivp;
- uiop->uio_iovcnt = cnt;
- mp = mrep;
- while (mp) {
- if (mp->m_len > 0) {
- ivp->iov_base = mtod(mp, caddr_t);
- ivp->iov_len = mp->m_len;
- ivp++;
- }
- mp = mp->m_next;
- }
-
- /*
- * XXX
- * The IO_METASYNC flag indicates that all metadata (and not just
- * enough to ensure data integrity) mus be written to stable storage
- * synchronously.
- * (IO_METASYNC is not yet implemented in 4.4BSD-Lite.)
- */
- if (stable == NFSV3WRITE_UNSTABLE)
- ioflags = IO_NODELOCKED;
- else if (stable == NFSV3WRITE_DATASYNC)
- ioflags = (IO_SYNC | IO_NODELOCKED);
- else
- ioflags = (IO_METASYNC | IO_SYNC | IO_NODELOCKED);
- uiop->uio_resid = len;
- uiop->uio_rw = UIO_WRITE;
- uiop->uio_segflg = UIO_SYSSPACE;
- uiop->uio_td = NULL;
- uiop->uio_offset = off;
- nh = nfsrv_sequential_heuristic(uiop, vp);
- ioflags |= nh->nh_seqcount << IO_SEQSHIFT;
- error = VOP_WRITE(vp, uiop, ioflags, cred);
- if (error == 0)
- nh->nh_nextoff = uiop->uio_offset;
- /* Unlocked write. */
- nfsrvstats.srvvop_writes++;
- free((caddr_t)iv, M_TEMP);
- }
- aftat_ret = VOP_GETATTR(vp, vap, cred);
- vput(vp);
- vp = NULL;
- if (!error)
- error = aftat_ret;
-ereply:
- nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) +
- 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3));
- if (v3) {
- nfsm_srvwcc_data(forat_ret, &forat, aftat_ret, vap);
- if (error) {
- error = 0;
- goto nfsmout;
- }
- tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
- *tl++ = txdr_unsigned(retlen);
- /*
- * If nfs_async is set, then pretend the write was FILESYNC.
- */
- if (stable == NFSV3WRITE_UNSTABLE && !nfs_async)
- *tl++ = txdr_unsigned(stable);
- else
- *tl++ = txdr_unsigned(NFSV3WRITE_FILESYNC);
- /*
- * Actually, there is no need to txdr these fields,
- * but it may make the values more human readable,
- * for debugging purposes.
- */
- if (nfsver.tv_sec == 0)
- nfsver = boottime;
- *tl++ = txdr_unsigned(nfsver.tv_sec);
- *tl = txdr_unsigned(nfsver.tv_usec);
- } else if (!error) {
- /* v2 non-error case. */
- fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
- nfsm_srvfillattr(vap, fp);
- }
- error = 0;
-nfsmout:
- if (vp)
- vput(vp);
- vn_finished_write(mntp);
- return(error);
-}
-
-/*
- * nfs create service
- * now does a truncate to 0 length via. setattr if it already exists
- */
-int
-nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nfs_fattr *fp;
- struct vattr va, dirfor, diraft;
- struct vattr *vap = &va;
- struct nfsv2_sattr *sp;
- u_int32_t *tl;
- struct nameidata nd;
- caddr_t bpos;
- int error = 0, rdev, len, tsize, dirfor_ret = 1, diraft_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0;
- struct mbuf *mb, *mreq;
- struct vnode *dirp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- u_quad_t tempsize;
- struct timespec cverf;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
-#ifndef nolint
- rdev = 0;
-#endif
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto ereply;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
-
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = CREATE;
- nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE;
-
- /*
- * Call namei and do initial cleanup to get a few things
- * out of the way. If we get an initial error we cleanup
- * and return here to avoid special-casing the invalid nd
- * structure through the rest of the case. dirp may be
- * set even if an error occurs, but the nd structure will not
- * be valid at all if an error occurs so we have to invalidate it
- * prior to calling nfsm_reply ( which might goto nfsmout ).
- */
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (dirp && !v3) {
- vrele(dirp);
- dirp = NULL;
- }
- if (error) {
- nfsm_reply(NFSX_WCCDATA(v3));
- if (v3)
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- error = 0;
- goto nfsmout;
- }
-
- /*
- * No error. Continue. State:
- *
- * startdir is valid ( we release this immediately )
- * dirp may be valid
- * nd.ni_vp may be valid
- * nd.ni_dvp is valid
- *
- * The error state is set through the code and we may also do some
- * opportunistic releasing of vnodes to avoid holding locks through
- * NFS I/O. The cleanup at the end is a catch-all
- */
-
- VATTR_NULL(vap);
- if (v3) {
- tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
- how = fxdr_unsigned(int, *tl);
- switch (how) {
- case NFSV3CREATE_GUARDED:
- if (nd.ni_vp) {
- error = EEXIST;
- break;
- }
- /* fall through */
- case NFSV3CREATE_UNCHECKED:
- nfsm_srvsattr(vap);
- break;
- case NFSV3CREATE_EXCLUSIVE:
- tl = nfsm_dissect_nonblock(u_int32_t *,
- NFSX_V3CREATEVERF);
- /* Unique bytes, endianness is not important. */
- cverf.tv_sec = (int32_t)tl[0];
- cverf.tv_nsec = tl[1];
- exclusive_flag = 1;
- break;
- };
- vap->va_type = VREG;
- } else {
- sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
- vap->va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode));
- if (vap->va_type == VNON)
- vap->va_type = VREG;
- vap->va_mode = nfstov_mode(sp->sa_mode);
- switch (vap->va_type) {
- case VREG:
- tsize = fxdr_unsigned(int32_t, sp->sa_size);
- if (tsize != -1)
- vap->va_size = (u_quad_t)tsize;
- break;
- case VCHR:
- case VBLK:
- case VFIFO:
- rdev = fxdr_unsigned(long, sp->sa_size);
- break;
- default:
- break;
- };
- }
-
- /*
- * Iff doesn't exist, create it
- * otherwise just truncate to 0 length
- * should I set the mode too ?
- *
- * The only possible error we can have at this point is EEXIST.
- * nd.ni_vp will also be non-NULL in that case.
- */
- if (nd.ni_vp == NULL) {
- if (vap->va_mode == (mode_t)VNOVAL)
- vap->va_mode = 0;
- if (vap->va_type == VREG || vap->va_type == VSOCK) {
- error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
- if (error)
- NDFREE(&nd, NDF_ONLY_PNBUF);
- else {
- if (exclusive_flag) {
- exclusive_flag = 0;
- VATTR_NULL(vap);
- vap->va_atime = cverf;
- error = VOP_SETATTR(nd.ni_vp, vap,
- cred);
- }
- }
- } else if (vap->va_type == VCHR || vap->va_type == VBLK ||
- vap->va_type == VFIFO) {
- /*
- * NFSv2-specific code for creating device nodes
- * and fifos.
- *
- * Handle SysV FIFO node special cases. All other
- * devices require super user to access.
- */
- if (vap->va_type == VCHR && rdev == 0xffffffff)
- vap->va_type = VFIFO;
- if (vap->va_type != VFIFO &&
- (error = priv_check_cred(cred, PRIV_VFS_MKNOD_DEV,
- 0))) {
- goto ereply;
- }
- vap->va_rdev = rdev;
- error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
- if (error) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- goto ereply;
- }
- vput(nd.ni_vp);
- nd.ni_vp = NULL;
-
- /*
- * release dvp prior to lookup
- */
- vput(nd.ni_dvp);
- nd.ni_dvp = NULL;
- /*
- * Setup for lookup.
- *
- * Even though LOCKPARENT was cleared, ni_dvp may
- * be garbage.
- */
- nd.ni_cnd.cn_nameiop = LOOKUP;
- nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
- nd.ni_cnd.cn_thread = curthread;
- nd.ni_cnd.cn_cred = cred;
- error = lookup(&nd);
- nd.ni_dvp = NULL;
- if (error)
- goto ereply;
-
- if (nd.ni_cnd.cn_flags & ISSYMLINK) {
- error = EINVAL;
- goto ereply;
- }
- } else {
- error = ENXIO;
- }
- } else {
- if (vap->va_size != -1) {
- error = nfsrv_access(nd.ni_vp, VWRITE,
- cred, (nd.ni_cnd.cn_flags & RDONLY), 0);
- if (!error) {
- tempsize = vap->va_size;
- VATTR_NULL(vap);
- vap->va_size = tempsize;
- error = VOP_SETATTR(nd.ni_vp, vap, cred);
- }
- }
- }
-
- if (!error) {
- bzero((caddr_t)fhp, sizeof(nfh));
- fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
- error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
- if (!error)
- error = VOP_GETATTR(nd.ni_vp, vap, cred);
- }
- if (v3) {
- if (exclusive_flag && !error &&
- bcmp(&cverf, &vap->va_atime, sizeof (cverf)))
- error = EEXIST;
- if (dirp == nd.ni_dvp)
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- else {
- /* Drop the other locks to avoid deadlock. */
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- nd.ni_dvp = NULL;
- nd.ni_vp = NULL;
-
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- VOP_UNLOCK(dirp, 0);
- }
- }
-ereply:
- nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
- if (v3) {
- if (!error) {
- nfsm_srvpostop_fh(fhp);
- nfsm_srvpostop_attr(0, vap);
- }
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- } else if (!error) {
- /* v2 non-error case. */
- nfsm_srvfhtom(fhp, v3);
- fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
- nfsm_srvfillattr(vap, fp);
- }
- error = 0;
-
-nfsmout:
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- if (nd.ni_startdir) {
- vrele(nd.ni_startdir);
- nd.ni_startdir = NULL;
- }
- if (dirp)
- vrele(dirp);
- NDFREE(&nd, NDF_ONLY_PNBUF);
- vn_finished_write(mp);
- return (error);
-}
-
-/*
- * nfs v3 mknod service
- */
-int
-nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct vattr va, dirfor, diraft;
- struct vattr *vap = &va;
- struct thread *td = curthread;
- u_int32_t *tl;
- struct nameidata nd;
- caddr_t bpos;
- int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
- u_int32_t major, minor;
- enum vtype vtyp;
- struct mbuf *mb, *mreq;
- struct vnode *vp, *dirp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct mount *mp = NULL;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (!v3)
- panic("nfsrv_mknod: v3 proc called on a v2 connection");
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto ereply;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
-
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = CREATE;
- nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE;
-
- /*
- * Handle nfs_namei() call. If an error occurs, the nd structure
- * is not valid. However, nfsm_*() routines may still jump to
- * nfsmout.
- */
-
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (error) {
- nfsm_reply(NFSX_WCCDATA(1));
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- error = 0;
- goto nfsmout;
- }
- tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
- vtyp = nfsv3tov_type(*tl);
- if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
- error = NFSERR_BADTYPE;
- goto out;
- }
- VATTR_NULL(vap);
- nfsm_srvsattr(vap);
- if (vtyp == VCHR || vtyp == VBLK) {
- tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
- major = fxdr_unsigned(u_int32_t, *tl++);
- minor = fxdr_unsigned(u_int32_t, *tl);
- vap->va_rdev = makedev(major, minor);
- }
-
- /*
- * Iff doesn't exist, create it.
- */
- if (nd.ni_vp) {
- error = EEXIST;
- goto out;
- }
- vap->va_type = vtyp;
- if (vap->va_mode == (mode_t)VNOVAL)
- vap->va_mode = 0;
- if (vtyp == VSOCK) {
- vrele(nd.ni_startdir);
- nd.ni_startdir = NULL;
- error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
- if (error)
- NDFREE(&nd, NDF_ONLY_PNBUF);
- } else {
- if (vtyp != VFIFO && (error = priv_check_cred(cred,
- PRIV_VFS_MKNOD_DEV, 0)))
- goto out;
- error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
- if (error) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- goto out;
- }
- vput(nd.ni_vp);
- nd.ni_vp = NULL;
-
- /*
- * Release dvp prior to lookup
- */
- vput(nd.ni_dvp);
- nd.ni_dvp = NULL;
-
- nd.ni_cnd.cn_nameiop = LOOKUP;
- nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
- nd.ni_cnd.cn_thread = td;
- nd.ni_cnd.cn_cred = td->td_ucred;
- error = lookup(&nd);
- nd.ni_dvp = NULL;
-
- if (error)
- goto out;
- if (nd.ni_cnd.cn_flags & ISSYMLINK)
- error = EINVAL;
- }
-
- /*
- * send response, cleanup, return.
- */
-out:
- vp = nd.ni_vp;
- if (!error) {
- bzero((caddr_t)fhp, sizeof(nfh));
- fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
- error = VOP_VPTOFH(vp, &fhp->fh_fid);
- if (!error)
- error = VOP_GETATTR(vp, vap, cred);
- }
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- nd.ni_dvp = NULL;
- }
- if (vp) {
- vput(vp);
- vp = NULL;
- nd.ni_vp = NULL;
- }
- if (nd.ni_startdir) {
- vrele(nd.ni_startdir);
- nd.ni_startdir = NULL;
- }
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (dirp) {
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- vput(dirp);
- }
-ereply:
- nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
- if (v3) {
- if (!error) {
- nfsm_srvpostop_fh(fhp);
- nfsm_srvpostop_attr(0, vap);
- }
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- }
- vn_finished_write(mp);
- return (0);
-nfsmout:
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- if (dirp)
- vrele(dirp);
- if (nd.ni_startdir)
- vrele(nd.ni_startdir);
- NDFREE(&nd, NDF_ONLY_PNBUF);
- vn_finished_write(mp);
- return (error);
-}
-
-/*
- * nfs remove service
- */
-int
-nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nameidata nd;
- caddr_t bpos;
- int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *dirp;
- struct vattr dirfor, diraft;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto ereply;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
-
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = DELETE;
- nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (dirp && !v3) {
- vrele(dirp);
- dirp = NULL;
- }
- if (error == 0) {
- if (nd.ni_vp->v_type == VDIR) {
- error = EPERM; /* POSIX */
- goto out;
- }
- /*
- * The root of a mounted filesystem cannot be deleted.
- */
- if (nd.ni_vp->v_vflag & VV_ROOT) {
- error = EBUSY;
- goto out;
- }
-out:
- if (!error) {
- error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
- NDFREE(&nd, NDF_ONLY_PNBUF);
- }
- }
- if (dirp && v3) {
- if (dirp == nd.ni_dvp)
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- else {
- /* Drop the other locks to avoid deadlock. */
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- nd.ni_dvp = NULL;
- nd.ni_vp = NULL;
-
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- VOP_UNLOCK(dirp, 0);
- }
- vrele(dirp);
- dirp = NULL;
- }
-ereply:
- nfsm_reply(NFSX_WCCDATA(v3));
- if (v3)
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- error = 0;
-nfsmout:
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- vn_finished_write(mp);
- return(error);
-}
-
-/*
- * nfs rename service
- */
-int
-nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- caddr_t bpos;
- int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
- int tdirfor_ret = 1, tdiraft_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct nameidata fromnd, tond;
- struct vnode *fvp, *tvp, *tdvp, *fdirp = NULL;
- struct vnode *tdirp = NULL;
- struct vattr fdirfor, fdiraft, tdirfor, tdiraft;
- nfsfh_t fnfh, tnfh;
- fhandle_t *ffhp, *tfhp;
- uid_t saved_uid;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
-#ifndef nolint
- fvp = NULL;
-#endif
- ffhp = &fnfh.fh_generic;
- tfhp = &tnfh.fh_generic;
-
- /*
- * Clear fields incase goto nfsmout occurs from macro.
- */
-
- ndclear(&fromnd);
- ndclear(&tond);
-
- nfsm_srvmtofh(ffhp);
- if ((mp = vfs_getvfs(&ffhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto out1;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
- /*
- * Remember our original uid so that we can reset cr_uid before
- * the second nfs_namei() call, in case it is remapped.
- */
- saved_uid = cred->cr_uid;
- fromnd.ni_cnd.cn_cred = cred;
- fromnd.ni_cnd.cn_nameiop = DELETE;
- fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART;
- error = nfs_namei(&fromnd, nfsd, ffhp, len, slp, nam, &md,
- &dpos, &fdirp, v3, &fdirfor, &fdirfor_ret, FALSE);
- if (fdirp && !v3) {
- vrele(fdirp);
- fdirp = NULL;
- }
- if (error) {
- nfsm_reply(2 * NFSX_WCCDATA(v3));
- if (v3) {
- nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
- nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
- }
- error = 0;
- goto nfsmout;
- }
- fvp = fromnd.ni_vp;
- nfsm_srvmtofh(tfhp);
- nfsm_srvnamesiz(len2);
- cred->cr_uid = saved_uid;
- tond.ni_cnd.cn_cred = cred;
- tond.ni_cnd.cn_nameiop = RENAME;
- tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
- error = nfs_namei(&tond, nfsd, tfhp, len2, slp, nam, &md,
- &dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, FALSE);
- if (tdirp && !v3) {
- vrele(tdirp);
- tdirp = NULL;
- }
- if (error)
- goto out1;
-
- tdvp = tond.ni_dvp;
- tvp = tond.ni_vp;
- if (tvp != NULL) {
- if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
- if (v3)
- error = EEXIST;
- else
- error = EISDIR;
- goto out;
- } else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
- if (v3)
- error = EEXIST;
- else
- error = ENOTDIR;
- goto out;
- }
- if (tvp->v_type == VDIR && tvp->v_mountedhere) {
- if (v3)
- error = EXDEV;
- else
- error = ENOTEMPTY;
- goto out;
- }
- }
- if (fvp->v_type == VDIR && fvp->v_mountedhere) {
- if (v3)
- error = EXDEV;
- else
- error = ENOTEMPTY;
- goto out;
- }
- if (fvp->v_mount != tdvp->v_mount) {
- if (v3)
- error = EXDEV;
- else
- error = ENOTEMPTY;
- goto out;
- }
- if (fvp == tdvp) {
- if (v3)
- error = EINVAL;
- else
- error = ENOTEMPTY;
- }
- /*
- * If source is the same as the destination (that is the
- * same vnode with the same name in the same directory),
- * then there is nothing to do.
- */
- if (fvp == tvp && fromnd.ni_dvp == tdvp &&
- fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
- !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
- fromnd.ni_cnd.cn_namelen))
- error = -1;
-out:
- if (!error) {
- /*
- * The VOP_RENAME function releases all vnode references &
- * locks prior to returning so we need to clear the pointers
- * to bypass cleanup code later on.
- */
- error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
- tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
- fromnd.ni_dvp = NULL;
- fromnd.ni_vp = NULL;
- tond.ni_dvp = NULL;
- tond.ni_vp = NULL;
- if (error) {
- NDFREE(&fromnd, NDF_ONLY_PNBUF);
- NDFREE(&tond, NDF_ONLY_PNBUF);
- }
- } else {
- if (error == -1)
- error = 0;
- }
- /* fall through */
-out1:
- nfsm_reply(2 * NFSX_WCCDATA(v3));
- if (v3) {
- /* Release existing locks to prevent deadlock. */
- if (tond.ni_dvp) {
- if (tond.ni_dvp == tond.ni_vp)
- vrele(tond.ni_dvp);
- else
- vput(tond.ni_dvp);
- }
- if (tond.ni_vp)
- vput(tond.ni_vp);
- tond.ni_dvp = NULL;
- tond.ni_vp = NULL;
-
- if (fdirp) {
- vn_lock(fdirp, LK_EXCLUSIVE | LK_RETRY);
- fdiraft_ret = VOP_GETATTR(fdirp, &fdiraft, cred);
- VOP_UNLOCK(fdirp, 0);
- }
- if (tdirp) {
- vn_lock(tdirp, LK_EXCLUSIVE | LK_RETRY);
- tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred);
- VOP_UNLOCK(tdirp, 0);
- }
- nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
- nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
- }
- error = 0;
- /* fall through */
-
-nfsmout:
- /*
- * Clear out tond related fields
- */
- if (tond.ni_dvp) {
- if (tond.ni_dvp == tond.ni_vp)
- vrele(tond.ni_dvp);
- else
- vput(tond.ni_dvp);
- }
- if (tond.ni_vp)
- vput(tond.ni_vp);
- if (tdirp)
- vrele(tdirp);
- if (tond.ni_startdir)
- vrele(tond.ni_startdir);
- NDFREE(&tond, NDF_ONLY_PNBUF);
- /*
- * Clear out fromnd related fields
- */
- if (fdirp)
- vrele(fdirp);
- if (fromnd.ni_startdir)
- vrele(fromnd.ni_startdir);
- NDFREE(&fromnd, NDF_ONLY_PNBUF);
- if (fromnd.ni_dvp)
- vrele(fromnd.ni_dvp);
- if (fromnd.ni_vp)
- vrele(fromnd.ni_vp);
-
- vn_finished_write(mp);
- return (error);
-}
-
-/*
- * nfs link service
- */
-int
-nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nameidata nd;
- caddr_t bpos;
- int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
- int getret = 1, v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *vp = NULL, *xp, *dirp = NULL;
- struct vattr dirfor, diraft, at;
- nfsfh_t nfh, dnfh;
- fhandle_t *fhp, *dfhp;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- dfhp = &dnfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto ereply;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvmtofh(dfhp);
- nfsm_srvnamesiz(len);
-
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
- if (v3) {
- nfsm_srvpostop_attr(getret, &at);
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- }
- vp = NULL;
- error = 0;
- goto nfsmout;
- }
- if (v3)
- getret = VOP_GETATTR(vp, &at, cred);
- if (vp->v_type == VDIR) {
- error = EPERM; /* POSIX */
- goto out1;
- }
- VOP_UNLOCK(vp, 0);
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = CREATE;
- nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE;
- error = nfs_namei(&nd, nfsd, dfhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (dirp && !v3) {
- vrele(dirp);
- dirp = NULL;
- }
- if (error) {
- vrele(vp);
- vp = NULL;
- goto out2;
- }
- xp = nd.ni_vp;
- if (xp != NULL) {
- error = EEXIST;
- vrele(vp);
- vp = NULL;
- goto out2;
- }
- xp = nd.ni_dvp;
- if (vp->v_mount != xp->v_mount) {
- error = EXDEV;
- vrele(vp);
- vp = NULL;
- goto out2;
- }
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
- NDFREE(&nd, NDF_ONLY_PNBUF);
- /* fall through */
-
-out1:
- if (v3)
- getret = VOP_GETATTR(vp, &at, cred);
-out2:
- if (dirp) {
- if (dirp == nd.ni_dvp)
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- else {
- /* Release existing locks to prevent deadlock. */
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vrele(nd.ni_vp);
- nd.ni_dvp = NULL;
- nd.ni_vp = NULL;
-
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- VOP_UNLOCK(dirp, 0);
- }
- }
-ereply:
- nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
- if (v3) {
- nfsm_srvpostop_attr(getret, &at);
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- }
- error = 0;
- /* fall through */
-
-nfsmout:
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (vp)
- vput(vp);
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (dirp)
- vrele(dirp);
- if (nd.ni_vp)
- vrele(nd.ni_vp);
- vn_finished_write(mp);
- return(error);
-}
-
-/*
- * nfs symbolic link service
- */
-int
-nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct vattr va, dirfor, diraft;
- struct nameidata nd;
- struct vattr *vap = &va;
- struct nfsv2_sattr *sp;
- char *bpos, *pathcp = NULL;
- struct uio io;
- struct iovec iv;
- int error = 0, len, len2, dirfor_ret = 1, diraft_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *dirp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto out;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = CREATE;
- nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | NOCACHE;
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (error == 0) {
- VATTR_NULL(vap);
- if (v3)
- nfsm_srvsattr(vap);
- nfsm_srvpathsiz(len2);
- }
- if (dirp && !v3) {
- vrele(dirp);
- dirp = NULL;
- }
- if (error)
- goto out;
- pathcp = malloc(len2 + 1, M_TEMP, M_WAITOK);
- iv.iov_base = pathcp;
- iv.iov_len = len2;
- io.uio_resid = len2;
- io.uio_offset = 0;
- io.uio_iov = &iv;
- io.uio_iovcnt = 1;
- io.uio_segflg = UIO_SYSSPACE;
- io.uio_rw = UIO_READ;
- io.uio_td = NULL;
- nfsm_mtouio(&io, len2);
- if (!v3) {
- sp = nfsm_dissect_nonblock(struct nfsv2_sattr *, NFSX_V2SATTR);
- vap->va_mode = nfstov_mode(sp->sa_mode);
- }
- *(pathcp + len2) = '\0';
- if (nd.ni_vp) {
- error = EEXIST;
- goto out;
- }
-
- /*
- * issue symlink op. SAVESTART is set so the underlying path component
- * is only freed by the VOP if an error occurs.
- */
- if (vap->va_mode == (mode_t)VNOVAL)
- vap->va_mode = 0;
- error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap, pathcp);
- if (error)
- NDFREE(&nd, NDF_ONLY_PNBUF);
- else
- vput(nd.ni_vp);
- nd.ni_vp = NULL;
- /*
- * releases directory prior to potential lookup op.
- */
- vput(nd.ni_dvp);
- nd.ni_dvp = NULL;
-
- if (error == 0) {
- if (v3) {
- /*
- * Issue lookup. Leave SAVESTART set so we can easily free
- * the name buffer later on.
- *
- * since LOCKPARENT is not set, ni_dvp will be garbage on
- * return whether an error occurs or not.
- */
- nd.ni_cnd.cn_nameiop = LOOKUP;
- nd.ni_cnd.cn_flags &= ~(LOCKPARENT | FOLLOW);
- nd.ni_cnd.cn_flags |= (NOFOLLOW | LOCKLEAF);
- nd.ni_cnd.cn_thread = curthread;
- nd.ni_cnd.cn_cred = cred;
- error = lookup(&nd);
- nd.ni_dvp = NULL;
-
- if (error == 0) {
- bzero((caddr_t)fhp, sizeof(nfh));
- fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
- error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
- if (!error)
- error = VOP_GETATTR(nd.ni_vp, vap, cred);
- vput(nd.ni_vp);
- nd.ni_vp = NULL;
- }
- }
- }
-out:
- /*
- * These releases aren't strictly required, does even doing them
- * make any sense? XXX can nfsm_reply() block?
- */
- if (pathcp) {
- free(pathcp, M_TEMP);
- pathcp = NULL;
- }
- if (dirp) {
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- VOP_UNLOCK(dirp, 0);
- }
- if (nd.ni_startdir) {
- vrele(nd.ni_startdir);
- nd.ni_startdir = NULL;
- }
- nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
- if (v3) {
- if (!error) {
- nfsm_srvpostop_fh(fhp);
- nfsm_srvpostop_attr(0, vap);
- }
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- }
- error = 0;
- /* fall through */
-
-nfsmout:
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vrele(nd.ni_vp);
- if (nd.ni_startdir)
- vrele(nd.ni_startdir);
- if (dirp)
- vrele(dirp);
- if (pathcp)
- free(pathcp, M_TEMP);
-
- vn_finished_write(mp);
- return (error);
-}
-
-/*
- * nfs mkdir service
- */
-int
-nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct vattr va, dirfor, diraft;
- struct vattr *vap = &va;
- struct nfs_fattr *fp;
- struct nameidata nd;
- u_int32_t *tl;
- caddr_t bpos;
- int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *dirp = NULL;
- int vpexcl = 0;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto out;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = CREATE;
- nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE;
-
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (dirp && !v3) {
- vrele(dirp);
- dirp = NULL;
- }
- if (error) {
- nfsm_reply(NFSX_WCCDATA(v3));
- if (v3)
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- error = 0;
- goto nfsmout;
- }
- VATTR_NULL(vap);
- if (v3) {
- nfsm_srvsattr(vap);
- } else {
- tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
- vap->va_mode = nfstov_mode(*tl++);
- }
-
- /*
- * At this point nd.ni_dvp is referenced and exclusively locked and
- * nd.ni_vp, if it exists, is referenced but not locked.
- */
-
- vap->va_type = VDIR;
- if (nd.ni_vp != NULL) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- error = EEXIST;
- goto out;
- }
-
- /*
- * Issue mkdir op. Since SAVESTART is not set, the pathname
- * component is freed by the VOP call. This will fill-in
- * nd.ni_vp, reference, and exclusively lock it.
- */
- if (vap->va_mode == (mode_t)VNOVAL)
- vap->va_mode = 0;
- error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, vap);
- NDFREE(&nd, NDF_ONLY_PNBUF);
- vpexcl = 1;
-
- vput(nd.ni_dvp);
- nd.ni_dvp = NULL;
-
- if (!error) {
- bzero((caddr_t)fhp, sizeof(nfh));
- fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
- error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
- if (!error)
- error = VOP_GETATTR(nd.ni_vp, vap, cred);
- }
-out:
- if (dirp) {
- if (dirp == nd.ni_dvp) {
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- } else {
- /* Release existing locks to prevent deadlock. */
- if (nd.ni_dvp) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (nd.ni_dvp == nd.ni_vp && vpexcl)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp) {
- if (vpexcl)
- vput(nd.ni_vp);
- else
- vrele(nd.ni_vp);
- }
- nd.ni_dvp = NULL;
- nd.ni_vp = NULL;
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- VOP_UNLOCK(dirp, 0);
- }
- }
- nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
- if (v3) {
- if (!error) {
- nfsm_srvpostop_fh(fhp);
- nfsm_srvpostop_attr(0, vap);
- }
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- } else if (!error) {
- /* v2 non-error case. */
- nfsm_srvfhtom(fhp, v3);
- fp = nfsm_build(struct nfs_fattr *, NFSX_V2FATTR);
- nfsm_srvfillattr(vap, fp);
- }
- error = 0;
- /* fall through */
-
-nfsmout:
- if (nd.ni_dvp) {
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (nd.ni_dvp == nd.ni_vp && vpexcl)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp) {
- if (vpexcl)
- vput(nd.ni_vp);
- else
- vrele(nd.ni_vp);
- }
- if (dirp)
- vrele(dirp);
- vn_finished_write(mp);
- return (error);
-}
-
-/*
- * nfs rmdir service
- */
-int
-nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- caddr_t bpos;
- int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *vp, *dirp = NULL;
- struct vattr dirfor, diraft;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct nameidata nd;
- struct mount *mp = NULL;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- ndclear(&nd);
-
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto out;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- nfsm_srvnamesiz(len);
- nd.ni_cnd.cn_cred = cred;
- nd.ni_cnd.cn_nameiop = DELETE;
- nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
- error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
- &dirp, v3, &dirfor, &dirfor_ret, FALSE);
- if (dirp && !v3) {
- vrele(dirp);
- dirp = NULL;
- }
- if (error) {
- nfsm_reply(NFSX_WCCDATA(v3));
- if (v3)
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- error = 0;
- goto nfsmout;
- }
- vp = nd.ni_vp;
- if (vp->v_type != VDIR) {
- error = ENOTDIR;
- goto out;
- }
- /*
- * No rmdir "." please.
- */
- if (nd.ni_dvp == vp) {
- error = EINVAL;
- goto out;
- }
- /*
- * The root of a mounted filesystem cannot be deleted.
- */
- if (vp->v_vflag & VV_ROOT)
- error = EBUSY;
-out:
- /*
- * Issue or abort op. Since SAVESTART is not set, path name
- * component is freed by the VOP after either.
- */
- if (!error)
- error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
- NDFREE(&nd, NDF_ONLY_PNBUF);
-
- if (dirp) {
- if (dirp == nd.ni_dvp)
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- else {
- /* Release existing locks to prevent deadlock. */
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- nd.ni_dvp = NULL;
- nd.ni_vp = NULL;
- vn_lock(dirp, LK_EXCLUSIVE | LK_RETRY);
- diraft_ret = VOP_GETATTR(dirp, &diraft, cred);
- VOP_UNLOCK(dirp, 0);
- }
- }
- nfsm_reply(NFSX_WCCDATA(v3));
- error = 0;
- if (v3)
- nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
- /* fall through */
-
-nfsmout:
- NDFREE(&nd, NDF_ONLY_PNBUF);
- if (nd.ni_dvp) {
- if (nd.ni_dvp == nd.ni_vp)
- vrele(nd.ni_dvp);
- else
- vput(nd.ni_dvp);
- }
- if (nd.ni_vp)
- vput(nd.ni_vp);
- if (dirp)
- vrele(dirp);
-
- vn_finished_write(mp);
- return(error);
-}
-
-/*
- * nfs readdir service
- * - mallocs what it thinks is enough to read
- * count rounded up to a multiple of NFS_DIRBLKSIZ <= NFS_MAXREADDIR
- * - calls VOP_READDIR()
- * - loops around building the reply
- * if the output generated exceeds count break out of loop
- * The nfsm_clget macro is used here so that the reply will be packed
- * tightly in mbuf clusters.
- * - it only knows that it has encountered eof when the VOP_READDIR()
- * reads nothing
- * - as such one readdir rpc will return eof false although you are there
- * and then the next will return eof
- * - it trims out records with d_fileno == 0
- * this doesn't matter for Unix clients, but they might confuse clients
- * for other os'.
- * NB: It is tempting to set eof to true if the VOP_READDIR() reads less
- * than requested, but this may not apply to all filesystems. For
- * example, client NFS does not { although it is never remote mounted
- * anyhow }
- * The alternate call nfsrv_readdirplus() does lookups as well.
- * PS: The NFS protocol spec. does not clarify what the "count" byte
- * argument is a count of.. just name strings and file id's or the
- * entire reply rpc or ...
- * I tried just file name and id sizes and it confused the Sun client,
- * so I am using the full rpc size now. The "paranoia.." comment refers
- * to including the status longwords that are not a part of the dir.
- * "entry" structures, but are in the rpc.
- */
-struct flrep {
- nfsuint64 fl_off;
- u_int32_t fl_postopok;
- u_int32_t fl_fattr[NFSX_V3FATTR / sizeof (u_int32_t)];
- u_int32_t fl_fhok;
- u_int32_t fl_fhsize;
- u_int32_t fl_nfh[NFSX_V3FH / sizeof (u_int32_t)];
-};
-
-int
-nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- char *bp, *be;
- struct mbuf *mp;
- struct dirent *dp;
- caddr_t cp;
- u_int32_t *tl;
- caddr_t bpos;
- struct mbuf *mb, *mreq;
- char *cpos, *cend, *rbuf;
- struct vnode *vp = NULL;
- struct vattr at;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct uio io;
- struct iovec iv;
- int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1;
- int siz, cnt, fullsiz, eofflag, rdonly, ncookies;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- u_quad_t off, toff, verf;
- u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
- int is_ufs;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if (v3) {
- tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
- toff = fxdr_hyper(tl);
- tl += 2;
- verf = fxdr_hyper(tl);
- tl += 2;
- } else {
- tl = nfsm_dissect_nonblock(u_int32_t *, 2 * NFSX_UNSIGNED);
- toff = fxdr_unsigned(u_quad_t, *tl++);
- verf = 0; /* shut up gcc */
- }
- off = toff;
- cnt = fxdr_unsigned(int, *tl);
- siz = ((cnt + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
- xfer = NFS_SRVMAXDATA(nfsd);
- if (cnt > xfer)
- cnt = xfer;
- if (siz > xfer)
- siz = xfer;
- fullsiz = siz;
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (!error && vp->v_type != VDIR) {
- error = ENOTDIR;
- vput(vp);
- vp = NULL;
- }
- if (error) {
- nfsm_reply(NFSX_UNSIGNED);
- if (v3)
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
-
- /*
- * Obtain lock on vnode for this section of the code
- */
- if (v3) {
- error = getret = VOP_GETATTR(vp, &at, cred);
-#if 0
- /*
- * XXX This check may be too strict for Solaris 2.5 clients.
- */
- if (!error && toff && verf && verf != at.va_filerev)
- error = NFSERR_BAD_COOKIE;
-#endif
- }
- if (!error)
- error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
- if (error) {
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(v3));
- if (v3)
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- is_ufs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "ufs") == 0;
- VOP_UNLOCK(vp, 0);
-
- /*
- * end section. Allocate rbuf and continue
- */
- rbuf = malloc(siz, M_TEMP, M_WAITOK);
-again:
- iv.iov_base = rbuf;
- iv.iov_len = fullsiz;
- io.uio_iov = &iv;
- io.uio_iovcnt = 1;
- io.uio_offset = (off_t)off;
- io.uio_resid = fullsiz;
- io.uio_segflg = UIO_SYSSPACE;
- io.uio_rw = UIO_READ;
- io.uio_td = NULL;
- eofflag = 0;
- if (cookies) {
- free((caddr_t)cookies, M_TEMP);
- cookies = NULL;
- }
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
- off = (off_t)io.uio_offset;
- if (!cookies && !error)
- error = NFSERR_PERM;
- if (v3) {
- getret = VOP_GETATTR(vp, &at, cred);
- if (!error)
- error = getret;
- }
- VOP_UNLOCK(vp, 0);
- if (error) {
- vrele(vp);
- vp = NULL;
- free((caddr_t)rbuf, M_TEMP);
- if (cookies)
- free((caddr_t)cookies, M_TEMP);
- nfsm_reply(NFSX_POSTOPATTR(v3));
- if (v3)
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- if (io.uio_resid) {
- siz -= io.uio_resid;
-
- /*
- * If nothing read, return eof
- * rpc reply
- */
- if (siz == 0) {
- vrele(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) +
- 2 * NFSX_UNSIGNED);
- if (v3) {
- nfsm_srvpostop_attr(getret, &at);
- tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
- txdr_hyper(at.va_filerev, tl);
- tl += 2;
- } else
- tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
- *tl++ = nfsrv_nfs_false;
- *tl = nfsrv_nfs_true;
- free((caddr_t)rbuf, M_TEMP);
- free((caddr_t)cookies, M_TEMP);
- error = 0;
- goto nfsmout;
- }
- }
-
- /*
- * Check for degenerate cases of nothing useful read.
- * If so go try again
- */
- cpos = rbuf;
- cend = rbuf + siz;
- dp = (struct dirent *)cpos;
- cookiep = cookies;
- /*
- * For some reason FreeBSD's ufs_readdir() chooses to back the
- * directory offset up to a block boundary, so it is necessary to
- * skip over the records that precede the requested offset. This
- * requires the assumption that file offset cookies monotonically
- * increase.
- */
- while (cpos < cend && ncookies > 0 &&
- (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
- (is_ufs == 1 && ((u_quad_t)(*cookiep)) <= toff))) {
- cpos += dp->d_reclen;
- dp = (struct dirent *)cpos;
- cookiep++;
- ncookies--;
- }
- if (cpos >= cend || ncookies == 0) {
- toff = off;
- siz = fullsiz;
- goto again;
- }
-
- len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */
- nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz);
- if (v3) {
- nfsm_srvpostop_attr(getret, &at);
- tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
- txdr_hyper(at.va_filerev, tl);
- }
- mp = mb;
- bp = bpos;
- be = bp + M_TRAILINGSPACE(mp);
-
- /* Loop through the records and build reply */
- while (cpos < cend && ncookies > 0) {
- if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
- nlen = dp->d_namlen;
- rem = nfsm_rndup(nlen) - nlen;
- len += (4 * NFSX_UNSIGNED + nlen + rem);
- if (v3)
- len += 2 * NFSX_UNSIGNED;
- if (len > cnt) {
- eofflag = 0;
- break;
- }
- /*
- * Build the directory record xdr from
- * the dirent entry.
- */
- nfsm_clget;
- *tl = nfsrv_nfs_true;
- bp += NFSX_UNSIGNED;
- if (v3) {
- nfsm_clget;
- *tl = 0;
- bp += NFSX_UNSIGNED;
- }
- nfsm_clget;
- *tl = txdr_unsigned(dp->d_fileno);
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- *tl = txdr_unsigned(nlen);
- bp += NFSX_UNSIGNED;
-
- /* And loop around copying the name */
- xfer = nlen;
- cp = dp->d_name;
- while (xfer > 0) {
- nfsm_clget;
- if ((bp+xfer) > be)
- tsiz = be-bp;
- else
- tsiz = xfer;
- bcopy(cp, bp, tsiz);
- bp += tsiz;
- xfer -= tsiz;
- if (xfer > 0)
- cp += tsiz;
- }
- /* And null pad to an int32_t boundary. */
- for (i = 0; i < rem; i++)
- *bp++ = '\0';
- nfsm_clget;
-
- /* Finish off the record */
- if (v3) {
- *tl = 0;
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- }
- *tl = txdr_unsigned(*cookiep);
- bp += NFSX_UNSIGNED;
- }
- cpos += dp->d_reclen;
- dp = (struct dirent *)cpos;
- cookiep++;
- ncookies--;
- }
- vrele(vp);
- vp = NULL;
- nfsm_clget;
- *tl = nfsrv_nfs_false;
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- if (eofflag)
- *tl = nfsrv_nfs_true;
- else
- *tl = nfsrv_nfs_false;
- bp += NFSX_UNSIGNED;
- if (mp != mb) {
- if (bp < be)
- mp->m_len = bp - mtod(mp, caddr_t);
- } else
- mp->m_len += bp - bpos;
- free((caddr_t)rbuf, M_TEMP);
- free((caddr_t)cookies, M_TEMP);
-
-nfsmout:
- if (vp)
- vrele(vp);
- return(error);
-}
-
-int
-nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- char *bp, *be;
- struct mbuf *mp;
- struct dirent *dp;
- caddr_t cp;
- u_int32_t *tl;
- caddr_t bpos;
- struct mbuf *mb, *mreq;
- char *cpos, *cend, *rbuf;
- struct vnode *vp = NULL, *nvp;
- struct flrep fl;
- nfsfh_t nfh;
- fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh;
- struct uio io;
- struct iovec iv;
- struct vattr va, at, *vap = &va;
- struct nfs_fattr *fp;
- int len, nlen, rem, xfer, tsiz, i, error = 0, error1, getret = 1;
- int vp_locked;
- int siz, cnt, fullsiz, eofflag, rdonly, dirlen, ncookies;
- u_quad_t off, toff, verf;
- u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- int usevget = 1;
- struct componentname cn;
- struct mount *mntp = NULL;
- int is_ufs;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- vp_locked = 0;
- if (!v3)
- panic("nfsrv_readdirplus: v3 proc called on a v2 connection");
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- tl = nfsm_dissect_nonblock(u_int32_t *, 6 * NFSX_UNSIGNED);
- toff = fxdr_hyper(tl);
- tl += 2;
- verf = fxdr_hyper(tl);
- tl += 2;
- siz = fxdr_unsigned(int, *tl++);
- cnt = fxdr_unsigned(int, *tl);
- off = toff;
- siz = ((siz + DIRBLKSIZ - 1) & ~(DIRBLKSIZ - 1));
- xfer = NFS_SRVMAXDATA(nfsd);
- if (cnt > xfer)
- cnt = xfer;
- if (siz > xfer)
- siz = xfer;
- fullsiz = siz;
- error = nfsrv_fhtovp(fhp, NFSRV_FLAG_BUSY, &vp, nfsd, slp,
- nam, &rdonly);
- if (!error) {
- vp_locked = 1;
- mntp = vp->v_mount;
- if (vp->v_type != VDIR) {
- error = ENOTDIR;
- vput(vp);
- vp = NULL;
- vp_locked = 0;
- }
- }
- if (error) {
- nfsm_reply(NFSX_UNSIGNED);
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- error = getret = VOP_GETATTR(vp, &at, cred);
-#if 0
- /*
- * XXX This check may be too strict for Solaris 2.5 clients.
- */
- if (!error && toff && verf && verf != at.va_filerev)
- error = NFSERR_BAD_COOKIE;
-#endif
- if (!error)
- error = nfsrv_access(vp, VEXEC, cred, rdonly, 0);
- if (error) {
- vput(vp);
- vp_locked = 0;
- vp = NULL;
- nfsm_reply(NFSX_V3POSTOPATTR);
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- is_ufs = strcmp(vp->v_mount->mnt_vfc->vfc_name, "ufs") == 0;
- VOP_UNLOCK(vp, 0);
- vp_locked = 0;
- rbuf = malloc(siz, M_TEMP, M_WAITOK);
-again:
- iv.iov_base = rbuf;
- iv.iov_len = fullsiz;
- io.uio_iov = &iv;
- io.uio_iovcnt = 1;
- io.uio_offset = (off_t)off;
- io.uio_resid = fullsiz;
- io.uio_segflg = UIO_SYSSPACE;
- io.uio_rw = UIO_READ;
- io.uio_td = NULL;
- eofflag = 0;
- vp_locked = 1;
- if (cookies) {
- free((caddr_t)cookies, M_TEMP);
- cookies = NULL;
- }
- vn_lock(vp, LK_SHARED | LK_RETRY);
- error = VOP_READDIR(vp, &io, cred, &eofflag, &ncookies, &cookies);
- off = (u_quad_t)io.uio_offset;
- getret = VOP_GETATTR(vp, &at, cred);
- VOP_UNLOCK(vp, 0);
- vp_locked = 0;
- if (!cookies && !error)
- error = NFSERR_PERM;
- if (!error)
- error = getret;
- if (error) {
- vrele(vp);
- vp = NULL;
- if (cookies)
- free((caddr_t)cookies, M_TEMP);
- free((caddr_t)rbuf, M_TEMP);
- nfsm_reply(NFSX_V3POSTOPATTR);
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- if (io.uio_resid) {
- siz -= io.uio_resid;
-
- /*
- * If nothing read, return eof
- * rpc reply
- */
- if (siz == 0) {
- vrele(vp);
- vp = NULL;
- nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
- 2 * NFSX_UNSIGNED);
- nfsm_srvpostop_attr(getret, &at);
- tl = nfsm_build(u_int32_t *, 4 * NFSX_UNSIGNED);
- txdr_hyper(at.va_filerev, tl);
- tl += 2;
- *tl++ = nfsrv_nfs_false;
- *tl = nfsrv_nfs_true;
- free((caddr_t)cookies, M_TEMP);
- free((caddr_t)rbuf, M_TEMP);
- error = 0;
- goto nfsmout;
- }
- }
-
- /*
- * Check for degenerate cases of nothing useful read.
- * If so go try again
- */
- cpos = rbuf;
- cend = rbuf + siz;
- dp = (struct dirent *)cpos;
- cookiep = cookies;
- /*
- * For some reason FreeBSD's ufs_readdir() chooses to back the
- * directory offset up to a block boundary, so it is necessary to
- * skip over the records that precede the requested offset. This
- * requires the assumption that file offset cookies monotonically
- * increase.
- */
- while (cpos < cend && ncookies > 0 &&
- (dp->d_fileno == 0 || dp->d_type == DT_WHT ||
- (is_ufs == 1 && ((u_quad_t)(*cookiep)) <= toff))) {
- cpos += dp->d_reclen;
- dp = (struct dirent *)cpos;
- cookiep++;
- ncookies--;
- }
- if (cpos >= cend || ncookies == 0) {
- toff = off;
- siz = fullsiz;
- goto again;
- }
-
- dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
- 2 * NFSX_UNSIGNED;
- nfsm_reply(cnt);
- nfsm_srvpostop_attr(getret, &at);
- tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
- txdr_hyper(at.va_filerev, tl);
- mp = mb;
- bp = bpos;
- be = bp + M_TRAILINGSPACE(mp);
-
- /* Loop through the records and build reply */
- while (cpos < cend && ncookies > 0) {
- if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
- nlen = dp->d_namlen;
- rem = nfsm_rndup(nlen)-nlen;
-
- if (usevget) {
- /*
- * For readdir_and_lookup get the vnode using
- * the file number.
- */
- error = VFS_VGET(mntp, dp->d_fileno, LK_SHARED,
- &nvp);
- if (error != 0 && error != EOPNOTSUPP) {
- error = 0;
- goto invalid;
- } else if (error == EOPNOTSUPP) {
- /*
- * VFS_VGET() not supported?
- * Let's switch to VOP_LOOKUP().
- */
- error = 0;
- usevget = 0;
- cn.cn_nameiop = LOOKUP;
- cn.cn_flags = ISLASTCN | NOFOLLOW | \
- LOCKSHARED | LOCKLEAF;
- cn.cn_lkflags = LK_SHARED | LK_RETRY;
- cn.cn_cred = cred;
- cn.cn_thread = curthread;
- }
- }
- if (!usevget) {
- cn.cn_nameptr = dp->d_name;
- cn.cn_namelen = dp->d_namlen;
- if (dp->d_namlen == 2 &&
- dp->d_name[0] == '.' &&
- dp->d_name[1] == '.') {
- cn.cn_flags |= ISDOTDOT;
- } else {
- cn.cn_flags &= ~ISDOTDOT;
- }
- if (!vp_locked) {
- vn_lock(vp, LK_SHARED | LK_RETRY);
- vp_locked = 1;
- }
- if ((vp->v_vflag & VV_ROOT) != 0 &&
- (cn.cn_flags & ISDOTDOT) != 0) {
- vref(vp);
- nvp = vp;
- } else if (VOP_LOOKUP(vp, &nvp, &cn) != 0)
- goto invalid;
- }
-
- bzero((caddr_t)nfhp, NFSX_V3FH);
- nfhp->fh_fsid = nvp->v_mount->mnt_stat.f_fsid;
- if ((error1 = VOP_VPTOFH(nvp, &nfhp->fh_fid)) == 0)
- error1 = VOP_GETATTR(nvp, vap, cred);
- if (!usevget && vp == nvp)
- vunref(nvp);
- else
- vput(nvp);
- nvp = NULL;
- if (error1 != 0)
- goto invalid;
-
- /*
- * If either the dircount or maxcount will be
- * exceeded, get out now. Both of these lengths
- * are calculated conservatively, including all
- * XDR overheads.
- */
- len += (8 * NFSX_UNSIGNED + nlen + rem + NFSX_V3FH +
- NFSX_V3POSTOPATTR);
- dirlen += (6 * NFSX_UNSIGNED + nlen + rem);
- if (len > cnt || dirlen > fullsiz) {
- eofflag = 0;
- break;
- }
-
- /*
- * Build the directory record xdr from
- * the dirent entry.
- */
- fp = (struct nfs_fattr *)&fl.fl_fattr;
- nfsm_srvfillattr(vap, fp);
- fl.fl_fhsize = txdr_unsigned(NFSX_V3FH);
- fl.fl_fhok = nfsrv_nfs_true;
- fl.fl_postopok = nfsrv_nfs_true;
- fl.fl_off.nfsuquad[0] = 0;
- fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep);
-
- nfsm_clget;
- *tl = nfsrv_nfs_true;
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- *tl = 0;
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- *tl = txdr_unsigned(dp->d_fileno);
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- *tl = txdr_unsigned(nlen);
- bp += NFSX_UNSIGNED;
-
- /* And loop around copying the name */
- xfer = nlen;
- cp = dp->d_name;
- while (xfer > 0) {
- nfsm_clget;
- if ((bp + xfer) > be)
- tsiz = be - bp;
- else
- tsiz = xfer;
- bcopy(cp, bp, tsiz);
- bp += tsiz;
- xfer -= tsiz;
- if (xfer > 0)
- cp += tsiz;
- }
- /* And null pad to an int32_t boundary. */
- for (i = 0; i < rem; i++)
- *bp++ = '\0';
-
- /*
- * Now copy the flrep structure out.
- */
- xfer = sizeof (struct flrep);
- cp = (caddr_t)&fl;
- while (xfer > 0) {
- nfsm_clget;
- if ((bp + xfer) > be)
- tsiz = be - bp;
- else
- tsiz = xfer;
- bcopy(cp, bp, tsiz);
- bp += tsiz;
- xfer -= tsiz;
- if (xfer > 0)
- cp += tsiz;
- }
- }
-invalid:
- cpos += dp->d_reclen;
- dp = (struct dirent *)cpos;
- cookiep++;
- ncookies--;
- }
- if (!usevget && vp_locked)
- vput(vp);
- else
- vrele(vp);
- vp = NULL;
- nfsm_clget;
- *tl = nfsrv_nfs_false;
- bp += NFSX_UNSIGNED;
- nfsm_clget;
- if (eofflag)
- *tl = nfsrv_nfs_true;
- else
- *tl = nfsrv_nfs_false;
- bp += NFSX_UNSIGNED;
- if (mp != mb) {
- if (bp < be)
- mp->m_len = bp - mtod(mp, caddr_t);
- } else
- mp->m_len += bp - bpos;
- free((caddr_t)cookies, M_TEMP);
- free((caddr_t)rbuf, M_TEMP);
-nfsmout:
- if (vp)
- vrele(vp);
- if (mntp)
- vfs_unbusy(mntp);
- return(error);
-}
-
-/*
- * nfs commit service
- */
-int
-nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct vattr bfor, aft;
- struct vnode *vp = NULL;
- nfsfh_t nfh;
- fhandle_t *fhp;
- u_int32_t *tl;
- caddr_t bpos;
- int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt;
- struct mbuf *mb, *mreq;
- u_quad_t off;
- struct mount *mp = NULL;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (!v3)
- panic("nfsrv_commit: v3 proc called on a v2 connection");
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
- error = ESTALE;
- goto ereply;
- }
- (void) vn_start_write(NULL, &mp, V_WAIT);
- vfs_rel(mp); /* The write holds a ref. */
- tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
-
- /*
- * XXX At this time VOP_FSYNC() does not accept offset and byte
- * count parameters, so these arguments are useless (someday maybe).
- */
- off = fxdr_hyper(tl);
- tl += 2;
- cnt = fxdr_unsigned(int, *tl);
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(2 * NFSX_UNSIGNED);
- nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
- error = 0;
- goto nfsmout;
- }
- for_ret = VOP_GETATTR(vp, &bfor, cred);
-
- /*
- * RFC 1813 3.3.21: if count is 0, a flush from offset to the end of file
- * is done. At this time VOP_FSYNC does not accept offset and byte count
- * parameters so call VOP_FSYNC the whole file for now.
- */
- if (cnt == 0 || cnt > MAX_COMMIT_COUNT) {
- /*
- * Give up and do the whole thing
- */
- if (vp->v_object &&
- (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) {
- VM_OBJECT_WLOCK(vp->v_object);
- vm_object_page_clean(vp->v_object, 0, 0, OBJPC_SYNC);
- VM_OBJECT_WUNLOCK(vp->v_object);
- }
- error = VOP_FSYNC(vp, MNT_WAIT, curthread);
- } else {
- /*
- * Locate and synchronously write any buffers that fall
- * into the requested range. Note: we are assuming that
- * f_iosize is a power of 2.
- */
- int iosize = vp->v_mount->mnt_stat.f_iosize;
- int iomask = iosize - 1;
- struct bufobj *bo;
- daddr_t lblkno;
-
- /*
- * Align to iosize boundry, super-align to page boundry.
- */
- if (off & iomask) {
- cnt += off & iomask;
- off &= ~(u_quad_t)iomask;
- }
- if (off & PAGE_MASK) {
- cnt += off & PAGE_MASK;
- off &= ~(u_quad_t)PAGE_MASK;
- }
- lblkno = off / iosize;
-
- if (vp->v_object &&
- (vp->v_object->flags & OBJ_MIGHTBEDIRTY)) {
- VM_OBJECT_WLOCK(vp->v_object);
- vm_object_page_clean(vp->v_object, off, off + cnt,
- OBJPC_SYNC);
- VM_OBJECT_WUNLOCK(vp->v_object);
- }
-
- bo = &vp->v_bufobj;
- BO_LOCK(bo);
- while (cnt > 0) {
- struct buf *bp;
-
- /*
- * If we have a buffer and it is marked B_DELWRI we
- * have to lock and write it. Otherwise the prior
- * write is assumed to have already been committed.
- *
- * gbincore() can return invalid buffers now so we
- * have to check that bit as well (though B_DELWRI
- * should not be set if B_INVAL is set there could be
- * a race here since we haven't locked the buffer).
- */
- if ((bp = gbincore(&vp->v_bufobj, lblkno)) != NULL) {
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_SLEEPFAIL |
- LK_INTERLOCK, BO_LOCKPTR(bo)) == ENOLCK) {
- BO_LOCK(bo);
- continue; /* retry */
- }
- if ((bp->b_flags & (B_DELWRI|B_INVAL)) ==
- B_DELWRI) {
- bremfree(bp);
- bp->b_flags &= ~B_ASYNC;
- bwrite(bp);
- ++nfs_commit_miss;
- } else
- BUF_UNLOCK(bp);
- BO_LOCK(bo);
- }
- ++nfs_commit_blks;
- if (cnt < iosize)
- break;
- cnt -= iosize;
- ++lblkno;
- }
- BO_UNLOCK(bo);
- }
-
- aft_ret = VOP_GETATTR(vp, &aft, cred);
- vput(vp);
- vp = NULL;
-ereply:
- nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF);
- nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
- if (!error) {
- tl = nfsm_build(u_int32_t *, NFSX_V3WRITEVERF);
- if (nfsver.tv_sec == 0)
- nfsver = boottime;
- *tl++ = txdr_unsigned(nfsver.tv_sec);
- *tl = txdr_unsigned(nfsver.tv_usec);
- } else {
- error = 0;
- }
-nfsmout:
- if (vp)
- vput(vp);
- vn_finished_write(mp);
- return(error);
-}
-
-/*
- * nfs statfs service
- */
-int
-nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct statfs *sf;
- struct nfs_statfs *sfp;
- caddr_t bpos;
- int error = 0, rdonly, getret = 1;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
- struct mbuf *mb, *mreq;
- struct vnode *vp = NULL;
- struct vattr at;
- nfsfh_t nfh;
- fhandle_t *fhp;
- struct statfs statfs;
- u_quad_t tval;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(NFSX_UNSIGNED);
- if (v3)
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- sf = &statfs;
- error = VFS_STATFS(vp->v_mount, sf);
- getret = VOP_GETATTR(vp, &at, cred);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3));
- if (v3)
- nfsm_srvpostop_attr(getret, &at);
- if (error) {
- error = 0;
- goto nfsmout;
- }
- sfp = nfsm_build(struct nfs_statfs *, NFSX_STATFS(v3));
- if (v3) {
- tval = (u_quad_t)sf->f_blocks;
- tval *= (u_quad_t)sf->f_bsize;
- txdr_hyper(tval, &sfp->sf_tbytes);
- tval = (u_quad_t)sf->f_bfree;
- tval *= (u_quad_t)sf->f_bsize;
- txdr_hyper(tval, &sfp->sf_fbytes);
- /*
- * Don't send negative values for available space,
- * since this field is unsigned in the NFS protocol.
- * Otherwise, the client would see absurdly high
- * numbers for free space.
- */
- if (sf->f_bavail < 0)
- tval = 0;
- else
- tval = (u_quad_t)sf->f_bavail;
- tval *= (u_quad_t)sf->f_bsize;
- txdr_hyper(tval, &sfp->sf_abytes);
- sfp->sf_tfiles.nfsuquad[0] = 0;
- sfp->sf_tfiles.nfsuquad[1] = txdr_unsigned(sf->f_files);
- sfp->sf_ffiles.nfsuquad[0] = 0;
- sfp->sf_ffiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
- sfp->sf_afiles.nfsuquad[0] = 0;
- sfp->sf_afiles.nfsuquad[1] = txdr_unsigned(sf->f_ffree);
- sfp->sf_invarsec = 0;
- } else {
- sfp->sf_tsize = txdr_unsigned(NFS_MAXDGRAMDATA);
- sfp->sf_bsize = txdr_unsigned(sf->f_bsize);
- sfp->sf_blocks = txdr_unsigned(sf->f_blocks);
- sfp->sf_bfree = txdr_unsigned(sf->f_bfree);
- if (sf->f_bavail < 0)
- sfp->sf_bavail = 0;
- else
- sfp->sf_bavail = txdr_unsigned(sf->f_bavail);
- }
-nfsmout:
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * nfs fsinfo service
- */
-int
-nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nfsv3_fsinfo *sip;
- caddr_t bpos;
- int error = 0, rdonly, getret = 1, pref;
- struct mbuf *mb, *mreq;
- struct vnode *vp = NULL;
- struct vattr at;
- nfsfh_t nfh;
- fhandle_t *fhp;
- u_quad_t maxfsize;
- struct statfs sb;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (!v3)
- panic("nfsrv_fsinfo: v3 proc called on a v2 connection");
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(NFSX_UNSIGNED);
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
-
- /* XXX Try to make a guess on the max file size. */
- VFS_STATFS(vp->v_mount, &sb);
- maxfsize = (u_quad_t)0x80000000 * sb.f_bsize - 1;
-
- getret = VOP_GETATTR(vp, &at, cred);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO);
- nfsm_srvpostop_attr(getret, &at);
- sip = nfsm_build(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
-
- /*
- * XXX
- * There should be filesystem VFS OP(s) to get this information.
- * For now, assume ufs.
- */
- pref = NFS_SRVMAXDATA(nfsd);
- sip->fs_rtmax = txdr_unsigned(pref);
- sip->fs_rtpref = txdr_unsigned(pref);
- sip->fs_rtmult = txdr_unsigned(NFS_FABLKSIZE);
- sip->fs_wtmax = txdr_unsigned(pref);
- sip->fs_wtpref = txdr_unsigned(pref);
- sip->fs_wtmult = txdr_unsigned(NFS_FABLKSIZE);
- sip->fs_dtpref = txdr_unsigned(pref);
- txdr_hyper(maxfsize, &sip->fs_maxfilesize);
- sip->fs_timedelta.nfsv3_sec = 0;
- sip->fs_timedelta.nfsv3_nsec = txdr_unsigned(1);
- sip->fs_properties = txdr_unsigned(NFSV3FSINFO_LINK |
- NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS |
- NFSV3FSINFO_CANSETTIME);
-nfsmout:
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * nfs pathconf service
- */
-int
-nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
- struct sockaddr *nam = nfsd->nd_nam;
- caddr_t dpos = nfsd->nd_dpos;
- struct ucred *cred = nfsd->nd_cr;
- struct nfsv3_pathconf *pc;
- caddr_t bpos;
- int error = 0, rdonly, getret = 1;
- register_t linkmax, namemax, chownres, notrunc;
- struct mbuf *mb, *mreq;
- struct vnode *vp = NULL;
- struct vattr at;
- nfsfh_t nfh;
- fhandle_t *fhp;
- int v3 = (nfsd->nd_flag & ND_NFSV3);
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (!v3)
- panic("nfsrv_pathconf: v3 proc called on a v2 connection");
- fhp = &nfh.fh_generic;
- nfsm_srvmtofh(fhp);
- error = nfsrv_fhtovp(fhp, 0, &vp, nfsd, slp, nam, &rdonly);
- if (error) {
- nfsm_reply(NFSX_UNSIGNED);
- nfsm_srvpostop_attr(getret, &at);
- error = 0;
- goto nfsmout;
- }
- error = VOP_PATHCONF(vp, _PC_LINK_MAX, &linkmax);
- if (!error)
- error = VOP_PATHCONF(vp, _PC_NAME_MAX, &namemax);
- if (!error)
- error = VOP_PATHCONF(vp, _PC_CHOWN_RESTRICTED, &chownres);
- if (!error)
- error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &notrunc);
- getret = VOP_GETATTR(vp, &at, cred);
- vput(vp);
- vp = NULL;
- nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF);
- nfsm_srvpostop_attr(getret, &at);
- if (error) {
- error = 0;
- goto nfsmout;
- }
- pc = nfsm_build(struct nfsv3_pathconf *, NFSX_V3PATHCONF);
-
- pc->pc_linkmax = txdr_unsigned(linkmax);
- pc->pc_namemax = txdr_unsigned(namemax);
- pc->pc_notrunc = txdr_unsigned(notrunc);
- pc->pc_chownrestricted = txdr_unsigned(chownres);
-
- /*
- * These should probably be supported by VOP_PATHCONF(), but
- * until msdosfs is exportable (why would you want to?), the
- * Unix defaults should be ok.
- */
- pc->pc_caseinsensitive = nfsrv_nfs_false;
- pc->pc_casepreserving = nfsrv_nfs_true;
-nfsmout:
- if (vp)
- vput(vp);
- return(error);
-}
-
-/*
- * Null operation, used by clients to ping server
- */
-/* ARGSUSED */
-int
-nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep;
- caddr_t bpos;
- int error = NFSERR_RETVOID;
- struct mbuf *mb, *mreq;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- nfsm_reply(0);
-nfsmout:
- return (error);
-}
-
-/*
- * No operation, used for obsolete procedures
- */
-/* ARGSUSED */
-int
-nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct mbuf **mrq)
-{
- struct mbuf *mrep = nfsd->nd_mrep;
- caddr_t bpos;
- int error;
- struct mbuf *mb, *mreq;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
- if (nfsd->nd_repstat)
- error = nfsd->nd_repstat;
- else
- error = EPROCUNAVAIL;
- nfsm_reply(0);
- error = 0;
-nfsmout:
- return (error);
-}
-
-/*
- * Perform access checking for vnodes obtained from file handles that would
- * refer to files already opened by a Unix client. You cannot just use
- * vn_writechk() and VOP_ACCESS() for two reasons.
- * 1 - You must check for exported rdonly as well as MNT_RDONLY for the write
- * case.
- * 2 - The owner is to be given access irrespective of mode bits for some
- * operations, so that processes that chmod after opening a file don't
- * break. I don't like this because it opens a security hole, but since
- * the nfs server opens a security hole the size of a barn door anyhow,
- * what the heck.
- *
- * The exception to rule 2 is EPERM. If a file is IMMUTABLE, VOP_ACCESS()
- * will return EPERM instead of EACCES. EPERM is always an error.
- */
-static int
-nfsrv_access(struct vnode *vp, accmode_t accmode, struct ucred *cred,
- int rdonly, int override)
-{
- struct vattr vattr;
- int error;
-
- nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
-
- if (accmode & VWRITE) {
- /* Just vn_writechk() changed to check rdonly */
- /*
- * Disallow write attempts on read-only filesystems;
- * unless the file is a socket or a block or character
- * device resident on the filesystem.
- */
- if (rdonly || (vp->v_mount->mnt_flag & MNT_RDONLY)) {
- switch (vp->v_type) {
- case VREG:
- case VDIR:
- case VLNK:
- return (EROFS);
- default:
- break;
- }
- }
- /*
- * If there's shared text associated with
- * the inode, we can't allow writing.
- */
- if (VOP_IS_TEXT(vp))
- return (ETXTBSY);
- }
-
- error = VOP_GETATTR(vp, &vattr, cred);
- if (error)
- return (error);
- error = VOP_ACCESS(vp, accmode, cred, curthread);
- /*
- * Allow certain operations for the owner (reads and writes
- * on files that are already open).
- */
- if (override && error == EACCES && cred->cr_uid == vattr.va_uid)
- error = 0;
- return (error);
-}
diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c
deleted file mode 100644
index 8bd045a..0000000
--- a/sys/nfsserver/nfs_srvkrpc.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_syscalls.c 8.5 (Berkeley) 3/30/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_inet6.h"
-#include "opt_kgssapi.h"
-
-#include <sys/param.h>
-#include <sys/capsicum.h>
-#include <sys/systm.h>
-#include <sys/sysproto.h>
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-#include <sys/file.h>
-#include <sys/filedesc.h>
-#include <sys/jail.h>
-#include <sys/vnode.h>
-#include <sys/malloc.h>
-#include <sys/mount.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/domain.h>
-#include <sys/protosw.h>
-#include <sys/namei.h>
-#include <sys/fcntl.h>
-#include <sys/lockf.h>
-#include <sys/eventhandler.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#ifdef INET6
-#include <net/if.h>
-#include <net/if_var.h> /* XXX: for in6_var.h */
-#include <netinet6/in6_var.h> /* XXX: for ip6_sprintf */
-#endif
-
-#include <rpc/rpc.h>
-#include <rpc/rpcsec_gss.h>
-#include <rpc/replay.h>
-
-#include <nfs/xdr_subs.h>
-#include <nfs/nfsproto.h>
-#include <nfs/nfs_fha.h>
-#include <nfsserver/nfs.h>
-#include <nfsserver/nfsm_subs.h>
-#include <nfsserver/nfsrvcache.h>
-#include <nfsserver/nfs_fha_old.h>
-
-#include <security/mac/mac_framework.h>
-
-static MALLOC_DEFINE(M_NFSSVC, "nfss_srvsock", "Nfs server structure");
-
-MALLOC_DEFINE(M_NFSRVDESC, "nfss_srvdesc", "NFS server socket descriptor");
-MALLOC_DEFINE(M_NFSD, "nfss_daemon", "Nfs server daemon structure");
-
-#define TRUE 1
-#define FALSE 0
-
-SYSCTL_DECL(_vfs_nfsrv);
-
-SVCPOOL *nfsrv_pool;
-int nfsd_waiting = 0;
-int nfsrv_numnfsd = 0;
-struct callout nfsrv_callout;
-static eventhandler_tag nfsrv_nmbclusters_tag;
-
-static int nfs_privport = 0;
-SYSCTL_INT(_vfs_nfsrv, NFS_NFSPRIVPORT, nfs_privport, CTLFLAG_RW,
- &nfs_privport, 0,
- "Only allow clients using a privileged port");
-SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay, CTLFLAG_RW,
- &nfsrvw_procrastinate, 0,
- "Delay value for write gathering");
-SYSCTL_INT(_vfs_nfsrv, OID_AUTO, gatherdelay_v3, CTLFLAG_RW,
- &nfsrvw_procrastinate_v3, 0,
- "Delay in seconds for NFSv3 write gathering");
-
-static int nfssvc_addsock(struct file *, struct thread *);
-static int nfssvc_nfsd(struct thread *, struct nfsd_nfsd_args *);
-
-extern u_long sb_max_adj;
-
-int32_t (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *nd,
- struct nfssvc_sock *slp, struct mbuf **mreqp) = {
- nfsrv_null,
- nfsrv_getattr,
- nfsrv_setattr,
- nfsrv_lookup,
- nfsrv3_access,
- nfsrv_readlink,
- nfsrv_read,
- nfsrv_write,
- nfsrv_create,
- nfsrv_mkdir,
- nfsrv_symlink,
- nfsrv_mknod,
- nfsrv_remove,
- nfsrv_rmdir,
- nfsrv_rename,
- nfsrv_link,
- nfsrv_readdir,
- nfsrv_readdirplus,
- nfsrv_statfs,
- nfsrv_fsinfo,
- nfsrv_pathconf,
- nfsrv_commit,
- nfsrv_noop
-};
-
-/*
- * NFS server system calls
- */
-/*
- * This is now called from nfssvc() in nfs/nfs_nfssvc.c.
- */
-
-/*
- * Nfs server psuedo system call for the nfsd's
- * Based on the flag value it either:
- * - adds a socket to the selection list
- * - remains in the kernel as an nfsd
- * - remains in the kernel as an nfsiod
- * For INET6 we suppose that nfsd provides only IN6P_IPV6_V6ONLY sockets
- * and that mountd provides
- * - sockaddr with no IPv4-mapped addresses
- * - mask for both INET and INET6 families if there is IPv4-mapped overlap
- */
-int
-nfssvc_nfsserver(struct thread *td, struct nfssvc_args *uap)
-{
- struct file *fp;
- struct nfsd_addsock_args addsockarg;
- struct nfsd_nfsd_args nfsdarg;
- cap_rights_t rights;
- int error;
-
- if (uap->flag & NFSSVC_ADDSOCK) {
- error = copyin(uap->argp, (caddr_t)&addsockarg,
- sizeof(addsockarg));
- if (error)
- return (error);
- error = fget(td, addsockarg.sock,
- cap_rights_init(&rights, CAP_SOCK_SERVER), &fp);
- if (error)
- return (error);
- if (fp->f_type != DTYPE_SOCKET) {
- fdrop(fp, td);
- return (error); /* XXXRW: Should be EINVAL? */
- }
- error = nfssvc_addsock(fp, td);
- fdrop(fp, td);
- } else if (uap->flag & NFSSVC_OLDNFSD)
- error = nfssvc_nfsd(td, NULL);
- else if (uap->flag & NFSSVC_NFSD) {
- if (!uap->argp)
- return (EINVAL);
- error = copyin(uap->argp, (caddr_t)&nfsdarg,
- sizeof(nfsdarg));
- if (error)
- return (error);
- error = nfssvc_nfsd(td, &nfsdarg);
- } else
- error = ENXIO;
- return (error);
-}
-
-/*
- * Generate the rpc reply header
- * siz arg. is used to decide if adding a cluster is worthwhile
- */
-struct mbuf *
-nfs_rephead(int siz, struct nfsrv_descript *nd, int err,
- struct mbuf **mbp, caddr_t *bposp)
-{
- u_int32_t *tl;
- struct mbuf *mreq;
- caddr_t bpos;
- struct mbuf *mb;
-
- if (err == EBADRPC)
- return (NULL);
-
- nd->nd_repstat = err;
- if (err && (nd->nd_flag & ND_NFSV3) == 0) /* XXX recheck */
- siz = 0;
-
- MGET(mreq, M_WAITOK, MT_DATA);
-
- /*
- * If this is a big reply, use a cluster
- */
- mreq->m_len = 0;
- if (siz >= MINCLSIZE) {
- MCLGET(mreq, M_WAITOK);
- }
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- if (err != NFSERR_RETVOID) {
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- if (err)
- *tl = txdr_unsigned(nfsrv_errmap(nd, err));
- else
- *tl = 0;
- }
-
- *mbp = mb;
- *bposp = bpos;
- if (err != 0 && err != NFSERR_RETVOID)
- nfsrvstats.srvrpc_errs++;
-
- return (mreq);
-}
-
-static void
-nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt)
-{
- rpcproc_t procnum;
- int32_t (*proc)(struct nfsrv_descript *nd, struct nfssvc_sock *slp,
- struct mbuf **mreqp);
- int flag;
- struct nfsrv_descript nd;
- struct mbuf *mreq, *mrep;
- int error;
-
- if (rqst->rq_vers == NFS_VER2) {
- if (rqst->rq_proc > NFSV2PROC_STATFS) {
- svcerr_noproc(rqst);
- svc_freereq(rqst);
- return;
- }
- procnum = nfsrv_nfsv3_procid[rqst->rq_proc];
- flag = 0;
- } else {
- if (rqst->rq_proc >= NFS_NPROCS) {
- svcerr_noproc(rqst);
- svc_freereq(rqst);
- return;
- }
- procnum = rqst->rq_proc;
- flag = ND_NFSV3;
- }
- proc = nfsrv3_procs[procnum];
-
- mreq = mrep = NULL;
- mreq = rqst->rq_args;
- rqst->rq_args = NULL;
- (void)nfs_realign(&mreq, M_WAITOK);
-
- /*
- * Note: we want rq_addr, not svc_getrpccaller for nd_nam2 -
- * NFS_SRVMAXDATA uses a NULL value for nd_nam2 to detect TCP
- * mounts.
- */
- memset(&nd, 0, sizeof(nd));
- nd.nd_md = nd.nd_mrep = mreq;
- nd.nd_dpos = mtod(mreq, caddr_t);
- nd.nd_nam = svc_getrpccaller(rqst);
- nd.nd_nam2 = rqst->rq_addr;
- nd.nd_procnum = procnum;
- nd.nd_cr = NULL;
- nd.nd_flag = flag;
-
- if (nfs_privport) {
- /* Check if source port is privileged */
- u_short port;
- struct sockaddr *nam = nd.nd_nam;
- struct sockaddr_in *sin;
-
- sin = (struct sockaddr_in *)nam;
- /*
- * INET/INET6 - same code:
- * sin_port and sin6_port are at same offset
- */
- port = ntohs(sin->sin_port);
- if (port >= IPPORT_RESERVED &&
- nd.nd_procnum != NFSPROC_NULL) {
-#ifdef INET6
- char b6[INET6_ADDRSTRLEN];
-#if defined(KLD_MODULE)
- /* Do not use ip6_sprintf: the nfs module should work without INET6. */
-#define ip6_sprintf(buf, a) \
- (sprintf((buf), "%x:%x:%x:%x:%x:%x:%x:%x", \
- (a)->s6_addr16[0], (a)->s6_addr16[1], \
- (a)->s6_addr16[2], (a)->s6_addr16[3], \
- (a)->s6_addr16[4], (a)->s6_addr16[5], \
- (a)->s6_addr16[6], (a)->s6_addr16[7]), \
- (buf))
-#endif
-#endif
- printf("NFS request from unprivileged port (%s:%d)\n",
-#ifdef INET6
- sin->sin_family == AF_INET6 ?
- ip6_sprintf(b6, &satosin6(sin)->sin6_addr) :
-#if defined(KLD_MODULE)
-#undef ip6_sprintf
-#endif
-#endif
- inet_ntoa(sin->sin_addr), port);
- m_freem(mreq);
- svcerr_weakauth(rqst);
- svc_freereq(rqst);
- return;
- }
- }
-
- if (proc != nfsrv_null) {
- if (!svc_getcred(rqst, &nd.nd_cr, &nd.nd_credflavor)) {
- m_freem(mreq);
- svcerr_weakauth(rqst);
- svc_freereq(rqst);
- return;
- }
-#ifdef MAC
- mac_cred_associate_nfsd(nd.nd_cr);
-#endif
- }
- nfsrvstats.srvrpccnt[nd.nd_procnum]++;
-
- error = proc(&nd, NULL, &mrep);
-
- if (nd.nd_cr)
- crfree(nd.nd_cr);
-
- if (mrep == NULL) {
- svcerr_decode(rqst);
- svc_freereq(rqst);
- return;
- }
- if (error && error != NFSERR_RETVOID) {
- svcerr_systemerr(rqst);
- svc_freereq(rqst);
- return;
- }
- if (nd.nd_repstat & NFSERR_AUTHERR) {
- svcerr_auth(rqst, nd.nd_repstat & ~NFSERR_AUTHERR);
- m_freem(mrep);
- } else {
- if (!svc_sendreply_mbuf(rqst, mrep))
- svcerr_systemerr(rqst);
- }
- svc_freereq(rqst);
-}
-
-/*
- * Adds a socket to the list for servicing by nfsds.
- */
-static int
-nfssvc_addsock(struct file *fp, struct thread *td)
-{
- int siz;
- struct socket *so;
- int error;
- SVCXPRT *xprt;
-
- so = fp->f_data;
-
- siz = sb_max_adj;
- error = soreserve(so, siz, siz);
- if (error)
- return (error);
-
- /*
- * Steal the socket from userland so that it doesn't close
- * unexpectedly.
- */
- if (so->so_type == SOCK_DGRAM)
- xprt = svc_dg_create(nfsrv_pool, so, 0, 0);
- else
- xprt = svc_vc_create(nfsrv_pool, so, 0, 0);
- if (xprt) {
- fp->f_ops = &badfileops;
- fp->f_data = NULL;
- svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, NULL);
- svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, NULL);
- SVC_RELEASE(xprt);
- }
-
- return (0);
-}
-
-/*
- * Called by nfssvc() for nfsds. Just loops around servicing rpc requests
- * until it is killed by a signal.
- */
-static int
-nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args)
-{
- char principal[128];
- int error;
-
- if (args) {
- error = copyinstr(args->principal, principal,
- sizeof(principal), NULL);
- if (error)
- return (error);
- } else {
- memcpy(principal, "nfs@", 4);
- getcredhostname(td->td_ucred, principal + 4,
- sizeof(principal) - 4);
- }
-
- /*
- * Only the first nfsd actually does any work. The RPC code
- * adds threads to it as needed. Any extra processes offered
- * by nfsd just exit. If nfsd is new enough, it will call us
- * once with a structure that specifies how many threads to
- * use.
- */
- NFSD_LOCK();
- if (nfsrv_numnfsd == 0) {
- nfsrv_numnfsd++;
-
- NFSD_UNLOCK();
-
- rpc_gss_set_svc_name_call(principal, "kerberosv5",
- GSS_C_INDEFINITE, NFS_PROG, NFS_VER2);
- rpc_gss_set_svc_name_call(principal, "kerberosv5",
- GSS_C_INDEFINITE, NFS_PROG, NFS_VER3);
-
- if (args) {
- nfsrv_pool->sp_minthreads = args->minthreads;
- nfsrv_pool->sp_maxthreads = args->maxthreads;
- } else {
- nfsrv_pool->sp_minthreads = 4;
- nfsrv_pool->sp_maxthreads = 4;
- }
-
- svc_run(nfsrv_pool);
-
- rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER2);
- rpc_gss_clear_svc_name_call(NFS_PROG, NFS_VER3);
-
- NFSD_LOCK();
- nfsrv_numnfsd--;
- nfsrv_init(TRUE);
- }
- NFSD_UNLOCK();
-
- return (0);
-}
-
-/*
- * Size the NFS server's duplicate request cache at 1/2 the
- * nmbclusters, floating within a (64, 2048) range. This is to
- * prevent all mbuf clusters being tied up in the NFS dupreq
- * cache for small values of nmbclusters.
- */
-static size_t
-nfsrv_replay_size(void)
-{
- size_t replaysiz;
-
- replaysiz = nmbclusters / 2;
- if (replaysiz > NFSRVCACHE_MAX_SIZE)
- replaysiz = NFSRVCACHE_MAX_SIZE;
- if (replaysiz < NFSRVCACHE_MIN_SIZE)
- replaysiz = NFSRVCACHE_MIN_SIZE;
- replaysiz *= MCLBYTES;
-
- return (replaysiz);
-}
-
-/*
- * Called when nmbclusters changes - we resize the replay cache
- * accordingly.
- */
-static void
-nfsrv_nmbclusters_change(void *tag)
-{
-
- if (nfsrv_pool)
- replay_setsize(nfsrv_pool->sp_rcache, nfsrv_replay_size());
-}
-
-/*
- * Initialize the data structures for the server.
- * Handshake with any new nfsds starting up to avoid any chance of
- * corruption.
- */
-void
-nfsrv_init(int terminating)
-{
-
- NFSD_LOCK_ASSERT();
-
- if (terminating) {
- NFSD_UNLOCK();
- EVENTHANDLER_DEREGISTER(nmbclusters_change,
- nfsrv_nmbclusters_tag);
- svcpool_destroy(nfsrv_pool);
- nfsrv_pool = NULL;
- NFSD_LOCK();
- } else
- nfs_pub.np_valid = 0;
-
- NFSD_UNLOCK();
-
- nfsrv_pool = svcpool_create("nfsd", SYSCTL_STATIC_CHILDREN(_vfs_nfsrv));
- nfsrv_pool->sp_rcache = replay_newcache(nfsrv_replay_size());
- nfsrv_pool->sp_assign = fhaold_assign;
- nfsrv_pool->sp_done = fha_nd_complete;
- nfsrv_nmbclusters_tag = EVENTHANDLER_REGISTER(nmbclusters_change,
- nfsrv_nmbclusters_change, NULL, EVENTHANDLER_PRI_FIRST);
-
- NFSD_LOCK();
-}
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
deleted file mode 100644
index 04371da..0000000
--- a/sys/nfsserver/nfs_srvsubs.c
+++ /dev/null
@@ -1,1418 +0,0 @@
-/*-
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * 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.
- * 4. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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.
- *
- * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * These functions support the macros and help fiddle mbuf chains for
- * the nfs op functions. They do things like create the rpc header and
- * copy data between mbuf chains and uio lists.
- */
-
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/mbuf.h>
-#include <sys/refcount.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/sysent.h>
-#include <sys/syscall.h>
-#include <sys/sysproto.h>
-
-#include <vm/vm.h>
-#include <vm/vm_object.h>
-#include <vm/vm_extern.h>
-#include <vm/uma.h>
-
-#include <rpc/rpc.h>
-
-#include <nfs/nfsproto.h>
-#include <nfsserver/nfs.h>
-#include <nfs/xdr_subs.h>
-#include <nfsserver/nfsm_subs.h>
-
-#include <netinet/in.h>
-
-/*
- * Data items converted to xdr at startup, since they are constant
- * This is kinda hokey, but may save a little time doing byte swaps
- */
-u_int32_t nfsrv_nfs_xdrneg1;
-u_int32_t nfsrv_nfs_true, nfsrv_nfs_false;
-
-/* And other global data */
-static const nfstype nfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR,
- NFLNK, NFNON, NFCHR, NFNON };
-#define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))])
-#define vtonfsv3_mode(m) txdr_unsigned((m) & ALLPERMS)
-
-int nfsrv_ticks;
-
-struct mtx nfsd_mtx;
-
-/*
- * Mapping of old NFS Version 2 RPC numbers to generic numbers.
- */
-const int nfsrv_nfsv3_procid[NFS_NPROCS] = {
- NFSPROC_NULL,
- NFSPROC_GETATTR,
- NFSPROC_SETATTR,
- NFSPROC_NOOP,
- NFSPROC_LOOKUP,
- NFSPROC_READLINK,
- NFSPROC_READ,
- NFSPROC_NOOP,
- NFSPROC_WRITE,
- NFSPROC_CREATE,
- NFSPROC_REMOVE,
- NFSPROC_RENAME,
- NFSPROC_LINK,
- NFSPROC_SYMLINK,
- NFSPROC_MKDIR,
- NFSPROC_RMDIR,
- NFSPROC_READDIR,
- NFSPROC_FSSTAT,
- NFSPROC_NOOP,
- NFSPROC_NOOP,
- NFSPROC_NOOP,
- NFSPROC_NOOP,
- NFSPROC_NOOP,
-};
-
-/*
- * and the reverse mapping from generic to Version 2 procedure numbers
- */
-const int nfsrvv2_procid[NFS_NPROCS] = {
- NFSV2PROC_NULL,
- NFSV2PROC_GETATTR,
- NFSV2PROC_SETATTR,
- NFSV2PROC_LOOKUP,
- NFSV2PROC_NOOP,
- NFSV2PROC_READLINK,
- NFSV2PROC_READ,
- NFSV2PROC_WRITE,
- NFSV2PROC_CREATE,
- NFSV2PROC_MKDIR,
- NFSV2PROC_SYMLINK,
- NFSV2PROC_CREATE,
- NFSV2PROC_REMOVE,
- NFSV2PROC_RMDIR,
- NFSV2PROC_RENAME,
- NFSV2PROC_LINK,
- NFSV2PROC_READDIR,
- NFSV2PROC_NOOP,
- NFSV2PROC_STATFS,
- NFSV2PROC_NOOP,
- NFSV2PROC_NOOP,
- NFSV2PROC_NOOP,
- NFSV2PROC_NOOP,
-};
-
-/*
- * Maps errno values to nfs error numbers.
- * Use 0 (which gets converted to NFSERR_IO) as the catch all for ones not
- * specifically defined in RFC 1094.
- */
-static const u_char nfsrv_v2errmap[ELAST] = {
- NFSERR_PERM, NFSERR_NOENT, 0, 0, 0,
- NFSERR_NXIO, 0, 0, 0, 0,
- 0, 0, NFSERR_ACCES, 0, 0,
- 0, NFSERR_EXIST, 0, NFSERR_NODEV, NFSERR_NOTDIR,
- NFSERR_ISDIR, 0, 0, 0, 0,
- 0, NFSERR_FBIG, NFSERR_NOSPC, 0, NFSERR_ROFS,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- 0, 0, NFSERR_NAMETOL, 0, 0,
- NFSERR_NOTEMPTY, 0, 0, NFSERR_DQUOT, NFSERR_STALE,
- 0
-};
-
-/*
- * Maps errno values to nfs error numbers.
- * Although it is not obvious whether or not NFS clients really care if
- * a returned error value is in the specified list for the procedure, the
- * safest thing to do is filter them appropriately. For Version 2, the
- * X/Open XNFS document is the only specification that defines error values
- * for each RPC (The RFC simply lists all possible error values for all RPCs),
- * so I have decided to not do this for Version 2.
- * The first entry is the default error return and the rest are the valid
- * errors for that RPC in increasing numeric order.
- */
-static const short nfsv3err_null[] = {
- 0,
- 0,
-};
-
-static const short nfsv3err_getattr[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_setattr[] = {
- NFSERR_IO,
- NFSERR_PERM,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_INVAL,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOT_SYNC,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_lookup[] = {
- NFSERR_IO,
- NFSERR_NOENT,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_NOTDIR,
- NFSERR_NAMETOL,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_access[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_readlink[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_INVAL,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_read[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_NXIO,
- NFSERR_ACCES,
- NFSERR_INVAL,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_write[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_INVAL,
- NFSERR_FBIG,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_create[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_NOTDIR,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_NAMETOL,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_mkdir[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_NOTDIR,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_NAMETOL,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_symlink[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_NOTDIR,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_NAMETOL,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_mknod[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_NOTDIR,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_NAMETOL,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- NFSERR_BADTYPE,
- 0,
-};
-
-static const short nfsv3err_remove[] = {
- NFSERR_IO,
- NFSERR_NOENT,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_NOTDIR,
- NFSERR_ROFS,
- NFSERR_NAMETOL,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_rmdir[] = {
- NFSERR_IO,
- NFSERR_NOENT,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_NOTDIR,
- NFSERR_INVAL,
- NFSERR_ROFS,
- NFSERR_NAMETOL,
- NFSERR_NOTEMPTY,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_rename[] = {
- NFSERR_IO,
- NFSERR_NOENT,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_XDEV,
- NFSERR_NOTDIR,
- NFSERR_ISDIR,
- NFSERR_INVAL,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_MLINK,
- NFSERR_NAMETOL,
- NFSERR_NOTEMPTY,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_link[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_EXIST,
- NFSERR_XDEV,
- NFSERR_NOTDIR,
- NFSERR_INVAL,
- NFSERR_NOSPC,
- NFSERR_ROFS,
- NFSERR_MLINK,
- NFSERR_NAMETOL,
- NFSERR_DQUOT,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_NOTSUPP,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_readdir[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_NOTDIR,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_BAD_COOKIE,
- NFSERR_TOOSMALL,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_readdirplus[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_ACCES,
- NFSERR_NOTDIR,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_BAD_COOKIE,
- NFSERR_NOTSUPP,
- NFSERR_TOOSMALL,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_fsstat[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_fsinfo[] = {
- NFSERR_STALE,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_pathconf[] = {
- NFSERR_STALE,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short nfsv3err_commit[] = {
- NFSERR_IO,
- NFSERR_IO,
- NFSERR_STALE,
- NFSERR_BADHANDLE,
- NFSERR_SERVERFAULT,
- 0,
-};
-
-static const short *nfsrv_v3errmap[] = {
- nfsv3err_null,
- nfsv3err_getattr,
- nfsv3err_setattr,
- nfsv3err_lookup,
- nfsv3err_access,
- nfsv3err_readlink,
- nfsv3err_read,
- nfsv3err_write,
- nfsv3err_create,
- nfsv3err_mkdir,
- nfsv3err_symlink,
- nfsv3err_mknod,
- nfsv3err_remove,
- nfsv3err_rmdir,
- nfsv3err_rename,
- nfsv3err_link,
- nfsv3err_readdir,
- nfsv3err_readdirplus,
- nfsv3err_fsstat,
- nfsv3err_fsinfo,
- nfsv3err_pathconf,
- nfsv3err_commit,
-};
-
-extern int (*nfsd_call_nfsserver)(struct thread *, struct nfssvc_args *);
-
-/*
- * Called once to initialize data structures...
- */
-static int
-nfsrv_modevent(module_t mod, int type, void *data)
-{
- int error = 0;
-
- switch (type) {
- case MOD_LOAD:
- mtx_init(&nfsd_mtx, "nfsd_mtx", NULL, MTX_DEF);
- nfsrv_nfs_true = txdr_unsigned(TRUE);
- nfsrv_nfs_false = txdr_unsigned(FALSE);
- nfsrv_nfs_xdrneg1 = txdr_unsigned(-1);
- nfsrv_ticks = (hz * NFS_TICKINTVL + 500) / 1000;
- if (nfsrv_ticks < 1)
- nfsrv_ticks = 1;
-
- NFSD_LOCK();
- nfsrv_init(0); /* Init server data structures */
- NFSD_UNLOCK();
-
- nfsd_call_nfsserver = nfssvc_nfsserver;
- break;
-
- case MOD_UNLOAD:
- if (nfsrv_numnfsd != 0) {
- error = EBUSY;
- break;
- }
-
- nfsd_call_nfsserver = NULL;
- callout_drain(&nfsrv_callout);
- mtx_destroy(&nfsd_mtx);
- break;
- default:
- error = EOPNOTSUPP;
- break;
- }
- return error;
-}
-static moduledata_t nfsserver_mod = {
- "nfsserver",
- nfsrv_modevent,
- NULL,
-};
-DECLARE_MODULE(nfsserver, nfsserver_mod, SI_SUB_VFS, SI_ORDER_ANY);
-
-/* So that loader and kldload(2) can find us, wherever we are.. */
-MODULE_VERSION(nfsserver, 1);
-MODULE_DEPEND(nfsserver, nfssvc, 1, 1, 1);
-MODULE_DEPEND(nfsserver, krpc, 1, 1, 1);
-MODULE_DEPEND(nfsserver, nfs_common, 1, 1, 1);
-
-/*
- * Set up nameidata for a lookup() call and do it.
- *
- * If pubflag is set, this call is done for a lookup operation on the
- * public filehandle. In that case we allow crossing mountpoints and
- * absolute pathnames. However, the caller is expected to check that
- * the lookup result is within the public fs, and deny access if
- * it is not.
- *
- * nfs_namei() clears out garbage fields that namei() might leave garbage.
- * This is mainly ni_vp and ni_dvp when an error occurs, and ni_dvp when no
- * error occurs but the parent was not requested.
- *
- * dirp may be set whether an error is returned or not, and must be
- * released by the caller.
- */
-int
-nfs_namei(struct nameidata *ndp, struct nfsrv_descript *nfsd,
- fhandle_t *fhp, int len, struct nfssvc_sock *slp,
- struct sockaddr *nam, struct mbuf **mdp,
- caddr_t *dposp, struct vnode **retdirp, int v3, struct vattr *retdirattrp,
- int *retdirattr_retp, int pubflag)
-{
- int i, rem;
- struct mbuf *md;
- char *fromcp, *tocp, *cp;
- struct iovec aiov;
- struct uio auio;
- struct vnode *dp;
- int error, rdonly, linklen;
- struct componentname *cnp = &ndp->ni_cnd;
- int lockleaf = (cnp->cn_flags & LOCKLEAF) != 0;
-
- *retdirp = NULL;
- cnp->cn_flags |= NOMACCHECK;
- cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
-
- /*
- * Copy the name from the mbuf list to ndp->ni_pnbuf
- * and set the various ndp fields appropriately.
- */
- fromcp = *dposp;
- tocp = cnp->cn_pnbuf;
- md = *mdp;
- rem = mtod(md, caddr_t) + md->m_len - fromcp;
- for (i = 0; i < len; i++) {
- while (rem == 0) {
- md = md->m_next;
- if (md == NULL) {
- error = EBADRPC;
- goto out;
- }
- fromcp = mtod(md, caddr_t);
- rem = md->m_len;
- }
- if (*fromcp == '\0' || (!pubflag && *fromcp == '/')) {
- error = EACCES;
- goto out;
- }
- *tocp++ = *fromcp++;
- rem--;
- }
- *tocp = '\0';
- *mdp = md;
- *dposp = fromcp;
- len = nfsm_rndup(len)-len;
- if (len > 0) {
- if (rem >= len)
- *dposp += len;
- else if ((error = nfs_adv(mdp, dposp, len, rem)) != 0)
- goto out;
- }
-
- if (!pubflag && nfs_ispublicfh(fhp))
- return (ESTALE);
-
- /*
- * Extract and set starting directory.
- */
- error = nfsrv_fhtovp(fhp, 0, &dp, nfsd, slp, nam, &rdonly);
- if (error)
- goto out;
- if (dp->v_type != VDIR) {
- vput(dp);
- error = ENOTDIR;
- goto out;
- }
-
- if (rdonly)
- cnp->cn_flags |= RDONLY;
-
- /*
- * Set return directory. Reference to dp is implicitly transfered
- * to the returned pointer
- */
- *retdirp = dp;
- if (v3) {
- *retdirattr_retp = VOP_GETATTR(dp, retdirattrp,
- ndp->ni_cnd.cn_cred);
- }
-
- VOP_UNLOCK(dp, 0);
-
- if (pubflag) {
- /*
- * Oh joy. For WebNFS, handle those pesky '%' escapes,
- * and the 'native path' indicator.
- */
- cp = uma_zalloc(namei_zone, M_WAITOK);
- fromcp = cnp->cn_pnbuf;
- tocp = cp;
- if ((unsigned char)*fromcp >= WEBNFS_SPECCHAR_START) {
- switch ((unsigned char)*fromcp) {
- case WEBNFS_NATIVE_CHAR:
- /*
- * 'Native' path for us is the same
- * as a path according to the NFS spec,
- * just skip the escape char.
- */
- fromcp++;
- break;
- /*
- * More may be added in the future, range 0x80-0xff
- */
- default:
- error = EIO;
- uma_zfree(namei_zone, cp);
- goto out;
- }
- }
- /*
- * Translate the '%' escapes, URL-style.
- */
- while (*fromcp != '\0') {
- if (*fromcp == WEBNFS_ESC_CHAR) {
- if (fromcp[1] != '\0' && fromcp[2] != '\0') {
- fromcp++;
- *tocp++ = HEXSTRTOI(fromcp);
- fromcp += 2;
- continue;
- } else {
- error = ENOENT;
- uma_zfree(namei_zone, cp);
- goto out;
- }
- } else
- *tocp++ = *fromcp++;
- }
- *tocp = '\0';
- uma_zfree(namei_zone, cnp->cn_pnbuf);
- cnp->cn_pnbuf = cp;
- }
-
- ndp->ni_pathlen = (tocp - cnp->cn_pnbuf) + 1;
- ndp->ni_segflg = UIO_SYSSPACE;
-
- if (pubflag) {
- ndp->ni_rootdir = rootvnode;
- ndp->ni_loopcnt = 0;
-
- if (cnp->cn_pnbuf[0] == '/')
- dp = rootvnode;
- } else {
- cnp->cn_flags |= NOCROSSMOUNT;
- }
-
- /*
- * Initialize for scan, set ni_startdir and bump ref on dp again
- * because lookup() will dereference ni_startdir.
- */
-
- cnp->cn_thread = curthread;
- VREF(dp);
- ndp->ni_startdir = dp;
-
- if (!lockleaf)
- cnp->cn_flags |= LOCKLEAF;
- for (;;) {
- cnp->cn_nameptr = cnp->cn_pnbuf;
- /*
- * Call lookup() to do the real work. If an error occurs,
- * ndp->ni_vp and ni_dvp are left uninitialized or NULL and
- * we do not have to dereference anything before returning.
- * In either case ni_startdir will be dereferenced and NULLed
- * out.
- */
- error = lookup(ndp);
- if (error)
- break;
-
- /*
- * Check for encountering a symbolic link. Trivial
- * termination occurs if no symlink encountered.
- * Note: zfree is safe because error is 0, so we will
- * not zfree it again when we break.
- */
- if ((cnp->cn_flags & ISSYMLINK) == 0) {
- if (cnp->cn_flags & (SAVENAME | SAVESTART))
- cnp->cn_flags |= HASBUF;
- else
- uma_zfree(namei_zone, cnp->cn_pnbuf);
- if (ndp->ni_vp && !lockleaf)
- VOP_UNLOCK(ndp->ni_vp, 0);
- break;
- }
-
- /*
- * Validate symlink
- */
- if ((cnp->cn_flags & LOCKPARENT) && ndp->ni_pathlen == 1)
- VOP_UNLOCK(ndp->ni_dvp, 0);
- if (!pubflag) {
- error = EINVAL;
- goto badlink2;
- }
-
- if (ndp->ni_loopcnt++ >= MAXSYMLINKS) {
- error = ELOOP;
- goto badlink2;
- }
- if (ndp->ni_pathlen > 1)
- cp = uma_zalloc(namei_zone, M_WAITOK);
- else
- cp = cnp->cn_pnbuf;
- aiov.iov_base = cp;
- aiov.iov_len = MAXPATHLEN;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_offset = 0;
- auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_td = NULL;
- auio.uio_resid = MAXPATHLEN;
- error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred);
- if (error) {
- badlink1:
- if (ndp->ni_pathlen > 1)
- uma_zfree(namei_zone, cp);
- badlink2:
- vput(ndp->ni_vp);
- vrele(ndp->ni_dvp);
- break;
- }
- linklen = MAXPATHLEN - auio.uio_resid;
- if (linklen == 0) {
- error = ENOENT;
- goto badlink1;
- }
- if (linklen + ndp->ni_pathlen >= MAXPATHLEN) {
- error = ENAMETOOLONG;
- goto badlink1;
- }
-
- /*
- * Adjust or replace path
- */
- if (ndp->ni_pathlen > 1) {
- bcopy(ndp->ni_next, cp + linklen, ndp->ni_pathlen);
- uma_zfree(namei_zone, cnp->cn_pnbuf);
- cnp->cn_pnbuf = cp;
- } else
- cnp->cn_pnbuf[linklen] = '\0';
- ndp->ni_pathlen += linklen;
-
- /*
- * Cleanup refs for next loop and check if root directory
- * should replace current directory. Normally ni_dvp
- * becomes the new base directory and is cleaned up when
- * we loop. Explicitly null pointers after invalidation
- * to clarify operation.
- */
- vput(ndp->ni_vp);
- ndp->ni_vp = NULL;
-
- if (cnp->cn_pnbuf[0] == '/') {
- vrele(ndp->ni_dvp);
- ndp->ni_dvp = ndp->ni_rootdir;
- VREF(ndp->ni_dvp);
- }
- ndp->ni_startdir = ndp->ni_dvp;
- ndp->ni_dvp = NULL;
- }
- if (!lockleaf)
- cnp->cn_flags &= ~LOCKLEAF;
-
- /*
- * nfs_namei() guarentees that fields will not contain garbage
- * whether an error occurs or not. This allows the caller to track
- * cleanup state trivially.
- */
-out:
- if (error) {
- uma_zfree(namei_zone, cnp->cn_pnbuf);
- ndp->ni_vp = NULL;
- ndp->ni_dvp = NULL;
- ndp->ni_startdir = NULL;
- cnp->cn_flags &= ~HASBUF;
- } else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) {
- ndp->ni_dvp = NULL;
- }
- return (error);
-}
-
-/*
- * A fiddled version of m_adj() that ensures null fill to a long
- * boundary and only trims off the back end
- */
-void
-nfsm_adj(struct mbuf *mp, int len, int nul)
-{
- struct mbuf *m;
- int count, i;
- char *cp;
-
- /*
- * Trim from tail. Scan the mbuf chain,
- * calculating its length and finding the last mbuf.
- * If the adjustment only affects this mbuf, then just
- * adjust and return. Otherwise, rescan and truncate
- * after the remaining size.
- */
- count = 0;
- m = mp;
- for (;;) {
- count += m->m_len;
- if (m->m_next == NULL)
- break;
- m = m->m_next;
- }
- if (m->m_len > len) {
- m->m_len -= len;
- if (nul > 0) {
- cp = mtod(m, caddr_t)+m->m_len-nul;
- for (i = 0; i < nul; i++)
- *cp++ = '\0';
- }
- return;
- }
- count -= len;
- if (count < 0)
- count = 0;
- /*
- * Correct length for chain is "count".
- * Find the mbuf with last data, adjust its length,
- * and toss data from remaining mbufs on chain.
- */
- for (m = mp; m; m = m->m_next) {
- if (m->m_len >= count) {
- m->m_len = count;
- if (nul > 0) {
- cp = mtod(m, caddr_t)+m->m_len-nul;
- for (i = 0; i < nul; i++)
- *cp++ = '\0';
- }
- if (m->m_next != NULL) {
- m_freem(m->m_next);
- m->m_next = NULL;
- }
- break;
- }
- count -= m->m_len;
- }
-}
-
-/*
- * Make these functions instead of macros, so that the kernel text size
- * doesn't get too big...
- */
-void
-nfsm_srvwcc(struct nfsrv_descript *nfsd, int before_ret,
- struct vattr *before_vap, int after_ret, struct vattr *after_vap,
- struct mbuf **mbp, char **bposp)
-{
- struct mbuf *mb = *mbp;
- char *bpos = *bposp;
- u_int32_t *tl;
-
- if (before_ret) {
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = nfsrv_nfs_false;
- } else {
- tl = nfsm_build(u_int32_t *, 7 * NFSX_UNSIGNED);
- *tl++ = nfsrv_nfs_true;
- txdr_hyper(before_vap->va_size, tl);
- tl += 2;
- txdr_nfsv3time(&(before_vap->va_mtime), tl);
- tl += 2;
- txdr_nfsv3time(&(before_vap->va_ctime), tl);
- }
- *bposp = bpos;
- *mbp = mb;
- nfsm_srvpostopattr(nfsd, after_ret, after_vap, mbp, bposp);
-}
-
-void
-nfsm_srvpostopattr(struct nfsrv_descript *nfsd, int after_ret,
- struct vattr *after_vap, struct mbuf **mbp, char **bposp)
-{
- struct mbuf *mb = *mbp;
- char *bpos = *bposp;
- u_int32_t *tl;
- struct nfs_fattr *fp;
-
- if (after_ret) {
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = nfsrv_nfs_false;
- } else {
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED + NFSX_V3FATTR);
- *tl++ = nfsrv_nfs_true;
- fp = (struct nfs_fattr *)tl;
- nfsm_srvfattr(nfsd, after_vap, fp);
- }
- *mbp = mb;
- *bposp = bpos;
-}
-
-void
-nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap,
- struct nfs_fattr *fp)
-{
-
- fp->fa_nlink = txdr_unsigned(vap->va_nlink);
- fp->fa_uid = txdr_unsigned(vap->va_uid);
- fp->fa_gid = txdr_unsigned(vap->va_gid);
- if (nfsd->nd_flag & ND_NFSV3) {
- fp->fa_type = vtonfsv3_type(vap->va_type);
- fp->fa_mode = vtonfsv3_mode(vap->va_mode);
- txdr_hyper(vap->va_size, &fp->fa3_size);
- txdr_hyper(vap->va_bytes, &fp->fa3_used);
- fp->fa3_rdev.specdata1 = txdr_unsigned(major(vap->va_rdev));
- fp->fa3_rdev.specdata2 = txdr_unsigned(minor(vap->va_rdev));
- fp->fa3_fsid.nfsuquad[0] = 0;
- fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(vap->va_fsid);
- fp->fa3_fileid.nfsuquad[0] = 0;
- fp->fa3_fileid.nfsuquad[1] = txdr_unsigned(vap->va_fileid);
- txdr_nfsv3time(&vap->va_atime, &fp->fa3_atime);
- txdr_nfsv3time(&vap->va_mtime, &fp->fa3_mtime);
- txdr_nfsv3time(&vap->va_ctime, &fp->fa3_ctime);
- } else {
- fp->fa_type = vtonfsv2_type(vap->va_type);
- fp->fa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
- fp->fa2_size = txdr_unsigned(vap->va_size);
- fp->fa2_blocksize = txdr_unsigned(vap->va_blocksize);
- if (vap->va_type == VFIFO)
- fp->fa2_rdev = 0xffffffff;
- else
- fp->fa2_rdev = txdr_unsigned(vap->va_rdev);
- fp->fa2_blocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE);
- fp->fa2_fsid = txdr_unsigned(vap->va_fsid);
- fp->fa2_fileid = txdr_unsigned(vap->va_fileid);
- txdr_nfsv2time(&vap->va_atime, &fp->fa2_atime);
- txdr_nfsv2time(&vap->va_mtime, &fp->fa2_mtime);
- txdr_nfsv2time(&vap->va_ctime, &fp->fa2_ctime);
- }
-}
-
-/*
- * nfsrv_fhtovp() - convert a fh to a vnode ptr (optionally locked)
- * - look up fsid in mount list (if not found ret error)
- * - get vp and export rights by calling VFS_FHTOVP()
- * - if cred->cr_uid == 0 or MNT_EXPORTANON set it to credanon
- */
-int
-nfsrv_fhtovp(fhandle_t *fhp, int flags, struct vnode **vpp,
- struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
- struct sockaddr *nam, int *rdonlyp)
-{
- struct mount *mp;
- int i;
- struct ucred *cred, *credanon;
- int error, exflags;
-#ifdef MNT_EXNORESPORT /* XXX needs mountd and /etc/exports help yet */
- struct sockaddr_int *saddr;
-#endif
- int credflavor;
- int numsecflavors, *secflavors;
- int authsys;
- int v3 = nfsd->nd_flag & ND_NFSV3;
- int mountreq;
-
- *vpp = NULL;
-
- if (nfs_ispublicfh(fhp)) {
- if (!nfs_pub.np_valid)
- return (ESTALE);
- fhp = &nfs_pub.np_handle;
- }
-
- mp = vfs_busyfs(&fhp->fh_fsid);
- if (!mp)
- return (ESTALE);
- error = VFS_CHECKEXP(mp, nam, &exflags, &credanon,
- &numsecflavors, &secflavors);
- if (error) {
- vfs_unbusy(mp);
- goto out;
- }
- if (numsecflavors == 0) {
- /*
- * This can happen if the system is running with an
- * old mountd that doesn't pass in a secflavor list.
- */
- numsecflavors = 1;
- authsys = AUTH_SYS;
- secflavors = &authsys;
- }
- credflavor = nfsd->nd_credflavor;
- for (i = 0; i < numsecflavors; i++) {
- if (secflavors[i] == credflavor)
- break;
- }
- if (i == numsecflavors) {
- /*
- * RFC 2623 section 2.3.2 - allow certain procedures
- * used at NFS client mount time even if they have
- * weak authentication.
- */
- mountreq = FALSE;
- if (v3) {
- if (nfsd->nd_procnum == NFSPROC_FSINFO
- || nfsd->nd_procnum == NFSPROC_GETATTR)
- mountreq = TRUE;
- } else {
- if (nfsd->nd_procnum == NFSPROC_FSSTAT
- || nfsd->nd_procnum == NFSPROC_GETATTR)
- mountreq = TRUE;
- }
- if (!mountreq) {
- error = NFSERR_AUTHERR | AUTH_TOOWEAK;
- vfs_unbusy(mp);
- goto out;
- }
- }
- error = VFS_FHTOVP(mp, &fhp->fh_fid, LK_EXCLUSIVE, vpp);
- if (error) {
- /* Make sure the server replies ESTALE to the client. */
- error = ESTALE;
- vfs_unbusy(mp);
- goto out;
- }
-#ifdef MNT_EXNORESPORT
- if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) {
- saddr = (struct sockaddr_in *)nam;
- if ((saddr->sin_family == AF_INET ||
- saddr->sin_family == AF_INET6) &&
- /* same code for INET and INET6: sin*_port at same offet */
- ntohs(saddr->sin_port) >= IPPORT_RESERVED) {
- vput(*vpp);
- *vpp = NULL;
- error = NFSERR_AUTHERR | AUTH_TOOWEAK;
- vfs_unbusy(mp);
- goto out;
- }
- }
-#endif
- /*
- * Check/setup credentials.
- */
- cred = nfsd->nd_cr;
- if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) {
- cred->cr_uid = credanon->cr_uid;
- crsetgroups(cred, credanon->cr_ngroups, credanon->cr_groups);
- }
- if (exflags & MNT_EXRDONLY)
- *rdonlyp = 1;
- else
- *rdonlyp = 0;
-
- if (!(flags & NFSRV_FLAG_BUSY))
- vfs_unbusy(mp);
-out:
- if (credanon != NULL)
- crfree(credanon);
-
- return (error);
-}
-
-
-/*
- * WebNFS: check if a filehandle is a public filehandle. For v3, this
- * means a length of 0, for v2 it means all zeroes. nfsm_srvmtofh has
- * transformed this to all zeroes in both cases, so check for it.
- */
-int
-nfs_ispublicfh(fhandle_t *fhp)
-{
- char *cp = (char *)fhp;
- int i;
-
- NFSD_LOCK_DONTCARE();
-
- for (i = 0; i < NFSX_V3FH; i++)
- if (*cp++ != 0)
- return (FALSE);
- return (TRUE);
-}
-
-/*
- * Map errnos to NFS error numbers. For Version 3 also filter out error
- * numbers not specified for the associated procedure.
- */
-int
-nfsrv_errmap(struct nfsrv_descript *nd, int err)
-{
- const short *defaulterrp, *errp;
- int e;
-
-
- if (nd->nd_flag & ND_NFSV3) {
- if (nd->nd_procnum <= NFSPROC_COMMIT) {
- errp = defaulterrp = nfsrv_v3errmap[nd->nd_procnum];
- while (*++errp) {
- if (*errp == err)
- return (err);
- else if (*errp > err)
- break;
- }
- return ((int)*defaulterrp);
- } else
- return (err & 0xffff);
- }
- e = 0;
- if (err <= ELAST)
- e = nfsrv_v2errmap[err - 1];
- if (e != 0)
- return (e);
- return (NFSERR_IO);
-}
-
-/*
- * Sort the group list in increasing numerical order.
- * (Insertion sort by Chris Torek, who was grossed out by the bubble sort
- * that used to be here.)
- */
-void
-nfsrvw_sort(gid_t *list, int num)
-{
- int i, j;
- gid_t v;
-
- /* Insertion sort. */
- for (i = 1; i < num; i++) {
- v = list[i];
- /* find correct slot for value v, moving others up */
- for (j = i; --j >= 0 && v < list[j];)
- list[j + 1] = list[j];
- list[j + 1] = v;
- }
-}
-
-/*
- * Helper functions for macros.
- */
-
-void
-nfsm_srvfhtom_xx(fhandle_t *f, int v3, struct mbuf **mb, caddr_t *bpos)
-{
- u_int32_t *tl;
-
- if (v3) {
- tl = nfsm_build_xx(NFSX_UNSIGNED + NFSX_V3FH, mb, bpos);
- *tl++ = txdr_unsigned(NFSX_V3FH);
- bcopy(f, tl, NFSX_V3FH);
- } else {
- tl = nfsm_build_xx(NFSX_V2FH, mb, bpos);
- bcopy(f, tl, NFSX_V2FH);
- }
-}
-
-void
-nfsm_srvpostop_fh_xx(fhandle_t *f, struct mbuf **mb, caddr_t *bpos)
-{
- u_int32_t *tl;
-
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED + NFSX_V3FH, mb, bpos);
- *tl++ = nfsrv_nfs_true;
- *tl++ = txdr_unsigned(NFSX_V3FH);
- bcopy(f, tl, NFSX_V3FH);
-}
-
-int
-nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
-
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- *s = fxdr_unsigned(int32_t, *tl);
- if (*s > m || *s <= 0)
- return EBADRPC;
- return 0;
-}
-
-int
-nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
-
- NFSD_LOCK_DONTCARE();
-
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- *s = fxdr_unsigned(int32_t, *tl);
- if (*s > m)
- return NFSERR_NAMETOL;
- if (*s <= 0)
- return EBADRPC;
- return 0;
-}
-
-int
-nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
-
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- *s = fxdr_unsigned(int32_t, *tl);
- if (*s > m)
- return NFSERR_NAMETOL;
- if (*s < 0)
- return EBADRPC;
- return 0;
-}
-
-void
-nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
- char **bp, char **be, caddr_t bpos)
-{
- struct mbuf *nmp;
-
- NFSD_UNLOCK_ASSERT();
-
- if (*bp >= *be) {
- if (*mp == mb)
- (*mp)->m_len += *bp - bpos;
- MGET(nmp, M_WAITOK, MT_DATA);
- MCLGET(nmp, M_WAITOK);
- nmp->m_len = NFSMSIZ(nmp);
- (*mp)->m_next = nmp;
- *mp = nmp;
- *bp = mtod(*mp, caddr_t);
- *be = *bp + (*mp)->m_len;
- }
- *tl = (u_int32_t *)*bp;
-}
-
-int
-nfsm_srvmtofh_xx(fhandle_t *f, int v3, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
- int fhlen;
-
- if (v3) {
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- fhlen = fxdr_unsigned(int, *tl);
- if (fhlen != 0 && fhlen != NFSX_V3FH)
- return EBADRPC;
- } else {
- fhlen = NFSX_V2FH;
- }
- if (fhlen != 0) {
- tl = nfsm_dissect_xx_nonblock(fhlen, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- bcopy((caddr_t)tl, (caddr_t)(f), fhlen);
- } else {
- bzero((caddr_t)(f), NFSX_V3FH);
- }
- return 0;
-}
-
-int
-nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos)
-{
- u_int32_t *tl;
- int toclient = 0;
-
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- if (*tl == nfsrv_nfs_true) {
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- (a)->va_mode = nfstov_mode(*tl);
- }
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- if (*tl == nfsrv_nfs_true) {
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- (a)->va_uid = fxdr_unsigned(uid_t, *tl);
- }
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- if (*tl == nfsrv_nfs_true) {
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- (a)->va_gid = fxdr_unsigned(gid_t, *tl);
- }
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- if (*tl == nfsrv_nfs_true) {
- tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- (a)->va_size = fxdr_hyper(tl);
- }
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- switch (fxdr_unsigned(int, *tl)) {
- case NFSV3SATTRTIME_TOCLIENT:
- tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- fxdr_nfsv3time(tl, &(a)->va_atime);
- toclient = 1;
- break;
- case NFSV3SATTRTIME_TOSERVER:
- vfs_timestamp(&a->va_atime);
- a->va_vaflags |= VA_UTIMES_NULL;
- break;
- }
- tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- switch (fxdr_unsigned(int, *tl)) {
- case NFSV3SATTRTIME_TOCLIENT:
- tl = nfsm_dissect_xx_nonblock(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return EBADRPC;
- fxdr_nfsv3time(tl, &(a)->va_mtime);
- a->va_vaflags &= ~VA_UTIMES_NULL;
- break;
- case NFSV3SATTRTIME_TOSERVER:
- vfs_timestamp(&a->va_mtime);
- if (toclient == 0)
- a->va_vaflags |= VA_UTIMES_NULL;
- break;
- }
- return 0;
-}
diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c
index 354c63b..2f30d6d 100644
--- a/sys/powerpc/aim/trap.c
+++ b/sys/powerpc/aim/trap.c
@@ -177,7 +177,7 @@ trap(struct trapframe *frame)
* handled the trap and modified the trap frame so that this
* function can return normally.
*/
- if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame))
+ if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, type) != 0)
return;
#endif
diff --git a/sys/sys/dtrace_bsd.h b/sys/sys/dtrace_bsd.h
index 6bcaf29..f46b900 100644
--- a/sys/sys/dtrace_bsd.h
+++ b/sys/sys/dtrace_bsd.h
@@ -39,14 +39,14 @@ struct vattr;
struct vnode;
struct reg;
-int dtrace_trap(struct trapframe *);
+int dtrace_trap(struct trapframe *, u_int);
/*
* The dtrace module handles traps that occur during a DTrace probe.
* This type definition is used in the trap handler to provide a
* hook for the dtrace module to register its handler with.
*/
-typedef int (*dtrace_trap_func_t)(struct trapframe *);
+typedef int (*dtrace_trap_func_t)(struct trapframe *, u_int);
extern dtrace_trap_func_t dtrace_trap_func;
/*
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
index ac3cfb2..cbb2a18 100644
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -757,7 +757,10 @@ static __inline void
m_clrprotoflags(struct mbuf *m)
{
- m->m_flags &= ~M_PROTOFLAGS;
+ while (m) {
+ m->m_flags &= ~M_PROTOFLAGS;
+ m = m->m_next;
+ }
}
static __inline struct mbuf *
diff --git a/sys/sys/param.h b/sys/sys/param.h
index d25cdef..a4922f1 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 1100050 /* Master, propagated to newvers */
+#define __FreeBSD_version 1100051 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/sem.h b/sys/sys/sem.h
index f52bc0c..0ea259b 100644
--- a/sys/sys/sem.h
+++ b/sys/sys/sem.h
@@ -37,7 +37,7 @@ struct semid_ds_old {
long sem_pad1; /* SVABI/386 says I need this here */
time_t sem_ctime; /* last change time */
/* Times measured in secs since */
- /* 00:00:00 GMT, Jan. 1, 1970 */
+ /* 00:00:00 UTC, Jan. 1, 1970, without leap seconds */
long sem_pad2; /* SVABI/386 says I need this here */
long sem_pad3[4]; /* SVABI/386 says I need this here */
};
@@ -50,7 +50,7 @@ struct semid_ds {
time_t sem_otime; /* last operation time */
time_t sem_ctime; /* last change time */
/* Times measured in secs since */
- /* 00:00:00 GMT, Jan. 1, 1970 */
+ /* 00:00:00 UTC, Jan. 1, 1970, without leap seconds */
};
/*
diff --git a/sys/sys/time.h b/sys/sys/time.h
index 1f0a530..395e888 100644
--- a/sys/sys/time.h
+++ b/sys/sys/time.h
@@ -398,7 +398,7 @@ extern sbintime_t sbt_tickthreshold;
* Functions containing "up" returns time relative to boot and
* should be used for calculating time intervals.
*
- * Functions without "up" returns GMT time.
+ * Functions without "up" returns UTC time.
*
* Functions with the "get" prefix returns a less precise result
* much faster than the functions without "get" prefix and should
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 87382b8..8a14f69 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -580,6 +580,7 @@ typedef void vop_getpages_iodone_t(void *, vm_page_t *, int, int);
/* vn_open_flags */
#define VN_OPEN_NOAUDIT 0x00000001
#define VN_OPEN_NOCAPCHECK 0x00000002
+#define VN_OPEN_NAMECACHE 0x00000004
/*
* Public vnode manipulation functions.
diff --git a/sys/teken/libteken/teken.3 b/sys/teken/libteken/teken.3
index 1c2ebbe..70bed07 100644
--- a/sys/teken/libteken/teken.3
+++ b/sys/teken/libteken/teken.3
@@ -188,7 +188,7 @@ prior to 9.0.
.Sh SEE ALSO
.Xr ncurses 3 ,
.Xr termcap 3 ,
-.Xr syscons 4 .
+.Xr syscons 4
.Sh HISTORY
The
.Nm
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 21d4ba4..3d7a21d 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -205,8 +205,10 @@ ufs_create(ap)
error =
ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
ap->a_dvp, ap->a_vpp, ap->a_cnp);
- if (error)
+ if (error != 0)
return (error);
+ if ((ap->a_cnp->cn_flags & MAKEENTRY) != 0)
+ cache_enter(ap->a_dvp, *ap->a_vpp, ap->a_cnp);
return (0);
}
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index b2877c1..79665ba 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -2711,6 +2711,8 @@ retrylookup:
sleep = (allocflags & VM_ALLOC_IGN_SBUSY) != 0 ?
vm_page_xbusied(m) : vm_page_busied(m);
if (sleep) {
+ if ((allocflags & VM_ALLOC_NOWAIT) != 0)
+ return (NULL);
/*
* Reference the page before unlocking and
* sleeping so that the page daemon is less
@@ -2736,8 +2738,10 @@ retrylookup:
return (m);
}
}
- m = vm_page_alloc(object, pindex, allocflags & ~VM_ALLOC_IGN_SBUSY);
+ m = vm_page_alloc(object, pindex, allocflags);
if (m == NULL) {
+ if ((allocflags & VM_ALLOC_NOWAIT) != 0)
+ return (NULL);
VM_OBJECT_WUNLOCK(object);
VM_WAIT;
VM_OBJECT_WLOCK(object);
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index f12b76c..cd30772 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -376,22 +376,36 @@ extern long first_page; /* first physical page number */
vm_page_t PHYS_TO_VM_PAGE(vm_paddr_t pa);
-/* page allocation classes: */
+/*
+ * Page allocation parameters for vm_page for the functions
+ * vm_page_alloc(), vm_page_grab(), vm_page_alloc_contig() and
+ * vm_page_alloc_freelist(). Some functions support only a subset
+ * of the flags, and ignore others, see the flags legend.
+ *
+ * Bits 0 - 1 define class.
+ * Bits 2 - 15 dedicated for flags.
+ * Legend:
+ * (a) - vm_page_alloc() supports the flag.
+ * (c) - vm_page_alloc_contig() supports the flag.
+ * (f) - vm_page_alloc_freelist() supports the flag.
+ * (g) - vm_page_grab() supports the flag.
+ * Bits above 15 define the count of additional pages that the caller
+ * intends to allocate.
+ */
#define VM_ALLOC_NORMAL 0
#define VM_ALLOC_INTERRUPT 1
#define VM_ALLOC_SYSTEM 2
#define VM_ALLOC_CLASS_MASK 3
-/* page allocation flags: */
-#define VM_ALLOC_WIRED 0x0020 /* non pageable */
-#define VM_ALLOC_ZERO 0x0040 /* Try to obtain a zeroed page */
-#define VM_ALLOC_NOOBJ 0x0100 /* No associated object */
-#define VM_ALLOC_NOBUSY 0x0200 /* Do not busy the page */
-#define VM_ALLOC_IFCACHED 0x0400 /* Fail if the page is not cached */
-#define VM_ALLOC_IFNOTCACHED 0x0800 /* Fail if the page is cached */
-#define VM_ALLOC_IGN_SBUSY 0x1000 /* vm_page_grab() only */
-#define VM_ALLOC_NODUMP 0x2000 /* don't include in dump */
-#define VM_ALLOC_SBUSY 0x4000 /* Shared busy the page */
-
+#define VM_ALLOC_WIRED 0x0020 /* (acfg) Allocate non pageable page */
+#define VM_ALLOC_ZERO 0x0040 /* (acfg) Try to obtain a zeroed page */
+#define VM_ALLOC_NOOBJ 0x0100 /* (acg) No associated object */
+#define VM_ALLOC_NOBUSY 0x0200 /* (acg) Do not busy the page */
+#define VM_ALLOC_IFCACHED 0x0400 /* (ag) Fail if page is not cached */
+#define VM_ALLOC_IFNOTCACHED 0x0800 /* (ag) Fail if page is cached */
+#define VM_ALLOC_IGN_SBUSY 0x1000 /* (g) Ignore shared busy flag */
+#define VM_ALLOC_NODUMP 0x2000 /* (ag) don't include in dump */
+#define VM_ALLOC_SBUSY 0x4000 /* (acg) Shared busy the page */
+#define VM_ALLOC_NOWAIT 0x8000 /* (g) Do not sleep, return NULL */
#define VM_ALLOC_COUNT_SHIFT 16
#define VM_ALLOC_COUNT(count) ((count) << VM_ALLOC_COUNT_SHIFT)
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index 6ba1776..553a768 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1333,26 +1333,6 @@ OLD_FILES+=usr/share/man/man1/gdbserver.1.gz
OLD_FILES+=usr/share/man/man1/kgdb.1.gz
.endif
-.if ${MK_GPIB} == no
-OLD_FILES+=usr/include/dev/ieee488/ibfoo_int.h
-OLD_FILES+=usr/include/dev/ieee488/tnt4882.h
-OLD_FILES+=usr/include/dev/ieee488/ugpib.h
-OLD_FILES+=usr/include/dev/ieee488/upd7210.h
-OLD_DIRS+=usr/include/dev/ieee488
-OLD_FILES+=usr/include/gpib/gpib.h
-OLD_DIRS+=usr/include/gpib
-OLD_FILES+=usr/lib/libgpib.a
-OLD_FILES+=usr/lib/libgpib.so
-OLD_LIBS+=usr/lib/libgpib.so.3
-OLD_FILES+=usr/lib/libgpib_p.a
-.if ${TARGET_ARCH} == "amd64" || ${TARGET_ARCH} == "powerpc64"
-OLD_FILES+=usr/lib32/libgpib.a
-OLD_FILES+=usr/lib32/libgpib.so
-OLD_LIBS+=usr/lib32/libgpib.so.3
-OLD_FILES+=usr/lib32/libgpib_p.a
-.endif
-.endif
-
.if ${MK_GPIO} == no
OLD_FILES+=usr/sbin/gpioctl
OLD_FILES+=usr/share/man/man8/gpioctl.8.gz
@@ -3705,7 +3685,6 @@ OLD_FILES+=usr/lib/libformw_p.a
OLD_FILES+=usr/lib/libgcc_p.a
OLD_FILES+=usr/lib/libgeom_p.a
OLD_FILES+=usr/lib/libgnuregex_p.a
-OLD_FILES+=usr/lib/libgpib_p.a
OLD_FILES+=usr/lib/libgssapi_krb5_p.a
OLD_FILES+=usr/lib/libgssapi_p.a
OLD_FILES+=usr/lib/libhdb_p.a
diff --git a/tools/build/options/WITHOUT_GPIB b/tools/build/options/WITHOUT_GPIB
deleted file mode 100644
index 82cec15..0000000
--- a/tools/build/options/WITHOUT_GPIB
+++ /dev/null
@@ -1,2 +0,0 @@
-.\" $FreeBSD$
-Set to not build GPIB bus support.
diff --git a/tools/tools/ether_reflect/ether_reflect.1 b/tools/tools/ether_reflect/ether_reflect.1
index e6539b1..421136b 100644
--- a/tools/tools/ether_reflect/ether_reflect.1
+++ b/tools/tools/ether_reflect/ether_reflect.1
@@ -91,10 +91,10 @@ are seen on ineterface em0. The timeout is 1 millisecond.
Rewrite the destination address in each packet to 00:00:00:aa:bb:cc
before reflecting the packet.
.Sh SEE ALSO
-.Xr ifconfig 8 ,
.Xr tcpdump 1 ,
+.Xr bpf 2 ,
.Xr pcap 4 ,
-.Xr bpf 2 .
+.Xr ifconfig 8
.Sh HISTORY
The
.Nm
diff --git a/tools/tools/sysbuild/sysbuild.sh b/tools/tools/sysbuild/sysbuild.sh
index bb22a69..d95b8df 100644
--- a/tools/tools/sysbuild/sysbuild.sh
+++ b/tools/tools/sysbuild/sysbuild.sh
@@ -219,6 +219,10 @@ ports_build() (
ports_recurse . $PORTS_WE_WANT
+ if [ "x${PKG_DIR}" != "x" ] ; then
+ mkdir -p ${PKG_DIR}
+ fi
+
# Now build & install them
for p in `cat /tmp/_.plist`
do
@@ -231,9 +235,7 @@ ports_build() (
(
cd $p
- make clean ${PORTS_OPTS}
- make all ${PORTS_OPTS}
- make install ${PORTS_OPTS}
+ make clean all install ${PORTS_OPTS}
) > _.$b 2>&1 < /dev/null
continue
fi
diff --git a/tools/tools/vimage/vimage.8 b/tools/tools/vimage/vimage.8
index 306bf83..3ceb069 100644
--- a/tools/tools/vimage/vimage.8
+++ b/tools/tools/vimage/vimage.8
@@ -178,8 +178,8 @@ The
.Nm
command exits 0 on success, and >0 if an error occurs.
.Sh SEE ALSO
-.Xr jail 8
-.Xr jexec 8
+.Xr jail 8 ,
+.Xr jexec 8 ,
.Xr jls 8
.Sh HISTORY
Network stack virtualization framework first appeared as a patchset
diff --git a/usr.bin/dpv/dpv.1 b/usr.bin/dpv/dpv.1
index dacfdf9..d277446 100644
--- a/usr.bin/dpv/dpv.1
+++ b/usr.bin/dpv/dpv.1
@@ -359,9 +359,9 @@ dpv -o /dev/md42 < /dev/zero
.Ed
.Sh SEE ALSO
.Xr dialog 1 ,
-.Xr dialog 3 ,
.Xr sh 1 ,
-.Xr Xdialog 1
+.Xr Xdialog 1 ,
+.Xr dialog 3
.Sh HISTORY
A
.Nm
diff --git a/usr.bin/iscsictl/iscsi.conf.5 b/usr.bin/iscsictl/iscsi.conf.5
index 2e7a68d..0343385 100644
--- a/usr.bin/iscsictl/iscsi.conf.5
+++ b/usr.bin/iscsictl/iscsi.conf.5
@@ -175,8 +175,8 @@ chaptest {
.Ed
.Sh SEE ALSO
.Xr iscsi_initiator 4 ,
-.Xr iscsictl 8 ,
-.Xr iscontrol 8
+.Xr iscontrol 8 ,
+.Xr iscsictl 8
.Sh STANDARDS
ISCSI RFC 3720
.\"Sh HISTORY
diff --git a/usr.bin/last/last.1 b/usr.bin/last/last.1
index 6cb2e68..e552dd6 100644
--- a/usr.bin/last/last.1
+++ b/usr.bin/last/last.1
@@ -198,9 +198,9 @@ login data base
.El
.Sh SEE ALSO
.Xr lastcomm 1 ,
-.Xr lastlogin 8 ,
.Xr getutxent 3 ,
-.Xr ac 8
+.Xr ac 8 ,
+.Xr lastlogin 8
.Sh HISTORY
A
.Nm
diff --git a/usr.bin/man/man.1 b/usr.bin/man/man.1
index ca497f3..5647b6c 100644
--- a/usr.bin/man/man.1
+++ b/usr.bin/man/man.1
@@ -349,17 +349,17 @@ Local configuration files.
.Sh SEE ALSO
.Xr apropos 1 ,
.Xr intro 1 ,
+.Xr locale 1 ,
+.Xr manpath 1 ,
+.Xr nroff 1 ,
+.Xr troff 1 ,
+.Xr whatis 1 ,
.Xr intro 2 ,
.Xr intro 3 ,
.Xr intro 4 ,
.Xr intro 5 ,
+.Xr man.conf 5 ,
.Xr intro 6 ,
.Xr intro 7 ,
.Xr intro 8 ,
-.Xr intro 9 ,
-.Xr locale 1 ,
-.Xr manpath 1 ,
-.Xr nroff 1 ,
-.Xr troff 1 ,
-.Xr whatis 1 ,
-.Xr man.conf 5
+.Xr intro 9
diff --git a/usr.bin/man/man.sh b/usr.bin/man/man.sh
index de03f40..86d6b14 100755
--- a/usr.bin/man/man.sh
+++ b/usr.bin/man/man.sh
@@ -312,7 +312,7 @@ man_display_page() {
fi
testline="mandoc -Tlint -Werror 2>/dev/null"
- pipeline="mandoc -Tlocale | $MANPAGER"
+ pipeline="mandoc | $MANPAGER"
if ! eval "$cattool $manpage | $testline" ;then
if which -s groff; then
diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile
index a5d871b..e55405b 100644
--- a/usr.bin/mandoc/Makefile
+++ b/usr.bin/mandoc/Makefile
@@ -26,6 +26,11 @@ TERM_SRCS= eqn_term.c \
term_ps.c \
tbl_term.c
+DB_SRCS= mandocdb.c \
+ mansearch.c \
+ mansearch_const.c \
+ manpath.c
+
SRCS= ${HTML_SRCS} \
${MAN_SRCS} \
${TERM_SRCS} \
@@ -33,13 +38,9 @@ SRCS= ${HTML_SRCS} \
out.c \
tree.c
-APROPOS_SRCS= mansearch.c \
- mansearch_const.c \
- manpath.c
-
-SRCS+= ${APROPOS_SRCS}
+SRCS+= ${DB_SRCS}
-WARNS?= 3
+WARNS?= 2
CFLAGS+= -DHAVE_CONFIG_H \
-I${.CURDIR}/../../lib/libohash/ \
-I${.CURDIR}/../../contrib/sqlite3
diff --git a/usr.bin/mkcsmapper/mkcsmapper.1 b/usr.bin/mkcsmapper/mkcsmapper.1
index cf1fde2..8faf5e6 100644
--- a/usr.bin/mkcsmapper/mkcsmapper.1
+++ b/usr.bin/mkcsmapper/mkcsmapper.1
@@ -77,8 +77,8 @@ Generate pivot data from
.Ex -std mkcsmapper
.Sh SEE ALSO
.Xr iconv 1 ,
-.Xr iconv 3 ,
-.Xr mkesdb 1
+.Xr mkesdb 1 ,
+.Xr iconv 3
.Sh HISTORY
.Nm
first appeared in
diff --git a/usr.bin/mkesdb/mkesdb.1 b/usr.bin/mkesdb/mkesdb.1
index c5d2edf..a0743b6 100644
--- a/usr.bin/mkesdb/mkesdb.1
+++ b/usr.bin/mkesdb/mkesdb.1
@@ -72,8 +72,8 @@ Put generated binary data to
.Ex -std mkesdb
.Sh SEE ALSO
.Xr iconv 1 ,
-.Xr iconv 3 ,
-.Xr mkcsmapper 1
+.Xr mkcsmapper 1 ,
+.Xr iconv 3
.Sh HISTORY
.Nm
first appeared in
diff --git a/usr.bin/patch/patch.c b/usr.bin/patch/patch.c
index 14aca68..987bddc 100644
--- a/usr.bin/patch/patch.c
+++ b/usr.bin/patch/patch.c
@@ -23,7 +23,7 @@
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
* behaviour
*
- * $OpenBSD: patch.c,v 1.52 2014/11/26 18:34:51 millert Exp $
+ * $OpenBSD: patch.c,v 1.54 2014/12/13 10:31:07 tobias Exp $
* $FreeBSD$
*
*/
@@ -215,13 +215,13 @@ main(int argc, char *argv[])
for (open_patch_file(filearg[1]); there_is_another_patch();
reinitialize_almost_everything()) {
/* for each patch in patch file */
-
+
patch_seen = true;
warn_on_invalid_line = true;
if (outname == NULL)
- outname = savestr(filearg[0]);
+ outname = xstrdup(filearg[0]);
/* for ed script just up and do it and exit */
if (diff_type == ED_DIFF) {
@@ -416,7 +416,7 @@ main(int argc, char *argv[])
}
set_signals(1);
}
-
+
if (!patch_seen)
error = 2;
@@ -514,10 +514,10 @@ get_some_switches(void)
/* FALLTHROUGH */
case 'z':
/* must directly follow 'b' case for backwards compat */
- simple_backup_suffix = savestr(optarg);
+ simple_backup_suffix = xstrdup(optarg);
break;
case 'B':
- origprae = savestr(optarg);
+ origprae = xstrdup(optarg);
break;
case 'c':
diff_type = CONTEXT_DIFF;
@@ -555,7 +555,7 @@ get_some_switches(void)
case 'i':
if (++filec == MAXFILEC)
fatal("too many file arguments\n");
- filearg[filec] = savestr(optarg);
+ filearg[filec] = xstrdup(optarg);
break;
case 'l':
canonicalize = true;
@@ -567,7 +567,7 @@ get_some_switches(void)
noreverse = true;
break;
case 'o':
- outname = savestr(optarg);
+ outname = xstrdup(optarg);
break;
case 'p':
strippath = atoi(optarg);
@@ -611,12 +611,12 @@ get_some_switches(void)
Argv += optind;
if (Argc > 0) {
- filearg[0] = savestr(*Argv++);
+ filearg[0] = xstrdup(*Argv++);
Argc--;
while (Argc > 0) {
if (++filec == MAXFILEC)
fatal("too many file arguments\n");
- filearg[filec] = savestr(*Argv++);
+ filearg[filec] = xstrdup(*Argv++);
Argc--;
}
}
diff --git a/usr.bin/patch/pch.c b/usr.bin/patch/pch.c
index bb4a688..aacafc8 100644
--- a/usr.bin/patch/pch.c
+++ b/usr.bin/patch/pch.c
@@ -205,14 +205,14 @@ there_is_another_patch(void)
while (filearg[0] == NULL) {
if (force || batch) {
say("No file to patch. Skipping...\n");
- filearg[0] = savestr(bestguess);
+ filearg[0] = xstrdup(bestguess);
skip_rest_of_patch = true;
return true;
}
ask("File to patch: ");
if (*buf != '\n') {
free(bestguess);
- bestguess = savestr(buf);
+ bestguess = xstrdup(buf);
filearg[0] = fetchname(buf, &exists, 0);
}
if (!exists) {
@@ -319,7 +319,7 @@ intuit_diff_type(void)
else if (strnEQ(s, "Prereq:", 7)) {
for (t = s + 7; isspace((unsigned char)*t); t++)
;
- revision = savestr(t);
+ revision = xstrdup(t);
for (t = revision;
*t && !isspace((unsigned char)*t); t++)
;
@@ -403,7 +403,7 @@ scan_exit:
free(bestguess);
bestguess = NULL;
if (filearg[0] != NULL)
- bestguess = savestr(filearg[0]);
+ bestguess = xstrdup(filearg[0]);
else if (!ok_to_create_file) {
/*
* We don't want to create a new file but we need a
@@ -1505,7 +1505,7 @@ posix_name(const struct file_name *names, bool assume_exists)
path = names[NEW_FILE].path;
}
- return path ? savestr(path) : NULL;
+ return path ? xstrdup(path) : NULL;
}
static char *
@@ -1571,7 +1571,7 @@ best_name(const struct file_name *names, bool assume_exists)
best = names[NEW_FILE].path;
}
- return best ? savestr(best) : NULL;
+ return best ? xstrdup(best) : NULL;
}
static size_t
@@ -1613,7 +1613,7 @@ strtolinenum(char *nptr, char **endptr)
if (errstr != NULL)
fatal("invalid line number at line %ld: `%s' is %s\n",
p_input_line, nptr, errstr);
-
+
*p = c;
*endptr = p;
diff --git a/usr.bin/patch/util.c b/usr.bin/patch/util.c
index 6980676..6d696b0 100644
--- a/usr.bin/patch/util.c
+++ b/usr.bin/patch/util.c
@@ -202,6 +202,22 @@ savestr(const char *s)
}
/*
+ * Allocate a unique area for a string. Call fatal if out of memory.
+ */
+char *
+xstrdup(const char *s)
+{
+ char *rv;
+
+ if (!s)
+ s = "Oops";
+ rv = strdup(s);
+ if (rv == NULL)
+ fatal("out of memory\n");
+ return rv;
+}
+
+/*
* Vanilla terminal output (buffered).
*/
void
diff --git a/usr.bin/patch/util.h b/usr.bin/patch/util.h
index 5759d68..ff2feab 100644
--- a/usr.bin/patch/util.h
+++ b/usr.bin/patch/util.h
@@ -23,7 +23,7 @@
* -C option added in 1998, original code by Marc Espie, based on FreeBSD
* behaviour
*
- * $OpenBSD: util.h,v 1.15 2005/06/20 07:14:06 otto Exp $
+ * $OpenBSD: util.h,v 1.16 2014/12/13 10:31:07 tobias Exp $
* $FreeBSD$
*/
@@ -41,6 +41,7 @@ void pfatal(const char *, ...)
void ask(const char *, ...)
__attribute__((__format__(__printf__, 1, 2)));
char *savestr(const char *);
+char *xstrdup(const char *);
void set_signals(int);
void ignore_signals(void);
void makedirs(const char *, bool);
diff --git a/usr.bin/rup/rup.1 b/usr.bin/rup/rup.1
index 8b16670..499d6ab 100644
--- a/usr.bin/rup/rup.1
+++ b/usr.bin/rup/rup.1
@@ -83,8 +83,8 @@ and cannot accommodate any RPC-based services.
The host may be down.
.El
.Sh SEE ALSO
-.Xr rpcbind 8 ,
-.Xr rpc.rstatd 8
+.Xr rpc.rstatd 8 ,
+.Xr rpcbind 8
.Sh HISTORY
The
.Nm
diff --git a/usr.bin/rusers/rusers.1 b/usr.bin/rusers/rusers.1
index b96933f..8980d21 100644
--- a/usr.bin/rusers/rusers.1
+++ b/usr.bin/rusers/rusers.1
@@ -92,8 +92,8 @@ The host may be down.
.Xr rwho 1 ,
.Xr users 1 ,
.Xr who 1 ,
-.Xr rpcbind 8 ,
-.Xr rpc.rusersd 8
+.Xr rpc.rusersd 8 ,
+.Xr rpcbind 8
.Sh HISTORY
The
.Nm
diff --git a/usr.bin/rwall/rwall.1 b/usr.bin/rwall/rwall.1
index 7e54603..bb545e8 100644
--- a/usr.bin/rwall/rwall.1
+++ b/usr.bin/rwall/rwall.1
@@ -67,8 +67,8 @@ The host may be down.
.El
.Sh SEE ALSO
.Xr who 1 ,
-.Xr rpcbind 8 ,
-.Xr rpc.rwalld 8
+.Xr rpc.rwalld 8 ,
+.Xr rpcbind 8
.Sh HISTORY
The
.Nm
diff --git a/usr.bin/script/script.1 b/usr.bin/script/script.1
index de8e7ff..239508f 100644
--- a/usr.bin/script/script.1
+++ b/usr.bin/script/script.1
@@ -164,7 +164,7 @@ is assumed.
.Pq Most shells set this variable automatically .
.El
.Sh SEE ALSO
-.Xr csh 1
+.Xr csh 1 ,
.Xr filemon 4
.Po
for the
diff --git a/usr.bin/seq/seq.1 b/usr.bin/seq/seq.1
index 1ac977e..12dd184 100644
--- a/usr.bin/seq/seq.1
+++ b/usr.bin/seq/seq.1
@@ -1,4 +1,4 @@
-.\" $NetBSD: seq.1,v 1.6 2008/11/26 15:03:47 ginsbach Exp $
+.\" $NetBSD: seq.1,v 1.8 2013/04/07 17:37:45 jdf Exp $
.\"
.\" Copyright (c) 2005 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 19, 2010
+.Dd September 10, 2013
.Dt SEQ 1
.Os
.Sh NAME
@@ -59,7 +59,7 @@ as possible, in increments of
When
.Ar first
is larger than
-.Ar last
+.Ar last ,
the default
.Ar incr
is -1.
@@ -79,8 +79,11 @@ style
.Ar format
to print each number.
Only the
+.Cm A ,
+.Cm a ,
.Cm E ,
.Cm e ,
+.Cm F ,
.Cm f ,
.Cm G ,
.Cm g ,
diff --git a/usr.bin/seq/seq.c b/usr.bin/seq/seq.c
index e077743..6d715e1 100644
--- a/usr.bin/seq/seq.c
+++ b/usr.bin/seq/seq.c
@@ -1,4 +1,4 @@
-/* $NetBSD: seq.c,v 1.5 2008/07/21 14:19:26 lukem Exp $ */
+/* $NetBSD: seq.c,v 1.7 2010/05/27 08:40:19 dholland Exp $ */
/*
* Copyright (c) 2005 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -158,6 +158,8 @@ main(int argc, char *argv[])
if (!valid_format(fmt))
errx(1, "invalid format string: `%s'", fmt);
fmt = unescape(fmt);
+ if (!valid_format(fmt))
+ errx(1, "invalid format string");
/*
* XXX to be bug for bug compatible with Plan 9 add a
* newline if none found at the end of the format string.
@@ -225,39 +227,56 @@ numeric(const char *s)
static int
valid_format(const char *fmt)
{
- int conversions = 0;
+ unsigned conversions = 0;
while (*fmt != '\0') {
/* scan for conversions */
- if (*fmt != '\0' && *fmt != '%') {
- do {
- fmt++;
- } while (*fmt != '\0' && *fmt != '%');
+ if (*fmt != '%') {
+ fmt++;
+ continue;
}
- /* scan a conversion */
- if (*fmt != '\0') {
- do {
- fmt++;
+ fmt++;
- /* ok %% */
- if (*fmt == '%') {
- fmt++;
- break;
- }
- /* valid conversions */
- if (strchr("eEfgG", *fmt) &&
- conversions++ < 1) {
- fmt++;
- break;
- }
- /* flags, width and precision */
- if (isdigit((unsigned char)*fmt) ||
- strchr("+- 0#.", *fmt))
- continue;
+ /* allow %% but not things like %10% */
+ if (*fmt == '%') {
+ fmt++;
+ continue;
+ }
- /* oops! bad conversion format! */
- return (0);
- } while (*fmt != '\0');
+ /* flags */
+ while (*fmt != '\0' && strchr("#0- +'", *fmt)) {
+ fmt++;
+ }
+
+ /* field width */
+ while (*fmt != '\0' && strchr("0123456789", *fmt)) {
+ fmt++;
+ }
+
+ /* precision */
+ if (*fmt == '.') {
+ fmt++;
+ while (*fmt != '\0' && strchr("0123456789", *fmt)) {
+ fmt++;
+ }
+ }
+
+ /* conversion */
+ switch (*fmt) {
+ case 'A':
+ case 'a':
+ case 'E':
+ case 'e':
+ case 'F':
+ case 'f':
+ case 'G':
+ case 'g':
+ /* floating point formats are accepted */
+ conversions++;
+ break;
+ default:
+ /* anything else is not */
+ return 0;
}
}
diff --git a/usr.bin/setchannel/setchannel.1 b/usr.bin/setchannel/setchannel.1
index 5b2d4ab..d0c865e 100644
--- a/usr.bin/setchannel/setchannel.1
+++ b/usr.bin/setchannel/setchannel.1
@@ -85,8 +85,8 @@ Channel number to set.
Frequency in MHz (must include decimal point).
.El
.Sh SEE ALSO
-.Xr cxm 4 ,
.Xr bktr 4 ,
+.Xr cxm 4 ,
.Xr meteor 4
.Sh HISTORY
The
diff --git a/usr.bin/showmount/showmount.8 b/usr.bin/showmount/showmount.8
index 106b1a1..2831593 100644
--- a/usr.bin/showmount/showmount.8
+++ b/usr.bin/showmount/showmount.8
@@ -84,8 +84,8 @@ Ignored for backwards compatibility.
.El
.Sh SEE ALSO
.Xr mount 8 ,
-.Xr mountd 8 ,
-.Xr mount_nfs 8
+.Xr mount_nfs 8 ,
+.Xr mountd 8
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/bluetooth/btpand/btpand.8 b/usr.sbin/bluetooth/btpand/btpand.8
index b89bf95..4f6ede6 100644
--- a/usr.sbin/bluetooth/btpand/btpand.8
+++ b/usr.sbin/bluetooth/btpand/btpand.8
@@ -206,10 +206,10 @@ Will create a Group Network and register the GN service with the local
SDP server.
.Sh SEE ALSO
.Xr bluetooth 3 ,
-.Xr tap 4 ,
.Xr bridge 4 ,
-.Xr hccontrol 8 ,
+.Xr tap 4 ,
.Xr dhclient 8 ,
+.Xr hccontrol 8 ,
.Xr ifconfig 8 ,
.Xr sdpd 8
.Pp
diff --git a/usr.sbin/bsdinstall/scripts/zfsboot b/usr.sbin/bsdinstall/scripts/zfsboot
index 2b01dea..673961a 100755
--- a/usr.sbin/bsdinstall/scripts/zfsboot
+++ b/usr.sbin/bsdinstall/scripts/zfsboot
@@ -65,9 +65,9 @@ f_include $BSDCFG_SHARE/variable.subr
: ${ZFSBOOT_VDEV_TYPE:=stripe}
#
-# Should we use gnop(8) to configure a transparent mapping to 4K sectors?
+# Should we use sysctl(8) vfs.zfs.min_auto_ashift=12 to force 4K sectors?
#
-: ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:=1}
+: ${ZFSBOOT_FORCE_4K_SECTORS:=1}
#
# Should we use geli(8) to encrypt the drives?
@@ -185,8 +185,6 @@ ECHO_APPEND='echo "%s" >> "%s"'
GELI_ATTACH='geli attach -j - -k "%s" "%s"'
GELI_DETACH_F='geli detach -f "%s"'
GELI_PASSWORD_INIT='geli init -b -B "%s" -e %s -J - -K "%s" -l 256 -s 4096 "%s"'
-GNOP_CREATE='gnop create -S 4096 "%s"'
-GNOP_DESTROY='gnop destroy "%s"'
GPART_ADD='gpart add -t %s "%s"'
GPART_ADD_INDEX='gpart add -i %s -t %s "%s"'
GPART_ADD_INDEX_WITH_SIZE='gpart add -i %s -t %s -s %s "%s"'
@@ -205,6 +203,7 @@ PRINTF_CONF="printf '%s=\"%%s\"\\\n' %s >> \"%s\""
PRINTF_FSTAB='printf "$FSTAB_FMT" "%s" "%s" "%s" "%s" "%s" "%s" >> "%s"'
SHELL_TRUNCATE=':> "%s"'
SWAP_GMIRROR_LABEL='gmirror label swap %s'
+SYSCTL_ZFS_MIN_ASHIFT_12='sysctl vfs.zfs.min_auto_ashift=12'
UMOUNT='umount "%s"'
ZFS_CREATE_WITH_OPTIONS='zfs create %s "%s"'
ZFS_SET='zfs set "%s" "%s"'
@@ -236,7 +235,7 @@ msg_encrypt_disks="Encrypt Disks?"
msg_encrypt_disks_help="Use geli(8) to encrypt all data partitions"
msg_error="Error"
msg_force_4k_sectors="Force 4K Sectors?"
-msg_force_4k_sectors_help="Use gnop(8) to configure forced 4K sector alignment"
+msg_force_4k_sectors_help="Use sysctl(8) vfs.zfs.min_auto_ashift=12 to force 4K sectors"
msg_freebsd_installer="FreeBSD Installer"
msg_geli_password="Enter a strong passphrase, used to protect your encryption keys. You will be required to enter this passphrase each time the system is booted"
msg_geli_setup="Initializing encryption on selected disks,\n this will take several seconds per disk"
@@ -315,7 +314,7 @@ dialog_menu_main()
local usegeli="$msg_no"
local swapgeli="$msg_no"
local swapmirror="$msg_no"
- [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] && force4k="$msg_yes"
+ [ "$ZFSBOOT_FORCE_4K_SECTORS" ] && force4k="$msg_yes"
[ "$ZFSBOOT_GELI_ENCRYPTION" ] && usegeli="$msg_yes"
[ "$ZFSBOOT_SWAP_ENCRYPTION" ] && swapgeli="$msg_yes"
[ "$ZFSBOOT_SWAP_MIRROR" ] && swapmirror="$msg_yes"
@@ -1062,36 +1061,22 @@ zfs_create_boot()
# Prepare the disks and build pool device list(s)
#
f_dprintf "$funcname: Preparing disk partitions for ZFS pool..."
- [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ] &&
- f_dprintf "$funcname: With 4k alignment using gnop(8)..."
+
+ # Force 4K sectors using vfs.zfs.min_auto_ashift=12
+ if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then
+ f_dprintf "$funcname: With 4K sectors..."
+ f_eval_catch $funcname sysctl "$SYSCTL_ZFS_MIN_ASHIFT_12" \
+ || return $FAILURE
+ fi
local n=0
for disk in $disks; do
zfs_create_diskpart $disk $n || return $FAILURE
# Now $bootpart, $targetpart, and $swappart are set (suffix
# for $disk)
-
- # Forced 4k alignment support using Geom NOP (see gnop(8))
- if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then
- if [ "$ZFSBOOT_BOOT_POOL" ]; then
- boot_vdevs="$boot_vdevs $disk$bootpart.nop"
- f_eval_catch $funcname gnop "$GNOP_CREATE" \
- $disk$bootpart || return $FAILURE
- fi
- # Don't gnop encrypted partition
- if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
- zroot_vdevs="$zroot_vdevs $disk$targetpart.eli"
- else
- zroot_vdevs="$zroot_vdevs $disk$targetpart.nop"
- f_eval_catch $funcname gnop "$GNOP_CREATE" \
- $disk$targetpart ||
- return $FAILURE
- fi
- else
- if [ "$ZFSBOOT_BOOT_POOL" ]; then
- boot_vdevs="$boot_vdevs $disk$bootpart"
- fi
- zroot_vdevs="$zroot_vdevs $disk$targetpart"
+ if [ "$ZFSBOOT_BOOT_POOL" ]; then
+ boot_vdevs="$boot_vdevs $disk$bootpart"
fi
+ zroot_vdevs="$zroot_vdevs $disk$targetpart"
n=$(( $n + 1 ))
done # disks
@@ -1266,18 +1251,6 @@ zfs_create_boot()
"$bootpool_name" || return $FAILURE
fi
- # Destroy the gnop devices (if enabled)
- for disk in ${ZFSBOOT_GNOP_4K_FORCE_ALIGN:+$disks}; do
- if [ "$ZFSBOOT_BOOT_POOL" ]; then
- f_eval_catch -d $funcname gnop "$GNOP_DESTROY" \
- $disk$bootpart.nop
- fi
- if [ ! "$ZFSBOOT_GELI_ENCRYPTION" ]; then
- f_eval_catch -d $funcname gnop "$GNOP_DESTROY" \
- $disk$targetpart.nop
- fi
- done
-
# MBR boot loader touch-up
if [ "$ZFSBOOT_PARTITION_SCHEME" = "MBR" ]; then
f_dprintf "$funcname: Updating MBR boot loader on disks..."
@@ -1544,10 +1517,10 @@ while :; do
;;
?" $msg_force_4k_sectors")
# Toggle the variable referenced both by the menu and later
- if [ "$ZFSBOOT_GNOP_4K_FORCE_ALIGN" ]; then
- ZFSBOOT_GNOP_4K_FORCE_ALIGN=
+ if [ "$ZFSBOOT_FORCE_4K_SECTORS" ]; then
+ ZFSBOOT_FORCE_4K_SECTORS=
else
- ZFSBOOT_GNOP_4K_FORCE_ALIGN=1
+ ZFSBOOT_FORCE_4K_SECTORS=1
fi
;;
?" $msg_encrypt_disks")
@@ -1555,7 +1528,7 @@ while :; do
if [ "$ZFSBOOT_GELI_ENCRYPTION" ]; then
ZFSBOOT_GELI_ENCRYPTION=
else
- ZFSBOOT_GNOP_4K_FORCE_ALIGN=1
+ ZFSBOOT_FORCE_4K_SECTORS=1
ZFSBOOT_GELI_ENCRYPTION=1
fi
;;
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
index 677a276..09484cf 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
@@ -112,8 +112,8 @@ This is the private BEGEMOT-BRIDGE-MIB that is implemented by this module.
.Sh SEE ALSO
.Xr bsnmpd 1 ,
.Xr gensnmptree 1 ,
+.Xr snmpmod 3 ,
.Xr if_bridge 4 ,
-.Xr ifconfig 8 ,
-.Xr snmpmod 3
+.Xr ifconfig 8
.Sh AUTHORS
.An Shteryana Shopova Aq Mt syrinx@FreeBSD.org
diff --git a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3 b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3
index 205f11f..d695eee 100644
--- a/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3
+++ b/usr.sbin/bsnmpd/modules/snmp_wlan/snmp_wlan.3
@@ -151,10 +151,10 @@ The private BEGEMOT-WIRELESS-MIB that is implemented by this module.
.Sh SEE ALSO
.Xr bsnmpd 1 ,
.Xr gensnmptree 1 ,
+.Xr snmpmod 3 ,
.Xr wlan 4 ,
.Xr wlan_acl 4 ,
.Xr wlan_wep 4 ,
-.Xr ifconfig 8 ,
-.Xr snmpmod 3
+.Xr ifconfig 8
.Sh AUTHORS
.An Shteryana Shopova Aq Mt syrinx@FreeBSD.org
diff --git a/usr.sbin/ctladm/ctladm.c b/usr.sbin/ctladm/ctladm.c
index 03f46c9..9f72c83 100644
--- a/usr.sbin/ctladm/ctladm.c
+++ b/usr.sbin/ctladm/ctladm.c
@@ -3643,11 +3643,14 @@ retry:
XML_SetCharacterDataHandler(parser, cctl_islist_char_handler);
retval = XML_Parse(parser, conn_str, strlen(conn_str), 1);
- XML_ParserFree(parser);
if (retval != 1) {
+ warnx("%s: Unable to parse XML: Error %d", __func__,
+ XML_GetErrorCode(parser));
+ XML_ParserFree(parser);
retval = 1;
goto bailout;
}
+ XML_ParserFree(parser);
if (verbose != 0) {
STAILQ_FOREACH(conn, &islist.conn_list, links) {
@@ -4058,11 +4061,14 @@ retry:
XML_SetCharacterDataHandler(parser, cctl_char_handler);
retval = XML_Parse(parser, lun_str, strlen(lun_str), 1);
- XML_ParserFree(parser);
if (retval != 1) {
+ warnx("%s: Unable to parse XML: Error %d", __func__,
+ XML_GetErrorCode(parser));
+ XML_ParserFree(parser);
retval = 1;
goto bailout;
}
+ XML_ParserFree(parser);
printf("LUN Backend %18s %4s %-16s %-16s\n", "Size (Blocks)", "BS",
"Serial Number", "Device ID");
@@ -4111,6 +4117,7 @@ struct cctl_portlist_data {
STAILQ_HEAD(,cctl_port) port_list;
struct cctl_port *cur_port;
int level;
+ uint64_t cur_id;
struct sbuf *cur_sb[32];
};
@@ -4133,6 +4140,14 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr)
if (portlist->cur_sb[portlist->level] == NULL)
err(1, "%s: Unable to allocate sbuf", __func__);
+ portlist->cur_id = 0;
+ for (i = 0; attr[i] != NULL; i += 2) {
+ if (strcmp(attr[i], "id") == 0) {
+ portlist->cur_id = strtoull(attr[i+1], NULL, 0);
+ break;
+ }
+ }
+
if (strcmp(name, "targ_port") == 0) {
if (cur_port != NULL)
errx(1, "%s: improper port element nesting", __func__);
@@ -4147,16 +4162,8 @@ cctl_start_pelement(void *user_data, const char *name, const char **attr)
STAILQ_INIT(&cur_port->init_list);
STAILQ_INIT(&cur_port->attr_list);
+ cur_port->port_id = portlist->cur_id;
STAILQ_INSERT_TAIL(&portlist->port_list, cur_port, links);
-
- for (i = 0; attr[i] != NULL; i += 2) {
- if (strcmp(attr[i], "id") == 0) {
- cur_port->port_id = strtoull(attr[i+1], NULL, 0);
- } else {
- errx(1, "%s: invalid LUN attribute %s = %s",
- __func__, attr[i], attr[i+1]);
- }
- }
}
}
@@ -4225,7 +4232,10 @@ cctl_end_pelement(void *user_data, const char *name)
err(1, "%s: can't allocate %zd bytes for nv pair",
__func__, sizeof(*nv));
- nv->name = strdup(name);
+ if (strcmp(name, "initiator") == 0)
+ asprintf(&nv->name, "%ju", portlist->cur_id);
+ else
+ nv->name = strdup(name);
if (nv->name == NULL)
err(1, "%s: can't allocated %zd bytes for string",
__func__, strlen(name));
@@ -4336,11 +4346,14 @@ retry:
XML_SetCharacterDataHandler(parser, cctl_char_phandler);
retval = XML_Parse(parser, port_str, strlen(port_str), 1);
- XML_ParserFree(parser);
if (retval != 1) {
+ warnx("%s: Unable to parse XML: Error %d", __func__,
+ XML_GetErrorCode(parser));
+ XML_ParserFree(parser);
retval = 1;
goto bailout;
}
+ XML_ParserFree(parser);
if (quiet == 0)
printf("Port Online Frontend Name pp vp\n");
@@ -4363,7 +4376,8 @@ retry:
if (port->target)
printf(" Target: %s\n", port->target);
STAILQ_FOREACH(nv, &port->init_list, links) {
- printf(" Initiator: %s\n", nv->value);
+ printf(" Initiator %s: %s\n",
+ nv->name, nv->value);
}
}
diff --git a/usr.sbin/ctld/login.c b/usr.sbin/ctld/login.c
index 7add09b..5358e4b 100644
--- a/usr.sbin/ctld/login.c
+++ b/usr.sbin/ctld/login.c
@@ -558,7 +558,7 @@ login_negotiate_key(struct pdu *request, const char *name,
tmp = MAX_DATA_SEGMENT_LENGTH;
}
conn->conn_max_data_segment_length = tmp;
- keys_add_int(response_keys, name, tmp);
+ keys_add_int(response_keys, name, MAX_DATA_SEGMENT_LENGTH);
} else if (strcmp(name, "MaxBurstLength") == 0) {
tmp = strtoul(value, NULL, 10);
if (tmp <= 0) {
diff --git a/usr.sbin/freebsd-update/freebsd-update.sh b/usr.sbin/freebsd-update/freebsd-update.sh
index f586909..4979c01 100644
--- a/usr.sbin/freebsd-update/freebsd-update.sh
+++ b/usr.sbin/freebsd-update/freebsd-update.sh
@@ -1395,6 +1395,7 @@ fetch_filter_metadata () {
# matter, since we add a leading "/" when we use paths later.
cut -f 3- -d '|' $1 |
sed -e 's,/|d|,|d|,' |
+ sed -e 's,/|-|,|-|,' |
sort -u > $1.tmp
# Figure out which lines to ignore and remove them.
@@ -2263,7 +2264,7 @@ upgrade_oldall_to_oldnew () {
}
# Helper for upgrade_merge: Return zero true iff the two files differ only
-# in the contents of their $FreeBSD$ tags.
+# in the contents of their RCS tags.
samef () {
X=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $1 | ${SHA256}`
Y=`sed -E 's/\\$FreeBSD.*\\$/\$FreeBSD\$/' < $2 | ${SHA256}`
@@ -2359,7 +2360,7 @@ upgrade_merge () {
# Ask the user to handle any files which didn't merge.
while read F; do
# If the installed file differs from the version in
- # the old release only due to $FreeBSD$ tag expansion
+ # the old release only due to RCS tag expansion
# then just use the version in the new release.
if samef merge/old/${F} merge/${OLDRELNUM}/${F}; then
cp merge/${RELNUM}/${F} merge/new/${F}
@@ -2381,14 +2382,14 @@ manually...
# of merging files.
while read F; do
# Skip files which haven't changed except possibly
- # in their $FreeBSD$ tags.
+ # in their RCS tags.
if [ -f merge/old/${F} ] && [ -f merge/new/${F} ] &&
samef merge/old/${F} merge/new/${F}; then
continue
fi
# Skip files where the installed file differs from
- # the old file only due to $FreeBSD$ tags.
+ # the old file only due to RCS tags.
if [ -f merge/old/${F} ] &&
[ -f merge/${OLDRELNUM}/${F} ] &&
samef merge/old/${F} merge/${OLDRELNUM}/${F}; then
diff --git a/usr.sbin/gpioctl/gpioctl.8 b/usr.sbin/gpioctl/gpioctl.8
index 8a43372..a0bf653 100644
--- a/usr.sbin/gpioctl/gpioctl.8
+++ b/usr.sbin/gpioctl/gpioctl.8
@@ -108,8 +108,8 @@ Configure pin 12 to be input pin
gpioctl -f /dev/gpioc0 -c 12 IN
.El
.Sh SEE ALSO
-.Xr gpio 4
-.Xr gpioiic 4
+.Xr gpio 4 ,
+.Xr gpioiic 4 ,
.Xr gpioled 4
.Sh HISTORY
The
diff --git a/usr.sbin/gssd/gssd.8 b/usr.sbin/gssd/gssd.8
index 82611f8..7eaf11a 100644
--- a/usr.sbin/gssd/gssd.8
+++ b/usr.sbin/gssd/gssd.8
@@ -106,8 +106,8 @@ by kernel GSS-API services.
.Ex -std
.Sh SEE ALSO
.Xr gssapi 3 ,
-.Xr mount_nfs 8 ,
-.Xr syslog 3
+.Xr syslog 3 ,
+.Xr mount_nfs 8
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/iscsid/login.c b/usr.sbin/iscsid/login.c
index 360b0ef..1338970 100644
--- a/usr.sbin/iscsid/login.c
+++ b/usr.sbin/iscsid/login.c
@@ -388,6 +388,11 @@ login_negotiate_key(struct connection *conn, const char *name,
if (tmp <= 0)
log_errx(1, "received invalid "
"MaxRecvDataSegmentLength");
+ if (tmp > ISCSI_MAX_DATA_SEGMENT_LENGTH) {
+ log_debugx("capping MaxRecvDataSegmentLength "
+ "from %d to %d", tmp, ISCSI_MAX_DATA_SEGMENT_LENGTH);
+ tmp = ISCSI_MAX_DATA_SEGMENT_LENGTH;
+ }
conn->conn_max_data_segment_length = tmp;
} else if (strcmp(name, "MaxBurstLength") == 0) {
if (conn->conn_immediate_data) {
@@ -451,10 +456,11 @@ login_negotiate(struct connection *conn)
keys_add(request_keys, "ImmediateData", "Yes");
keys_add_int(request_keys, "MaxBurstLength",
- ISCSI_MAX_DATA_SEGMENT_LENGTH);
+ 2 * ISCSI_MAX_DATA_SEGMENT_LENGTH);
keys_add_int(request_keys, "FirstBurstLength",
ISCSI_MAX_DATA_SEGMENT_LENGTH);
keys_add(request_keys, "InitialR2T", "Yes");
+ keys_add(request_keys, "MaxOutstandingR2T", "1");
} else {
keys_add(request_keys, "HeaderDigest", "None");
keys_add(request_keys, "DataDigest", "None");
@@ -465,7 +471,6 @@ login_negotiate(struct connection *conn)
keys_add(request_keys, "DefaultTime2Wait", "0");
keys_add(request_keys, "DefaultTime2Retain", "0");
keys_add(request_keys, "ErrorRecoveryLevel", "0");
- keys_add(request_keys, "MaxOutstandingR2T", "1");
keys_save(request_keys, request);
keys_delete(request_keys);
request_keys = NULL;
diff --git a/usr.sbin/jail/jail.8 b/usr.sbin/jail/jail.8
index 927e2bb..9719854 100644
--- a/usr.sbin/jail/jail.8
+++ b/usr.sbin/jail/jail.8
@@ -1183,7 +1183,6 @@ environment of the first jail.
.Xr pkill 1 ,
.Xr ps 1 ,
.Xr quota 1 ,
-.Xr ifconfig 8 ,
.Xr jail_set 2 ,
.Xr devfs 5 ,
.Xr fdescfs 5 ,
@@ -1194,6 +1193,7 @@ environment of the first jail.
.Xr chroot 8 ,
.Xr devfs 8 ,
.Xr halt 8 ,
+.Xr ifconfig 8 ,
.Xr inetd 8 ,
.Xr jexec 8 ,
.Xr jls 8 ,
diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c
index 9144ba0..73c6004 100644
--- a/usr.sbin/kldxref/kldxref.c
+++ b/usr.sbin/kldxref/kldxref.c
@@ -53,7 +53,7 @@
#include "ef.h"
-#define MAXRECSIZE 1024
+#define MAXRECSIZE 8192
#define check(val) if ((error = (val)) != 0) break
static int dflag; /* do not create a hint file, only write on stdout */
diff --git a/usr.sbin/nandsim/nandsim.8 b/usr.sbin/nandsim/nandsim.8
index c7bdb9a..d89767b 100644
--- a/usr.sbin/nandsim/nandsim.8
+++ b/usr.sbin/nandsim/nandsim.8
@@ -217,7 +217,7 @@ All commands issues to any chip on this controller are ignored.
.El
.Sh SEE ALSO
.Xr nand 4 ,
-.Xr nandsim 4
+.Xr nandsim 4 ,
.Xr nandsim.conf 5
.Sh HISTORY
The
diff --git a/usr.sbin/nfsuserd/nfsuserd.8 b/usr.sbin/nfsuserd/nfsuserd.8
index 04100ea..6e170db 100644
--- a/usr.sbin/nfsuserd/nfsuserd.8
+++ b/usr.sbin/nfsuserd/nfsuserd.8
@@ -89,12 +89,12 @@ performance impact, whereas running too many will only tie up some resources,
such as a process table entry and swap space.
.El
.Sh SEE ALSO
-.Xr getpwent 3 ,
.Xr getgrent 3 ,
+.Xr getpwent 3 ,
.Xr nfsv4 4 ,
.Xr group 5 ,
.Xr passwd 5 ,
-.Xr nfsd 8 .
+.Xr nfsd 8
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/rpc.umntall/rpc.umntall.8 b/usr.sbin/rpc.umntall/rpc.umntall.8
index 7f294a0..1f7607f 100644
--- a/usr.sbin/rpc.umntall/rpc.umntall.8
+++ b/usr.sbin/rpc.umntall/rpc.umntall.8
@@ -114,8 +114,8 @@ entry.
mounted nfs-file systems
.El
.Sh SEE ALSO
-.Xr mountd 8 ,
.Xr mount_nfs 8 ,
+.Xr mountd 8 ,
.Xr umount 8
.Sh HISTORY
The
diff --git a/usr.sbin/rtadvctl/rtadvctl.8 b/usr.sbin/rtadvctl/rtadvctl.8
index 5df6e5c..4b7c888 100644
--- a/usr.sbin/rtadvctl/rtadvctl.8
+++ b/usr.sbin/rtadvctl/rtadvctl.8
@@ -92,8 +92,8 @@ Displays information on Router Advertisement messages being sent
on each interface.
.El
.Sh SEE ALSO
-.Xr rtadvd 8 ,
-.Xr rtadvd.conf 5
+.Xr rtadvd.conf 5 ,
+.Xr rtadvd 8
.Sh HISTORY
The
.Nm
diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5
index e8b3011..d4a0c02 100644
--- a/usr.sbin/rtadvd/rtadvd.conf.5
+++ b/usr.sbin/rtadvd/rtadvd.conf.5
@@ -488,8 +488,8 @@ ef0:\\
:addr="2001:db8:ffff:1000::":prefixlen#64:tc=default:
.Ed
.Sh SEE ALSO
-.Xr termcap 5 ,
.Xr resolver 5 ,
+.Xr termcap 5 ,
.Xr rtadvd 8 ,
.Xr rtsol 8
.Rs
OpenPOWER on IntegriCloud