Index: head/etc/mtree/BSD.include.dist =================================================================== --- head/etc/mtree/BSD.include.dist (revision 349351) +++ head/etc/mtree/BSD.include.dist (revision 349352) @@ -1,382 +1,378 @@ # $FreeBSD$ # # Please see the file src/etc/mtree/README before making changes to this file. # /set type=dir uname=root gname=wheel mode=0755 . arpa .. atf-c .. atf-c++ .. bsm .. bsnmp .. c++ 4.2 backward .. bits .. debug .. ext pb_ds detail basic_tree_policy .. bin_search_tree_ .. binary_heap_ .. binomial_heap_ .. binomial_heap_base_ .. cc_hash_table_map_ .. eq_fn .. gp_hash_table_map_ .. hash_fn .. left_child_next_sibling_heap_ .. list_update_map_ .. list_update_policy .. ov_tree_map_ .. pairing_heap_ .. pat_trie_ .. rb_tree_map_ .. rc_binomial_heap_ .. resize_policy .. splay_tree_ .. thin_heap_ .. tree_policy .. trie_policy .. unordered_iterator .. .. .. .. tr1 .. .. v1 experimental .. ext .. tr1 .. .. .. cam ata .. mmc .. nvme .. scsi .. .. casper .. crypto .. dev acpica .. agp .. an .. bktr .. ciss .. evdev .. filemon .. firewire .. hwpmc .. hyperv .. ic .. iicbus .. io .. mfi .. mlx5 .. mmc .. mpt mpilib .. .. - nand - .. nvme .. ofw .. pbio .. pci .. powermac_nvram .. ppbus .. pwm .. smbus .. speaker .. tcp_log .. usb .. veriexec .. vkbd .. wi .. .. devdctl .. edit readline .. .. fs cuse .. devfs .. fdescfs .. msdosfs - .. - nandfs .. nfs .. nullfs .. procfs .. smbfs .. udf .. unionfs .. .. gcc 4.2 .. .. geom cache .. concat .. eli .. gate .. journal .. label .. mirror .. mountver .. multipath .. nop .. raid .. raid3 .. shsec .. stripe .. virstor .. .. gnu posix .. .. gssapi .. infiniband complib .. iba .. opensm .. vendor .. .. isofs cd9660 .. .. kadm5 .. krb5 .. lib80211 .. libipt .. libmilter .. libxo .. lzma .. machine pc .. .. net altq .. .. net80211 .. netgraph atm .. bluetooth include .. .. netflow .. .. netinet cc .. netdump .. .. netinet6 .. netipsec .. netnatm api .. msg .. saal .. sig .. .. netpfil pf .. .. netsmb .. nfs .. nfsclient .. nfsserver .. opencsd c_api .. etmv3 .. etmv4 .. ptm .. stm .. .. openssl .. pcap .. protocols .. rdma .. rpc .. rpcsvc .. security audit .. mac_biba .. mac_bsdextended .. mac_lomac .. mac_mls .. mac_partition .. mac_veriexec .. .. ssp .. sys disk .. .. teken .. ufs ffs .. ufs .. .. vm .. xlocale .. .. Index: head/include/Makefile =================================================================== --- head/include/Makefile (revision 349351) +++ head/include/Makefile (revision 349352) @@ -1,418 +1,404 @@ # @(#)Makefile 8.2 (Berkeley) 1/4/94 # $FreeBSD$ # # Doing a "make install" builds /usr/include. .include PACKAGE=runtime TAGS+= development CLEANFILES= osreldate.h version SUBDIR= arpa protocols rpcsvc rpc xlocale SUBDIR_PARALLEL= INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \ db.h \ dirent.h dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \ fts.h ftw.h getopt.h glob.h grp.h \ ieeefp.h ifaddrs.h \ inttypes.h iso646.h kenv.h langinfo.h libgen.h limits.h link.h \ locale.h malloc.h malloc_np.h memory.h monetary.h mpool.h mqueue.h \ ndbm.h netconfig.h \ netdb.h nl_types.h nlist.h nss.h nsswitch.h paths.h \ printf.h proc_service.h pthread.h \ pthread_np.h pwd.h ranlib.h readpassphrase.h regex.h \ res_update.h resolv.h runetype.h search.h semaphore.h setjmp.h \ signal.h spawn.h stab.h stdalign.h stdbool.h stddef.h \ stdnoreturn.h stdio.h stdlib.h string.h stringlist.h \ strings.h sysexits.h tar.h termios.h tgmath.h \ time.h timeconv.h timers.h ttyent.h \ uchar.h ulimit.h unistd.h utime.h utmpx.h uuid.h varargs.h \ wchar.h wctype.h wordexp.h xlocale.h .PATH: ${SRCTOP}/contrib/libc-vis INCS+= vis.h MHDRS= float.h floatingpoint.h stdarg.h PHDRS= sched.h _semaphore.h LHDRS= aio.h errno.h fcntl.h linker_set.h poll.h stdatomic.h stdint.h \ syslog.h ucontext.h LDIRS= bsm cam geom net net80211 netgraph netinet netinet6 \ netipsec netsmb nfs nfsclient nfsserver sys vm LSUBDIRS= cam/ata cam/mmc cam/nvme cam/scsi \ dev/acpica dev/agp dev/an dev/bktr dev/ciss dev/filemon dev/firewire \ dev/hwpmc dev/hyperv \ dev/ic dev/iicbus dev/io dev/mfi dev/mmc dev/nvme \ dev/ofw dev/pbio dev/pci ${_dev_powermac_nvram} dev/ppbus dev/pwm \ dev/smbus dev/speaker dev/tcp_log dev/veriexec dev/vkbd dev/wi \ - fs/devfs fs/fdescfs fs/msdosfs fs/nandfs fs/nfs fs/nullfs \ + fs/devfs fs/fdescfs fs/msdosfs fs/nfs fs/nullfs \ fs/procfs fs/smbfs fs/udf fs/unionfs \ geom/cache geom/concat geom/eli geom/gate geom/journal geom/label \ geom/mirror geom/mountver geom/multipath geom/nop \ geom/raid geom/raid3 geom/shsec geom/stripe geom/virstor \ net/altq \ netgraph/atm netgraph/netflow \ netinet/cc \ netinet/netdump \ security/audit \ security/mac_biba security/mac_bsdextended security/mac_lomac \ security/mac_mls security/mac_partition \ security/mac_veriexec \ sys/disk \ ufs/ffs ufs/ufs LSUBSUBDIRS= dev/mpt/mpilib .if ${MK_BLUETOOTH} != "no" LSUBSUBDIRS+= netgraph/bluetooth/include .endif .if ${MK_CUSE} != "no" LSUBDIRS+= fs/cuse .endif .if ${MK_GSSAPI} != "no" SUBDIR+= gssapi INCS+= gssapi.h .endif .if ${MK_HESIOD} != "no" INCS+= hesiod.h .endif # Handle the #define aliases for libiconv .if ${MK_ICONV} == "yes" INCS+= iconv.h .endif .if ${MK_USB} != "no" LSUBDIRS+= dev/usb .endif .if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "powerpc64" _dev_powermac_nvram= dev/powermac_nvram .endif # Define SHARED to indicate whether you want symbolic links to the system # source (``symlinks''), or a separate copy (``copies''). ``symlinks'' is # probably only useful for developers and should be avoided if you do not # wish to tie your /usr/include and /usr/src together. #SHARED= symlinks SHARED?= copies INCS+= osreldate.h SYSDIR= ${SRCTOP}/sys NEWVERS_SH= ${SYSDIR}/conf/newvers.sh PARAM_H= ${SYSDIR}/sys/param.h MK_OSRELDATE_SH= ${.CURDIR}/mk-osreldate.sh SYMLINKS+= ${LIBDIR:C,[^/]+,..,g:C,^/,,}${INCLUDEDIR} ${LIBDIR}/include osreldate.h: ${NEWVERS_SH} ${PARAM_H} ${MK_OSRELDATE_SH} env NEWVERS_SH=${NEWVERS_SH} PARAMFILE=${PARAM_H} SYSDIR=${SYSDIR} \ sh ${MK_OSRELDATE_SH} .for i in ${LHDRS} INCSLINKS+= sys/$i ${INCLUDEDIR}/$i .endfor .for i in ${MHDRS} INCSLINKS+= machine/$i ${INCLUDEDIR}/$i .endfor .for i in ${PHDRS} INCSLINKS+= sys/$i ${INCLUDEDIR}/$i .endfor .if ${MACHINE} != ${MACHINE_CPUARCH} _MARCHS= ${MACHINE_CPUARCH} .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _MARCHS+= x86 .endif META_TARGETS+= compat stage_includes: ${SHARED} SDESTDIR= ${SYSROOT:U${DESTDIR}} # Take care of stale directory-level symlinks. compat: .for i in ${LDIRS} ${LSUBDIRS} machine ${_MARCHS} crypto if [ -L ${SDESTDIR}${INCLUDEDIR}/$i ]; then \ rm -f ${SDESTDIR}${INCLUDEDIR}/$i; \ fi .endfor mtree -deU ${NO_ROOT:D-W} ${MTREE_FOLLOWS_SYMLINKS} \ -f ${SRCTOP}/etc/mtree/BSD.include.dist \ -p ${SDESTDIR}${INCLUDEDIR} > /dev/null copies: .PHONY .META .for i in ${LDIRS} ${LSUBDIRS} ${LSUBSUBDIRS} crypto machine machine/pc \ ${_MARCHS} if [ -d ${SDESTDIR}${INCLUDEDIR}/$i ]; then \ cd ${SDESTDIR}${INCLUDEDIR}/$i; \ for h in *.h; do \ if [ -L $$h ]; then rm -f $$h; fi; \ done; \ fi .endfor -.for i in ${LDIRS} ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/evdev:Ndev/hyperv:Ndev/nand:Ndev/pci:Ndev/veriexec} ${LSUBSUBDIRS} +.for i in ${LDIRS} ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/evdev:Ndev/hyperv:Ndev/pci:Ndev/veriexec} ${LSUBSUBDIRS} cd ${SRCTOP}/sys; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 $i/*.h \ ${SDESTDIR}${INCLUDEDIR}/$i .endfor cd ${SRCTOP}/sys/dev/acpica; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 acpiio.h \ ${SDESTDIR}${INCLUDEDIR}/dev/acpica; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 acpi_hpet.h \ ${SDESTDIR}${INCLUDEDIR}/dev/acpica cd ${SRCTOP}/sys/dev/agp; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 agpreg.h \ ${SDESTDIR}${INCLUDEDIR}/dev/agp cd ${SRCTOP}/sys/dev/bktr; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 ioctl_*.h \ ${SDESTDIR}${INCLUDEDIR}/dev/bktr -.if ${MK_NAND} != "no" - cd ${SRCTOP}/sys/dev/nand; \ - ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nandsim.h \ - ${SDESTDIR}${INCLUDEDIR}/dev/nand; \ - ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nand_dev.h \ - ${SDESTDIR}${INCLUDEDIR}/dev/nand -.endif cd ${SRCTOP}/sys/dev/evdev; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 input.h \ ${SDESTDIR}${INCLUDEDIR}/dev/evdev; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 input-event-codes.h \ ${SDESTDIR}${INCLUDEDIR}/dev/evdev; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 uinput.h \ ${SDESTDIR}${INCLUDEDIR}/dev/evdev cd ${SRCTOP}/sys/dev/hyperv/include; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 hyperv.h \ ${SDESTDIR}${INCLUDEDIR}/dev/hyperv cd ${SRCTOP}/sys/dev/hyperv/utilities; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 hv_snapshot.h \ ${SDESTDIR}${INCLUDEDIR}/dev/hyperv cd ${SRCTOP}/sys/dev/pci; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 pcireg.h \ ${SDESTDIR}${INCLUDEDIR}/dev/pci cd ${SRCTOP}/sys/dev/veriexec; \ ${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 veriexec_ioctl.h \ ${SDESTDIR}${INCLUDEDIR}/dev/veriexec cd ${SRCTOP}/sys/fs/cd9660/; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/isofs/cd9660 .if ${MK_IPFILTER} != "no" cd ${SRCTOP}/sys/contrib/ipfilter/netinet; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/netinet .endif .if ${MK_PF} != "no" cd ${SRCTOP}/sys/netpfil/pf; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/netpfil/pf .endif cd ${SRCTOP}/sys/crypto; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 rijndael/rijndael.h \ ${SDESTDIR}${INCLUDEDIR}/crypto cd ${SRCTOP}/sys/opencrypto; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/crypto cd ${SRCTOP}/sys/${MACHINE}/include; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/machine .if exists(${SRCTOP}/sys/${MACHINE}/include/pc) cd ${SRCTOP}/sys/${MACHINE}/include/pc; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/machine/pc .endif .for _MARCH in ${_MARCHS} .if exists(${SRCTOP}/sys/${_MARCH}/include) ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}; \ cd ${SRCTOP}/sys/${_MARCH}/include; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH} .if exists(${SRCTOP}/sys/${_MARCH}/include/pc) ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ cd ${SRCTOP}/sys/${_MARCH}/include/pc; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 *.h \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}/pc .endif .endif .endfor cd ${SRCTOP}/sys/rpc; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 types.h \ ${SDESTDIR}${INCLUDEDIR}/rpc cd ${SRCTOP}/sys/teken; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 teken.h \ ${SDESTDIR}${INCLUDEDIR}/teken .if ${MK_CDDL} != "no" cd ${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/sys; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 nvpair.h \ ${SDESTDIR}${INCLUDEDIR}/sys .endif .if ${MK_MLX5TOOL} != "no" cd ${SRCTOP}/sys/dev/mlx5; \ ${INSTALL} -C ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 mlx5io.h \ ${SDESTDIR}${INCLUDEDIR}/dev/mlx5 .endif symlinks: .PHONY .META @${ECHO} "Setting up symlinks to kernel source tree..." .for i in ${LDIRS} cd ${SRCTOP}/sys/$i; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/$i/$$h ${SDESTDIR}${INCLUDEDIR}/$i; \ done .endfor -.for i in ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/evdev:Ndev/hyperv:Ndev/nand:Ndev/pci:Ndev/veriexec} +.for i in ${LSUBDIRS:Ndev/agp:Ndev/acpica:Ndev/bktr:Ndev/evdev:Ndev/hyperv:Ndev/pci:Ndev/veriexec} cd ${SRCTOP}/sys/$i; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/$i/$$h ${SDESTDIR}${INCLUDEDIR}/$i; \ done .endfor cd ${SRCTOP}/sys/dev/acpica; \ for h in acpiio.h acpi_hpet.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/acpica/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/acpica; \ done cd ${SRCTOP}/sys/dev/agp; \ for h in agpreg.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/agp/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/agp; \ done cd ${SRCTOP}/sys/dev/bktr; \ for h in ioctl_*.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/bktr/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/bktr; \ done -.if ${MK_NAND} != "no" - cd ${SRCTOP}/sys/dev/nand; \ - for h in nandsim.h nand_dev.h; do \ - ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/nand/$$h \ - ${SDESTDIR}${INCLUDEDIR}/dev/nand; \ - done -.endif cd ${SRCTOP}/sys/dev/evdev; \ for h in input.h input-event-codes.h uinput.h; do \ ln -fs ../../../../sys/dev/evdev/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/evdev; \ done cd ${SRCTOP}/sys/dev/hyperv/include; \ for h in hyperv.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/hyperv/include/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/hyperv; \ done cd ${SRCTOP}/sys/dev/hyperv/utilities; \ for h in hv_snapshot.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/hyperv/utilities/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/hyperv; \ done cd ${SRCTOP}/sys/dev/pci; \ for h in pcireg.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/pci/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/pci; \ done cd ${SRCTOP}/sys/dev/veriexec; \ for h in veriexec_ioctl.h; do \ ln -fs ../../../../sys/dev/veriexec/$$h \ ${SDESTDIR}${INCLUDEDIR}/dev/veriexec; \ done .for i in ${LSUBSUBDIRS} cd ${SRCTOP}/sys/$i; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../../sys/$i/$$h ${SDESTDIR}${INCLUDEDIR}/$i; \ done .endfor .if ${MK_IPFILTER} != "no" cd ${SRCTOP}/sys/contrib/ipfilter/netinet; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/contrib/ipfilter/netinet/$$h \ ${SDESTDIR}${INCLUDEDIR}/netinet; \ done .endif .if ${MK_PF} != "no" cd ${SRCTOP}/sys/netpfil/pf; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/netpfil/pf/$$h \ ${SDESTDIR}${INCLUDEDIR}/netpfil/pf; \ done .endif cd ${SRCTOP}/sys/crypto; \ for h in rijndael/rijndael.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/crypto/$$h \ ${SDESTDIR}${INCLUDEDIR}/crypto; \ done cd ${SRCTOP}/sys/opencrypto; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/opencrypto/$$h \ ${SDESTDIR}${INCLUDEDIR}/crypto; \ done cd ${SRCTOP}/sys/${MACHINE}/include; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/${MACHINE}/include/$$h \ ${SDESTDIR}${INCLUDEDIR}/machine; \ done .if exists(${SRCTOP}/sys/${MACHINE}/include/pc) cd ${SRCTOP}/sys/${MACHINE}/include/pc; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/${MACHINE}/include/pc/$$h \ ${SDESTDIR}${INCLUDEDIR}/machine/pc; \ done .endif .for _MARCH in ${_MARCHS} .if exists(${SRCTOP}/sys/${_MARCH}/include) ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}; \ cd ${SRCTOP}/sys/${_MARCH}/include; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/${_MARCH}/include/$$h \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}; \ done .if exists(${SRCTOP}/sys/${_MARCH}/include/pc) ${INSTALL} -d ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 755 \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ cd ${SRCTOP}/sys/${_MARCH}/include/pc; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/${_MARCH}/include/pc/$$h \ ${SDESTDIR}${INCLUDEDIR}/${_MARCH}/pc; \ done .endif .endif .endfor cd ${SRCTOP}/sys/fs/cd9660; \ for h in *.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/fs/cd9660/$$h \ ${SDESTDIR}${INCLUDEDIR}/isofs/cd9660; \ done cd ${SRCTOP}/sys/rpc; \ for h in types.h; do \ ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../sys/rpc/$$h \ ${SDESTDIR}${INCLUDEDIR}/rpc; \ done .if ${MK_CDDL} != "no" ${INSTALL_SYMLINK} ${TAG_ARGS} \ ../../../sys/cddl/contrib/opensolaris/uts/common/sys/nvpair.h \ ${SDESTDIR}${INCLUDEDIR}/sys .endif .if ${MK_MLX5TOOL} != "no" ${INSTALL_SYMLINK} ${TAG_ARGS} ../../../../sys/dev/mlx5/mlx5io.h \ ${SDESTDIR}${INCLUDEDIR}/dev/mlx5 .endif .include installincludes: ${SHARED} ${SHARED}: compat .if ${MACHINE} == "host" && !defined(_SKIP_BUILD) # we're here because we are building a sysroot... # we need MACHINE et al set correctly HOST_MACHINE!= uname -m HOST_MACHINE_ARCH!= uname -p MACHINE:= ${HOST_MACHINE} MACHINE_ARCH:= ${HOST_MACHINE_ARCH} .endif Index: head/lib/Makefile =================================================================== --- head/lib/Makefile (revision 349351) +++ head/lib/Makefile (revision 349352) @@ -1,217 +1,216 @@ # @(#)Makefile 8.1 (Berkeley) 6/4/93 # $FreeBSD$ .include # The SUBDIR_BOOTSTRAP list is a small set of libraries which are used by many # of the other libraries. These are built first with a .WAIT between them # and the main list to avoid needing a SUBDIR_DEPEND line on every library # naming just these few items. SUBDIR_BOOTSTRAP= \ csu \ .WAIT \ libc \ libc_nonshared \ libcompiler_rt \ ${_libclang_rt} \ ${_libcplusplus} \ ${_libcxxrt} \ libelf \ msun # The main list; please keep these sorted alphabetically. SUBDIR= ${SUBDIR_BOOTSTRAP} \ .WAIT \ geom \ libalias \ libarchive \ libauditd \ libbegemot \ libblocksruntime \ libbsdstat \ libbsm \ libbz2 \ libcalendar \ libcam \ libcapsicum \ libcasper \ libcompat \ libcrypt \ libdevctl \ libdevinfo \ libdevstat \ libdl \ libdwarf \ libedit \ libelftc \ libevent \ libexecinfo \ libexpat \ libfetch \ libfigpar \ libgeom \ libifconfig \ libipsec \ libjail \ libkiconv \ libkvm \ liblzma \ libmemstat \ libmd \ libmt \ lib80211 \ libnetbsd \ libnv \ libopenbsd \ libopie \ libpam \ libpathconv \ libpcap \ libpjdlog \ ${_libproc} \ libprocstat \ libregex \ librpcsvc \ librss \ librt \ ${_librtld_db} \ libsbuf \ libsmb \ libsqlite3 \ libstdbuf \ libstdthreads \ libsysdecode \ libtacplus \ libthread_db \ libucl \ libufs \ libugidfw \ libulog \ libutil \ ${_libvgl} \ libwrap \ libxo \ liby \ libz \ libzstd \ ncurses # Inter-library dependencies. When the makefile for a library contains LDADD # libraries, those libraries should be listed as build order dependencies here. SUBDIR_DEPEND_geom= libufs SUBDIR_DEPEND_libarchive= libz libbz2 libexpat liblzma libmd SUBDIR_DEPEND_libauditdm= libbsm SUBDIR_DEPEND_libbsnmp= ${_libnetgraph} SUBDIR_DEPEND_libc++:= libcxxrt SUBDIR_DEPEND_libc= libcompiler_rt SUBDIR_DEPEND_libcam= libsbuf SUBDIR_DEPEND_libcasper= libnv SUBDIR_DEPEND_libdevstat= libkvm SUBDIR_DEPEND_libdpv= libfigpar ncurses libutil SUBDIR_DEPEND_libedit= ncurses SUBDIR_DEPEND_libgeom= libexpat libsbuf SUBDIR_DEPEND_librpcsec_gss= libgssapi SUBDIR_DEPEND_libmagic= libz SUBDIR_DEPEND_libmemstat= libkvm SUBDIR_DEPEND_libopie= libmd SUBDIR_DEPEND_libpam= libcrypt libopie ${_libradius} librpcsvc libtacplus libutil ${_libypclnt} ${_libcom_err} SUBDIR_DEPEND_libpjdlog= libutil SUBDIR_DEPEND_libprocstat= libkvm libutil SUBDIR_DEPEND_libradius= libmd SUBDIR_DEPEND_libsmb= libkiconv SUBDIR_DEPEND_libtacplus= libmd SUBDIR_DEPEND_libulog= libmd SUBDIR_DEPEND_libunbound= ${_libldns} SUBDIR_DEPEND_liblzma= ${_libthr} .if ${MK_OFED} != "no" SUBDIR_DEPEND_libpcap= ofed .endif # NB: keep these sorted by MK_* knobs SUBDIR.${MK_ATM}+= libngatm SUBDIR.${MK_BEARSSL}+= libbearssl libsecureboot SUBDIR.${MK_BLACKLIST}+=libblacklist SUBDIR.${MK_BLUETOOTH}+=libbluetooth libsdp SUBDIR.${MK_BSNMP}+= libbsnmp .if !defined(COMPAT_32BIT) && !defined(COMPAT_SOFTFP) SUBDIR.${MK_CLANG}+= clang .endif SUBDIR.${MK_CUSE}+= libcuse SUBDIR.${MK_CXX}+= libdevdctl SUBDIR.${MK_TOOLCHAIN}+=libpe SUBDIR.${MK_DIALOG}+= libdpv SUBDIR.${MK_FILE}+= libmagic SUBDIR.${MK_GPIO}+= libgpio SUBDIR.${MK_GSSAPI}+= libgssapi librpcsec_gss SUBDIR.${MK_ICONV}+= libiconv_modules SUBDIR.${MK_KERBEROS_SUPPORT}+= libcom_err SUBDIR.${MK_LDNS}+= libldns # The libraries under libclang_rt can only be built by clang, and only make # sense to build when clang is enabled at all. Furthermore, they can only be # built for certain architectures. .if ${MK_CLANG} != "no" && ${COMPILER_TYPE} == "clang" && \ (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "i386") _libclang_rt= libclang_rt .endif .if ${MK_LIBCPLUSPLUS} != "no" _libcxxrt= libcxxrt _libcplusplus= libc++ _libcplusplus+= libc++experimental _libcplusplus+= libc++fs .endif SUBDIR.${MK_EFI}+= libefivar SUBDIR.${MK_GOOGLETEST}+= googletest SUBDIR.${MK_LIBTHR}+= libthr SUBDIR.${MK_LLVM_LIBUNWIND}+= libgcc_eh SUBDIR.${MK_LLVM_LIBUNWIND}+= libgcc_s -SUBDIR.${MK_NAND}+= libnandfs SUBDIR.${MK_NETGRAPH}+= libnetgraph SUBDIR.${MK_NIS}+= libypclnt .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _libvgl= libvgl .endif .if ${MACHINE_CPUARCH} == "aarch64" SUBDIR.${MK_PMC}+= libopencsd .endif .if ${MACHINE_CPUARCH} == "amd64" SUBDIR.${MK_PMC}+= libipt SUBDIR.${MK_BHYVE}+= libvmmapi .endif .if ${MACHINE_CPUARCH} != "sparc64" _libproc= libproc _librtld_db= librtld_db .endif SUBDIR.${MK_OPENMP}+= libomp SUBDIR.${MK_OPENSSL}+= libmp SUBDIR.${MK_PMC}+= libpmc libpmcstat SUBDIR.${MK_RADIUS_SUPPORT}+= libradius SUBDIR.${MK_SENDMAIL}+= libmilter libsm libsmdb libsmutil SUBDIR.${MK_TELNET}+= libtelnet SUBDIR.${MK_TESTS_SUPPORT}+= atf SUBDIR.${MK_TESTS}+= tests SUBDIR.${MK_UNBOUND}+= libunbound SUBDIR.${MK_USB}+= libusbhid libusb SUBDIR.${MK_OFED}+= ofed SUBDIR.${MK_VERIEXEC}+= libveriexec SUBDIR.${MK_ZFS}+= libbe .if !make(install) SUBDIR_PARALLEL= .endif .include Index: head/lib/libnandfs/nandfs.c =================================================================== --- head/lib/libnandfs/nandfs.c (revision 349351) +++ head/lib/libnandfs/nandfs.c (nonexistent) @@ -1,249 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define NANDFS_IS_VALID 0x1 -#define NANDFS_IS_OPENED 0x2 -#define NANDFS_IS_OPENED_DEV 0x4 -#define NANDFS_IS_ERROR 0x8 - -#define DEBUG -#undef DEBUG -#ifdef DEBUG -#define NANDFS_DEBUG(fmt, args...) do { \ - printf("libnandfs:" fmt "\n", ##args); } while (0) -#else -#define NANDFS_DEBUG(fmt, args...) -#endif - -#define NANDFS_ASSERT_VALID(fs) assert((fs)->n_flags & NANDFS_IS_VALID) -#define NANDFS_ASSERT_VALID_DEV(fs) \ - assert(((fs)->n_flags & (NANDFS_IS_VALID | NANDFS_IS_OPENED_DEV)) == \ - (NANDFS_IS_VALID | NANDFS_IS_OPENED_DEV)) - -int -nandfs_iserror(struct nandfs *fs) -{ - - NANDFS_ASSERT_VALID(fs); - - return (fs->n_flags & NANDFS_IS_ERROR); -} - -const char * -nandfs_errmsg(struct nandfs *fs) -{ - - NANDFS_ASSERT_VALID(fs); - - assert(nandfs_iserror(fs)); - assert(fs->n_errmsg); - return (fs->n_errmsg); -} - -static void -nandfs_seterr(struct nandfs *fs, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vsnprintf(fs->n_errmsg, sizeof(fs->n_errmsg), fmt, ap); - va_end(ap); - fs->n_flags |= NANDFS_IS_ERROR; -} - -const char * -nandfs_dev(struct nandfs *fs) -{ - - NANDFS_ASSERT_VALID(fs); - return (fs->n_dev); -} - -void -nandfs_init(struct nandfs *fs, const char *dir) -{ - - snprintf(fs->n_ioc, sizeof(fs->n_ioc), "%s/%s", dir, "."); - fs->n_iocfd = -1; - fs->n_flags = NANDFS_IS_VALID; -} - -void -nandfs_destroy(struct nandfs *fs) -{ - - assert(fs->n_iocfd == -1); - fs->n_flags &= - ~(NANDFS_IS_ERROR | NANDFS_IS_VALID); - assert(fs->n_flags == 0); -} - -int -nandfs_open(struct nandfs *fs) -{ - struct nandfs_fsinfo fsinfo; - - fs->n_flags |= NANDFS_IS_OPENED; - - fs->n_iocfd = open(fs->n_ioc, O_RDONLY, S_IRUSR | S_IWUSR | S_IRGRP | - S_IWGRP | S_IROTH | S_IWOTH); - if (fs->n_iocfd == -1) { - nandfs_seterr(fs, "couldn't open %s: %s", fs->n_ioc, - strerror(errno)); - return (-1); - } - - if (ioctl(fs->n_iocfd, NANDFS_IOCTL_GET_FSINFO, &fsinfo) == -1) { - nandfs_seterr(fs, "couldn't fetch fsinfo: %s", - strerror(errno)); - return (-1); - } - - memcpy(&fs->n_fsdata, &fsinfo.fs_fsdata, sizeof(fs->n_fsdata)); - memcpy(&fs->n_sb, &fsinfo.fs_super, sizeof(fs->n_sb)); - snprintf(fs->n_dev, sizeof(fs->n_dev), "%s", fsinfo.fs_dev); - - return (0); -} - -void -nandfs_close(struct nandfs *fs) -{ - - NANDFS_ASSERT_VALID(fs); - assert(fs->n_flags & NANDFS_IS_OPENED); - - close(fs->n_iocfd); - fs->n_iocfd = -1; - fs->n_flags &= ~NANDFS_IS_OPENED; -} - -int -nandfs_get_cpstat(struct nandfs *fs, struct nandfs_cpstat *cpstat) -{ - - NANDFS_ASSERT_VALID(fs); - - if (ioctl(fs->n_iocfd, NANDFS_IOCTL_GET_CPSTAT, cpstat) == -1) { - nandfs_seterr(fs, "ioctl NANDFS_IOCTL_GET_CPSTAT: %s", - strerror(errno)); - return (-1); - } - - return (0); -} - -static ssize_t -nandfs_get_cpinfo(struct nandfs *fs, uint64_t cno, int mode, - struct nandfs_cpinfo *cpinfo, size_t nci) -{ - struct nandfs_argv args; - - NANDFS_ASSERT_VALID(fs); - - args.nv_base = (u_long)cpinfo; - args.nv_nmembs = nci; - args.nv_index = cno; - args.nv_flags = mode; - - if (ioctl(fs->n_iocfd, NANDFS_IOCTL_GET_CPINFO, &args) == -1) { - nandfs_seterr(fs, "ioctl NANDFS_IOCTL_GET_CPINFO: %s", - strerror(errno)); - return (-1); - } - - return (args.nv_nmembs); -} - -ssize_t -nandfs_get_cp(struct nandfs *fs, uint64_t cno, struct nandfs_cpinfo *cpinfo, - size_t nci) -{ - - return (nandfs_get_cpinfo(fs, cno, NANDFS_CHECKPOINT, cpinfo, nci)); -} - -ssize_t -nandfs_get_snap(struct nandfs *fs, uint64_t cno, struct nandfs_cpinfo *cpinfo, - size_t nci) -{ - - return (nandfs_get_cpinfo(fs, cno, NANDFS_SNAPSHOT, cpinfo, nci)); -} - -int -nandfs_make_snap(struct nandfs *fs, uint64_t *cno) -{ - - NANDFS_ASSERT_VALID(fs); - - if (ioctl(fs->n_iocfd, NANDFS_IOCTL_MAKE_SNAP, cno) == -1) { - nandfs_seterr(fs, "ioctl NANDFS_IOCTL_MAKE_SNAP: %s", - strerror(errno)); - return (-1); - } - - return (0); -} - -int -nandfs_delete_snap(struct nandfs *fs, uint64_t cno) -{ - - NANDFS_ASSERT_VALID(fs); - - if (ioctl(fs->n_iocfd, NANDFS_IOCTL_DELETE_SNAP, &cno) == -1) { - nandfs_seterr(fs, "ioctl NANDFS_IOCTL_DELETE_SNAP: %s", - strerror(errno)); - return (-1); - } - - return (0); -} Property changes on: head/lib/libnandfs/nandfs.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/lib/libnandfs/Makefile.depend =================================================================== --- head/lib/libnandfs/Makefile.depend (revision 349351) +++ head/lib/libnandfs/Makefile.depend (nonexistent) @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Property changes on: head/lib/libnandfs/Makefile.depend ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/lib/libnandfs/libnandfs.h =================================================================== --- head/lib/libnandfs/libnandfs.h (revision 349351) +++ head/lib/libnandfs/libnandfs.h (nonexistent) @@ -1,67 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * 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 _LIBNANDFS_NANDFS_H -#define _LIBNANDFS_NANDFS_H - -struct nandfs { - struct nandfs_fsdata n_fsdata; - struct nandfs_super_block n_sb; - char n_ioc[MNAMELEN]; - char n_dev[MNAMELEN]; - int n_iocfd; - int n_devfd; - int n_flags; - char n_errmsg[120]; -}; - -int nandfs_iserror(struct nandfs *); -const char *nandfs_errmsg(struct nandfs *); - -void nandfs_init(struct nandfs *, const char *); -void nandfs_destroy(struct nandfs *); - -const char *nandfs_dev(struct nandfs *); - -int nandfs_open(struct nandfs *); -void nandfs_close(struct nandfs *); - -int nandfs_get_cpstat(struct nandfs *, struct nandfs_cpstat *); - -ssize_t nandfs_get_cp(struct nandfs *, uint64_t, - struct nandfs_cpinfo *, size_t); - -ssize_t nandfs_get_snap(struct nandfs *, uint64_t, - struct nandfs_cpinfo *, size_t); - -int nandfs_make_snap(struct nandfs *, uint64_t *); -int nandfs_delete_snap(struct nandfs *, uint64_t); - -#endif /* _LIBNANDFS_NANDFS_H */ Property changes on: head/lib/libnandfs/libnandfs.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/lib/libnandfs/Makefile =================================================================== --- head/lib/libnandfs/Makefile (revision 349351) +++ head/lib/libnandfs/Makefile (nonexistent) @@ -1,10 +0,0 @@ -# $FreeBSD$ - -PACKAGE=lib${LIB} -LIB= nandfs -SRCS+= nandfs.c -INCS= libnandfs.h - -CFLAGS += -I${.CURDIR} - -.include Property changes on: head/lib/libnandfs/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/Makefile =================================================================== --- head/sbin/Makefile (revision 349351) +++ head/sbin/Makefile (revision 349352) @@ -1,100 +1,98 @@ # @(#)Makefile 8.5 (Berkeley) 3/31/94 # $FreeBSD$ .include SUBDIR=adjkerntz \ camcontrol \ clri \ comcontrol \ conscontrol \ ddb \ devfs \ devmatch \ dhclient \ dmesg \ dump \ dumpfs \ dumpon \ etherswitchcfg \ ffsinfo \ fsck \ fsck_ffs \ fsck_msdosfs \ fsdb \ fsirand \ gbde \ geom \ ggate \ growfs \ gvinum \ ifconfig \ init \ kldconfig \ kldload \ kldstat \ kldunload \ ldconfig \ md5 \ mdconfig \ mdmfs \ mknod \ mksnap_ffs \ mount \ mount_cd9660 \ mount_fusefs \ mount_msdosfs \ mount_nfs \ mount_nullfs \ mount_udf \ mount_unionfs \ newfs \ newfs_msdos \ nfsiod \ nos-tun \ pfilctl \ ping \ rcorder \ reboot \ recoverdisk \ resolvconf \ restore \ route \ savecore \ setkey \ shutdown \ spppcontrol \ swapon \ sysctl \ tunefs \ umount SUBDIR.${MK_CCD}+= ccdconfig SUBDIR.${MK_CXX}+= devd SUBDIR.${MK_HAST}+= hastctl SUBDIR.${MK_HAST}+= hastd SUBDIR.${MK_INET6}+= ping6 SUBDIR.${MK_INET6}+= rtsol SUBDIR.${MK_IPFILTER}+= ipf SUBDIR.${MK_IPFW}+= ipfw SUBDIR.${MK_IPFW}+= natd SUBDIR.${MK_ISCSI}+= iscontrol -SUBDIR.${MK_NAND}+= nandfs -SUBDIR.${MK_NAND}+= newfs_nandfs SUBDIR.${MK_NVME}+= nvmecontrol SUBDIR.${MK_OPENSSL}+= decryptcore SUBDIR.${MK_PF}+= pfctl SUBDIR.${MK_PF}+= pflogd SUBDIR.${MK_QUOTAS}+= quotacheck SUBDIR.${MK_ROUTED}+= routed SUBDIR.${MK_VERIEXEC}+= veriexec SUBDIR.${MK_ZFS}+= bectl SUBDIR.${MK_ZFS}+= zfsbootcfg SUBDIR.${MK_TESTS}+= tests .include SUBDIR_PARALLEL= .include Index: head/sbin/camcontrol/camcontrol.c =================================================================== --- head/sbin/camcontrol/camcontrol.c (revision 349351) +++ head/sbin/camcontrol/camcontrol.c (revision 349352) @@ -1,10324 +1,10342 @@ /* * Copyright (c) 1997-2007 Kenneth D. Merry * 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef MINIMALISTIC #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "camcontrol.h" #ifdef WITH_NVME #include "nvmecontrol_ext.h" #endif typedef enum { CAM_CMD_NONE = 0x00000000, CAM_CMD_DEVLIST = 0x00000001, CAM_CMD_TUR = 0x00000002, CAM_CMD_INQUIRY = 0x00000003, CAM_CMD_STARTSTOP = 0x00000004, CAM_CMD_RESCAN = 0x00000005, CAM_CMD_READ_DEFECTS = 0x00000006, CAM_CMD_MODE_PAGE = 0x00000007, CAM_CMD_SCSI_CMD = 0x00000008, CAM_CMD_DEVTREE = 0x00000009, CAM_CMD_USAGE = 0x0000000a, CAM_CMD_DEBUG = 0x0000000b, CAM_CMD_RESET = 0x0000000c, CAM_CMD_FORMAT = 0x0000000d, CAM_CMD_TAG = 0x0000000e, CAM_CMD_RATE = 0x0000000f, CAM_CMD_DETACH = 0x00000010, CAM_CMD_REPORTLUNS = 0x00000011, CAM_CMD_READCAP = 0x00000012, CAM_CMD_IDENTIFY = 0x00000013, CAM_CMD_IDLE = 0x00000014, CAM_CMD_STANDBY = 0x00000015, CAM_CMD_SLEEP = 0x00000016, CAM_CMD_SMP_CMD = 0x00000017, CAM_CMD_SMP_RG = 0x00000018, CAM_CMD_SMP_PC = 0x00000019, CAM_CMD_SMP_PHYLIST = 0x0000001a, CAM_CMD_SMP_MANINFO = 0x0000001b, CAM_CMD_DOWNLOAD_FW = 0x0000001c, CAM_CMD_SECURITY = 0x0000001d, CAM_CMD_HPA = 0x0000001e, CAM_CMD_SANITIZE = 0x0000001f, CAM_CMD_PERSIST = 0x00000020, CAM_CMD_APM = 0x00000021, CAM_CMD_AAM = 0x00000022, CAM_CMD_ATTRIB = 0x00000023, CAM_CMD_OPCODES = 0x00000024, CAM_CMD_REPROBE = 0x00000025, CAM_CMD_ZONE = 0x00000026, CAM_CMD_EPC = 0x00000027, CAM_CMD_TIMESTAMP = 0x00000028, CAM_CMD_MMCSD_CMD = 0x00000029, CAM_CMD_POWER_MODE = 0x0000002a, } cam_cmdmask; typedef enum { CAM_ARG_NONE = 0x00000000, CAM_ARG_VERBOSE = 0x00000001, CAM_ARG_DEVICE = 0x00000002, CAM_ARG_BUS = 0x00000004, CAM_ARG_TARGET = 0x00000008, CAM_ARG_LUN = 0x00000010, CAM_ARG_EJECT = 0x00000020, CAM_ARG_UNIT = 0x00000040, CAM_ARG_FORMAT_BLOCK = 0x00000080, CAM_ARG_FORMAT_BFI = 0x00000100, CAM_ARG_FORMAT_PHYS = 0x00000200, CAM_ARG_PLIST = 0x00000400, CAM_ARG_GLIST = 0x00000800, CAM_ARG_GET_SERIAL = 0x00001000, CAM_ARG_GET_STDINQ = 0x00002000, CAM_ARG_GET_XFERRATE = 0x00004000, CAM_ARG_INQ_MASK = 0x00007000, CAM_ARG_TIMEOUT = 0x00020000, CAM_ARG_CMD_IN = 0x00040000, CAM_ARG_CMD_OUT = 0x00080000, CAM_ARG_ERR_RECOVER = 0x00200000, CAM_ARG_RETRIES = 0x00400000, CAM_ARG_START_UNIT = 0x00800000, CAM_ARG_DEBUG_INFO = 0x01000000, CAM_ARG_DEBUG_TRACE = 0x02000000, CAM_ARG_DEBUG_SUBTRACE = 0x04000000, CAM_ARG_DEBUG_CDB = 0x08000000, CAM_ARG_DEBUG_XPT = 0x10000000, CAM_ARG_DEBUG_PERIPH = 0x20000000, CAM_ARG_DEBUG_PROBE = 0x40000000, } cam_argmask; struct camcontrol_opts { const char *optname; uint32_t cmdnum; cam_argmask argnum; const char *subopt; }; #ifndef MINIMALISTIC struct ata_res_pass16 { u_int16_t reserved[5]; u_int8_t flags; u_int8_t error; u_int8_t sector_count_exp; u_int8_t sector_count; u_int8_t lba_low_exp; u_int8_t lba_low; u_int8_t lba_mid_exp; u_int8_t lba_mid; u_int8_t lba_high_exp; u_int8_t lba_high; u_int8_t device; u_int8_t status; }; struct ata_set_max_pwd { u_int16_t reserved1; u_int8_t password[32]; u_int16_t reserved2[239]; }; static struct scsi_nv task_attrs[] = { { "simple", MSG_SIMPLE_Q_TAG }, { "head", MSG_HEAD_OF_Q_TAG }, { "ordered", MSG_ORDERED_Q_TAG }, { "iwr", MSG_IGN_WIDE_RESIDUE }, { "aca", MSG_ACA_TASK } }; static const char scsicmd_opts[] = "a:c:dfi:o:r"; static const char readdefect_opts[] = "f:GPqsS:X"; static const char negotiate_opts[] = "acD:M:O:qR:T:UW:"; static const char smprg_opts[] = "l"; static const char smppc_opts[] = "a:A:d:lm:M:o:p:s:S:T:"; static const char smpphylist_opts[] = "lq"; static char pwd_opt; #endif static struct camcontrol_opts option_table[] = { #ifndef MINIMALISTIC {"tur", CAM_CMD_TUR, CAM_ARG_NONE, NULL}, {"inquiry", CAM_CMD_INQUIRY, CAM_ARG_NONE, "DSR"}, {"identify", CAM_CMD_IDENTIFY, CAM_ARG_NONE, NULL}, {"start", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT, NULL}, {"stop", CAM_CMD_STARTSTOP, CAM_ARG_NONE, NULL}, {"load", CAM_CMD_STARTSTOP, CAM_ARG_START_UNIT | CAM_ARG_EJECT, NULL}, {"eject", CAM_CMD_STARTSTOP, CAM_ARG_EJECT, NULL}, {"reportluns", CAM_CMD_REPORTLUNS, CAM_ARG_NONE, "clr:"}, {"readcapacity", CAM_CMD_READCAP, CAM_ARG_NONE, "bhHlNqs"}, {"reprobe", CAM_CMD_REPROBE, CAM_ARG_NONE, NULL}, #endif /* MINIMALISTIC */ {"rescan", CAM_CMD_RESCAN, CAM_ARG_NONE, NULL}, {"reset", CAM_CMD_RESET, CAM_ARG_NONE, NULL}, #ifndef MINIMALISTIC {"cmd", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, {"mmcsdcmd", CAM_CMD_MMCSD_CMD, CAM_ARG_NONE, "c:a:f:Wb:l:41S:I"}, {"command", CAM_CMD_SCSI_CMD, CAM_ARG_NONE, scsicmd_opts}, {"smpcmd", CAM_CMD_SMP_CMD, CAM_ARG_NONE, "r:R:"}, {"smprg", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, {"smpreportgeneral", CAM_CMD_SMP_RG, CAM_ARG_NONE, smprg_opts}, {"smppc", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts}, {"smpphycontrol", CAM_CMD_SMP_PC, CAM_ARG_NONE, smppc_opts}, {"smpplist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts}, {"smpphylist", CAM_CMD_SMP_PHYLIST, CAM_ARG_NONE, smpphylist_opts}, {"smpmaninfo", CAM_CMD_SMP_MANINFO, CAM_ARG_NONE, "l"}, {"defects", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, {"defectlist", CAM_CMD_READ_DEFECTS, CAM_ARG_NONE, readdefect_opts}, #endif /* MINIMALISTIC */ {"devlist", CAM_CMD_DEVTREE, CAM_ARG_NONE, "-b"}, #ifndef MINIMALISTIC {"periphlist", CAM_CMD_DEVLIST, CAM_ARG_NONE, NULL}, {"modepage", CAM_CMD_MODE_PAGE, CAM_ARG_NONE, "bdelm:P:"}, {"tags", CAM_CMD_TAG, CAM_ARG_NONE, "N:q"}, {"negotiate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, {"rate", CAM_CMD_RATE, CAM_ARG_NONE, negotiate_opts}, {"debug", CAM_CMD_DEBUG, CAM_ARG_NONE, "IPTSXcp"}, {"format", CAM_CMD_FORMAT, CAM_ARG_NONE, "qrwy"}, {"sanitize", CAM_CMD_SANITIZE, CAM_ARG_NONE, "a:c:IP:qrUwy"}, {"idle", CAM_CMD_IDLE, CAM_ARG_NONE, "t:"}, {"standby", CAM_CMD_STANDBY, CAM_ARG_NONE, "t:"}, {"sleep", CAM_CMD_SLEEP, CAM_ARG_NONE, ""}, {"powermode", CAM_CMD_POWER_MODE, CAM_ARG_NONE, ""}, {"apm", CAM_CMD_APM, CAM_ARG_NONE, "l:"}, {"aam", CAM_CMD_AAM, CAM_ARG_NONE, "l:"}, {"fwdownload", CAM_CMD_DOWNLOAD_FW, CAM_ARG_NONE, "f:qsy"}, {"security", CAM_CMD_SECURITY, CAM_ARG_NONE, "d:e:fh:k:l:qs:T:U:y"}, {"hpa", CAM_CMD_HPA, CAM_ARG_NONE, "Pflp:qs:U:y"}, {"persist", CAM_CMD_PERSIST, CAM_ARG_NONE, "ai:I:k:K:o:ps:ST:U"}, {"attrib", CAM_CMD_ATTRIB, CAM_ARG_NONE, "a:ce:F:p:r:s:T:w:V:"}, {"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"}, {"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"}, {"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"}, {"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"}, #endif /* MINIMALISTIC */ {"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, {"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, {"-h", CAM_CMD_USAGE, CAM_ARG_NONE, NULL}, {NULL, 0, 0, NULL} }; struct cam_devitem { struct device_match_result dev_match; int num_periphs; struct periph_match_result *periph_matches; struct scsi_vpd_device_id *device_id; int device_id_len; STAILQ_ENTRY(cam_devitem) links; }; struct cam_devlist { STAILQ_HEAD(, cam_devitem) dev_queue; path_id_t path_id; }; static cam_cmdmask cmdlist; static cam_argmask arglist; camcontrol_optret getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum, cam_argmask *argnum, const char **subopt); #ifndef MINIMALISTIC static int getdevlist(struct cam_device *device); #endif /* MINIMALISTIC */ static int getdevtree(int argc, char **argv, char *combinedopt); static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr); static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr); static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr); static int print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr); #ifdef WITH_NVME static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr); #endif #ifndef MINIMALISTIC static int testunitready(struct cam_device *device, int task_attr, int retry_count, int timeout, int quiet); static int scsistart(struct cam_device *device, int startstop, int loadeject, int task_attr, int retry_count, int timeout); static int scsiinquiry(struct cam_device *device, int task_attr, int retry_count, int timeout); static int scsiserial(struct cam_device *device, int task_attr, int retry_count, int timeout); #endif /* MINIMALISTIC */ static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun, cam_argmask *arglst); static int dorescan_or_reset(int argc, char **argv, int rescan); static int rescan_or_reset_bus(path_id_t bus, int rescan); static int scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan); #ifndef MINIMALISTIC static int readdefects(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static void modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static int scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static int smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int smpreportgeneral(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int smpphycontrol(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int smpmaninfo(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int getdevid(struct cam_devitem *item); static int buildbusdevlist(struct cam_devlist *devlist); static void freebusdevlist(struct cam_devlist *devlist); static struct cam_devitem *findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr); static int smpphylist(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int tagcontrol(struct cam_device *device, int argc, char **argv, char *combinedopt); static void cts_print(struct cam_device *device, struct ccb_trans_settings *cts); static void cpi_print(struct ccb_pathinq *cpi); static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi); static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd); static int get_print_cts(struct cam_device *device, int user_settings, int quiet, struct ccb_trans_settings *cts); static int ratecontrol(struct cam_device *device, int task_attr, int retry_count, int timeout, int argc, char **argv, char *combinedopt); static int scsiformat(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static int scsisanitize(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static int scsireportluns(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static int scsireadcapacity(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout); static int atapm(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout); static int atasecurity(struct cam_device *device, int retry_count, int timeout, int argc, char **argv, char *combinedopt); static int atahpa(struct cam_device *device, int retry_count, int timeout, int argc, char **argv, char *combinedopt); static int scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set, int req_sa, uint8_t *buf, uint32_t valid_len); static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf, uint32_t valid_len); static int scsiopcodes(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout, int verbose); static int scsireprobe(struct cam_device *device); #endif /* MINIMALISTIC */ #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #ifndef max #define max(a,b) (((a)>(b))?(a):(b)) #endif camcontrol_optret getoption(struct camcontrol_opts *table, char *arg, uint32_t *cmdnum, cam_argmask *argnum, const char **subopt) { struct camcontrol_opts *opts; int num_matches = 0; for (opts = table; (opts != NULL) && (opts->optname != NULL); opts++) { if (strncmp(opts->optname, arg, strlen(arg)) == 0) { *cmdnum = opts->cmdnum; *argnum = opts->argnum; *subopt = opts->subopt; if (++num_matches > 1) return (CC_OR_AMBIGUOUS); } } if (num_matches > 0) return (CC_OR_FOUND); else return (CC_OR_NOT_FOUND); } #ifndef MINIMALISTIC static int getdevlist(struct cam_device *device) { union ccb *ccb; char status[32]; int error = 0; ccb = cam_getccb(device); ccb->ccb_h.func_code = XPT_GDEVLIST; ccb->ccb_h.flags = CAM_DIR_NONE; ccb->ccb_h.retry_count = 1; ccb->cgdl.index = 0; ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS; while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) { if (cam_send_ccb(device, ccb) < 0) { perror("error getting device list"); cam_freeccb(ccb); return (1); } status[0] = '\0'; switch (ccb->cgdl.status) { case CAM_GDEVLIST_MORE_DEVS: strcpy(status, "MORE"); break; case CAM_GDEVLIST_LAST_DEVICE: strcpy(status, "LAST"); break; case CAM_GDEVLIST_LIST_CHANGED: strcpy(status, "CHANGED"); break; case CAM_GDEVLIST_ERROR: strcpy(status, "ERROR"); error = 1; break; } fprintf(stdout, "%s%d: generation: %d index: %d status: %s\n", ccb->cgdl.periph_name, ccb->cgdl.unit_number, ccb->cgdl.generation, ccb->cgdl.index, status); /* * If the list has changed, we need to start over from the * beginning. */ if (ccb->cgdl.status == CAM_GDEVLIST_LIST_CHANGED) ccb->cgdl.index = 0; } cam_freeccb(ccb); return (error); } #endif /* MINIMALISTIC */ static int getdevtree(int argc, char **argv, char *combinedopt) { union ccb ccb; int bufsize, fd; unsigned int i; int need_close = 0; int error = 0; int skip_device = 0; int busonly = 0; int c; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'b': if ((arglist & CAM_ARG_VERBOSE) == 0) busonly = 1; break; default: break; } } if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { warn("couldn't open %s", XPT_DEVICE); return (1); } bzero(&ccb, sizeof(union ccb)); ccb.ccb_h.path_id = CAM_XPT_PATH_ID; ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; ccb.ccb_h.func_code = XPT_DEV_MATCH; bufsize = sizeof(struct dev_match_result) * 100; ccb.cdm.match_buf_len = bufsize; ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); if (ccb.cdm.matches == NULL) { warnx("can't malloc memory for matches"); close(fd); return (1); } ccb.cdm.num_matches = 0; /* * We fetch all nodes, since we display most of them in the default * case, and all in the verbose case. */ ccb.cdm.num_patterns = 0; ccb.cdm.pattern_buf_len = 0; /* * We do the ioctl multiple times if necessary, in case there are * more than 100 nodes in the EDT. */ do { if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { warn("error sending CAMIOCOMMAND ioctl"); error = 1; break; } if ((ccb.ccb_h.status != CAM_REQ_CMP) || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { warnx("got CAM error %#x, CDM error %d\n", ccb.ccb_h.status, ccb.cdm.status); error = 1; break; } for (i = 0; i < ccb.cdm.num_matches; i++) { switch (ccb.cdm.matches[i].type) { case DEV_MATCH_BUS: { struct bus_match_result *bus_result; /* * Only print the bus information if the * user turns on the verbose flag. */ if ((busonly == 0) && (arglist & CAM_ARG_VERBOSE) == 0) break; bus_result = &ccb.cdm.matches[i].result.bus_result; if (need_close) { fprintf(stdout, ")\n"); need_close = 0; } fprintf(stdout, "scbus%d on %s%d bus %d%s\n", bus_result->path_id, bus_result->dev_name, bus_result->unit_number, bus_result->bus_id, (busonly ? "" : ":")); break; } case DEV_MATCH_DEVICE: { struct device_match_result *dev_result; char tmpstr[256]; if (busonly == 1) break; dev_result = &ccb.cdm.matches[i].result.device_result; if ((dev_result->flags & DEV_RESULT_UNCONFIGURED) && ((arglist & CAM_ARG_VERBOSE) == 0)) { skip_device = 1; break; } else skip_device = 0; if (dev_result->protocol == PROTO_SCSI) { if (print_dev_scsi(dev_result, &tmpstr[0]) != 0) { skip_device = 1; break; } } else if (dev_result->protocol == PROTO_ATA || dev_result->protocol == PROTO_SATAPM) { if (print_dev_ata(dev_result, &tmpstr[0]) != 0) { skip_device = 1; break; } } else if (dev_result->protocol == PROTO_MMCSD){ if (print_dev_mmcsd(dev_result, &tmpstr[0]) != 0) { skip_device = 1; break; } } else if (dev_result->protocol == PROTO_SEMB) { if (print_dev_semb(dev_result, &tmpstr[0]) != 0) { skip_device = 1; break; } #ifdef WITH_NVME } else if (dev_result->protocol == PROTO_NVME) { if (print_dev_nvme(dev_result, &tmpstr[0]) != 0) { skip_device = 1; break; } #endif } else { sprintf(tmpstr, "<>"); } if (need_close) { fprintf(stdout, ")\n"); need_close = 0; } fprintf(stdout, "%-33s at scbus%d " "target %d lun %jx (", tmpstr, dev_result->path_id, dev_result->target_id, (uintmax_t)dev_result->target_lun); need_close = 1; break; } case DEV_MATCH_PERIPH: { struct periph_match_result *periph_result; periph_result = &ccb.cdm.matches[i].result.periph_result; if (busonly || skip_device != 0) break; if (need_close > 1) fprintf(stdout, ","); fprintf(stdout, "%s%d", periph_result->periph_name, periph_result->unit_number); need_close++; break; } default: fprintf(stdout, "unknown match type\n"); break; } } } while ((ccb.ccb_h.status == CAM_REQ_CMP) && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); if (need_close) fprintf(stdout, ")\n"); close(fd); return (error); } static int print_dev_scsi(struct device_match_result *dev_result, char *tmpstr) { char vendor[16], product[48], revision[16]; cam_strvis(vendor, dev_result->inq_data.vendor, sizeof(dev_result->inq_data.vendor), sizeof(vendor)); cam_strvis(product, dev_result->inq_data.product, sizeof(dev_result->inq_data.product), sizeof(product)); cam_strvis(revision, dev_result->inq_data.revision, sizeof(dev_result->inq_data.revision), sizeof(revision)); sprintf(tmpstr, "<%s %s %s>", vendor, product, revision); return (0); } static int print_dev_ata(struct device_match_result *dev_result, char *tmpstr) { char product[48], revision[16]; cam_strvis(product, dev_result->ident_data.model, sizeof(dev_result->ident_data.model), sizeof(product)); cam_strvis(revision, dev_result->ident_data.revision, sizeof(dev_result->ident_data.revision), sizeof(revision)); sprintf(tmpstr, "<%s %s>", product, revision); return (0); } static int print_dev_semb(struct device_match_result *dev_result, char *tmpstr) { struct sep_identify_data *sid; char vendor[16], product[48], revision[16], fw[5]; sid = (struct sep_identify_data *)&dev_result->ident_data; cam_strvis(vendor, sid->vendor_id, sizeof(sid->vendor_id), sizeof(vendor)); cam_strvis(product, sid->product_id, sizeof(sid->product_id), sizeof(product)); cam_strvis(revision, sid->product_rev, sizeof(sid->product_rev), sizeof(revision)); cam_strvis(fw, sid->firmware_rev, sizeof(sid->firmware_rev), sizeof(fw)); sprintf(tmpstr, "<%s %s %s %s>", vendor, product, revision, fw); return (0); } static int print_dev_mmcsd(struct device_match_result *dev_result, char *tmpstr) { union ccb *ccb; struct ccb_dev_advinfo *advi; struct cam_device *dev; struct mmc_params mmc_ident_data; dev = cam_open_btl(dev_result->path_id, dev_result->target_id, dev_result->target_lun, O_RDWR, NULL); if (dev == NULL) { warnx("%s", cam_errbuf); return (1); } ccb = cam_getccb(dev); if (ccb == NULL) { warnx("couldn't allocate CCB"); cam_close_device(dev); return (1); } advi = &ccb->cdai; advi->ccb_h.flags = CAM_DIR_IN; advi->ccb_h.func_code = XPT_DEV_ADVINFO; advi->flags = CDAI_FLAG_NONE; advi->buftype = CDAI_TYPE_MMC_PARAMS; advi->bufsiz = sizeof(struct mmc_params); advi->buf = (uint8_t *)&mmc_ident_data; if (cam_send_ccb(dev, ccb) < 0) { warn("error sending CAMIOCOMMAND ioctl"); cam_freeccb(ccb); cam_close_device(dev); return (1); } if (strlen(mmc_ident_data.model) > 0) { sprintf(tmpstr, "<%s>", mmc_ident_data.model); } else { sprintf(tmpstr, "<%s card>", mmc_ident_data.card_features & CARD_FEATURE_SDIO ? "SDIO" : "unknown"); } cam_freeccb(ccb); cam_close_device(dev); return (0); } #ifdef WITH_NVME static int nvme_get_cdata(struct cam_device *dev, struct nvme_controller_data *cdata) { union ccb *ccb; struct ccb_dev_advinfo *advi; ccb = cam_getccb(dev); if (ccb == NULL) { warnx("couldn't allocate CCB"); cam_close_device(dev); return (1); } advi = &ccb->cdai; advi->ccb_h.flags = CAM_DIR_IN; advi->ccb_h.func_code = XPT_DEV_ADVINFO; advi->flags = CDAI_FLAG_NONE; advi->buftype = CDAI_TYPE_NVME_CNTRL; advi->bufsiz = sizeof(struct nvme_controller_data); advi->buf = (uint8_t *)cdata; if (cam_send_ccb(dev, ccb) < 0) { warn("error sending CAMIOCOMMAND ioctl"); cam_freeccb(ccb); cam_close_device(dev); return(1); } if (advi->ccb_h.status != CAM_REQ_CMP) { warnx("got CAM error %#x", advi->ccb_h.status); cam_freeccb(ccb); cam_close_device(dev); return(1); } cam_freeccb(ccb); return 0; } static int print_dev_nvme(struct device_match_result *dev_result, char *tmpstr) { struct cam_device *dev; struct nvme_controller_data cdata; char vendor[64], product[64]; dev = cam_open_btl(dev_result->path_id, dev_result->target_id, dev_result->target_lun, O_RDWR, NULL); if (dev == NULL) { warnx("%s", cam_errbuf); return (1); } if (nvme_get_cdata(dev, &cdata)) return (1); cam_strvis(vendor, cdata.mn, sizeof(cdata.mn), sizeof(vendor)); cam_strvis(product, cdata.fr, sizeof(cdata.fr), sizeof(product)); sprintf(tmpstr, "<%s %s>", vendor, product); cam_close_device(dev); return (0); } #endif #ifndef MINIMALISTIC static int testunitready(struct cam_device *device, int task_attr, int retry_count, int timeout, int quiet) { int error = 0; union ccb *ccb; ccb = cam_getccb(device); scsi_test_unit_ready(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { if (quiet == 0) perror("error sending test unit ready"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } cam_freeccb(ccb); return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { if (quiet == 0) fprintf(stdout, "Unit is ready\n"); } else { if (quiet == 0) fprintf(stdout, "Unit is not ready\n"); error = 1; if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } } cam_freeccb(ccb); return (error); } static int scsistart(struct cam_device *device, int startstop, int loadeject, int task_attr, int retry_count, int timeout) { union ccb *ccb; int error = 0; ccb = cam_getccb(device); /* * If we're stopping, send an ordered tag so the drive in question * will finish any previously queued writes before stopping. If * the device isn't capable of tagged queueing, or if tagged * queueing is turned off, the tag action is a no-op. We override * the default simple tag, although this also has the effect of * overriding the user's wishes if he wanted to specify a simple * tag. */ if ((startstop == 0) && (task_attr == MSG_SIMPLE_Q_TAG)) task_attr = MSG_ORDERED_Q_TAG; scsi_start_stop(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* start/stop */ startstop, /* load_eject */ loadeject, /* immediate */ 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 120000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { perror("error sending start unit"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } cam_freeccb(ccb); return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) if (startstop) { fprintf(stdout, "Unit started successfully"); if (loadeject) fprintf(stdout,", Media loaded\n"); else fprintf(stdout,"\n"); } else { fprintf(stdout, "Unit stopped successfully"); if (loadeject) fprintf(stdout, ", Media ejected\n"); else fprintf(stdout, "\n"); } else { error = 1; if (startstop) fprintf(stdout, "Error received from start unit command\n"); else fprintf(stdout, "Error received from stop unit command\n"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } } cam_freeccb(ccb); return (error); } int scsidoinquiry(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { int c; int error = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'D': arglist |= CAM_ARG_GET_STDINQ; break; case 'R': arglist |= CAM_ARG_GET_XFERRATE; break; case 'S': arglist |= CAM_ARG_GET_SERIAL; break; default: break; } } /* * If the user didn't specify any inquiry options, he wants all of * them. */ if ((arglist & CAM_ARG_INQ_MASK) == 0) arglist |= CAM_ARG_INQ_MASK; if (arglist & CAM_ARG_GET_STDINQ) error = scsiinquiry(device, task_attr, retry_count, timeout); if (error != 0) return (error); if (arglist & CAM_ARG_GET_SERIAL) scsiserial(device, task_attr, retry_count, timeout); if (arglist & CAM_ARG_GET_XFERRATE) error = camxferrate(device); return (error); } static int scsiinquiry(struct cam_device *device, int task_attr, int retry_count, int timeout) { union ccb *ccb; struct scsi_inquiry_data *inq_buf; int error = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("couldn't allocate CCB"); return (1); } /* cam_getccb cleans up the header, caller has to zero the payload */ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); inq_buf = (struct scsi_inquiry_data *)malloc( sizeof(struct scsi_inquiry_data)); if (inq_buf == NULL) { cam_freeccb(ccb); warnx("can't malloc memory for inquiry\n"); return (1); } bzero(inq_buf, sizeof(*inq_buf)); /* * Note that although the size of the inquiry buffer is the full * 256 bytes specified in the SCSI spec, we only tell the device * that we have allocated SHORT_INQUIRY_LENGTH bytes. There are * two reasons for this: * * - The SCSI spec says that when a length field is only 1 byte, * a value of 0 will be interpreted as 256. Therefore * scsi_inquiry() will convert an inq_len (which is passed in as * a u_int32_t, but the field in the CDB is only 1 byte) of 256 * to 0. Evidently, very few devices meet the spec in that * regard. Some devices, like many Seagate disks, take the 0 as * 0, and don't return any data. One Pioneer DVD-R drive * returns more data than the command asked for. * * So, since there are numerous devices that just don't work * right with the full inquiry size, we don't send the full size. * * - The second reason not to use the full inquiry data length is * that we don't need it here. The only reason we issue a * standard inquiry is to get the vendor name, device name, * and revision so scsi_print_inquiry() can print them. * * If, at some point in the future, more inquiry data is needed for * some reason, this code should use a procedure similar to the * probe code. i.e., issue a short inquiry, and determine from * the additional length passed back from the device how much * inquiry data the device supports. Once the amount the device * supports is determined, issue an inquiry for that amount and no * more. * * KDM, 2/18/2000 */ scsi_inquiry(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* inq_buf */ (u_int8_t *)inq_buf, /* inq_len */ SHORT_INQUIRY_LENGTH, /* evpd */ 0, /* page_code */ 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { perror("error sending SCSI inquiry"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } cam_freeccb(ccb); return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { error = 1; if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } } cam_freeccb(ccb); if (error != 0) { free(inq_buf); return (error); } fprintf(stdout, "%s%d: ", device->device_name, device->dev_unit_num); scsi_print_inquiry(inq_buf); free(inq_buf); return (0); } static int scsiserial(struct cam_device *device, int task_attr, int retry_count, int timeout) { union ccb *ccb; struct scsi_vpd_unit_serial_number *serial_buf; char serial_num[SVPD_SERIAL_NUM_SIZE + 1]; int error = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("couldn't allocate CCB"); return (1); } /* cam_getccb cleans up the header, caller has to zero the payload */ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); serial_buf = (struct scsi_vpd_unit_serial_number *) malloc(sizeof(*serial_buf)); if (serial_buf == NULL) { cam_freeccb(ccb); warnx("can't malloc memory for serial number"); return (1); } scsi_inquiry(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /* tag_action */ task_attr, /* inq_buf */ (u_int8_t *)serial_buf, /* inq_len */ sizeof(*serial_buf), /* evpd */ 1, /* page_code */ SVPD_UNIT_SERIAL_NUMBER, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { warn("error getting serial number"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } cam_freeccb(ccb); free(serial_buf); return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { error = 1; if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } } cam_freeccb(ccb); if (error != 0) { free(serial_buf); return (error); } bcopy(serial_buf->serial_num, serial_num, serial_buf->length); serial_num[serial_buf->length] = '\0'; if ((arglist & CAM_ARG_GET_STDINQ) || (arglist & CAM_ARG_GET_XFERRATE)) fprintf(stdout, "%s%d: Serial Number ", device->device_name, device->dev_unit_num); fprintf(stdout, "%.60s\n", serial_num); free(serial_buf); return (0); } int camxferrate(struct cam_device *device) { struct ccb_pathinq cpi; u_int32_t freq = 0; u_int32_t speed = 0; union ccb *ccb; u_int mb; int retval = 0; if ((retval = get_cpi(device, &cpi)) != 0) return (1); ccb = cam_getccb(device); if (ccb == NULL) { warnx("couldn't allocate CCB"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char error_string[] = "error getting transfer settings"; if (retval < 0) warn(error_string); else warnx(error_string); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto xferrate_bailout; } speed = cpi.base_transfer_speed; freq = 0; if (ccb->cts.transport == XPORT_SPI) { struct ccb_trans_settings_spi *spi = &ccb->cts.xport_specific.spi; if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { freq = scsi_calc_syncsrate(spi->sync_period); speed = freq; } if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { speed *= (0x01 << spi->bus_width); } } else if (ccb->cts.transport == XPORT_FC) { struct ccb_trans_settings_fc *fc = &ccb->cts.xport_specific.fc; if (fc->valid & CTS_FC_VALID_SPEED) speed = fc->bitrate; } else if (ccb->cts.transport == XPORT_SAS) { struct ccb_trans_settings_sas *sas = &ccb->cts.xport_specific.sas; if (sas->valid & CTS_SAS_VALID_SPEED) speed = sas->bitrate; } else if (ccb->cts.transport == XPORT_ATA) { struct ccb_trans_settings_pata *pata = &ccb->cts.xport_specific.ata; if (pata->valid & CTS_ATA_VALID_MODE) speed = ata_mode2speed(pata->mode); } else if (ccb->cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &ccb->cts.xport_specific.sata; if (sata->valid & CTS_SATA_VALID_REVISION) speed = ata_revision2speed(sata->revision); } mb = speed / 1000; if (mb > 0) { fprintf(stdout, "%s%d: %d.%03dMB/s transfers", device->device_name, device->dev_unit_num, mb, speed % 1000); } else { fprintf(stdout, "%s%d: %dKB/s transfers", device->device_name, device->dev_unit_num, speed); } if (ccb->cts.transport == XPORT_SPI) { struct ccb_trans_settings_spi *spi = &ccb->cts.xport_specific.spi; if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) && (spi->sync_offset != 0)) fprintf(stdout, " (%d.%03dMHz, offset %d", freq / 1000, freq % 1000, spi->sync_offset); if (((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) && (spi->bus_width > 0)) { if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) && (spi->sync_offset != 0)) { fprintf(stdout, ", "); } else { fprintf(stdout, " ("); } fprintf(stdout, "%dbit)", 8 * (0x01 << spi->bus_width)); } else if (((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) && (spi->sync_offset != 0)) { fprintf(stdout, ")"); } } else if (ccb->cts.transport == XPORT_ATA) { struct ccb_trans_settings_pata *pata = &ccb->cts.xport_specific.ata; printf(" ("); if (pata->valid & CTS_ATA_VALID_MODE) printf("%s, ", ata_mode2string(pata->mode)); if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) printf("ATAPI %dbytes, ", pata->atapi); if (pata->valid & CTS_ATA_VALID_BYTECOUNT) printf("PIO %dbytes", pata->bytecount); printf(")"); } else if (ccb->cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &ccb->cts.xport_specific.sata; printf(" ("); if (sata->valid & CTS_SATA_VALID_REVISION) printf("SATA %d.x, ", sata->revision); else printf("SATA, "); if (sata->valid & CTS_SATA_VALID_MODE) printf("%s, ", ata_mode2string(sata->mode)); if ((sata->valid & CTS_SATA_VALID_ATAPI) && sata->atapi != 0) printf("ATAPI %dbytes, ", sata->atapi); if (sata->valid & CTS_SATA_VALID_BYTECOUNT) printf("PIO %dbytes", sata->bytecount); printf(")"); } if (ccb->cts.protocol == PROTO_SCSI) { struct ccb_trans_settings_scsi *scsi = &ccb->cts.proto_specific.scsi; if (scsi->valid & CTS_SCSI_VALID_TQ) { if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { fprintf(stdout, ", Command Queueing Enabled"); } } } fprintf(stdout, "\n"); xferrate_bailout: cam_freeccb(ccb); return (retval); } static void atahpa_print(struct ata_params *parm, u_int64_t hpasize, int header) { u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | ((u_int32_t)parm->lba_size_2 << 16); u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | ((u_int64_t)parm->lba_size48_2 << 16) | ((u_int64_t)parm->lba_size48_3 << 32) | ((u_int64_t)parm->lba_size48_4 << 48); if (header) { printf("\nFeature " "Support Enabled Value\n"); } printf("Host Protected Area (HPA) "); if (parm->support.command1 & ATA_SUPPORT_PROTECTED) { u_int64_t lba = lbasize48 ? lbasize48 : lbasize; printf("yes %s %ju/%ju\n", (hpasize > lba) ? "yes" : "no ", lba, hpasize); printf("HPA - Security "); if (parm->support.command1 & ATA_SUPPORT_MAXSECURITY) printf("yes\n"); else printf("no\n"); } else { printf("no\n"); } } static int atasata(struct ata_params *parm) { if (parm->satacapabilities != 0xffff && parm->satacapabilities != 0x0000) return 1; return 0; } static void atacapprint(struct ata_params *parm) { u_int32_t lbasize = (u_int32_t)parm->lba_size_1 | ((u_int32_t)parm->lba_size_2 << 16); u_int64_t lbasize48 = ((u_int64_t)parm->lba_size48_1) | ((u_int64_t)parm->lba_size48_2 << 16) | ((u_int64_t)parm->lba_size48_3 << 32) | ((u_int64_t)parm->lba_size48_4 << 48); printf("\n"); printf("protocol "); printf("ATA/ATAPI-%d", ata_version(parm->version_major)); if (parm->satacapabilities && parm->satacapabilities != 0xffff) { if (parm->satacapabilities & ATA_SATA_GEN3) printf(" SATA 3.x\n"); else if (parm->satacapabilities & ATA_SATA_GEN2) printf(" SATA 2.x\n"); else if (parm->satacapabilities & ATA_SATA_GEN1) printf(" SATA 1.x\n"); else printf(" SATA\n"); } else printf("\n"); printf("device model %.40s\n", parm->model); printf("firmware revision %.8s\n", parm->revision); printf("serial number %.20s\n", parm->serial); if (parm->enabled.extension & ATA_SUPPORT_64BITWWN) { printf("WWN %04x%04x%04x%04x\n", parm->wwn[0], parm->wwn[1], parm->wwn[2], parm->wwn[3]); } if (parm->enabled.extension & ATA_SUPPORT_MEDIASN) { printf("media serial number %.30s\n", parm->media_serial); } printf("cylinders %d\n", parm->cylinders); printf("heads %d\n", parm->heads); printf("sectors/track %d\n", parm->sectors); printf("sector size logical %u, physical %lu, offset %lu\n", ata_logical_sector_size(parm), (unsigned long)ata_physical_sector_size(parm), (unsigned long)ata_logical_sector_offset(parm)); if (parm->config == ATA_PROTO_CFA || (parm->support.command2 & ATA_SUPPORT_CFA)) printf("CFA supported\n"); printf("LBA%ssupported ", parm->capabilities1 & ATA_SUPPORT_LBA ? " " : " not "); if (lbasize) printf("%d sectors\n", lbasize); else printf("\n"); printf("LBA48%ssupported ", parm->support.command2 & ATA_SUPPORT_ADDRESS48 ? " " : " not "); if (lbasize48) printf("%ju sectors\n", (uintmax_t)lbasize48); else printf("\n"); printf("PIO supported PIO"); switch (ata_max_pmode(parm)) { case ATA_PIO4: printf("4"); break; case ATA_PIO3: printf("3"); break; case ATA_PIO2: printf("2"); break; case ATA_PIO1: printf("1"); break; default: printf("0"); } if ((parm->capabilities1 & ATA_SUPPORT_IORDY) == 0) printf(" w/o IORDY"); printf("\n"); printf("DMA%ssupported ", parm->capabilities1 & ATA_SUPPORT_DMA ? " " : " not "); if (parm->capabilities1 & ATA_SUPPORT_DMA) { if (parm->mwdmamodes & 0xff) { printf("WDMA"); if (parm->mwdmamodes & 0x04) printf("2"); else if (parm->mwdmamodes & 0x02) printf("1"); else if (parm->mwdmamodes & 0x01) printf("0"); printf(" "); } if ((parm->atavalid & ATA_FLAG_88) && (parm->udmamodes & 0xff)) { printf("UDMA"); if (parm->udmamodes & 0x40) printf("6"); else if (parm->udmamodes & 0x20) printf("5"); else if (parm->udmamodes & 0x10) printf("4"); else if (parm->udmamodes & 0x08) printf("3"); else if (parm->udmamodes & 0x04) printf("2"); else if (parm->udmamodes & 0x02) printf("1"); else if (parm->udmamodes & 0x01) printf("0"); printf(" "); } } printf("\n"); if (parm->media_rotation_rate == 1) { printf("media RPM non-rotating\n"); } else if (parm->media_rotation_rate >= 0x0401 && parm->media_rotation_rate <= 0xFFFE) { printf("media RPM %d\n", parm->media_rotation_rate); } printf("Zoned-Device Commands "); switch (parm->support3 & ATA_SUPPORT_ZONE_MASK) { case ATA_SUPPORT_ZONE_DEV_MANAGED: printf("device managed\n"); break; case ATA_SUPPORT_ZONE_HOST_AWARE: printf("host aware\n"); break; default: printf("no\n"); } printf("\nFeature " "Support Enabled Value Vendor\n"); printf("read ahead %s %s\n", parm->support.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no", parm->enabled.command1 & ATA_SUPPORT_LOOKAHEAD ? "yes" : "no"); printf("write cache %s %s\n", parm->support.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no", parm->enabled.command1 & ATA_SUPPORT_WRITECACHE ? "yes" : "no"); printf("flush cache %s %s\n", parm->support.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_FLUSHCACHE ? "yes" : "no"); printf("overlap %s\n", parm->capabilities1 & ATA_SUPPORT_OVERLAP ? "yes" : "no"); printf("Tagged Command Queuing (TCQ) %s %s", parm->support.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_QUEUED ? "yes" : "no"); if (parm->support.command2 & ATA_SUPPORT_QUEUED) { printf(" %d tags\n", ATA_QUEUE_LEN(parm->queue) + 1); } else printf("\n"); printf("Native Command Queuing (NCQ) "); if (parm->satacapabilities != 0xffff && (parm->satacapabilities & ATA_SUPPORT_NCQ)) { printf("yes %d tags\n", ATA_QUEUE_LEN(parm->queue) + 1); } else printf("no\n"); printf("NCQ Queue Management %s\n", atasata(parm) && parm->satacapabilities2 & ATA_SUPPORT_NCQ_QMANAGEMENT ? "yes" : "no"); printf("NCQ Streaming %s\n", atasata(parm) && parm->satacapabilities2 & ATA_SUPPORT_NCQ_STREAM ? "yes" : "no"); printf("Receive & Send FPDMA Queued %s\n", atasata(parm) && parm->satacapabilities2 & ATA_SUPPORT_RCVSND_FPDMA_QUEUED ? "yes" : "no"); printf("SMART %s %s\n", parm->support.command1 & ATA_SUPPORT_SMART ? "yes" : "no", parm->enabled.command1 & ATA_SUPPORT_SMART ? "yes" : "no"); printf("microcode download %s %s\n", parm->support.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_MICROCODE ? "yes" : "no"); printf("security %s %s\n", parm->support.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no", parm->enabled.command1 & ATA_SUPPORT_SECURITY ? "yes" : "no"); printf("power management %s %s\n", parm->support.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no", parm->enabled.command1 & ATA_SUPPORT_POWERMGT ? "yes" : "no"); printf("advanced power management %s %s", parm->support.command2 & ATA_SUPPORT_APM ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_APM ? "yes" : "no"); if (parm->support.command2 & ATA_SUPPORT_APM) { printf(" %d/0x%02X\n", parm->apm_value & 0xff, parm->apm_value & 0xff); } else printf("\n"); printf("automatic acoustic management %s %s", parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no", parm->enabled.command2 & ATA_SUPPORT_AUTOACOUSTIC ? "yes" :"no"); if (parm->support.command2 & ATA_SUPPORT_AUTOACOUSTIC) { printf(" %d/0x%02X %d/0x%02X\n", ATA_ACOUSTIC_CURRENT(parm->acoustic), ATA_ACOUSTIC_CURRENT(parm->acoustic), ATA_ACOUSTIC_VENDOR(parm->acoustic), ATA_ACOUSTIC_VENDOR(parm->acoustic)); } else printf("\n"); printf("media status notification %s %s\n", parm->support.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_NOTIFY ? "yes" : "no"); printf("power-up in Standby %s %s\n", parm->support.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no", parm->enabled.command2 & ATA_SUPPORT_STANDBY ? "yes" : "no"); printf("write-read-verify %s %s", parm->support2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no", parm->enabled2 & ATA_SUPPORT_WRITEREADVERIFY ? "yes" : "no"); if (parm->support2 & ATA_SUPPORT_WRITEREADVERIFY) { printf(" %d/0x%x\n", parm->wrv_mode, parm->wrv_mode); } else printf("\n"); printf("unload %s %s\n", parm->support.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no", parm->enabled.extension & ATA_SUPPORT_UNLOAD ? "yes" : "no"); printf("general purpose logging %s %s\n", parm->support.extension & ATA_SUPPORT_GENLOG ? "yes" : "no", parm->enabled.extension & ATA_SUPPORT_GENLOG ? "yes" : "no"); printf("free-fall %s %s\n", parm->support2 & ATA_SUPPORT_FREEFALL ? "yes" : "no", parm->enabled2 & ATA_SUPPORT_FREEFALL ? "yes" : "no"); printf("Data Set Management (DSM/TRIM) "); if (parm->support_dsm & ATA_SUPPORT_DSM_TRIM) { printf("yes\n"); printf("DSM - max 512byte blocks "); if (parm->max_dsm_blocks == 0x00) printf("yes not specified\n"); else printf("yes %d\n", parm->max_dsm_blocks); printf("DSM - deterministic read "); if (parm->support3 & ATA_SUPPORT_DRAT) { if (parm->support3 & ATA_SUPPORT_RZAT) printf("yes zeroed\n"); else printf("yes any value\n"); } else { printf("no\n"); } } else { printf("no\n"); } } static int scsi_cam_pass_16_send(struct cam_device *device, union ccb *ccb, int quiet) { struct ata_pass_16 *ata_pass_16; struct ata_cmd ata_cmd; ata_pass_16 = (struct ata_pass_16 *)ccb->csio.cdb_io.cdb_bytes; ata_cmd.command = ata_pass_16->command; ata_cmd.control = ata_pass_16->control; ata_cmd.features = ata_pass_16->features; if (arglist & CAM_ARG_VERBOSE) { warnx("sending ATA %s via pass_16 with timeout of %u msecs", ata_op_string(&ata_cmd), ccb->csio.ccb_h.timeout); } /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { warn("error sending ATA %s via pass_16", ata_op_string(&ata_cmd)); } if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } return (1); } if (!(ata_pass_16->flags & AP_FLAG_CHK_COND) && (ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { warnx("ATA %s via pass_16 failed", ata_op_string(&ata_cmd)); } if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } return (1); } return (0); } static int ata_cam_send(struct cam_device *device, union ccb *ccb, int quiet) { if (arglist & CAM_ARG_VERBOSE) { warnx("sending ATA %s with timeout of %u msecs", ata_op_string(&(ccb->ataio.cmd)), ccb->ataio.ccb_h.timeout); } /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { warn("error sending ATA %s", ata_op_string(&(ccb->ataio.cmd))); } if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } return (1); } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (quiet != 1 || arglist & CAM_ARG_VERBOSE) { warnx("ATA %s failed: %d", ata_op_string(&(ccb->ataio.cmd)), quiet); } if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } return (1); } return (0); } static int ata_do_pass_16(struct cam_device *device, union ccb *ccb, int retries, u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, u_int8_t tag_action, u_int8_t command, u_int8_t features, u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, int timeout, int quiet) { if (data_ptr != NULL) { ata_flags |= AP_FLAG_BYT_BLOK_BYTES | AP_FLAG_TLEN_SECT_CNT; if (flags & CAM_DIR_OUT) ata_flags |= AP_FLAG_TDIR_TO_DEV; else ata_flags |= AP_FLAG_TDIR_FROM_DEV; } else { ata_flags |= AP_FLAG_TLEN_NO_DATA; } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); scsi_ata_pass_16(&ccb->csio, retries, NULL, flags, tag_action, protocol, ata_flags, features, sector_count, lba, command, /*control*/0, data_ptr, dxfer_len, /*sense_len*/SSD_FULL_SIZE, timeout); return scsi_cam_pass_16_send(device, ccb, quiet); } static int ata_try_pass_16(struct cam_device *device) { struct ccb_pathinq cpi; if (get_cpi(device, &cpi) != 0) { warnx("couldn't get CPI"); return (-1); } if (cpi.protocol == PROTO_SCSI) { /* possibly compatible with pass_16 */ return (1); } /* likely not compatible with pass_16 */ return (0); } static int ata_do_28bit_cmd(struct cam_device *device, union ccb *ccb, int retries, u_int32_t flags, u_int8_t protocol, u_int8_t tag_action, u_int8_t command, u_int8_t features, u_int32_t lba, u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, int timeout, int quiet) { switch (ata_try_pass_16(device)) { case -1: return (1); case 1: /* Try using SCSI Passthrough */ return ata_do_pass_16(device, ccb, retries, flags, protocol, 0, tag_action, command, features, lba, sector_count, data_ptr, dxfer_len, timeout, quiet); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio); cam_fill_ataio(&ccb->ataio, retries, NULL, flags, tag_action, data_ptr, dxfer_len, timeout); ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); return ata_cam_send(device, ccb, quiet); } static int ata_do_cmd(struct cam_device *device, union ccb *ccb, int retries, u_int32_t flags, u_int8_t protocol, u_int8_t ata_flags, u_int8_t tag_action, u_int8_t command, u_int8_t features, u_int64_t lba, u_int8_t sector_count, u_int8_t *data_ptr, u_int16_t dxfer_len, int timeout, int force48bit) { int retval; retval = ata_try_pass_16(device); if (retval == -1) return (1); if (retval == 1) { int error; /* Try using SCSI Passthrough */ error = ata_do_pass_16(device, ccb, retries, flags, protocol, ata_flags, tag_action, command, features, lba, sector_count, data_ptr, dxfer_len, timeout, 0); if (ata_flags & AP_FLAG_CHK_COND) { /* Decode ata_res from sense data */ struct ata_res_pass16 *res_pass16; struct ata_res *res; u_int i; u_int16_t *ptr; /* sense_data is 4 byte aligned */ ptr = (uint16_t*)(uintptr_t)&ccb->csio.sense_data; for (i = 0; i < sizeof(*res_pass16) / 2; i++) ptr[i] = le16toh(ptr[i]); /* sense_data is 4 byte aligned */ res_pass16 = (struct ata_res_pass16 *)(uintptr_t) &ccb->csio.sense_data; res = &ccb->ataio.res; res->flags = res_pass16->flags; res->status = res_pass16->status; res->error = res_pass16->error; res->lba_low = res_pass16->lba_low; res->lba_mid = res_pass16->lba_mid; res->lba_high = res_pass16->lba_high; res->device = res_pass16->device; res->lba_low_exp = res_pass16->lba_low_exp; res->lba_mid_exp = res_pass16->lba_mid_exp; res->lba_high_exp = res_pass16->lba_high_exp; res->sector_count = res_pass16->sector_count; res->sector_count_exp = res_pass16->sector_count_exp; } return (error); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->ataio); cam_fill_ataio(&ccb->ataio, retries, NULL, flags, tag_action, data_ptr, dxfer_len, timeout); if (force48bit || lba > ATA_MAX_28BIT_LBA) ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count); else ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); if (ata_flags & AP_FLAG_CHK_COND) ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; return ata_cam_send(device, ccb, 0); } static void dump_data(uint16_t *ptr, uint32_t len) { u_int i; for (i = 0; i < len / 2; i++) { if ((i % 8) == 0) printf(" %3d: ", i); printf("%04hx ", ptr[i]); if ((i % 8) == 7) printf("\n"); } if ((i % 8) != 7) printf("\n"); } static int atahpa_proc_resp(struct cam_device *device, union ccb *ccb, int is48bit, u_int64_t *hpasize) { struct ata_res *res; res = &ccb->ataio.res; if (res->status & ATA_STATUS_ERROR) { if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); printf("error = 0x%02x, sector_count = 0x%04x, " "device = 0x%02x, status = 0x%02x\n", res->error, res->sector_count, res->device, res->status); } if (res->error & ATA_ERROR_ID_NOT_FOUND) { warnx("Max address has already been set since " "last power-on or hardware reset"); } return (1); } if (arglist & CAM_ARG_VERBOSE) { fprintf(stdout, "%s%d: Raw native max data:\n", device->device_name, device->dev_unit_num); /* res is 4 byte aligned */ dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res)); printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, " "status = 0x%02x\n", res->error, res->sector_count, res->device, res->status); } if (hpasize != NULL) { if (is48bit) { *hpasize = (((u_int64_t)((res->lba_high_exp << 16) | (res->lba_mid_exp << 8) | res->lba_low_exp) << 24) | ((res->lba_high << 16) | (res->lba_mid << 8) | res->lba_low)) + 1; } else { *hpasize = (((res->device & 0x0f) << 24) | (res->lba_high << 16) | (res->lba_mid << 8) | res->lba_low) + 1; } } return (0); } static int ata_read_native_max(struct cam_device *device, int retry_count, u_int32_t timeout, union ccb *ccb, struct ata_params *parm, u_int64_t *hpasize) { int error; u_int cmd, is48bit; u_int8_t protocol; is48bit = parm->support.command2 & ATA_SUPPORT_ADDRESS48; protocol = AP_PROTO_NON_DATA; if (is48bit) { cmd = ATA_READ_NATIVE_MAX_ADDRESS48; protocol |= AP_EXTEND; } else { cmd = ATA_READ_NATIVE_MAX_ADDRESS; } error = ata_do_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/protocol, /*ata_flags*/AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/NULL, /*dxfer_len*/0, timeout ? timeout : 5000, is48bit); if (error) return (error); return atahpa_proc_resp(device, ccb, is48bit, hpasize); } static int atahpa_set_max(struct cam_device *device, int retry_count, u_int32_t timeout, union ccb *ccb, int is48bit, u_int64_t maxsize, int persist) { int error; u_int cmd; u_int8_t protocol; protocol = AP_PROTO_NON_DATA; if (is48bit) { cmd = ATA_SET_MAX_ADDRESS48; protocol |= AP_EXTEND; } else { cmd = ATA_SET_MAX_ADDRESS; } /* lba's are zero indexed so the max lba is requested max - 1 */ if (maxsize) maxsize--; error = ata_do_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/protocol, /*ata_flags*/AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_MAX_ADDR, /*lba*/maxsize, /*sector_count*/persist, /*data_ptr*/NULL, /*dxfer_len*/0, timeout ? timeout : 1000, is48bit); if (error) return (error); return atahpa_proc_resp(device, ccb, is48bit, NULL); } static int atahpa_password(struct cam_device *device, int retry_count, u_int32_t timeout, union ccb *ccb, int is48bit, struct ata_set_max_pwd *pwd) { int error; u_int cmd; u_int8_t protocol; protocol = AP_PROTO_PIO_OUT; cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; error = ata_do_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/protocol, /*ata_flags*/AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_SET_PWD, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t*)pwd, /*dxfer_len*/sizeof(struct ata_set_max_pwd), timeout ? timeout : 1000, is48bit); if (error) return (error); return atahpa_proc_resp(device, ccb, is48bit, NULL); } static int atahpa_lock(struct cam_device *device, int retry_count, u_int32_t timeout, union ccb *ccb, int is48bit) { int error; u_int cmd; u_int8_t protocol; protocol = AP_PROTO_NON_DATA; cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; error = ata_do_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/protocol, /*ata_flags*/AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_LOCK, /*lba*/0, /*sector_count*/0, /*data_ptr*/NULL, /*dxfer_len*/0, timeout ? timeout : 1000, is48bit); if (error) return (error); return atahpa_proc_resp(device, ccb, is48bit, NULL); } static int atahpa_unlock(struct cam_device *device, int retry_count, u_int32_t timeout, union ccb *ccb, int is48bit, struct ata_set_max_pwd *pwd) { int error; u_int cmd; u_int8_t protocol; protocol = AP_PROTO_PIO_OUT; cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; error = ata_do_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/protocol, /*ata_flags*/AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_UNLOCK, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t*)pwd, /*dxfer_len*/sizeof(struct ata_set_max_pwd), timeout ? timeout : 1000, is48bit); if (error) return (error); return atahpa_proc_resp(device, ccb, is48bit, NULL); } static int atahpa_freeze_lock(struct cam_device *device, int retry_count, u_int32_t timeout, union ccb *ccb, int is48bit) { int error; u_int cmd; u_int8_t protocol; protocol = AP_PROTO_NON_DATA; cmd = (is48bit) ? ATA_SET_MAX_ADDRESS48 : ATA_SET_MAX_ADDRESS; error = ata_do_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/protocol, /*ata_flags*/AP_FLAG_CHK_COND, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/ATA_HPA_FEAT_FREEZE, /*lba*/0, /*sector_count*/0, /*data_ptr*/NULL, /*dxfer_len*/0, timeout ? timeout : 1000, is48bit); if (error) return (error); return atahpa_proc_resp(device, ccb, is48bit, NULL); } int ata_do_identify(struct cam_device *device, int retry_count, int timeout, union ccb *ccb, struct ata_params** ident_bufp) { struct ata_params *ident_buf; struct ccb_pathinq cpi; struct ccb_getdev cgd; u_int i, error; int16_t *ptr; u_int8_t command, retry_command; if (get_cpi(device, &cpi) != 0) { warnx("couldn't get CPI"); return (-1); } /* Neither PROTO_ATAPI or PROTO_SATAPM are used in cpi.protocol */ if (cpi.protocol == PROTO_ATA) { if (get_cgd(device, &cgd) != 0) { warnx("couldn't get CGD"); return (-1); } command = (cgd.protocol == PROTO_ATA) ? ATA_ATA_IDENTIFY : ATA_ATAPI_IDENTIFY; retry_command = 0; } else { /* We don't know which for sure so try both */ command = ATA_ATA_IDENTIFY; retry_command = ATA_ATAPI_IDENTIFY; } ptr = (uint16_t *)calloc(1, sizeof(struct ata_params)); if (ptr == NULL) { warnx("can't calloc memory for identify\n"); return (1); } error = ata_do_28bit_cmd(device, ccb, /*retries*/retry_count, /*flags*/CAM_DIR_IN, /*protocol*/AP_PROTO_PIO_IN, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/command, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t *)ptr, /*dxfer_len*/sizeof(struct ata_params), /*timeout*/timeout ? timeout : 30 * 1000, /*quiet*/1); if (error != 0) { if (retry_command == 0) { free(ptr); return (1); } error = ata_do_28bit_cmd(device, ccb, /*retries*/retry_count, /*flags*/CAM_DIR_IN, /*protocol*/AP_PROTO_PIO_IN, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/retry_command, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t *)ptr, /*dxfer_len*/sizeof(struct ata_params), /*timeout*/timeout ? timeout : 30 * 1000, /*quiet*/0); if (error != 0) { free(ptr); return (1); } } - ident_buf = (struct ata_params *)ptr; - ata_param_fixup(ident_buf); - error = 1; for (i = 0; i < sizeof(struct ata_params) / 2; i++) { + ptr[i] = le16toh(ptr[i]); if (ptr[i] != 0) error = 0; } if (arglist & CAM_ARG_VERBOSE) { fprintf(stdout, "%s%d: Raw identify data:\n", device->device_name, device->dev_unit_num); dump_data(ptr, sizeof(struct ata_params)); } /* check for invalid (all zero) response */ if (error != 0) { warnx("Invalid identify response detected"); free(ptr); return (error); } + + ident_buf = (struct ata_params *)ptr; + if (strncmp(ident_buf->model, "FX", 2) && + strncmp(ident_buf->model, "NEC", 3) && + strncmp(ident_buf->model, "Pioneer", 7) && + strncmp(ident_buf->model, "SHARP", 5)) { + ata_bswap(ident_buf->model, sizeof(ident_buf->model)); + ata_bswap(ident_buf->revision, sizeof(ident_buf->revision)); + ata_bswap(ident_buf->serial, sizeof(ident_buf->serial)); + ata_bswap(ident_buf->media_serial, sizeof(ident_buf->media_serial)); + } + ata_btrim(ident_buf->model, sizeof(ident_buf->model)); + ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model)); + ata_btrim(ident_buf->revision, sizeof(ident_buf->revision)); + ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision)); + ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); + ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); + ata_btrim(ident_buf->media_serial, sizeof(ident_buf->media_serial)); + ata_bpack(ident_buf->media_serial, ident_buf->media_serial, + sizeof(ident_buf->media_serial)); *ident_bufp = ident_buf; return (0); } static int ataidentify(struct cam_device *device, int retry_count, int timeout) { union ccb *ccb; struct ata_params *ident_buf; u_int64_t hpasize; if ((ccb = cam_getccb(device)) == NULL) { warnx("couldn't allocate CCB"); return (1); } if (ata_do_identify(device, retry_count, timeout, ccb, &ident_buf) != 0) { cam_freeccb(ccb); return (1); } if (ident_buf->support.command1 & ATA_SUPPORT_PROTECTED) { if (ata_read_native_max(device, retry_count, timeout, ccb, ident_buf, &hpasize) != 0) { cam_freeccb(ccb); return (1); } } else { hpasize = 0; } printf("%s%d: ", device->device_name, device->dev_unit_num); ata_print_ident(ident_buf); camxferrate(device); atacapprint(ident_buf); atahpa_print(ident_buf, hpasize, 0); free(ident_buf); cam_freeccb(ccb); return (0); } #ifdef WITH_NVME static int nvmeidentify(struct cam_device *device, int retry_count __unused, int timeout __unused) { struct nvme_controller_data cdata; if (nvme_get_cdata(device, &cdata)) return (1); nvme_print_controller(&cdata); return (0); } #endif static int identify(struct cam_device *device, int retry_count, int timeout) { #ifdef WITH_NVME struct ccb_pathinq cpi; if (get_cpi(device, &cpi) != 0) { warnx("couldn't get CPI"); return (-1); } if (cpi.protocol == PROTO_NVME) { return (nvmeidentify(device, retry_count, timeout)); } #endif return (ataidentify(device, retry_count, timeout)); } #endif /* MINIMALISTIC */ #ifndef MINIMALISTIC enum { ATA_SECURITY_ACTION_PRINT, ATA_SECURITY_ACTION_FREEZE, ATA_SECURITY_ACTION_UNLOCK, ATA_SECURITY_ACTION_DISABLE, ATA_SECURITY_ACTION_ERASE, ATA_SECURITY_ACTION_ERASE_ENHANCED, ATA_SECURITY_ACTION_SET_PASSWORD }; static void atasecurity_print_time(u_int16_t tw) { if (tw == 0) printf("unspecified"); else if (tw >= 255) printf("> 508 min"); else printf("%i min", 2 * tw); } static u_int32_t atasecurity_erase_timeout_msecs(u_int16_t timeout) { if (timeout == 0) return 2 * 3600 * 1000; /* default: two hours */ else if (timeout > 255) return (508 + 60) * 60 * 1000; /* spec says > 508 minutes */ return ((2 * timeout) + 5) * 60 * 1000; /* add a 5min margin */ } static void atasecurity_notify(u_int8_t command, struct ata_security_password *pwd) { struct ata_cmd cmd; bzero(&cmd, sizeof(cmd)); cmd.command = command; printf("Issuing %s", ata_op_string(&cmd)); if (pwd != NULL) { char pass[sizeof(pwd->password)+1]; /* pwd->password may not be null terminated */ pass[sizeof(pwd->password)] = '\0'; strncpy(pass, pwd->password, sizeof(pwd->password)); printf(" password='%s', user='%s'", pass, (pwd->ctrl & ATA_SECURITY_PASSWORD_MASTER) ? "master" : "user"); if (command == ATA_SECURITY_SET_PASSWORD) { printf(", mode='%s'", (pwd->ctrl & ATA_SECURITY_LEVEL_MAXIMUM) ? "maximum" : "high"); } } printf("\n"); } static int atasecurity_freeze(struct cam_device *device, union ccb *ccb, int retry_count, u_int32_t timeout, int quiet) { if (quiet == 0) atasecurity_notify(ATA_SECURITY_FREEZE_LOCK, NULL); return ata_do_28bit_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/AP_PROTO_NON_DATA, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SECURITY_FREEZE_LOCK, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/NULL, /*dxfer_len*/0, /*timeout*/timeout, /*quiet*/0); } static int atasecurity_unlock(struct cam_device *device, union ccb *ccb, int retry_count, u_int32_t timeout, struct ata_security_password *pwd, int quiet) { if (quiet == 0) atasecurity_notify(ATA_SECURITY_UNLOCK, pwd); return ata_do_28bit_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/AP_PROTO_PIO_OUT, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SECURITY_UNLOCK, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t *)pwd, /*dxfer_len*/sizeof(*pwd), /*timeout*/timeout, /*quiet*/0); } static int atasecurity_disable(struct cam_device *device, union ccb *ccb, int retry_count, u_int32_t timeout, struct ata_security_password *pwd, int quiet) { if (quiet == 0) atasecurity_notify(ATA_SECURITY_DISABLE_PASSWORD, pwd); return ata_do_28bit_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/AP_PROTO_PIO_OUT, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SECURITY_DISABLE_PASSWORD, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t *)pwd, /*dxfer_len*/sizeof(*pwd), /*timeout*/timeout, /*quiet*/0); } static int atasecurity_erase_confirm(struct cam_device *device, struct ata_params* ident_buf) { printf("\nYou are about to ERASE ALL DATA from the following" " device:\n%s%d,%s%d: ", device->device_name, device->dev_unit_num, device->given_dev_name, device->given_unit_number); ata_print_ident(ident_buf); for(;;) { char str[50]; printf("\nAre you SURE you want to ERASE ALL DATA? (yes/no) "); if (fgets(str, sizeof(str), stdin) != NULL) { if (strncasecmp(str, "yes", 3) == 0) { return (1); } else if (strncasecmp(str, "no", 2) == 0) { return (0); } else { printf("Please answer \"yes\" or " "\"no\"\n"); } } } /* NOTREACHED */ return (0); } static int atasecurity_erase(struct cam_device *device, union ccb *ccb, int retry_count, u_int32_t timeout, u_int32_t erase_timeout, struct ata_security_password *pwd, int quiet) { int error; if (quiet == 0) atasecurity_notify(ATA_SECURITY_ERASE_PREPARE, NULL); error = ata_do_28bit_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/AP_PROTO_NON_DATA, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SECURITY_ERASE_PREPARE, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/NULL, /*dxfer_len*/0, /*timeout*/timeout, /*quiet*/0); if (error != 0) return error; if (quiet == 0) atasecurity_notify(ATA_SECURITY_ERASE_UNIT, pwd); error = ata_do_28bit_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/AP_PROTO_PIO_OUT, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SECURITY_ERASE_UNIT, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t *)pwd, /*dxfer_len*/sizeof(*pwd), /*timeout*/erase_timeout, /*quiet*/0); if (error == 0 && quiet == 0) printf("\nErase Complete\n"); return error; } static int atasecurity_set_password(struct cam_device *device, union ccb *ccb, int retry_count, u_int32_t timeout, struct ata_security_password *pwd, int quiet) { if (quiet == 0) atasecurity_notify(ATA_SECURITY_SET_PASSWORD, pwd); return ata_do_28bit_cmd(device, ccb, retry_count, /*flags*/CAM_DIR_OUT, /*protocol*/AP_PROTO_PIO_OUT, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SECURITY_SET_PASSWORD, /*features*/0, /*lba*/0, /*sector_count*/0, /*data_ptr*/(u_int8_t *)pwd, /*dxfer_len*/sizeof(*pwd), /*timeout*/timeout, /*quiet*/0); } static void atasecurity_print(struct ata_params *parm) { printf("\nSecurity Option Value\n"); if (arglist & CAM_ARG_VERBOSE) { printf("status %04x\n", parm->security_status); } printf("supported %s\n", parm->security_status & ATA_SECURITY_SUPPORTED ? "yes" : "no"); if (!(parm->security_status & ATA_SECURITY_SUPPORTED)) return; printf("enabled %s\n", parm->security_status & ATA_SECURITY_ENABLED ? "yes" : "no"); printf("drive locked %s\n", parm->security_status & ATA_SECURITY_LOCKED ? "yes" : "no"); printf("security config frozen %s\n", parm->security_status & ATA_SECURITY_FROZEN ? "yes" : "no"); printf("count expired %s\n", parm->security_status & ATA_SECURITY_COUNT_EXP ? "yes" : "no"); printf("security level %s\n", parm->security_status & ATA_SECURITY_LEVEL ? "maximum" : "high"); printf("enhanced erase supported %s\n", parm->security_status & ATA_SECURITY_ENH_SUPP ? "yes" : "no"); printf("erase time "); atasecurity_print_time(parm->erase_time); printf("\n"); printf("enhanced erase time "); atasecurity_print_time(parm->enhanced_erase_time); printf("\n"); printf("master password rev %04x%s\n", parm->master_passwd_revision, parm->master_passwd_revision == 0x0000 || parm->master_passwd_revision == 0xFFFF ? " (unsupported)" : ""); } /* * Validates and copies the password in optarg to the passed buffer. * If the password in optarg is the same length as the buffer then * the data will still be copied but no null termination will occur. */ static int ata_getpwd(u_int8_t *passwd, int max, char opt) { int len; len = strlen(optarg); if (len > max) { warnx("-%c password is too long", opt); return (1); } else if (len == 0) { warnx("-%c password is missing", opt); return (1); } else if (optarg[0] == '-'){ warnx("-%c password starts with '-' (generic arg?)", opt); return (1); } else if (strlen(passwd) != 0 && strcmp(passwd, optarg) != 0) { warnx("-%c password conflicts with existing password from -%c", opt, pwd_opt); return (1); } /* Callers pass in a buffer which does NOT need to be terminated */ strncpy(passwd, optarg, max); pwd_opt = opt; return (0); } enum { ATA_HPA_ACTION_PRINT, ATA_HPA_ACTION_SET_MAX, ATA_HPA_ACTION_SET_PWD, ATA_HPA_ACTION_LOCK, ATA_HPA_ACTION_UNLOCK, ATA_HPA_ACTION_FREEZE_LOCK }; static int atahpa_set_confirm(struct cam_device *device, struct ata_params* ident_buf, u_int64_t maxsize, int persist) { printf("\nYou are about to configure HPA to limit the user accessible\n" "sectors to %ju %s on the device:\n%s%d,%s%d: ", maxsize, persist ? "persistently" : "temporarily", device->device_name, device->dev_unit_num, device->given_dev_name, device->given_unit_number); ata_print_ident(ident_buf); for(;;) { char str[50]; printf("\nAre you SURE you want to configure HPA? (yes/no) "); if (NULL != fgets(str, sizeof(str), stdin)) { if (0 == strncasecmp(str, "yes", 3)) { return (1); } else if (0 == strncasecmp(str, "no", 2)) { return (0); } else { printf("Please answer \"yes\" or " "\"no\"\n"); } } } /* NOTREACHED */ return (0); } static int atahpa(struct cam_device *device, int retry_count, int timeout, int argc, char **argv, char *combinedopt) { union ccb *ccb; struct ata_params *ident_buf; struct ccb_getdev cgd; struct ata_set_max_pwd pwd; int error, confirm, quiet, c, action, actions, persist; int security, is48bit, pwdsize; u_int64_t hpasize, maxsize; actions = 0; confirm = 0; quiet = 0; maxsize = 0; persist = 0; security = 0; memset(&pwd, 0, sizeof(pwd)); /* default action is to print hpa information */ action = ATA_HPA_ACTION_PRINT; pwdsize = sizeof(pwd.password); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c){ case 's': action = ATA_HPA_ACTION_SET_MAX; maxsize = strtoumax(optarg, NULL, 0); actions++; break; case 'p': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); action = ATA_HPA_ACTION_SET_PWD; security = 1; actions++; break; case 'l': action = ATA_HPA_ACTION_LOCK; security = 1; actions++; break; case 'U': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); action = ATA_HPA_ACTION_UNLOCK; security = 1; actions++; break; case 'f': action = ATA_HPA_ACTION_FREEZE_LOCK; security = 1; actions++; break; case 'P': persist = 1; break; case 'y': confirm++; break; case 'q': quiet++; break; } } if (actions > 1) { warnx("too many hpa actions specified"); return (1); } if (get_cgd(device, &cgd) != 0) { warnx("couldn't get CGD"); return (1); } ccb = cam_getccb(device); if (ccb == NULL) { warnx("couldn't allocate CCB"); return (1); } error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); if (error != 0) { cam_freeccb(ccb); return (1); } if (quiet == 0) { printf("%s%d: ", device->device_name, device->dev_unit_num); ata_print_ident(ident_buf); camxferrate(device); } if (action == ATA_HPA_ACTION_PRINT) { error = ata_read_native_max(device, retry_count, timeout, ccb, ident_buf, &hpasize); if (error == 0) atahpa_print(ident_buf, hpasize, 1); cam_freeccb(ccb); free(ident_buf); return (error); } if (!(ident_buf->support.command1 & ATA_SUPPORT_PROTECTED)) { warnx("HPA is not supported by this device"); cam_freeccb(ccb); free(ident_buf); return (1); } if (security && !(ident_buf->support.command1 & ATA_SUPPORT_MAXSECURITY)) { warnx("HPA Security is not supported by this device"); cam_freeccb(ccb); free(ident_buf); return (1); } is48bit = ident_buf->support.command2 & ATA_SUPPORT_ADDRESS48; /* * The ATA spec requires: * 1. Read native max addr is called directly before set max addr * 2. Read native max addr is NOT called before any other set max call */ switch(action) { case ATA_HPA_ACTION_SET_MAX: if (confirm == 0 && atahpa_set_confirm(device, ident_buf, maxsize, persist) == 0) { cam_freeccb(ccb); free(ident_buf); return (1); } error = ata_read_native_max(device, retry_count, timeout, ccb, ident_buf, &hpasize); if (error == 0) { error = atahpa_set_max(device, retry_count, timeout, ccb, is48bit, maxsize, persist); if (error == 0) { /* redo identify to get new lba values */ error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); atahpa_print(ident_buf, hpasize, 1); } } break; case ATA_HPA_ACTION_SET_PWD: error = atahpa_password(device, retry_count, timeout, ccb, is48bit, &pwd); if (error == 0) printf("HPA password has been set\n"); break; case ATA_HPA_ACTION_LOCK: error = atahpa_lock(device, retry_count, timeout, ccb, is48bit); if (error == 0) printf("HPA has been locked\n"); break; case ATA_HPA_ACTION_UNLOCK: error = atahpa_unlock(device, retry_count, timeout, ccb, is48bit, &pwd); if (error == 0) printf("HPA has been unlocked\n"); break; case ATA_HPA_ACTION_FREEZE_LOCK: error = atahpa_freeze_lock(device, retry_count, timeout, ccb, is48bit); if (error == 0) printf("HPA has been frozen\n"); break; default: errx(1, "Option currently not supported"); } cam_freeccb(ccb); free(ident_buf); return (error); } static int atasecurity(struct cam_device *device, int retry_count, int timeout, int argc, char **argv, char *combinedopt) { union ccb *ccb; struct ata_params *ident_buf; int error, confirm, quiet, c, action, actions, setpwd; int security_enabled, erase_timeout, pwdsize; struct ata_security_password pwd; actions = 0; setpwd = 0; erase_timeout = 0; confirm = 0; quiet = 0; memset(&pwd, 0, sizeof(pwd)); /* default action is to print security information */ action = ATA_SECURITY_ACTION_PRINT; /* user is master by default as its safer that way */ pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER; pwdsize = sizeof(pwd.password); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c){ case 'f': action = ATA_SECURITY_ACTION_FREEZE; actions++; break; case 'U': if (strcasecmp(optarg, "user") == 0) { pwd.ctrl |= ATA_SECURITY_PASSWORD_USER; pwd.ctrl &= ~ATA_SECURITY_PASSWORD_MASTER; } else if (strcasecmp(optarg, "master") == 0) { pwd.ctrl |= ATA_SECURITY_PASSWORD_MASTER; pwd.ctrl &= ~ATA_SECURITY_PASSWORD_USER; } else { warnx("-U argument '%s' is invalid (must be " "'user' or 'master')", optarg); return (1); } break; case 'l': if (strcasecmp(optarg, "high") == 0) { pwd.ctrl |= ATA_SECURITY_LEVEL_HIGH; pwd.ctrl &= ~ATA_SECURITY_LEVEL_MAXIMUM; } else if (strcasecmp(optarg, "maximum") == 0) { pwd.ctrl |= ATA_SECURITY_LEVEL_MAXIMUM; pwd.ctrl &= ~ATA_SECURITY_LEVEL_HIGH; } else { warnx("-l argument '%s' is unknown (must be " "'high' or 'maximum')", optarg); return (1); } break; case 'k': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); action = ATA_SECURITY_ACTION_UNLOCK; actions++; break; case 'd': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); action = ATA_SECURITY_ACTION_DISABLE; actions++; break; case 'e': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); action = ATA_SECURITY_ACTION_ERASE; actions++; break; case 'h': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); pwd.ctrl |= ATA_SECURITY_ERASE_ENHANCED; action = ATA_SECURITY_ACTION_ERASE_ENHANCED; actions++; break; case 's': if (ata_getpwd(pwd.password, pwdsize, c) != 0) return (1); setpwd = 1; if (action == ATA_SECURITY_ACTION_PRINT) action = ATA_SECURITY_ACTION_SET_PASSWORD; /* * Don't increment action as this can be combined * with other actions. */ break; case 'y': confirm++; break; case 'q': quiet++; break; case 'T': erase_timeout = atoi(optarg) * 1000; break; } } if (actions > 1) { warnx("too many security actions specified"); return (1); } if ((ccb = cam_getccb(device)) == NULL) { warnx("couldn't allocate CCB"); return (1); } error = ata_do_identify(device, retry_count, timeout, ccb, &ident_buf); if (error != 0) { cam_freeccb(ccb); return (1); } if (quiet == 0) { printf("%s%d: ", device->device_name, device->dev_unit_num); ata_print_ident(ident_buf); camxferrate(device); } if (action == ATA_SECURITY_ACTION_PRINT) { atasecurity_print(ident_buf); free(ident_buf); cam_freeccb(ccb); return (0); } if ((ident_buf->support.command1 & ATA_SUPPORT_SECURITY) == 0) { warnx("Security not supported"); free(ident_buf); cam_freeccb(ccb); return (1); } /* default timeout 15 seconds the same as linux hdparm */ timeout = timeout ? timeout : 15 * 1000; security_enabled = ident_buf->security_status & ATA_SECURITY_ENABLED; /* first set the password if requested */ if (setpwd == 1) { /* confirm we can erase before setting the password if erasing */ if (confirm == 0 && (action == ATA_SECURITY_ACTION_ERASE_ENHANCED || action == ATA_SECURITY_ACTION_ERASE) && atasecurity_erase_confirm(device, ident_buf) == 0) { cam_freeccb(ccb); free(ident_buf); return (error); } if (pwd.ctrl & ATA_SECURITY_PASSWORD_MASTER) { pwd.revision = ident_buf->master_passwd_revision; if (pwd.revision != 0 && pwd.revision != 0xfff && --pwd.revision == 0) { pwd.revision = 0xfffe; } } error = atasecurity_set_password(device, ccb, retry_count, timeout, &pwd, quiet); if (error != 0) { cam_freeccb(ccb); free(ident_buf); return (error); } security_enabled = 1; } switch(action) { case ATA_SECURITY_ACTION_FREEZE: error = atasecurity_freeze(device, ccb, retry_count, timeout, quiet); break; case ATA_SECURITY_ACTION_UNLOCK: if (security_enabled) { if (ident_buf->security_status & ATA_SECURITY_LOCKED) { error = atasecurity_unlock(device, ccb, retry_count, timeout, &pwd, quiet); } else { warnx("Can't unlock, drive is not locked"); error = 1; } } else { warnx("Can't unlock, security is disabled"); error = 1; } break; case ATA_SECURITY_ACTION_DISABLE: if (security_enabled) { /* First unlock the drive if its locked */ if (ident_buf->security_status & ATA_SECURITY_LOCKED) { error = atasecurity_unlock(device, ccb, retry_count, timeout, &pwd, quiet); } if (error == 0) { error = atasecurity_disable(device, ccb, retry_count, timeout, &pwd, quiet); } } else { warnx("Can't disable security (already disabled)"); error = 1; } break; case ATA_SECURITY_ACTION_ERASE: if (security_enabled) { if (erase_timeout == 0) { erase_timeout = atasecurity_erase_timeout_msecs( ident_buf->erase_time); } error = atasecurity_erase(device, ccb, retry_count, timeout, erase_timeout, &pwd, quiet); } else { warnx("Can't secure erase (security is disabled)"); error = 1; } break; case ATA_SECURITY_ACTION_ERASE_ENHANCED: if (security_enabled) { if (ident_buf->security_status & ATA_SECURITY_ENH_SUPP) { if (erase_timeout == 0) { erase_timeout = atasecurity_erase_timeout_msecs( ident_buf->enhanced_erase_time); } error = atasecurity_erase(device, ccb, retry_count, timeout, erase_timeout, &pwd, quiet); } else { warnx("Enhanced erase is not supported"); error = 1; } } else { warnx("Can't secure erase (enhanced), " "(security is disabled)"); error = 1; } break; } cam_freeccb(ccb); free(ident_buf); return (error); } #endif /* MINIMALISTIC */ /* * Parse out a bus, or a bus, target and lun in the following * format: * bus * bus:target * bus:target:lun * * Returns the number of parsed components, or 0. */ static int parse_btl(char *tstr, path_id_t *bus, target_id_t *target, lun_id_t *lun, cam_argmask *arglst) { char *tmpstr; int convs = 0; while (isspace(*tstr) && (*tstr != '\0')) tstr++; tmpstr = (char *)strtok(tstr, ":"); if ((tmpstr != NULL) && (*tmpstr != '\0')) { *bus = strtol(tmpstr, NULL, 0); *arglst |= CAM_ARG_BUS; convs++; tmpstr = (char *)strtok(NULL, ":"); if ((tmpstr != NULL) && (*tmpstr != '\0')) { *target = strtol(tmpstr, NULL, 0); *arglst |= CAM_ARG_TARGET; convs++; tmpstr = (char *)strtok(NULL, ":"); if ((tmpstr != NULL) && (*tmpstr != '\0')) { *lun = strtol(tmpstr, NULL, 0); *arglst |= CAM_ARG_LUN; convs++; } } } return convs; } static int dorescan_or_reset(int argc, char **argv, int rescan) { static const char must[] = "you must specify \"all\", a bus, or a bus:target:lun to %s"; int rv, error = 0; path_id_t bus = CAM_BUS_WILDCARD; target_id_t target = CAM_TARGET_WILDCARD; lun_id_t lun = CAM_LUN_WILDCARD; char *tstr; if (argc < 3) { warnx(must, rescan? "rescan" : "reset"); return (1); } tstr = argv[optind]; while (isspace(*tstr) && (*tstr != '\0')) tstr++; if (strncasecmp(tstr, "all", strlen("all")) == 0) arglist |= CAM_ARG_BUS; else if (isdigit(*tstr)) { rv = parse_btl(argv[optind], &bus, &target, &lun, &arglist); if (rv != 1 && rv != 3) { warnx(must, rescan? "rescan" : "reset"); return (1); } } else { char name[30]; int unit; int fd = -1; union ccb ccb; /* * Note that resetting or rescanning a device used to * require a bus or bus:target:lun. This is because the * device in question may not exist and you're trying to * get the controller to rescan to find it. It may also be * because the device is hung / unresponsive, and opening * an unresponsive device is not desireable. * * It can be more convenient to reference a device by * peripheral name and unit number, though, and it is * possible to get the bus:target:lun for devices that * currently exist in the EDT. So this can work for * devices that we want to reset, or devices that exist * that we want to rescan, but not devices that do not * exist yet. * * So, we are careful here to look up the bus/target/lun * for the device the user wants to operate on, specified * by peripheral instance (e.g. da0, pass32) without * actually opening that device. The process is similar to * what cam_lookup_pass() does, except that we don't * actually open the passthrough driver instance in the end. */ if (cam_get_device(tstr, name, sizeof(name), &unit) == -1) { warnx("%s", cam_errbuf); error = 1; goto bailout; } if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { warn("Unable to open %s", XPT_DEVICE); error = 1; goto bailout; } bzero(&ccb, sizeof(ccb)); /* * The function code isn't strictly necessary for the * GETPASSTHRU ioctl. */ ccb.ccb_h.func_code = XPT_GDEVLIST; /* * These two are necessary for the GETPASSTHRU ioctl to * work. */ strlcpy(ccb.cgdl.periph_name, name, sizeof(ccb.cgdl.periph_name)); ccb.cgdl.unit_number = unit; /* * Attempt to get the passthrough device. This ioctl will * fail if the device name is null, if the device doesn't * exist, or if the passthrough driver isn't in the kernel. */ if (ioctl(fd, CAMGETPASSTHRU, &ccb) == -1) { warn("Unable to find bus:target:lun for device %s%d", name, unit); error = 1; close(fd); goto bailout; } if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { const struct cam_status_entry *entry; entry = cam_fetch_status_entry(ccb.ccb_h.status); warnx("Unable to find bus:target_lun for device %s%d, " "CAM status: %s (%#x)", name, unit, entry ? entry->status_text : "Unknown", ccb.ccb_h.status); error = 1; close(fd); goto bailout; } /* * The kernel fills in the bus/target/lun. We don't * need the passthrough device name and unit number since * we aren't going to open it. */ bus = ccb.ccb_h.path_id; target = ccb.ccb_h.target_id; lun = ccb.ccb_h.target_lun; arglist |= CAM_ARG_BUS | CAM_ARG_TARGET | CAM_ARG_LUN; close(fd); } if ((arglist & CAM_ARG_BUS) && (arglist & CAM_ARG_TARGET) && (arglist & CAM_ARG_LUN)) error = scanlun_or_reset_dev(bus, target, lun, rescan); else error = rescan_or_reset_bus(bus, rescan); bailout: return (error); } static int rescan_or_reset_bus(path_id_t bus, int rescan) { union ccb *ccb = NULL, *matchccb = NULL; int fd = -1, retval; int bufsize; retval = 0; if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { warnx("error opening transport layer device %s", XPT_DEVICE); warn("%s", XPT_DEVICE); return (1); } ccb = malloc(sizeof(*ccb)); if (ccb == NULL) { warn("failed to allocate CCB"); retval = 1; goto bailout; } bzero(ccb, sizeof(*ccb)); if (bus != CAM_BUS_WILDCARD) { ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; ccb->ccb_h.path_id = bus; ccb->ccb_h.target_id = CAM_TARGET_WILDCARD; ccb->ccb_h.target_lun = CAM_LUN_WILDCARD; ccb->crcn.flags = CAM_FLAG_NONE; /* run this at a low priority */ ccb->ccb_h.pinfo.priority = 5; if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { fprintf(stdout, "%s of bus %d was successful\n", rescan ? "Re-scan" : "Reset", bus); } else { fprintf(stdout, "%s of bus %d returned error %#x\n", rescan ? "Re-scan" : "Reset", bus, ccb->ccb_h.status & CAM_STATUS_MASK); retval = 1; } goto bailout; } /* * The right way to handle this is to modify the xpt so that it can * handle a wildcarded bus in a rescan or reset CCB. At the moment * that isn't implemented, so instead we enumerate the buses and * send the rescan or reset to those buses in the case where the * given bus is -1 (wildcard). We don't send a rescan or reset * to the xpt bus; sending a rescan to the xpt bus is effectively a * no-op, sending a rescan to the xpt bus would result in a status of * CAM_REQ_INVALID. */ matchccb = malloc(sizeof(*matchccb)); if (matchccb == NULL) { warn("failed to allocate CCB"); retval = 1; goto bailout; } bzero(matchccb, sizeof(*matchccb)); matchccb->ccb_h.func_code = XPT_DEV_MATCH; matchccb->ccb_h.path_id = CAM_BUS_WILDCARD; bufsize = sizeof(struct dev_match_result) * 20; matchccb->cdm.match_buf_len = bufsize; matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize); if (matchccb->cdm.matches == NULL) { warnx("can't malloc memory for matches"); retval = 1; goto bailout; } matchccb->cdm.num_matches = 0; matchccb->cdm.num_patterns = 1; matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern); matchccb->cdm.patterns = (struct dev_match_pattern *)malloc( matchccb->cdm.pattern_buf_len); if (matchccb->cdm.patterns == NULL) { warnx("can't malloc memory for patterns"); retval = 1; goto bailout; } matchccb->cdm.patterns[0].type = DEV_MATCH_BUS; matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY; do { unsigned int i; if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); retval = 1; goto bailout; } if ((matchccb->ccb_h.status != CAM_REQ_CMP) || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST) && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) { warnx("got CAM error %#x, CDM error %d\n", matchccb->ccb_h.status, matchccb->cdm.status); retval = 1; goto bailout; } for (i = 0; i < matchccb->cdm.num_matches; i++) { struct bus_match_result *bus_result; /* This shouldn't happen. */ if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS) continue; bus_result =&matchccb->cdm.matches[i].result.bus_result; /* * We don't want to rescan or reset the xpt bus. * See above. */ if (bus_result->path_id == CAM_XPT_PATH_ID) continue; ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; ccb->ccb_h.path_id = bus_result->path_id; ccb->ccb_h.target_id = CAM_TARGET_WILDCARD; ccb->ccb_h.target_lun = CAM_LUN_WILDCARD; ccb->crcn.flags = CAM_FLAG_NONE; /* run this at a low priority */ ccb->ccb_h.pinfo.priority = 5; if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){ fprintf(stdout, "%s of bus %d was successful\n", rescan? "Re-scan" : "Reset", bus_result->path_id); } else { /* * Don't bail out just yet, maybe the other * rescan or reset commands will complete * successfully. */ fprintf(stderr, "%s of bus %d returned error " "%#x\n", rescan? "Re-scan" : "Reset", bus_result->path_id, ccb->ccb_h.status & CAM_STATUS_MASK); retval = 1; } } } while ((matchccb->ccb_h.status == CAM_REQ_CMP) && (matchccb->cdm.status == CAM_DEV_MATCH_MORE)); bailout: if (fd != -1) close(fd); if (matchccb != NULL) { free(matchccb->cdm.patterns); free(matchccb->cdm.matches); free(matchccb); } free(ccb); return (retval); } static int scanlun_or_reset_dev(path_id_t bus, target_id_t target, lun_id_t lun, int scan) { union ccb ccb; struct cam_device *device; int fd; device = NULL; if (bus == CAM_BUS_WILDCARD) { warnx("invalid bus number %d", bus); return (1); } if (target == CAM_TARGET_WILDCARD) { warnx("invalid target number %d", target); return (1); } if (lun == CAM_LUN_WILDCARD) { warnx("invalid lun number %jx", (uintmax_t)lun); return (1); } fd = -1; bzero(&ccb, sizeof(union ccb)); if (scan) { if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { warnx("error opening transport layer device %s\n", XPT_DEVICE); warn("%s", XPT_DEVICE); return (1); } } else { device = cam_open_btl(bus, target, lun, O_RDWR, NULL); if (device == NULL) { warnx("%s", cam_errbuf); return (1); } } ccb.ccb_h.func_code = (scan)? XPT_SCAN_LUN : XPT_RESET_DEV; ccb.ccb_h.path_id = bus; ccb.ccb_h.target_id = target; ccb.ccb_h.target_lun = lun; ccb.ccb_h.timeout = 5000; ccb.crcn.flags = CAM_FLAG_NONE; /* run this at a low priority */ ccb.ccb_h.pinfo.priority = 5; if (scan) { if (ioctl(fd, CAMIOCOMMAND, &ccb) < 0) { warn("CAMIOCOMMAND ioctl failed"); close(fd); return (1); } } else { if (cam_send_ccb(device, &ccb) < 0) { warn("error sending XPT_RESET_DEV CCB"); cam_close_device(device); return (1); } } if (scan) close(fd); else cam_close_device(device); /* * An error code of CAM_BDR_SENT is normal for a BDR request. */ if (((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) || ((!scan) && ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_BDR_SENT))) { fprintf(stdout, "%s of %d:%d:%jx was successful\n", scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun); return (0); } else { fprintf(stdout, "%s of %d:%d:%jx returned error %#x\n", scan? "Re-scan" : "Reset", bus, target, (uintmax_t)lun, ccb.ccb_h.status & CAM_STATUS_MASK); return (1); } } #ifndef MINIMALISTIC static struct scsi_nv defect_list_type_map[] = { { "block", SRDD10_BLOCK_FORMAT }, { "extbfi", SRDD10_EXT_BFI_FORMAT }, { "extphys", SRDD10_EXT_PHYS_FORMAT }, { "longblock", SRDD10_LONG_BLOCK_FORMAT }, { "bfi", SRDD10_BYTES_FROM_INDEX_FORMAT }, { "phys", SRDD10_PHYSICAL_SECTOR_FORMAT } }; static int readdefects(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { union ccb *ccb = NULL; struct scsi_read_defect_data_hdr_10 *hdr10 = NULL; struct scsi_read_defect_data_hdr_12 *hdr12 = NULL; size_t hdr_size = 0, entry_size = 0; int use_12byte = 0; int hex_format = 0; u_int8_t *defect_list = NULL; u_int8_t list_format = 0; int list_type_set = 0; u_int32_t dlist_length = 0; u_int32_t returned_length = 0, valid_len = 0; u_int32_t num_returned = 0, num_valid = 0; u_int32_t max_possible_size = 0, hdr_max = 0; u_int32_t starting_offset = 0; u_int8_t returned_format, returned_type; unsigned int i; int summary = 0, quiet = 0; int c, error = 0; int lists_specified = 0; int get_length = 1, first_pass = 1; int mads = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c){ case 'f': { scsi_nv_status status; int entry_num = 0; status = scsi_get_nv(defect_list_type_map, sizeof(defect_list_type_map) / sizeof(defect_list_type_map[0]), optarg, &entry_num, SCSI_NV_FLAG_IG_CASE); if (status == SCSI_NV_FOUND) { list_format = defect_list_type_map[ entry_num].value; list_type_set = 1; } else { warnx("%s: %s %s option %s", __func__, (status == SCSI_NV_AMBIGUOUS) ? "ambiguous" : "invalid", "defect list type", optarg); error = 1; goto defect_bailout; } break; } case 'G': arglist |= CAM_ARG_GLIST; break; case 'P': arglist |= CAM_ARG_PLIST; break; case 'q': quiet = 1; break; case 's': summary = 1; break; case 'S': { char *endptr; starting_offset = strtoul(optarg, &endptr, 0); if (*endptr != '\0') { error = 1; warnx("invalid starting offset %s", optarg); goto defect_bailout; } break; } case 'X': hex_format = 1; break; default: break; } } if (list_type_set == 0) { error = 1; warnx("no defect list format specified"); goto defect_bailout; } if (arglist & CAM_ARG_PLIST) { list_format |= SRDD10_PLIST; lists_specified++; } if (arglist & CAM_ARG_GLIST) { list_format |= SRDD10_GLIST; lists_specified++; } /* * This implies a summary, and was the previous behavior. */ if (lists_specified == 0) summary = 1; ccb = cam_getccb(device); retry_12byte: /* * We start off asking for just the header to determine how much * defect data is available. Some Hitachi drives return an error * if you ask for more data than the drive has. Once we know the * length, we retry the command with the returned length. */ if (use_12byte == 0) dlist_length = sizeof(*hdr10); else dlist_length = sizeof(*hdr12); retry: if (defect_list != NULL) { free(defect_list); defect_list = NULL; } defect_list = malloc(dlist_length); if (defect_list == NULL) { warnx("can't malloc memory for defect list"); error = 1; goto defect_bailout; } next_batch: bzero(defect_list, dlist_length); /* * cam_getccb() zeros the CCB header only. So we need to zero the * payload portion of the ccb. */ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); scsi_read_defects(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*tag_action*/ task_attr, /*list_format*/ list_format, /*addr_desc_index*/ starting_offset, /*data_ptr*/ defect_list, /*dxfer_len*/ dlist_length, /*minimum_cmd_size*/ use_12byte ? 12 : 0, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (cam_send_ccb(device, ccb) < 0) { perror("error reading defect list"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto defect_bailout; } valid_len = ccb->csio.dxfer_len - ccb->csio.resid; if (use_12byte == 0) { hdr10 = (struct scsi_read_defect_data_hdr_10 *)defect_list; hdr_size = sizeof(*hdr10); hdr_max = SRDDH10_MAX_LENGTH; if (valid_len >= hdr_size) { returned_length = scsi_2btoul(hdr10->length); returned_format = hdr10->format; } else { returned_length = 0; returned_format = 0; } } else { hdr12 = (struct scsi_read_defect_data_hdr_12 *)defect_list; hdr_size = sizeof(*hdr12); hdr_max = SRDDH12_MAX_LENGTH; if (valid_len >= hdr_size) { returned_length = scsi_4btoul(hdr12->length); returned_format = hdr12->format; } else { returned_length = 0; returned_format = 0; } } returned_type = returned_format & SRDDH10_DLIST_FORMAT_MASK; switch (returned_type) { case SRDD10_BLOCK_FORMAT: entry_size = sizeof(struct scsi_defect_desc_block); break; case SRDD10_LONG_BLOCK_FORMAT: entry_size = sizeof(struct scsi_defect_desc_long_block); break; case SRDD10_EXT_PHYS_FORMAT: case SRDD10_PHYSICAL_SECTOR_FORMAT: entry_size = sizeof(struct scsi_defect_desc_phys_sector); break; case SRDD10_EXT_BFI_FORMAT: case SRDD10_BYTES_FROM_INDEX_FORMAT: entry_size = sizeof(struct scsi_defect_desc_bytes_from_index); break; default: warnx("Unknown defect format 0x%x\n", returned_type); error = 1; goto defect_bailout; break; } max_possible_size = (hdr_max / entry_size) * entry_size; num_returned = returned_length / entry_size; num_valid = min(returned_length, valid_len - hdr_size); num_valid /= entry_size; if (get_length != 0) { get_length = 0; if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) { struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; sense = &ccb->csio.sense_data; scsi_extract_sense_len(sense, ccb->csio.sense_len - ccb->csio.sense_resid, &error_code, &sense_key, &asc, &ascq, /*show_errors*/ 1); /* * If the drive is reporting that it just doesn't * support the defect list format, go ahead and use * the length it reported. Otherwise, the length * may not be valid, so use the maximum. */ if ((sense_key == SSD_KEY_RECOVERED_ERROR) && (asc == 0x1c) && (ascq == 0x00) && (returned_length > 0)) { if ((use_12byte == 0) && (returned_length >= max_possible_size)) { get_length = 1; use_12byte = 1; goto retry_12byte; } dlist_length = returned_length + hdr_size; } else if ((sense_key == SSD_KEY_RECOVERED_ERROR) && (asc == 0x1f) && (ascq == 0x00) && (returned_length > 0)) { /* Partial defect list transfer */ /* * Hitachi drives return this error * along with a partial defect list if they * have more defects than the 10 byte * command can support. Retry with the 12 * byte command. */ if (use_12byte == 0) { get_length = 1; use_12byte = 1; goto retry_12byte; } dlist_length = returned_length + hdr_size; } else if ((sense_key == SSD_KEY_ILLEGAL_REQUEST) && (asc == 0x24) && (ascq == 0x00)) { /* Invalid field in CDB */ /* * SBC-3 says that if the drive has more * defects than can be reported with the * 10 byte command, it should return this * error and no data. Retry with the 12 * byte command. */ if (use_12byte == 0) { get_length = 1; use_12byte = 1; goto retry_12byte; } dlist_length = returned_length + hdr_size; } else { /* * If we got a SCSI error and no valid length, * just use the 10 byte maximum. The 12 * byte maximum is too large. */ if (returned_length == 0) dlist_length = SRDD10_MAX_LENGTH; else { if ((use_12byte == 0) && (returned_length >= max_possible_size)) { get_length = 1; use_12byte = 1; goto retry_12byte; } dlist_length = returned_length + hdr_size; } } } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP){ error = 1; warnx("Error reading defect header"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); goto defect_bailout; } else { if ((use_12byte == 0) && (returned_length >= max_possible_size)) { get_length = 1; use_12byte = 1; goto retry_12byte; } dlist_length = returned_length + hdr_size; } if (summary != 0) { fprintf(stdout, "%u", num_returned); if (quiet == 0) { fprintf(stdout, " defect%s", (num_returned != 1) ? "s" : ""); } fprintf(stdout, "\n"); goto defect_bailout; } /* * We always limit the list length to the 10-byte maximum * length (0xffff). The reason is that some controllers * can't handle larger I/Os, and we can transfer the entire * 10 byte list in one shot. For drives that support the 12 * byte read defects command, we'll step through the list * by specifying a starting offset. For drives that don't * support the 12 byte command's starting offset, we'll * just display the first 64K. */ dlist_length = min(dlist_length, SRDD10_MAX_LENGTH); goto retry; } if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; sense = &ccb->csio.sense_data; scsi_extract_sense_len(sense, ccb->csio.sense_len - ccb->csio.sense_resid, &error_code, &sense_key, &asc, &ascq, /*show_errors*/ 1); /* * According to the SCSI spec, if the disk doesn't support * the requested format, it will generally return a sense * key of RECOVERED ERROR, and an additional sense code * of "DEFECT LIST NOT FOUND". HGST drives also return * Primary/Grown defect list not found errors. So just * check for an ASC of 0x1c. */ if ((sense_key == SSD_KEY_RECOVERED_ERROR) && (asc == 0x1c)) { const char *format_str; format_str = scsi_nv_to_str(defect_list_type_map, sizeof(defect_list_type_map) / sizeof(defect_list_type_map[0]), list_format & SRDD10_DLIST_FORMAT_MASK); warnx("requested defect format %s not available", format_str ? format_str : "unknown"); format_str = scsi_nv_to_str(defect_list_type_map, sizeof(defect_list_type_map) / sizeof(defect_list_type_map[0]), returned_type); if (format_str != NULL) { warnx("Device returned %s format", format_str); } else { error = 1; warnx("Device returned unknown defect" " data format %#x", returned_type); goto defect_bailout; } } else { error = 1; warnx("Error returned from read defect data command"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); goto defect_bailout; } } else if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { error = 1; warnx("Error returned from read defect data command"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); goto defect_bailout; } if (first_pass != 0) { fprintf(stderr, "Got %d defect", num_returned); if ((lists_specified == 0) || (num_returned == 0)) { fprintf(stderr, "s.\n"); goto defect_bailout; } else if (num_returned == 1) fprintf(stderr, ":\n"); else fprintf(stderr, "s:\n"); first_pass = 0; } /* * XXX KDM I should probably clean up the printout format for the * disk defects. */ switch (returned_type) { case SRDD10_PHYSICAL_SECTOR_FORMAT: case SRDD10_EXT_PHYS_FORMAT: { struct scsi_defect_desc_phys_sector *dlist; dlist = (struct scsi_defect_desc_phys_sector *) (defect_list + hdr_size); for (i = 0; i < num_valid; i++) { uint32_t sector; sector = scsi_4btoul(dlist[i].sector); if (returned_type == SRDD10_EXT_PHYS_FORMAT) { mads = (sector & SDD_EXT_PHYS_MADS) ? 0 : 1; sector &= ~SDD_EXT_PHYS_FLAG_MASK; } if (hex_format == 0) fprintf(stdout, "%d:%d:%d%s", scsi_3btoul(dlist[i].cylinder), dlist[i].head, scsi_4btoul(dlist[i].sector), mads ? " - " : "\n"); else fprintf(stdout, "0x%x:0x%x:0x%x%s", scsi_3btoul(dlist[i].cylinder), dlist[i].head, scsi_4btoul(dlist[i].sector), mads ? " - " : "\n"); mads = 0; } if (num_valid < num_returned) { starting_offset += num_valid; goto next_batch; } break; } case SRDD10_BYTES_FROM_INDEX_FORMAT: case SRDD10_EXT_BFI_FORMAT: { struct scsi_defect_desc_bytes_from_index *dlist; dlist = (struct scsi_defect_desc_bytes_from_index *) (defect_list + hdr_size); for (i = 0; i < num_valid; i++) { uint32_t bfi; bfi = scsi_4btoul(dlist[i].bytes_from_index); if (returned_type == SRDD10_EXT_BFI_FORMAT) { mads = (bfi & SDD_EXT_BFI_MADS) ? 1 : 0; bfi &= ~SDD_EXT_BFI_FLAG_MASK; } if (hex_format == 0) fprintf(stdout, "%d:%d:%d%s", scsi_3btoul(dlist[i].cylinder), dlist[i].head, scsi_4btoul(dlist[i].bytes_from_index), mads ? " - " : "\n"); else fprintf(stdout, "0x%x:0x%x:0x%x%s", scsi_3btoul(dlist[i].cylinder), dlist[i].head, scsi_4btoul(dlist[i].bytes_from_index), mads ? " - " : "\n"); mads = 0; } if (num_valid < num_returned) { starting_offset += num_valid; goto next_batch; } break; } case SRDDH10_BLOCK_FORMAT: { struct scsi_defect_desc_block *dlist; dlist = (struct scsi_defect_desc_block *) (defect_list + hdr_size); for (i = 0; i < num_valid; i++) { if (hex_format == 0) fprintf(stdout, "%u\n", scsi_4btoul(dlist[i].address)); else fprintf(stdout, "0x%x\n", scsi_4btoul(dlist[i].address)); } if (num_valid < num_returned) { starting_offset += num_valid; goto next_batch; } break; } case SRDD10_LONG_BLOCK_FORMAT: { struct scsi_defect_desc_long_block *dlist; dlist = (struct scsi_defect_desc_long_block *) (defect_list + hdr_size); for (i = 0; i < num_valid; i++) { if (hex_format == 0) fprintf(stdout, "%ju\n", (uintmax_t)scsi_8btou64( dlist[i].address)); else fprintf(stdout, "0x%jx\n", (uintmax_t)scsi_8btou64( dlist[i].address)); } if (num_valid < num_returned) { starting_offset += num_valid; goto next_batch; } break; } default: fprintf(stderr, "Unknown defect format 0x%x\n", returned_type); error = 1; break; } defect_bailout: if (defect_list != NULL) free(defect_list); if (ccb != NULL) cam_freeccb(ccb); return (error); } #endif /* MINIMALISTIC */ #if 0 void reassignblocks(struct cam_device *device, u_int32_t *blocks, int num_blocks) { union ccb *ccb; ccb = cam_getccb(device); cam_freeccb(ccb); } #endif #ifndef MINIMALISTIC void mode_sense(struct cam_device *device, int dbd, int pc, int page, int subpage, int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen) { union ccb *ccb; int retval; ccb = cam_getccb(device); if (ccb == NULL) errx(1, "mode_sense: couldn't allocate CCB"); CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); scsi_mode_sense_subpage(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* dbd */ dbd, /* pc */ pc << 6, /* page */ page, /* subpage */ subpage, /* param_buf */ data, /* param_len */ datalen, /* minimum_cmd_size */ 0, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } cam_freeccb(ccb); cam_close_device(device); if (retval < 0) err(1, "error sending mode sense command"); else errx(1, "error sending mode sense command"); } cam_freeccb(ccb); } void mode_select(struct cam_device *device, int save_pages, int task_attr, int retry_count, int timeout, u_int8_t *data, int datalen) { union ccb *ccb; int retval; ccb = cam_getccb(device); if (ccb == NULL) errx(1, "mode_select: couldn't allocate CCB"); CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); scsi_mode_select(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* scsi_page_fmt */ 1, /* save_pages */ save_pages, /* param_buf */ data, /* param_len */ datalen, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } cam_freeccb(ccb); cam_close_device(device); if (retval < 0) err(1, "error sending mode select command"); else errx(1, "error sending mode select command"); } cam_freeccb(ccb); } void modepage(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { char *str_subpage; int c, page = -1, subpage = -1, pc = 0; int binary = 0, dbd = 0, edit = 0, list = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'b': binary = 1; break; case 'd': dbd = 1; break; case 'e': edit = 1; break; case 'l': list++; break; case 'm': str_subpage = optarg; strsep(&str_subpage, ","); page = strtol(optarg, NULL, 0); if (str_subpage) subpage = strtol(str_subpage, NULL, 0); else subpage = 0; if (page < 0) errx(1, "invalid mode page %d", page); if (subpage < 0) errx(1, "invalid mode subpage %d", subpage); break; case 'P': pc = strtol(optarg, NULL, 0); if ((pc < 0) || (pc > 3)) errx(1, "invalid page control field %d", pc); break; default: break; } } if (page == -1 && list == 0) errx(1, "you must specify a mode page!"); if (list != 0) { mode_list(device, dbd, pc, list > 1, task_attr, retry_count, timeout); } else { mode_edit(device, dbd, pc, page, subpage, edit, binary, task_attr, retry_count, timeout); } } static int scsicmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { union ccb *ccb; u_int32_t flags = CAM_DIR_NONE; u_int8_t *data_ptr = NULL; u_int8_t cdb[20]; u_int8_t atacmd[12]; struct get_hook hook; int c, data_bytes = 0, valid_bytes; int cdb_len = 0; int atacmd_len = 0; int dmacmd = 0; int fpdmacmd = 0; int need_res = 0; char *datastr = NULL, *tstr, *resstr = NULL; int error = 0; int fd_data = 0, fd_res = 0; int retval; ccb = cam_getccb(device); if (ccb == NULL) { warnx("scsicmd: error allocating ccb"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(ccb); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'a': tstr = optarg; while (isspace(*tstr) && (*tstr != '\0')) tstr++; hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; atacmd_len = buff_encode_visit(atacmd, sizeof(atacmd), tstr, iget, &hook); /* * Increment optind by the number of arguments the * encoding routine processed. After each call to * getopt(3), optind points to the argument that * getopt should process _next_. In this case, * that means it points to the first command string * argument, if there is one. Once we increment * this, it should point to either the next command * line argument, or it should be past the end of * the list. */ optind += hook.got; break; case 'c': tstr = optarg; while (isspace(*tstr) && (*tstr != '\0')) tstr++; hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; cdb_len = buff_encode_visit(cdb, sizeof(cdb), tstr, iget, &hook); /* * Increment optind by the number of arguments the * encoding routine processed. After each call to * getopt(3), optind points to the argument that * getopt should process _next_. In this case, * that means it points to the first command string * argument, if there is one. Once we increment * this, it should point to either the next command * line argument, or it should be past the end of * the list. */ optind += hook.got; break; case 'd': dmacmd = 1; break; case 'f': fpdmacmd = 1; break; case 'i': if (arglist & CAM_ARG_CMD_OUT) { warnx("command must either be " "read or write, not both"); error = 1; goto scsicmd_bailout; } arglist |= CAM_ARG_CMD_IN; flags = CAM_DIR_IN; data_bytes = strtol(optarg, NULL, 0); if (data_bytes <= 0) { warnx("invalid number of input bytes %d", data_bytes); error = 1; goto scsicmd_bailout; } hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; optind++; datastr = cget(&hook, NULL); /* * If the user supplied "-" instead of a format, he * wants the data to be written to stdout. */ if ((datastr != NULL) && (datastr[0] == '-')) fd_data = 1; data_ptr = (u_int8_t *)malloc(data_bytes); if (data_ptr == NULL) { warnx("can't malloc memory for data_ptr"); error = 1; goto scsicmd_bailout; } break; case 'o': if (arglist & CAM_ARG_CMD_IN) { warnx("command must either be " "read or write, not both"); error = 1; goto scsicmd_bailout; } arglist |= CAM_ARG_CMD_OUT; flags = CAM_DIR_OUT; data_bytes = strtol(optarg, NULL, 0); if (data_bytes <= 0) { warnx("invalid number of output bytes %d", data_bytes); error = 1; goto scsicmd_bailout; } hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; datastr = cget(&hook, NULL); data_ptr = (u_int8_t *)malloc(data_bytes); if (data_ptr == NULL) { warnx("can't malloc memory for data_ptr"); error = 1; goto scsicmd_bailout; } bzero(data_ptr, data_bytes); /* * If the user supplied "-" instead of a format, he * wants the data to be read from stdin. */ if ((datastr != NULL) && (datastr[0] == '-')) fd_data = 1; else buff_encode_visit(data_ptr, data_bytes, datastr, iget, &hook); optind += hook.got; break; case 'r': need_res = 1; hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; resstr = cget(&hook, NULL); if ((resstr != NULL) && (resstr[0] == '-')) fd_res = 1; optind += hook.got; break; default: break; } } /* * If fd_data is set, and we're writing to the device, we need to * read the data the user wants written from stdin. */ if ((fd_data == 1) && (arglist & CAM_ARG_CMD_OUT)) { ssize_t amt_read; int amt_to_read = data_bytes; u_int8_t *buf_ptr = data_ptr; for (amt_read = 0; amt_to_read > 0; amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { if (amt_read == -1) { warn("error reading data from stdin"); error = 1; goto scsicmd_bailout; } amt_to_read -= amt_read; buf_ptr += amt_read; } } if (arglist & CAM_ARG_ERR_RECOVER) flags |= CAM_PASS_ERR_RECOVER; /* Disable freezing the device queue */ flags |= CAM_DEV_QFRZDIS; if (cdb_len) { /* * This is taken from the SCSI-3 draft spec. * (T10/1157D revision 0.3) * The top 3 bits of an opcode are the group code. * The next 5 bits are the command code. * Group 0: six byte commands * Group 1: ten byte commands * Group 2: ten byte commands * Group 3: reserved * Group 4: sixteen byte commands * Group 5: twelve byte commands * Group 6: vendor specific * Group 7: vendor specific */ switch((cdb[0] >> 5) & 0x7) { case 0: cdb_len = 6; break; case 1: case 2: cdb_len = 10; break; case 3: case 6: case 7: /* computed by buff_encode_visit */ break; case 4: cdb_len = 16; break; case 5: cdb_len = 12; break; } /* * We should probably use csio_build_visit or something like that * here, but it's easier to encode arguments as you go. The * alternative would be skipping the CDB argument and then encoding * it here, since we've got the data buffer argument by now. */ bcopy(cdb, &ccb->csio.cdb_io.cdb_bytes, cdb_len); cam_fill_csio(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, /*tag_action*/ task_attr, /*data_ptr*/ data_ptr, /*dxfer_len*/ data_bytes, /*sense_len*/ SSD_FULL_SIZE, /*cdb_len*/ cdb_len, /*timeout*/ timeout ? timeout : 5000); } else { atacmd_len = 12; bcopy(atacmd, &ccb->ataio.cmd.command, atacmd_len); if (need_res) ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; if (dmacmd) ccb->ataio.cmd.flags |= CAM_ATAIO_DMA; if (fpdmacmd) ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA; cam_fill_ataio(&ccb->ataio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, /*tag_action*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ data_bytes, /*timeout*/ timeout ? timeout : 5000); } if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto scsicmd_bailout; } if (atacmd_len && need_res) { if (fd_res == 0) { buff_decode_visit(&ccb->ataio.res.status, 11, resstr, arg_put, NULL); fprintf(stdout, "\n"); } else { fprintf(stdout, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", ccb->ataio.res.status, ccb->ataio.res.error, ccb->ataio.res.lba_low, ccb->ataio.res.lba_mid, ccb->ataio.res.lba_high, ccb->ataio.res.device, ccb->ataio.res.lba_low_exp, ccb->ataio.res.lba_mid_exp, ccb->ataio.res.lba_high_exp, ccb->ataio.res.sector_count, ccb->ataio.res.sector_count_exp); fflush(stdout); } } if (cdb_len) valid_bytes = ccb->csio.dxfer_len - ccb->csio.resid; else valid_bytes = ccb->ataio.dxfer_len - ccb->ataio.resid; if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (arglist & CAM_ARG_CMD_IN) && (valid_bytes > 0)) { if (fd_data == 0) { buff_decode_visit(data_ptr, valid_bytes, datastr, arg_put, NULL); fprintf(stdout, "\n"); } else { ssize_t amt_written; int amt_to_write = valid_bytes; u_int8_t *buf_ptr = data_ptr; for (amt_written = 0; (amt_to_write > 0) && (amt_written =write(1, buf_ptr,amt_to_write))> 0;){ amt_to_write -= amt_written; buf_ptr += amt_written; } if (amt_written == -1) { warn("error writing data to stdout"); error = 1; goto scsicmd_bailout; } else if ((amt_written == 0) && (amt_to_write > 0)) { warnx("only wrote %u bytes out of %u", valid_bytes - amt_to_write, valid_bytes); } } } scsicmd_bailout: if ((data_bytes > 0) && (data_ptr != NULL)) free(data_ptr); cam_freeccb(ccb); return (error); } static int camdebug(int argc, char **argv, char *combinedopt) { int c, fd; path_id_t bus = CAM_BUS_WILDCARD; target_id_t target = CAM_TARGET_WILDCARD; lun_id_t lun = CAM_LUN_WILDCARD; char *tstr, *tmpstr = NULL; union ccb ccb; int error = 0; bzero(&ccb, sizeof(union ccb)); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'I': arglist |= CAM_ARG_DEBUG_INFO; ccb.cdbg.flags |= CAM_DEBUG_INFO; break; case 'P': arglist |= CAM_ARG_DEBUG_PERIPH; ccb.cdbg.flags |= CAM_DEBUG_PERIPH; break; case 'S': arglist |= CAM_ARG_DEBUG_SUBTRACE; ccb.cdbg.flags |= CAM_DEBUG_SUBTRACE; break; case 'T': arglist |= CAM_ARG_DEBUG_TRACE; ccb.cdbg.flags |= CAM_DEBUG_TRACE; break; case 'X': arglist |= CAM_ARG_DEBUG_XPT; ccb.cdbg.flags |= CAM_DEBUG_XPT; break; case 'c': arglist |= CAM_ARG_DEBUG_CDB; ccb.cdbg.flags |= CAM_DEBUG_CDB; break; case 'p': arglist |= CAM_ARG_DEBUG_PROBE; ccb.cdbg.flags |= CAM_DEBUG_PROBE; break; default: break; } } if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) { warnx("error opening transport layer device %s", XPT_DEVICE); warn("%s", XPT_DEVICE); return (1); } argc -= optind; argv += optind; if (argc <= 0) { warnx("you must specify \"off\", \"all\" or a bus,"); warnx("bus:target, or bus:target:lun"); close(fd); return (1); } tstr = *argv; while (isspace(*tstr) && (*tstr != '\0')) tstr++; if (strncmp(tstr, "off", 3) == 0) { ccb.cdbg.flags = CAM_DEBUG_NONE; arglist &= ~(CAM_ARG_DEBUG_INFO|CAM_ARG_DEBUG_PERIPH| CAM_ARG_DEBUG_TRACE|CAM_ARG_DEBUG_SUBTRACE| CAM_ARG_DEBUG_XPT|CAM_ARG_DEBUG_PROBE); } else if (strncmp(tstr, "all", 3) != 0) { tmpstr = (char *)strtok(tstr, ":"); if ((tmpstr != NULL) && (*tmpstr != '\0')){ bus = strtol(tmpstr, NULL, 0); arglist |= CAM_ARG_BUS; tmpstr = (char *)strtok(NULL, ":"); if ((tmpstr != NULL) && (*tmpstr != '\0')){ target = strtol(tmpstr, NULL, 0); arglist |= CAM_ARG_TARGET; tmpstr = (char *)strtok(NULL, ":"); if ((tmpstr != NULL) && (*tmpstr != '\0')){ lun = strtol(tmpstr, NULL, 0); arglist |= CAM_ARG_LUN; } } } else { error = 1; warnx("you must specify \"all\", \"off\", or a bus,"); warnx("bus:target, or bus:target:lun to debug"); } } if (error == 0) { ccb.ccb_h.func_code = XPT_DEBUG; ccb.ccb_h.path_id = bus; ccb.ccb_h.target_id = target; ccb.ccb_h.target_lun = lun; if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); error = 1; } if (error == 0) { if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_FUNC_NOTAVAIL) { warnx("CAM debugging not available"); warnx("you need to put options CAMDEBUG in" " your kernel config file!"); error = 1; } else if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_DEBUG CCB failed with status %#x", ccb.ccb_h.status); error = 1; } else { if (ccb.cdbg.flags == CAM_DEBUG_NONE) { fprintf(stderr, "Debugging turned off\n"); } else { fprintf(stderr, "Debugging enabled for " "%d:%d:%jx\n", bus, target, (uintmax_t)lun); } } } close(fd); } return (error); } static int tagcontrol(struct cam_device *device, int argc, char **argv, char *combinedopt) { int c; union ccb *ccb; int numtags = -1; int retval = 0; int quiet = 0; char pathstr[1024]; ccb = cam_getccb(device); if (ccb == NULL) { warnx("tagcontrol: error allocating ccb"); return (1); } while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'N': numtags = strtol(optarg, NULL, 0); if (numtags < 0) { warnx("tag count %d is < 0", numtags); retval = 1; goto tagcontrol_bailout; } break; case 'q': quiet++; break; default: break; } } cam_path_string(device, pathstr, sizeof(pathstr)); if (numtags >= 0) { CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->crs); ccb->ccb_h.func_code = XPT_REL_SIMQ; ccb->ccb_h.flags = CAM_DEV_QFREEZE; ccb->crs.release_flags = RELSIM_ADJUST_OPENINGS; ccb->crs.openings = numtags; if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_REL_SIMQ CCB"); retval = 1; goto tagcontrol_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_REL_SIMQ CCB failed"); cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto tagcontrol_bailout; } if (quiet == 0) fprintf(stdout, "%stagged openings now %d\n", pathstr, ccb->crs.openings); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgds); ccb->ccb_h.func_code = XPT_GDEV_STATS; if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_GDEV_STATS CCB"); retval = 1; goto tagcontrol_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_GDEV_STATS CCB failed"); cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto tagcontrol_bailout; } if (arglist & CAM_ARG_VERBOSE) { fprintf(stdout, "%s", pathstr); fprintf(stdout, "dev_openings %d\n", ccb->cgds.dev_openings); fprintf(stdout, "%s", pathstr); fprintf(stdout, "dev_active %d\n", ccb->cgds.dev_active); fprintf(stdout, "%s", pathstr); fprintf(stdout, "allocated %d\n", ccb->cgds.allocated); fprintf(stdout, "%s", pathstr); fprintf(stdout, "queued %d\n", ccb->cgds.queued); fprintf(stdout, "%s", pathstr); fprintf(stdout, "held %d\n", ccb->cgds.held); fprintf(stdout, "%s", pathstr); fprintf(stdout, "mintags %d\n", ccb->cgds.mintags); fprintf(stdout, "%s", pathstr); fprintf(stdout, "maxtags %d\n", ccb->cgds.maxtags); } else { if (quiet == 0) { fprintf(stdout, "%s", pathstr); fprintf(stdout, "device openings: "); } fprintf(stdout, "%d\n", ccb->cgds.dev_openings + ccb->cgds.dev_active); } tagcontrol_bailout: cam_freeccb(ccb); return (retval); } static void cts_print(struct cam_device *device, struct ccb_trans_settings *cts) { char pathstr[1024]; cam_path_string(device, pathstr, sizeof(pathstr)); if (cts->transport == XPORT_SPI) { struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { fprintf(stdout, "%ssync parameter: %d\n", pathstr, spi->sync_period); if (spi->sync_offset != 0) { u_int freq; freq = scsi_calc_syncsrate(spi->sync_period); fprintf(stdout, "%sfrequency: %d.%03dMHz\n", pathstr, freq / 1000, freq % 1000); } } if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { fprintf(stdout, "%soffset: %d\n", pathstr, spi->sync_offset); } if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { fprintf(stdout, "%sbus width: %d bits\n", pathstr, (0x01 << spi->bus_width) * 8); } if (spi->valid & CTS_SPI_VALID_DISC) { fprintf(stdout, "%sdisconnection is %s\n", pathstr, (spi->flags & CTS_SPI_FLAGS_DISC_ENB) ? "enabled" : "disabled"); } } if (cts->transport == XPORT_FC) { struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc; if (fc->valid & CTS_FC_VALID_WWNN) fprintf(stdout, "%sWWNN: 0x%llx\n", pathstr, (long long) fc->wwnn); if (fc->valid & CTS_FC_VALID_WWPN) fprintf(stdout, "%sWWPN: 0x%llx\n", pathstr, (long long) fc->wwpn); if (fc->valid & CTS_FC_VALID_PORT) fprintf(stdout, "%sPortID: 0x%x\n", pathstr, fc->port); if (fc->valid & CTS_FC_VALID_SPEED) fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", pathstr, fc->bitrate / 1000, fc->bitrate % 1000); } if (cts->transport == XPORT_SAS) { struct ccb_trans_settings_sas *sas = &cts->xport_specific.sas; if (sas->valid & CTS_SAS_VALID_SPEED) fprintf(stdout, "%stransfer speed: %d.%03dMB/s\n", pathstr, sas->bitrate / 1000, sas->bitrate % 1000); } if (cts->transport == XPORT_ATA) { struct ccb_trans_settings_pata *pata = &cts->xport_specific.ata; if ((pata->valid & CTS_ATA_VALID_MODE) != 0) { fprintf(stdout, "%sATA mode: %s\n", pathstr, ata_mode2string(pata->mode)); } if ((pata->valid & CTS_ATA_VALID_ATAPI) != 0) { fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, pata->atapi); } if ((pata->valid & CTS_ATA_VALID_BYTECOUNT) != 0) { fprintf(stdout, "%sPIO transaction length: %d\n", pathstr, pata->bytecount); } } if (cts->transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &cts->xport_specific.sata; if ((sata->valid & CTS_SATA_VALID_REVISION) != 0) { fprintf(stdout, "%sSATA revision: %d.x\n", pathstr, sata->revision); } if ((sata->valid & CTS_SATA_VALID_MODE) != 0) { fprintf(stdout, "%sATA mode: %s\n", pathstr, ata_mode2string(sata->mode)); } if ((sata->valid & CTS_SATA_VALID_ATAPI) != 0) { fprintf(stdout, "%sATAPI packet length: %d\n", pathstr, sata->atapi); } if ((sata->valid & CTS_SATA_VALID_BYTECOUNT) != 0) { fprintf(stdout, "%sPIO transaction length: %d\n", pathstr, sata->bytecount); } if ((sata->valid & CTS_SATA_VALID_PM) != 0) { fprintf(stdout, "%sPMP presence: %d\n", pathstr, sata->pm_present); } if ((sata->valid & CTS_SATA_VALID_TAGS) != 0) { fprintf(stdout, "%sNumber of tags: %d\n", pathstr, sata->tags); } if ((sata->valid & CTS_SATA_VALID_CAPS) != 0) { fprintf(stdout, "%sSATA capabilities: %08x\n", pathstr, sata->caps); } } if (cts->protocol == PROTO_ATA) { struct ccb_trans_settings_ata *ata= &cts->proto_specific.ata; if (ata->valid & CTS_ATA_VALID_TQ) { fprintf(stdout, "%stagged queueing: %s\n", pathstr, (ata->flags & CTS_ATA_FLAGS_TAG_ENB) ? "enabled" : "disabled"); } } if (cts->protocol == PROTO_SCSI) { struct ccb_trans_settings_scsi *scsi= &cts->proto_specific.scsi; if (scsi->valid & CTS_SCSI_VALID_TQ) { fprintf(stdout, "%stagged queueing: %s\n", pathstr, (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) ? "enabled" : "disabled"); } } #ifdef WITH_NVME if (cts->protocol == PROTO_NVME) { struct ccb_trans_settings_nvme *nvmex = &cts->xport_specific.nvme; if (nvmex->valid & CTS_NVME_VALID_SPEC) { fprintf(stdout, "%sNVMe Spec: %d.%d\n", pathstr, NVME_MAJOR(nvmex->spec), NVME_MINOR(nvmex->spec)); } if (nvmex->valid & CTS_NVME_VALID_LINK) { fprintf(stdout, "%sPCIe lanes: %d (%d max)\n", pathstr, nvmex->lanes, nvmex->max_lanes); fprintf(stdout, "%sPCIe Generation: %d (%d max)\n", pathstr, nvmex->speed, nvmex->max_speed); } } #endif } /* * Get a path inquiry CCB for the specified device. */ static int get_cpi(struct cam_device *device, struct ccb_pathinq *cpi) { union ccb *ccb; int retval = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("get_cpi: couldn't allocate CCB"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); ccb->ccb_h.func_code = XPT_PATH_INQ; if (cam_send_ccb(device, ccb) < 0) { warn("get_cpi: error sending Path Inquiry CCB"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto get_cpi_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto get_cpi_bailout; } bcopy(&ccb->cpi, cpi, sizeof(struct ccb_pathinq)); get_cpi_bailout: cam_freeccb(ccb); return (retval); } /* * Get a get device CCB for the specified device. */ static int get_cgd(struct cam_device *device, struct ccb_getdev *cgd) { union ccb *ccb; int retval = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("get_cgd: couldn't allocate CCB"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cgd); ccb->ccb_h.func_code = XPT_GDEV_TYPE; if (cam_send_ccb(device, ccb) < 0) { warn("get_cgd: error sending Path Inquiry CCB"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto get_cgd_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto get_cgd_bailout; } bcopy(&ccb->cgd, cgd, sizeof(struct ccb_getdev)); get_cgd_bailout: cam_freeccb(ccb); return (retval); } /* * Returns 1 if the device has the VPD page, 0 if it does not, and -1 on an * error. */ int dev_has_vpd_page(struct cam_device *dev, uint8_t page_id, int retry_count, int timeout, int verbosemode) { union ccb *ccb = NULL; struct scsi_vpd_supported_page_list sup_pages; int i; int retval = 0; ccb = cam_getccb(dev); if (ccb == NULL) { warn("Unable to allocate CCB"); retval = -1; goto bailout; } /* cam_getccb cleans up the header, caller has to zero the payload */ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); bzero(&sup_pages, sizeof(sup_pages)); scsi_inquiry(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /* tag_action */ MSG_SIMPLE_Q_TAG, /* inq_buf */ (u_int8_t *)&sup_pages, /* inq_len */ sizeof(sup_pages), /* evpd */ 1, /* page_code */ SVPD_SUPPORTED_PAGE_LIST, /* sense_len */ SSD_FULL_SIZE, /* timeout */ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (retry_count != 0) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(dev, ccb) < 0) { cam_freeccb(ccb); ccb = NULL; retval = -1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (verbosemode != 0) cam_error_print(dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = -1; goto bailout; } for (i = 0; i < sup_pages.length; i++) { if (sup_pages.list[i] == page_id) { retval = 1; goto bailout; } } bailout: if (ccb != NULL) cam_freeccb(ccb); return (retval); } /* * devtype is filled in with the type of device. * Returns 0 for success, non-zero for failure. */ int get_device_type(struct cam_device *dev, int retry_count, int timeout, int verbosemode, camcontrol_devtype *devtype) { struct ccb_getdev cgd; int retval = 0; retval = get_cgd(dev, &cgd); if (retval != 0) goto bailout; switch (cgd.protocol) { case PROTO_SCSI: break; case PROTO_ATA: case PROTO_ATAPI: case PROTO_SATAPM: *devtype = CC_DT_ATA; goto bailout; break; /*NOTREACHED*/ default: *devtype = CC_DT_UNKNOWN; goto bailout; break; /*NOTREACHED*/ } /* * Check for the ATA Information VPD page (0x89). If this is an * ATA device behind a SCSI to ATA translation layer, this VPD page * should be present. * * If that VPD page isn't present, or we get an error back from the * INQUIRY command, we'll just treat it as a normal SCSI device. */ retval = dev_has_vpd_page(dev, SVPD_ATA_INFORMATION, retry_count, timeout, verbosemode); if (retval == 1) *devtype = CC_DT_ATA_BEHIND_SCSI; else *devtype = CC_DT_SCSI; retval = 0; bailout: return (retval); } int build_ata_cmd(union ccb *ccb, uint32_t retry_count, uint32_t flags, uint8_t tag_action, uint8_t protocol, uint8_t ata_flags, uint16_t features, uint16_t sector_count, uint64_t lba, uint8_t command, uint32_t auxiliary, uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage, size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout, int is48bit, camcontrol_devtype devtype) { int retval = 0; if (devtype == CC_DT_ATA) { cam_fill_ataio(&ccb->ataio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, /*tag_action*/ tag_action, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*timeout*/ timeout); if (is48bit || lba > ATA_MAX_28BIT_LBA) ata_48bit_cmd(&ccb->ataio, command, features, lba, sector_count); else ata_28bit_cmd(&ccb->ataio, command, features, lba, sector_count); if (auxiliary != 0) { ccb->ataio.ata_flags |= ATA_FLAG_AUX; ccb->ataio.aux = auxiliary; } if (ata_flags & AP_FLAG_CHK_COND) ccb->ataio.cmd.flags |= CAM_ATAIO_NEEDRESULT; if ((protocol & AP_PROTO_MASK) == AP_PROTO_DMA) ccb->ataio.cmd.flags |= CAM_ATAIO_DMA; else if ((protocol & AP_PROTO_MASK) == AP_PROTO_FPDMA) ccb->ataio.cmd.flags |= CAM_ATAIO_FPDMA; } else { if (is48bit || lba > ATA_MAX_28BIT_LBA) protocol |= AP_EXTEND; retval = scsi_ata_pass(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, /*tag_action*/ tag_action, /*protocol*/ protocol, /*ata_flags*/ ata_flags, /*features*/ features, /*sector_count*/ sector_count, /*lba*/ lba, /*command*/ command, /*device*/ 0, /*icc*/ 0, /*auxiliary*/ auxiliary, /*control*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*cdb_storage*/ cdb_storage, /*cdb_storage_len*/ cdb_storage_len, /*minimum_cmd_size*/ 0, /*sense_len*/ sense_len, /*timeout*/ timeout); } return (retval); } int get_ata_status(struct cam_device *dev, union ccb *ccb, uint8_t *error, uint16_t *count, uint64_t *lba, uint8_t *device, uint8_t *status) { int retval = 0; switch (ccb->ccb_h.func_code) { case XPT_SCSI_IO: { uint8_t opcode; int error_code = 0, sense_key = 0, asc = 0, ascq = 0; /* * In this case, we have SCSI ATA PASS-THROUGH command, 12 * or 16 byte, and need to see what */ if (ccb->ccb_h.flags & CAM_CDB_POINTER) opcode = ccb->csio.cdb_io.cdb_ptr[0]; else opcode = ccb->csio.cdb_io.cdb_bytes[0]; if ((opcode != ATA_PASS_12) && (opcode != ATA_PASS_16)) { retval = 1; warnx("%s: unsupported opcode %02x", __func__, opcode); goto bailout; } retval = scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq); /* Note: the _ccb() variant returns 0 for an error */ if (retval == 0) { retval = 1; goto bailout; } else retval = 0; switch (error_code) { case SSD_DESC_CURRENT_ERROR: case SSD_DESC_DEFERRED_ERROR: { struct scsi_sense_data_desc *sense; struct scsi_sense_ata_ret_desc *desc; uint8_t *desc_ptr; sense = (struct scsi_sense_data_desc *) &ccb->csio.sense_data; desc_ptr = scsi_find_desc(sense, ccb->csio.sense_len - ccb->csio.sense_resid, SSD_DESC_ATA); if (desc_ptr == NULL) { cam_error_print(dev, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } desc = (struct scsi_sense_ata_ret_desc *)desc_ptr; *error = desc->error; *count = (desc->count_15_8 << 8) | desc->count_7_0; *lba = ((uint64_t)desc->lba_47_40 << 40) | ((uint64_t)desc->lba_39_32 << 32) | ((uint64_t)desc->lba_31_24 << 24) | (desc->lba_23_16 << 16) | (desc->lba_15_8 << 8) | desc->lba_7_0; *device = desc->device; *status = desc->status; /* * If the extend bit isn't set, the result is for a * 12-byte ATA PASS-THROUGH command or a 16 or 32 byte * command without the extend bit set. This means * that the device is supposed to return 28-bit * status. The count field is only 8 bits, and the * LBA field is only 8 bits. */ if ((desc->flags & SSD_DESC_ATA_FLAG_EXTEND) == 0){ *count &= 0xff; *lba &= 0x0fffffff; } break; } case SSD_CURRENT_ERROR: case SSD_DEFERRED_ERROR: { #if 0 struct scsi_sense_data_fixed *sense; #endif /* * XXX KDM need to support fixed sense data. */ warnx("%s: Fixed sense data not supported yet", __func__); retval = 1; goto bailout; break; /*NOTREACHED*/ } default: retval = 1; goto bailout; break; } break; } case XPT_ATA_IO: { struct ata_res *res; /* * In this case, we have an ATA command, and we need to * fill in the requested values from the result register * set. */ res = &ccb->ataio.res; *error = res->error; *status = res->status; *device = res->device; *count = res->sector_count; *lba = (res->lba_high << 16) | (res->lba_mid << 8) | (res->lba_low); if (res->flags & CAM_ATAIO_48BIT) { *count |= (res->sector_count_exp << 8); *lba |= ((uint64_t)res->lba_low_exp << 24) | ((uint64_t)res->lba_mid_exp << 32) | ((uint64_t)res->lba_high_exp << 40); } else { *lba |= (res->device & 0xf) << 24; } break; } default: retval = 1; break; } bailout: return (retval); } static void cpi_print(struct ccb_pathinq *cpi) { char adapter_str[1024]; uint64_t i; snprintf(adapter_str, sizeof(adapter_str), "%s%d:", cpi->dev_name, cpi->unit_number); fprintf(stdout, "%s SIM/HBA version: %d\n", adapter_str, cpi->version_num); for (i = 1; i < UINT8_MAX; i = i << 1) { const char *str; if ((i & cpi->hba_inquiry) == 0) continue; fprintf(stdout, "%s supports ", adapter_str); switch(i) { case PI_MDP_ABLE: str = "MDP message"; break; case PI_WIDE_32: str = "32 bit wide SCSI"; break; case PI_WIDE_16: str = "16 bit wide SCSI"; break; case PI_SDTR_ABLE: str = "SDTR message"; break; case PI_LINKED_CDB: str = "linked CDBs"; break; case PI_TAG_ABLE: str = "tag queue messages"; break; case PI_SOFT_RST: str = "soft reset alternative"; break; case PI_SATAPM: str = "SATA Port Multiplier"; break; default: str = "unknown PI bit set"; break; } fprintf(stdout, "%s\n", str); } for (i = 1; i < UINT32_MAX; i = i << 1) { const char *str; if ((i & cpi->hba_misc) == 0) continue; fprintf(stdout, "%s ", adapter_str); switch(i) { case PIM_ATA_EXT: str = "can understand ata_ext requests"; break; case PIM_EXTLUNS: str = "64bit extended LUNs supported"; break; case PIM_SCANHILO: str = "bus scans from high ID to low ID"; break; case PIM_NOREMOVE: str = "removable devices not included in scan"; break; case PIM_NOINITIATOR: str = "initiator role not supported"; break; case PIM_NOBUSRESET: str = "user has disabled initial BUS RESET or" " controller is in target/mixed mode"; break; case PIM_NO_6_BYTE: str = "do not send 6-byte commands"; break; case PIM_SEQSCAN: str = "scan bus sequentially"; break; case PIM_UNMAPPED: str = "unmapped I/O supported"; break; case PIM_NOSCAN: str = "does its own scanning"; break; default: str = "unknown PIM bit set"; break; } fprintf(stdout, "%s\n", str); } for (i = 1; i < UINT16_MAX; i = i << 1) { const char *str; if ((i & cpi->target_sprt) == 0) continue; fprintf(stdout, "%s supports ", adapter_str); switch(i) { case PIT_PROCESSOR: str = "target mode processor mode"; break; case PIT_PHASE: str = "target mode phase cog. mode"; break; case PIT_DISCONNECT: str = "disconnects in target mode"; break; case PIT_TERM_IO: str = "terminate I/O message in target mode"; break; case PIT_GRP_6: str = "group 6 commands in target mode"; break; case PIT_GRP_7: str = "group 7 commands in target mode"; break; default: str = "unknown PIT bit set"; break; } fprintf(stdout, "%s\n", str); } fprintf(stdout, "%s HBA engine count: %d\n", adapter_str, cpi->hba_eng_cnt); fprintf(stdout, "%s maximum target: %d\n", adapter_str, cpi->max_target); fprintf(stdout, "%s maximum LUN: %d\n", adapter_str, cpi->max_lun); fprintf(stdout, "%s highest path ID in subsystem: %d\n", adapter_str, cpi->hpath_id); fprintf(stdout, "%s initiator ID: %d\n", adapter_str, cpi->initiator_id); fprintf(stdout, "%s SIM vendor: %s\n", adapter_str, cpi->sim_vid); fprintf(stdout, "%s HBA vendor: %s\n", adapter_str, cpi->hba_vid); fprintf(stdout, "%s HBA vendor ID: 0x%04x\n", adapter_str, cpi->hba_vendor); fprintf(stdout, "%s HBA device ID: 0x%04x\n", adapter_str, cpi->hba_device); fprintf(stdout, "%s HBA subvendor ID: 0x%04x\n", adapter_str, cpi->hba_subvendor); fprintf(stdout, "%s HBA subdevice ID: 0x%04x\n", adapter_str, cpi->hba_subdevice); fprintf(stdout, "%s bus ID: %d\n", adapter_str, cpi->bus_id); fprintf(stdout, "%s base transfer speed: ", adapter_str); if (cpi->base_transfer_speed > 1000) fprintf(stdout, "%d.%03dMB/sec\n", cpi->base_transfer_speed / 1000, cpi->base_transfer_speed % 1000); else fprintf(stdout, "%dKB/sec\n", (cpi->base_transfer_speed % 1000) * 1000); fprintf(stdout, "%s maximum transfer size: %u bytes\n", adapter_str, cpi->maxio); } static int get_print_cts(struct cam_device *device, int user_settings, int quiet, struct ccb_trans_settings *cts) { int retval; union ccb *ccb; retval = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("get_print_cts: error allocating ccb"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; if (user_settings == 0) ccb->cts.type = CTS_TYPE_CURRENT_SETTINGS; else ccb->cts.type = CTS_TYPE_USER_SETTINGS; if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_GET_TRAN_SETTINGS CCB"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto get_print_cts_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_GET_TRANS_SETTINGS CCB failed"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto get_print_cts_bailout; } if (quiet == 0) cts_print(device, &ccb->cts); if (cts != NULL) bcopy(&ccb->cts, cts, sizeof(struct ccb_trans_settings)); get_print_cts_bailout: cam_freeccb(ccb); return (retval); } static int ratecontrol(struct cam_device *device, int task_attr, int retry_count, int timeout, int argc, char **argv, char *combinedopt) { int c; union ccb *ccb; int user_settings = 0; int retval = 0; int disc_enable = -1, tag_enable = -1; int mode = -1; int offset = -1; double syncrate = -1; int bus_width = -1; int quiet = 0; int change_settings = 0, send_tur = 0; struct ccb_pathinq cpi; ccb = cam_getccb(device); if (ccb == NULL) { warnx("ratecontrol: error allocating ccb"); return (1); } while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c){ case 'a': send_tur = 1; break; case 'c': user_settings = 0; break; case 'D': if (strncasecmp(optarg, "enable", 6) == 0) disc_enable = 1; else if (strncasecmp(optarg, "disable", 7) == 0) disc_enable = 0; else { warnx("-D argument \"%s\" is unknown", optarg); retval = 1; goto ratecontrol_bailout; } change_settings = 1; break; case 'M': mode = ata_string2mode(optarg); if (mode < 0) { warnx("unknown mode '%s'", optarg); retval = 1; goto ratecontrol_bailout; } change_settings = 1; break; case 'O': offset = strtol(optarg, NULL, 0); if (offset < 0) { warnx("offset value %d is < 0", offset); retval = 1; goto ratecontrol_bailout; } change_settings = 1; break; case 'q': quiet++; break; case 'R': syncrate = atof(optarg); if (syncrate < 0) { warnx("sync rate %f is < 0", syncrate); retval = 1; goto ratecontrol_bailout; } change_settings = 1; break; case 'T': if (strncasecmp(optarg, "enable", 6) == 0) tag_enable = 1; else if (strncasecmp(optarg, "disable", 7) == 0) tag_enable = 0; else { warnx("-T argument \"%s\" is unknown", optarg); retval = 1; goto ratecontrol_bailout; } change_settings = 1; break; case 'U': user_settings = 1; break; case 'W': bus_width = strtol(optarg, NULL, 0); if (bus_width < 0) { warnx("bus width %d is < 0", bus_width); retval = 1; goto ratecontrol_bailout; } change_settings = 1; break; default: break; } } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cpi); /* * Grab path inquiry information, so we can determine whether * or not the initiator is capable of the things that the user * requests. */ ccb->ccb_h.func_code = XPT_PATH_INQ; if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_PATH_INQ CCB"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto ratecontrol_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_PATH_INQ CCB failed"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto ratecontrol_bailout; } bcopy(&ccb->cpi, &cpi, sizeof(struct ccb_pathinq)); CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cts); if (quiet == 0) { fprintf(stdout, "%s parameters:\n", user_settings ? "User" : "Current"); } retval = get_print_cts(device, user_settings, quiet, &ccb->cts); if (retval != 0) goto ratecontrol_bailout; if (arglist & CAM_ARG_VERBOSE) cpi_print(&cpi); if (change_settings) { int didsettings = 0; struct ccb_trans_settings_spi *spi = NULL; struct ccb_trans_settings_pata *pata = NULL; struct ccb_trans_settings_sata *sata = NULL; struct ccb_trans_settings_ata *ata = NULL; struct ccb_trans_settings_scsi *scsi = NULL; if (ccb->cts.transport == XPORT_SPI) spi = &ccb->cts.xport_specific.spi; if (ccb->cts.transport == XPORT_ATA) pata = &ccb->cts.xport_specific.ata; if (ccb->cts.transport == XPORT_SATA) sata = &ccb->cts.xport_specific.sata; if (ccb->cts.protocol == PROTO_ATA) ata = &ccb->cts.proto_specific.ata; if (ccb->cts.protocol == PROTO_SCSI) scsi = &ccb->cts.proto_specific.scsi; ccb->cts.xport_specific.valid = 0; ccb->cts.proto_specific.valid = 0; if (spi && disc_enable != -1) { spi->valid |= CTS_SPI_VALID_DISC; if (disc_enable == 0) spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; else spi->flags |= CTS_SPI_FLAGS_DISC_ENB; didsettings++; } if (tag_enable != -1) { if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0) { warnx("HBA does not support tagged queueing, " "so you cannot modify tag settings"); retval = 1; goto ratecontrol_bailout; } if (ata) { ata->valid |= CTS_SCSI_VALID_TQ; if (tag_enable == 0) ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; else ata->flags |= CTS_ATA_FLAGS_TAG_ENB; didsettings++; } else if (scsi) { scsi->valid |= CTS_SCSI_VALID_TQ; if (tag_enable == 0) scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; else scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; didsettings++; } } if (spi && offset != -1) { if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { warnx("HBA is not capable of changing offset"); retval = 1; goto ratecontrol_bailout; } spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; spi->sync_offset = offset; didsettings++; } if (spi && syncrate != -1) { int prelim_sync_period; if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { warnx("HBA is not capable of changing " "transfer rates"); retval = 1; goto ratecontrol_bailout; } spi->valid |= CTS_SPI_VALID_SYNC_RATE; /* * The sync rate the user gives us is in MHz. * We need to translate it into KHz for this * calculation. */ syncrate *= 1000; /* * Next, we calculate a "preliminary" sync period * in tenths of a nanosecond. */ if (syncrate == 0) prelim_sync_period = 0; else prelim_sync_period = 10000000 / syncrate; spi->sync_period = scsi_calc_syncparam(prelim_sync_period); didsettings++; } if (sata && syncrate != -1) { if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { warnx("HBA is not capable of changing " "transfer rates"); retval = 1; goto ratecontrol_bailout; } if (!user_settings) { warnx("You can modify only user rate " "settings for SATA"); retval = 1; goto ratecontrol_bailout; } sata->revision = ata_speed2revision(syncrate * 100); if (sata->revision < 0) { warnx("Invalid rate %f", syncrate); retval = 1; goto ratecontrol_bailout; } sata->valid |= CTS_SATA_VALID_REVISION; didsettings++; } if ((pata || sata) && mode != -1) { if ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0) { warnx("HBA is not capable of changing " "transfer rates"); retval = 1; goto ratecontrol_bailout; } if (!user_settings) { warnx("You can modify only user mode " "settings for ATA/SATA"); retval = 1; goto ratecontrol_bailout; } if (pata) { pata->mode = mode; pata->valid |= CTS_ATA_VALID_MODE; } else { sata->mode = mode; sata->valid |= CTS_SATA_VALID_MODE; } didsettings++; } /* * The bus_width argument goes like this: * 0 == 8 bit * 1 == 16 bit * 2 == 32 bit * Therefore, if you shift the number of bits given on the * command line right by 4, you should get the correct * number. */ if (spi && bus_width != -1) { /* * We might as well validate things here with a * decipherable error message, rather than what * will probably be an indecipherable error message * by the time it gets back to us. */ if ((bus_width == 16) && ((cpi.hba_inquiry & PI_WIDE_16) == 0)) { warnx("HBA does not support 16 bit bus width"); retval = 1; goto ratecontrol_bailout; } else if ((bus_width == 32) && ((cpi.hba_inquiry & PI_WIDE_32) == 0)) { warnx("HBA does not support 32 bit bus width"); retval = 1; goto ratecontrol_bailout; } else if ((bus_width != 8) && (bus_width != 16) && (bus_width != 32)) { warnx("Invalid bus width %d", bus_width); retval = 1; goto ratecontrol_bailout; } spi->valid |= CTS_SPI_VALID_BUS_WIDTH; spi->bus_width = bus_width >> 4; didsettings++; } if (didsettings == 0) { goto ratecontrol_bailout; } ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; if (cam_send_ccb(device, ccb) < 0) { perror("error sending XPT_SET_TRAN_SETTINGS CCB"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto ratecontrol_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { warnx("XPT_SET_TRANS_SETTINGS CCB failed"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto ratecontrol_bailout; } } if (send_tur) { retval = testunitready(device, task_attr, retry_count, timeout, (arglist & CAM_ARG_VERBOSE) ? 0 : 1); /* * If the TUR didn't succeed, just bail. */ if (retval != 0) { if (quiet == 0) fprintf(stderr, "Test Unit Ready failed\n"); goto ratecontrol_bailout; } } if ((change_settings || send_tur) && !quiet && (ccb->cts.transport == XPORT_ATA || ccb->cts.transport == XPORT_SATA || send_tur)) { fprintf(stdout, "New parameters:\n"); retval = get_print_cts(device, user_settings, 0, NULL); } ratecontrol_bailout: cam_freeccb(ccb); return (retval); } static int scsiformat(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { union ccb *ccb; int c; int ycount = 0, quiet = 0; int error = 0, retval = 0; int use_timeout = 10800 * 1000; int immediate = 1; struct format_defect_list_header fh; u_int8_t *data_ptr = NULL; u_int32_t dxfer_len = 0; u_int8_t byte2 = 0; int num_warnings = 0; int reportonly = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("scsiformat: error allocating ccb"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'q': quiet++; break; case 'r': reportonly = 1; break; case 'w': immediate = 0; break; case 'y': ycount++; break; } } if (reportonly) goto doreport; if (quiet == 0) { fprintf(stdout, "You are about to REMOVE ALL DATA from the " "following device:\n"); error = scsidoinquiry(device, argc, argv, combinedopt, task_attr, retry_count, timeout); if (error != 0) { warnx("scsiformat: error sending inquiry"); goto scsiformat_bailout; } } if (ycount == 0) { if (!get_confirmation()) { error = 1; goto scsiformat_bailout; } } if (timeout != 0) use_timeout = timeout; if (quiet == 0) { fprintf(stdout, "Current format timeout is %d seconds\n", use_timeout / 1000); } /* * If the user hasn't disabled questions and didn't specify a * timeout on the command line, ask them if they want the current * timeout. */ if ((ycount == 0) && (timeout == 0)) { char str[1024]; int new_timeout = 0; fprintf(stdout, "Enter new timeout in seconds or press\n" "return to keep the current timeout [%d] ", use_timeout / 1000); if (fgets(str, sizeof(str), stdin) != NULL) { if (str[0] != '\0') new_timeout = atoi(str); } if (new_timeout != 0) { use_timeout = new_timeout * 1000; fprintf(stdout, "Using new timeout value %d\n", use_timeout / 1000); } } /* * Keep this outside the if block below to silence any unused * variable warnings. */ bzero(&fh, sizeof(fh)); /* * If we're in immediate mode, we've got to include the format * header */ if (immediate != 0) { fh.byte2 = FU_DLH_IMMED; data_ptr = (u_int8_t *)&fh; dxfer_len = sizeof(fh); byte2 = FU_FMT_DATA; } else if (quiet == 0) { fprintf(stdout, "Formatting..."); fflush(stdout); } scsi_format_unit(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* byte2 */ byte2, /* ileave */ 0, /* data_ptr */ data_ptr, /* dxfer_len */ dxfer_len, /* sense_len */ SSD_FULL_SIZE, /* timeout */ use_timeout); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((immediate == 0) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP))) { const char errstr[] = "error sending format command"; if (retval < 0) warn(errstr); else warnx(errstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto scsiformat_bailout; } /* * If we ran in non-immediate mode, we already checked for errors * above and printed out any necessary information. If we're in * immediate mode, we need to loop through and get status * information periodically. */ if (immediate == 0) { if (quiet == 0) { fprintf(stdout, "Format Complete\n"); } goto scsiformat_bailout; } doreport: do { cam_status status; CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); /* * There's really no need to do error recovery or * retries here, since we're just going to sit in a * loop and wait for the device to finish formatting. */ scsi_test_unit_ready(&ccb->csio, /* retries */ 0, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* sense_len */ SSD_FULL_SIZE, /* timeout */ 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; retval = cam_send_ccb(device, ccb); /* * If we get an error from the ioctl, bail out. SCSI * errors are expected. */ if (retval < 0) { warn("error sending CAMIOCOMMAND ioctl"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto scsiformat_bailout; } status = ccb->ccb_h.status & CAM_STATUS_MASK; if ((status != CAM_REQ_CMP) && (status == CAM_SCSI_STATUS_ERROR) && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; sense = &ccb->csio.sense_data; scsi_extract_sense_len(sense, ccb->csio.sense_len - ccb->csio.sense_resid, &error_code, &sense_key, &asc, &ascq, /*show_errors*/ 1); /* * According to the SCSI-2 and SCSI-3 specs, a * drive that is in the middle of a format should * return NOT READY with an ASC of "logical unit * not ready, format in progress". The sense key * specific bytes will then be a progress indicator. */ if ((sense_key == SSD_KEY_NOT_READY) && (asc == 0x04) && (ascq == 0x04)) { uint8_t sks[3]; if ((scsi_get_sks(sense, ccb->csio.sense_len - ccb->csio.sense_resid, sks) == 0) && (quiet == 0)) { uint32_t val; u_int64_t percentage; val = scsi_2btoul(&sks[1]); percentage = 10000ull * val; fprintf(stdout, "\rFormatting: %ju.%02u %% " "(%u/%d) done", (uintmax_t)(percentage / (0x10000 * 100)), (unsigned)((percentage / 0x10000) % 100), val, 0x10000); fflush(stdout); } else if ((quiet == 0) && (++num_warnings <= 1)) { warnx("Unexpected SCSI Sense Key " "Specific value returned " "during format:"); scsi_sense_print(device, &ccb->csio, stderr); warnx("Unable to print status " "information, but format will " "proceed."); warnx("will exit when format is " "complete"); } sleep(1); } else { warnx("Unexpected SCSI error during format"); cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); error = 1; goto scsiformat_bailout; } } else if (status != CAM_REQ_CMP) { warnx("Unexpected CAM status %#x", status); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); error = 1; goto scsiformat_bailout; } } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); if (quiet == 0) fprintf(stdout, "\nFormat Complete\n"); scsiformat_bailout: cam_freeccb(ccb); return (error); } static int scsisanitize(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { union ccb *ccb; u_int8_t action = 0; int c; int ycount = 0, quiet = 0; int error = 0, retval = 0; int use_timeout = 10800 * 1000; int immediate = 1; int invert = 0; int passes = 0; int ause = 0; int fd = -1; const char *pattern = NULL; u_int8_t *data_ptr = NULL; u_int32_t dxfer_len = 0; u_int8_t byte2 = 0; int num_warnings = 0; int reportonly = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("scsisanitize: error allocating ccb"); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch(c) { case 'a': if (strcasecmp(optarg, "overwrite") == 0) action = SSZ_SERVICE_ACTION_OVERWRITE; else if (strcasecmp(optarg, "block") == 0) action = SSZ_SERVICE_ACTION_BLOCK_ERASE; else if (strcasecmp(optarg, "crypto") == 0) action = SSZ_SERVICE_ACTION_CRYPTO_ERASE; else if (strcasecmp(optarg, "exitfailure") == 0) action = SSZ_SERVICE_ACTION_EXIT_MODE_FAILURE; else { warnx("invalid service operation \"%s\"", optarg); error = 1; goto scsisanitize_bailout; } break; case 'c': passes = strtol(optarg, NULL, 0); if (passes < 1 || passes > 31) { warnx("invalid passes value %d", passes); error = 1; goto scsisanitize_bailout; } break; case 'I': invert = 1; break; case 'P': pattern = optarg; break; case 'q': quiet++; break; case 'U': ause = 1; break; case 'r': reportonly = 1; break; case 'w': immediate = 0; break; case 'y': ycount++; break; } } if (reportonly) goto doreport; if (action == 0) { warnx("an action is required"); error = 1; goto scsisanitize_bailout; } else if (action == SSZ_SERVICE_ACTION_OVERWRITE) { struct scsi_sanitize_parameter_list *pl; struct stat sb; ssize_t sz, amt; if (pattern == NULL) { warnx("overwrite action requires -P argument"); error = 1; goto scsisanitize_bailout; } fd = open(pattern, O_RDONLY); if (fd < 0) { warn("cannot open pattern file %s", pattern); error = 1; goto scsisanitize_bailout; } if (fstat(fd, &sb) < 0) { warn("cannot stat pattern file %s", pattern); error = 1; goto scsisanitize_bailout; } sz = sb.st_size; if (sz > SSZPL_MAX_PATTERN_LENGTH) { warnx("pattern file size exceeds maximum value %d", SSZPL_MAX_PATTERN_LENGTH); error = 1; goto scsisanitize_bailout; } dxfer_len = sizeof(*pl) + sz; data_ptr = calloc(1, dxfer_len); if (data_ptr == NULL) { warnx("cannot allocate parameter list buffer"); error = 1; goto scsisanitize_bailout; } amt = read(fd, data_ptr + sizeof(*pl), sz); if (amt < 0) { warn("cannot read pattern file"); error = 1; goto scsisanitize_bailout; } else if (amt != sz) { warnx("short pattern file read"); error = 1; goto scsisanitize_bailout; } pl = (struct scsi_sanitize_parameter_list *)data_ptr; if (passes == 0) pl->byte1 = 1; else pl->byte1 = passes; if (invert != 0) pl->byte1 |= SSZPL_INVERT; scsi_ulto2b(sz, pl->length); } else { const char *arg; if (passes != 0) arg = "-c"; else if (invert != 0) arg = "-I"; else if (pattern != NULL) arg = "-P"; else arg = NULL; if (arg != NULL) { warnx("%s argument only valid with overwrite " "operation", arg); error = 1; goto scsisanitize_bailout; } } if (quiet == 0) { fprintf(stdout, "You are about to REMOVE ALL DATA from the " "following device:\n"); error = scsidoinquiry(device, argc, argv, combinedopt, task_attr, retry_count, timeout); if (error != 0) { warnx("scsisanitize: error sending inquiry"); goto scsisanitize_bailout; } } if (ycount == 0) { if (!get_confirmation()) { error = 1; goto scsisanitize_bailout; } } if (timeout != 0) use_timeout = timeout; if (quiet == 0) { fprintf(stdout, "Current sanitize timeout is %d seconds\n", use_timeout / 1000); } /* * If the user hasn't disabled questions and didn't specify a * timeout on the command line, ask them if they want the current * timeout. */ if ((ycount == 0) && (timeout == 0)) { char str[1024]; int new_timeout = 0; fprintf(stdout, "Enter new timeout in seconds or press\n" "return to keep the current timeout [%d] ", use_timeout / 1000); if (fgets(str, sizeof(str), stdin) != NULL) { if (str[0] != '\0') new_timeout = atoi(str); } if (new_timeout != 0) { use_timeout = new_timeout * 1000; fprintf(stdout, "Using new timeout value %d\n", use_timeout / 1000); } } byte2 = action; if (ause != 0) byte2 |= SSZ_UNRESTRICTED_EXIT; if (immediate != 0) byte2 |= SSZ_IMMED; scsi_sanitize(&ccb->csio, /* retries */ retry_count, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* byte2 */ byte2, /* control */ 0, /* data_ptr */ data_ptr, /* dxfer_len */ dxfer_len, /* sense_len */ SSD_FULL_SIZE, /* timeout */ use_timeout); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { warn("error sending sanitize command"); error = 1; goto scsisanitize_bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR) { sense = &ccb->csio.sense_data; scsi_extract_sense_len(sense, ccb->csio.sense_len - ccb->csio.sense_resid, &error_code, &sense_key, &asc, &ascq, /*show_errors*/ 1); if (sense_key == SSD_KEY_ILLEGAL_REQUEST && asc == 0x20 && ascq == 0x00) warnx("sanitize is not supported by " "this device"); else warnx("error sanitizing this device"); } else warnx("error sanitizing this device"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto scsisanitize_bailout; } /* * If we ran in non-immediate mode, we already checked for errors * above and printed out any necessary information. If we're in * immediate mode, we need to loop through and get status * information periodically. */ if (immediate == 0) { if (quiet == 0) { fprintf(stdout, "Sanitize Complete\n"); } goto scsisanitize_bailout; } doreport: do { cam_status status; CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); /* * There's really no need to do error recovery or * retries here, since we're just going to sit in a * loop and wait for the device to finish sanitizing. */ scsi_test_unit_ready(&ccb->csio, /* retries */ 0, /* cbfcnp */ NULL, /* tag_action */ task_attr, /* sense_len */ SSD_FULL_SIZE, /* timeout */ 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; retval = cam_send_ccb(device, ccb); /* * If we get an error from the ioctl, bail out. SCSI * errors are expected. */ if (retval < 0) { warn("error sending CAMIOCOMMAND ioctl"); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto scsisanitize_bailout; } status = ccb->ccb_h.status & CAM_STATUS_MASK; if ((status != CAM_REQ_CMP) && (status == CAM_SCSI_STATUS_ERROR) && ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0)) { struct scsi_sense_data *sense; int error_code, sense_key, asc, ascq; sense = &ccb->csio.sense_data; scsi_extract_sense_len(sense, ccb->csio.sense_len - ccb->csio.sense_resid, &error_code, &sense_key, &asc, &ascq, /*show_errors*/ 1); /* * According to the SCSI-3 spec, a drive that is in the * middle of a sanitize should return NOT READY with an * ASC of "logical unit not ready, sanitize in * progress". The sense key specific bytes will then * be a progress indicator. */ if ((sense_key == SSD_KEY_NOT_READY) && (asc == 0x04) && (ascq == 0x1b)) { uint8_t sks[3]; if ((scsi_get_sks(sense, ccb->csio.sense_len - ccb->csio.sense_resid, sks) == 0) && (quiet == 0)) { int val; u_int64_t percentage; val = scsi_2btoul(&sks[1]); percentage = 10000 * val; fprintf(stdout, "\rSanitizing: %ju.%02u %% " "(%d/%d) done", (uintmax_t)(percentage / (0x10000 * 100)), (unsigned)((percentage / 0x10000) % 100), val, 0x10000); fflush(stdout); } else if ((quiet == 0) && (++num_warnings <= 1)) { warnx("Unexpected SCSI Sense Key " "Specific value returned " "during sanitize:"); scsi_sense_print(device, &ccb->csio, stderr); warnx("Unable to print status " "information, but sanitze will " "proceed."); warnx("will exit when sanitize is " "complete"); } sleep(1); } else { warnx("Unexpected SCSI error during sanitize"); cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); error = 1; goto scsisanitize_bailout; } } else if (status != CAM_REQ_CMP) { warnx("Unexpected CAM status %#x", status); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); error = 1; goto scsisanitize_bailout; } } while((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP); if (quiet == 0) fprintf(stdout, "\nSanitize Complete\n"); scsisanitize_bailout: if (fd >= 0) close(fd); if (data_ptr != NULL) free(data_ptr); cam_freeccb(ccb); return (error); } static int scsireportluns(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { union ccb *ccb; int c, countonly, lunsonly; struct scsi_report_luns_data *lundata; int alloc_len; uint8_t report_type; uint32_t list_len, i, j; int retval; retval = 0; lundata = NULL; report_type = RPL_REPORT_DEFAULT; ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating ccb", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); countonly = 0; lunsonly = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'c': countonly++; break; case 'l': lunsonly++; break; case 'r': if (strcasecmp(optarg, "default") == 0) report_type = RPL_REPORT_DEFAULT; else if (strcasecmp(optarg, "wellknown") == 0) report_type = RPL_REPORT_WELLKNOWN; else if (strcasecmp(optarg, "all") == 0) report_type = RPL_REPORT_ALL; else { warnx("%s: invalid report type \"%s\"", __func__, optarg); retval = 1; goto bailout; } break; default: break; } } if ((countonly != 0) && (lunsonly != 0)) { warnx("%s: you can only specify one of -c or -l", __func__); retval = 1; goto bailout; } /* * According to SPC-4, the allocation length must be at least 16 * bytes -- enough for the header and one LUN. */ alloc_len = sizeof(*lundata) + 8; retry: lundata = malloc(alloc_len); if (lundata == NULL) { warn("%s: error mallocing %d bytes", __func__, alloc_len); retval = 1; goto bailout; } scsi_report_luns(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*tag_action*/ task_attr, /*select_report*/ report_type, /*rpl_buf*/ lundata, /*alloc_len*/ alloc_len, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { warn("error sending REPORT LUNS command"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } list_len = scsi_4btoul(lundata->length); /* * If we need to list the LUNs, and our allocation * length was too short, reallocate and retry. */ if ((countonly == 0) && (list_len > (alloc_len - sizeof(*lundata)))) { alloc_len = list_len + sizeof(*lundata); free(lundata); goto retry; } if (lunsonly == 0) fprintf(stdout, "%u LUN%s found\n", list_len / 8, ((list_len / 8) > 1) ? "s" : ""); if (countonly != 0) goto bailout; for (i = 0; i < (list_len / 8); i++) { int no_more; no_more = 0; for (j = 0; j < sizeof(lundata->luns[i].lundata); j += 2) { if (j != 0) fprintf(stdout, ","); switch (lundata->luns[i].lundata[j] & RPL_LUNDATA_ATYP_MASK) { case RPL_LUNDATA_ATYP_PERIPH: if ((lundata->luns[i].lundata[j] & RPL_LUNDATA_PERIPH_BUS_MASK) != 0) fprintf(stdout, "%d:", lundata->luns[i].lundata[j] & RPL_LUNDATA_PERIPH_BUS_MASK); else if ((j == 0) && ((lundata->luns[i].lundata[j+2] & RPL_LUNDATA_PERIPH_BUS_MASK) == 0)) no_more = 1; fprintf(stdout, "%d", lundata->luns[i].lundata[j+1]); break; case RPL_LUNDATA_ATYP_FLAT: { uint8_t tmplun[2]; tmplun[0] = lundata->luns[i].lundata[j] & RPL_LUNDATA_FLAT_LUN_MASK; tmplun[1] = lundata->luns[i].lundata[j+1]; fprintf(stdout, "%d", scsi_2btoul(tmplun)); no_more = 1; break; } case RPL_LUNDATA_ATYP_LUN: fprintf(stdout, "%d:%d:%d", (lundata->luns[i].lundata[j+1] & RPL_LUNDATA_LUN_BUS_MASK) >> 5, lundata->luns[i].lundata[j] & RPL_LUNDATA_LUN_TARG_MASK, lundata->luns[i].lundata[j+1] & RPL_LUNDATA_LUN_LUN_MASK); break; case RPL_LUNDATA_ATYP_EXTLUN: { int field_len_code, eam_code; eam_code = lundata->luns[i].lundata[j] & RPL_LUNDATA_EXT_EAM_MASK; field_len_code = (lundata->luns[i].lundata[j] & RPL_LUNDATA_EXT_LEN_MASK) >> 4; if ((eam_code == RPL_LUNDATA_EXT_EAM_WK) && (field_len_code == 0x00)) { fprintf(stdout, "%d", lundata->luns[i].lundata[j+1]); } else if ((eam_code == RPL_LUNDATA_EXT_EAM_NOT_SPEC) && (field_len_code == 0x03)) { uint8_t tmp_lun[8]; /* * This format takes up all 8 bytes. * If we aren't starting at offset 0, * that's a bug. */ if (j != 0) { fprintf(stdout, "Invalid " "offset %d for " "Extended LUN not " "specified format", j); no_more = 1; break; } bzero(tmp_lun, sizeof(tmp_lun)); bcopy(&lundata->luns[i].lundata[j+1], &tmp_lun[1], sizeof(tmp_lun) - 1); fprintf(stdout, "%#jx", (intmax_t)scsi_8btou64(tmp_lun)); no_more = 1; } else { fprintf(stderr, "Unknown Extended LUN" "Address method %#x, length " "code %#x", eam_code, field_len_code); no_more = 1; } break; } default: fprintf(stderr, "Unknown LUN address method " "%#x\n", lundata->luns[i].lundata[0] & RPL_LUNDATA_ATYP_MASK); break; } /* * For the flat addressing method, there are no * other levels after it. */ if (no_more != 0) break; } fprintf(stdout, "\n"); } bailout: cam_freeccb(ccb); free(lundata); return (retval); } static int scsireadcapacity(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout) { union ccb *ccb; int blocksizeonly, humanize, numblocks, quiet, sizeonly, baseten, longonly; struct scsi_read_capacity_data rcap; struct scsi_read_capacity_data_long rcaplong; uint64_t maxsector; uint32_t block_len; int retval; int c; blocksizeonly = 0; humanize = 0; longonly = 0; numblocks = 0; quiet = 0; sizeonly = 0; baseten = 0; retval = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating ccb", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'b': blocksizeonly++; break; case 'h': humanize++; baseten = 0; break; case 'H': humanize++; baseten++; break; case 'l': longonly++; break; case 'N': numblocks++; break; case 'q': quiet++; break; case 's': sizeonly++; break; default: break; } } if ((blocksizeonly != 0) && (numblocks != 0)) { warnx("%s: you can only specify one of -b or -N", __func__); retval = 1; goto bailout; } if ((blocksizeonly != 0) && (sizeonly != 0)) { warnx("%s: you can only specify one of -b or -s", __func__); retval = 1; goto bailout; } if ((humanize != 0) && (quiet != 0)) { warnx("%s: you can only specify one of -h/-H or -q", __func__); retval = 1; goto bailout; } if ((humanize != 0) && (blocksizeonly != 0)) { warnx("%s: you can only specify one of -h/-H or -b", __func__); retval = 1; goto bailout; } if (longonly != 0) goto long_only; scsi_read_capacity(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*tag_action*/ task_attr, &rcap, SSD_FULL_SIZE, /*timeout*/ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { warn("error sending READ CAPACITY command"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } maxsector = scsi_4btoul(rcap.addr); block_len = scsi_4btoul(rcap.length); /* * A last block of 2^32-1 means that the true capacity is over 2TB, * and we need to issue the long READ CAPACITY to get the real * capacity. Otherwise, we're all set. */ if (maxsector != 0xffffffff) goto do_print; long_only: scsi_read_capacity_16(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*tag_action*/ task_attr, /*lba*/ 0, /*reladdr*/ 0, /*pmi*/ 0, /*rcap_buf*/ (uint8_t *)&rcaplong, /*rcap_buf_len*/ sizeof(rcaplong), /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ timeout ? timeout : 5000); /* Disable freezing the device queue */ ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (arglist & CAM_ARG_ERR_RECOVER) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { warn("error sending READ CAPACITY (16) command"); if (arglist & CAM_ARG_VERBOSE) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } maxsector = scsi_8btou64(rcaplong.addr); block_len = scsi_4btoul(rcaplong.length); do_print: if (blocksizeonly == 0) { /* * Humanize implies !quiet, and also implies numblocks. */ if (humanize != 0) { char tmpstr[6]; int64_t tmpbytes; int ret; tmpbytes = (maxsector + 1) * block_len; ret = humanize_number(tmpstr, sizeof(tmpstr), tmpbytes, "", HN_AUTOSCALE, HN_B | HN_DECIMAL | ((baseten != 0) ? HN_DIVISOR_1000 : 0)); if (ret == -1) { warnx("%s: humanize_number failed!", __func__); retval = 1; goto bailout; } fprintf(stdout, "Device Size: %s%s", tmpstr, (sizeonly == 0) ? ", " : "\n"); } else if (numblocks != 0) { fprintf(stdout, "%s%ju%s", (quiet == 0) ? "Blocks: " : "", (uintmax_t)maxsector + 1, (sizeonly == 0) ? ", " : "\n"); } else { fprintf(stdout, "%s%ju%s", (quiet == 0) ? "Last Block: " : "", (uintmax_t)maxsector, (sizeonly == 0) ? ", " : "\n"); } } if (sizeonly == 0) fprintf(stdout, "%s%u%s\n", (quiet == 0) ? "Block Length: " : "", block_len, (quiet == 0) ? " bytes" : ""); bailout: cam_freeccb(ccb); return (retval); } static int smpcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { int c, error = 0; union ccb *ccb; uint8_t *smp_request = NULL, *smp_response = NULL; int request_size = 0, response_size = 0; int fd_request = 0, fd_response = 0; char *datastr = NULL; struct get_hook hook; int retval; int flags = 0; /* * Note that at the moment we don't support sending SMP CCBs to * devices that aren't probed by CAM. */ ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'R': arglist |= CAM_ARG_CMD_IN; response_size = strtol(optarg, NULL, 0); if (response_size <= 0) { warnx("invalid number of response bytes %d", response_size); error = 1; goto smpcmd_bailout; } hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; optind++; datastr = cget(&hook, NULL); /* * If the user supplied "-" instead of a format, he * wants the data to be written to stdout. */ if ((datastr != NULL) && (datastr[0] == '-')) fd_response = 1; smp_response = (u_int8_t *)malloc(response_size); if (smp_response == NULL) { warn("can't malloc memory for SMP response"); error = 1; goto smpcmd_bailout; } break; case 'r': arglist |= CAM_ARG_CMD_OUT; request_size = strtol(optarg, NULL, 0); if (request_size <= 0) { warnx("invalid number of request bytes %d", request_size); error = 1; goto smpcmd_bailout; } hook.argc = argc - optind; hook.argv = argv + optind; hook.got = 0; datastr = cget(&hook, NULL); smp_request = (u_int8_t *)malloc(request_size); if (smp_request == NULL) { warn("can't malloc memory for SMP request"); error = 1; goto smpcmd_bailout; } bzero(smp_request, request_size); /* * If the user supplied "-" instead of a format, he * wants the data to be read from stdin. */ if ((datastr != NULL) && (datastr[0] == '-')) fd_request = 1; else buff_encode_visit(smp_request, request_size, datastr, iget, &hook); optind += hook.got; break; default: break; } } /* * If fd_data is set, and we're writing to the device, we need to * read the data the user wants written from stdin. */ if ((fd_request == 1) && (arglist & CAM_ARG_CMD_OUT)) { ssize_t amt_read; int amt_to_read = request_size; u_int8_t *buf_ptr = smp_request; for (amt_read = 0; amt_to_read > 0; amt_read = read(STDIN_FILENO, buf_ptr, amt_to_read)) { if (amt_read == -1) { warn("error reading data from stdin"); error = 1; goto smpcmd_bailout; } amt_to_read -= amt_read; buf_ptr += amt_read; } } if (((arglist & CAM_ARG_CMD_IN) == 0) || ((arglist & CAM_ARG_CMD_OUT) == 0)) { warnx("%s: need both the request (-r) and response (-R) " "arguments", __func__); error = 1; goto smpcmd_bailout; } flags |= CAM_DEV_QFRZDIS; cam_fill_smpio(&ccb->smpio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, /*smp_request*/ smp_request, /*smp_request_len*/ request_size, /*smp_response*/ smp_response, /*smp_response_len*/ response_size, /*timeout*/ timeout ? timeout : 5000); ccb->smpio.flags = SMP_FLAG_NONE; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } } if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (response_size > 0)) { if (fd_response == 0) { buff_decode_visit(smp_response, response_size, datastr, arg_put, NULL); fprintf(stdout, "\n"); } else { ssize_t amt_written; int amt_to_write = response_size; u_int8_t *buf_ptr = smp_response; for (amt_written = 0; (amt_to_write > 0) && (amt_written = write(STDOUT_FILENO, buf_ptr, amt_to_write)) > 0;){ amt_to_write -= amt_written; buf_ptr += amt_written; } if (amt_written == -1) { warn("error writing data to stdout"); error = 1; goto smpcmd_bailout; } else if ((amt_written == 0) && (amt_to_write > 0)) { warnx("only wrote %u bytes out of %u", response_size - amt_to_write, response_size); } } } smpcmd_bailout: if (ccb != NULL) cam_freeccb(ccb); if (smp_request != NULL) free(smp_request); if (smp_response != NULL) free(smp_response); return (error); } static int mmcsdcmd(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { int c, error = 0; union ccb *ccb; int32_t mmc_opcode = 0, mmc_arg = 0; int32_t mmc_flags = -1; int retval; int is_write = 0; int is_bw_4 = 0, is_bw_1 = 0; int is_highspeed = 0, is_stdspeed = 0; int is_info_request = 0; int flags = 0; uint8_t mmc_data_byte = 0; /* For IO_RW_EXTENDED command */ uint8_t *mmc_data = NULL; struct mmc_data mmc_d; int mmc_data_len = 0; /* * Note that at the moment we don't support sending SMP CCBs to * devices that aren't probed by CAM. */ ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); return (1); } bzero(&(&ccb->ccb_h)[1], sizeof(union ccb) - sizeof(struct ccb_hdr)); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case '4': is_bw_4 = 1; break; case '1': is_bw_1 = 1; break; case 'S': if (!strcmp(optarg, "high")) is_highspeed = 1; else is_stdspeed = 1; break; case 'I': is_info_request = 1; break; case 'c': mmc_opcode = strtol(optarg, NULL, 0); if (mmc_opcode < 0) { warnx("invalid MMC opcode %d", mmc_opcode); error = 1; goto mmccmd_bailout; } break; case 'a': mmc_arg = strtol(optarg, NULL, 0); if (mmc_arg < 0) { warnx("invalid MMC arg %d", mmc_arg); error = 1; goto mmccmd_bailout; } break; case 'f': mmc_flags = strtol(optarg, NULL, 0); if (mmc_flags < 0) { warnx("invalid MMC flags %d", mmc_flags); error = 1; goto mmccmd_bailout; } break; case 'l': mmc_data_len = strtol(optarg, NULL, 0); if (mmc_data_len <= 0) { warnx("invalid MMC data len %d", mmc_data_len); error = 1; goto mmccmd_bailout; } break; case 'W': is_write = 1; break; case 'b': mmc_data_byte = strtol(optarg, NULL, 0); break; default: break; } } flags |= CAM_DEV_QFRZDIS; /* masks are broken?! */ /* If flags are left default, supply the right flags */ if (mmc_flags < 0) switch (mmc_opcode) { case MMC_GO_IDLE_STATE: mmc_flags = MMC_RSP_NONE | MMC_CMD_BC; break; case IO_SEND_OP_COND: mmc_flags = MMC_RSP_R4; break; case SD_SEND_RELATIVE_ADDR: mmc_flags = MMC_RSP_R6 | MMC_CMD_BCR; break; case MMC_SELECT_CARD: mmc_flags = MMC_RSP_R1B | MMC_CMD_AC; mmc_arg = mmc_arg << 16; break; case SD_IO_RW_DIRECT: mmc_flags = MMC_RSP_R5 | MMC_CMD_AC; mmc_arg = SD_IO_RW_ADR(mmc_arg); if (is_write) mmc_arg |= SD_IO_RW_WR | SD_IO_RW_RAW | SD_IO_RW_DAT(mmc_data_byte); break; case SD_IO_RW_EXTENDED: mmc_flags = MMC_RSP_R5 | MMC_CMD_ADTC; mmc_arg = SD_IO_RW_ADR(mmc_arg); int len_arg = mmc_data_len; if (mmc_data_len == 512) len_arg = 0; // Byte mode mmc_arg |= SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR; // Block mode // mmc_arg |= SD_IOE_RW_BLK | SD_IOE_RW_LEN(len_arg) | SD_IO_RW_INCR; break; default: mmc_flags = MMC_RSP_R1; break; } // Switch bus width instead of sending IO command if (is_bw_4 || is_bw_1) { struct ccb_trans_settings_mmc *cts; ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; ccb->ccb_h.flags = 0; cts = &ccb->cts.proto_specific.mmc; cts->ios.bus_width = is_bw_4 == 1 ? bus_width_4 : bus_width_1; cts->ios_valid = MMC_BW; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { warn("Error sending command"); } else { printf("Parameters set OK\n"); } cam_freeccb(ccb); return (retval); } // Switch bus speed instead of sending IO command if (is_stdspeed || is_highspeed) { struct ccb_trans_settings_mmc *cts; ccb->ccb_h.func_code = XPT_SET_TRAN_SETTINGS; ccb->ccb_h.flags = 0; cts = &ccb->cts.proto_specific.mmc; cts->ios.timing = is_highspeed == 1 ? bus_timing_hs : bus_timing_normal; cts->ios_valid = MMC_BT; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { warn("Error sending command"); } else { printf("Speed set OK (HS: %d)\n", is_highspeed); } cam_freeccb(ccb); return (retval); } // Get information about controller and its settings if (is_info_request) { ccb->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; ccb->ccb_h.flags = 0; struct ccb_trans_settings_mmc *cts; cts = &ccb->cts.proto_specific.mmc; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { warn("Error sending command"); return (retval); } printf("Host controller information\n"); printf("Host OCR: 0x%x\n", cts->host_ocr); printf("Min frequency: %u KHz\n", cts->host_f_min / 1000); printf("Max frequency: %u MHz\n", cts->host_f_max / 1000000); printf("Supported bus width: "); if (cts->host_caps & MMC_CAP_4_BIT_DATA) printf(" 4 bit\n"); if (cts->host_caps & MMC_CAP_8_BIT_DATA) printf(" 8 bit\n"); printf("\nCurrent settings:\n"); printf("Bus width: "); switch (cts->ios.bus_width) { case bus_width_1: printf("1 bit\n"); break; case bus_width_4: printf("4 bit\n"); break; case bus_width_8: printf("8 bit\n"); break; } printf("Freq: %d.%03d MHz%s\n", cts->ios.clock / 1000000, (cts->ios.clock / 1000) % 1000, cts->ios.timing == bus_timing_hs ? "(high-speed timing)" : ""); return (0); } printf("CMD %d arg %d flags %02x\n", mmc_opcode, mmc_arg, mmc_flags); if (mmc_data_len > 0) { flags |= CAM_DIR_IN; mmc_data = malloc(mmc_data_len); memset(mmc_data, 0, mmc_data_len); memset(&mmc_d, 0, sizeof(mmc_d)); mmc_d.len = mmc_data_len; mmc_d.data = mmc_data; mmc_d.flags = MMC_DATA_READ; } else flags |= CAM_DIR_NONE; cam_fill_mmcio(&ccb->mmcio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*flags*/ flags, /*mmc_opcode*/ mmc_opcode, /*mmc_arg*/ mmc_arg, /*mmc_flags*/ mmc_flags, /*mmc_data*/ mmc_data_len > 0 ? &mmc_d : NULL, /*timeout*/ timeout ? timeout : 5000); if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } } if (((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)) { printf("MMCIO: error %d, %08x %08x %08x %08x\n", ccb->mmcio.cmd.error, ccb->mmcio.cmd.resp[0], ccb->mmcio.cmd.resp[1], ccb->mmcio.cmd.resp[2], ccb->mmcio.cmd.resp[3]); switch (mmc_opcode) { case SD_IO_RW_DIRECT: printf("IO_RW_DIRECT: resp byte %02x, cur state %d\n", SD_R5_DATA(ccb->mmcio.cmd.resp), (ccb->mmcio.cmd.resp[0] >> 12) & 0x3); break; case SD_IO_RW_EXTENDED: printf("IO_RW_EXTENDED: read %d bytes w/o error:\n", mmc_data_len); hexdump(mmc_data, mmc_data_len, NULL, 0); break; case SD_SEND_RELATIVE_ADDR: printf("SEND_RELATIVE_ADDR: published RCA %02x\n", ccb->mmcio.cmd.resp[0] >> 16); break; default: printf("No command-specific decoder for CMD %d\n", mmc_opcode); } } mmccmd_bailout: if (ccb != NULL) cam_freeccb(ccb); if (mmc_data_len > 0 && mmc_data != NULL) free(mmc_data); return (error); } static int smpreportgeneral(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { union ccb *ccb; struct smp_report_general_request *request = NULL; struct smp_report_general_response *response = NULL; struct sbuf *sb = NULL; int error = 0; int c, long_response = 0; int retval; /* * Note that at the moment we don't support sending SMP CCBs to * devices that aren't probed by CAM. */ ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'l': long_response = 1; break; default: break; } } request = malloc(sizeof(*request)); if (request == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*request)); error = 1; goto bailout; } response = malloc(sizeof(*response)); if (response == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*response)); error = 1; goto bailout; } try_long: smp_report_general(&ccb->smpio, retry_count, /*cbfcnp*/ NULL, request, /*request_len*/ sizeof(*request), (uint8_t *)response, /*response_len*/ sizeof(*response), /*long_response*/ long_response, timeout); if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } error = 1; goto bailout; } /* * If the device supports the long response bit, try again and see * if we can get all of the data. */ if ((response->long_response & SMP_RG_LONG_RESPONSE) && (long_response == 0)) { ccb->ccb_h.status = CAM_REQ_INPROG; CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); long_response = 1; goto try_long; } /* * XXX KDM detect and decode SMP errors here. */ sb = sbuf_new_auto(); if (sb == NULL) { warnx("%s: error allocating sbuf", __func__); goto bailout; } smp_report_general_sbuf(response, sizeof(*response), sb); if (sbuf_finish(sb) != 0) { warnx("%s: sbuf_finish", __func__); goto bailout; } printf("%s", sbuf_data(sb)); bailout: if (ccb != NULL) cam_freeccb(ccb); if (request != NULL) free(request); if (response != NULL) free(response); if (sb != NULL) sbuf_delete(sb); return (error); } static struct camcontrol_opts phy_ops[] = { {"nop", SMP_PC_PHY_OP_NOP, CAM_ARG_NONE, NULL}, {"linkreset", SMP_PC_PHY_OP_LINK_RESET, CAM_ARG_NONE, NULL}, {"hardreset", SMP_PC_PHY_OP_HARD_RESET, CAM_ARG_NONE, NULL}, {"disable", SMP_PC_PHY_OP_DISABLE, CAM_ARG_NONE, NULL}, {"clearerrlog", SMP_PC_PHY_OP_CLEAR_ERR_LOG, CAM_ARG_NONE, NULL}, {"clearaffiliation", SMP_PC_PHY_OP_CLEAR_AFFILIATON, CAM_ARG_NONE,NULL}, {"sataportsel", SMP_PC_PHY_OP_TRANS_SATA_PSS, CAM_ARG_NONE, NULL}, {"clearitnl", SMP_PC_PHY_OP_CLEAR_STP_ITN_LS, CAM_ARG_NONE, NULL}, {"setdevname", SMP_PC_PHY_OP_SET_ATT_DEV_NAME, CAM_ARG_NONE, NULL}, {NULL, 0, 0, NULL} }; static int smpphycontrol(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { union ccb *ccb; struct smp_phy_control_request *request = NULL; struct smp_phy_control_response *response = NULL; int long_response = 0; int retval = 0; int phy = -1; uint32_t phy_operation = SMP_PC_PHY_OP_NOP; int phy_op_set = 0; uint64_t attached_dev_name = 0; int dev_name_set = 0; uint32_t min_plr = 0, max_plr = 0; uint32_t pp_timeout_val = 0; int slumber_partial = 0; int set_pp_timeout_val = 0; int c; /* * Note that at the moment we don't support sending SMP CCBs to * devices that aren't probed by CAM. */ ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'a': case 'A': case 's': case 'S': { int enable = -1; if (strcasecmp(optarg, "enable") == 0) enable = 1; else if (strcasecmp(optarg, "disable") == 0) enable = 2; else { warnx("%s: Invalid argument %s", __func__, optarg); retval = 1; goto bailout; } switch (c) { case 's': slumber_partial |= enable << SMP_PC_SAS_SLUMBER_SHIFT; break; case 'S': slumber_partial |= enable << SMP_PC_SAS_PARTIAL_SHIFT; break; case 'a': slumber_partial |= enable << SMP_PC_SATA_SLUMBER_SHIFT; break; case 'A': slumber_partial |= enable << SMP_PC_SATA_PARTIAL_SHIFT; break; default: warnx("%s: programmer error", __func__); retval = 1; goto bailout; break; /*NOTREACHED*/ } break; } case 'd': attached_dev_name = (uintmax_t)strtoumax(optarg, NULL,0); dev_name_set = 1; break; case 'l': long_response = 1; break; case 'm': /* * We don't do extensive checking here, so this * will continue to work when new speeds come out. */ min_plr = strtoul(optarg, NULL, 0); if ((min_plr == 0) || (min_plr > 0xf)) { warnx("%s: invalid link rate %x", __func__, min_plr); retval = 1; goto bailout; } break; case 'M': /* * We don't do extensive checking here, so this * will continue to work when new speeds come out. */ max_plr = strtoul(optarg, NULL, 0); if ((max_plr == 0) || (max_plr > 0xf)) { warnx("%s: invalid link rate %x", __func__, max_plr); retval = 1; goto bailout; } break; case 'o': { camcontrol_optret optreturn; cam_argmask argnums; const char *subopt; if (phy_op_set != 0) { warnx("%s: only one phy operation argument " "(-o) allowed", __func__); retval = 1; goto bailout; } phy_op_set = 1; /* * Allow the user to specify the phy operation * numerically, as well as with a name. This will * future-proof it a bit, so options that are added * in future specs can be used. */ if (isdigit(optarg[0])) { phy_operation = strtoul(optarg, NULL, 0); if ((phy_operation == 0) || (phy_operation > 0xff)) { warnx("%s: invalid phy operation %#x", __func__, phy_operation); retval = 1; goto bailout; } break; } optreturn = getoption(phy_ops, optarg, &phy_operation, &argnums, &subopt); if (optreturn == CC_OR_AMBIGUOUS) { warnx("%s: ambiguous option %s", __func__, optarg); usage(0); retval = 1; goto bailout; } else if (optreturn == CC_OR_NOT_FOUND) { warnx("%s: option %s not found", __func__, optarg); usage(0); retval = 1; goto bailout; } break; } case 'p': phy = atoi(optarg); break; case 'T': pp_timeout_val = strtoul(optarg, NULL, 0); if (pp_timeout_val > 15) { warnx("%s: invalid partial pathway timeout " "value %u, need a value less than 16", __func__, pp_timeout_val); retval = 1; goto bailout; } set_pp_timeout_val = 1; break; default: break; } } if (phy == -1) { warnx("%s: a PHY (-p phy) argument is required",__func__); retval = 1; goto bailout; } if (((dev_name_set != 0) && (phy_operation != SMP_PC_PHY_OP_SET_ATT_DEV_NAME)) || ((phy_operation == SMP_PC_PHY_OP_SET_ATT_DEV_NAME) && (dev_name_set == 0))) { warnx("%s: -d name and -o setdevname arguments both " "required to set device name", __func__); retval = 1; goto bailout; } request = malloc(sizeof(*request)); if (request == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*request)); retval = 1; goto bailout; } response = malloc(sizeof(*response)); if (response == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*response)); retval = 1; goto bailout; } smp_phy_control(&ccb->smpio, retry_count, /*cbfcnp*/ NULL, request, sizeof(*request), (uint8_t *)response, sizeof(*response), long_response, /*expected_exp_change_count*/ 0, phy, phy_operation, (set_pp_timeout_val != 0) ? 1 : 0, attached_dev_name, min_plr, max_plr, slumber_partial, pp_timeout_val, timeout); if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { /* * Use CAM_EPF_NORMAL so we only get one line of * SMP command decoding. */ cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_NORMAL, stderr); } retval = 1; goto bailout; } /* XXX KDM print out something here for success? */ bailout: if (ccb != NULL) cam_freeccb(ccb); if (request != NULL) free(request); if (response != NULL) free(response); return (retval); } static int smpmaninfo(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { union ccb *ccb; struct smp_report_manuf_info_request request; struct smp_report_manuf_info_response response; struct sbuf *sb = NULL; int long_response = 0; int retval = 0; int c; /* * Note that at the moment we don't support sending SMP CCBs to * devices that aren't probed by CAM. */ ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'l': long_response = 1; break; default: break; } } bzero(&request, sizeof(request)); bzero(&response, sizeof(response)); smp_report_manuf_info(&ccb->smpio, retry_count, /*cbfcnp*/ NULL, &request, sizeof(request), (uint8_t *)&response, sizeof(response), long_response, timeout); if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto bailout; } sb = sbuf_new_auto(); if (sb == NULL) { warnx("%s: error allocating sbuf", __func__); goto bailout; } smp_report_manuf_info_sbuf(&response, sizeof(response), sb); if (sbuf_finish(sb) != 0) { warnx("%s: sbuf_finish", __func__); goto bailout; } printf("%s", sbuf_data(sb)); bailout: if (ccb != NULL) cam_freeccb(ccb); if (sb != NULL) sbuf_delete(sb); return (retval); } static int getdevid(struct cam_devitem *item) { int retval = 0; union ccb *ccb = NULL; struct cam_device *dev; dev = cam_open_btl(item->dev_match.path_id, item->dev_match.target_id, item->dev_match.target_lun, O_RDWR, NULL); if (dev == NULL) { warnx("%s", cam_errbuf); retval = 1; goto bailout; } item->device_id_len = 0; ccb = cam_getccb(dev); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); retval = 1; goto bailout; } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->cdai); /* * On the first try, we just probe for the size of the data, and * then allocate that much memory and try again. */ retry: ccb->ccb_h.func_code = XPT_DEV_ADVINFO; ccb->ccb_h.flags = CAM_DIR_IN; ccb->cdai.flags = CDAI_FLAG_NONE; ccb->cdai.buftype = CDAI_TYPE_SCSI_DEVID; ccb->cdai.bufsiz = item->device_id_len; if (item->device_id_len != 0) ccb->cdai.buf = (uint8_t *)item->device_id; if (cam_send_ccb(dev, ccb) < 0) { warn("%s: error sending XPT_GDEV_ADVINFO CCB", __func__); retval = 1; goto bailout; } if (ccb->ccb_h.status != CAM_REQ_CMP) { warnx("%s: CAM status %#x", __func__, ccb->ccb_h.status); retval = 1; goto bailout; } if (item->device_id_len == 0) { /* * This is our first time through. Allocate the buffer, * and then go back to get the data. */ if (ccb->cdai.provsiz == 0) { warnx("%s: invalid .provsiz field returned with " "XPT_GDEV_ADVINFO CCB", __func__); retval = 1; goto bailout; } item->device_id_len = ccb->cdai.provsiz; item->device_id = malloc(item->device_id_len); if (item->device_id == NULL) { warn("%s: unable to allocate %d bytes", __func__, item->device_id_len); retval = 1; goto bailout; } ccb->ccb_h.status = CAM_REQ_INPROG; goto retry; } bailout: if (dev != NULL) cam_close_device(dev); if (ccb != NULL) cam_freeccb(ccb); return (retval); } /* * XXX KDM merge this code with getdevtree()? */ static int buildbusdevlist(struct cam_devlist *devlist) { union ccb ccb; int bufsize, fd = -1; struct dev_match_pattern *patterns; struct cam_devitem *item = NULL; int skip_device = 0; int retval = 0; if ((fd = open(XPT_DEVICE, O_RDWR)) == -1) { warn("couldn't open %s", XPT_DEVICE); return (1); } bzero(&ccb, sizeof(union ccb)); ccb.ccb_h.path_id = CAM_XPT_PATH_ID; ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; ccb.ccb_h.func_code = XPT_DEV_MATCH; bufsize = sizeof(struct dev_match_result) * 100; ccb.cdm.match_buf_len = bufsize; ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize); if (ccb.cdm.matches == NULL) { warnx("can't malloc memory for matches"); close(fd); return (1); } ccb.cdm.num_matches = 0; ccb.cdm.num_patterns = 2; ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern) * ccb.cdm.num_patterns; patterns = (struct dev_match_pattern *)malloc(ccb.cdm.pattern_buf_len); if (patterns == NULL) { warnx("can't malloc memory for patterns"); retval = 1; goto bailout; } ccb.cdm.patterns = patterns; bzero(patterns, ccb.cdm.pattern_buf_len); patterns[0].type = DEV_MATCH_DEVICE; patterns[0].pattern.device_pattern.flags = DEV_MATCH_PATH; patterns[0].pattern.device_pattern.path_id = devlist->path_id; patterns[1].type = DEV_MATCH_PERIPH; patterns[1].pattern.periph_pattern.flags = PERIPH_MATCH_PATH; patterns[1].pattern.periph_pattern.path_id = devlist->path_id; /* * We do the ioctl multiple times if necessary, in case there are * more than 100 nodes in the EDT. */ do { unsigned int i; if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { warn("error sending CAMIOCOMMAND ioctl"); retval = 1; goto bailout; } if ((ccb.ccb_h.status != CAM_REQ_CMP) || ((ccb.cdm.status != CAM_DEV_MATCH_LAST) && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) { warnx("got CAM error %#x, CDM error %d\n", ccb.ccb_h.status, ccb.cdm.status); retval = 1; goto bailout; } for (i = 0; i < ccb.cdm.num_matches; i++) { switch (ccb.cdm.matches[i].type) { case DEV_MATCH_DEVICE: { struct device_match_result *dev_result; dev_result = &ccb.cdm.matches[i].result.device_result; if (dev_result->flags & DEV_RESULT_UNCONFIGURED) { skip_device = 1; break; } else skip_device = 0; item = malloc(sizeof(*item)); if (item == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*item)); retval = 1; goto bailout; } bzero(item, sizeof(*item)); bcopy(dev_result, &item->dev_match, sizeof(*dev_result)); STAILQ_INSERT_TAIL(&devlist->dev_queue, item, links); if (getdevid(item) != 0) { retval = 1; goto bailout; } break; } case DEV_MATCH_PERIPH: { struct periph_match_result *periph_result; periph_result = &ccb.cdm.matches[i].result.periph_result; if (skip_device != 0) break; item->num_periphs++; item->periph_matches = realloc( item->periph_matches, item->num_periphs * sizeof(struct periph_match_result)); if (item->periph_matches == NULL) { warn("%s: error allocating periph " "list", __func__); retval = 1; goto bailout; } bcopy(periph_result, &item->periph_matches[ item->num_periphs - 1], sizeof(*periph_result)); break; } default: fprintf(stderr, "%s: unexpected match " "type %d\n", __func__, ccb.cdm.matches[i].type); retval = 1; goto bailout; break; /*NOTREACHED*/ } } } while ((ccb.ccb_h.status == CAM_REQ_CMP) && (ccb.cdm.status == CAM_DEV_MATCH_MORE)); bailout: if (fd != -1) close(fd); free(patterns); free(ccb.cdm.matches); if (retval != 0) freebusdevlist(devlist); return (retval); } static void freebusdevlist(struct cam_devlist *devlist) { struct cam_devitem *item, *item2; STAILQ_FOREACH_SAFE(item, &devlist->dev_queue, links, item2) { STAILQ_REMOVE(&devlist->dev_queue, item, cam_devitem, links); free(item->device_id); free(item->periph_matches); free(item); } } static struct cam_devitem * findsasdevice(struct cam_devlist *devlist, uint64_t sasaddr) { struct cam_devitem *item; STAILQ_FOREACH(item, &devlist->dev_queue, links) { struct scsi_vpd_id_descriptor *idd; /* * XXX KDM look for LUN IDs as well? */ idd = scsi_get_devid(item->device_id, item->device_id_len, scsi_devid_is_sas_target); if (idd == NULL) continue; if (scsi_8btou64(idd->identifier) == sasaddr) return (item); } return (NULL); } static int smpphylist(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { struct smp_report_general_request *rgrequest = NULL; struct smp_report_general_response *rgresponse = NULL; struct smp_discover_request *disrequest = NULL; struct smp_discover_response *disresponse = NULL; struct cam_devlist devlist; union ccb *ccb; int long_response = 0; int num_phys = 0; int quiet = 0; int retval; int i, c; /* * Note that at the moment we don't support sending SMP CCBs to * devices that aren't probed by CAM. */ ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating CCB", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); STAILQ_INIT(&devlist.dev_queue); rgrequest = malloc(sizeof(*rgrequest)); if (rgrequest == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*rgrequest)); retval = 1; goto bailout; } rgresponse = malloc(sizeof(*rgresponse)); if (rgresponse == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*rgresponse)); retval = 1; goto bailout; } while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'l': long_response = 1; break; case 'q': quiet = 1; break; default: break; } } smp_report_general(&ccb->smpio, retry_count, /*cbfcnp*/ NULL, rgrequest, /*request_len*/ sizeof(*rgrequest), (uint8_t *)rgresponse, /*response_len*/ sizeof(*rgresponse), /*long_response*/ long_response, timeout); ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (((retval = cam_send_ccb(device, ccb)) < 0) || ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto bailout; } num_phys = rgresponse->num_phys; if (num_phys == 0) { if (quiet == 0) fprintf(stdout, "%s: No Phys reported\n", __func__); retval = 1; goto bailout; } devlist.path_id = device->path_id; retval = buildbusdevlist(&devlist); if (retval != 0) goto bailout; if (quiet == 0) { fprintf(stdout, "%d PHYs:\n", num_phys); fprintf(stdout, "PHY Attached SAS Address\n"); } disrequest = malloc(sizeof(*disrequest)); if (disrequest == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*disrequest)); retval = 1; goto bailout; } disresponse = malloc(sizeof(*disresponse)); if (disresponse == NULL) { warn("%s: unable to allocate %zd bytes", __func__, sizeof(*disresponse)); retval = 1; goto bailout; } for (i = 0; i < num_phys; i++) { struct cam_devitem *item; struct device_match_result *dev_match; char vendor[16], product[48], revision[16]; char tmpstr[256]; int j; CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->smpio); ccb->ccb_h.status = CAM_REQ_INPROG; ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; smp_discover(&ccb->smpio, retry_count, /*cbfcnp*/ NULL, disrequest, sizeof(*disrequest), (uint8_t *)disresponse, sizeof(*disresponse), long_response, /*ignore_zone_group*/ 0, /*phy*/ i, timeout); if (((retval = cam_send_ccb(device, ccb)) < 0) || (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && (disresponse->function_result != SMP_FR_PHY_VACANT))) { const char warnstr[] = "error sending command"; if (retval < 0) warn(warnstr); else warnx(warnstr); if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); } retval = 1; goto bailout; } if (disresponse->function_result == SMP_FR_PHY_VACANT) { if (quiet == 0) fprintf(stdout, "%3d \n", i); continue; } if (disresponse->attached_device == SMP_DIS_AD_TYPE_NONE) { item = NULL; } else { item = findsasdevice(&devlist, scsi_8btou64(disresponse->attached_sas_address)); } if ((quiet == 0) || (item != NULL)) { fprintf(stdout, "%3d 0x%016jx", i, (uintmax_t)scsi_8btou64( disresponse->attached_sas_address)); if (item == NULL) { fprintf(stdout, "\n"); continue; } } else if (quiet != 0) continue; dev_match = &item->dev_match; if (dev_match->protocol == PROTO_SCSI) { cam_strvis(vendor, dev_match->inq_data.vendor, sizeof(dev_match->inq_data.vendor), sizeof(vendor)); cam_strvis(product, dev_match->inq_data.product, sizeof(dev_match->inq_data.product), sizeof(product)); cam_strvis(revision, dev_match->inq_data.revision, sizeof(dev_match->inq_data.revision), sizeof(revision)); sprintf(tmpstr, "<%s %s %s>", vendor, product, revision); } else if ((dev_match->protocol == PROTO_ATA) || (dev_match->protocol == PROTO_SATAPM)) { cam_strvis(product, dev_match->ident_data.model, sizeof(dev_match->ident_data.model), sizeof(product)); cam_strvis(revision, dev_match->ident_data.revision, sizeof(dev_match->ident_data.revision), sizeof(revision)); sprintf(tmpstr, "<%s %s>", product, revision); } else { sprintf(tmpstr, "<>"); } fprintf(stdout, " %-33s ", tmpstr); /* * If we have 0 periphs, that's a bug... */ if (item->num_periphs == 0) { fprintf(stdout, "\n"); continue; } fprintf(stdout, "("); for (j = 0; j < item->num_periphs; j++) { if (j > 0) fprintf(stdout, ","); fprintf(stdout, "%s%d", item->periph_matches[j].periph_name, item->periph_matches[j].unit_number); } fprintf(stdout, ")\n"); } bailout: if (ccb != NULL) cam_freeccb(ccb); free(rgrequest); free(rgresponse); free(disrequest); free(disresponse); freebusdevlist(&devlist); return (retval); } static int atapm_proc_resp(struct cam_device *device, union ccb *ccb) { struct ata_res *res; res = &ccb->ataio.res; if (res->status & ATA_STATUS_ERROR) { if (arglist & CAM_ARG_VERBOSE) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); printf("error = 0x%02x, sector_count = 0x%04x, " "device = 0x%02x, status = 0x%02x\n", res->error, res->sector_count, res->device, res->status); } return (1); } if (arglist & CAM_ARG_VERBOSE) { fprintf(stdout, "%s%d: Raw native check power data:\n", device->device_name, device->dev_unit_num); /* res is 4 byte aligned */ dump_data((uint16_t*)(uintptr_t)res, sizeof(struct ata_res)); printf("error = 0x%02x, sector_count = 0x%04x, device = 0x%02x, " "status = 0x%02x\n", res->error, res->sector_count, res->device, res->status); } printf("%s%d: ", device->device_name, device->dev_unit_num); switch (res->sector_count) { case 0x00: printf("Standby mode\n"); break; case 0x40: printf("NV Cache Power Mode and the spindle is spun down or spinning down\n"); break; case 0x41: printf("NV Cache Power Mode and the spindle is spun up or spinning up\n"); break; case 0x80: printf("Idle mode\n"); break; case 0xff: printf("Active or Idle mode\n"); break; default: printf("Unknown mode 0x%02x\n", res->sector_count); break; } return (0); } static int atapm(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { union ccb *ccb; int retval = 0; int t = -1; int c; u_int8_t ata_flags = 0; u_char cmd, sc; ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating ccb", __func__); return (1); } while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 't': t = atoi(optarg); break; default: break; } } if (strcmp(argv[1], "idle") == 0) { if (t == -1) cmd = ATA_IDLE_IMMEDIATE; else cmd = ATA_IDLE_CMD; } else if (strcmp(argv[1], "standby") == 0) { if (t == -1) cmd = ATA_STANDBY_IMMEDIATE; else cmd = ATA_STANDBY_CMD; } else if (strcmp(argv[1], "powermode") == 0) { cmd = ATA_CHECK_POWER_MODE; ata_flags = AP_FLAG_CHK_COND; t = -1; } else { cmd = ATA_SLEEP; t = -1; } if (t < 0) sc = 0; else if (t <= (240 * 5)) sc = (t + 4) / 5; else if (t <= (252 * 5)) /* special encoding for 21 minutes */ sc = 252; else if (t <= (11 * 30 * 60)) sc = (t - 1) / (30 * 60) + 241; else sc = 253; retval = ata_do_cmd(device, ccb, /*retries*/retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/AP_PROTO_NON_DATA, /*ata_flags*/ata_flags, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/cmd, /*features*/0, /*lba*/0, /*sector_count*/sc, /*data_ptr*/NULL, /*dxfer_len*/0, /*timeout*/timeout ? timeout : 30 * 1000, /*quiet*/1); cam_freeccb(ccb); if (retval || cmd != ATA_CHECK_POWER_MODE) return (retval); return (atapm_proc_resp(device, ccb)); } static int ataaxm(struct cam_device *device, int argc, char **argv, char *combinedopt, int retry_count, int timeout) { union ccb *ccb; int retval = 0; int l = -1; int c; u_char cmd, sc; ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating ccb", __func__); return (1); } while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'l': l = atoi(optarg); break; default: break; } } sc = 0; if (strcmp(argv[1], "apm") == 0) { if (l == -1) cmd = 0x85; else { cmd = 0x05; sc = l; } } else /* aam */ { if (l == -1) cmd = 0xC2; else { cmd = 0x42; sc = l; } } retval = ata_do_28bit_cmd(device, ccb, /*retries*/retry_count, /*flags*/CAM_DIR_NONE, /*protocol*/AP_PROTO_NON_DATA, /*tag_action*/MSG_SIMPLE_Q_TAG, /*command*/ATA_SETFEATURES, /*features*/cmd, /*lba*/0, /*sector_count*/sc, /*data_ptr*/NULL, /*dxfer_len*/0, /*timeout*/timeout ? timeout : 30 * 1000, /*quiet*/1); cam_freeccb(ccb); return (retval); } int scsigetopcodes(struct cam_device *device, int opcode_set, int opcode, int show_sa_errors, int sa_set, int service_action, int timeout_desc, int task_attr, int retry_count, int timeout, int verbosemode, uint32_t *fill_len, uint8_t **data_ptr) { union ccb *ccb = NULL; uint8_t *buf = NULL; uint32_t alloc_len = 0, num_opcodes; uint32_t valid_len = 0; uint32_t avail_len = 0; struct scsi_report_supported_opcodes_all *all_hdr; struct scsi_report_supported_opcodes_one *one; int options = 0; int retval = 0; /* * Make it clear that we haven't yet allocated or filled anything. */ *fill_len = 0; *data_ptr = NULL; ccb = cam_getccb(device); if (ccb == NULL) { warnx("couldn't allocate CCB"); retval = 1; goto bailout; } /* cam_getccb cleans up the header, caller has to zero the payload */ CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); if (opcode_set != 0) { options |= RSO_OPTIONS_OC; num_opcodes = 1; alloc_len = sizeof(*one) + CAM_MAX_CDBLEN; } else { num_opcodes = 256; alloc_len = sizeof(*all_hdr) + (num_opcodes * sizeof(struct scsi_report_supported_opcodes_descr)); } if (timeout_desc != 0) { options |= RSO_RCTD; alloc_len += num_opcodes * sizeof(struct scsi_report_supported_opcodes_timeout); } if (sa_set != 0) { options |= RSO_OPTIONS_OC_SA; if (show_sa_errors != 0) options &= ~RSO_OPTIONS_OC; } retry_alloc: if (buf != NULL) { free(buf); buf = NULL; } buf = malloc(alloc_len); if (buf == NULL) { warn("Unable to allocate %u bytes", alloc_len); retval = 1; goto bailout; } bzero(buf, alloc_len); scsi_report_supported_opcodes(&ccb->csio, /*retries*/ retry_count, /*cbfcnp*/ NULL, /*tag_action*/ task_attr, /*options*/ options, /*req_opcode*/ opcode, /*req_service_action*/ service_action, /*data_ptr*/ buf, /*dxfer_len*/ alloc_len, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ timeout ? timeout : 10000); ccb->ccb_h.flags |= CAM_DEV_QFRZDIS; if (retry_count != 0) ccb->ccb_h.flags |= CAM_PASS_ERR_RECOVER; if (cam_send_ccb(device, ccb) < 0) { perror("error sending REPORT SUPPORTED OPERATION CODES"); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (verbosemode != 0) cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } valid_len = ccb->csio.dxfer_len - ccb->csio.resid; if (((options & RSO_OPTIONS_MASK) == RSO_OPTIONS_ALL) && (valid_len >= sizeof(*all_hdr))) { all_hdr = (struct scsi_report_supported_opcodes_all *)buf; avail_len = scsi_4btoul(all_hdr->length) + sizeof(*all_hdr); } else if (((options & RSO_OPTIONS_MASK) != RSO_OPTIONS_ALL) && (valid_len >= sizeof(*one))) { uint32_t cdb_length; one = (struct scsi_report_supported_opcodes_one *)buf; cdb_length = scsi_2btoul(one->cdb_length); avail_len = sizeof(*one) + cdb_length; if (one->support & RSO_ONE_CTDP) { struct scsi_report_supported_opcodes_timeout *td; td = (struct scsi_report_supported_opcodes_timeout *) &buf[avail_len]; if (valid_len >= (avail_len + sizeof(td->length))) { avail_len += scsi_2btoul(td->length) + sizeof(td->length); } else { avail_len += sizeof(*td); } } } /* * avail_len could be zero if we didn't get enough data back from * thet target to determine */ if ((avail_len != 0) && (avail_len > valid_len)) { alloc_len = avail_len; goto retry_alloc; } *fill_len = valid_len; *data_ptr = buf; bailout: if (retval != 0) free(buf); cam_freeccb(ccb); return (retval); } static int scsiprintoneopcode(struct cam_device *device, int req_opcode, int sa_set, int req_sa, uint8_t *buf, uint32_t valid_len) { struct scsi_report_supported_opcodes_one *one; struct scsi_report_supported_opcodes_timeout *td; uint32_t cdb_len = 0, td_len = 0; const char *op_desc = NULL; unsigned int i; int retval = 0; one = (struct scsi_report_supported_opcodes_one *)buf; /* * If we don't have the full single opcode descriptor, no point in * continuing. */ if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, cdb_length)) { warnx("Only %u bytes returned, not enough to verify support", valid_len); retval = 1; goto bailout; } op_desc = scsi_op_desc(req_opcode, &device->inq_data); printf("%s (0x%02x)", op_desc != NULL ? op_desc : "UNKNOWN", req_opcode); if (sa_set != 0) printf(", SA 0x%x", req_sa); printf(": "); switch (one->support & RSO_ONE_SUP_MASK) { case RSO_ONE_SUP_UNAVAIL: printf("No command support information currently available\n"); break; case RSO_ONE_SUP_NOT_SUP: printf("Command not supported\n"); retval = 1; goto bailout; break; /*NOTREACHED*/ case RSO_ONE_SUP_AVAIL: printf("Command is supported, complies with a SCSI standard\n"); break; case RSO_ONE_SUP_VENDOR: printf("Command is supported, vendor-specific " "implementation\n"); break; default: printf("Unknown command support flags 0x%#x\n", one->support & RSO_ONE_SUP_MASK); break; } /* * If we don't have the CDB length, it isn't exactly an error, the * command probably isn't supported. */ if (valid_len < __offsetof(struct scsi_report_supported_opcodes_one, cdb_usage)) goto bailout; cdb_len = scsi_2btoul(one->cdb_length); /* * If our valid data doesn't include the full reported length, * return. The caller should have detected this and adjusted his * allocation length to get all of the available data. */ if (valid_len < sizeof(*one) + cdb_len) { retval = 1; goto bailout; } /* * If all we have is the opcode, there is no point in printing out * the usage bitmap. */ if (cdb_len <= 1) { retval = 1; goto bailout; } printf("CDB usage bitmap:"); for (i = 0; i < cdb_len; i++) { printf(" %02x", one->cdb_usage[i]); } printf("\n"); /* * If we don't have a timeout descriptor, we're done. */ if ((one->support & RSO_ONE_CTDP) == 0) goto bailout; /* * If we don't have enough valid length to include the timeout * descriptor length, we're done. */ if (valid_len < (sizeof(*one) + cdb_len + sizeof(td->length))) goto bailout; td = (struct scsi_report_supported_opcodes_timeout *) &buf[sizeof(*one) + cdb_len]; td_len = scsi_2btoul(td->length); td_len += sizeof(td->length); /* * If we don't have the full timeout descriptor, we're done. */ if (td_len < sizeof(*td)) goto bailout; /* * If we don't have enough valid length to contain the full timeout * descriptor, we're done. */ if (valid_len < (sizeof(*one) + cdb_len + td_len)) goto bailout; printf("Timeout information:\n"); printf("Command-specific: 0x%02x\n", td->cmd_specific); printf("Nominal timeout: %u seconds\n", scsi_4btoul(td->nominal_time)); printf("Recommended timeout: %u seconds\n", scsi_4btoul(td->recommended_time)); bailout: return (retval); } static int scsiprintopcodes(struct cam_device *device, int td_req, uint8_t *buf, uint32_t valid_len) { struct scsi_report_supported_opcodes_all *hdr; struct scsi_report_supported_opcodes_descr *desc; uint32_t avail_len = 0, used_len = 0; uint8_t *cur_ptr; int retval = 0; if (valid_len < sizeof(*hdr)) { warnx("%s: not enough returned data (%u bytes) opcode list", __func__, valid_len); retval = 1; goto bailout; } hdr = (struct scsi_report_supported_opcodes_all *)buf; avail_len = scsi_4btoul(hdr->length); avail_len += sizeof(hdr->length); /* * Take the lesser of the amount of data the drive claims is * available, and the amount of data the HBA says was returned. */ avail_len = MIN(avail_len, valid_len); used_len = sizeof(hdr->length); printf("%-6s %4s %8s ", "Opcode", "SA", "CDB len" ); if (td_req != 0) printf("%5s %6s %6s ", "CS", "Nom", "Rec"); printf(" Description\n"); while ((avail_len - used_len) > sizeof(*desc)) { struct scsi_report_supported_opcodes_timeout *td; uint32_t td_len; const char *op_desc = NULL; cur_ptr = &buf[used_len]; desc = (struct scsi_report_supported_opcodes_descr *)cur_ptr; op_desc = scsi_op_desc(desc->opcode, &device->inq_data); if (op_desc == NULL) op_desc = "UNKNOWN"; printf("0x%02x %#4x %8u ", desc->opcode, scsi_2btoul(desc->service_action), scsi_2btoul(desc->cdb_length)); used_len += sizeof(*desc); if ((desc->flags & RSO_CTDP) == 0) { printf(" %s\n", op_desc); continue; } /* * If we don't have enough space to fit a timeout * descriptor, then we're done. */ if (avail_len - used_len < sizeof(*td)) { used_len = avail_len; printf(" %s\n", op_desc); continue; } cur_ptr = &buf[used_len]; td = (struct scsi_report_supported_opcodes_timeout *)cur_ptr; td_len = scsi_2btoul(td->length); td_len += sizeof(td->length); used_len += td_len; /* * If the given timeout descriptor length is less than what * we understand, skip it. */ if (td_len < sizeof(*td)) { printf(" %s\n", op_desc); continue; } printf(" 0x%02x %6u %6u %s\n", td->cmd_specific, scsi_4btoul(td->nominal_time), scsi_4btoul(td->recommended_time), op_desc); } bailout: return (retval); } static int scsiopcodes(struct cam_device *device, int argc, char **argv, char *combinedopt, int task_attr, int retry_count, int timeout, int verbosemode) { int c; uint32_t opcode = 0, service_action = 0; int td_set = 0, opcode_set = 0, sa_set = 0; int show_sa_errors = 1; uint32_t valid_len = 0; uint8_t *buf = NULL; char *endptr; int retval = 0; while ((c = getopt(argc, argv, combinedopt)) != -1) { switch (c) { case 'N': show_sa_errors = 0; break; case 'o': opcode = strtoul(optarg, &endptr, 0); if (*endptr != '\0') { warnx("Invalid opcode \"%s\", must be a number", optarg); retval = 1; goto bailout; } if (opcode > 0xff) { warnx("Invalid opcode 0x%#x, must be between" "0 and 0xff inclusive", opcode); retval = 1; goto bailout; } opcode_set = 1; break; case 's': service_action = strtoul(optarg, &endptr, 0); if (*endptr != '\0') { warnx("Invalid service action \"%s\", must " "be a number", optarg); retval = 1; goto bailout; } if (service_action > 0xffff) { warnx("Invalid service action 0x%#x, must " "be between 0 and 0xffff inclusive", service_action); retval = 1; } sa_set = 1; break; case 'T': td_set = 1; break; default: break; } } if ((sa_set != 0) && (opcode_set == 0)) { warnx("You must specify an opcode with -o if a service " "action is given"); retval = 1; goto bailout; } retval = scsigetopcodes(device, opcode_set, opcode, show_sa_errors, sa_set, service_action, td_set, task_attr, retry_count, timeout, verbosemode, &valid_len, &buf); if (retval != 0) goto bailout; if ((opcode_set != 0) || (sa_set != 0)) { retval = scsiprintoneopcode(device, opcode, sa_set, service_action, buf, valid_len); } else { retval = scsiprintopcodes(device, td_set, buf, valid_len); } bailout: free(buf); return (retval); } #endif /* MINIMALISTIC */ static int scsireprobe(struct cam_device *device) { union ccb *ccb; int retval = 0; ccb = cam_getccb(device); if (ccb == NULL) { warnx("%s: error allocating ccb", __func__); return (1); } CCB_CLEAR_ALL_EXCEPT_HDR(&ccb->csio); ccb->ccb_h.func_code = XPT_REPROBE_LUN; if (cam_send_ccb(device, ccb) < 0) { warn("error sending XPT_REPROBE_LUN CCB"); retval = 1; goto bailout; } if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { cam_error_print(device, ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); retval = 1; goto bailout; } bailout: cam_freeccb(ccb); return (retval); } void usage(int printlong) { fprintf(printlong ? stdout : stderr, "usage: camcontrol [device id][generic args][command args]\n" " camcontrol devlist [-b] [-v]\n" #ifndef MINIMALISTIC " camcontrol periphlist [dev_id][-n dev_name] [-u unit]\n" " camcontrol tur [dev_id][generic args]\n" " camcontrol inquiry [dev_id][generic args] [-D] [-S] [-R]\n" " camcontrol identify [dev_id][generic args] [-v]\n" " camcontrol reportluns [dev_id][generic args] [-c] [-l] [-r report]\n" " camcontrol readcap [dev_id][generic args] [-b] [-h] [-H] [-N]\n" " [-q] [-s] [-l]\n" " camcontrol start [dev_id][generic args]\n" " camcontrol stop [dev_id][generic args]\n" " camcontrol load [dev_id][generic args]\n" " camcontrol eject [dev_id][generic args]\n" " camcontrol reprobe [dev_id][generic args]\n" #endif /* MINIMALISTIC */ " camcontrol rescan \n" " camcontrol reset \n" #ifndef MINIMALISTIC " camcontrol defects [dev_id][generic args] <-f format> [-P][-G]\n" " [-q][-s][-S offset][-X]\n" " camcontrol modepage [dev_id][generic args] <-m page | -l>\n" " [-P pagectl][-e | -b][-d]\n" " camcontrol cmd [dev_id][generic args]\n" " <-a cmd [args] | -c cmd [args]>\n" " [-d] [-f] [-i len fmt|-o len fmt [args]] [-r fmt]\n" " camcontrol smpcmd [dev_id][generic args]\n" " <-r len fmt [args]> <-R len fmt [args]>\n" " camcontrol smprg [dev_id][generic args][-l]\n" " camcontrol smppc [dev_id][generic args] <-p phy> [-l]\n" " [-o operation][-d name][-m rate][-M rate]\n" " [-T pp_timeout][-a enable|disable]\n" " [-A enable|disable][-s enable|disable]\n" " [-S enable|disable]\n" " camcontrol smpphylist [dev_id][generic args][-l][-q]\n" " camcontrol smpmaninfo [dev_id][generic args][-l]\n" " camcontrol debug [-I][-P][-T][-S][-X][-c]\n" " \n" " camcontrol tags [dev_id][generic args] [-N tags] [-q] [-v]\n" " camcontrol negotiate [dev_id][generic args] [-a][-c]\n" " [-D ][-M mode][-O offset]\n" " [-q][-R syncrate][-v][-T ]\n" " [-U][-W bus_width]\n" " camcontrol format [dev_id][generic args][-q][-r][-w][-y]\n" " camcontrol sanitize [dev_id][generic args]\n" " [-a overwrite|block|crypto|exitfailure]\n" " [-c passes][-I][-P pattern][-q][-U][-r][-w]\n" " [-y]\n" " camcontrol idle [dev_id][generic args][-t time]\n" " camcontrol standby [dev_id][generic args][-t time]\n" " camcontrol sleep [dev_id][generic args]\n" " camcontrol powermode [dev_id][generic args]\n" " camcontrol apm [dev_id][generic args][-l level]\n" " camcontrol aam [dev_id][generic args][-l level]\n" " camcontrol fwdownload [dev_id][generic args] <-f fw_image> [-q]\n" " [-s][-y]\n" " camcontrol security [dev_id][generic args]\n" " <-d pwd | -e pwd | -f | -h pwd | -k pwd>\n" " [-l ] [-q] [-s pwd] [-T timeout]\n" " [-U ] [-y]\n" " camcontrol hpa [dev_id][generic args] [-f] [-l] [-P] [-p pwd]\n" " [-q] [-s max_sectors] [-U pwd] [-y]\n" " camcontrol persist [dev_id][generic args] <-i action|-o action>\n" " [-a][-I tid][-k key][-K sa_key][-p][-R rtp]\n" " [-s scope][-S][-T type][-U]\n" " camcontrol attrib [dev_id][generic args] <-r action|-w attr>\n" " [-a attr_num][-c][-e elem][-F form1,form1]\n" " [-p part][-s start][-T type][-V vol]\n" " camcontrol opcodes [dev_id][generic args][-o opcode][-s SA]\n" " [-N][-T]\n" " camcontrol zone [dev_id][generic args]<-c cmd> [-a] [-l LBA]\n" " [-o rep_opts] [-P print_opts]\n" " camcontrol epc [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n" " [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n" " [-S power_src] [-T timer]\n" " camcontrol timestamp [dev_id][generic_args] <-r [-f format|-m|-U]>|\n" " <-s <-f format -T time | -U >>\n" " \n" #endif /* MINIMALISTIC */ " camcontrol help\n"); if (!printlong) return; #ifndef MINIMALISTIC fprintf(stdout, "Specify one of the following options:\n" "devlist list all CAM devices\n" "periphlist list all CAM peripheral drivers attached to a device\n" "tur send a test unit ready to the named device\n" "inquiry send a SCSI inquiry command to the named device\n" "identify send a ATA identify command to the named device\n" "reportluns send a SCSI report luns command to the device\n" "readcap send a SCSI read capacity command to the device\n" "start send a Start Unit command to the device\n" "stop send a Stop Unit command to the device\n" "load send a Start Unit command to the device with the load bit set\n" "eject send a Stop Unit command to the device with the eject bit set\n" "reprobe update capacity information of the given device\n" "rescan rescan all buses, the given bus, bus:target:lun or device\n" "reset reset all buses, the given bus, bus:target:lun or device\n" "defects read the defect list of the specified device\n" "modepage display or edit (-e) the given mode page\n" "cmd send the given SCSI command, may need -i or -o as well\n" "smpcmd send the given SMP command, requires -o and -i\n" "smprg send the SMP Report General command\n" "smppc send the SMP PHY Control command, requires -p\n" "smpphylist display phys attached to a SAS expander\n" "smpmaninfo send the SMP Report Manufacturer Info command\n" "debug turn debugging on/off for a bus, target, or lun, or all devices\n" "tags report or set the number of transaction slots for a device\n" "negotiate report or set device negotiation parameters\n" "format send the SCSI FORMAT UNIT command to the named device\n" "sanitize send the SCSI SANITIZE command to the named device\n" "idle send the ATA IDLE command to the named device\n" "standby send the ATA STANDBY command to the named device\n" "sleep send the ATA SLEEP command to the named device\n" "powermode send the ATA CHECK POWER MODE command to the named device\n" "fwdownload program firmware of the named device with the given image\n" "security report or send ATA security commands to the named device\n" "persist send the SCSI PERSISTENT RESERVE IN or OUT commands\n" "attrib send the SCSI READ or WRITE ATTRIBUTE commands\n" "opcodes send the SCSI REPORT SUPPORTED OPCODES command\n" "zone manage Zoned Block (Shingled) devices\n" "epc send ATA Extended Power Conditions commands\n" "timestamp report or set the device's timestamp\n" "help this message\n" "Device Identifiers:\n" "bus:target specify the bus and target, lun defaults to 0\n" "bus:target:lun specify the bus, target and lun\n" "deviceUNIT specify the device name, like \"da4\" or \"cd2\"\n" "Generic arguments:\n" "-v be verbose, print out sense information\n" "-t timeout command timeout in seconds, overrides default timeout\n" "-n dev_name specify device name, e.g. \"da\", \"cd\"\n" "-u unit specify unit number, e.g. \"0\", \"5\"\n" "-E have the kernel attempt to perform SCSI error recovery\n" "-C count specify the SCSI command retry count (needs -E to work)\n" "-Q task_attr specify ordered, simple or head tag type for SCSI cmds\n" "modepage arguments:\n" "-l list all available mode pages\n" "-m page specify the mode page to view or edit\n" "-e edit the specified mode page\n" "-b force view to binary mode\n" "-d disable block descriptors for mode sense\n" "-P pgctl page control field 0-3\n" "defects arguments:\n" "-f format specify defect list format (block, bfi or phys)\n" "-G get the grown defect list\n" "-P get the permanent defect list\n" "inquiry arguments:\n" "-D get the standard inquiry data\n" "-S get the serial number\n" "-R get the transfer rate, etc.\n" "reportluns arguments:\n" "-c only report a count of available LUNs\n" "-l only print out luns, and not a count\n" "-r specify \"default\", \"wellknown\" or \"all\"\n" "readcap arguments\n" "-b only report the blocksize\n" "-h human readable device size, base 2\n" "-H human readable device size, base 10\n" "-N print the number of blocks instead of last block\n" "-q quiet, print numbers only\n" "-s only report the last block/device size\n" "cmd arguments:\n" "-c cdb [args] specify the SCSI CDB\n" "-i len fmt specify input data and input data format\n" "-o len fmt [args] specify output data and output data fmt\n" "smpcmd arguments:\n" "-r len fmt [args] specify the SMP command to be sent\n" "-R len fmt [args] specify SMP response format\n" "smprg arguments:\n" "-l specify the long response format\n" "smppc arguments:\n" "-p phy specify the PHY to operate on\n" "-l specify the long request/response format\n" "-o operation specify the phy control operation\n" "-d name set the attached device name\n" "-m rate set the minimum physical link rate\n" "-M rate set the maximum physical link rate\n" "-T pp_timeout set the partial pathway timeout value\n" "-a enable|disable enable or disable SATA slumber\n" "-A enable|disable enable or disable SATA partial phy power\n" "-s enable|disable enable or disable SAS slumber\n" "-S enable|disable enable or disable SAS partial phy power\n" "smpphylist arguments:\n" "-l specify the long response format\n" "-q only print phys with attached devices\n" "smpmaninfo arguments:\n" "-l specify the long response format\n" "debug arguments:\n" "-I CAM_DEBUG_INFO -- scsi commands, errors, data\n" "-T CAM_DEBUG_TRACE -- routine flow tracking\n" "-S CAM_DEBUG_SUBTRACE -- internal routine command flow\n" "-c CAM_DEBUG_CDB -- print out SCSI CDBs only\n" "tags arguments:\n" "-N tags specify the number of tags to use for this device\n" "-q be quiet, don't report the number of tags\n" "-v report a number of tag-related parameters\n" "negotiate arguments:\n" "-a send a test unit ready after negotiation\n" "-c report/set current negotiation settings\n" "-D \"enable\" or \"disable\" disconnection\n" "-M mode set ATA mode\n" "-O offset set command delay offset\n" "-q be quiet, don't report anything\n" "-R syncrate synchronization rate in MHz\n" "-T \"enable\" or \"disable\" tagged queueing\n" "-U report/set user negotiation settings\n" "-W bus_width set the bus width in bits (8, 16 or 32)\n" "-v also print a Path Inquiry CCB for the controller\n" "format arguments:\n" "-q be quiet, don't print status messages\n" "-r run in report only mode\n" "-w don't send immediate format command\n" "-y don't ask any questions\n" "sanitize arguments:\n" "-a operation operation mode: overwrite, block, crypto or exitfailure\n" "-c passes overwrite passes to perform (1 to 31)\n" "-I invert overwrite pattern after each pass\n" "-P pattern path to overwrite pattern file\n" "-q be quiet, don't print status messages\n" "-r run in report only mode\n" "-U run operation in unrestricted completion exit mode\n" "-w don't send immediate sanitize command\n" "-y don't ask any questions\n" "idle/standby arguments:\n" "-t number of seconds before respective state.\n" "fwdownload arguments:\n" "-f fw_image path to firmware image file\n" "-q don't print informational messages, only errors\n" "-s run in simulation mode\n" "-v print info for every firmware segment sent to device\n" "-y don't ask any questions\n" "security arguments:\n" "-d pwd disable security using the given password for the selected\n" " user\n" "-e pwd erase the device using the given pwd for the selected user\n" "-f freeze the security configuration of the specified device\n" "-h pwd enhanced erase the device using the given pwd for the\n" " selected user\n" "-k pwd unlock the device using the given pwd for the selected\n" " user\n" "-l specifies which security level to set: high or maximum\n" "-q be quiet, do not print any status messages\n" "-s pwd password the device (enable security) using the given\n" " pwd for the selected user\n" "-T timeout overrides the timeout (seconds) used for erase operation\n" "-U specifies which user to set: user or master\n" "-y don't ask any questions\n" "hpa arguments:\n" "-f freeze the HPA configuration of the device\n" "-l lock the HPA configuration of the device\n" "-P make the HPA max sectors persist\n" "-p pwd Set the HPA configuration password required for unlock\n" " calls\n" "-q be quiet, do not print any status messages\n" "-s sectors configures the maximum user accessible sectors of the\n" " device\n" "-U pwd unlock the HPA configuration of the device\n" "-y don't ask any questions\n" "persist arguments:\n" "-i action specify read_keys, read_reservation, report_cap, or\n" " read_full_status\n" "-o action specify register, register_ignore, reserve, release,\n" " clear, preempt, preempt_abort, register_move, replace_lost\n" "-a set the All Target Ports (ALL_TG_PT) bit\n" "-I tid specify a Transport ID, e.g.: sas,0x1234567812345678\n" "-k key specify the Reservation Key\n" "-K sa_key specify the Service Action Reservation Key\n" "-p set the Activate Persist Through Power Loss bit\n" "-R rtp specify the Relative Target Port\n" "-s scope specify the scope: lun, extent, element or a number\n" "-S specify Transport ID for register, requires -I\n" "-T res_type specify the reservation type: read_shared, wr_ex, rd_ex,\n" " ex_ac, wr_ex_ro, ex_ac_ro, wr_ex_ar, ex_ac_ar\n" "-U unregister the current initiator for register_move\n" "attrib arguments:\n" "-r action specify attr_values, attr_list, lv_list, part_list, or\n" " supp_attr\n" "-w attr specify an attribute to write, one -w argument per attr\n" "-a attr_num only display this attribute number\n" "-c get cached attributes\n" "-e elem_addr request attributes for the given element in a changer\n" "-F form1,form2 output format, comma separated list: text_esc, text_raw,\n" " nonascii_esc, nonascii_trim, nonascii_raw, field_all,\n" " field_none, field_desc, field_num, field_size, field_rw\n" "-p partition request attributes for the given partition\n" "-s start_attr request attributes starting at the given number\n" "-T elem_type specify the element type (used with -e)\n" "-V logical_vol specify the logical volume ID\n" "opcodes arguments:\n" "-o opcode specify the individual opcode to list\n" "-s service_action specify the service action for the opcode\n" "-N do not return SCSI error for unsupported SA\n" "-T request nominal and recommended timeout values\n" "zone arguments:\n" "-c cmd required: rz, open, close, finish, or rwp\n" "-a apply the action to all zones\n" "-l LBA specify the zone starting LBA\n" "-o rep_opts report zones options: all, empty, imp_open, exp_open,\n" " closed, full, ro, offline, reset, nonseq, nonwp\n" "-P print_opt report zones printing: normal, summary, script\n" "epc arguments:\n" "-c cmd required: restore, goto, timer, state, enable, disable,\n" " source, status, list\n" "-d disable power mode (timer, state)\n" "-D delayed entry (goto)\n" "-e enable power mode (timer, state)\n" "-H hold power mode (goto)\n" "-p power_cond Idle_a, Idle_b, Idle_c, Standby_y, Standby_z (timer,\n" " state, goto)\n" "-P only display power mode (status)\n" "-r rst_src restore settings from: default, saved (restore)\n" "-s save mode (timer, state, restore)\n" "-S power_src set power source: battery, nonbattery (source)\n" "-T timer set timer, seconds, .1 sec resolution (timer)\n" "timestamp arguments:\n" "-r report the timestamp of the device\n" "-f format report the timestamp of the device with the given\n" " strftime(3) format string\n" "-m report the timestamp of the device as milliseconds since\n" " January 1st, 1970\n" "-U report the time with UTC instead of the local time zone\n" "-s set the timestamp of the device\n" "-f format the format of the time string passed into strptime(3)\n" "-T time the time value passed into strptime(3)\n" "-U set the timestamp of the device to UTC time\n" ); #endif /* MINIMALISTIC */ } int main(int argc, char **argv) { int c; char *device = NULL; int unit = 0; struct cam_device *cam_dev = NULL; int timeout = 0, retry_count = 1; camcontrol_optret optreturn; char *tstr; const char *mainopt = "C:En:Q:t:u:v"; const char *subopt = NULL; char combinedopt[256]; int error = 0, optstart = 2; int task_attr = MSG_SIMPLE_Q_TAG; int devopen = 1; #ifndef MINIMALISTIC path_id_t bus; target_id_t target; lun_id_t lun; #endif /* MINIMALISTIC */ cmdlist = CAM_CMD_NONE; arglist = CAM_ARG_NONE; if (argc < 2) { usage(0); exit(1); } /* * Get the base option. */ optreturn = getoption(option_table,argv[1], &cmdlist, &arglist,&subopt); if (optreturn == CC_OR_AMBIGUOUS) { warnx("ambiguous option %s", argv[1]); usage(0); exit(1); } else if (optreturn == CC_OR_NOT_FOUND) { warnx("option %s not found", argv[1]); usage(0); exit(1); } /* * Ahh, getopt(3) is a pain. * * This is a gross hack. There really aren't many other good * options (excuse the pun) for parsing options in a situation like * this. getopt is kinda braindead, so you end up having to run * through the options twice, and give each invocation of getopt * the option string for the other invocation. * * You would think that you could just have two groups of options. * The first group would get parsed by the first invocation of * getopt, and the second group would get parsed by the second * invocation of getopt. It doesn't quite work out that way. When * the first invocation of getopt finishes, it leaves optind pointing * to the argument _after_ the first argument in the second group. * So when the second invocation of getopt comes around, it doesn't * recognize the first argument it gets and then bails out. * * A nice alternative would be to have a flag for getopt that says * "just keep parsing arguments even when you encounter an unknown * argument", but there isn't one. So there's no real clean way to * easily parse two sets of arguments without having one invocation * of getopt know about the other. * * Without this hack, the first invocation of getopt would work as * long as the generic arguments are first, but the second invocation * (in the subfunction) would fail in one of two ways. In the case * where you don't set optreset, it would fail because optind may be * pointing to the argument after the one it should be pointing at. * In the case where you do set optreset, and reset optind, it would * fail because getopt would run into the first set of options, which * it doesn't understand. * * All of this would "sort of" work if you could somehow figure out * whether optind had been incremented one option too far. The * mechanics of that, however, are more daunting than just giving * both invocations all of the expect options for either invocation. * * Needless to say, I wouldn't mind if someone invented a better * (non-GPL!) command line parsing interface than getopt. I * wouldn't mind if someone added more knobs to getopt to make it * work better. Who knows, I may talk myself into doing it someday, * if the standards weenies let me. As it is, it just leads to * hackery like this and causes people to avoid it in some cases. * * KDM, September 8th, 1998 */ if (subopt != NULL) sprintf(combinedopt, "%s%s", mainopt, subopt); else sprintf(combinedopt, "%s", mainopt); /* * For these options we do not parse optional device arguments and * we do not open a passthrough device. */ if ((cmdlist == CAM_CMD_RESCAN) || (cmdlist == CAM_CMD_RESET) || (cmdlist == CAM_CMD_DEVTREE) || (cmdlist == CAM_CMD_USAGE) || (cmdlist == CAM_CMD_DEBUG)) devopen = 0; #ifndef MINIMALISTIC if ((devopen == 1) && (argc > 2 && argv[2][0] != '-')) { char name[30]; int rv; if (isdigit(argv[2][0])) { /* device specified as bus:target[:lun] */ rv = parse_btl(argv[2], &bus, &target, &lun, &arglist); if (rv < 2) errx(1, "numeric device specification must " "be either bus:target, or " "bus:target:lun"); /* default to 0 if lun was not specified */ if ((arglist & CAM_ARG_LUN) == 0) { lun = 0; arglist |= CAM_ARG_LUN; } optstart++; } else { if (cam_get_device(argv[2], name, sizeof name, &unit) == -1) errx(1, "%s", cam_errbuf); device = strdup(name); arglist |= CAM_ARG_DEVICE | CAM_ARG_UNIT; optstart++; } } #endif /* MINIMALISTIC */ /* * Start getopt processing at argv[2/3], since we've already * accepted argv[1..2] as the command name, and as a possible * device name. */ optind = optstart; /* * Now we run through the argument list looking for generic * options, and ignoring options that possibly belong to * subfunctions. */ while ((c = getopt(argc, argv, combinedopt))!= -1){ switch(c) { case 'C': retry_count = strtol(optarg, NULL, 0); if (retry_count < 0) errx(1, "retry count %d is < 0", retry_count); arglist |= CAM_ARG_RETRIES; break; case 'E': arglist |= CAM_ARG_ERR_RECOVER; break; case 'n': arglist |= CAM_ARG_DEVICE; tstr = optarg; while (isspace(*tstr) && (*tstr != '\0')) tstr++; device = (char *)strdup(tstr); break; case 'Q': { char *endptr; int table_entry = 0; tstr = optarg; while (isspace(*tstr) && (*tstr != '\0')) tstr++; if (isdigit(*tstr)) { task_attr = strtol(tstr, &endptr, 0); if (*endptr != '\0') { errx(1, "Invalid queue option " "%s", tstr); } } else { size_t table_size; scsi_nv_status status; table_size = sizeof(task_attrs) / sizeof(task_attrs[0]); status = scsi_get_nv(task_attrs, table_size, tstr, &table_entry, SCSI_NV_FLAG_IG_CASE); if (status == SCSI_NV_FOUND) task_attr = task_attrs[ table_entry].value; else { errx(1, "%s option %s", (status == SCSI_NV_AMBIGUOUS)? "ambiguous" : "invalid", tstr); } } break; } case 't': timeout = strtol(optarg, NULL, 0); if (timeout < 0) errx(1, "invalid timeout %d", timeout); /* Convert the timeout from seconds to ms */ timeout *= 1000; arglist |= CAM_ARG_TIMEOUT; break; case 'u': arglist |= CAM_ARG_UNIT; unit = strtol(optarg, NULL, 0); break; case 'v': arglist |= CAM_ARG_VERBOSE; break; default: break; } } #ifndef MINIMALISTIC /* * For most commands we'll want to open the passthrough device * associated with the specified device. In the case of the rescan * commands, we don't use a passthrough device at all, just the * transport layer device. */ if (devopen == 1) { if (((arglist & (CAM_ARG_BUS|CAM_ARG_TARGET)) == 0) && (((arglist & CAM_ARG_DEVICE) == 0) || ((arglist & CAM_ARG_UNIT) == 0))) { errx(1, "subcommand \"%s\" requires a valid device " "identifier", argv[1]); } if ((cam_dev = ((arglist & (CAM_ARG_BUS | CAM_ARG_TARGET))? cam_open_btl(bus, target, lun, O_RDWR, NULL) : cam_open_spec_device(device,unit,O_RDWR,NULL))) == NULL) errx(1,"%s", cam_errbuf); } #endif /* MINIMALISTIC */ /* * Reset optind to 2, and reset getopt, so these routines can parse * the arguments again. */ optind = optstart; optreset = 1; switch(cmdlist) { #ifndef MINIMALISTIC case CAM_CMD_DEVLIST: error = getdevlist(cam_dev); break; case CAM_CMD_HPA: error = atahpa(cam_dev, retry_count, timeout, argc, argv, combinedopt); break; #endif /* MINIMALISTIC */ case CAM_CMD_DEVTREE: error = getdevtree(argc, argv, combinedopt); break; #ifndef MINIMALISTIC case CAM_CMD_TUR: error = testunitready(cam_dev, task_attr, retry_count, timeout, 0); break; case CAM_CMD_INQUIRY: error = scsidoinquiry(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_IDENTIFY: error = identify(cam_dev, retry_count, timeout); break; case CAM_CMD_STARTSTOP: error = scsistart(cam_dev, arglist & CAM_ARG_START_UNIT, arglist & CAM_ARG_EJECT, task_attr, retry_count, timeout); break; #endif /* MINIMALISTIC */ case CAM_CMD_RESCAN: error = dorescan_or_reset(argc, argv, 1); break; case CAM_CMD_RESET: error = dorescan_or_reset(argc, argv, 0); break; #ifndef MINIMALISTIC case CAM_CMD_READ_DEFECTS: error = readdefects(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_MODE_PAGE: modepage(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_SCSI_CMD: error = scsicmd(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_MMCSD_CMD: error = mmcsdcmd(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_SMP_CMD: error = smpcmd(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_SMP_RG: error = smpreportgeneral(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_SMP_PC: error = smpphycontrol(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_SMP_PHYLIST: error = smpphylist(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_SMP_MANINFO: error = smpmaninfo(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_DEBUG: error = camdebug(argc, argv, combinedopt); break; case CAM_CMD_TAG: error = tagcontrol(cam_dev, argc, argv, combinedopt); break; case CAM_CMD_RATE: error = ratecontrol(cam_dev, task_attr, retry_count, timeout, argc, argv, combinedopt); break; case CAM_CMD_FORMAT: error = scsiformat(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_REPORTLUNS: error = scsireportluns(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_READCAP: error = scsireadcapacity(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_IDLE: case CAM_CMD_STANDBY: case CAM_CMD_SLEEP: case CAM_CMD_POWER_MODE: error = atapm(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_APM: case CAM_CMD_AAM: error = ataaxm(cam_dev, argc, argv, combinedopt, retry_count, timeout); break; case CAM_CMD_SECURITY: error = atasecurity(cam_dev, retry_count, timeout, argc, argv, combinedopt); break; case CAM_CMD_DOWNLOAD_FW: error = fwdownload(cam_dev, argc, argv, combinedopt, arglist & CAM_ARG_VERBOSE, task_attr, retry_count, timeout); break; case CAM_CMD_SANITIZE: error = scsisanitize(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout); break; case CAM_CMD_PERSIST: error = scsipersist(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout, arglist & CAM_ARG_VERBOSE, arglist & CAM_ARG_ERR_RECOVER); break; case CAM_CMD_ATTRIB: error = scsiattrib(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout, arglist & CAM_ARG_VERBOSE, arglist & CAM_ARG_ERR_RECOVER); break; case CAM_CMD_OPCODES: error = scsiopcodes(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout, arglist & CAM_ARG_VERBOSE); break; case CAM_CMD_REPROBE: error = scsireprobe(cam_dev); break; case CAM_CMD_ZONE: error = zone(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout, arglist & CAM_ARG_VERBOSE); break; case CAM_CMD_EPC: error = epc(cam_dev, argc, argv, combinedopt, retry_count, timeout, arglist & CAM_ARG_VERBOSE); break; case CAM_CMD_TIMESTAMP: error = timestamp(cam_dev, argc, argv, combinedopt, task_attr, retry_count, timeout, arglist & CAM_ARG_VERBOSE); break; #endif /* MINIMALISTIC */ case CAM_CMD_USAGE: usage(1); break; default: usage(0); error = 1; break; } if (cam_dev != NULL) cam_close_device(cam_dev); exit(error); } Index: head/sbin/nandfs/nandfs.8 =================================================================== --- head/sbin/nandfs/nandfs.8 (revision 349351) +++ head/sbin/nandfs/nandfs.8 (nonexistent) @@ -1,79 +0,0 @@ -.\" -.\" Copyright (c) 2012 The FreeBSD Foundation -.\" All rights reserved. -.\" -.\" This software was developed by Semihalf under sponsorship -.\" from the FreeBSD Foundation. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd September 10, 2016 -.Dt NANDFS 8 -.Os -.Sh NAME -.Nm nandfs -.Nd manage mounted NAND FS -.Sh SYNOPSIS -.Nm -.Cm lssnap -.Ar node -.Nm -.Cm mksnap -.Ar node -.Nm -.Cm rmsnap -.Ar snapshot node -.Sh DESCRIPTION -The -.Nm -utility allows the management of snapshots on a mounted NAND FS. -.Sh EXAMPLES -Create a snapshot of filesystem mounted on -.Em /nand . -.Bd -literal -offset 2n -.Li # Ic nandfs mksnap /nand -1 -.Ed -.Pp -List snapshots of filesystem mounted on -.Em /nand . -.Bd -literal -offset 2n -.Li # Ic nandfs lssnap /nand -1 2012-02-28 18:49:45 ss 138 2 -.Ed -.Pp -Remove snapshot 1 of filesystem mounted on -.Em /nand . -.Bd -literal -offset 2n -.Li # Ic nandfs rmsnap 1 /nand -.Ed -.Sh HISTORY -The -.Nm -utility appeared in -.Fx 10.0 . -.Sh AUTHORS -This utility and manual page were written by -.An Mateusz Guzik . Property changes on: head/sbin/nandfs/nandfs.8 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/nandfs.c =================================================================== --- head/sbin/nandfs/nandfs.c (revision 349351) +++ head/sbin/nandfs/nandfs.c (nonexistent) @@ -1,76 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Semihalf under sponsorship - * from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include "nandfs.h" - -static void -usage(void) -{ - - fprintf(stderr, "usage: nandfs [lssnap | mksnap | rmsnap ] " - "node\n"); - exit(1); -} - -int -main(int argc, char **argv) -{ - int error = 0; - char *cmd; - - if (argc < 2) - usage(); - - cmd = argv[1]; - argc -= 2; - argv += 2; - - if (strcmp(cmd, "lssnap") == 0) - error = nandfs_lssnap(argc, argv); - else if (strcmp(cmd, "mksnap") == 0) - error = nandfs_mksnap(argc, argv); - else if (strcmp(cmd, "rmsnap") == 0) - error = nandfs_rmsnap(argc, argv); - else - usage(); - - return (error); -} Property changes on: head/sbin/nandfs/nandfs.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/nandfs.h =================================================================== --- head/sbin/nandfs/nandfs.h (revision 349351) +++ head/sbin/nandfs/nandfs.h (nonexistent) @@ -1,42 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Semihalf under sponsorship - * from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef NANDFS_H -#define NANDFS_H - -int nandfs_lssnap(int, char **); -int nandfs_mksnap(int, char **); -int nandfs_rmsnap(int, char **); - -#endif /* !NANDFS_H */ Property changes on: head/sbin/nandfs/nandfs.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/rmsnap.c =================================================================== --- head/sbin/nandfs/rmsnap.c (revision 349351) +++ head/sbin/nandfs/rmsnap.c (nonexistent) @@ -1,89 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Semihalf under sponsorship - * from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include - -#include -#include -#include -#include - -#include -#include - -#include "nandfs.h" - -static void -rmsnap_usage(void) -{ - - fprintf(stderr, "usage:\n"); - fprintf(stderr, "\trmsnap snap node\n"); -} - -int -nandfs_rmsnap(int argc, char **argv) -{ - struct nandfs fs; - uint64_t cpno; - int error; - - if (argc != 2) { - rmsnap_usage(); - return (EX_USAGE); - } - - cpno = strtoll(argv[0], (char **)NULL, 10); - if (cpno == 0) { - fprintf(stderr, "%s must be a number greater than 0\n", - argv[0]); - return (EX_USAGE); - } - - nandfs_init(&fs, argv[1]); - error = nandfs_open(&fs); - if (error == -1) { - fprintf(stderr, "nandfs_open: %s\n", nandfs_errmsg(&fs)); - goto out; - } - - error = nandfs_delete_snap(&fs, cpno); - if (error == -1) - fprintf(stderr, "nandfs_delete_snap: %s\n", nandfs_errmsg(&fs)); - -out: - nandfs_close(&fs); - nandfs_destroy(&fs); - return (error); -} Property changes on: head/sbin/nandfs/rmsnap.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/Makefile.depend =================================================================== --- head/sbin/nandfs/Makefile.depend (revision 349351) +++ head/sbin/nandfs/Makefile.depend (nonexistent) @@ -1,18 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libnandfs \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Property changes on: head/sbin/nandfs/Makefile.depend ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/lssnap.c =================================================================== --- head/sbin/nandfs/lssnap.c (revision 349351) +++ head/sbin/nandfs/lssnap.c (nonexistent) @@ -1,114 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Semihalf under sponsorship - * from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include - -#include -#include -#include -#include - -#include -#include - -#include "nandfs.h" - -#define NCPINFO 512 - -static void -lssnap_usage(void) -{ - - fprintf(stderr, "usage:\n"); - fprintf(stderr, "\tlssnap node\n"); -} - -static void -print_cpinfo(struct nandfs_cpinfo *cpinfo) -{ - struct tm tm; - time_t t; - char timebuf[128]; - - t = (time_t)cpinfo->nci_create; - localtime_r(&t, &tm); - strftime(timebuf, sizeof(timebuf), "%F %T", &tm); - - printf("%20llu %s\n", (unsigned long long)cpinfo->nci_cno, timebuf); -} - -int -nandfs_lssnap(int argc, char **argv) -{ - struct nandfs_cpinfo *cpinfos; - struct nandfs fs; - uint64_t next; - int error, nsnap, i; - - if (argc != 1) { - lssnap_usage(); - return (EX_USAGE); - } - - cpinfos = malloc(sizeof(*cpinfos) * NCPINFO); - if (cpinfos == NULL) { - fprintf(stderr, "cannot allocate memory\n"); - return (-1); - } - - nandfs_init(&fs, argv[0]); - error = nandfs_open(&fs); - if (error == -1) { - fprintf(stderr, "nandfs_open: %s\n", nandfs_errmsg(&fs)); - goto out; - } - - for (next = 1; next != 0; next = cpinfos[nsnap - 1].nci_next) { - nsnap = nandfs_get_snap(&fs, next, cpinfos, NCPINFO); - if (nsnap < 1) - break; - - for (i = 0; i < nsnap; i++) - print_cpinfo(&cpinfos[i]); - } - - if (nsnap == -1) - fprintf(stderr, "nandfs_get_snap: %s\n", nandfs_errmsg(&fs)); - -out: - nandfs_close(&fs); - nandfs_destroy(&fs); - free(cpinfos); - return (error); -} Property changes on: head/sbin/nandfs/lssnap.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/Makefile =================================================================== --- head/sbin/nandfs/Makefile (revision 349351) +++ head/sbin/nandfs/Makefile (nonexistent) @@ -1,10 +0,0 @@ -# $FreeBSD$ - -PACKAGE=nandfs -PROG= nandfs -SRCS= nandfs.c lssnap.c mksnap.c rmsnap.c -MAN= nandfs.8 - -LIBADD= nandfs - -.include Property changes on: head/sbin/nandfs/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/nandfs/mksnap.c =================================================================== --- head/sbin/nandfs/mksnap.c (revision 349351) +++ head/sbin/nandfs/mksnap.c (nonexistent) @@ -1,82 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Semihalf under sponsorship - * from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); -#include - -#include -#include - -#include -#include - -#include "nandfs.h" - -static void -mksnap_usage(void) -{ - - fprintf(stderr, "usage:\n"); - fprintf(stderr, "\tmksnap node\n"); -} - -int -nandfs_mksnap(int argc, char **argv) -{ - struct nandfs fs; - uint64_t cpno; - int error; - - if (argc != 1) { - mksnap_usage(); - return (EX_USAGE); - } - - nandfs_init(&fs, argv[0]); - error = nandfs_open(&fs); - if (error == -1) { - fprintf(stderr, "nandfs_open: %s\n", nandfs_errmsg(&fs)); - goto out; - } - - error = nandfs_make_snap(&fs, &cpno); - if (error == -1) - fprintf(stderr, "nandfs_make_snap: %s\n", nandfs_errmsg(&fs)); - else - printf("%jd\n", cpno); - -out: - nandfs_close(&fs); - nandfs_destroy(&fs); - return (error); -} Property changes on: head/sbin/nandfs/mksnap.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/newfs_nandfs/Makefile.depend =================================================================== --- head/sbin/newfs_nandfs/Makefile.depend (revision 349351) +++ head/sbin/newfs_nandfs/Makefile.depend (nonexistent) @@ -1,20 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libexpat \ - lib/libgeom \ - lib/libsbuf \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Property changes on: head/sbin/newfs_nandfs/Makefile.depend ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/newfs_nandfs/newfs_nandfs.c =================================================================== --- head/sbin/newfs_nandfs/newfs_nandfs.c (revision 349351) +++ head/sbin/newfs_nandfs/newfs_nandfs.c (nonexistent) @@ -1,1183 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DEBUG -#undef DEBUG -#ifdef DEBUG -#define debug(fmt, args...) do { \ - printf("nandfs:" fmt "\n", ##args); } while (0) -#else -#define debug(fmt, args...) -#endif - -#define NANDFS_FIRST_BLOCK nandfs_first_block() -#define NANDFS_FIRST_CNO 1 -#define NANDFS_BLOCK_BAD 1 -#define NANDFS_BLOCK_GOOD 0 - -struct file_info { - uint64_t ino; - const char *name; - uint32_t mode; - uint64_t size; - uint8_t nblocks; - uint32_t *blocks; - struct nandfs_inode *inode; -}; - -static struct file_info user_files[] = { - { NANDFS_ROOT_INO, NULL, S_IFDIR | 0755, 0, 1, NULL, NULL }, -}; - -static struct file_info ifile = - { NANDFS_IFILE_INO, NULL, 0, 0, -1, NULL, NULL }; -static struct file_info sufile = - { NANDFS_SUFILE_INO, NULL, 0, 0, -1, NULL, NULL }; -static struct file_info cpfile = - { NANDFS_CPFILE_INO, NULL, 0, 0, -1, NULL, NULL }; -static struct file_info datfile = - { NANDFS_DAT_INO, NULL, 0, 0, -1, NULL, NULL }; - -struct nandfs_block { - LIST_ENTRY(nandfs_block) block_link; - uint32_t number; - uint64_t offset; - void *data; -}; - -static LIST_HEAD(, nandfs_block) block_head = - LIST_HEAD_INITIALIZER(&block_head); - -/* Storage geometry */ -static off_t mediasize; -static ssize_t sectorsize; -static uint64_t nsegments; -static uint64_t erasesize; -static uint64_t segsize; - -static struct nandfs_fsdata fsdata; -static struct nandfs_super_block super_block; - -static int is_nand; - -/* Nandfs parameters */ -static size_t blocksize = NANDFS_DEF_BLOCKSIZE; -static long blocks_per_segment; -static long rsv_segment_percent = 5; -static time_t nandfs_time; -static uint32_t bad_segments_count = 0; -static uint32_t *bad_segments = NULL; -static uint8_t fsdata_blocks_state[NANDFS_NFSAREAS]; - -static u_char *volumelabel = NULL; - -static struct nandfs_super_root *sr; - -static uint32_t nuserfiles; -static uint32_t seg_nblocks; -static uint32_t seg_endblock; - -#define SIZE_TO_BLOCK(size) howmany(size, blocksize) - -static uint32_t -nandfs_first_block(void) -{ - uint32_t i, first_free, start_bad_segments = 0; - - for (i = 0; i < bad_segments_count; i++) { - if (i == bad_segments[i]) - start_bad_segments++; - else - break; - } - - first_free = SIZE_TO_BLOCK(NANDFS_DATA_OFFSET_BYTES(erasesize) + - (start_bad_segments * segsize)); - - if (first_free < (uint32_t)blocks_per_segment) - return (blocks_per_segment); - else - return (first_free); -} - -static void -usage(void) -{ - - fprintf(stderr, - "usage: newfs_nandfs [ -options ] device\n" - "where the options are:\n" - "\t-b block-size\n" - "\t-B blocks-per-segment\n" - "\t-L volume label\n" - "\t-m reserved-segments-percentage\n"); - exit(1); -} - -static int -nandfs_log2(unsigned n) -{ - unsigned count; - - /* - * N.B. this function will return 0 if supplied 0. - */ - for (count = 0; n/2; count++) - n /= 2; - return count; -} - -/* from NetBSD's src/sys/net/if_ethersubr.c */ -static uint32_t -crc32_le(uint32_t crc, const uint8_t *buf, size_t len) -{ - static const uint32_t crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - size_t i; - - crc = crc ^ ~0U; - - for (i = 0; i < len; i++) { - crc ^= buf[i]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - - return (crc ^ ~0U); -} - -static void * -get_block(uint32_t block_nr, uint64_t offset) -{ - struct nandfs_block *block, *new_block; - - LIST_FOREACH(block, &block_head, block_link) { - if (block->number == block_nr) - return block->data; - } - - debug("allocating block %x\n", block_nr); - - new_block = malloc(sizeof(*block)); - if (!new_block) - err(1, "cannot allocate block"); - - new_block->number = block_nr; - new_block->offset = offset; - new_block->data = malloc(blocksize); - if (!new_block->data) - err(1, "cannot allocate block data"); - - memset(new_block->data, 0, blocksize); - - LIST_INSERT_HEAD(&block_head, new_block, block_link); - - return (new_block->data); -} - -static int -nandfs_seg_usage_blk_offset(uint64_t seg, uint64_t *blk, uint64_t *offset) -{ - uint64_t off; - uint16_t seg_size; - - seg_size = sizeof(struct nandfs_segment_usage); - - off = roundup(sizeof(struct nandfs_sufile_header), seg_size); - off += (seg * seg_size); - - *blk = off / blocksize; - *offset = (off % blocksize) / seg_size; - return (0); -} - -static uint32_t -segment_size(void) -{ - u_int size; - - size = sizeof(struct nandfs_segment_summary ); - size += seg_nblocks * sizeof(struct nandfs_binfo_v); - - if (size > blocksize) - err(1, "segsum info bigger that blocksize"); - - return (size); -} - - -static void -prepare_blockgrouped_file(uint32_t block) -{ - struct nandfs_block_group_desc *desc; - uint32_t i, entries; - - desc = (struct nandfs_block_group_desc *)get_block(block, 0); - entries = blocksize / sizeof(struct nandfs_block_group_desc); - for (i = 0; i < entries; i++) - desc[i].bg_nfrees = blocksize * 8; -} - -static void -alloc_blockgrouped_file(uint32_t block, uint32_t entry) -{ - struct nandfs_block_group_desc *desc; - uint32_t desc_nr; - uint32_t *bitmap; - - desc = (struct nandfs_block_group_desc *)get_block(block, 0); - bitmap = (uint32_t *)get_block(block + 1, 1); - - bitmap += (entry >> 5); - if (*bitmap & (1 << (entry % 32))) { - printf("nandfs: blockgrouped entry %d already allocated\n", - entry); - } - *bitmap |= (1 << (entry % 32)); - - desc_nr = entry / (blocksize * 8); - desc[desc_nr].bg_nfrees--; -} - - -static uint64_t -count_su_blocks(void) -{ - uint64_t maxblk, blk, offset, i; - - maxblk = blk = 0; - - for (i = 0; i < bad_segments_count; i++) { - nandfs_seg_usage_blk_offset(bad_segments[i], &blk, &offset); - debug("bad segment at block:%jx off: %jx", blk, offset); - if (blk > maxblk) - maxblk = blk; - } - - debug("bad segment needs %#jx", blk); - if (blk >= NANDFS_NDADDR) { - printf("nandfs: file too big (%jd > %d)\n", blk, NANDFS_NDADDR); - exit(2); - } - - sufile.size = (blk + 1) * blocksize; - return (blk + 1); -} - -static void -count_seg_blocks(void) -{ - uint32_t i; - - for (i = 0; i < nuserfiles; i++) - if (user_files[i].nblocks) { - seg_nblocks += user_files[i].nblocks; - user_files[i].blocks = malloc(user_files[i].nblocks * sizeof(uint32_t)); - } - - ifile.nblocks = 2 + - SIZE_TO_BLOCK(sizeof(struct nandfs_inode) * (NANDFS_USER_INO + 1)); - ifile.blocks = malloc(ifile.nblocks * sizeof(uint32_t)); - seg_nblocks += ifile.nblocks; - - cpfile.nblocks = - SIZE_TO_BLOCK((NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET + 1) * - sizeof(struct nandfs_checkpoint)); - cpfile.blocks = malloc(cpfile.nblocks * sizeof(uint32_t)); - seg_nblocks += cpfile.nblocks; - - if (!bad_segments) { - sufile.nblocks = - SIZE_TO_BLOCK((NANDFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET + 1) * - sizeof(struct nandfs_segment_usage)); - } else { - debug("bad blocks found: extra space for sufile"); - sufile.nblocks = count_su_blocks(); - } - - sufile.blocks = malloc(sufile.nblocks * sizeof(uint32_t)); - seg_nblocks += sufile.nblocks; - - datfile.nblocks = 2 + - SIZE_TO_BLOCK((seg_nblocks) * sizeof(struct nandfs_dat_entry)); - datfile.blocks = malloc(datfile.nblocks * sizeof(uint32_t)); - seg_nblocks += datfile.nblocks; -} - -static void -assign_file_blocks(uint64_t start_block) -{ - uint32_t i, j; - - for (i = 0; i < nuserfiles; i++) - for (j = 0; j < user_files[i].nblocks; j++) { - debug("user file %d at block %d at %#jx", - i, j, (uintmax_t)start_block); - user_files[i].blocks[j] = start_block++; - } - - for (j = 0; j < ifile.nblocks; j++) { - debug("ifile block %d at %#jx", j, (uintmax_t)start_block); - ifile.blocks[j] = start_block++; - } - - for (j = 0; j < cpfile.nblocks; j++) { - debug("cpfile block %d at %#jx", j, (uintmax_t)start_block); - cpfile.blocks[j] = start_block++; - } - - for (j = 0; j < sufile.nblocks; j++) { - debug("sufile block %d at %#jx", j, (uintmax_t)start_block); - sufile.blocks[j] = start_block++; - } - - for (j = 0; j < datfile.nblocks; j++) { - debug("datfile block %d at %#jx", j, (uintmax_t)start_block); - datfile.blocks[j] = start_block++; - } - - /* add one for superroot */ - debug("sr at block %#jx", (uintmax_t)start_block); - sr = (struct nandfs_super_root *)get_block(start_block++, 0); - seg_endblock = start_block; -} - -static void -save_datfile(void) -{ - - prepare_blockgrouped_file(datfile.blocks[0]); -} - -static uint64_t -update_datfile(uint64_t block) -{ - struct nandfs_dat_entry *dat; - static uint64_t vblock = 0; - uint64_t allocated, i, off; - - if (vblock == 0) { - alloc_blockgrouped_file(datfile.blocks[0], vblock); - vblock++; - } - allocated = vblock; - i = vblock / (blocksize / sizeof(*dat)); - off = vblock % (blocksize / sizeof(*dat)); - vblock++; - - dat = (struct nandfs_dat_entry *)get_block(datfile.blocks[2 + i], 2 + i); - - alloc_blockgrouped_file(datfile.blocks[0], allocated); - dat[off].de_blocknr = block; - dat[off].de_start = NANDFS_FIRST_CNO; - dat[off].de_end = UINTMAX_MAX; - - return (allocated); -} - -static union nandfs_binfo * -update_block_info(union nandfs_binfo *binfo, struct file_info *file) -{ - nandfs_daddr_t vblock; - uint32_t i; - - for (i = 0; i < file->nblocks; i++) { - debug("%s: blk %x", __func__, i); - if (file->ino != NANDFS_DAT_INO) { - vblock = update_datfile(file->blocks[i]); - binfo->bi_v.bi_vblocknr = vblock; - binfo->bi_v.bi_blkoff = i; - binfo->bi_v.bi_ino = file->ino; - file->inode->i_db[i] = vblock; - } else { - binfo->bi_dat.bi_blkoff = i; - binfo->bi_dat.bi_ino = file->ino; - file->inode->i_db[i] = datfile.blocks[i]; - } - binfo++; - } - - return (binfo); -} - -static void -save_segsum(struct nandfs_segment_summary *ss) -{ - union nandfs_binfo *binfo; - struct nandfs_block *block; - uint32_t sum_bytes, i; - uint8_t crc_data, crc_skip; - - sum_bytes = segment_size(); - ss->ss_magic = NANDFS_SEGSUM_MAGIC; - ss->ss_bytes = sizeof(struct nandfs_segment_summary); - ss->ss_flags = NANDFS_SS_LOGBGN | NANDFS_SS_LOGEND | NANDFS_SS_SR; - ss->ss_seq = 1; - ss->ss_create = nandfs_time; - - ss->ss_next = nandfs_first_block() + blocks_per_segment; - /* nblocks = segment blocks + segsum block + superroot */ - ss->ss_nblocks = seg_nblocks + 2; - ss->ss_nbinfos = seg_nblocks; - ss->ss_sumbytes = sum_bytes; - - crc_skip = sizeof(ss->ss_datasum) + sizeof(ss->ss_sumsum); - ss->ss_sumsum = crc32_le(0, (uint8_t *)ss + crc_skip, - sum_bytes - crc_skip); - crc_data = 0; - - binfo = (union nandfs_binfo *)(ss + 1); - for (i = 0; i < nuserfiles; i++) { - if (user_files[i].nblocks) - binfo = update_block_info(binfo, &user_files[i]); - } - - binfo = update_block_info(binfo, &ifile); - binfo = update_block_info(binfo, &cpfile); - binfo = update_block_info(binfo, &sufile); - update_block_info(binfo, &datfile); - - /* save superroot crc */ - crc_skip = sizeof(sr->sr_sum); - sr->sr_sum = crc32_le(0, (uint8_t *)sr + crc_skip, - NANDFS_SR_BYTES - crc_skip); - - /* segment checksup */ - crc_skip = sizeof(ss->ss_datasum); - LIST_FOREACH(block, &block_head, block_link) { - if (block->number < NANDFS_FIRST_BLOCK) - continue; - if (block->number == NANDFS_FIRST_BLOCK) - crc_data = crc32_le(0, - (uint8_t *)block->data + crc_skip, - blocksize - crc_skip); - else - crc_data = crc32_le(crc_data, (uint8_t *)block->data, - blocksize); - } - ss->ss_datasum = crc_data; -} - -static void -create_fsdata(void) -{ - struct uuid tmp; - - memset(&fsdata, 0, sizeof(struct nandfs_fsdata)); - - fsdata.f_magic = NANDFS_FSDATA_MAGIC; - fsdata.f_nsegments = nsegments; - fsdata.f_erasesize = erasesize; - fsdata.f_first_data_block = NANDFS_FIRST_BLOCK; - fsdata.f_blocks_per_segment = blocks_per_segment; - fsdata.f_r_segments_percentage = rsv_segment_percent; - fsdata.f_rev_level = NANDFS_CURRENT_REV; - fsdata.f_sbbytes = NANDFS_SB_BYTES; - fsdata.f_bytes = NANDFS_FSDATA_CRC_BYTES; - fsdata.f_ctime = nandfs_time; - fsdata.f_log_block_size = nandfs_log2(blocksize) - 10; - fsdata.f_errors = 1; - fsdata.f_inode_size = sizeof(struct nandfs_inode); - fsdata.f_dat_entry_size = sizeof(struct nandfs_dat_entry); - fsdata.f_checkpoint_size = sizeof(struct nandfs_checkpoint); - fsdata.f_segment_usage_size = sizeof(struct nandfs_segment_usage); - - uuidgen(&tmp, 1); - fsdata.f_uuid = tmp; - - if (volumelabel) - memcpy(fsdata.f_volume_name, volumelabel, 16); - - fsdata.f_sum = crc32_le(0, (const uint8_t *)&fsdata, - NANDFS_FSDATA_CRC_BYTES); -} - -static void -save_fsdata(void *data) -{ - - memcpy(data, &fsdata, sizeof(fsdata)); -} - -static void -create_super_block(void) -{ - - memset(&super_block, 0, sizeof(struct nandfs_super_block)); - - super_block.s_magic = NANDFS_SUPER_MAGIC; - super_block.s_last_cno = NANDFS_FIRST_CNO; - super_block.s_last_pseg = NANDFS_FIRST_BLOCK; - super_block.s_last_seq = 1; - super_block.s_free_blocks_count = - (nsegments - bad_segments_count) * blocks_per_segment; - super_block.s_mtime = 0; - super_block.s_wtime = nandfs_time; - super_block.s_state = NANDFS_VALID_FS; - - super_block.s_sum = crc32_le(0, (const uint8_t *)&super_block, - NANDFS_SB_BYTES); -} - -static void -save_super_block(void *data) -{ - - memcpy(data, &super_block, sizeof(super_block)); -} - -static void -save_super_root(void) -{ - - sr->sr_bytes = NANDFS_SR_BYTES; - sr->sr_flags = 0; - sr->sr_nongc_ctime = nandfs_time; - datfile.inode = &sr->sr_dat; - cpfile.inode = &sr->sr_cpfile; - sufile.inode = &sr->sr_sufile; -} - -static struct nandfs_dir_entry * -add_de(void *block, struct nandfs_dir_entry *de, uint64_t ino, - const char *name, uint8_t type) -{ - uint16_t reclen; - - /* modify last de */ - de->rec_len = NANDFS_DIR_REC_LEN(de->name_len); - de = (void *)((uint8_t *)de + de->rec_len); - - reclen = blocksize - ((uintptr_t)de - (uintptr_t)block); - if (reclen < NANDFS_DIR_REC_LEN(strlen(name))) { - printf("nandfs: too many dir entries for one block\n"); - return (NULL); - } - - de->inode = ino; - de->rec_len = reclen; - de->name_len = strlen(name); - de->file_type = type; - memset(de->name, 0, - (strlen(name) + NANDFS_DIR_PAD - 1) & ~NANDFS_DIR_ROUND); - memcpy(de->name, name, strlen(name)); - - return (de); -} - -static struct nandfs_dir_entry * -make_dir(void *block, uint64_t ino, uint64_t parent_ino) -{ - struct nandfs_dir_entry *de = (struct nandfs_dir_entry *)block; - - /* create '..' entry */ - de->inode = parent_ino; - de->rec_len = NANDFS_DIR_REC_LEN(2); - de->name_len = 2; - de->file_type = DT_DIR; - memset(de->name, 0, NANDFS_DIR_NAME_LEN(2)); - memcpy(de->name, "..", 2); - - /* create '.' entry */ - de = (void *)((uint8_t *)block + NANDFS_DIR_REC_LEN(2)); - de->inode = ino; - de->rec_len = blocksize - NANDFS_DIR_REC_LEN(2); - de->name_len = 1; - de->file_type = DT_DIR; - memset(de->name, 0, NANDFS_DIR_NAME_LEN(1)); - memcpy(de->name, ".", 1); - - return (de); -} - -static void -save_root_dir(void) -{ - struct file_info *root = &user_files[0]; - struct nandfs_dir_entry *de; - uint32_t i; - void *block; - - block = get_block(root->blocks[0], 0); - - de = make_dir(block, root->ino, root->ino); - for (i = 1; i < nuserfiles; i++) - de = add_de(block, de, user_files[i].ino, user_files[i].name, - IFTODT(user_files[i].mode)); - - root->size = ((uintptr_t)de - (uintptr_t)block) + - NANDFS_DIR_REC_LEN(de->name_len); -} - -static void -save_sufile(void) -{ - struct nandfs_sufile_header *header; - struct nandfs_segment_usage *su; - uint64_t blk, i, off; - void *block; - int start; - - /* - * At the beginning just zero-out everything - */ - for (i = 0; i < sufile.nblocks; i++) - get_block(sufile.blocks[i], 0); - - start = 0; - - block = get_block(sufile.blocks[start], 0); - header = (struct nandfs_sufile_header *)block; - header->sh_ncleansegs = nsegments - bad_segments_count - 1; - header->sh_ndirtysegs = 1; - header->sh_last_alloc = 1; - - su = (struct nandfs_segment_usage *)header; - off = NANDFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET; - /* Allocate data segment */ - su[off].su_lastmod = nandfs_time; - /* nblocks = segment blocks + segsum block + superroot */ - su[off].su_nblocks = seg_nblocks + 2; - su[off].su_flags = NANDFS_SEGMENT_USAGE_DIRTY; - off++; - /* Allocate next segment */ - su[off].su_lastmod = nandfs_time; - su[off].su_nblocks = 0; - su[off].su_flags = NANDFS_SEGMENT_USAGE_DIRTY; - for (i = 0; i < bad_segments_count; i++) { - nandfs_seg_usage_blk_offset(bad_segments[i], &blk, &off); - debug("storing bad_segments[%jd]=%x at %jx off %jx\n", i, - bad_segments[i], blk, off); - block = get_block(sufile.blocks[blk], - off * sizeof(struct nandfs_segment_usage *)); - su = (struct nandfs_segment_usage *)block; - su[off].su_lastmod = nandfs_time; - su[off].su_nblocks = 0; - su[off].su_flags = NANDFS_SEGMENT_USAGE_ERROR; - } -} - -static void -save_cpfile(void) -{ - struct nandfs_cpfile_header *header; - struct nandfs_checkpoint *cp, *initial_cp; - int i, entries = blocksize / sizeof(struct nandfs_checkpoint); - uint64_t cno; - - header = (struct nandfs_cpfile_header *)get_block(cpfile.blocks[0], 0); - header->ch_ncheckpoints = 1; - header->ch_nsnapshots = 0; - - cp = (struct nandfs_checkpoint *)header; - - /* fill first checkpoint data*/ - initial_cp = &cp[NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET]; - initial_cp->cp_flags = 0; - initial_cp->cp_checkpoints_count = 0; - initial_cp->cp_cno = NANDFS_FIRST_CNO; - initial_cp->cp_create = nandfs_time; - initial_cp->cp_nblk_inc = seg_endblock - 1; - initial_cp->cp_blocks_count = seg_nblocks; - memset(&initial_cp->cp_snapshot_list, 0, - sizeof(struct nandfs_snapshot_list)); - - ifile.inode = &initial_cp->cp_ifile_inode; - - /* mark rest of cp as invalid */ - cno = NANDFS_FIRST_CNO + 1; - i = NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET + 1; - for (; i < entries; i++) { - cp[i].cp_cno = cno++; - cp[i].cp_flags = NANDFS_CHECKPOINT_INVALID; - } -} - -static void -init_inode(struct nandfs_inode *inode, struct file_info *file) -{ - - inode->i_blocks = file->nblocks; - inode->i_ctime = nandfs_time; - inode->i_mtime = nandfs_time; - inode->i_mode = file->mode & 0xffff; - inode->i_links_count = 1; - - if (file->size > 0) - inode->i_size = file->size; - else - inode->i_size = 0; - - if (file->ino == NANDFS_USER_INO) - inode->i_flags = SF_NOUNLINK|UF_NOUNLINK; - else - inode->i_flags = 0; -} - -static void -save_ifile(void) -{ - struct nandfs_inode *inode; - struct file_info *file; - uint64_t ino, blk, off; - uint32_t i; - - prepare_blockgrouped_file(ifile.blocks[0]); - for (i = 0; i <= NANDFS_USER_INO; i++) - alloc_blockgrouped_file(ifile.blocks[0], i); - - for (i = 0; i < nuserfiles; i++) { - file = &user_files[i]; - ino = file->ino; - blk = ino / (blocksize / sizeof(*inode)); - off = ino % (blocksize / sizeof(*inode)); - inode = - (struct nandfs_inode *)get_block(ifile.blocks[2 + blk], 2 + blk); - file->inode = &inode[off]; - init_inode(file->inode, file); - } - - init_inode(ifile.inode, &ifile); - init_inode(cpfile.inode, &cpfile); - init_inode(sufile.inode, &sufile); - init_inode(datfile.inode, &datfile); -} - -static int -create_fs(void) -{ - uint64_t start_block; - uint32_t segsum_size; - char *data; - int i; - - nuserfiles = nitems(user_files); - - /* Count and assign blocks */ - count_seg_blocks(); - segsum_size = segment_size(); - start_block = NANDFS_FIRST_BLOCK + SIZE_TO_BLOCK(segsum_size); - assign_file_blocks(start_block); - - /* Create super root structure */ - save_super_root(); - - /* Create root directory */ - save_root_dir(); - - /* Fill in file contents */ - save_sufile(); - save_cpfile(); - save_ifile(); - save_datfile(); - - /* Save fsdata and superblocks */ - create_fsdata(); - create_super_block(); - - for (i = 0; i < NANDFS_NFSAREAS; i++) { - if (fsdata_blocks_state[i] != NANDFS_BLOCK_GOOD) - continue; - - data = get_block((i * erasesize)/blocksize, 0); - save_fsdata(data); - - data = get_block((i * erasesize + NANDFS_SBLOCK_OFFSET_BYTES) / - blocksize, 0); - if (blocksize > NANDFS_SBLOCK_OFFSET_BYTES) - data += NANDFS_SBLOCK_OFFSET_BYTES; - save_super_block(data); - memset(data + sizeof(struct nandfs_super_block), 0xff, - (blocksize - sizeof(struct nandfs_super_block) - - NANDFS_SBLOCK_OFFSET_BYTES)); - } - - /* Save segment summary and CRCs */ - save_segsum(get_block(NANDFS_FIRST_BLOCK, 0)); - - return (0); -} - -static void -write_fs(int fda) -{ - struct nandfs_block *block; - char *data; - u_int ret; - - /* Overwrite next block with ff if not nand device */ - if (!is_nand) { - data = get_block(seg_endblock, 0); - memset(data, 0xff, blocksize); - } - - LIST_FOREACH(block, &block_head, block_link) { - lseek(fda, block->number * blocksize, SEEK_SET); - ret = write(fda, block->data, blocksize); - if (ret != blocksize) - err(1, "cannot write filesystem data"); - } -} - -static void -check_parameters(void) -{ - int i; - - /* check blocksize */ - if ((blocksize < NANDFS_MIN_BLOCKSIZE) || (blocksize > MAXBSIZE) || - ((blocksize - 1) & blocksize)) { - errx(1, "Bad blocksize (%zu). Must be in range [%u-%u] " - "and a power of two.", blocksize, NANDFS_MIN_BLOCKSIZE, - MAXBSIZE); - } - - /* check blocks per segments */ - if ((blocks_per_segment < NANDFS_SEG_MIN_BLOCKS) || - ((blocksize - 1) & blocksize)) - errx(1, "Bad blocks per segment (%lu). Must be greater than " - "%u and a power of two.", blocks_per_segment, - NANDFS_SEG_MIN_BLOCKS); - - /* check reserved segment percentage */ - if ((rsv_segment_percent < 1) || (rsv_segment_percent > 99)) - errx(1, "Bad reserved segment percentage. " - "Must in range 1..99."); - - /* check volume label */ - i = 0; - if (volumelabel) { - while (isalnum(volumelabel[++i])) - ; - - if (volumelabel[i] != '\0') { - errx(1, "bad volume label. " - "Valid characters are alphanumerics."); - } - - if (strlen(volumelabel) >= 16) - errx(1, "Bad volume label. Length is longer than %d.", - 16); - } - - nandfs_time = time(NULL); -} - -static void -print_parameters(void) -{ - - printf("filesystem parameters:\n"); - printf("blocksize: %#zx sectorsize: %#zx\n", blocksize, sectorsize); - printf("erasesize: %#jx mediasize: %#jx\n", erasesize, mediasize); - printf("segment size: %#jx blocks per segment: %#x\n", segsize, - (uint32_t)blocks_per_segment); -} - -/* - * Exit with error if file system is mounted. - */ -static void -check_mounted(const char *fname, mode_t mode) -{ - struct statfs *mp; - const char *s1, *s2; - size_t len; - int n, r; - - if (!(n = getmntinfo(&mp, MNT_NOWAIT))) - err(1, "getmntinfo"); - - len = strlen(_PATH_DEV); - s1 = fname; - if (!strncmp(s1, _PATH_DEV, len)) - s1 += len; - - r = S_ISCHR(mode) && s1 != fname && *s1 == 'r'; - - for (; n--; mp++) { - s2 = mp->f_mntfromname; - - if (!strncmp(s2, _PATH_DEV, len)) - s2 += len; - if ((r && s2 != mp->f_mntfromname && !strcmp(s1 + 1, s2)) || - !strcmp(s1, s2)) - errx(1, "%s is mounted on %s", fname, mp->f_mntonname); - } -} - -static void -calculate_geometry(int fd) -{ - struct chip_param_io chip_params; - char ident[DISK_IDENT_SIZE]; - char medianame[MAXPATHLEN]; - - /* Check storage type */ - g_get_ident(fd, ident, DISK_IDENT_SIZE); - g_get_name(ident, medianame, MAXPATHLEN); - debug("device name: %s", medianame); - - is_nand = (strstr(medianame, "gnand") != NULL); - debug("is_nand = %d", is_nand); - - sectorsize = g_sectorsize(fd); - debug("sectorsize: %#zx", sectorsize); - - /* Get storage size */ - mediasize = g_mediasize(fd); - debug("mediasize: %#jx", mediasize); - - /* Get storage erase unit size */ - if (!is_nand) - erasesize = NANDFS_DEF_ERASESIZE; - else if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) != -1) - erasesize = chip_params.page_size * chip_params.pages_per_block; - else - errx(1, "Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - - debug("erasesize: %#jx", (uintmax_t)erasesize); - - if (blocks_per_segment == 0) { - if (erasesize >= NANDFS_MIN_SEGSIZE) - blocks_per_segment = erasesize / blocksize; - else - blocks_per_segment = NANDFS_MIN_SEGSIZE / blocksize; - } - - /* Calculate number of segments */ - segsize = blocksize * blocks_per_segment; - nsegments = ((mediasize - NANDFS_NFSAREAS * erasesize) / segsize) - 2; - debug("segsize: %#jx", segsize); - debug("nsegments: %#jx", nsegments); -} - -static void -erase_device(int fd) -{ - int rest, failed; - uint64_t i, nblocks; - off_t offset; - - failed = 0; - for (i = 0; i < NANDFS_NFSAREAS; i++) { - debug("Deleting %jx\n", i * erasesize); - if (g_delete(fd, i * erasesize, erasesize)) { - printf("cannot delete %jx\n", i * erasesize); - fsdata_blocks_state[i] = NANDFS_BLOCK_BAD; - failed++; - } else - fsdata_blocks_state[i] = NANDFS_BLOCK_GOOD; - } - - if (failed == NANDFS_NFSAREAS) { - printf("%d first blocks not usable. Unable to create " - "filesystem.\n", failed); - exit(1); - } - - for (i = 0; i < nsegments; i++) { - offset = NANDFS_NFSAREAS * erasesize + i * segsize; - if (g_delete(fd, offset, segsize)) { - printf("cannot delete segment %jx (offset %jd)\n", - i, offset); - bad_segments_count++; - bad_segments = realloc(bad_segments, - bad_segments_count * sizeof(uint32_t)); - bad_segments[bad_segments_count - 1] = i; - } - } - - if (bad_segments_count == nsegments) { - printf("no valid segments\n"); - exit(1); - } - - /* Delete remaining blocks at the end of device */ - rest = mediasize % segsize; - nblocks = rest / erasesize; - for (i = 0; i < nblocks; i++) { - offset = (segsize * nsegments) + (i * erasesize); - if (g_delete(fd, offset, erasesize)) { - printf("cannot delete space after last segment " - "- probably a bad block\n"); - } - } -} - -static void -erase_initial(int fd) -{ - char buf[512]; - u_int i; - - memset(buf, 0xff, sizeof(buf)); - - lseek(fd, 0, SEEK_SET); - for (i = 0; i < NANDFS_NFSAREAS * erasesize; i += sizeof(buf)) - write(fd, buf, sizeof(buf)); -} - -static void -create_nandfs(int fd) -{ - - create_fs(); - - write_fs(fd); -} - -static void -print_summary(void) -{ - - printf("filesystem was created successfully\n"); - printf("total segments: %#jx valid segments: %#jx\n", nsegments, - nsegments - bad_segments_count); - printf("total space: %ju MB free: %ju MB\n", - (nsegments * - blocks_per_segment * blocksize) / (1024 * 1024), - ((nsegments - bad_segments_count) * - blocks_per_segment * blocksize) / (1024 * 1024)); -} - -int -main(int argc, char *argv[]) -{ - struct stat sb; - char buf[MAXPATHLEN]; - const char opts[] = "b:B:L:m:"; - const char *fname; - int ch, fd; - - while ((ch = getopt(argc, argv, opts)) != -1) { - switch (ch) { - case 'b': - blocksize = strtol(optarg, (char **)NULL, 10); - if (blocksize == 0) - usage(); - break; - case 'B': - blocks_per_segment = strtol(optarg, (char **)NULL, 10); - if (blocks_per_segment == 0) - usage(); - break; - case 'L': - volumelabel = optarg; - break; - case 'm': - rsv_segment_percent = strtol(optarg, (char **)NULL, 10); - if (rsv_segment_percent == 0) - usage(); - break; - default: - usage(); - } - } - - argc -= optind; - argv += optind; - if (argc < 1 || argc > 2) - usage(); - - /* construct proper device path */ - fname = *argv++; - if (!strchr(fname, '/')) { - snprintf(buf, sizeof(buf), "%s%s", _PATH_DEV, fname); - if (!(fname = strdup(buf))) - err(1, NULL); - } - - fd = g_open(fname, 1); - if (fd == -1) - err(1, "Cannot open %s", fname); - - if (fstat(fd, &sb) == -1) - err(1, "Cannot stat %s", fname); - if (!S_ISCHR(sb.st_mode)) - warnx("%s is not a character device", fname); - - check_mounted(fname, sb.st_mode); - - calculate_geometry(fd); - - check_parameters(); - - print_parameters(); - - if (is_nand) - erase_device(fd); - else - erase_initial(fd); - - create_nandfs(fd); - - print_summary(); - - g_close(fd); - - return (0); -} - - Property changes on: head/sbin/newfs_nandfs/newfs_nandfs.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/newfs_nandfs/newfs_nandfs.8 =================================================================== --- head/sbin/newfs_nandfs/newfs_nandfs.8 (revision 349351) +++ head/sbin/newfs_nandfs/newfs_nandfs.8 (nonexistent) @@ -1,74 +0,0 @@ -.\" -.\" Copyright (c) 2010 Semihalf -.\" 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 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 October 1, 2013 -.Dt NEWFS_NANDFS 8 -.Os -.Sh NAME -.Nm newfs_nandfs -.Nd construct a new NAND FS file system -.Sh SYNOPSIS -.Nm -.Op Fl b Ar blocsize -.Op Fl B Ar blocks-per-segment -.Op Fl L Ar label -.Op Fl m Ar reserved-segment-percent -.Ar device -.Sh DESCRIPTION -The -.Nm -utility creates a NAND FS file system on device. -.Pp -The options are as follow: -.Bl -tag -width indent -.It Fl b Ar blocksize -Size of block (1024 if not specified). -.It Fl B Ar blocks_per_segment -Number of blocks per segment (2048 if not specified). -.It Fl L Ar label -Volume label (up to 16 characters). -.It Fl m Ar reserved_block_percent -Percentage of reserved blocks (5 if not specified). -.El -.Sh EXIT STATUS -Exit status is 0 on success and 1 on error. -.Sh EXAMPLES -Create a file system, using default parameters, on -.Pa /dev/ada0s1 : -.Bd -literal -offset indent -newfs_nandfs /dev/ada0s1 -.Ed -.Sh SEE ALSO -.Xr gpart 8 , -.Xr newfs 8 -.Sh HISTORY -The -.Nm -utility first appeared in -.Fx 10.0 . -.Sh AUTHORS -.An Grzegorz Bernacki Property changes on: head/sbin/newfs_nandfs/newfs_nandfs.8 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sbin/newfs_nandfs/Makefile =================================================================== --- head/sbin/newfs_nandfs/Makefile (revision 349351) +++ head/sbin/newfs_nandfs/Makefile (nonexistent) @@ -1,9 +0,0 @@ -# $FreeBSD$ - -PACKAGE=nandfs -PROG= newfs_nandfs -MAN= newfs_nandfs.8 - -LIBADD= geom - -.include Property changes on: head/sbin/newfs_nandfs/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/share/man/man4/nandsim.4 =================================================================== --- head/share/man/man4/nandsim.4 (revision 349351) +++ head/share/man/man4/nandsim.4 (nonexistent) @@ -1,93 +0,0 @@ -.\" -.\" Copyright (c) 2012 The FreeBSD Foundation -.\" All rights reserved. -.\" -.\" This documentation was written by Semihalf under sponsorship from -.\" the FreeBSD Foundation. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd March 8, 2012 -.Dt NANDSIM 4 -.Os -.Sh NAME -.Nm nandsim -.Nd NAND Flash simulator driver -.Sh SYNOPSIS -.Cd "device nand" -.Cd "device nandsim" -.Cd "options ALQ" -.Sh DESCRIPTION -The -.Nm -is part of the -.Fx -NAND framework -.Xr nand 4 -and can be characterized with the following highlights: -.Bl -bullet -.It -plugs into the -.Xr nand 4 -framework APIs as if it were a hardware controller (hanging on the nexus bus) -with real NAND chips connected to it -.It -physically part of the kernel code (either statically linked into the kernel -image or built as a module) -.It -controlled with a user space program -.Xr nandsim 8 -.El -.Pp -From the user perspective, the -.Nm -allows for imitating ONFI-compliant NAND Flash devices as if they were -attached to the system via a virtual controller. -.Pp -Some -.Nm -features rely on the ability to log contents to a file, which is achieved -through the -.Xr alq 9 -facility. -.Sh SEE ALSO -.Xr nand 4 , -.Xr nandsim.conf 5 , -.Xr nandsim 8 -.Sh STANDARDS -Open NAND Flash Interface Working Group -.Pq Vt ONFI . -.Sh HISTORY -The -.Nm -support first appeared in -.Fx 10.0 . -.Sh AUTHORS -.An -nosplit -The -.Nm -kernel driver was developed by -.An Grzegorz Bernacki . -This manual page was written by -.An Rafal Jaworowski . Property changes on: head/share/man/man4/nandsim.4 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/share/man/man4/nand.4 =================================================================== --- head/share/man/man4/nand.4 (revision 349351) +++ head/share/man/man4/nand.4 (nonexistent) @@ -1,145 +0,0 @@ -.\" -.\" Copyright (c) 2012 The FreeBSD Foundation -.\" All rights reserved. -.\" -.\" This documentation was written by Semihalf under sponsorship from -.\" the FreeBSD Foundation. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd March 8, 2012 -.Dt NAND 4 -.Os -.Sh NAME -.Nm nand -.Nd NAND Flash framework -.Sh SYNOPSIS -.Cd "device nand" -.Sh DESCRIPTION -The -.Fx -.Nm -framework consists of a set of interfaces that aim to provide an extensible, -object oriented environment for NAND controllers and NAND Flash memory chips -from various hardware vendors, and to allow for uniform and flexible -management of the NAND devices. -It comprises of the following major components: -.Bl -bullet -.It -NAND Flash controller (NFC) interface. -.Pp -Defines methods which allow to send commands as well as send/receive data -between the controller and a NAND chip. -Back-end drivers for specific NAND -controllers plug into this interface and implement low-level routines for a -given NAND controller. -.Pp -This layer implements basic functionality of a NAND Flash controller. -It allows to send command and address to chip, drive CS (chip select line), -as well as read/write to the selected NAND chip. -This layer is independent of -NAND chip devices actually connected to the controller. -.It -NAND chip interface. -.Pp -Provides basic operations like read page, program page, erase block. -Currently three generic classes of drivers are available, which provide -support for the following chips: -.Bl -bullet -.It -large page -.It -small page -.It -ONFI-compliant -.El -.Pp -This layer implements basic operations to be performed on a NAND chip, like -read, program, erase, get status etc. -Since these operations use specific -commands (depending on the vendor), each chip has potentially its own -implementation of the commands set. -.Pp -The framework is extensible so it is also possible to create a custom command -set for a non standard chip support. -.It -NANDbus. -.Pp -This layer is responsible for enumerating NAND chips in the system and -establishing the hierarchy between chips and their supervising controllers. -.Pp -Its main purpose is detecting type of NAND chips connected to a given chip -select (CS line). -It also allows manages locking access to the NAND -controller. -NANDbus passes requests from an active chip to the chip controller. -.It -NAND character / GEOM device. -.Pp -For each NAND chip found in a system a character and GEOM devices are created -which allows to read / write directly to a device, as well as perform other -specific operations (like via ioctl). -.Pp -There are two GEOM devices created for each NAND chip: -.Bl -bullet -.It -raw device -.It -normal device -.El -.Pp -Raw device allows to bypass ECC checking when reading/writing to it, while -normal device always uses ECC algorithm to validate the read data. -.Pp -NAND character devices will be created for each NAND chip detected while -probing the NAND controller. -.El -.Sh SEE ALSO -.Xr libnandfs 3 , -.Xr gnand 4 , -.Xr nandsim 4 , -.Xr nandfs 5 , -.Xr makefs 8 , -.Xr mount_nandfs 8 , -.Xr nandfs 8 , -.Xr nandsim 8 , -.Xr nandtool 8 , -.Xr newfs_nandfs 8 , -.Xr umount_nandfs 8 -.Sh STANDARDS -Open NAND Flash Interface Working Group -.Pq Vt ONFI . -.Sh HISTORY -The -.Nm -framework support first appeared in -.Fx 10.0 . -.Sh AUTHORS -.An -nosplit -The -.Nm -framework was designed and developed by -.An Grzegorz Bernacki . -This manual page was written by -.An Rafal Jaworowski . Property changes on: head/share/man/man4/nand.4 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/share/man/man4/Makefile =================================================================== --- head/share/man/man4/Makefile (revision 349351) +++ head/share/man/man4/Makefile (revision 349352) @@ -1,993 +1,991 @@ # @(#)Makefile 8.1 (Berkeley) 6/18/93 # $FreeBSD$ .include PACKAGE=runtime-manuals MAN= aac.4 \ aacraid.4 \ acpi.4 \ ${_acpi_asus.4} \ ${_acpi_asus_wmi.4} \ ${_acpi_dock.4} \ ${_acpi_fujitsu.4} \ ${_acpi_hp.4} \ ${_acpi_ibm.4} \ ${_acpi_panasonic.4} \ ${_acpi_rapidstart.4} \ ${_acpi_sony.4} \ acpi_thermal.4 \ ${_acpi_toshiba.4} \ acpi_video.4 \ ${_acpi_wmi.4} \ ada.4 \ adm6996fc.4 \ ae.4 \ ${_aesni.4} \ age.4 \ agp.4 \ ahc.4 \ ahci.4 \ ahd.4 \ ${_aibs.4} \ aio.4 \ alc.4 \ ale.4 \ alpm.4 \ altera_atse.4 \ altera_avgen.4 \ altera_jtag_uart.4 \ altera_sdcard.4 \ altq.4 \ amdpm.4 \ ${_amdsbwd.4} \ ${_amdsmb.4} \ ${_amdsmn.4} \ ${_amdtemp.4} \ ${_bxe.4} \ amr.4 \ an.4 \ ${_aout.4} \ ${_apic.4} \ arcmsr.4 \ ${_asmc.4} \ at45d.4 \ ata.4 \ ath.4 \ ath_ahb.4 \ ath_hal.4 \ ath_pci.4 \ atkbd.4 \ atkbdc.4 \ atp.4 \ ${_atf_test_case.4} \ ${_atrtc.4} \ ${_attimer.4} \ audit.4 \ auditpipe.4 \ aue.4 \ axe.4 \ axge.4 \ bce.4 \ bcma.4 \ bfe.4 \ bge.4 \ ${_bhyve.4} \ bhnd.4 \ bhnd_chipc.4 \ bhnd_pmu.4 \ bhndb.4 \ bhndb_pci.4 \ bktr.4 \ blackhole.4 \ bnxt.4 \ bpf.4 \ bridge.4 \ bt.4 \ bwi.4 \ bwn.4 \ ${_bytgpio.4} \ ${_chvgpio.4} \ capsicum.4 \ cardbus.4 \ carp.4 \ cas.4 \ cc_cdg.4 \ cc_chd.4 \ cc_cubic.4 \ cc_dctcp.4 \ cc_hd.4 \ cc_htcp.4 \ cc_newreno.4 \ cc_vegas.4 \ ${_ccd.4} \ ccr.4 \ cd.4 \ cdce.4 \ cfi.4 \ cfumass.4 \ ch.4 \ chromebook_platform.4 \ ciss.4 \ cloudabi.4 \ cmx.4 \ ${_coretemp.4} \ ${_cpuctl.4} \ cpufreq.4 \ crypto.4 \ ctl.4 \ cue.4 \ cxgb.4 \ cxgbe.4 \ cxgbev.4 \ cy.4 \ cyapa.4 \ da.4 \ dc.4 \ dcons.4 \ dcons_crom.4 \ ddb.4 \ devctl.4 \ disc.4 \ divert.4 \ ${_dpms.4} \ ds1307.4 \ ds3231.4 \ ${_dtrace_provs} \ dummynet.4 \ edsc.4 \ ehci.4 \ em.4 \ ena.4 \ enc.4 \ epair.4 \ esp.4 \ est.4 \ et.4 \ etherswitch.4 \ eventtimers.4 \ exca.4 \ e6060sw.4 \ fd.4 \ fdc.4 \ fdt.4 \ fdt_pinctrl.4 \ fdtbus.4 \ ffclock.4 \ filemon.4 \ firewire.4 \ full.4 \ fwe.4 \ fwip.4 \ fwohci.4 \ fxp.4 \ gbde.4 \ gdb.4 \ gem.4 \ geom.4 \ geom_fox.4 \ geom_linux_lvm.4 \ geom_map.4 \ geom_uzip.4 \ gif.4 \ gpio.4 \ gpioiic.4 \ gpioled.4 \ gre.4 \ h_ertt.4 \ hifn.4 \ hme.4 \ hpet.4 \ ${_hpt27xx.4} \ ${_hptiop.4} \ ${_hptmv.4} \ ${_hptnr.4} \ ${_hptrr.4} \ ${_hv_kvp.4} \ ${_hv_netvsc.4} \ ${_hv_storvsc.4} \ ${_hv_utils.4} \ ${_hv_vmbus.4} \ ${_hv_vss.4} \ hwpmc.4 \ iavf.4 \ ichsmb.4 \ ${_ichwd.4} \ icmp.4 \ icmp6.4 \ ida.4 \ if_ipsec.4 \ iflib.4 \ ifmib.4 \ ig4.4 \ igmp.4 \ iic.4 \ iicbb.4 \ iicbus.4 \ iicsmb.4 \ iir.4 \ ${_imcsmb.4} \ inet.4 \ inet6.4 \ intpm.4 \ intro.4 \ ${_io.4} \ ${_ioat.4} \ ip.4 \ ip6.4 \ ipfirewall.4 \ ipheth.4 \ ${_ipmi.4} \ ips.4 \ ipsec.4 \ ipw.4 \ ipwfw.4 \ isci.4 \ isl.4 \ ismt.4 \ isp.4 \ ispfw.4 \ iwi.4 \ iwifw.4 \ iwm.4 \ iwmfw.4 \ iwn.4 \ iwnfw.4 \ ixgbe.4 \ ixl.4 \ jedec_dimm.4 \ jme.4 \ kbdmux.4 \ keyboard.4 \ kld.4 \ ksyms.4 \ ksz8995ma.4 \ ktr.4 \ kue.4 \ lagg.4 \ le.4 \ led.4 \ lge.4 \ ${_linux.4} \ liquidio.4 \ lm75.4 \ lo.4 \ lp.4 \ lpbb.4 \ lpt.4 \ mac.4 \ mac_biba.4 \ mac_bsdextended.4 \ mac_ifoff.4 \ mac_lomac.4 \ mac_mls.4 \ mac_none.4 \ mac_ntpd.4 \ mac_partition.4 \ mac_portacl.4 \ mac_seeotheruids.4 \ mac_stub.4 \ mac_test.4 \ malo.4 \ md.4 \ mdio.4 \ me.4 \ mem.4 \ meteor.4 \ mfi.4 \ miibus.4 \ mk48txx.4 \ mld.4 \ mlx.4 \ mlx4en.4 \ mlx5en.4 \ mly.4 \ mmc.4 \ mmcsd.4 \ mn.4 \ mod_cc.4 \ mos.4 \ mouse.4 \ mpr.4 \ mps.4 \ mpt.4 \ mrsas.4 \ msk.4 \ mtio.4 \ multicast.4 \ muge.4 \ mvs.4 \ mwl.4 \ mwlfw.4 \ mx25l.4 \ mxge.4 \ my.4 \ - nand.4 \ - nandsim.4 \ ${_ndis.4} \ net80211.4 \ netdump.4 \ netfpga10g_nf10bmac.4 \ netgraph.4 \ netintro.4 \ netmap.4 \ ${_nfe.4} \ ${_nfsmb.4} \ ng_async.4 \ ngatmbase.4 \ ng_atmllc.4 \ ng_bpf.4 \ ng_bridge.4 \ ng_bt3c.4 \ ng_btsocket.4 \ ng_car.4 \ ng_ccatm.4 \ ng_checksum.4 \ ng_cisco.4 \ ng_deflate.4 \ ng_device.4 \ nge.4 \ ng_echo.4 \ ng_eiface.4 \ ng_etf.4 \ ng_ether.4 \ ng_ether_echo.4 \ ng_frame_relay.4 \ ng_gif.4 \ ng_gif_demux.4 \ ng_h4.4 \ ng_hci.4 \ ng_hole.4 \ ng_hub.4 \ ng_iface.4 \ ng_ipfw.4 \ ng_ip_input.4 \ ng_ksocket.4 \ ng_l2cap.4 \ ng_l2tp.4 \ ng_lmi.4 \ ng_mppc.4 \ ng_nat.4 \ ng_netflow.4 \ ng_one2many.4 \ ng_patch.4 \ ng_ppp.4 \ ng_pppoe.4 \ ng_pptpgre.4 \ ng_pred1.4 \ ng_rfc1490.4 \ ng_socket.4 \ ng_source.4 \ ng_split.4 \ ng_sppp.4 \ ng_sscfu.4 \ ng_sscop.4 \ ng_tag.4 \ ng_tcpmss.4 \ ng_tee.4 \ ng_tty.4 \ ng_ubt.4 \ ng_UI.4 \ ng_uni.4 \ ng_vjc.4 \ ng_vlan.4 \ nmdm.4 \ ${_ntb.4} \ ${_ntb_hw_intel.4} \ ${_ntb_hw_plx.4} \ ${_ntb_transport.4} \ ${_nda.4} \ ${_if_ntb.4} \ null.4 \ numa.4 \ ${_nvd.4} \ ${_nvme.4} \ ${_nvram.4} \ ${_nvram2env.4} \ oce.4 \ ocs_fc.4\ ohci.4 \ orm.4 \ ow.4 \ ow_temp.4 \ owc.4 \ ${_padlock.4} \ pass.4 \ pccard.4 \ pccbb.4 \ pcf.4 \ pci.4 \ pcib.4 \ pcic.4 \ pcm.4 \ ${_pf.4} \ ${_pflog.4} \ ${_pfsync.4} \ pim.4 \ pms.4 \ polling.4 \ ppbus.4 \ ppc.4 \ ppi.4 \ procdesc.4 \ proto.4 \ psm.4 \ pst.4 \ pt.4 \ pts.4 \ pty.4 \ puc.4 \ pwmc.4 \ ${_qlxge.4} \ ${_qlxgb.4} \ ${_qlxgbe.4} \ ${_qlnxe.4} \ ral.4 \ random.4 \ rc.4 \ rctl.4 \ re.4 \ rgephy.4 \ rights.4 \ rl.4 \ rndtest.4 \ route.4 \ rp.4 \ rtwn.4 \ rtwnfw.4 \ rtwn_pci.4 \ rue.4 \ sa.4 \ safe.4 \ sbp.4 \ sbp_targ.4 \ scc.4 \ sched_4bsd.4 \ sched_ule.4 \ screen.4 \ scsi.4 \ sctp.4 \ sdhci.4 \ sem.4 \ send.4 \ ses.4 \ ${_sfxge.4} \ sge.4 \ siba.4 \ siftr.4 \ siis.4 \ simplebus.4 \ sio.4 \ sis.4 \ sk.4 \ ${_smartpqi.4} \ smb.4 \ smbus.4 \ smp.4 \ smsc.4 \ snd_ad1816.4 \ snd_als4000.4 \ snd_atiixp.4 \ snd_cmi.4 \ snd_cs4281.4 \ snd_csa.4 \ snd_ds1.4 \ snd_emu10k1.4 \ snd_emu10kx.4 \ snd_envy24.4 \ snd_envy24ht.4 \ snd_es137x.4 \ snd_ess.4 \ snd_fm801.4 \ snd_gusc.4 \ snd_hda.4 \ snd_hdspe.4 \ snd_ich.4 \ snd_maestro3.4 \ snd_maestro.4 \ snd_mss.4 \ snd_neomagic.4 \ snd_sbc.4 \ snd_solo.4 \ snd_spicds.4 \ snd_t4dwave.4 \ snd_uaudio.4 \ snd_via8233.4 \ snd_via82c686.4 \ snd_vibes.4 \ snp.4 \ spigen.4 \ ${_spkr.4} \ splash.4 \ sppp.4 \ ste.4 \ stf.4 \ stge.4 \ sym.4 \ syncache.4 \ syncer.4 \ syscons.4 \ sysmouse.4 \ tap.4 \ targ.4 \ tcp.4 \ tdfx.4 \ terasic_mtl.4 \ termios.4 \ textdump.4 \ ti.4 \ timecounters.4 \ ${_tpm.4} \ trm.4 \ tty.4 \ tun.4 \ twa.4 \ twe.4 \ tws.4 \ udp.4 \ udplite.4 \ ure.4 \ vale.4 \ vga.4 \ vge.4 \ viapm.4 \ ${_viawd.4} \ ${_virtio.4} \ ${_virtio_balloon.4} \ ${_virtio_blk.4} \ ${_virtio_console.4} \ ${_virtio_random.4} \ ${_virtio_scsi.4} \ ${_vmci.4} \ vkbd.4 \ vlan.4 \ vxlan.4 \ ${_vmm.4} \ ${_vmx.4} \ vpo.4 \ vr.4 \ vt.4 \ vte.4 \ ${_vtnet.4} \ watchdog.4 \ ${_wbwd.4} \ wi.4 \ witness.4 \ wlan.4 \ wlan_acl.4 \ wlan_amrr.4 \ wlan_ccmp.4 \ wlan_tkip.4 \ wlan_wep.4 \ wlan_xauth.4 \ wmt.4 \ ${_wpi.4} \ wsp.4 \ ${_xen.4} \ xhci.4 \ xl.4 \ ${_xnb.4} \ xpt.4 \ zero.4 MLINKS= ae.4 if_ae.4 MLINKS+=age.4 if_age.4 MLINKS+=agp.4 agpgart.4 MLINKS+=alc.4 if_alc.4 MLINKS+=ale.4 if_ale.4 MLINKS+=altera_atse.4 atse.4 MLINKS+=altera_sdcard.4 altera_sdcardc.4 MLINKS+=altq.4 ALTQ.4 MLINKS+=ath.4 if_ath.4 MLINKS+=ath_pci.4 if_ath_pci.4 MLINKS+=an.4 if_an.4 MLINKS+=aue.4 if_aue.4 MLINKS+=axe.4 if_axe.4 MLINKS+=bce.4 if_bce.4 MLINKS+=bfe.4 if_bfe.4 MLINKS+=bge.4 if_bge.4 MLINKS+=bktr.4 brooktree.4 MLINKS+=bnxt.4 if_bnxt.4 MLINKS+=bridge.4 if_bridge.4 MLINKS+=bwi.4 if_bwi.4 MLINKS+=bwn.4 if_bwn.4 MLINKS+=${_bxe.4} ${_if_bxe.4} MLINKS+=cas.4 if_cas.4 MLINKS+=cdce.4 if_cdce.4 MLINKS+=cfi.4 cfid.4 MLINKS+=cloudabi.4 cloudabi32.4 \ cloudabi.4 cloudabi64.4 MLINKS+=crypto.4 cryptodev.4 MLINKS+=cue.4 if_cue.4 MLINKS+=cxgb.4 if_cxgb.4 MLINKS+=cxgbe.4 if_cxgbe.4 \ cxgbe.4 vcxgbe.4 \ cxgbe.4 if_vcxgbe.4 \ cxgbe.4 cxl.4 \ cxgbe.4 if_cxl.4 \ cxgbe.4 vcxl.4 \ cxgbe.4 if_vcxl.4 \ cxgbe.4 cc.4 \ cxgbe.4 if_cc.4 \ cxgbe.4 vcc.4 \ cxgbe.4 if_vcc.4 MLINKS+=cxgbev.4 if_cxgbev.4 \ cxgbev.4 cxlv.4 \ cxgbev.4 if_cxlv.4 \ cxgbev.4 ccv.4 \ cxgbev.4 if_ccv.4 MLINKS+=dc.4 if_dc.4 MLINKS+=disc.4 if_disc.4 MLINKS+=edsc.4 if_edsc.4 MLINKS+=em.4 if_em.4 MLINKS+=enc.4 if_enc.4 MLINKS+=epair.4 if_epair.4 MLINKS+=et.4 if_et.4 MLINKS+=fd.4 stderr.4 \ fd.4 stdin.4 \ fd.4 stdout.4 MLINKS+=fdt.4 FDT.4 MLINKS+=firewire.4 ieee1394.4 MLINKS+=fwe.4 if_fwe.4 MLINKS+=fwip.4 if_fwip.4 MLINKS+=fxp.4 if_fxp.4 MLINKS+=gem.4 if_gem.4 MLINKS+=geom.4 GEOM.4 MLINKS+=gif.4 if_gif.4 MLINKS+=gpio.4 gpiobus.4 MLINKS+=gre.4 if_gre.4 MLINKS+=hme.4 if_hme.4 MLINKS+=hpet.4 acpi_hpet.4 MLINKS+=${_hptrr.4} ${_rr232x.4} MLINKS+=${_attimer.4} ${_i8254.4} MLINKS+=ip.4 rawip.4 MLINKS+=ipfirewall.4 ipaccounting.4 \ ipfirewall.4 ipacct.4 \ ipfirewall.4 ipfw.4 MLINKS+=ipheth.4 if_ipheth.4 MLINKS+=ipw.4 if_ipw.4 MLINKS+=iwi.4 if_iwi.4 MLINKS+=iwm.4 if_iwm.4 MLINKS+=iwn.4 if_iwn.4 MLINKS+=ixgbe.4 ix.4 MLINKS+=ixgbe.4 if_ix.4 MLINKS+=ixgbe.4 if_ixgbe.4 MLINKS+=ixl.4 if_ixl.4 MLINKS+=iavf.4 if_iavf.4 MLINKS+=jme.4 if_jme.4 MLINKS+=kue.4 if_kue.4 MLINKS+=lagg.4 trunk.4 MLINKS+=lagg.4 if_lagg.4 MLINKS+=le.4 if_le.4 MLINKS+=lge.4 if_lge.4 MLINKS+=lo.4 loop.4 MLINKS+=lp.4 plip.4 MLINKS+=malo.4 if_malo.4 MLINKS+=md.4 vn.4 MLINKS+=mem.4 kmem.4 MLINKS+=mfi.4 mfi_linux.4 \ mfi.4 mfip.4 MLINKS+=mlx5en.4 mce.4 MLINKS+=mn.4 if_mn.4 MLINKS+=mos.4 if_mos.4 MLINKS+=msk.4 if_msk.4 MLINKS+=mwl.4 if_mwl.4 MLINKS+=mxge.4 if_mxge.4 MLINKS+=my.4 if_my.4 MLINKS+=${_ndis.4} ${_if_ndis.4} MLINKS+=netfpga10g_nf10bmac.4 if_nf10bmac.4 MLINKS+=netintro.4 net.4 \ netintro.4 networking.4 MLINKS+=${_nfe.4} ${_if_nfe.4} MLINKS+=nge.4 if_nge.4 MLINKS+=ow.4 onewire.4 MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 snd.4 \ pcm.4 sound.4 MLINKS+=pms.4 pmspcv.4 MLINKS+=ral.4 if_ral.4 MLINKS+=re.4 if_re.4 MLINKS+=rl.4 if_rl.4 MLINKS+=rtwn_pci.4 if_rtwn_pci.4 MLINKS+=rue.4 if_rue.4 MLINKS+=scsi.4 CAM.4 \ scsi.4 cam.4 \ scsi.4 scbus.4 \ scsi.4 SCSI.4 MLINKS+=sge.4 if_sge.4 MLINKS+=sis.4 if_sis.4 MLINKS+=sk.4 if_sk.4 MLINKS+=smp.4 SMP.4 MLINKS+=smsc.4 if_smsc.4 MLINKS+=snd_envy24.4 snd_ak452x.4 MLINKS+=snd_sbc.4 snd_sb16.4 \ snd_sbc.4 snd_sb8.4 MLINKS+=${_spkr.4} ${_speaker.4} MLINKS+=splash.4 screensaver.4 MLINKS+=ste.4 if_ste.4 MLINKS+=stf.4 if_stf.4 MLINKS+=stge.4 if_stge.4 MLINKS+=syncache.4 syncookies.4 MLINKS+=syscons.4 sc.4 MLINKS+=tap.4 if_tap.4 MLINKS+=tdfx.4 tdfx_linux.4 MLINKS+=ti.4 if_ti.4 MLINKS+=tun.4 if_tun.4 MLINKS+=ure.4 if_ure.4 MLINKS+=vge.4 if_vge.4 MLINKS+=vlan.4 if_vlan.4 MLINKS+=vxlan.4 if_vxlan.4 MLINKS+=${_vmx.4} ${_if_vmx.4} MLINKS+=vpo.4 imm.4 MLINKS+=vr.4 if_vr.4 MLINKS+=vte.4 if_vte.4 MLINKS+=${_vtnet.4} ${_if_vtnet.4} MLINKS+=watchdog.4 SW_WATCHDOG.4 MLINKS+=wi.4 if_wi.4 MLINKS+=${_wpi.4} ${_if_wpi.4} MLINKS+=xl.4 if_xl.4 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" _acpi_asus.4= acpi_asus.4 _acpi_asus_wmi.4= acpi_asus_wmi.4 _acpi_dock.4= acpi_dock.4 _acpi_fujitsu.4=acpi_fujitsu.4 _acpi_hp.4= acpi_hp.4 _acpi_ibm.4= acpi_ibm.4 _acpi_panasonic.4=acpi_panasonic.4 _acpi_rapidstart.4=acpi_rapidstart.4 _acpi_sony.4= acpi_sony.4 _acpi_toshiba.4=acpi_toshiba.4 _acpi_wmi.4= acpi_wmi.4 _aesni.4= aesni.4 _aout.4= aout.4 _apic.4= apic.4 _atrtc.4= atrtc.4 _attimer.4= attimer.4 _aibs.4= aibs.4 _amdsbwd.4= amdsbwd.4 _amdsmb.4= amdsmb.4 _amdsmn.4= amdsmn.4 _amdtemp.4= amdtemp.4 _asmc.4= asmc.4 _bxe.4= bxe.4 _bytgpio.4= bytgpio.4 _chvgpio.4= chvgpio.4 _coretemp.4= coretemp.4 _cpuctl.4= cpuctl.4 _dpms.4= dpms.4 _hpt27xx.4= hpt27xx.4 _hptiop.4= hptiop.4 _hptmv.4= hptmv.4 _hptnr.4= hptnr.4 _hptrr.4= hptrr.4 _hv_kvp.4= hv_kvp.4 _hv_netvsc.4= hv_netvsc.4 _hv_storvsc.4= hv_storvsc.4 _hv_utils.4= hv_utils.4 _hv_vmbus.4= hv_vmbus.4 _hv_vss.4= hv_vss.4 _i8254.4= i8254.4 _ichwd.4= ichwd.4 _if_bxe.4= if_bxe.4 _if_ndis.4= if_ndis.4 _if_nfe.4= if_nfe.4 _if_urtw.4= if_urtw.4 _if_vmx.4= if_vmx.4 _if_vtnet.4= if_vtnet.4 _if_wpi.4= if_wpi.4 _imcsmb.4= imcsmb.4 _ipmi.4= ipmi.4 _io.4= io.4 _linux.4= linux.4 _nda.4= nda.4 _ndis.4= ndis.4 _nfe.4= nfe.4 _nfsmb.4= nfsmb.4 _nvd.4= nvd.4 _nvme.4= nvme.4 _nvram.4= nvram.4 _virtio.4= virtio.4 _virtio_balloon.4=virtio_balloon.4 _virtio_blk.4= virtio_blk.4 _virtio_console.4=virtio_console.4 _virtio_random.4= virtio_random.4 _virtio_scsi.4= virtio_scsi.4 _vmx.4= vmx.4 _vtnet.4= vtnet.4 _padlock.4= padlock.4 _rr232x.4= rr232x.4 _speaker.4= speaker.4 _spkr.4= spkr.4 _tpm.4= tpm.4 _urtw.4= urtw.4 _viawd.4= viawd.4 _vmci.4= vmci.4 _wbwd.4= wbwd.4 _wpi.4= wpi.4 _xen.4= xen.4 _xnb.4= xnb.4 .endif .if ${MACHINE_CPUARCH} == "amd64" _if_ntb.4= if_ntb.4 _ioat.4= ioat.4 _ntb.4= ntb.4 _ntb_hw_intel.4= ntb_hw_intel.4 _ntb_hw_plx.4= ntb_hw_plx.4 _ntb_transport.4=ntb_transport.4 _qlxge.4= qlxge.4 _qlxgb.4= qlxgb.4 _qlxgbe.4= qlxgbe.4 _qlnxe.4= qlnxe.4 _sfxge.4= sfxge.4 _smartpqi.4= smartpqi.4 MLINKS+=qlxge.4 if_qlxge.4 MLINKS+=qlxgb.4 if_qlxgb.4 MLINKS+=qlxgbe.4 if_qlxgbe.4 MLINKS+=qlnxe.4 if_qlnxe.4 MLINKS+=sfxge.4 if_sfxge.4 .if ${MK_BHYVE} != "no" _bhyve.4= bhyve.4 _vmm.4= vmm.4 .endif .endif .if ${MACHINE_CPUARCH} == "mips" _nvram2env.4= nvram2env.4 .endif .if ${MACHINE_CPUARCH} == "powerpc" _nvd.4= nvd.4 _nvme.4= nvme.4 .endif .if empty(MAN_ARCH) __arches= ${MACHINE} ${MACHINE_ARCH} ${MACHINE_CPUARCH} .elif ${MAN_ARCH} == "all" __arches= ${:!/bin/sh -c "/bin/ls -d ${.CURDIR}/man4.*"!:E} .else __arches= ${MAN_ARCH} .endif .for __arch in ${__arches:O:u} .if exists(${.CURDIR}/man4.${__arch}) SUBDIR+= man4.${__arch} .endif .endfor .if ${MK_BLUETOOTH} != "no" MAN+= ng_bluetooth.4 .endif .if ${MK_CCD} != "no" _ccd.4= ccd.4 .endif .if ${MK_CDDL} != "no" _dtrace_provs= dtrace_audit.4 \ dtrace_io.4 \ dtrace_ip.4 \ dtrace_lockstat.4 \ dtrace_proc.4 \ dtrace_sched.4 \ dtrace_sctp.4 \ dtrace_tcp.4 \ dtrace_udp.4 \ dtrace_udplite.4 MLINKS+= dtrace_audit.4 dtaudit.4 .endif .if ${MK_EFI} != "no" MAN+= efidev.4 MLINKS+= efidev.4 efirtc.4 .endif .if ${MK_ISCSI} != "no" MAN+= cfiscsi.4 MAN+= iscsi.4 MAN+= iscsi_initiator.4 MAN+= iser.4 .endif .if ${MK_OFED} != "no" MAN+= mlx4ib.4 MAN+= mlx5ib.4 .endif .if ${MK_MLX5TOOL} != "no" MAN+= mlx5io.4 .endif .if ${MK_TESTS} != "no" ATF= ${SRCTOP}/contrib/atf .PATH: ${ATF}/doc _atf_test_case.4= atf-test-case.4 .endif .if ${MK_PF} != "no" _pf.4= pf.4 _pflog.4= pflog.4 _pfsync.4= pfsync.4 .endif .if ${MK_USB} != "no" MAN+= \ otus.4 \ otusfw.4 \ rsu.4 \ rsufw.4 \ rtwn_usb.4 \ rum.4 \ run.4 \ runfw.4 \ u3g.4 \ uark.4 \ uart.4 \ uath.4 \ ubsa.4 \ ubsec.4 \ ubser.4 \ ubtbcmfw.4 \ uchcom.4 \ ucom.4 \ ucycom.4 \ udav.4 \ udbp.4 \ udl.4 \ uep.4 \ ufm.4 \ ufoma.4 \ uftdi.4 \ ugen.4 \ ugold.4 \ uhci.4 \ uhid.4 \ uhso.4 \ uipaq.4 \ ukbd.4 \ uled.4 \ ulpt.4 \ umass.4 \ umcs.4 \ umct.4 \ umodem.4 \ umoscom.4 \ ums.4 \ unix.4 \ upgt.4 \ uplcom.4 \ ural.4 \ urio.4 \ urndis.4 \ ${_urtw.4} \ usb.4 \ usb_quirk.4 \ usb_template.4 \ usfs.4 \ uslcom.4 \ uvisor.4 \ uvscom.4 \ zyd.4 MLINKS+=otus.4 if_otus.4 MLINKS+=rsu.4 if_rsu.4 MLINKS+=rtwn_usb.4 if_rtwn_usb.4 MLINKS+=rum.4 if_rum.4 MLINKS+=run.4 if_run.4 MLINKS+=u3g.4 u3gstub.4 MLINKS+=uath.4 if_uath.4 MLINKS+=udav.4 if_udav.4 MLINKS+=upgt.4 if_upgt.4 MLINKS+=ural.4 if_ural.4 MLINKS+=urndis.4 if_urndis.4 MLINKS+=${_urtw.4} ${_if_urtw.4} MLINKS+=zyd.4 if_zyd.4 .endif .include Index: head/share/man/man5/nandfs.5 =================================================================== --- head/share/man/man5/nandfs.5 (revision 349351) +++ head/share/man/man5/nandfs.5 (nonexistent) @@ -1,132 +0,0 @@ -.\" -.\" Copyright (c) 2010 Semihalf -.\" 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 Nov 11, 2010 -.Dt NANDFS 5 -.Os -.Sh NAME -.Nm nandfs -.Nd NAND Flash file system -.Sh SYNOPSIS -To compile support for the -.Nm , -place the following in your kernel configuration file: -.Bd -ragged -offset indent -.Cd "options NANDFS" -.Ed -.Pp -Even though the NAND FS can be used with any storage media, it has been -optimized and designed towards NAND Flash devices, so typically the following -driver is used: -.Bd -ragged -offset indent -.Cd "device nand" -.Ed -.Sh DESCRIPTION -The -.Nm -driver enables -.Fx -with support for NAND-oriented file system. -.Pp -It is a log-structured style file system with the following major features and -characteristics: -.Bl -bullet -.It -Hard links, symbolic links support -.It -Block journaling -.It -Copy-On-Write -.It -Snapshots (continuous, taken automatically, simultaneously mountable) -.It -Quick crash recovery at mount time -.It -64-bit data structures; supports many files, large files and volumes -.It -POSIX file permissions -.It -Checksum / ECC -.El -.Sh EXAMPLES -The most common usage is mounting the file system: -.Pp -.Dl "mount -t nandfs /dev/ /mnt" -.Pp -or: -.Dl "mount_nandfs /dev/ /mnt" -.Pp -where -.Ar gnandN -is the GEOM device representing a Flash partition (slice) containing the -.Nm -structure, and -.Pa /mnt -is a mount point. -.Pp -It is possible to define an entry in -.Pa /etc/fstab -for the -.Nm : -.Bd -literal -/dev/gnand0 /flash nandfs rw 0 0 -.Ed -.Pp -This will mount a -.Nm -partition at the specified mount point during system boot. -.Sh SEE ALSO -.Xr gnand 4 , -.Xr nand 4 , -.Xr mount_nandfs 8 , -.Xr nandfs 8 , -.Xr nandsim 8 , -.Xr nandtool 8 , -.Xr umount_nandfs 8 -.Sh HISTORY -The NAND FS concepts are based on NILFS principles and initial implementation -was derived from early read-only NILFS NetBSD code. -Since then the NAND FS -code diverged significantly and is by no means compatible with NILFS. -.Pp -The NAND Flash file system first appeared in -.Fx 10.0 . -.Sh AUTHORS -.An -nosplit -The NAND FS was written by -.An Grzegorz Bernacki -with the help of -.An Mateusz Guzik , -based on the NetBSD code created by -.An Reinoud Zandijk . -Additional help and support by -.An Lukasz Plachno , -.An Jan Sieka -and -.An Lukasz Wojcik . -This manual page was written by -.An Rafal Jaworowski . Property changes on: head/share/man/man5/nandfs.5 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/share/man/man5/Makefile =================================================================== --- head/share/man/man5/Makefile (revision 349351) +++ head/share/man/man5/Makefile (revision 349352) @@ -1,117 +1,113 @@ # @(#)Makefile 8.1 (Berkeley) 6/5/93 # $FreeBSD$ .include PACKAGE=runtime-manuals #MISSING: dump.5 plot.5 MAN= acct.5 \ ar.5 \ a.out.5 \ ${_boot.config.5} \ cd9660.5 \ core.5 \ devfs.5 \ devfs.conf.5 \ devfs.rules.5 \ device.hints.5 \ dir.5 \ disktab.5 \ elf.5 \ ethers.5 \ eui64.5 \ ext2fs.5 \ fbtab.5 \ fdescfs.5 \ forward.5 \ fs.5 \ fstab.5 \ fusefs.5 \ group.5 \ hosts.5 \ hosts.equiv.5 \ hosts.lpd.5 \ intro.5 \ libmap.conf.5 \ link.5 \ linprocfs.5 \ linsysfs.5 \ mailer.conf.5 \ make.conf.5 \ moduli.5 \ motd.5 \ mount.conf.5 \ mqueuefs.5 \ msdosfs.5 \ networks.5 \ nsmb.conf.5 \ nsswitch.conf.5 \ nullfs.5 \ passwd.5 \ pbm.5 \ periodic.conf.5 \ phones.5 \ portindex.5 \ portsnap.conf.5 \ procfs.5 \ protocols.5 \ quota.user.5 \ rc.conf.5 \ rctl.conf.5 \ regdomain.5 \ remote.5 \ resolver.5 \ services.5 \ shells.5 \ src.conf.5 \ stab.5 \ style.Makefile.5 \ style.mdoc.5 \ sysctl.conf.5 \ tmpfs.5 MLINKS= dir.5 dirent.5 MLINKS+=ext2fs.5 ext4fs.5 MLINKS+=fs.5 inode.5 MLINKS+=hosts.equiv.5 rhosts.5 MLINKS+=msdosfs.5 msdos.5 MLINKS+=passwd.5 master.passwd.5 MLINKS+=portindex.5 INDEX.5 MLINKS+=quota.user.5 quota.group.5 MLINKS+=rc.conf.5 rc.conf.local.5 MLINKS+=resolver.5 resolv.conf.5 MLINKS+=src.conf.5 src-env.conf.5 .if ${MK_AUTOFS} != "no" MAN+= autofs.5 .endif .if ${MK_BLUETOOTH} != "no" MAN+= bluetooth.device.conf.5 \ bluetooth.hosts.5 \ bluetooth.protocols.5 .endif .if ${MK_FREEBSD_UPDATE} != "no" MAN+= freebsd-update.conf.5 .endif .if ${MK_HESIOD} != "no" MAN+= hesiod.conf.5 .endif -.if ${MK_NAND} != "no" -MAN+= nandfs.5 -.endif - .if ${MK_PF} != "no" MAN+= pf.conf.5 \ pf.os.5 .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" _boot.config.5= boot.config.5 .endif .include Index: head/share/mk/bsd.libnames.mk =================================================================== --- head/share/mk/bsd.libnames.mk (revision 349351) +++ head/share/mk/bsd.libnames.mk (revision 349352) @@ -1,215 +1,214 @@ # $FreeBSD$ # The include file define library names. # Other include files (e.g. bsd.prog.mk, bsd.lib.mk) include this # file where necessary. .if !target(____) .error bsd.libnames.mk cannot be included directly. .endif LIBDESTDIR= ${SYSROOT:U${DESTDIR}} .sinclude # Src directory locations are also defined in src.libnames.mk. LIBCRT0?= ${LIBDESTDIR}${LIBDIR_BASE}/crt0.o LIB80211?= ${LIBDESTDIR}${LIBDIR_BASE}/lib80211.a LIBALIAS?= ${LIBDESTDIR}${LIBDIR_BASE}/libalias.a LIBARCHIVE?= ${LIBDESTDIR}${LIBDIR_BASE}/libarchive.a LIBASN1?= ${LIBDESTDIR}${LIBDIR_BASE}/libasn1.a LIBATM?= ${LIBDESTDIR}${LIBDIR_BASE}/libatm.a LIBAUDITD?= ${LIBDESTDIR}${LIBDIR_BASE}/libauditd.a LIBAVL?= ${LIBDESTDIR}${LIBDIR_BASE}/libavl.a LIBBE?= ${LIBDESTDIR}${LIBDIR_BASE}/libbe.a LIBBEGEMOT?= ${LIBDESTDIR}${LIBDIR_BASE}/libbegemot.a LIBBLACKLIST?= ${LIBDESTDIR}${LIBDIR_BASE}/libblacklist.a LIBBLUETOOTH?= ${LIBDESTDIR}${LIBDIR_BASE}/libbluetooth.a LIBBSDXML?= ${LIBDESTDIR}${LIBDIR_BASE}/libbsdxml.a LIBBSM?= ${LIBDESTDIR}${LIBDIR_BASE}/libbsm.a LIBBSNMP?= ${LIBDESTDIR}${LIBDIR_BASE}/libbsnmp.a LIBBZ2?= ${LIBDESTDIR}${LIBDIR_BASE}/libbz2.a LIBC?= ${LIBDESTDIR}${LIBDIR_BASE}/libc.a LIBCALENDAR?= ${LIBDESTDIR}${LIBDIR_BASE}/libcalendar.a LIBCAM?= ${LIBDESTDIR}${LIBDIR_BASE}/libcam.a LIBCOMPAT?= ${LIBDESTDIR}${LIBDIR_BASE}/libcompat.a LIBCOMPILER_RT?=${LIBDESTDIR}${LIBDIR_BASE}/libcompiler_rt.a LIBCOM_ERR?= ${LIBDESTDIR}${LIBDIR_BASE}/libcom_err.a LIBCPLUSPLUS?= ${LIBDESTDIR}${LIBDIR_BASE}/libc++.a LIBCRYPT?= ${LIBDESTDIR}${LIBDIR_BASE}/libcrypt.a LIBCRYPTO?= ${LIBDESTDIR}${LIBDIR_BASE}/libcrypto.a LIBCTF?= ${LIBDESTDIR}${LIBDIR_BASE}/libctf.a LIBCURSES?= ${LIBDESTDIR}${LIBDIR_BASE}/libcurses.a LIBCUSE?= ${LIBDESTDIR}${LIBDIR_BASE}/libcuse.a LIBCXGB4?= ${LIBDESTDIR}${LIBDIR_BASE}/libcxgb4.a LIBCXXRT?= ${LIBDESTDIR}${LIBDIR_BASE}/libcxxrt.a LIBC_PIC?= ${LIBDESTDIR}${LIBDIR_BASE}/libc_pic.a LIBDEVCTL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevctl.a LIBDEVDCTL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevdctl.a LIBDEVINFO?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevinfo.a LIBDEVSTAT?= ${LIBDESTDIR}${LIBDIR_BASE}/libdevstat.a LIBDIALOG?= ${LIBDESTDIR}${LIBDIR_BASE}/libdialog.a LIBDL?= ${LIBDESTDIR}${LIBDIR_BASE}/libdl.a LIBDNS?= ${LIBDESTDIR}${LIBDIR_BASE}/libdns.a LIBDPV?= ${LIBDESTDIR}${LIBDIR_BASE}/libdpv.a LIBDTRACE?= ${LIBDESTDIR}${LIBDIR_BASE}/libdtrace.a LIBDWARF?= ${LIBDESTDIR}${LIBDIR_BASE}/libdwarf.a LIBEDIT?= ${LIBDESTDIR}${LIBDIR_BASE}/libedit.a LIBEFIVAR?= ${LIBDESTDIR}${LIBDIR_BASE}/libefivar.a LIBELF?= ${LIBDESTDIR}${LIBDIR_BASE}/libelf.a LIBEXECINFO?= ${LIBDESTDIR}${LIBDIR_BASE}/libexecinfo.a LIBFETCH?= ${LIBDESTDIR}${LIBDIR_BASE}/libfetch.a LIBFIGPAR?= ${LIBDESTDIR}${LIBDIR_BASE}/libfigpar.a LIBFL?= "don't use LIBFL, use LIBL" LIBFORM?= ${LIBDESTDIR}${LIBDIR_BASE}/libform.a LIBG2C?= ${LIBDESTDIR}${LIBDIR_BASE}/libg2c.a LIBGEOM?= ${LIBDESTDIR}${LIBDIR_BASE}/libgeom.a LIBGNUREGEX?= ${LIBDESTDIR}${LIBDIR_BASE}/libgnuregex.a LIBGPIO?= ${LIBDESTDIR}${LIBDIR_BASE}/libgpio.a LIBGSSAPI?= ${LIBDESTDIR}${LIBDIR_BASE}/libgssapi.a LIBGSSAPI_KRB5?= ${LIBDESTDIR}${LIBDIR_BASE}/libgssapi_krb5.a LIBHDB?= ${LIBDESTDIR}${LIBDIR_BASE}/libhdb.a LIBHEIMBASE?= ${LIBDESTDIR}${LIBDIR_BASE}/libheimbase.a LIBHEIMNTLM?= ${LIBDESTDIR}${LIBDIR_BASE}/libheimntlm.a LIBHEIMSQLITE?= ${LIBDESTDIR}${LIBDIR_BASE}/libheimsqlite.a LIBHX509?= ${LIBDESTDIR}${LIBDIR_BASE}/libhx509.a LIBIBCM?= ${LIBDESTDIR}${LIBDIR_BASE}/libibcm.a LIBIBMAD?= ${LIBDESTDIR}${LIBDIR_BASE}/libibmad.a LIBIBNETDISC?= ${LIBDESTDIR}${LIBDIR_BASE}/libibnetdisc.a LIBIBUMAD?= ${LIBDESTDIR}${LIBDIR_BASE}/libibumad.a LIBIBVERBS?= ${LIBDESTDIR}${LIBDIR_BASE}/libibverbs.a LIBIPSEC?= ${LIBDESTDIR}${LIBDIR_BASE}/libipsec.a LIBIPT?= ${LIBDESTDIR}${LIBDIR_BASE}/libipt.a LIBJAIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libjail.a LIBKADM5CLNT?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5clnt.a LIBKADM5SRV?= ${LIBDESTDIR}${LIBDIR_BASE}/libkadm5srv.a LIBKAFS5?= ${LIBDESTDIR}${LIBDIR_BASE}/libkafs5.a LIBKDC?= ${LIBDESTDIR}${LIBDIR_BASE}/libkdc.a LIBKEYCAP?= ${LIBDESTDIR}${LIBDIR_BASE}/libkeycap.a LIBKICONV?= ${LIBDESTDIR}${LIBDIR_BASE}/libkiconv.a LIBKRB5?= ${LIBDESTDIR}${LIBDIR_BASE}/libkrb5.a LIBKVM?= ${LIBDESTDIR}${LIBDIR_BASE}/libkvm.a LIBL?= ${LIBDESTDIR}${LIBDIR_BASE}/libl.a LIBLN?= "don't use LIBLN, use LIBL" LIBLZMA?= ${LIBDESTDIR}${LIBDIR_BASE}/liblzma.a LIBM?= ${LIBDESTDIR}${LIBDIR_BASE}/libm.a LIBMAGIC?= ${LIBDESTDIR}${LIBDIR_BASE}/libmagic.a LIBMD?= ${LIBDESTDIR}${LIBDIR_BASE}/libmd.a LIBMEMSTAT?= ${LIBDESTDIR}${LIBDIR_BASE}/libmemstat.a LIBMENU?= ${LIBDESTDIR}${LIBDIR_BASE}/libmenu.a LIBMILTER?= ${LIBDESTDIR}${LIBDIR_BASE}/libmilter.a LIBMLX4?= ${LIBDESTDIR}${LIBDIR_BASE}/libmlx4.a LIBMLX5?= ${LIBDESTDIR}${LIBDIR_BASE}/libmlx5.a LIBMP?= ${LIBDESTDIR}${LIBDIR_BASE}/libmp.a LIBMT?= ${LIBDESTDIR}${LIBDIR_BASE}/libmt.a -LIBNANDFS?= ${LIBDESTDIR}${LIBDIR_BASE}/libnandfs.a LIBNCURSES?= ${LIBDESTDIR}${LIBDIR_BASE}/libncurses.a LIBNCURSESW?= ${LIBDESTDIR}${LIBDIR_BASE}/libncursesw.a LIBNETGRAPH?= ${LIBDESTDIR}${LIBDIR_BASE}/libnetgraph.a LIBNGATM?= ${LIBDESTDIR}${LIBDIR_BASE}/libngatm.a LIBNV?= ${LIBDESTDIR}${LIBDIR_BASE}/libnv.a LIBNVPAIR?= ${LIBDESTDIR}${LIBDIR_BASE}/libnvpair.a LIBOPENCSD?= ${LIBDESTDIR}${LIBDIR_BASE}/libopencsd.a LIBOPENSM?= ${LIBDESTDIR}${LIBDIR_BASE}/libopensm.a LIBOPIE?= ${LIBDESTDIR}${LIBDIR_BASE}/libopie.a LIBOSMCOMP?= ${LIBDESTDIR}${LIBDIR_BASE}/libosmcomp.a LIBOSMVENDOR?= ${LIBDESTDIR}${LIBDIR_BASE}/libosmvendor.a LIBPAM?= ${LIBDESTDIR}${LIBDIR_BASE}/libpam.a LIBPANEL?= ${LIBDESTDIR}${LIBDIR_BASE}/libpanel.a LIBPANELW?= ${LIBDESTDIR}${LIBDIR_BASE}/libpanelw.a LIBPCAP?= ${LIBDESTDIR}${LIBDIR_BASE}/libpcap.a LIBPJDLOG?= ${LIBDESTDIR}${LIBDIR_BASE}/libpjdlog.a LIBPMC?= ${LIBDESTDIR}${LIBDIR_BASE}/libpmc.a LIBPROC?= ${LIBDESTDIR}${LIBDIR_BASE}/libproc.a LIBPROCSTAT?= ${LIBDESTDIR}${LIBDIR_BASE}/libprocstat.a LIBPTHREAD?= ${LIBDESTDIR}${LIBDIR_BASE}/libpthread.a LIBRADIUS?= ${LIBDESTDIR}${LIBDIR_BASE}/libradius.a LIBRDMACM?= ${LIBDESTDIR}${LIBDIR_BASE}/librdmacm.a LIBREGEX?= ${LIBDESTDIR}${LIBDIR_BASE}/libregex.a LIBROKEN?= ${LIBDESTDIR}${LIBDIR_BASE}/libroken.a LIBRPCSEC_GSS?= ${LIBDESTDIR}${LIBDIR_BASE}/librpcsec_gss.a LIBRPCSVC?= ${LIBDESTDIR}${LIBDIR_BASE}/librpcsvc.a LIBRT?= ${LIBDESTDIR}${LIBDIR_BASE}/librt.a LIBRTLD_DB?= ${LIBDESTDIR}${LIBDIR_BASE}/librtld_db.a LIBSBUF?= ${LIBDESTDIR}${LIBDIR_BASE}/libsbuf.a LIBSDP?= ${LIBDESTDIR}${LIBDIR_BASE}/libsdp.a LIBSMB?= ${LIBDESTDIR}${LIBDIR_BASE}/libsmb.a LIBSSL?= ${LIBDESTDIR}${LIBDIR_BASE}/libssl.a LIBSSP_NONSHARED?= ${LIBDESTDIR}${LIBDIR_BASE}/libssp_nonshared.a LIBSTDCPLUSPLUS?= ${LIBDESTDIR}${LIBDIR_BASE}/libstdc++.a LIBSTDTHREADS?= ${LIBDESTDIR}${LIBDIR_BASE}/libstdthreads.a LIBSYSDECODE?= ${LIBDESTDIR}${LIBDIR_BASE}/libsysdecode.a LIBTACPLUS?= ${LIBDESTDIR}${LIBDIR_BASE}/libtacplus.a LIBTERMCAP?= ${LIBDESTDIR}${LIBDIR_BASE}/libtermcap.a LIBTERMCAPW?= ${LIBDESTDIR}${LIBDIR_BASE}/libtermcapw.a LIBTERMLIB?= "don't use LIBTERMLIB, use LIBTERMCAP" LIBTINFO?= "don't use LIBTINFO, use LIBNCURSES" LIBUFS?= ${LIBDESTDIR}${LIBDIR_BASE}/libufs.a LIBUGIDFW?= ${LIBDESTDIR}${LIBDIR_BASE}/libugidfw.a LIBULOG?= ${LIBDESTDIR}${LIBDIR_BASE}/libulog.a LIBUMEM?= ${LIBDESTDIR}${LIBDIR_BASE}/libumem.a LIBUSB?= ${LIBDESTDIR}${LIBDIR_BASE}/libusb.a LIBUSBHID?= ${LIBDESTDIR}${LIBDIR_BASE}/libusbhid.a LIBUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libutil.a LIBUUTIL?= ${LIBDESTDIR}${LIBDIR_BASE}/libuutil.a LIBVGL?= ${LIBDESTDIR}${LIBDIR_BASE}/libvgl.a LIBVMMAPI?= ${LIBDESTDIR}${LIBDIR_BASE}/libvmmapi.a LIBWIND?= ${LIBDESTDIR}${LIBDIR_BASE}/libwind.a LIBWRAP?= ${LIBDESTDIR}${LIBDIR_BASE}/libwrap.a LIBXO?= ${LIBDESTDIR}${LIBDIR_BASE}/libxo.a LIBXPG4?= ${LIBDESTDIR}${LIBDIR_BASE}/libxpg4.a LIBY?= ${LIBDESTDIR}${LIBDIR_BASE}/liby.a LIBYPCLNT?= ${LIBDESTDIR}${LIBDIR_BASE}/libypclnt.a LIBZ?= ${LIBDESTDIR}${LIBDIR_BASE}/libz.a LIBZFS?= ${LIBDESTDIR}${LIBDIR_BASE}/libzfs.a LIBZFS_CORE?= ${LIBDESTDIR}${LIBDIR_BASE}/libzfs_core.a LIBZPOOL?= ${LIBDESTDIR}${LIBDIR_BASE}/libzpool.a # enforce the 2 -lpthread and -lc to always be the last in that exact order .if defined(LDADD) .if ${LDADD:M-lpthread} LDADD:= ${LDADD:N-lpthread} -lpthread .endif .if ${LDADD:M-lc} LDADD:= ${LDADD:N-lc} -lc .endif .endif # Only do this for src builds. .if defined(SRCTOP) .if defined(_LIBRARIES) && defined(LIB) && \ ${_LIBRARIES:M${LIB}} != "" .if !defined(LIB${LIB:tu}) .error ${.CURDIR}: Missing value for LIB${LIB:tu} in ${_this:T}. Likely should be: LIB${LIB:tu}?= $${LIBDESTDIR}$${LIBDIR_BASE}/lib${LIB}.a .endif .endif # Derive LIB*SRCDIR from LIB*DIR .for lib in ${_LIBRARIES} LIB${lib:tu}SRCDIR?= ${SRCTOP}/${LIB${lib:tu}DIR:S,^${OBJTOP}/,,} .endfor .else # Out of tree builds # There are LIBADD defined in an out-of-tree build. Are they *all* # in-tree libraries? If so convert them to LDADD to support # partial checkouts. .if !empty(LIBADD) _convert_libadd= 1 .for l in ${LIBADD} .if empty(LIB${l:tu}) _convert_libadd= 0 .endif .endfor .if ${_convert_libadd} == 1 .warning Converting out-of-tree build LIBADDs into LDADD. This is not fully supported. .for l in ${LIBADD} LDADD+= -l${l} .endfor .endif .endif .endif # defined(SRCTOP) Index: head/share/mk/src.libnames.mk =================================================================== --- head/share/mk/src.libnames.mk (revision 349351) +++ head/share/mk/src.libnames.mk (revision 349352) @@ -1,659 +1,658 @@ # $FreeBSD$ # # The include file define library names suitable # for INTERNALLIB and PRIVATELIB definition .if !target(____) .error src.libnames.mk cannot be included directly. .endif .if !target(____) ____: .include _PRIVATELIBS= \ atf_c \ atf_cxx \ bsdstat \ devdctl \ event \ gmock \ gtest \ gmock_main \ gtest_main \ heimipcc \ heimipcs \ ldns \ sqlite3 \ ssh \ ucl \ unbound \ zstd _INTERNALLIBS= \ amu \ bsnmptools \ c_nossp_pic \ cron \ elftc \ fifolog \ ifconfig \ ipf \ lpr \ netbsd \ ntp \ ntpevent \ openbsd \ opts \ parse \ pe \ pmcstat \ sl \ sm \ smdb \ smutil \ telnet \ vers _LIBRARIES= \ ${_PRIVATELIBS} \ ${_INTERNALLIBS} \ ${LOCAL_LIBRARIES} \ 80211 \ alias \ archive \ asn1 \ auditd \ avl \ be \ begemot \ bluetooth \ bsdxml \ bsm \ bsnmp \ bz2 \ c \ c_pic \ calendar \ cam \ casper \ cap_dns \ cap_fileargs \ cap_grp \ cap_pwd \ cap_random \ cap_sysctl \ cap_syslog \ com_err \ compiler_rt \ crypt \ crypto \ ctf \ cuse \ cxxrt \ devctl \ devdctl \ devinfo \ devstat \ dialog \ dl \ dpv \ dtrace \ dwarf \ edit \ efivar \ elf \ execinfo \ fetch \ figpar \ geom \ gnuregex \ gpio \ gssapi \ gssapi_krb5 \ hdb \ heimbase \ heimntlm \ heimsqlite \ hx509 \ ipsec \ ipt \ jail \ kadm5clnt \ kadm5srv \ kafs5 \ kdc \ kiconv \ krb5 \ kvm \ l \ lzma \ m \ magic \ md \ memstat \ mp \ mt \ - nandfs \ ncurses \ ncursesw \ netgraph \ ngatm \ nv \ nvpair \ opencsd \ opie \ pam \ panel \ panelw \ pcap \ pcsclite \ pjdlog \ pmc \ proc \ procstat \ pthread \ radius \ regex \ roken \ rpcsec_gss \ rpcsvc \ rt \ rtld_db \ sbuf \ sdp \ sm \ smb \ ssl \ ssp_nonshared \ stdthreads \ supcplusplus \ sysdecode \ tacplus \ termcap \ termcapw \ ufs \ ugidfw \ ulog \ umem \ usb \ usbhid \ util \ uutil \ vmmapi \ wind \ wrap \ xo \ y \ ypclnt \ z \ zfs_core \ zfs \ zpool \ .if ${MK_BLACKLIST} != "no" _LIBRARIES+= \ blacklist \ .endif .if ${MK_OFED} != "no" _LIBRARIES+= \ cxgb4 \ ibcm \ ibmad \ ibnetdisc \ ibumad \ ibverbs \ mlx4 \ mlx5 \ rdmacm \ osmcomp \ opensm \ osmvendor .endif .if ${MK_BEARSSL} == "yes" _INTERNALLIBS+= \ bearssl \ secureboot \ LIBBEARSSL?= ${LIBBEARSSLDIR}/libbearssl${PIE_SUFFIX}.a LIBSECUREBOOT?= ${LIBSECUREBOOTDIR}/libsecureboot${PIE_SUFFIX}.a .endif .if ${MK_VERIEXEC} == "yes" _INTERNALLIBS+= veriexec LIBVERIEXEC?= ${LIBVERIEXECDIR}/libveriexec${PIE_SUFFIX}.a .endif # Each library's LIBADD needs to be duplicated here for static linkage of # 2nd+ order consumers. Auto-generating this would be better. _DP_80211= sbuf bsdxml _DP_archive= z bz2 lzma bsdxml _DP_zstd= pthread .if ${MK_BLACKLIST} != "no" _DP_blacklist+= pthread .endif _DP_crypto= pthread .if ${MK_OPENSSL} != "no" _DP_archive+= crypto .else _DP_archive+= md .endif _DP_sqlite3= pthread _DP_ssl= crypto _DP_ssh= crypto crypt z .if ${MK_LDNS} != "no" _DP_ssh+= ldns .endif _DP_edit= ncursesw .if ${MK_OPENSSL} != "no" _DP_bsnmp= crypto .endif _DP_geom= bsdxml sbuf _DP_cam= sbuf _DP_kvm= elf _DP_casper= nv _DP_cap_dns= nv _DP_cap_fileargs= nv _DP_cap_grp= nv _DP_cap_pwd= nv _DP_cap_random= nv _DP_cap_sysctl= nv _DP_cap_syslog= nv .if ${MK_OFED} != "no" _DP_pcap= ibverbs mlx5 .endif _DP_pjdlog= util _DP_opie= md _DP_usb= pthread _DP_unbound= ssl crypto pthread _DP_rt= pthread .if ${MK_OPENSSL} == "no" _DP_radius= md .else _DP_radius= crypto .endif _DP_rtld_db= elf procstat _DP_procstat= kvm util elf .if ${MK_CXX} == "yes" .if ${MK_LIBCPLUSPLUS} != "no" _DP_proc= cxxrt .else _DP_proc= supcplusplus .endif .endif .if ${MK_CDDL} != "no" _DP_proc+= ctf .endif _DP_proc+= elf procstat rtld_db util _DP_mp= crypto _DP_memstat= kvm _DP_magic= z _DP_mt= sbuf bsdxml _DP_ldns= ssl crypto .if ${MK_OPENSSL} != "no" _DP_fetch= ssl crypto .else _DP_fetch= md .endif _DP_execinfo= elf _DP_dwarf= elf _DP_dpv= dialog figpar util ncursesw _DP_dialog= ncursesw m _DP_cuse= pthread _DP_atf_cxx= atf_c _DP_gtest= pthread _DP_gmock= gtest _DP_gmock_main= gmock _DP_gtest_main= gtest _DP_devstat= kvm _DP_pam= radius tacplus opie md util .if ${MK_KERBEROS} != "no" _DP_pam+= krb5 .endif .if ${MK_OPENSSH} != "no" _DP_pam+= ssh .endif .if ${MK_NIS} != "no" _DP_pam+= ypclnt .endif _DP_roken= crypt _DP_kadm5clnt= com_err krb5 roken _DP_kadm5srv= com_err hdb krb5 roken _DP_heimntlm= crypto com_err krb5 roken _DP_hx509= asn1 com_err crypto roken wind _DP_hdb= asn1 com_err krb5 roken sqlite3 _DP_asn1= com_err roken _DP_kdc= roken hdb hx509 krb5 heimntlm asn1 crypto _DP_wind= com_err roken _DP_heimbase= pthread _DP_heimipcc= heimbase roken pthread _DP_heimipcs= heimbase roken pthread _DP_kafs5= asn1 krb5 roken _DP_krb5+= asn1 com_err crypt crypto hx509 roken wind heimbase heimipcc _DP_gssapi_krb5+= gssapi krb5 crypto roken asn1 com_err _DP_lzma= pthread _DP_ucl= m _DP_vmmapi= util _DP_opencsd= cxxrt _DP_ctf= z _DP_dtrace= ctf elf proc pthread rtld_db _DP_xo= util # The libc dependencies are not strictly needed but are defined to make the # assert happy. _DP_c= compiler_rt .if ${MK_SSP} != "no" _DP_c+= ssp_nonshared .endif _DP_stdthreads= pthread _DP_tacplus= md _DP_panel= ncurses _DP_panelw= ncursesw _DP_rpcsec_gss= gssapi _DP_smb= kiconv _DP_ulog= md _DP_fifolog= z _DP_ipf= kvm _DP_zfs= md pthread umem util uutil m nvpair avl bsdxml geom nvpair z \ zfs_core _DP_zfs_core= nvpair _DP_zpool= md pthread z nvpair avl umem _DP_be= zfs nvpair # OFED support .if ${MK_OFED} != "no" _DP_cxgb4= ibverbs pthread _DP_ibcm= ibverbs _DP_ibmad= ibumad _DP_ibnetdisc= osmcomp ibmad ibumad _DP_ibumad= _DP_ibverbs= _DP_mlx4= ibverbs pthread _DP_mlx5= ibverbs pthread _DP_rdmacm= ibverbs _DP_osmcomp= pthread _DP_opensm= pthread _DP_osmvendor= ibumad pthread .endif # Define special cases LDADD_supcplusplus= -lsupc++ LIBATF_C= ${LIBDESTDIR}${LIBDIR_BASE}/libprivateatf-c.a LIBATF_CXX= ${LIBDESTDIR}${LIBDIR_BASE}/libprivateatf-c++.a LDADD_atf_c= -lprivateatf-c LDADD_atf_cxx= -lprivateatf-c++ LIBGMOCK= ${LIBDESTDIR}${LIBDIR_BASE}/libprivategmock.a LIBGMOCK_MAIN= ${LIBDESTDIR}${LIBDIR_BASE}/libprivategmock_main.a LIBGTEST= ${LIBDESTDIR}${LIBDIR_BASE}/libprivategtest.a LIBGTEST_MAIN= ${LIBDESTDIR}${LIBDIR_BASE}/libprivategtest_main.a LDADD_gmock= -lprivategmock LDADD_gtest= -lprivategtest LDADD_gmock_main= -lprivategmock_main LDADD_gtest_main= -lprivategtest_main .for _l in ${_PRIVATELIBS} LIB${_l:tu}?= ${LIBDESTDIR}${LIBDIR_BASE}/libprivate${_l}.a .endfor .if ${MK_PIE} != "no" PIE_SUFFIX= _pie .endif .for _l in ${_LIBRARIES} .if ${_INTERNALLIBS:M${_l}} || !defined(SYSROOT) LDADD_${_l}_L+= -L${LIB${_l:tu}DIR} .endif DPADD_${_l}?= ${LIB${_l:tu}} .if ${_PRIVATELIBS:M${_l}} LDADD_${_l}?= -lprivate${_l} .elif ${_INTERNALLIBS:M${_l}} LDADD_${_l}?= ${LDADD_${_l}_L} -l${_l:S/${PIE_SUFFIX}//}${PIE_SUFFIX} .else LDADD_${_l}?= ${LDADD_${_l}_L} -l${_l} .endif # Add in all dependencies for static linkage. .if defined(_DP_${_l}) && (${_INTERNALLIBS:M${_l}} || \ (defined(NO_SHARED) && ${NO_SHARED:tl} != "no")) .for _d in ${_DP_${_l}} DPADD_${_l}+= ${DPADD_${_d}} LDADD_${_l}+= ${LDADD_${_d}} .endfor .endif .endfor # These are special cases where the library is broken and anything that uses # it needs to add more dependencies. Broken usually means that it has a # cyclic dependency and cannot link its own dependencies. This is bad, please # fix the library instead. # Unless the library itself is broken then the proper place to define # dependencies is _DP_* above. # libatf-c++ exposes libatf-c abi hence we need to explicit link to atf_c for # atf_cxx DPADD_atf_cxx+= ${DPADD_atf_c} LDADD_atf_cxx+= ${LDADD_atf_c} DPADD_gmock+= ${DPADD_gtest} LDADD_gmock+= ${LDADD_gtest} DPADD_gmock_main+= ${DPADD_gmock} LDADD_gmock_main+= ${LDADD_gmock} DPADD_gtest_main+= ${DPADD_gtest} LDADD_gtest_main+= ${LDADD_gtest} # Detect LDADD/DPADD that should be LIBADD, before modifying LDADD here. _BADLDADD= .for _l in ${LDADD:M-l*:N-l*/*:C,^-l,,} .if ${_LIBRARIES:M${_l}} && !${_PRIVATELIBS:M${_l}} _BADLDADD+= ${_l} .endif .endfor .if !empty(_BADLDADD) .error ${.CURDIR}: These libraries should be LIBADD+=foo rather than DPADD/LDADD+=-lfoo: ${_BADLDADD} .endif .for _l in ${LIBADD} DPADD+= ${DPADD_${_l}} LDADD+= ${LDADD_${_l}} .endfor # INTERNALLIB definitions. LIBELFTCDIR= ${OBJTOP}/lib/libelftc LIBELFTC?= ${LIBELFTCDIR}/libelftc${PIE_SUFFIX}.a LIBPEDIR= ${OBJTOP}/lib/libpe LIBPE?= ${LIBPEDIR}/libpe${PIE_SUFFIX}.a LIBOPENBSDDIR= ${OBJTOP}/lib/libopenbsd LIBOPENBSD?= ${LIBOPENBSDDIR}/libopenbsd${PIE_SUFFIX}.a LIBSMDIR= ${OBJTOP}/lib/libsm LIBSM?= ${LIBSMDIR}/libsm${PIE_SUFFIX}.a LIBSMDBDIR= ${OBJTOP}/lib/libsmdb LIBSMDB?= ${LIBSMDBDIR}/libsmdb${PIE_SUFFIX}.a LIBSMUTILDIR= ${OBJTOP}/lib/libsmutil LIBSMUTIL?= ${LIBSMUTILDIR}/libsmutil${PIE_SUFFIX}.a LIBNETBSDDIR?= ${OBJTOP}/lib/libnetbsd LIBNETBSD?= ${LIBNETBSDDIR}/libnetbsd${PIE_SUFFIX}.a LIBVERSDIR?= ${OBJTOP}/kerberos5/lib/libvers LIBVERS?= ${LIBVERSDIR}/libvers${PIE_SUFFIX}.a LIBSLDIR= ${OBJTOP}/kerberos5/lib/libsl LIBSL?= ${LIBSLDIR}/libsl${PIE_SUFFIX}.a LIBIFCONFIGDIR= ${OBJTOP}/lib/libifconfig LIBIFCONFIG?= ${LIBIFCONFIGDIR}/libifconfig${PIE_SUFFIX}.a LIBIPFDIR= ${OBJTOP}/sbin/ipf/libipf LIBIPF?= ${LIBIPFDIR}/libipf${PIE_SUFFIX}.a LIBTELNETDIR= ${OBJTOP}/lib/libtelnet LIBTELNET?= ${LIBTELNETDIR}/libtelnet${PIE_SUFFIX}.a LIBCRONDIR= ${OBJTOP}/usr.sbin/cron/lib LIBCRON?= ${LIBCRONDIR}/libcron${PIE_SUFFIX}.a LIBNTPDIR= ${OBJTOP}/usr.sbin/ntp/libntp LIBNTP?= ${LIBNTPDIR}/libntp${PIE_SUFFIX}.a LIBNTPEVENTDIR= ${OBJTOP}/usr.sbin/ntp/libntpevent LIBNTPEVENT?= ${LIBNTPEVENTDIR}/libntpevent${PIE_SUFFIX}.a LIBOPTSDIR= ${OBJTOP}/usr.sbin/ntp/libopts LIBOPTS?= ${LIBOPTSDIR}/libopts${PIE_SUFFIX}.a LIBPARSEDIR= ${OBJTOP}/usr.sbin/ntp/libparse LIBPARSE?= ${LIBPARSEDIR}/libparse${PIE_SUFFIX}.a LIBLPRDIR= ${OBJTOP}/usr.sbin/lpr/common_source LIBLPR?= ${LIBLPRDIR}/liblpr${PIE_SUFFIX}.a LIBFIFOLOGDIR= ${OBJTOP}/usr.sbin/fifolog/lib LIBFIFOLOG?= ${LIBFIFOLOGDIR}/libfifolog${PIE_SUFFIX}.a LIBBSNMPTOOLSDIR= ${OBJTOP}/usr.sbin/bsnmpd/tools/libbsnmptools LIBBSNMPTOOLS?= ${LIBBSNMPTOOLSDIR}/libbsnmptools${PIE_SUFFIX}.a LIBAMUDIR= ${OBJTOP}/usr.sbin/amd/libamu LIBAMU?= ${LIBAMUDIR}/libamu${PIE_SUFFIX}.a LIBBE?= ${LIBBEDIR}/libbe${PIE_SUFFIX}.a LIBPMCSTATDIR= ${OBJTOP}/lib/libpmcstat LIBPMCSTAT?= ${LIBPMCSTATDIR}/libpmcstat${PIE_SUFFIX}.a LIBC_NOSSP_PICDIR= ${OBJTOP}/lib/libc LIBC_NOSSP_PIC?= ${LIBC_NOSSP_PICDIR}/libc_nossp_pic.a # Define a directory for each library. This is useful for adding -L in when # not using a --sysroot or for meta mode bootstrapping when there is no # Makefile.depend. These are sorted by directory. LIBAVLDIR= ${OBJTOP}/cddl/lib/libavl LIBCTFDIR= ${OBJTOP}/cddl/lib/libctf LIBDTRACEDIR= ${OBJTOP}/cddl/lib/libdtrace LIBNVPAIRDIR= ${OBJTOP}/cddl/lib/libnvpair LIBUMEMDIR= ${OBJTOP}/cddl/lib/libumem LIBUUTILDIR= ${OBJTOP}/cddl/lib/libuutil LIBZFSDIR= ${OBJTOP}/cddl/lib/libzfs LIBZFS_COREDIR= ${OBJTOP}/cddl/lib/libzfs_core LIBZPOOLDIR= ${OBJTOP}/cddl/lib/libzpool # OFED support LIBCXGB4DIR= ${OBJTOP}/lib/ofed/libcxgb4 LIBIBCMDIR= ${OBJTOP}/lib/ofed/libibcm LIBIBMADDIR= ${OBJTOP}/lib/ofed/libibmad LIBIBNETDISCDIR=${OBJTOP}/lib/ofed/libibnetdisc LIBIBUMADDIR= ${OBJTOP}/lib/ofed/libibumad LIBIBVERBSDIR= ${OBJTOP}/lib/ofed/libibverbs LIBMLX4DIR= ${OBJTOP}/lib/ofed/libmlx4 LIBMLX5DIR= ${OBJTOP}/lib/ofed/libmlx5 LIBRDMACMDIR= ${OBJTOP}/lib/ofed/librdmacm LIBOSMCOMPDIR= ${OBJTOP}/lib/ofed/complib LIBOPENSMDIR= ${OBJTOP}/lib/ofed/libopensm LIBOSMVENDORDIR=${OBJTOP}/lib/ofed/libvendor LIBDIALOGDIR= ${OBJTOP}/gnu/lib/libdialog LIBGCOVDIR= ${OBJTOP}/gnu/lib/libgcov LIBGOMPDIR= ${OBJTOP}/gnu/lib/libgomp LIBGNUREGEXDIR= ${OBJTOP}/gnu/lib/libregex LIBSSPDIR= ${OBJTOP}/gnu/lib/libssp LIBSSP_NONSHAREDDIR= ${OBJTOP}/gnu/lib/libssp/libssp_nonshared LIBSUPCPLUSPLUSDIR= ${OBJTOP}/gnu/lib/libsupc++ LIBASN1DIR= ${OBJTOP}/kerberos5/lib/libasn1 LIBGSSAPI_KRB5DIR= ${OBJTOP}/kerberos5/lib/libgssapi_krb5 LIBGSSAPI_NTLMDIR= ${OBJTOP}/kerberos5/lib/libgssapi_ntlm LIBGSSAPI_SPNEGODIR= ${OBJTOP}/kerberos5/lib/libgssapi_spnego LIBHDBDIR= ${OBJTOP}/kerberos5/lib/libhdb LIBHEIMBASEDIR= ${OBJTOP}/kerberos5/lib/libheimbase LIBHEIMIPCCDIR= ${OBJTOP}/kerberos5/lib/libheimipcc LIBHEIMIPCSDIR= ${OBJTOP}/kerberos5/lib/libheimipcs LIBHEIMNTLMDIR= ${OBJTOP}/kerberos5/lib/libheimntlm LIBHX509DIR= ${OBJTOP}/kerberos5/lib/libhx509 LIBKADM5CLNTDIR= ${OBJTOP}/kerberos5/lib/libkadm5clnt LIBKADM5SRVDIR= ${OBJTOP}/kerberos5/lib/libkadm5srv LIBKAFS5DIR= ${OBJTOP}/kerberos5/lib/libkafs5 LIBKDCDIR= ${OBJTOP}/kerberos5/lib/libkdc LIBKRB5DIR= ${OBJTOP}/kerberos5/lib/libkrb5 LIBROKENDIR= ${OBJTOP}/kerberos5/lib/libroken LIBWINDDIR= ${OBJTOP}/kerberos5/lib/libwind LIBATF_CDIR= ${OBJTOP}/lib/atf/libatf-c LIBATF_CXXDIR= ${OBJTOP}/lib/atf/libatf-c++ LIBGMOCKDIR= ${OBJTOP}/lib/googletest/gmock LIBGMOCK_MAINDIR= ${OBJTOP}/lib/googletest/gmock_main LIBGTESTDIR= ${OBJTOP}/lib/googletest/gtest LIBGTEST_MAINDIR= ${OBJTOP}/lib/googletest/gtest_main LIBALIASDIR= ${OBJTOP}/lib/libalias/libalias LIBBLACKLISTDIR= ${OBJTOP}/lib/libblacklist LIBBLOCKSRUNTIMEDIR= ${OBJTOP}/lib/libblocksruntime LIBBSNMPDIR= ${OBJTOP}/lib/libbsnmp/libbsnmp LIBCASPERDIR= ${OBJTOP}/lib/libcasper/libcasper LIBCAP_DNSDIR= ${OBJTOP}/lib/libcasper/services/cap_dns LIBCAP_GRPDIR= ${OBJTOP}/lib/libcasper/services/cap_grp LIBCAP_PWDDIR= ${OBJTOP}/lib/libcasper/services/cap_pwd LIBCAP_RANDOMDIR= ${OBJTOP}/lib/libcasper/services/cap_random LIBCAP_SYSCTLDIR= ${OBJTOP}/lib/libcasper/services/cap_sysctl LIBCAP_SYSLOGDIR= ${OBJTOP}/lib/libcasper/services/cap_syslog LIBBSDXMLDIR= ${OBJTOP}/lib/libexpat LIBKVMDIR= ${OBJTOP}/lib/libkvm LIBPTHREADDIR= ${OBJTOP}/lib/libthr LIBMDIR= ${OBJTOP}/lib/msun LIBFORMDIR= ${OBJTOP}/lib/ncurses/form LIBFORMLIBWDIR= ${OBJTOP}/lib/ncurses/formw LIBMENUDIR= ${OBJTOP}/lib/ncurses/menu LIBMENULIBWDIR= ${OBJTOP}/lib/ncurses/menuw LIBNCURSESDIR= ${OBJTOP}/lib/ncurses/ncurses LIBNCURSESWDIR= ${OBJTOP}/lib/ncurses/ncursesw LIBPANELDIR= ${OBJTOP}/lib/ncurses/panel LIBPANELWDIR= ${OBJTOP}/lib/ncurses/panelw LIBCRYPTODIR= ${OBJTOP}/secure/lib/libcrypto LIBSSHDIR= ${OBJTOP}/secure/lib/libssh LIBSSLDIR= ${OBJTOP}/secure/lib/libssl LIBTEKENDIR= ${OBJTOP}/sys/teken/libteken LIBEGACYDIR= ${OBJTOP}/tools/build LIBLNDIR= ${OBJTOP}/usr.bin/lex/lib LIBTERMCAPDIR= ${LIBNCURSESDIR} LIBTERMCAPWDIR= ${LIBNCURSESWDIR} # Default other library directories to lib/libNAME. .for lib in ${_LIBRARIES} LIB${lib:tu}DIR?= ${OBJTOP}/lib/lib${lib} .endfor # Validate that listed LIBADD are valid. .for _l in ${LIBADD} .if empty(_LIBRARIES:M${_l}) _BADLIBADD+= ${_l} .endif .endfor .if !empty(_BADLIBADD) .error ${.CURDIR}: Invalid LIBADD used which may need to be added to ${_this:T}: ${_BADLIBADD} .endif # Sanity check that libraries are defined here properly when building them. .if defined(LIB) && ${_LIBRARIES:M${LIB}} != "" .if !empty(LIBADD) && \ (!defined(_DP_${LIB}) || ${LIBADD:O:u} != ${_DP_${LIB}:O:u}) .error ${.CURDIR}: Missing or incorrect _DP_${LIB} entry in ${_this:T}. Should match LIBADD for ${LIB} ('${LIBADD}' vs '${_DP_${LIB}}') .endif # Note that OBJTOP is not yet defined here but for the purpose of the check # it is fine as it resolves to the SRC directory. .if !defined(LIB${LIB:tu}DIR) || !exists(${SRCTOP}/${LIB${LIB:tu}DIR:S,^${OBJTOP}/,,}) .error ${.CURDIR}: Missing or incorrect value for LIB${LIB:tu}DIR in ${_this:T}: ${LIB${LIB:tu}DIR:S,^${OBJTOP}/,,} .endif .if ${_INTERNALLIBS:M${LIB}} != "" && !defined(LIB${LIB:tu}) .error ${.CURDIR}: Missing value for LIB${LIB:tu} in ${_this:T}. Likely should be: LIB${LIB:tu}?= $${LIB${LIB:tu}DIR}/lib${LIB}.a .endif .endif .endif # !target(____) Index: head/share/mk/src.opts.mk =================================================================== --- head/share/mk/src.opts.mk (revision 349351) +++ head/share/mk/src.opts.mk (revision 349352) @@ -1,590 +1,589 @@ # $FreeBSD$ # # Option file for FreeBSD /usr/src builds. # # Users define WITH_FOO and WITHOUT_FOO on the command line or in /etc/src.conf # and /etc/make.conf files. These translate in the build system to MK_FOO={yes,no} # with sensible (usually) defaults. # # Makefiles must include bsd.opts.mk after defining specific MK_FOO options that # are applicable for that Makefile (typically there are none, but sometimes there # are exceptions). Recursive makes usually add MK_FOO=no for options that they wish # to omit from that make. # # Makefiles must include bsd.mkopt.mk before they test the value of any MK_FOO # variable. # # Makefiles may also assume that this file is included by src.opts.mk should it # need variables defined there prior to the end of the Makefile where # bsd.{subdir,lib.bin}.mk is traditionally included. # # The old-style YES_FOO and NO_FOO are being phased out. No new instances of them # should be added. Old instances should be removed since they were just to # bridge the gap between FreeBSD 4 and FreeBSD 5. # # Makefiles should never test WITH_FOO or WITHOUT_FOO directly (although an # exception is made for _WITHOUT_SRCONF which turns off this mechanism # completely inside bsd.*.mk files). # .if !target(____) ____: .include # # Define MK_* variables (which are either "yes" or "no") for users # to set via WITH_*/WITHOUT_* in /etc/src.conf and override in the # make(1) environment. # These should be tested with `== "no"' or `!= "no"' in makefiles. # The NO_* variables should only be set by makefiles for variables # that haven't been converted over. # # These options are used by the src builds. Those listed in # __DEFAULT_YES_OPTIONS default to 'yes' and will build unless turned # off. __DEFAULT_NO_OPTIONS will default to 'no' and won't build # unless turned on. Any options listed in 'BROKEN_OPTIONS' will be # hard-wired to 'no'. "Broken" here means not working or # not-appropriate and/or not supported. It doesn't imply something is # wrong with the code. There's not a single good word for this, so # BROKEN was selected as the least imperfect one considered at the # time. Options are added to BROKEN_OPTIONS list on a per-arch basis. # At this time, there's no provision for mutually incompatible options. __DEFAULT_YES_OPTIONS = \ ACCT \ ACPI \ AMD \ APM \ AT \ ATM \ AUDIT \ AUTHPF \ AUTOFS \ BHYVE \ BINUTILS \ BINUTILS_BOOTSTRAP \ BLACKLIST \ BLUETOOTH \ BOOT \ BOOTPARAMD \ BOOTPD \ BSD_CPIO \ BSD_CRTBEGIN \ BSDINSTALL \ BSNMP \ BZIP2 \ CALENDAR \ CAPSICUM \ CASPER \ CCD \ CDDL \ CPP \ CROSS_COMPILER \ CRYPT \ CUSE \ CXX \ CXGBETOOL \ DIALOG \ DICT \ DMAGENT \ DYNAMICROOT \ EE \ EFI \ ELFTOOLCHAIN_BOOTSTRAP \ EXAMPLES \ FDT \ FILE \ FINGER \ FLOPPY \ FMTREE \ FORTH \ FP_LIBC \ FREEBSD_UPDATE \ FTP \ GAMES \ GCOV \ GDB \ GNU_DIFF \ GNU_GREP \ GOOGLETEST \ GPIO \ HAST \ HTML \ HYPERV \ ICONV \ INET \ INET6 \ INETD \ IPFILTER \ IPFW \ ISCSI \ JAIL \ KDUMP \ KVM \ LDNS \ LDNS_UTILS \ LEGACY_CONSOLE \ LIB32 \ LIBPTHREAD \ LIBTHR \ LLVM_COV \ LOADER_GELI \ LOADER_LUA \ LOADER_OFW \ LOADER_UBOOT \ LOCALES \ LOCATE \ LPR \ LS_COLORS \ LZMA_SUPPORT \ MAIL \ MAILWRAPPER \ MAKE \ MLX5TOOL \ NDIS \ NETCAT \ NETGRAPH \ NLS_CATALOGS \ NS_CACHING \ NTP \ NVME \ OFED \ OPENSSL \ PAM \ PC_SYSINSTALL \ PF \ PKGBOOTSTRAP \ PMC \ PORTSNAP \ PPP \ QUOTAS \ RADIUS_SUPPORT \ RBOOTD \ REPRODUCIBLE_BUILD \ RESCUE \ ROUTED \ SENDMAIL \ SERVICESDB \ SETUID_LOGIN \ SHAREDOCS \ SOURCELESS \ SOURCELESS_HOST \ SOURCELESS_UCODE \ SVNLITE \ SYSCONS \ SYSTEM_COMPILER \ SYSTEM_LINKER \ TALK \ TCP_WRAPPERS \ TCSH \ TELNET \ TEXTPROC \ TFTP \ UNBOUND \ USB \ UTMPX \ VI \ VT \ WIRELESS \ WPA_SUPPLICANT_EAPOL \ ZFS \ LOADER_ZFS \ ZONEINFO __DEFAULT_NO_OPTIONS = \ BEARSSL \ BSD_GREP \ CLANG_EXTRAS \ DTRACE_TESTS \ EXPERIMENTAL \ GNU_GREP_COMPAT \ HESIOD \ LIBSOFT \ LOADER_FIREWIRE \ LOADER_FORCE_LE \ LOADER_VERBOSE \ LOADER_VERIEXEC_PASS_MANIFEST \ - NAND \ OFED_EXTRA \ OPENLDAP \ RPCBIND_WARMSTART_SUPPORT \ SHARED_TOOLCHAIN \ SORT_THREADS \ SVN \ ZONEINFO_LEAPSECONDS_SUPPORT \ ZONEINFO_OLD_TIMEZONES_SUPPORT \ # LEFT/RIGHT. Left options which default to "yes" unless their corresponding # RIGHT option is disabled. __DEFAULT_DEPENDENT_OPTIONS= \ CLANG_FULL/CLANG \ LLVM_TARGET_ALL/CLANG \ LOADER_VERIEXEC/BEARSSL \ LOADER_EFI_SECUREBOOT/LOADER_VERIEXEC \ VERIEXEC/BEARSSL \ # MK_*_SUPPORT options which default to "yes" unless their corresponding # MK_* variable is set to "no". # .for var in \ BLACKLIST \ BZIP2 \ INET \ INET6 \ KERBEROS \ KVM \ NETGRAPH \ PAM \ TESTS \ WIRELESS __DEFAULT_DEPENDENT_OPTIONS+= ${var}_SUPPORT/${var} .endfor # # Default behaviour of some options depends on the architecture. Unfortunately # this means that we have to test TARGET_ARCH (the buildworld case) as well # as MACHINE_ARCH (the non-buildworld case). Normally TARGET_ARCH is not # used at all in bsd.*.mk, but we have to make an exception here if we want # to allow defaults for some things like clang to vary by target architecture. # Additional, per-target behavior should be rarely added only after much # gnashing of teeth and grinding of gears. # .if defined(TARGET_ARCH) __T=${TARGET_ARCH} .else __T=${MACHINE_ARCH} .endif .if defined(TARGET) __TT=${TARGET} .else __TT=${MACHINE} .endif # All supported backends for LLVM_TARGET_XXX __LLVM_TARGETS= \ aarch64 \ arm \ mips \ powerpc \ sparc \ x86 __LLVM_TARGET_FILT= C/(amd64|i386)/x86/:S/sparc64/sparc/:S/arm64/aarch64/ .for __llt in ${__LLVM_TARGETS} # Default the given TARGET's LLVM_TARGET support to the value of MK_CLANG. .if ${__TT:${__LLVM_TARGET_FILT}} == ${__llt} __DEFAULT_DEPENDENT_OPTIONS+= LLVM_TARGET_${__llt:${__LLVM_TARGET_FILT}:tu}/CLANG # Disable other targets for arm and armv6, to work around "relocation truncated # to fit" errors with BFD ld, since libllvm.a will get too large to link. .elif ${__T} == "arm" || ${__T} == "armv6" __DEFAULT_NO_OPTIONS+=LLVM_TARGET_${__llt:tu} # aarch64 needs arm for -m32 support. .elif ${__TT} == "arm64" && ${__llt} == "arm" __DEFAULT_DEPENDENT_OPTIONS+= LLVM_TARGET_ARM/LLVM_TARGET_AARCH64 # Default the rest of the LLVM_TARGETs to the value of MK_LLVM_TARGET_ALL # which is based on MK_CLANG. .else __DEFAULT_DEPENDENT_OPTIONS+= LLVM_TARGET_${__llt:${__LLVM_TARGET_FILT}:tu}/LLVM_TARGET_ALL .endif .endfor __DEFAULT_NO_OPTIONS+=LLVM_TARGET_BPF __DEFAULT_NO_OPTIONS+=LLVM_TARGET_RISCV .include # If the compiler is not C++11 capable, disable Clang and use GCC instead. # This means that architectures that have GCC 4.2 as default can not # build Clang without using an external compiler. .if ${COMPILER_FEATURES:Mc++11} && (${__T} == "aarch64" || \ ${__T} == "amd64" || ${__TT} == "arm" || ${__T} == "i386") # Clang is enabled, and will be installed as the default /usr/bin/cc. __DEFAULT_YES_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_IS_CC LLD __DEFAULT_NO_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX GPL_DTC .elif ${COMPILER_FEATURES:Mc++11} && ${__T:Mriscv*} == "" && ${__T} != "sparc64" # If an external compiler that supports C++11 is used as ${CC} and Clang # supports the target, then Clang is enabled but GCC is installed as the # default /usr/bin/cc. __DEFAULT_YES_OPTIONS+=CLANG GCC GCC_BOOTSTRAP GNUCXX GPL_DTC LLD __DEFAULT_NO_OPTIONS+=CLANG_BOOTSTRAP CLANG_IS_CC .else # Everything else disables Clang, and uses GCC instead. __DEFAULT_YES_OPTIONS+=GCC GCC_BOOTSTRAP GNUCXX GPL_DTC __DEFAULT_NO_OPTIONS+=CLANG CLANG_BOOTSTRAP CLANG_IS_CC LLD .endif # In-tree binutils/gcc are older versions without modern architecture support. .if ${__T} == "aarch64" || ${__T:Mriscv*} != "" BROKEN_OPTIONS+=BINUTILS BINUTILS_BOOTSTRAP GCC GCC_BOOTSTRAP GDB .endif .if ${__T:Mriscv*} != "" BROKEN_OPTIONS+=OFED .endif .if ${__T} == "aarch64" || ${__T} == "amd64" || ${__T} == "i386" || \ ${__T:Mriscv*} != "" || ${__TT} == "mips" __DEFAULT_YES_OPTIONS+=LLVM_LIBUNWIND .else __DEFAULT_NO_OPTIONS+=LLVM_LIBUNWIND .endif .if ${__T} == "aarch64" || ${__T} == "amd64" || ${__T} == "armv7" || \ ${__T} == "i386" __DEFAULT_YES_OPTIONS+=LLD_BOOTSTRAP LLD_IS_LD .else __DEFAULT_NO_OPTIONS+=LLD_BOOTSTRAP LLD_IS_LD .endif .if ${__T} == "aarch64" || ${__T} == "amd64" || ${__T} == "i386" __DEFAULT_YES_OPTIONS+=LLDB .else __DEFAULT_NO_OPTIONS+=LLDB .endif # LLVM lacks support for FreeBSD 64-bit atomic operations for ARMv4/ARMv5 .if ${__T} == "arm" BROKEN_OPTIONS+=LLDB .endif # GDB in base is generally less functional than GDB in ports. Ports GDB # sparc64 kernel support has not been tested. .if ${__T} == "sparc64" __DEFAULT_NO_OPTIONS+=GDB_LIBEXEC .else __DEFAULT_YES_OPTIONS+=GDB_LIBEXEC .endif # Only doing soft float API stuff on armv6 and armv7 .if ${__T} != "armv6" && ${__T} != "armv7" BROKEN_OPTIONS+=LIBSOFT .endif .if ${__T:Mmips*} BROKEN_OPTIONS+=SSP .endif # EFI doesn't exist on mips, powerpc, sparc or riscv. .if ${__T:Mmips*} || ${__T:Mpowerpc*} || ${__T:Msparc64} || ${__T:Mriscv*} BROKEN_OPTIONS+=EFI .endif # OFW is only for powerpc and sparc64, exclude others .if ${__T:Mpowerpc*} == "" && ${__T:Msparc64} == "" BROKEN_OPTIONS+=LOADER_OFW .endif # UBOOT is only for arm, mips and powerpc, exclude others .if ${__T:Marm*} == "" && ${__T:Mmips*} == "" && ${__T:Mpowerpc*} == "" BROKEN_OPTIONS+=LOADER_UBOOT .endif # GELI and Lua in loader currently cause boot failures on sparc64 and powerpc. # Further debugging is required -- probably they are just broken on big # endian systems generically (they jump to null pointers or try to read # crazy high addresses, which is typical of endianness problems). .if ${__T} == "sparc64" || ${__T:Mpowerpc*} BROKEN_OPTIONS+=LOADER_GELI LOADER_LUA .endif .if ${__T:Mmips64*} # profiling won't work on MIPS64 because there is only assembly for o32 BROKEN_OPTIONS+=PROFILE .endif .if ${__T} != "aarch64" && ${__T} != "amd64" && ${__T} != "i386" && \ ${__T} != "powerpc64" && ${__T} != "sparc64" BROKEN_OPTIONS+=CXGBETOOL BROKEN_OPTIONS+=MLX5TOOL .endif # HyperV is currently x86-only .if ${__T} != "amd64" && ${__T} != "i386" BROKEN_OPTIONS+=HYPERV .endif # NVME is only x86 and powerpc64 .if ${__T} != "amd64" && ${__T} != "i386" && ${__T} != "powerpc64" BROKEN_OPTIONS+=NVME .endif # PowerPC and Sparc64 need extra crt*.o files .if ${__T:Mpowerpc*} || ${__T:Msparc64} BROKEN_OPTIONS+=BSD_CRTBEGIN .endif .if ${COMPILER_FEATURES:Mc++11} && (${__T} == "amd64" || ${__T} == "i386") __DEFAULT_YES_OPTIONS+=OPENMP .else __DEFAULT_NO_OPTIONS+=OPENMP .endif .include # # MK_* options that default to "yes" if the compiler is a C++11 compiler. # .for var in \ LIBCPLUSPLUS .if !defined(MK_${var}) .if ${COMPILER_FEATURES:Mc++11} .if defined(WITHOUT_${var}) MK_${var}:= no .else MK_${var}:= yes .endif .else .if defined(WITH_${var}) MK_${var}:= yes .else MK_${var}:= no .endif .endif .endif .endfor # # Force some options off if their dependencies are off. # Order is somewhat important. # .if !${COMPILER_FEATURES:Mc++11} MK_GOOGLETEST:= no MK_LLVM_LIBUNWIND:= no .endif .if ${MK_CAPSICUM} == "no" MK_CASPER:= no .endif .if ${MK_LIBPTHREAD} == "no" MK_LIBTHR:= no .endif .if ${MK_LDNS} == "no" MK_LDNS_UTILS:= no MK_UNBOUND:= no .endif .if ${MK_SOURCELESS} == "no" MK_SOURCELESS_HOST:= no MK_SOURCELESS_UCODE:= no .endif .if ${MK_CDDL} == "no" MK_ZFS:= no MK_LOADER_ZFS:= no MK_CTF:= no .endif .if ${MK_CRYPT} == "no" MK_OPENSSL:= no MK_OPENSSH:= no MK_KERBEROS:= no .endif .if ${MK_CXX} == "no" MK_CLANG:= no MK_GNUCXX:= no MK_TESTS:= no .endif .if ${MK_DIALOG} == "no" MK_BSDINSTALL:= no .endif .if ${MK_MAIL} == "no" MK_MAILWRAPPER:= no MK_SENDMAIL:= no MK_DMAGENT:= no .endif .if ${MK_NETGRAPH} == "no" MK_ATM:= no MK_BLUETOOTH:= no .endif .if ${MK_NLS} == "no" MK_NLS_CATALOGS:= no .endif .if ${MK_OPENSSL} == "no" MK_OPENSSH:= no MK_KERBEROS:= no .endif .if ${MK_PF} == "no" MK_AUTHPF:= no .endif .if ${MK_OFED} == "no" MK_OFED_EXTRA:= no .endif .if ${MK_PORTSNAP} == "no" # freebsd-update depends on phttpget from portsnap MK_FREEBSD_UPDATE:= no .endif .if ${MK_TESTS} == "no" MK_DTRACE_TESTS:= no .endif .if ${MK_TESTS_SUPPORT} == "no" MK_GOOGLETEST:= no .endif .if ${MK_ZONEINFO} == "no" MK_ZONEINFO_LEAPSECONDS_SUPPORT:= no MK_ZONEINFO_OLD_TIMEZONES_SUPPORT:= no .endif .if ${MK_CROSS_COMPILER} == "no" MK_BINUTILS_BOOTSTRAP:= no MK_CLANG_BOOTSTRAP:= no MK_ELFTOOLCHAIN_BOOTSTRAP:= no MK_GCC_BOOTSTRAP:= no MK_LLD_BOOTSTRAP:= no .endif .if ${MK_TOOLCHAIN} == "no" MK_BINUTILS:= no MK_CLANG:= no MK_GCC:= no MK_GDB:= no MK_INCLUDES:= no MK_LLD:= no MK_LLDB:= no .endif .if ${MK_CLANG} == "no" MK_CLANG_EXTRAS:= no MK_CLANG_FULL:= no MK_LLVM_COV:= no .endif .if ${MK_LOADER_VERIEXEC} == "no" MK_LOADER_VERIEXEC_PASS_MANIFEST := no .endif # # MK_* options whose default value depends on another option. # .for vv in \ GSSAPI/KERBEROS \ MAN_UTILS/MAN .if defined(WITH_${vv:H}) MK_${vv:H}:= yes .elif defined(WITHOUT_${vv:H}) MK_${vv:H}:= no .else MK_${vv:H}:= ${MK_${vv:T}} .endif .endfor # # Set defaults for the MK_*_SUPPORT variables. # .if !${COMPILER_FEATURES:Mc++11} MK_LLDB:= no .endif # gcc 4.8 and newer supports libc++, so suppress gnuc++ in that case. # while in theory we could build it with that, we don't want to do # that since it creates too much confusion for too little gain. # XXX: This is incomplete and needs X_COMPILER_TYPE/VERSION checks too # to prevent Makefile.inc1 from bootstrapping unneeded dependencies # and to support 'make delete-old' when supplying an external toolchain. .if ${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 40800 MK_GNUCXX:=no MK_GCC:=no .endif .endif # !target(____) Index: head/stand/arm/uboot/conf.c =================================================================== --- head/stand/arm/uboot/conf.c (revision 349351) +++ head/stand/arm/uboot/conf.c (revision 349352) @@ -1,97 +1,94 @@ /*- * Copyright (c) 2008 Semihalf, Rafal Jaworowski * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include #include "bootstrap.h" #include "libuboot.h" #if defined(LOADER_NET_SUPPORT) #include "dev_net.h" #endif /* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ void (*exitfn)(int) = exit; struct devsw *devsw[] = { #if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) &uboot_storage, #endif #if defined(LOADER_NET_SUPPORT) &netdev, #endif NULL }; struct fs_ops *file_system[] = { #if defined(LOADER_UFS_SUPPORT) &ufs_fsops, #endif #if defined(LOADER_CD9660_SUPPORT) &cd9660_fsops, #endif #if defined(LOADER_EXT2FS_SUPPORT) &ext2fs_fsops, #endif -#if defined(LOADER_NANDFS_SUPPORT) - &nandfs_fsops, -#endif #if defined(LOADER_NFS_SUPPORT) &nfs_fsops, #endif #if defined(LOADER_TFTP_SUPPORT) &tftp_fsops, #endif #if defined(LOADER_GZIP_SUPPORT) &gzipfs_fsops, #endif #if defined(LOADER_BZIP2_SUPPORT) &bzipfs_fsops, #endif NULL }; struct netif_driver *netif_drivers[] = { #if defined(LOADER_NET_SUPPORT) &uboot_net, #endif NULL, }; struct file_format *file_formats[] = { &uboot_elf, NULL }; extern struct console uboot_console; struct console *consoles[] = { &uboot_console, NULL }; Index: head/stand/arm/uboot/version =================================================================== --- head/stand/arm/uboot/version (revision 349351) +++ head/stand/arm/uboot/version (revision 349352) @@ -1,9 +1,10 @@ $FreeBSD$ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. +1.3: Remove NAND FS support. 1.2: Extended with NAND FS support. 1.1: Flattened Device Tree blob support. 1.0: Added storage support. Booting from HDD, USB, etc. is now possible. 0.5: Initial U-Boot/arm version (netbooting only). Index: head/stand/common/part.c =================================================================== --- head/stand/common/part.c (revision 349351) +++ head/stand/common/part.c (revision 349352) @@ -1,949 +1,941 @@ /*- * Copyright (c) 2012 Andrey V. Elsukov * 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef PART_DEBUG #define DPRINTF(fmt, args...) printf("%s: " fmt "\n", __func__, ## args) #else #define DPRINTF(fmt, args...) ((void)0) #endif #ifdef LOADER_GPT_SUPPORT #define MAXTBLSZ 64 static const uuid_t gpt_uuid_unused = GPT_ENT_TYPE_UNUSED; static const uuid_t gpt_uuid_ms_basic_data = GPT_ENT_TYPE_MS_BASIC_DATA; static const uuid_t gpt_uuid_freebsd_ufs = GPT_ENT_TYPE_FREEBSD_UFS; static const uuid_t gpt_uuid_efi = GPT_ENT_TYPE_EFI; static const uuid_t gpt_uuid_freebsd = GPT_ENT_TYPE_FREEBSD; static const uuid_t gpt_uuid_freebsd_boot = GPT_ENT_TYPE_FREEBSD_BOOT; -static const uuid_t gpt_uuid_freebsd_nandfs = GPT_ENT_TYPE_FREEBSD_NANDFS; static const uuid_t gpt_uuid_freebsd_swap = GPT_ENT_TYPE_FREEBSD_SWAP; static const uuid_t gpt_uuid_freebsd_zfs = GPT_ENT_TYPE_FREEBSD_ZFS; static const uuid_t gpt_uuid_freebsd_vinum = GPT_ENT_TYPE_FREEBSD_VINUM; #endif struct pentry { struct ptable_entry part; uint64_t flags; union { uint8_t bsd; uint8_t mbr; uuid_t gpt; uint16_t vtoc8; } type; STAILQ_ENTRY(pentry) entry; }; struct ptable { enum ptable_type type; uint16_t sectorsize; uint64_t sectors; STAILQ_HEAD(, pentry) entries; }; static struct parttypes { enum partition_type type; const char *desc; } ptypes[] = { { PART_UNKNOWN, "Unknown" }, { PART_EFI, "EFI" }, { PART_FREEBSD, "FreeBSD" }, { PART_FREEBSD_BOOT, "FreeBSD boot" }, - { PART_FREEBSD_NANDFS, "FreeBSD nandfs" }, { PART_FREEBSD_UFS, "FreeBSD UFS" }, { PART_FREEBSD_ZFS, "FreeBSD ZFS" }, { PART_FREEBSD_SWAP, "FreeBSD swap" }, { PART_FREEBSD_VINUM, "FreeBSD vinum" }, { PART_LINUX, "Linux" }, { PART_LINUX_SWAP, "Linux swap" }, { PART_DOS, "DOS/Windows" }, { PART_ISO9660, "ISO9660" }, }; const char * parttype2str(enum partition_type type) { size_t i; for (i = 0; i < nitems(ptypes); i++) if (ptypes[i].type == type) return (ptypes[i].desc); return (ptypes[0].desc); } #ifdef LOADER_GPT_SUPPORT static void uuid_letoh(uuid_t *uuid) { uuid->time_low = le32toh(uuid->time_low); uuid->time_mid = le16toh(uuid->time_mid); uuid->time_hi_and_version = le16toh(uuid->time_hi_and_version); } static enum partition_type gpt_parttype(uuid_t type) { if (uuid_equal(&type, &gpt_uuid_efi, NULL)) return (PART_EFI); else if (uuid_equal(&type, &gpt_uuid_ms_basic_data, NULL)) return (PART_DOS); else if (uuid_equal(&type, &gpt_uuid_freebsd_boot, NULL)) return (PART_FREEBSD_BOOT); else if (uuid_equal(&type, &gpt_uuid_freebsd_ufs, NULL)) return (PART_FREEBSD_UFS); else if (uuid_equal(&type, &gpt_uuid_freebsd_zfs, NULL)) return (PART_FREEBSD_ZFS); else if (uuid_equal(&type, &gpt_uuid_freebsd_swap, NULL)) return (PART_FREEBSD_SWAP); else if (uuid_equal(&type, &gpt_uuid_freebsd_vinum, NULL)) return (PART_FREEBSD_VINUM); - else if (uuid_equal(&type, &gpt_uuid_freebsd_nandfs, NULL)) - return (PART_FREEBSD_NANDFS); else if (uuid_equal(&type, &gpt_uuid_freebsd, NULL)) return (PART_FREEBSD); return (PART_UNKNOWN); } static struct gpt_hdr * gpt_checkhdr(struct gpt_hdr *hdr, uint64_t lba_self, uint64_t lba_last, uint16_t sectorsize) { uint32_t sz, crc; if (memcmp(hdr->hdr_sig, GPT_HDR_SIG, sizeof(hdr->hdr_sig)) != 0) { DPRINTF("no GPT signature"); return (NULL); } sz = le32toh(hdr->hdr_size); if (sz < 92 || sz > sectorsize) { DPRINTF("invalid GPT header size: %d", sz); return (NULL); } crc = le32toh(hdr->hdr_crc_self); hdr->hdr_crc_self = 0; if (crc32(hdr, sz) != crc) { DPRINTF("GPT header's CRC doesn't match"); return (NULL); } hdr->hdr_crc_self = crc; hdr->hdr_revision = le32toh(hdr->hdr_revision); if (hdr->hdr_revision < GPT_HDR_REVISION) { DPRINTF("unsupported GPT revision %d", hdr->hdr_revision); return (NULL); } hdr->hdr_lba_self = le64toh(hdr->hdr_lba_self); if (hdr->hdr_lba_self != lba_self) { DPRINTF("self LBA doesn't match"); return (NULL); } hdr->hdr_lba_alt = le64toh(hdr->hdr_lba_alt); if (hdr->hdr_lba_alt == hdr->hdr_lba_self) { DPRINTF("invalid alternate LBA"); return (NULL); } hdr->hdr_entries = le32toh(hdr->hdr_entries); hdr->hdr_entsz = le32toh(hdr->hdr_entsz); if (hdr->hdr_entries == 0 || hdr->hdr_entsz < sizeof(struct gpt_ent) || sectorsize % hdr->hdr_entsz != 0) { DPRINTF("invalid entry size or number of entries"); return (NULL); } hdr->hdr_lba_start = le64toh(hdr->hdr_lba_start); hdr->hdr_lba_end = le64toh(hdr->hdr_lba_end); hdr->hdr_lba_table = le64toh(hdr->hdr_lba_table); hdr->hdr_crc_table = le32toh(hdr->hdr_crc_table); uuid_letoh(&hdr->hdr_uuid); return (hdr); } static int gpt_checktbl(const struct gpt_hdr *hdr, uint8_t *tbl, size_t size, uint64_t lba_last) { struct gpt_ent *ent; uint32_t i, cnt; cnt = size / hdr->hdr_entsz; if (hdr->hdr_entries <= cnt) { cnt = hdr->hdr_entries; /* Check CRC only when buffer size is enough for table. */ if (hdr->hdr_crc_table != crc32(tbl, hdr->hdr_entries * hdr->hdr_entsz)) { DPRINTF("GPT table's CRC doesn't match"); return (-1); } } for (i = 0; i < cnt; i++) { ent = (struct gpt_ent *)(tbl + i * hdr->hdr_entsz); uuid_letoh(&ent->ent_type); if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) continue; ent->ent_lba_start = le64toh(ent->ent_lba_start); ent->ent_lba_end = le64toh(ent->ent_lba_end); } return (0); } static struct ptable * ptable_gptread(struct ptable *table, void *dev, diskread_t dread) { struct pentry *entry; struct gpt_hdr *phdr, hdr; struct gpt_ent *ent; uint8_t *buf, *tbl; uint64_t offset; int pri, sec; size_t size, i; buf = malloc(table->sectorsize); if (buf == NULL) return (NULL); tbl = malloc(table->sectorsize * MAXTBLSZ); if (tbl == NULL) { free(buf); return (NULL); } /* Read the primary GPT header. */ if (dread(dev, buf, 1, 1) != 0) { ptable_close(table); table = NULL; goto out; } pri = sec = 0; /* Check the primary GPT header. */ phdr = gpt_checkhdr((struct gpt_hdr *)buf, 1, table->sectors - 1, table->sectorsize); if (phdr != NULL) { /* Read the primary GPT table. */ size = MIN(MAXTBLSZ, howmany(phdr->hdr_entries * phdr->hdr_entsz, table->sectorsize)); if (dread(dev, tbl, size, phdr->hdr_lba_table) == 0 && gpt_checktbl(phdr, tbl, size * table->sectorsize, table->sectors - 1) == 0) { memcpy(&hdr, phdr, sizeof(hdr)); pri = 1; } } offset = pri ? hdr.hdr_lba_alt: table->sectors - 1; /* Read the backup GPT header. */ if (dread(dev, buf, 1, offset) != 0) phdr = NULL; else phdr = gpt_checkhdr((struct gpt_hdr *)buf, offset, table->sectors - 1, table->sectorsize); if (phdr != NULL) { /* * Compare primary and backup headers. * If they are equal, then we do not need to read backup * table. If they are different, then prefer backup header * and try to read backup table. */ if (pri == 0 || uuid_equal(&hdr.hdr_uuid, &phdr->hdr_uuid, NULL) == 0 || hdr.hdr_revision != phdr->hdr_revision || hdr.hdr_size != phdr->hdr_size || hdr.hdr_lba_start != phdr->hdr_lba_start || hdr.hdr_lba_end != phdr->hdr_lba_end || hdr.hdr_entries != phdr->hdr_entries || hdr.hdr_entsz != phdr->hdr_entsz || hdr.hdr_crc_table != phdr->hdr_crc_table) { /* Read the backup GPT table. */ size = MIN(MAXTBLSZ, howmany(phdr->hdr_entries * phdr->hdr_entsz, table->sectorsize)); if (dread(dev, tbl, size, phdr->hdr_lba_table) == 0 && gpt_checktbl(phdr, tbl, size * table->sectorsize, table->sectors - 1) == 0) { memcpy(&hdr, phdr, sizeof(hdr)); sec = 1; } } } if (pri == 0 && sec == 0) { /* Both primary and backup tables are invalid. */ table->type = PTABLE_NONE; goto out; } DPRINTF("GPT detected"); size = MIN(hdr.hdr_entries * hdr.hdr_entsz, MAXTBLSZ * table->sectorsize); /* * If the disk's sector count is smaller than the sector count recorded * in the disk's GPT table header, set the table->sectors to the value * recorded in GPT tables. This is done to work around buggy firmware * that returns truncated disk sizes. * * Note, this is still not a foolproof way to get disk's size. For * example, an image file can be truncated when copied to smaller media. */ table->sectors = hdr.hdr_lba_alt + 1; for (i = 0; i < size / hdr.hdr_entsz; i++) { ent = (struct gpt_ent *)(tbl + i * hdr.hdr_entsz); if (uuid_equal(&ent->ent_type, &gpt_uuid_unused, NULL)) continue; /* Simple sanity checks. */ if (ent->ent_lba_start < hdr.hdr_lba_start || ent->ent_lba_end > hdr.hdr_lba_end || ent->ent_lba_start > ent->ent_lba_end) continue; entry = malloc(sizeof(*entry)); if (entry == NULL) break; entry->part.start = ent->ent_lba_start; entry->part.end = ent->ent_lba_end; entry->part.index = i + 1; entry->part.type = gpt_parttype(ent->ent_type); entry->flags = le64toh(ent->ent_attr); memcpy(&entry->type.gpt, &ent->ent_type, sizeof(uuid_t)); STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new GPT partition added"); } out: free(buf); free(tbl); return (table); } #endif /* LOADER_GPT_SUPPORT */ #ifdef LOADER_MBR_SUPPORT /* We do not need to support too many EBR partitions in the loader */ #define MAXEBRENTRIES 8 static enum partition_type mbr_parttype(uint8_t type) { switch (type) { case DOSPTYP_386BSD: return (PART_FREEBSD); case DOSPTYP_LINSWP: return (PART_LINUX_SWAP); case DOSPTYP_LINUX: return (PART_LINUX); case 0x01: case 0x04: case 0x06: case 0x07: case 0x0b: case 0x0c: case 0x0e: return (PART_DOS); } return (PART_UNKNOWN); } static struct ptable * ptable_ebrread(struct ptable *table, void *dev, diskread_t dread) { struct dos_partition *dp; struct pentry *e1, *entry; uint32_t start, end, offset; u_char *buf; int i, index; STAILQ_FOREACH(e1, &table->entries, entry) { if (e1->type.mbr == DOSPTYP_EXT || e1->type.mbr == DOSPTYP_EXTLBA) break; } if (e1 == NULL) return (table); index = 5; offset = e1->part.start; buf = malloc(table->sectorsize); if (buf == NULL) return (table); DPRINTF("EBR detected"); for (i = 0; i < MAXEBRENTRIES; i++) { #if 0 /* Some BIOSes return an incorrect number of sectors */ if (offset >= table->sectors) break; #endif if (dread(dev, buf, 1, offset) != 0) break; dp = (struct dos_partition *)(buf + DOSPARTOFF); if (dp[0].dp_typ == 0) break; start = le32toh(dp[0].dp_start); if (dp[0].dp_typ == DOSPTYP_EXT && dp[1].dp_typ == 0) { offset = e1->part.start + start; continue; } end = le32toh(dp[0].dp_size); entry = malloc(sizeof(*entry)); if (entry == NULL) break; entry->part.start = offset + start; entry->part.end = entry->part.start + end - 1; entry->part.index = index++; entry->part.type = mbr_parttype(dp[0].dp_typ); entry->flags = dp[0].dp_flag; entry->type.mbr = dp[0].dp_typ; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new EBR partition added"); if (dp[1].dp_typ == 0) break; offset = e1->part.start + le32toh(dp[1].dp_start); } free(buf); return (table); } #endif /* LOADER_MBR_SUPPORT */ static enum partition_type bsd_parttype(uint8_t type) { switch (type) { - case FS_NANDFS: - return (PART_FREEBSD_NANDFS); case FS_SWAP: return (PART_FREEBSD_SWAP); case FS_BSDFFS: return (PART_FREEBSD_UFS); case FS_VINUM: return (PART_FREEBSD_VINUM); case FS_ZFS: return (PART_FREEBSD_ZFS); } return (PART_UNKNOWN); } static struct ptable * ptable_bsdread(struct ptable *table, void *dev, diskread_t dread) { struct disklabel *dl; struct partition *part; struct pentry *entry; uint8_t *buf; uint32_t raw_offset; int i; if (table->sectorsize < sizeof(struct disklabel)) { DPRINTF("Too small sectorsize"); return (table); } buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, 1) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } dl = (struct disklabel *)buf; if (le32toh(dl->d_magic) != DISKMAGIC && le32toh(dl->d_magic2) != DISKMAGIC) goto out; if (le32toh(dl->d_secsize) != table->sectorsize) { DPRINTF("unsupported sector size"); goto out; } dl->d_npartitions = le16toh(dl->d_npartitions); if (dl->d_npartitions > 20 || dl->d_npartitions < 8) { DPRINTF("invalid number of partitions"); goto out; } DPRINTF("BSD detected"); part = &dl->d_partitions[0]; raw_offset = le32toh(part[RAW_PART].p_offset); for (i = 0; i < dl->d_npartitions; i++, part++) { if (i == RAW_PART) continue; if (part->p_size == 0) continue; entry = malloc(sizeof(*entry)); if (entry == NULL) break; entry->part.start = le32toh(part->p_offset) - raw_offset; entry->part.end = entry->part.start + le32toh(part->p_size) - 1; entry->part.type = bsd_parttype(part->p_fstype); entry->part.index = i; /* starts from zero */ entry->type.bsd = part->p_fstype; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new BSD partition added"); } table->type = PTABLE_BSD; out: free(buf); return (table); } #ifdef LOADER_VTOC8_SUPPORT static enum partition_type vtoc8_parttype(uint16_t type) { switch (type) { - case VTOC_TAG_FREEBSD_NANDFS: - return (PART_FREEBSD_NANDFS); case VTOC_TAG_FREEBSD_SWAP: return (PART_FREEBSD_SWAP); case VTOC_TAG_FREEBSD_UFS: return (PART_FREEBSD_UFS); case VTOC_TAG_FREEBSD_VINUM: return (PART_FREEBSD_VINUM); case VTOC_TAG_FREEBSD_ZFS: return (PART_FREEBSD_ZFS); } return (PART_UNKNOWN); } static struct ptable * ptable_vtoc8read(struct ptable *table, void *dev, diskread_t dread) { struct pentry *entry; struct vtoc8 *dl; uint8_t *buf; uint16_t sum, heads, sectors; int i; if (table->sectorsize != sizeof(struct vtoc8)) return (table); buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, 0) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } dl = (struct vtoc8 *)buf; /* Check the sum */ for (i = sum = 0; i < sizeof(struct vtoc8); i += sizeof(sum)) sum ^= be16dec(buf + i); if (sum != 0) { DPRINTF("incorrect checksum"); goto out; } if (be16toh(dl->nparts) != VTOC8_NPARTS) { DPRINTF("invalid number of entries"); goto out; } sectors = be16toh(dl->nsecs); heads = be16toh(dl->nheads); if (sectors * heads == 0) { DPRINTF("invalid geometry"); goto out; } DPRINTF("VTOC8 detected"); for (i = 0; i < VTOC8_NPARTS; i++) { dl->part[i].tag = be16toh(dl->part[i].tag); if (i == VTOC_RAW_PART || dl->part[i].tag == VTOC_TAG_UNASSIGNED) continue; entry = malloc(sizeof(*entry)); if (entry == NULL) break; entry->part.start = be32toh(dl->map[i].cyl) * heads * sectors; entry->part.end = be32toh(dl->map[i].nblks) + entry->part.start - 1; entry->part.type = vtoc8_parttype(dl->part[i].tag); entry->part.index = i; /* starts from zero */ entry->type.vtoc8 = dl->part[i].tag; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new VTOC8 partition added"); } table->type = PTABLE_VTOC8; out: free(buf); return (table); } #endif /* LOADER_VTOC8_SUPPORT */ #define cdb2devb(bno) ((bno) * ISO_DEFAULT_BLOCK_SIZE / table->sectorsize) static struct ptable * ptable_iso9660read(struct ptable *table, void *dev, diskread_t dread) { uint8_t *buf; struct iso_primary_descriptor *vd; struct pentry *entry; buf = malloc(table->sectorsize); if (buf == NULL) return (table); if (dread(dev, buf, 1, cdb2devb(16)) != 0) { DPRINTF("read failed"); ptable_close(table); table = NULL; goto out; } vd = (struct iso_primary_descriptor *)buf; if (bcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0) goto out; entry = malloc(sizeof(*entry)); if (entry == NULL) goto out; entry->part.start = 0; entry->part.end = table->sectors; entry->part.type = PART_ISO9660; entry->part.index = 0; STAILQ_INSERT_TAIL(&table->entries, entry, entry); table->type = PTABLE_ISO9660; out: free(buf); return (table); } struct ptable * ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread) { struct dos_partition *dp; struct ptable *table; uint8_t *buf; int i, count; #ifdef LOADER_MBR_SUPPORT struct pentry *entry; uint32_t start, end; int has_ext; #endif table = NULL; buf = malloc(sectorsize); if (buf == NULL) return (NULL); /* First, read the MBR. */ if (dread(dev, buf, 1, DOSBBSECTOR) != 0) { DPRINTF("read failed"); goto out; } table = malloc(sizeof(*table)); if (table == NULL) goto out; table->sectors = sectors; table->sectorsize = sectorsize; table->type = PTABLE_NONE; STAILQ_INIT(&table->entries); if (ptable_iso9660read(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_ISO9660) goto out; #ifdef LOADER_VTOC8_SUPPORT if (be16dec(buf + offsetof(struct vtoc8, magic)) == VTOC_MAGIC) { if (ptable_vtoc8read(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_VTOC8) goto out; } #endif /* Check the BSD label. */ if (ptable_bsdread(table, dev, dread) == NULL) { /* Read error. */ table = NULL; goto out; } else if (table->type == PTABLE_BSD) goto out; #if defined(LOADER_GPT_SUPPORT) || defined(LOADER_MBR_SUPPORT) /* Check the MBR magic. */ if (buf[DOSMAGICOFFSET] != 0x55 || buf[DOSMAGICOFFSET + 1] != 0xaa) { DPRINTF("magic sequence not found"); #if defined(LOADER_GPT_SUPPORT) /* There is no PMBR, check that we have backup GPT */ table->type = PTABLE_GPT; table = ptable_gptread(table, dev, dread); #endif goto out; } /* Check that we have PMBR. Also do some validation. */ dp = (struct dos_partition *)(buf + DOSPARTOFF); for (i = 0, count = 0; i < NDOSPART; i++) { if (dp[i].dp_flag != 0 && dp[i].dp_flag != 0x80) { DPRINTF("invalid partition flag %x", dp[i].dp_flag); goto out; } #ifdef LOADER_GPT_SUPPORT if (dp[i].dp_typ == DOSPTYP_PMBR) { table->type = PTABLE_GPT; DPRINTF("PMBR detected"); } #endif if (dp[i].dp_typ != 0) count++; } /* Do we have some invalid values? */ if (table->type == PTABLE_GPT && count > 1) { if (dp[1].dp_typ != DOSPTYP_HFS) { table->type = PTABLE_NONE; DPRINTF("Incorrect PMBR, ignore it"); } else { DPRINTF("Bootcamp detected"); } } #ifdef LOADER_GPT_SUPPORT if (table->type == PTABLE_GPT) { table = ptable_gptread(table, dev, dread); goto out; } #endif #ifdef LOADER_MBR_SUPPORT /* Read MBR. */ DPRINTF("MBR detected"); table->type = PTABLE_MBR; for (i = has_ext = 0; i < NDOSPART; i++) { if (dp[i].dp_typ == 0) continue; start = le32dec(&(dp[i].dp_start)); end = le32dec(&(dp[i].dp_size)); if (start == 0 || end == 0) continue; #if 0 /* Some BIOSes return an incorrect number of sectors */ if (start + end - 1 >= sectors) continue; /* XXX: ignore */ #endif if (dp[i].dp_typ == DOSPTYP_EXT || dp[i].dp_typ == DOSPTYP_EXTLBA) has_ext = 1; entry = malloc(sizeof(*entry)); if (entry == NULL) break; entry->part.start = start; entry->part.end = start + end - 1; entry->part.index = i + 1; entry->part.type = mbr_parttype(dp[i].dp_typ); entry->flags = dp[i].dp_flag; entry->type.mbr = dp[i].dp_typ; STAILQ_INSERT_TAIL(&table->entries, entry, entry); DPRINTF("new MBR partition added"); } if (has_ext) { table = ptable_ebrread(table, dev, dread); /* FALLTHROUGH */ } #endif /* LOADER_MBR_SUPPORT */ #endif /* LOADER_MBR_SUPPORT || LOADER_GPT_SUPPORT */ out: free(buf); return (table); } void ptable_close(struct ptable *table) { struct pentry *entry; if (table == NULL) return; while (!STAILQ_EMPTY(&table->entries)) { entry = STAILQ_FIRST(&table->entries); STAILQ_REMOVE_HEAD(&table->entries, entry); free(entry); } free(table); } enum ptable_type ptable_gettype(const struct ptable *table) { return (table->type); } int ptable_getsize(const struct ptable *table, uint64_t *sizep) { uint64_t tmp = table->sectors * table->sectorsize; if (tmp < table->sectors) return (EOVERFLOW); if (sizep != NULL) *sizep = tmp; return (0); } int ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index) { struct pentry *entry; if (part == NULL || table == NULL) return (EINVAL); STAILQ_FOREACH(entry, &table->entries, entry) { if (entry->part.index != index) continue; memcpy(part, &entry->part, sizeof(*part)); return (0); } return (ENOENT); } /* * Search for a slice with the following preferences: * * 1: Active FreeBSD slice * 2: Non-active FreeBSD slice * 3: Active Linux slice * 4: non-active Linux slice * 5: Active FAT/FAT32 slice * 6: non-active FAT/FAT32 slice */ #define PREF_RAWDISK 0 #define PREF_FBSD_ACT 1 #define PREF_FBSD 2 #define PREF_LINUX_ACT 3 #define PREF_LINUX 4 #define PREF_DOS_ACT 5 #define PREF_DOS 6 #define PREF_NONE 7 int ptable_getbestpart(const struct ptable *table, struct ptable_entry *part) { struct pentry *entry, *best; int pref, preflevel; if (part == NULL || table == NULL) return (EINVAL); best = NULL; preflevel = pref = PREF_NONE; STAILQ_FOREACH(entry, &table->entries, entry) { #ifdef LOADER_MBR_SUPPORT if (table->type == PTABLE_MBR) { switch (entry->type.mbr) { case DOSPTYP_386BSD: pref = entry->flags & 0x80 ? PREF_FBSD_ACT: PREF_FBSD; break; case DOSPTYP_LINUX: pref = entry->flags & 0x80 ? PREF_LINUX_ACT: PREF_LINUX; break; case 0x01: /* DOS/Windows */ case 0x04: case 0x06: case 0x0c: case 0x0e: case DOSPTYP_FAT32: pref = entry->flags & 0x80 ? PREF_DOS_ACT: PREF_DOS; break; default: pref = PREF_NONE; } } #endif /* LOADER_MBR_SUPPORT */ #ifdef LOADER_GPT_SUPPORT if (table->type == PTABLE_GPT) { if (entry->part.type == PART_DOS) pref = PREF_DOS; else if (entry->part.type == PART_FREEBSD_UFS || entry->part.type == PART_FREEBSD_ZFS) pref = PREF_FBSD; else pref = PREF_NONE; } #endif /* LOADER_GPT_SUPPORT */ if (pref < preflevel) { preflevel = pref; best = entry; } } if (best != NULL) { memcpy(part, &best->part, sizeof(*part)); return (0); } return (ENOENT); } int ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter) { struct pentry *entry; char name[32]; int ret = 0; name[0] = '\0'; STAILQ_FOREACH(entry, &table->entries, entry) { #ifdef LOADER_MBR_SUPPORT if (table->type == PTABLE_MBR) sprintf(name, "s%d", entry->part.index); else #endif #ifdef LOADER_GPT_SUPPORT if (table->type == PTABLE_GPT) sprintf(name, "p%d", entry->part.index); else #endif #ifdef LOADER_VTOC8_SUPPORT if (table->type == PTABLE_VTOC8) sprintf(name, "%c", (uint8_t) 'a' + entry->part.index); else #endif if (table->type == PTABLE_BSD) sprintf(name, "%c", (uint8_t) 'a' + entry->part.index); if ((ret = iter(arg, name, &entry->part)) != 0) return (ret); } return (ret); } Index: head/stand/common/part.h =================================================================== --- head/stand/common/part.h (revision 349351) +++ head/stand/common/part.h (revision 349352) @@ -1,85 +1,84 @@ /*- * Copyright (c) 2012 Andrey V. Elsukov * 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _PART_H_ #define _PART_H_ struct ptable; enum ptable_type { PTABLE_NONE, PTABLE_BSD, PTABLE_MBR, PTABLE_GPT, PTABLE_VTOC8, PTABLE_ISO9660 }; enum partition_type { PART_UNKNOWN, PART_EFI, PART_FREEBSD, PART_FREEBSD_BOOT, - PART_FREEBSD_NANDFS, PART_FREEBSD_UFS, PART_FREEBSD_ZFS, PART_FREEBSD_SWAP, PART_FREEBSD_VINUM, PART_LINUX, PART_LINUX_SWAP, PART_DOS, PART_ISO9660 }; struct ptable_entry { uint64_t start; uint64_t end; int index; enum partition_type type; }; /* The offset and size are in sectors */ typedef int (diskread_t)(void *arg, void *buf, size_t blocks, uint64_t offset); typedef int (ptable_iterate_t)(void *arg, const char *partname, const struct ptable_entry *part); struct ptable *ptable_open(void *dev, uint64_t sectors, uint16_t sectorsize, diskread_t *dread); void ptable_close(struct ptable *table); enum ptable_type ptable_gettype(const struct ptable *table); int ptable_getsize(const struct ptable *table, uint64_t *sizep); int ptable_getpart(const struct ptable *table, struct ptable_entry *part, int index); int ptable_getbestpart(const struct ptable *table, struct ptable_entry *part); int ptable_iterate(const struct ptable *table, void *arg, ptable_iterate_t *iter); const char *parttype2str(enum partition_type type); #endif /* !_PART_H_ */ Index: head/stand/i386/loader/conf.c =================================================================== --- head/stand/i386/loader/conf.c (revision 349351) +++ head/stand/i386/loader/conf.c (revision 349352) @@ -1,170 +1,167 @@ /*- * Copyright (c) 1998 Michael Smith * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include "libi386/libi386.h" #if defined(LOADER_ZFS_SUPPORT) #include "libzfs.h" #endif /* * We could use linker sets for some or all of these, but * then we would have to control what ended up linked into * the bootstrap. So it's easier to conditionalise things * here. * * XXX rename these arrays to be consistent and less namespace-hostile * * XXX as libi386 and biosboot merge, some of these can become linker sets. */ #if defined(LOADER_FIREWIRE_SUPPORT) extern struct devsw fwohci; #endif extern struct devsw vdisk_dev; /* Exported for libstand */ struct devsw *devsw[] = { &biosfd, &bioscd, &bioshd, #if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT) &pxedisk, #endif #if defined(LOADER_FIREWIRE_SUPPORT) &fwohci, #endif &vdisk_dev, #if defined(LOADER_ZFS_SUPPORT) &zfs_dev, #endif NULL }; struct fs_ops *file_system[] = { #if defined(LOADER_ZFS_SUPPORT) &zfs_fsops, #endif #if defined(LOADER_UFS_SUPPORT) &ufs_fsops, #endif #if defined(LOADER_EXT2FS_SUPPORT) &ext2fs_fsops, #endif #if defined(LOADER_MSDOS_SUPPORT) &dosfs_fsops, #endif #if defined(LOADER_CD9660_SUPPORT) &cd9660_fsops, #endif -#if defined(LOADER_NANDFS_SUPPORT) - &nandfs_fsops, -#endif #ifdef LOADER_NFS_SUPPORT &nfs_fsops, #endif #ifdef LOADER_TFTP_SUPPORT &tftp_fsops, #endif #ifdef LOADER_GZIP_SUPPORT &gzipfs_fsops, #endif #ifdef LOADER_BZIP2_SUPPORT &bzipfs_fsops, #endif #ifdef LOADER_SPLIT_SUPPORT &splitfs_fsops, #endif NULL }; /* Exported for i386 only */ /* * Sort formats so that those that can detect based on arguments * rather than reading the file go first. */ extern struct file_format i386_elf; extern struct file_format i386_elf_obj; extern struct file_format amd64_elf; extern struct file_format amd64_elf_obj; extern struct file_format multiboot; extern struct file_format multiboot_obj; struct file_format *file_formats[] = { &multiboot, &multiboot_obj, #ifdef LOADER_PREFER_AMD64 &amd64_elf, &amd64_elf_obj, #endif &i386_elf, &i386_elf_obj, #ifndef LOADER_PREFER_AMD64 &amd64_elf, &amd64_elf_obj, #endif NULL }; /* * Consoles * * We don't prototype these in libi386.h because they require * data structures from bootstrap.h as well. */ extern struct console vidconsole; extern struct console comconsole; #if defined(LOADER_FIREWIRE_SUPPORT) extern struct console dconsole; #endif extern struct console nullconsole; extern struct console spinconsole; struct console *consoles[] = { &vidconsole, &comconsole, #if defined(LOADER_FIREWIRE_SUPPORT) &dconsole, #endif &nullconsole, &spinconsole, NULL }; extern struct pnphandler isapnphandler; extern struct pnphandler biospnphandler; extern struct pnphandler biospcihandler; struct pnphandler *pnphandlers[] = { &biospnphandler, /* should go first, as it may set isapnp_readport */ &isapnphandler, &biospcihandler, NULL }; Index: head/stand/libsa/nandfs.c =================================================================== --- head/stand/libsa/nandfs.c (revision 349351) +++ head/stand/libsa/nandfs.c (nonexistent) @@ -1,1061 +0,0 @@ -/*- - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include "stand.h" -#include "string.h" -#include "zlib.h" - -#define DEBUG -#undef DEBUG -#ifdef DEBUG -#define NANDFS_DEBUG(fmt, args...) do { \ - printf("NANDFS_DEBUG:" fmt "\n", ##args); } while (0) -#else -#define NANDFS_DEBUG(fmt, args...) -#endif - -struct nandfs_mdt { - uint32_t entries_per_block; - uint32_t entries_per_group; - uint32_t blocks_per_group; - uint32_t groups_per_desc_block; /* desc is super group */ - uint32_t blocks_per_desc_block; /* desc is super group */ -}; - -struct bmap_buf { - LIST_ENTRY(bmap_buf) list; - nandfs_daddr_t blknr; - uint64_t *map; -}; - -struct nandfs_node { - struct nandfs_inode *inode; - LIST_HEAD(, bmap_buf) bmap_bufs; -}; -struct nandfs { - int nf_blocksize; - int nf_sectorsize; - int nf_cpno; - - struct open_file *nf_file; - struct nandfs_node *nf_opened_node; - u_int nf_offset; - uint8_t *nf_buf; - int64_t nf_buf_blknr; - - struct nandfs_fsdata *nf_fsdata; - struct nandfs_super_block *nf_sb; - struct nandfs_segment_summary nf_segsum; - struct nandfs_checkpoint nf_checkpoint; - struct nandfs_super_root nf_sroot; - struct nandfs_node nf_ifile; - struct nandfs_node nf_datfile; - struct nandfs_node nf_cpfile; - struct nandfs_mdt nf_datfile_mdt; - struct nandfs_mdt nf_ifile_mdt; - - int nf_nindir[NANDFS_NIADDR]; -}; - -static int nandfs_open(const char *, struct open_file *); -static int nandfs_close(struct open_file *); -static int nandfs_read(struct open_file *, void *, size_t, size_t *); -static off_t nandfs_seek(struct open_file *, off_t, int); -static int nandfs_stat(struct open_file *, struct stat *); -static int nandfs_readdir(struct open_file *, struct dirent *); - -static int nandfs_buf_read(struct nandfs *, void **, size_t *); -static struct nandfs_node *nandfs_lookup_path(struct nandfs *, const char *); -static int nandfs_read_inode(struct nandfs *, struct nandfs_node *, - nandfs_lbn_t, u_int, void *, int); -static int nandfs_read_blk(struct nandfs *, nandfs_daddr_t, void *, int); -static int nandfs_bmap_lookup(struct nandfs *, struct nandfs_node *, - nandfs_lbn_t, nandfs_daddr_t *, int); -static int nandfs_get_checkpoint(struct nandfs *, uint64_t, - struct nandfs_checkpoint *); -static nandfs_daddr_t nandfs_vtop(struct nandfs *, nandfs_daddr_t); -static void nandfs_calc_mdt_consts(int, struct nandfs_mdt *, int); -static void nandfs_mdt_trans(struct nandfs_mdt *, uint64_t, - nandfs_daddr_t *, uint32_t *); -static int ioread(struct open_file *, off_t, void *, u_int); -static int nandfs_probe_sectorsize(struct open_file *); - -struct fs_ops nandfs_fsops = { - "nandfs", - nandfs_open, - nandfs_close, - nandfs_read, - null_write, - nandfs_seek, - nandfs_stat, - nandfs_readdir -}; - -#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t)) - -/* from NetBSD's src/sys/net/if_ethersubr.c */ -static uint32_t -nandfs_crc32(uint32_t crc, const uint8_t *buf, size_t len) -{ - static const uint32_t crctab[] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, - 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, - 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c - }; - size_t i; - - crc = crc ^ ~0U; - for (i = 0; i < len; i++) { - crc ^= buf[i]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - crc = (crc >> 4) ^ crctab[crc & 0xf]; - } - return (crc ^ ~0U); -} - -static int -nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata) -{ - uint32_t fsdata_crc, comp_crc; - - if (fsdata->f_magic != NANDFS_FSDATA_MAGIC) - return (0); - - /* Preserve crc */ - fsdata_crc = fsdata->f_sum; - - /* Calculate */ - fsdata->f_sum = (0); - comp_crc = nandfs_crc32(0, (uint8_t *)fsdata, fsdata->f_bytes); - - /* Restore */ - fsdata->f_sum = fsdata_crc; - - /* Check CRC */ - return (fsdata_crc == comp_crc); -} - -static int -nandfs_check_superblock_crc(struct nandfs_fsdata *fsdata, - struct nandfs_super_block *super) -{ - uint32_t super_crc, comp_crc; - - /* Check super block magic */ - if (super->s_magic != NANDFS_SUPER_MAGIC) - return (0); - - /* Preserve CRC */ - super_crc = super->s_sum; - - /* Calculate */ - super->s_sum = (0); - comp_crc = nandfs_crc32(0, (uint8_t *)super, fsdata->f_sbbytes); - - /* Restore */ - super->s_sum = super_crc; - - /* Check CRC */ - return (super_crc == comp_crc); -} - -static int -nandfs_find_super_block(struct nandfs *fs, struct open_file *f) -{ - struct nandfs_super_block *sb; - int i, j, n, s; - int sectors_to_read, error; - - sb = malloc(fs->nf_sectorsize); - if (sb == NULL) - return (ENOMEM); - - memset(fs->nf_sb, 0, sizeof(*fs->nf_sb)); - - sectors_to_read = (NANDFS_NFSAREAS * fs->nf_fsdata->f_erasesize) / - fs->nf_sectorsize; - for (i = 0; i < sectors_to_read; i++) { - NANDFS_DEBUG("reading i %d offset %d\n", i, - i * fs->nf_sectorsize); - error = ioread(f, i * fs->nf_sectorsize, (char *)sb, - fs->nf_sectorsize); - if (error) { - NANDFS_DEBUG("error %d\n", error); - continue; - } - n = fs->nf_sectorsize / sizeof(struct nandfs_super_block); - s = 0; - if ((i * fs->nf_sectorsize) % fs->nf_fsdata->f_erasesize == 0) { - if (fs->nf_sectorsize == sizeof(struct nandfs_fsdata)) - continue; - else { - s += (sizeof(struct nandfs_fsdata) / - sizeof(struct nandfs_super_block)); - } - } - - for (j = s; j < n; j++) { - if (!nandfs_check_superblock_crc(fs->nf_fsdata, &sb[j])) - continue; - NANDFS_DEBUG("magic %x wtime %jd, lastcp 0x%jx\n", - sb[j].s_magic, sb[j].s_wtime, sb[j].s_last_cno); - if (sb[j].s_last_cno > fs->nf_sb->s_last_cno) - memcpy(fs->nf_sb, &sb[j], sizeof(*fs->nf_sb)); - } - } - - free(sb); - - return (fs->nf_sb->s_magic != 0 ? 0 : EINVAL); -} - -static int -nandfs_find_fsdata(struct nandfs *fs, struct open_file *f) -{ - int offset, error, i; - - NANDFS_DEBUG("starting\n"); - - offset = 0; - for (i = 0; i < 64 * NANDFS_NFSAREAS; i++) { - error = ioread(f, offset, (char *)fs->nf_fsdata, - sizeof(struct nandfs_fsdata)); - if (error) - return (error); - if (fs->nf_fsdata->f_magic == NANDFS_FSDATA_MAGIC) { - NANDFS_DEBUG("found at %x, volume %s\n", offset, - fs->nf_fsdata->f_volume_name); - if (nandfs_check_fsdata_crc(fs->nf_fsdata)) - break; - } - offset += fs->nf_sectorsize; - } - - return (error); -} - -static int -nandfs_read_structures(struct nandfs *fs, struct open_file *f) -{ - int error; - - error = nandfs_find_fsdata(fs, f); - if (error) - return (error); - - error = nandfs_find_super_block(fs, f); - - if (error == 0) - NANDFS_DEBUG("selected sb with w_time %jd last_pseg %jx\n", - fs->nf_sb->s_wtime, fs->nf_sb->s_last_pseg); - - return (error); -} - -static int -nandfs_mount(struct nandfs *fs, struct open_file *f) -{ - int err = 0, level; - uint64_t last_pseg; - - fs->nf_fsdata = malloc(sizeof(struct nandfs_fsdata)); - fs->nf_sb = malloc(sizeof(struct nandfs_super_block)); - - err = nandfs_read_structures(fs, f); - if (err) { - free(fs->nf_fsdata); - free(fs->nf_sb); - return (err); - } - - fs->nf_blocksize = 1 << (fs->nf_fsdata->f_log_block_size + 10); - - NANDFS_DEBUG("using superblock with wtime %jd\n", fs->nf_sb->s_wtime); - - fs->nf_cpno = fs->nf_sb->s_last_cno; - last_pseg = fs->nf_sb->s_last_pseg; - - /* - * Calculate indirect block levels. - */ - nandfs_daddr_t mult; - - mult = 1; - for (level = 0; level < NANDFS_NIADDR; level++) { - mult *= NINDIR(fs); - fs->nf_nindir[level] = mult; - } - - nandfs_calc_mdt_consts(fs->nf_blocksize, &fs->nf_datfile_mdt, - fs->nf_fsdata->f_dat_entry_size); - - nandfs_calc_mdt_consts(fs->nf_blocksize, &fs->nf_ifile_mdt, - fs->nf_fsdata->f_inode_size); - - err = ioread(f, last_pseg * fs->nf_blocksize, &fs->nf_segsum, - sizeof(struct nandfs_segment_summary)); - if (err) { - free(fs->nf_sb); - free(fs->nf_fsdata); - return (err); - } - - err = ioread(f, (last_pseg + fs->nf_segsum.ss_nblocks - 1) * - fs->nf_blocksize, &fs->nf_sroot, sizeof(struct nandfs_super_root)); - if (err) { - free(fs->nf_sb); - free(fs->nf_fsdata); - return (err); - } - - fs->nf_datfile.inode = &fs->nf_sroot.sr_dat; - LIST_INIT(&fs->nf_datfile.bmap_bufs); - fs->nf_cpfile.inode = &fs->nf_sroot.sr_cpfile; - LIST_INIT(&fs->nf_cpfile.bmap_bufs); - - err = nandfs_get_checkpoint(fs, fs->nf_cpno, &fs->nf_checkpoint); - if (err) { - free(fs->nf_sb); - free(fs->nf_fsdata); - return (err); - } - - NANDFS_DEBUG("checkpoint cp_cno=%lld\n", fs->nf_checkpoint.cp_cno); - NANDFS_DEBUG("checkpoint cp_inodes_count=%lld\n", - fs->nf_checkpoint.cp_inodes_count); - NANDFS_DEBUG("checkpoint cp_ifile_inode.i_blocks=%lld\n", - fs->nf_checkpoint.cp_ifile_inode.i_blocks); - - fs->nf_ifile.inode = &fs->nf_checkpoint.cp_ifile_inode; - LIST_INIT(&fs->nf_ifile.bmap_bufs); - return (0); -} - -#define NINDIR(fs) ((fs)->nf_blocksize / sizeof(nandfs_daddr_t)) - -static int -nandfs_open(const char *path, struct open_file *f) -{ - struct nandfs *fs; - struct nandfs_node *node; - int err, bsize, level; - - NANDFS_DEBUG("nandfs_open('%s', %p)\n", path, f); - - fs = malloc(sizeof(struct nandfs)); - f->f_fsdata = fs; - fs->nf_file = f; - - bsize = nandfs_probe_sectorsize(f); - if (bsize < 0) { - printf("Cannot probe medium sector size\n"); - return (EINVAL); - } - - fs->nf_sectorsize = bsize; - - /* - * Calculate indirect block levels. - */ - nandfs_daddr_t mult; - - mult = 1; - for (level = 0; level < NANDFS_NIADDR; level++) { - mult *= NINDIR(fs); - fs->nf_nindir[level] = mult; - } - - NANDFS_DEBUG("fs %p nf_sectorsize=%x\n", fs, fs->nf_sectorsize); - - err = nandfs_mount(fs, f); - if (err) { - NANDFS_DEBUG("Cannot mount nandfs: %s\n", strerror(err)); - return (err); - } - - node = nandfs_lookup_path(fs, path); - if (node == NULL) - return (EINVAL); - - fs->nf_offset = 0; - fs->nf_buf = NULL; - fs->nf_buf_blknr = -1; - fs->nf_opened_node = node; - LIST_INIT(&fs->nf_opened_node->bmap_bufs); - return (0); -} - -static void -nandfs_free_node(struct nandfs_node *node) -{ - struct bmap_buf *bmap, *tmp; - - free(node->inode); - LIST_FOREACH_SAFE(bmap, &node->bmap_bufs, list, tmp) { - LIST_REMOVE(bmap, list); - free(bmap->map); - free(bmap); - } - free(node); -} - -static int -nandfs_close(struct open_file *f) -{ - struct nandfs *fs = f->f_fsdata; - - NANDFS_DEBUG("nandfs_close(%p)\n", f); - - if (fs->nf_buf != NULL) - free(fs->nf_buf); - - nandfs_free_node(fs->nf_opened_node); - free(fs->nf_sb); - free(fs); - return (0); -} - -static int -nandfs_read(struct open_file *f, void *addr, size_t size, size_t *resid) -{ - struct nandfs *fs = (struct nandfs *)f->f_fsdata; - size_t csize, buf_size; - void *buf; - int error = 0; - - NANDFS_DEBUG("nandfs_read(file=%p, addr=%p, size=%d)\n", f, addr, size); - - while (size != 0) { - if (fs->nf_offset >= fs->nf_opened_node->inode->i_size) - break; - - error = nandfs_buf_read(fs, &buf, &buf_size); - if (error) - break; - - csize = size; - if (csize > buf_size) - csize = buf_size; - - bcopy(buf, addr, csize); - - fs->nf_offset += csize; - addr = (char *)addr + csize; - size -= csize; - } - - if (resid) - *resid = size; - return (error); -} - -static off_t -nandfs_seek(struct open_file *f, off_t offset, int where) -{ - struct nandfs *fs = f->f_fsdata; - off_t off; - u_int size; - - NANDFS_DEBUG("nandfs_seek(file=%p, offset=%lld, where=%d)\n", f, - offset, where); - - size = fs->nf_opened_node->inode->i_size; - - switch (where) { - case SEEK_SET: - off = 0; - break; - case SEEK_CUR: - off = fs->nf_offset; - break; - case SEEK_END: - off = size; - break; - default: - errno = EINVAL; - return (-1); - } - - off += offset; - if (off < 0 || off > size) { - errno = EINVAL; - return(-1); - } - - fs->nf_offset = (u_int)off; - - return (off); -} - -static int -nandfs_stat(struct open_file *f, struct stat *sb) -{ - struct nandfs *fs = f->f_fsdata; - - NANDFS_DEBUG("nandfs_stat(file=%p, stat=%p)\n", f, sb); - - sb->st_size = fs->nf_opened_node->inode->i_size; - sb->st_mode = fs->nf_opened_node->inode->i_mode; - sb->st_uid = fs->nf_opened_node->inode->i_uid; - sb->st_gid = fs->nf_opened_node->inode->i_gid; - return (0); -} - -static int -nandfs_readdir(struct open_file *f, struct dirent *d) -{ - struct nandfs *fs = f->f_fsdata; - struct nandfs_dir_entry *dirent; - void *buf; - size_t buf_size; - - NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)\n", f, d); - - if (fs->nf_offset >= fs->nf_opened_node->inode->i_size) { - NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p) ENOENT\n", - f, d); - return (ENOENT); - } - - if (nandfs_buf_read(fs, &buf, &buf_size)) { - NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p)" - "buf_read failed\n", f, d); - return (EIO); - } - - NANDFS_DEBUG("nandfs_readdir(file=%p, dirent=%p) moving forward\n", - f, d); - - dirent = (struct nandfs_dir_entry *)buf; - fs->nf_offset += dirent->rec_len; - strncpy(d->d_name, dirent->name, dirent->name_len); - d->d_name[dirent->name_len] = '\0'; - d->d_type = dirent->file_type; - return (0); -} - -static int -nandfs_buf_read(struct nandfs *fs, void **buf_p, size_t *size_p) -{ - nandfs_daddr_t blknr, blkoff; - - blknr = fs->nf_offset / fs->nf_blocksize; - blkoff = fs->nf_offset % fs->nf_blocksize; - - if (blknr != fs->nf_buf_blknr) { - if (fs->nf_buf == NULL) - fs->nf_buf = malloc(fs->nf_blocksize); - - if (nandfs_read_inode(fs, fs->nf_opened_node, blknr, 1, - fs->nf_buf, 0)) - return (EIO); - - fs->nf_buf_blknr = blknr; - } - - *buf_p = fs->nf_buf + blkoff; - *size_p = fs->nf_blocksize - blkoff; - - NANDFS_DEBUG("nandfs_buf_read buf_p=%p size_p=%d\n", *buf_p, *size_p); - - if (*size_p > fs->nf_opened_node->inode->i_size - fs->nf_offset) - *size_p = fs->nf_opened_node->inode->i_size - fs->nf_offset; - - return (0); -} - -static struct nandfs_node * -nandfs_lookup_node(struct nandfs *fs, uint64_t ino) -{ - uint64_t blocknr; - int entrynr; - struct nandfs_inode *buffer; - struct nandfs_node *node; - struct nandfs_inode *inode; - - NANDFS_DEBUG("nandfs_lookup_node ino=%lld\n", ino); - - if (ino == 0) { - printf("nandfs_lookup_node: invalid inode requested\n"); - return (NULL); - } - - buffer = malloc(fs->nf_blocksize); - inode = malloc(sizeof(struct nandfs_inode)); - node = malloc(sizeof(struct nandfs_node)); - - nandfs_mdt_trans(&fs->nf_ifile_mdt, ino, &blocknr, &entrynr); - - if (nandfs_read_inode(fs, &fs->nf_ifile, blocknr, 1, buffer, 0)) - return (NULL); - - memcpy(inode, &buffer[entrynr], sizeof(struct nandfs_inode)); - node->inode = inode; - free(buffer); - return (node); -} - -static struct nandfs_node * -nandfs_lookup_path(struct nandfs *fs, const char *path) -{ - struct nandfs_node *node; - struct nandfs_dir_entry *dirent; - char *namebuf; - uint64_t i, done, pinode, inode; - int nlinks = 0, counter, len, link_len, nameidx; - uint8_t *buffer, *orig; - char *strp, *lpath; - - buffer = malloc(fs->nf_blocksize); - orig = buffer; - - namebuf = malloc(2 * MAXPATHLEN + 2); - strncpy(namebuf, path, MAXPATHLEN); - namebuf[MAXPATHLEN] = '\0'; - done = nameidx = 0; - lpath = namebuf; - - /* Get the root inode */ - node = nandfs_lookup_node(fs, NANDFS_ROOT_INO); - inode = NANDFS_ROOT_INO; - - while ((strp = strsep(&lpath, "/")) != NULL) { - if (*strp == '\0') - continue; - if ((node->inode->i_mode & IFMT) != IFDIR) { - nandfs_free_node(node); - node = NULL; - goto out; - } - - len = strlen(strp); - NANDFS_DEBUG("%s: looking for %s\n", __func__, strp); - for (i = 0; i < node->inode->i_blocks; i++) { - if (nandfs_read_inode(fs, node, i, 1, orig, 0)) { - node = NULL; - goto out; - } - - buffer = orig; - done = counter = 0; - while (1) { - dirent = - (struct nandfs_dir_entry *)(void *)buffer; - NANDFS_DEBUG("%s: dirent.name = %s\n", - __func__, dirent->name); - NANDFS_DEBUG("%s: dirent.rec_len = %d\n", - __func__, dirent->rec_len); - NANDFS_DEBUG("%s: dirent.inode = %lld\n", - __func__, dirent->inode); - if (len == dirent->name_len && - (strncmp(strp, dirent->name, len) == 0) && - dirent->inode != 0) { - nandfs_free_node(node); - node = nandfs_lookup_node(fs, - dirent->inode); - pinode = inode; - inode = dirent->inode; - done = 1; - break; - } - - counter += dirent->rec_len; - buffer += dirent->rec_len; - - if (counter == fs->nf_blocksize) - break; - } - - if (done) - break; - } - - if (!done) { - node = NULL; - goto out; - } - - NANDFS_DEBUG("%s: %.*s has mode %o\n", __func__, - dirent->name_len, dirent->name, node->inode->i_mode); - - if ((node->inode->i_mode & IFMT) == IFLNK) { - NANDFS_DEBUG("%s: %.*s is symlink\n", - __func__, dirent->name_len, dirent->name); - link_len = node->inode->i_size; - - if (++nlinks > MAXSYMLINKS) { - nandfs_free_node(node); - node = NULL; - goto out; - } - - if (nandfs_read_inode(fs, node, 0, 1, orig, 0)) { - nandfs_free_node(node); - node = NULL; - goto out; - } - - NANDFS_DEBUG("%s: symlink is %.*s\n", - __func__, link_len, (char *)orig); - - nameidx = (nameidx == 0) ? MAXPATHLEN + 1 : 0; - bcopy((char *)orig, namebuf + nameidx, - (unsigned)link_len); - if (lpath != NULL) { - namebuf[nameidx + link_len++] = '/'; - strncpy(namebuf + nameidx + link_len, lpath, - MAXPATHLEN - link_len); - namebuf[nameidx + MAXPATHLEN] = '\0'; - } else - namebuf[nameidx + link_len] = '\0'; - - NANDFS_DEBUG("%s: strp=%s, lpath=%s, namebuf0=%s, " - "namebuf1=%s, idx=%d\n", __func__, strp, lpath, - namebuf + 0, namebuf + MAXPATHLEN + 1, nameidx); - - lpath = namebuf + nameidx; - - nandfs_free_node(node); - - /* - * If absolute pathname, restart at root. Otherwise - * continue with out parent inode. - */ - inode = (orig[0] == '/') ? NANDFS_ROOT_INO : pinode; - node = nandfs_lookup_node(fs, inode); - } - } - -out: - free(namebuf); - free(orig); - return (node); -} - -static int -nandfs_read_inode(struct nandfs *fs, struct nandfs_node *node, - nandfs_daddr_t blknr, u_int nblks, void *buf, int raw) -{ - uint64_t *pblks; - uint64_t *vblks; - u_int i; - int error; - - pblks = malloc(nblks * sizeof(uint64_t)); - vblks = malloc(nblks * sizeof(uint64_t)); - - NANDFS_DEBUG("nandfs_read_inode fs=%p node=%p blknr=%lld nblks=%d\n", - fs, node, blknr, nblks); - for (i = 0; i < nblks; i++) { - error = nandfs_bmap_lookup(fs, node, blknr + i, &vblks[i], raw); - if (error) { - free(pblks); - free(vblks); - return (error); - } - if (raw == 0) - pblks[i] = nandfs_vtop(fs, vblks[i]); - else - pblks[i] = vblks[i]; - } - - for (i = 0; i < nblks; i++) { - if (ioread(fs->nf_file, pblks[i] * fs->nf_blocksize, buf, - fs->nf_blocksize)) { - free(pblks); - free(vblks); - return (EIO); - } - - buf = (void *)((uintptr_t)buf + fs->nf_blocksize); - } - - free(pblks); - free(vblks); - return (0); -} - -static int -nandfs_read_blk(struct nandfs *fs, nandfs_daddr_t blknr, void *buf, int phys) -{ - uint64_t pblknr; - - pblknr = (phys ? blknr : nandfs_vtop(fs, blknr)); - - return (ioread(fs->nf_file, pblknr * fs->nf_blocksize, buf, - fs->nf_blocksize)); -} - -static int -nandfs_get_checkpoint(struct nandfs *fs, uint64_t cpno, - struct nandfs_checkpoint *cp) -{ - uint64_t blocknr; - int blockoff, cp_per_block, dlen; - uint8_t *buf; - - NANDFS_DEBUG("nandfs_get_checkpoint(fs=%p cpno=%lld)\n", fs, cpno); - - buf = malloc(fs->nf_blocksize); - - cpno += NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET - 1; - dlen = fs->nf_fsdata->f_checkpoint_size; - cp_per_block = fs->nf_blocksize / dlen; - blocknr = cpno / cp_per_block; - blockoff = (cpno % cp_per_block) * dlen; - - if (nandfs_read_inode(fs, &fs->nf_cpfile, blocknr, 1, buf, 0)) { - free(buf); - return (EINVAL); - } - - memcpy(cp, buf + blockoff, sizeof(struct nandfs_checkpoint)); - free(buf); - - return (0); -} - -static uint64_t * -nandfs_get_map(struct nandfs *fs, struct nandfs_node *node, nandfs_daddr_t blknr, - int phys) -{ - struct bmap_buf *bmap; - uint64_t *map; - - LIST_FOREACH(bmap, &node->bmap_bufs, list) { - if (bmap->blknr == blknr) - return (bmap->map); - } - - map = malloc(fs->nf_blocksize); - if (nandfs_read_blk(fs, blknr, map, phys)) { - free(map); - return (NULL); - } - - bmap = malloc(sizeof(struct bmap_buf)); - bmap->blknr = blknr; - bmap->map = map; - - LIST_INSERT_HEAD(&node->bmap_bufs, bmap, list); - - NANDFS_DEBUG("%s:(node=%p, map=%p)\n", __func__, node, map); - return (map); -} - -static int -nandfs_bmap_lookup(struct nandfs *fs, struct nandfs_node *node, - nandfs_lbn_t lblknr, nandfs_daddr_t *vblknr, int phys) -{ - struct nandfs_inode *ino; - nandfs_daddr_t ind_block_num; - uint64_t *map; - int idx; - int level; - - ino = node->inode; - - if (lblknr < NANDFS_NDADDR) { - *vblknr = ino->i_db[lblknr]; - return (0); - } - - lblknr -= NANDFS_NDADDR; - - /* - * nindir[0] = NINDIR - * nindir[1] = NINDIR**2 - * nindir[2] = NINDIR**3 - * etc - */ - for (level = 0; level < NANDFS_NIADDR; level++) { - NANDFS_DEBUG("lblknr=%jx fs->nf_nindir[%d]=%d\n", lblknr, level, fs->nf_nindir[level]); - if (lblknr < fs->nf_nindir[level]) - break; - lblknr -= fs->nf_nindir[level]; - } - - if (level == NANDFS_NIADDR) { - /* Block number too high */ - NANDFS_DEBUG("lblknr %jx too high\n", lblknr); - return (EFBIG); - } - - ind_block_num = ino->i_ib[level]; - - for (; level >= 0; level--) { - if (ind_block_num == 0) { - *vblknr = 0; /* missing */ - return (0); - } - - 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) - return (EIO); - - if (level > 0) { - idx = lblknr / fs->nf_nindir[level - 1]; - lblknr %= fs->nf_nindir[level - 1]; - } else - idx = lblknr; - - ind_block_num = ((nandfs_daddr_t *)map)[idx]; - } - - *vblknr = ind_block_num; - - return (0); -} - -static nandfs_daddr_t -nandfs_vtop(struct nandfs *fs, nandfs_daddr_t vblocknr) -{ - nandfs_lbn_t blocknr; - nandfs_daddr_t pblocknr; - int entrynr; - struct nandfs_dat_entry *dat; - - dat = malloc(fs->nf_blocksize); - nandfs_mdt_trans(&fs->nf_datfile_mdt, vblocknr, &blocknr, &entrynr); - - if (nandfs_read_inode(fs, &fs->nf_datfile, blocknr, 1, dat, 1)) { - free(dat); - return (0); - } - - NANDFS_DEBUG("nandfs_vtop entrynr=%d vblocknr=%lld pblocknr=%lld\n", - entrynr, vblocknr, dat[entrynr].de_blocknr); - - pblocknr = dat[entrynr].de_blocknr; - free(dat); - return (pblocknr); -} - -static void -nandfs_calc_mdt_consts(int blocksize, struct nandfs_mdt *mdt, int entry_size) -{ - - mdt->entries_per_group = blocksize * 8; /* bits in sector */ - mdt->entries_per_block = blocksize / entry_size; - mdt->blocks_per_group = - (mdt->entries_per_group -1) / mdt->entries_per_block + 1 + 1; - mdt->groups_per_desc_block = - blocksize / sizeof(struct nandfs_block_group_desc); - mdt->blocks_per_desc_block = - mdt->groups_per_desc_block * mdt->blocks_per_group + 1; -} - -static void -nandfs_mdt_trans(struct nandfs_mdt *mdt, uint64_t index, - nandfs_daddr_t *blocknr, uint32_t *entry_in_block) -{ - nandfs_daddr_t blknr; - uint64_t group, group_offset, blocknr_in_group; - uint64_t desc_block, desc_offset; - - /* Calculate our offset in the file */ - group = index / mdt->entries_per_group; - group_offset = index % mdt->entries_per_group; - desc_block = group / mdt->groups_per_desc_block; - desc_offset = group % mdt->groups_per_desc_block; - blocknr_in_group = group_offset / mdt->entries_per_block; - - /* To descgroup offset */ - blknr = 1 + desc_block * mdt->blocks_per_desc_block; - - /* To group offset */ - blknr += desc_offset * mdt->blocks_per_group; - - /* To actual file block */ - blknr += 1 + blocknr_in_group; - - *blocknr = blknr; - *entry_in_block = group_offset % mdt->entries_per_block; -} - -static int -ioread(struct open_file *f, off_t pos, void *buf, u_int length) -{ - void *buffer; - int err; - int bsize = ((struct nandfs *)f->f_fsdata)->nf_sectorsize; - u_int off, nsec; - - off = pos % bsize; - pos /= bsize; - nsec = howmany(length, bsize); - - NANDFS_DEBUG("pos=%lld length=%d off=%d nsec=%d\n", pos, length, - off, nsec); - - buffer = malloc(nsec * bsize); - - err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, pos, - nsec * bsize, buffer, NULL); - - memcpy(buf, (void *)((uintptr_t)buffer + off), length); - free(buffer); - - return (err); -} - -static int -nandfs_probe_sectorsize(struct open_file *f) -{ - void *buffer; - int i, err; - - buffer = malloc(16 * 1024); - - NANDFS_DEBUG("probing for sector size: "); - - for (i = 512; i < (16 * 1024); i <<= 1) { - NANDFS_DEBUG("%d ", i); - err = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, 0, i, - buffer, NULL); - - if (err == 0) { - NANDFS_DEBUG("found"); - free(buffer); - return (i); - } - } - - free(buffer); - NANDFS_DEBUG("not found\n"); - return (-1); -} Property changes on: head/stand/libsa/nandfs.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/stand/libsa/Makefile =================================================================== --- head/stand/libsa/Makefile (revision 349351) +++ head/stand/libsa/Makefile (revision 349352) @@ -1,177 +1,174 @@ # $FreeBSD$ # Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $ # # Notes: # - We don't use the libc strerror/sys_errlist because the string table is # quite large. # .include LIBSA_CPUARCH?=${MACHINE_CPUARCH} LIBC_SRC= ${SRCTOP}/lib/libc LIB?= sa # standalone components and stuff we have modified locally SRCS+= gzguts.h zutil.h __main.c abort.c assert.c bcd.c environment.c getopt.c gets.c \ globals.c pager.c panic.c printf.c strdup.c strerror.c \ random.c sbrk.c twiddle.c zalloc.c zalloc_malloc.c # private (pruned) versions of libc string functions SRCS+= strcasecmp.c .PATH: ${LIBC_SRC}/net SRCS+= ntoh.c # string functions from libc .PATH: ${LIBC_SRC}/string SRCS+= bcmp.c bcopy.c bzero.c ffs.c fls.c \ memccpy.c memchr.c memcmp.c memcpy.c memmove.c memset.c \ qdivrem.c strcat.c strchr.c strcmp.c strcpy.c stpcpy.c stpncpy.c \ strcspn.c strlcat.c strlcpy.c strlen.c strncat.c strncmp.c strncpy.c \ strnlen.c strpbrk.c strrchr.c strsep.c strspn.c strstr.c strtok.c swab.c # stdlib functions from libc .PATH: ${LIBC_SRC}/stdlib SRCS+= abs.c strtol.c strtoll.c strtoul.c strtoull.c # common boot code .PATH: ${SYSDIR}/kern SRCS+= subr_boot.c .if ${MACHINE_CPUARCH} == "arm" .PATH: ${LIBC_SRC}/arm/gen # Do not generate movt/movw, because the relocation fixup for them does not # translate to the -Bsymbolic -pie format required by self_reloc() in loader(8). # Also, the fpu is not available in a standalone environment. .if ${COMPILER_VERSION} < 30800 CFLAGS.clang+= -mllvm -arm-use-movt=0 .else CFLAGS.clang+= -mno-movt .endif CFLAGS.clang+= -mfpu=none # Compiler support functions .PATH: ${SRCTOP}/contrib/compiler-rt/lib/builtins/ # __clzsi2 and ctzsi2 for various builtin functions SRCS+= clzsi2.c ctzsi2.c # Divide and modulus functions called by the compiler SRCS+= divmoddi4.c divmodsi4.c divdi3.c divsi3.c moddi3.c modsi3.c SRCS+= udivmoddi4.c udivmodsi4.c udivdi3.c udivsi3.c umoddi3.c umodsi3.c .PATH: ${SRCTOP}/contrib/compiler-rt/lib/builtins/arm/ SRCS+= aeabi_idivmod.S aeabi_ldivmod.S aeabi_uidivmod.S aeabi_uldivmod.S SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "riscv" .PATH: ${LIBC_SRC}/${MACHINE_CPUARCH}/gen .endif .if ${MACHINE_CPUARCH} == "powerpc" .PATH: ${LIBC_SRC}/quad SRCS+= ashldi3.c ashrdi3.c lshrdi3.c SRCS+= syncicache.c .endif .if ${MACHINE_CPUARCH} == "mips" .PATH: ${LIBC_SRC}/quad SRCS+= ashldi3.c ashrdi3.c lshrdi3.c .endif # uuid functions from libc .PATH: ${LIBC_SRC}/uuid SRCS+= uuid_create_nil.c uuid_equal.c uuid_from_string.c uuid_is_nil.c uuid_to_string.c # _setjmp/_longjmp .PATH: ${SASRC}/${LIBSA_CPUARCH} SRCS+= _setjmp.S # decompression functionality from libbz2 # NOTE: to actually test this functionality after libbz2 upgrade compile # loader(8) with LOADER_BZIP2_SUPPORT defined .PATH: ${SRCTOP}/contrib/bzip2 CFLAGS+= -DBZ_NO_STDIO -DBZ_NO_COMPRESS SRCS+=bzlib.c crctable.c decompress.c huffman.c randtable.c # decompression functionality from zlib .PATH: ${SRCTOP}/sys/contrib/zlib CFLAGS+=-DHAVE_MEMCPY -I${SRCTOP}/sys/contrib/zlib SRCS+= adler32.c crc32.c SRCS+= infback.c inffast.c inflate.c inftrees.c zutil.c # Create a subset of includes that are safe, as well as adjusting those that aren't # The lists may drive people nuts, but they are explicitly opt-in FAKE_DIRS=xlocale arpa SAFE_INCS=a.out.h assert.h elf.h limits.h nlist.h setjmp.h stddef.h stdbool.h string.h strings.h time.h unistd.h uuid.h STAND_H_INC=ctype.h fcntl.h signal.h stdio.h stdlib.h OTHER_INC=stdarg.h errno.h stdint.h beforedepend: mkdir -p ${FAKE_DIRS}; \ for i in ${SAFE_INCS}; do \ ln -sf ${SRCTOP}/include/$$i $$i; \ done; \ ln -sf ${SYSDIR}/${MACHINE}/include/stdarg.h stdarg.h; \ ln -sf ${SYSDIR}/sys/errno.h errno.h; \ ln -sf ${SYSDIR}/sys/stdint.h stdint.h; \ ln -sf ${SRCTOP}/include/arpa/inet.h arpa/inet.h; \ ln -sf ${SRCTOP}/include/arpa/tftp.h arpa/tftp.h; \ for i in _time.h _strings.h _string.h; do \ [ -f xlocale/$$i ] || cp /dev/null xlocale/$$i; \ done; \ for i in ${STAND_H_INC}; do \ ln -sf ${SASRC}/stand.h $$i; \ done CLEANDIRS+=${FAKE_DIRS} CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC} # io routines SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \ fstat.c close.c lseek.c open.c read.c write.c readdir.c # network routines SRCS+= arp.c ether.c ip.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c # network info services: SRCS+= bootp.c rarp.c bootparam.c # boot filesystems SRCS+= ufs.c nfs.c cd9660.c tftp.c gzipfs.c bzipfs.c SRCS+= dosfs.c ext2fs.c SRCS+= splitfs.c SRCS+= pkgfs.c -.if ${MK_NAND} != "no" -SRCS+= nandfs.c -.endif # kernel ufs support .PATH: ${SRCTOP}/sys/ufs/ffs SRCS+=ffs_subr.c ffs_tables.c CFLAGS.bzipfs.c+= -I${SRCTOP}/contrib/bzip2 # explicit_bzero and calculate_crc32c .PATH: ${SYSDIR}/libkern SRCS+= explicit_bzero.c crc32_libkern.c # Maybe GELI .if ${MK_LOADER_GELI} == "yes" .include "${SASRC}/geli/Makefile.inc" .endif .if ${MK_LOADER_VERIEXEC} == "yes" && ${MK_BEARSSL} == "yes" .include "${SRCTOP}/lib/libbearssl/Makefile.libsa.inc" .include "${SRCTOP}/lib/libsecureboot/Makefile.libsa.inc" .endif # Maybe ZFS .if ${MK_LOADER_ZFS} == "yes" .include "${SASRC}/zfs/Makefile.inc" .endif .include Index: head/stand/libsa/stand.h =================================================================== --- head/stand/libsa/stand.h (revision 349351) +++ head/stand/libsa/stand.h (revision 349352) @@ -1,450 +1,449 @@ /* * Copyright (c) 1998 Michael Smith. * 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$ * From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $ */ /*- * Copyright (c) 1993 * The Regents of the University of California. 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 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. * * @(#)stand.h 8.1 (Berkeley) 6/11/93 */ #ifndef STAND_H #define STAND_H #include #include #include #include /* this header intentionally exports NULL from */ #include #define strcoll(a, b) strcmp((a), (b)) #define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args) #define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __func__, __LINE__ , ##args); getchar();} #include /* special stand error codes */ #define EADAPT (ELAST+1) /* bad adaptor */ #define ECTLR (ELAST+2) /* bad controller */ #define EUNIT (ELAST+3) /* bad unit */ #define ESLICE (ELAST+4) /* bad slice */ #define EPART (ELAST+5) /* bad partition */ #define ERDLAB (ELAST+6) /* can't read disk label */ #define EUNLAB (ELAST+7) /* unlabeled disk */ #define EOFFSET (ELAST+8) /* relative seek not supported */ #define ESALAST (ELAST+8) /* */ /* Partial signal emulation for sig_atomic_t */ #include struct open_file; /* * This structure is used to define file system operations in a file system * independent way. * * XXX note that filesystem providers should export a pointer to their fs_ops * struct, so that consumers can reference this and thus include the * filesystems that they require. */ struct fs_ops { const char *fs_name; int (*fo_open)(const char *path, struct open_file *f); int (*fo_close)(struct open_file *f); int (*fo_read)(struct open_file *f, void *buf, size_t size, size_t *resid); int (*fo_write)(struct open_file *f, const void *buf, size_t size, size_t *resid); off_t (*fo_seek)(struct open_file *f, off_t offset, int where); int (*fo_stat)(struct open_file *f, struct stat *sb); int (*fo_readdir)(struct open_file *f, struct dirent *d); }; /* * libstand-supplied filesystems */ extern struct fs_ops ufs_fsops; extern struct fs_ops tftp_fsops; extern struct fs_ops nfs_fsops; extern struct fs_ops cd9660_fsops; -extern struct fs_ops nandfs_fsops; extern struct fs_ops gzipfs_fsops; extern struct fs_ops bzipfs_fsops; extern struct fs_ops dosfs_fsops; extern struct fs_ops ext2fs_fsops; extern struct fs_ops splitfs_fsops; extern struct fs_ops pkgfs_fsops; extern struct fs_ops efihttp_fsops; /* where values for lseek(2) */ #define SEEK_SET 0 /* set file offset to offset */ #define SEEK_CUR 1 /* set file offset to current plus offset */ #define SEEK_END 2 /* set file offset to EOF plus offset */ /* * Device switch */ struct devsw { const char dv_name[8]; int dv_type; /* opaque type constant, arch-dependant */ #define DEVT_NONE 0 #define DEVT_DISK 1 #define DEVT_NET 2 #define DEVT_CD 3 #define DEVT_ZFS 4 #define DEVT_FD 5 int (*dv_init)(void); /* early probe call */ int (*dv_strategy)(void *devdata, int rw, daddr_t blk, size_t size, char *buf, size_t *rsize); int (*dv_open)(struct open_file *f, ...); int (*dv_close)(struct open_file *f); int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data); int (*dv_print)(int verbose); /* print device information */ void (*dv_cleanup)(void); }; /* * libstand-supplied device switch */ extern struct devsw netdev; extern int errno; /* * Generic device specifier; architecture-dependent * versions may be larger, but should be allowed to * overlap. */ struct devdesc { struct devsw *d_dev; int d_unit; void *d_opendata; }; struct open_file { int f_flags; /* see F_* below */ struct devsw *f_dev; /* pointer to device operations */ void *f_devdata; /* device specific data */ struct fs_ops *f_ops; /* pointer to file system operations */ void *f_fsdata; /* file system specific data */ off_t f_offset; /* current file offset */ char *f_rabuf; /* readahead buffer pointer */ size_t f_ralen; /* valid data in readahead buffer */ off_t f_raoffset; /* consumer offset in readahead buffer */ #define SOPEN_RASIZE 512 }; #define SOPEN_MAX 64 extern struct open_file files[]; /* f_flags values */ #define F_READ 0x0001 /* file opened for reading */ #define F_WRITE 0x0002 /* file opened for writing */ #define F_RAW 0x0004 /* raw device open - no file system */ #define F_NODEV 0x0008 /* network open - no device */ #define F_MASK 0xFFFF /* Mode modifier for strategy() */ #define F_NORA (0x01 << 16) /* Disable Read-Ahead */ #define isascii(c) (((c) & ~0x7F) == 0) static __inline int isupper(int c) { return c >= 'A' && c <= 'Z'; } static __inline int islower(int c) { return c >= 'a' && c <= 'z'; } static __inline int isspace(int c) { return c == ' ' || (c >= 0x9 && c <= 0xd); } static __inline int isdigit(int c) { return c >= '0' && c <= '9'; } static __inline int isxdigit(int c) { return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } static __inline int isalpha(int c) { return isupper(c) || islower(c); } static __inline int isalnum(int c) { return isalpha(c) || isdigit(c); } static __inline int iscntrl(int c) { return (c >= 0 && c < ' ') || c == 127; } static __inline int isgraph(int c) { return c >= '!' && c <= '~'; } static __inline int ispunct(int c) { return (c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~'); } static __inline int toupper(int c) { return islower(c) ? c - 'a' + 'A' : c; } static __inline int tolower(int c) { return isupper(c) ? c - 'A' + 'a' : c; } /* sbrk emulation */ extern void setheap(void *base, void *top); extern char *sbrk(int incr); extern void *reallocf(void *ptr, size_t size); extern void mallocstats(void); extern int printf(const char *fmt, ...) __printflike(1, 2); extern int asprintf(char **buf, const char *cfmt, ...) __printflike(2, 3); 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 int vprintf(const char *fmt, __va_list); extern int vsprintf(char *buf, const char *cfmt, __va_list); extern int vsnprintf(char *buf, size_t size, const char *cfmt, __va_list); extern void twiddle(u_int callerdiv); extern void twiddle_divisor(u_int globaldiv); extern void ngets(char *, int); #define gets(x) ngets((x), 0) extern int fgetstr(char *buf, int size, int fd); extern int open(const char *, int); #define O_RDONLY 0x0 #define O_WRONLY 0x1 #define O_RDWR 0x2 #define O_ACCMODE 0x3 /* NOT IMPLEMENTED */ #define O_CREAT 0x0200 /* create if nonexistent */ #define O_TRUNC 0x0400 /* truncate to zero length */ extern int close(int); extern void closeall(void); extern ssize_t read(int, void *, size_t); extern ssize_t write(int, const void *, size_t); extern struct dirent *readdirfd(int); extern void srandom(unsigned int); extern long random(void); /* imports from stdlib, locally modified */ extern char *optarg; /* getopt(3) external variables */ extern int optind, opterr, optopt, optreset; extern int getopt(int, char * const [], const char *); /* pager.c */ extern void pager_open(void); extern void pager_close(void); extern int pager_output(const char *lines); extern int pager_file(const char *fname); /* No signal state to preserve */ #define setjmp _setjmp #define longjmp _longjmp /* environment.c */ #define EV_DYNAMIC (1<<0) /* value was dynamically allocated, free if changed/unset */ #define EV_VOLATILE (1<<1) /* value is volatile, make a copy of it */ #define EV_NOHOOK (1<<2) /* don't call hook when setting */ struct env_var; typedef char *(ev_format_t)(struct env_var *ev); typedef int (ev_sethook_t)(struct env_var *ev, int flags, const void *value); typedef int (ev_unsethook_t)(struct env_var *ev); struct env_var { char *ev_name; int ev_flags; void *ev_value; ev_sethook_t *ev_sethook; ev_unsethook_t *ev_unsethook; struct env_var *ev_next, *ev_prev; }; extern struct env_var *environ; extern struct env_var *env_getenv(const char *name); extern int env_setenv(const char *name, int flags, const void *value, ev_sethook_t sethook, ev_unsethook_t unsethook); extern char *getenv(const char *name); extern int setenv(const char *name, const char *value, int overwrite); extern int putenv(char *string); extern int unsetenv(const char *name); extern ev_sethook_t env_noset; /* refuse set operation */ extern ev_unsethook_t env_nounset; /* refuse unset operation */ /* stdlib.h routines */ extern int abs(int a); extern void abort(void) __dead2; extern long strtol(const char * __restrict, char ** __restrict, int); extern long long strtoll(const char * __restrict, char ** __restrict, int); extern unsigned long strtoul(const char * __restrict, char ** __restrict, int); extern unsigned long long strtoull(const char * __restrict, char ** __restrict, int); /* BCD conversions (undocumented) */ extern u_char const bcd2bin_data[]; extern u_char const bin2bcd_data[]; extern char const hex2ascii_data[]; #define bcd2bin(bcd) (bcd2bin_data[bcd]) #define bin2bcd(bin) (bin2bcd_data[bin]) #define hex2ascii(hex) (hex2ascii_data[hex]) #define validbcd(bcd) (bcd == 0 || (bcd > 0 && bcd <= 0x99 && bcd2bin_data[bcd] != 0)) /* min/max (undocumented) */ static __inline int imax(int a, int b) { return (a > b ? a : b); } static __inline int imin(int a, int b) { return (a < b ? a : b); } static __inline long lmax(long a, long b) { return (a > b ? a : b); } static __inline long lmin(long a, long b) { return (a < b ? a : b); } static __inline u_int max(u_int a, u_int b) { return (a > b ? a : b); } static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); } static __inline quad_t qmax(quad_t a, quad_t b) { return (a > b ? a : b); } static __inline quad_t qmin(quad_t a, quad_t b) { return (a < b ? a : b); } static __inline u_long ulmax(u_long a, u_long b) { return (a > b ? a : b); } static __inline u_long ulmin(u_long a, u_long b) { return (a < b ? a : b); } /* null functions for device/filesystem switches (undocumented) */ extern int nodev(void); extern int noioctl(struct open_file *, u_long, void *); extern void nullsys(void); extern int null_open(const char *path, struct open_file *f); extern int null_close(struct open_file *f); extern int null_read(struct open_file *f, void *buf, size_t size, size_t *resid); extern int null_write(struct open_file *f, const void *buf, size_t size, size_t *resid); extern off_t null_seek(struct open_file *f, off_t offset, int where); extern int null_stat(struct open_file *f, struct stat *sb); extern int null_readdir(struct open_file *f, struct dirent *d); /* * Machine dependent functions and data, must be provided or stubbed by * the consumer */ extern void exit(int) __dead2; extern int getchar(void); extern int ischar(void); extern void putchar(int); extern int devopen(struct open_file *, const char *, const char **); extern int devclose(struct open_file *f); extern void panic(const char *, ...) __dead2 __printflike(1, 2); extern void panic_action(void) __weak_symbol __dead2; extern time_t getsecs(void); extern struct fs_ops *file_system[]; extern struct fs_ops *exclusive_file_system; extern struct devsw *devsw[]; /* * Expose byteorder(3) functions. */ #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED extern uint32_t htonl(uint32_t); extern uint16_t htons(uint16_t); extern uint32_t ntohl(uint32_t); extern uint16_t ntohs(uint16_t); #endif #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif void *Malloc(size_t, const char *, int); void *Calloc(size_t, size_t, const char *, int); void *Realloc(void *, size_t, const char *, int); void Free(void *, const char *, int); #ifdef DEBUG_MALLOC #define malloc(x) Malloc(x, __FILE__, __LINE__) #define calloc(x, y) Calloc(x, y, __FILE__, __LINE__) #define free(x) Free(x, __FILE__, __LINE__) #define realloc(x, y) Realloc(x, y, __FILE__, __LINE__) #else #define malloc(x) Malloc(x, NULL, 0) #define calloc(x, y) Calloc(x, y, NULL, 0) #define free(x) Free(x, NULL, 0) #define realloc(x, y) Realloc(x, y, NULL, 0) #endif #endif /* STAND_H */ Index: head/stand/loader.mk =================================================================== --- head/stand/loader.mk (revision 349351) +++ head/stand/loader.mk (revision 349352) @@ -1,178 +1,175 @@ # $FreeBSD$ .PATH: ${LDRSRC} ${BOOTSRC}/libsa CFLAGS+=-I${LDRSRC} SRCS+= boot.c commands.c console.c devopen.c interp.c SRCS+= interp_backslash.c interp_parse.c ls.c misc.c SRCS+= module.c .if ${MACHINE} == "i386" || ${MACHINE_CPUARCH} == "amd64" SRCS+= load_elf32.c load_elf32_obj.c reloc_elf32.c SRCS+= load_elf64.c load_elf64_obj.c reloc_elf64.c .elif ${MACHINE_CPUARCH} == "aarch64" SRCS+= load_elf64.c reloc_elf64.c .elif ${MACHINE_CPUARCH} == "arm" SRCS+= load_elf32.c reloc_elf32.c .elif ${MACHINE_CPUARCH} == "powerpc" SRCS+= load_elf32.c reloc_elf32.c SRCS+= load_elf64.c reloc_elf64.c SRCS+= metadata.c .elif ${MACHINE_CPUARCH} == "sparc64" SRCS+= load_elf64.c reloc_elf64.c SRCS+= metadata.c .elif ${MACHINE_ARCH:Mmips64*} != "" SRCS+= load_elf64.c reloc_elf64.c SRCS+= metadata.c .elif ${MACHINE} == "mips" SRCS+= load_elf32.c reloc_elf32.c SRCS+= metadata.c .endif .if ${LOADER_DISK_SUPPORT:Uyes} == "yes" SRCS+= disk.c part.c vdisk.c .endif .if ${LOADER_NET_SUPPORT:Uno} == "yes" SRCS+= dev_net.c .endif .if defined(HAVE_BCACHE) SRCS+= bcache.c .endif .if defined(MD_IMAGE_SIZE) CFLAGS+= -DMD_IMAGE_SIZE=${MD_IMAGE_SIZE} SRCS+= md.c .else CLEANFILES+= md.o .endif # Machine-independant ISA PnP .if defined(HAVE_ISABUS) SRCS+= isapnp.c .endif .if defined(HAVE_PNP) SRCS+= pnp.c .endif .if ${LOADER_INTERP} == "lua" SRCS+= interp_lua.c .include "${BOOTSRC}/lua.mk" LDR_INTERP= ${LIBLUA} LDR_INTERP32= ${LIBLUA32} .elif ${LOADER_INTERP} == "4th" SRCS+= interp_forth.c .include "${BOOTSRC}/ficl.mk" LDR_INTERP= ${LIBFICL} LDR_INTERP32= ${LIBFICL32} .elif ${LOADER_INTERP} == "simp" SRCS+= interp_simple.c .else .error Unknown interpreter ${LOADER_INTERP} .endif .if ${MK_LOADER_VERIEXEC} != "no" CFLAGS+= -DLOADER_VERIEXEC -I${SRCTOP}/lib/libsecureboot/h .endif .if ${MK_LOADER_VERIEXEC_PASS_MANIFEST} != "no" CFLAGS+= -DLOADER_VERIEXEC_PASS_MANIFEST -I${SRCTOP}/lib/libsecureboot/h .endif .if defined(BOOT_PROMPT_123) CFLAGS+= -DBOOT_PROMPT_123 .endif .if defined(LOADER_INSTALL_SUPPORT) SRCS+= install.c .endif # Filesystem support .if ${LOADER_CD9660_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_CD9660_SUPPORT .endif .if ${LOADER_EXT2FS_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_EXT2FS_SUPPORT .endif .if ${LOADER_MSDOS_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_MSDOS_SUPPORT .endif -.if ${LOADER_NANDFS_SUPPORT:U${MK_NAND}} == "yes" -CFLAGS+= -DLOADER_NANDFS_SUPPORT -.endif .if ${LOADER_UFS_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_UFS_SUPPORT .endif # Compression .if ${LOADER_GZIP_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_GZIP_SUPPORT .endif .if ${LOADER_BZIP2_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_BZIP2_SUPPORT .endif # Network related things .if ${LOADER_NET_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_NET_SUPPORT .endif .if ${LOADER_NFS_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_NFS_SUPPORT .endif .if ${LOADER_TFTP_SUPPORT:Uno} == "yes" CFLAGS+= -DLOADER_TFTP_SUPPORT .endif # Partition support .if ${LOADER_GPT_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_GPT_SUPPORT .endif .if ${LOADER_MBR_SUPPORT:Uyes} == "yes" CFLAGS+= -DLOADER_MBR_SUPPORT .endif .if ${HAVE_ZFS:Uno} == "yes" CFLAGS+= -DLOADER_ZFS_SUPPORT CFLAGS+= -I${ZFSSRC} CFLAGS+= -I${SYSDIR}/cddl/boot/zfs SRCS+= zfs_cmd.c .endif LIBFICL= ${BOOTOBJ}/ficl/libficl.a .if ${MACHINE} == "i386" LIBFICL32= ${LIBFICL} .else LIBFICL32= ${BOOTOBJ}/ficl32/libficl.a .endif LIBLUA= ${BOOTOBJ}/liblua/liblua.a .if ${MACHINE} == "i386" LIBLUA32= ${LIBLUA} .else LIBLUA32= ${BOOTOBJ}/liblua32/liblua.a .endif CLEANFILES+= vers.c VERSION_FILE?= ${.CURDIR}/version .if ${MK_REPRODUCIBLE_BUILD} != no REPRO_FLAG= -r .endif vers.c: ${LDRSRC}/newvers.sh ${VERSION_FILE} sh ${LDRSRC}/newvers.sh ${REPRO_FLAG} ${VERSION_FILE} \ ${NEWVERSWHAT} .if ${MK_LOADER_VERBOSE} != "no" CFLAGS+= -DELF_VERBOSE .endif .if !empty(HELP_FILES) HELP_FILES+= ${LDRSRC}/help.common CLEANFILES+= loader.help FILES+= loader.help loader.help: ${HELP_FILES} cat ${HELP_FILES} | awk -f ${LDRSRC}/merge_help.awk > ${.TARGET} .endif Index: head/stand/mips/uboot/conf.c =================================================================== --- head/stand/mips/uboot/conf.c (revision 349351) +++ head/stand/mips/uboot/conf.c (revision 349352) @@ -1,120 +1,117 @@ /*- * Copyright (c) 2008 Semihalf, Rafal Jaworowski * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include #include "bootstrap.h" #include "libuboot.h" #if defined(LOADER_NET_SUPPORT) #include "dev_net.h" #endif /* Make sure we have an explicit reference to exit so libsa's panic pulls in the MD exit */ void (*exitfn)(int) = exit; struct devsw *devsw[] = { #if defined(LOADER_DISK_SUPPORT) || defined(LOADER_CD9660_SUPPORT) &uboot_storage, #endif #if defined(LOADER_NET_SUPPORT) &netdev, #endif NULL }; struct fs_ops *file_system[] = { #if defined(LOADER_MSDOS_SUPPORT) &dosfs_fsops, #endif #if defined(LOADER_UFS_SUPPORT) &ufs_fsops, #endif #if defined(LOADER_CD9660_SUPPORT) &cd9660_fsops, #endif #if defined(LOADER_EXT2FS_SUPPORT) &ext2fs_fsops, #endif -#if defined(LOADER_NANDFS_SUPPORT) - &nandfs_fsops, -#endif #if defined(LOADER_NFS_SUPPORT) &nfs_fsops, #endif #if defined(LOADER_TFTP_SUPPORT) &tftp_fsops, #endif #if defined(LOADER_GZIP_SUPPORT) &gzipfs_fsops, #endif #if defined(LOADER_BZIP2_SUPPORT) &bzipfs_fsops, #endif NULL }; struct netif_driver *netif_drivers[] = { #if defined(LOADER_NET_SUPPORT) &uboot_net, #endif NULL, }; struct file_format *file_formats[] = { &uboot_elf, NULL }; extern struct console uboot_console; struct console *consoles[] = { &uboot_console, NULL }; void abort(void) { printf("error: loader abort\n"); while (1); __unreachable(); } void longjmperror(void) { printf("error: loader longjmp error\n"); while (1); __unreachable(); } int debug = 1; Index: head/stand/mips/uboot/version =================================================================== --- head/stand/mips/uboot/version (revision 349351) +++ head/stand/mips/uboot/version (revision 349352) @@ -1,9 +1,10 @@ $FreeBSD$ NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this file is important. Make sure the current version number is on line 6. +1.3: Remove NAND FS support. 1.2: Extended with NAND FS support. 1.1: Flattened Device Tree blob support. 1.0: Added storage support. Booting from HDD, USB, etc. is now possible. 0.5: Initial U-Boot/arm version (netbooting only). Index: head/sys/arm/conf/DB-78XXX =================================================================== --- head/sys/arm/conf/DB-78XXX (revision 349351) +++ head/sys/arm/conf/DB-78XXX (revision 349352) @@ -1,86 +1,83 @@ # # Custom kernel for Marvell DB-78xx boards. # # $FreeBSD$ # ident DB-88F78XX include "std.arm" include "../mv/discovery/std.db78xxx" options SOC_MV_DISCOVERY makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme options TMPFS # Efficient memory filesystem options FFS # Berkeley Fast Filesystem options NANDFS # NAND Filesystem options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL options BOOTP options BOOTP_NFSROOT options BOOTP_NFSV3 options BOOTP_WIRED_TO=mge0 #options ROOTDEVNAME=\"ufs:/dev/da0a\" 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 device pci # Pseudo devices device loop device md # Serial ports device uart # Networking device ether device mge # Marvell Gigabit Ethernet controller device mii device mdio device e1000phy device bpf # USB device usb device ehci device umass device scbus device pass device da # I2C (TWSI) device iic device iicbus device twsi device ds133x # SATA device mvs -# NAND -device nand - # GPIO device gpio # Flattened Device Tree options FDT options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=db78100.dts Index: head/sys/arm/conf/DB-88F6XXX =================================================================== --- head/sys/arm/conf/DB-88F6XXX (revision 349351) +++ head/sys/arm/conf/DB-88F6XXX (revision 349352) @@ -1,90 +1,87 @@ # # Custom kernel for Marvell DB-88F6xxx boards. # # $FreeBSD$ # ident DB-88F6XXX include "std.arm" include "../mv/kirkwood/std.db88f6xxx" options SOC_MV_KIRKWOOD makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options NANDFS # NAND Filesystem options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL options TMPFS # Efficient memory filesystem options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme 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 # NFS root from boopt/dhcp options BOOTP options BOOTP_NFSROOT options BOOTP_NFSV3 options BOOTP_WIRED_TO=mge0 #options ROOTDEVNAME=\"ufs:/dev/da0a\" device pci # Pseudo devices device loop device md # Serial ports device uart # Networking device ether device mge # Marvell Gigabit Ethernet controller device mii device mdio device e1000phy device bpf device cesa # Marvell security engine device crypto device cryptodev # USB device usb device ehci device umass device scbus device pass device da # I2C (TWSI) device iic device iicbus device twsi # SATA device mvs -# NAND -device nand - # GPIO device gpio # Flattened Device Tree options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=db88f6281.dts Index: head/sys/arm/conf/DREAMPLUG-1001 =================================================================== --- head/sys/arm/conf/DREAMPLUG-1001 (revision 349351) +++ head/sys/arm/conf/DREAMPLUG-1001 (revision 349352) @@ -1,171 +1,163 @@ # Kernel config for GlobalScale Technologies DreamPlug version 1001. # # This is for units that are version 10, revision 01, with NOR SPI flash. # These units are identified with the number "1001" on the S/N label. # # For more information on this file, please read the handbook section on # Kernel Configuration Files: # # https://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 (https://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$ # #NO_UNIVERSE ident DREAMPLUG-1001 include "std.arm" include "../mv/kirkwood/std.db88f6xxx" options SOC_MV_KIRKWOOD options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options SOFTUPDATES # Enable FFS soft updates support options NFSCL # 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 NULLFS # NULL 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 GEOM_LABEL # Provides labelization options GEOM_ELI # Disk encryption 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 # Enable these options for nfs root configured via BOOTP. #options BOOTP #options BOOTP_NFSROOT #options BOOTP_NFSV3 #options BOOTP_WIRED_TO=mge0 # If not using BOOTP, use something like one of these... #options ROOTDEVNAME=\"ufs:/dev/da1a\" options ROOTDEVNAME=\"ufs:/dev/da1s1a\" #options ROOTDEVNAME=\"ufs:/dev/da1p10\" #options ROOTDEVNAME=\"nfs:192.168.0.254/dreamplug\" # Misc pseudo devices device bpf # Required for DHCP device firmware # firmware(9) required for USB wlan device gif # IPv6 and IPv4 tunneling device loop # Network loopback device md # Memory/malloc disk device pty # BSD-style compatibility pseudo ttys device tuntap # Packet tunnel. device ether # Required for all ethernet devices 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 # Serial ports device uart # Networking device mge # Marvell Gigabit Ethernet controller device mii device mdio device e1000phy # USB options USB_HOST_ALIGN=32 # Align DMA to cacheline 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 device twsi # GPIO device gpio # SATA device mvs device ahci # Sound device sound device snd_uaudio #crypto device cesa # Marvell security engine device crypto device cryptodev # IPSec device enc options IPSEC 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 #PF 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_DEBUG -# To use this configuration with the (rare) model 1001N (nand flash), -# create a kernel config file that looks like this: -# -# include DREAMPLUG-1001 -# nomakeoptions FDT_DTS_FILE -# makeoptions FDT_DTS_FILE=dreamplug-1001N.dts -# device nand - # Flattened Device Tree options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=dreamplug-1001.dts Index: head/sys/arm/conf/NOTES.armv5 =================================================================== --- head/sys/arm/conf/NOTES.armv5 (revision 349351) +++ head/sys/arm/conf/NOTES.armv5 (revision 349352) @@ -1,38 +1,33 @@ # armv5-specific changes for doing a LINT build. # # The contents of sys/conf/NOTES, sys/arm/conf/NOTES, and this file are # concatenated (in that order) to create the LINT-V5 kernel config file. # # $FreeBSD$ #NO_UNIVERSE machine arm arm cpu CPU_ARM9E files "../mv/files.mv" files "../mv/discovery/files.db78xxx" files "../mv/kirkwood/files.kirkwood" files "../mv/orion/files.db88f5xxx" files "../mv/orion/files.ts7800" makeoptions CONF_CFLAGS+="-march=armv5te" makeoptions LDFLAGS="-zmuldefs" makeoptions KERNPHYSADDR=0x00000000 # Undo options from sys/conf/NOTES that we do not want... nooptions SMP # All armv5 are single-core # Add options for armv5 that are not in sys/conf/NOTES... options ARM_MANY_BOARD options SOC_MV_DISCOVERY options SOC_MV_KIRKWOOD options SOC_MV_ORION - -# Add devices which are specific to various arm platforms... - -device nand - Index: head/sys/arm/conf/SHEEVAPLUG =================================================================== --- head/sys/arm/conf/SHEEVAPLUG (revision 349351) +++ head/sys/arm/conf/SHEEVAPLUG (revision 349352) @@ -1,84 +1,81 @@ # # Custom kernel for Marvell SheevaPlug devices. # # $FreeBSD$ # #NO_UNIVERSE ident SHEEVAPLUG include "std.arm" include "../mv/kirkwood/std.db88f6xxx" options SOC_MV_KIRKWOOD makeoptions WERROR="-Werror" options HZ=1000 options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking options INET6 # IPv6 communications protocols options TCP_HHOOK # hhook(9) framework for TCP options FFS # Berkeley Fast Filesystem options NANDFS # NAND Filesystem options NFSCL # Network Filesystem Client options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL options TMPFS # Efficient memory filesystem options GEOM_PART_BSD # BSD partition scheme options GEOM_PART_MBR # MBR partition scheme 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 # NFS root from boopt/dhcp options BOOTP options BOOTP_NFSROOT options BOOTP_NFSV3 options BOOTP_WIRED_TO=mge0 # Root fs on USB device #options ROOTDEVNAME=\"ufs:/dev/da0a\" # Pseudo devices device loop # Serial ports device uart # Networking device ether device mge # Marvell Gigabit Ethernet controller device mii device mdio device e1000phy device bpf options DEVICE_POLLING device vlan device cesa # Marvell security engine device crypto device cryptodev # USB device usb device ehci device umass device scbus device pass device da -# NAND -device nand - # GPIO device gpio # Flattened Device Tree options FDT # Configure using FDT/DTB data options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=sheevaplug.dts Index: head/sys/arm/conf/VYBRID =================================================================== --- head/sys/arm/conf/VYBRID (revision 349351) +++ head/sys/arm/conf/VYBRID (revision 349352) @@ -1,113 +1,110 @@ # # Kernel configuration for Vybrid Family boards. # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # https://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 (https://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 VYBRID include "std.armv7" include "../freescale/vybrid/std.vybrid" makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options PLATFORM # Platform based SoC #options NANDFS # NAND Filesystem #options SMP # Enable multiple cores # 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 MUTEX_NOINLINE options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING # Interrupt controller device gic # ARM MPCore timer device mpcore_timer # MMC/SD/SDIO Card slot support device mmc # mmc/sd bus device mmcsd # mmc/sd flash cards device sdhci # generic sdhci # Pseudo devices device loop device pty device md device gpio # USB support options USB_HOST_ALIGN=32 # Align usb buffers to cache line size. device usb #device musb device ehci #device ohci device umass device scbus # SCSI bus (required for ATA/SCSI) device da # Direct Access (disks) device pass # SATA #device ata #device atadisk #device mvs - -device nand # Serial ports device uart # I2C (TWSI) device iic device iicbus # Ethernet device ether device ffec # USB ethernet support, requires miibus device miibus device axe # ASIX Electronics USB Ethernet device bpf # Berkeley packet filter device sound # SPI device spibus device vf_spi # Framebuffer device vt device kbdmux device ukbd # Flattened Device Tree options FDT # Configure using FDT/DTB data Index: head/sys/arm/freescale/vybrid/vf_nfc.c =================================================================== --- head/sys/arm/freescale/vybrid/vf_nfc.c (revision 349351) +++ head/sys/arm/freescale/vybrid/vf_nfc.c (nonexistent) @@ -1,528 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2013 Ruslan Bukin - * 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. - */ - -/* - * Vybrid Family NAND Flash Controller (NFC) - * Chapter 31, Vybrid Reference Manual, Rev. 5, 07/2013 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "nfc_if.h" - -#include - -enum addr_type { - ADDR_NONE, - ADDR_ID, - ADDR_ROW, - ADDR_ROWCOL -}; - -struct fsl_nfc_fcm { - uint32_t addr_bits; - enum addr_type addr_type; - uint32_t col_addr_bits; - uint32_t row_addr_bits; - u_int read_ptr; - u_int addr_ptr; - u_int command; - u_int code; -}; - -struct vf_nand_softc { - struct nand_softc nand_dev; - bus_space_handle_t bsh; - bus_space_tag_t bst; - struct resource *res[2]; - struct fsl_nfc_fcm fcm; -}; - -static struct resource_spec nfc_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { SYS_RES_IRQ, 0, RF_ACTIVE }, - { -1, 0 } -}; - -static int vf_nand_attach(device_t); -static int vf_nand_probe(device_t); -static int vf_nand_send_command(device_t, uint8_t); -static int vf_nand_send_address(device_t, uint8_t); -static int vf_nand_start_command(device_t); -static uint8_t vf_nand_read_byte(device_t); -static void vf_nand_read_buf(device_t, void *, uint32_t); -static void vf_nand_write_buf(device_t, void *, uint32_t); -static int vf_nand_select_cs(device_t, uint8_t); -static int vf_nand_read_rnb(device_t); - -#define CMD_READ_PAGE 0x7EE0 -#define CMD_PROG_PAGE 0x7FC0 -#define CMD_PROG_PAGE_DMA 0xFFC8 -#define CMD_ERASE 0x4EC0 -#define CMD_READ_ID 0x4804 -#define CMD_READ_STATUS 0x4068 -#define CMD_RESET 0x4040 -#define CMD_RANDOM_IN 0x7140 -#define CMD_RANDOM_OUT 0x70E0 - -#define CMD_BYTE2_PROG_PAGE 0x10 -#define CMD_BYTE2_PAGE_READ 0x30 -#define CMD_BYTE2_ERASE 0xD0 - -#define NFC_CMD1 0x3F00 /* Flash command 1 */ -#define NFC_CMD2 0x3F04 /* Flash command 2 */ -#define NFC_CAR 0x3F08 /* Column address */ -#define NFC_RAR 0x3F0C /* Row address */ -#define NFC_RPT 0x3F10 /* Flash command repeat */ -#define NFC_RAI 0x3F14 /* Row address increment */ -#define NFC_SR1 0x3F18 /* Flash status 1 */ -#define NFC_SR2 0x3F1C /* Flash status 2 */ -#define NFC_DMA_CH1 0x3F20 /* DMA channel 1 address */ -#define NFC_DMACFG 0x3F24 /* DMA configuration */ -#define NFC_SWAP 0x3F28 /* Cach swap */ -#define NFC_SECSZ 0x3F2C /* Sector size */ -#define NFC_CFG 0x3F30 /* Flash configuration */ -#define NFC_DMA_CH2 0x3F34 /* DMA channel 2 address */ -#define NFC_ISR 0x3F38 /* Interrupt status */ - -#define ECCMODE_SHIFT 17 -#define AIAD_SHIFT 5 -#define AIBN_SHIFT 4 -#define PAGECOUNT_SHIFT 0 -#define BITWIDTH_SHIFT 7 -#define BITWIDTH8 0 -#define BITWIDTH16 1 -#define PAGECOUNT_MASK 0xf - -#define CMD2_BYTE1_SHIFT 24 -#define CMD2_CODE_SHIFT 8 -#define CMD2_BUFNO_SHIFT 1 -#define CMD2_START_SHIFT 0 - -static device_method_t vf_nand_methods[] = { - DEVMETHOD(device_probe, vf_nand_probe), - DEVMETHOD(device_attach, vf_nand_attach), - DEVMETHOD(nfc_start_command, vf_nand_start_command), - DEVMETHOD(nfc_send_command, vf_nand_send_command), - DEVMETHOD(nfc_send_address, vf_nand_send_address), - DEVMETHOD(nfc_read_byte, vf_nand_read_byte), - DEVMETHOD(nfc_read_buf, vf_nand_read_buf), - DEVMETHOD(nfc_write_buf, vf_nand_write_buf), - DEVMETHOD(nfc_select_cs, vf_nand_select_cs), - DEVMETHOD(nfc_read_rnb, vf_nand_read_rnb), - { 0, 0 }, -}; - -static driver_t vf_nand_driver = { - "nand", - vf_nand_methods, - sizeof(struct vf_nand_softc), -}; - -static devclass_t vf_nand_devclass; -DRIVER_MODULE(vf_nand, simplebus, vf_nand_driver, vf_nand_devclass, 0, 0); - -static int -vf_nand_probe(device_t dev) -{ - - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (!ofw_bus_is_compatible(dev, "fsl,mvf600-nand")) - return (ENXIO); - - device_set_desc(dev, "Vybrid Family NAND controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -vf_nand_attach(device_t dev) -{ - struct vf_nand_softc *sc; - int err; - int reg; - - sc = device_get_softc(dev); - if (bus_alloc_resources(dev, nfc_spec, sc->res)) { - device_printf(dev, "could not allocate resources!\n"); - return (ENXIO); - } - - sc->bst = rman_get_bustag(sc->res[0]); - sc->bsh = rman_get_bushandle(sc->res[0]); - - /* Size in bytes of one elementary transfer unit */ - WRITE4(sc, NFC_SECSZ, 2048); - - /* Flash mode width */ - reg = READ4(sc, NFC_CFG); - reg |= (BITWIDTH16 << BITWIDTH_SHIFT); - - /* No correction, ECC bypass */ - reg &= ~(0x7 << ECCMODE_SHIFT); - - /* Disable Auto-incrementing of flash row address */ - reg &= ~(0x1 << AIAD_SHIFT); - - /* Disable Auto-incrementing of buffer numbers */ - reg &= ~(0x1 << AIBN_SHIFT); - - /* - * Number of virtual pages (in one physical flash page) - * to be programmed or read, etc. - */ - reg &= ~(PAGECOUNT_MASK); - reg |= (1 << PAGECOUNT_SHIFT); - WRITE4(sc, NFC_CFG, reg); - - nand_init(&sc->nand_dev, dev, NAND_ECC_NONE, 0, 0, NULL, NULL); - err = nandbus_create(dev); - return (err); -} - -static int -vf_nand_start_command(device_t dev) -{ - struct vf_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - int reg; - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - nand_debug(NDBG_DRV,"vf_nand: start command %x", fcm->command); - - /* CMD2 */ - reg = READ4(sc, NFC_CMD2); - reg &= ~(0xff << CMD2_BYTE1_SHIFT); - reg |= (fcm->command << CMD2_BYTE1_SHIFT); - WRITE4(sc, NFC_CMD2, reg); - - /* CMD1 */ - if ((fcm->command == NAND_CMD_READ) || - (fcm->command == NAND_CMD_PROG) || - (fcm->command == NAND_CMD_ERASE)) { - reg = READ4(sc, NFC_CMD1); - reg &= ~(0xff << 24); - - if (fcm->command == NAND_CMD_READ) - reg |= (CMD_BYTE2_PAGE_READ << 24); - else if (fcm->command == NAND_CMD_PROG) - reg |= (CMD_BYTE2_PROG_PAGE << 24); - else if (fcm->command == NAND_CMD_ERASE) - reg |= (CMD_BYTE2_ERASE << 24); - - WRITE4(sc, NFC_CMD1, reg); - } - - /* We work with 1st buffer */ - reg = READ4(sc, NFC_CMD2); - reg &= ~(0xf << CMD2_BUFNO_SHIFT); - reg |= (0 << CMD2_BUFNO_SHIFT); - WRITE4(sc, NFC_CMD2, reg); - - /* Cmd CODE */ - reg = READ4(sc, NFC_CMD2); - reg &= ~(0xffff << CMD2_CODE_SHIFT); - reg |= (fcm->code << CMD2_CODE_SHIFT); - WRITE4(sc, NFC_CMD2, reg); - - /* Col */ - if (fcm->addr_type == ADDR_ROWCOL) { - reg = READ4(sc, NFC_CAR); - reg &= ~(0xffff); - reg |= fcm->col_addr_bits; - nand_debug(NDBG_DRV,"setting CAR to 0x%08x\n", reg); - WRITE4(sc, NFC_CAR, reg); - } - - /* Row */ - reg = READ4(sc, NFC_RAR); - reg &= ~(0xffffff); - if (fcm->addr_type == ADDR_ID) - reg |= fcm->addr_bits; - else - reg |= fcm->row_addr_bits; - WRITE4(sc, NFC_RAR, reg); - - /* Start */ - reg = READ4(sc, NFC_CMD2); - reg |= (1 << CMD2_START_SHIFT); - WRITE4(sc, NFC_CMD2, reg); - - /* Wait command completion */ - while (READ4(sc, NFC_CMD2) & (1 << CMD2_START_SHIFT)) - ; - - return (0); -} - -static int -vf_nand_send_command(device_t dev, uint8_t command) -{ - struct vf_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - - nand_debug(NDBG_DRV,"vf_nand: send command %x", command); - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - if ((command == NAND_CMD_READ_END) || - (command == NAND_CMD_PROG_END) || - (command == NAND_CMD_ERASE_END)) { - return (0); - } - - fcm->command = command; - - fcm->code = 0; - fcm->read_ptr = 0; - fcm->addr_type = 0; - fcm->addr_bits = 0; - - fcm->addr_ptr = 0; - fcm->col_addr_bits = 0; - fcm->row_addr_bits = 0; - - switch (command) { - case NAND_CMD_READ: - fcm->code = CMD_READ_PAGE; - fcm->addr_type = ADDR_ROWCOL; - break; - case NAND_CMD_PROG: - fcm->code = CMD_PROG_PAGE; - fcm->addr_type = ADDR_ROWCOL; - break; - case NAND_CMD_PROG_END: - break; - case NAND_CMD_ERASE_END: - break; - case NAND_CMD_RESET: - fcm->code = CMD_RESET; - break; - case NAND_CMD_READ_ID: - fcm->code = CMD_READ_ID; - fcm->addr_type = ADDR_ID; - break; - case NAND_CMD_READ_PARAMETER: - fcm->code = CMD_READ_PAGE; - fcm->addr_type = ADDR_ID; - break; - case NAND_CMD_STATUS: - fcm->code = CMD_READ_STATUS; - break; - case NAND_CMD_ERASE: - fcm->code = CMD_ERASE; - fcm->addr_type = ADDR_ROW; - break; - default: - nand_debug(NDBG_DRV, "unknown command %d\n", command); - return (1); - } - - return (0); -} - -static int -vf_nand_send_address(device_t dev, uint8_t addr) -{ - struct vf_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - - nand_debug(NDBG_DRV,"vf_nand: send address %x", addr); - sc = device_get_softc(dev); - fcm = &sc->fcm; - - nand_debug(NDBG_DRV, "setting addr #%d to 0x%02x\n", fcm->addr_ptr, addr); - - if (fcm->addr_type == ADDR_ID) { - fcm->addr_bits = addr; - } else if (fcm->addr_type == ADDR_ROWCOL) { - - if (fcm->addr_ptr < 2) - fcm->col_addr_bits |= (addr << (fcm->addr_ptr * 8)); - else - fcm->row_addr_bits |= (addr << ((fcm->addr_ptr - 2) * 8)); - - } else if (fcm->addr_type == ADDR_ROW) - fcm->row_addr_bits |= (addr << (fcm->addr_ptr * 8)); - - fcm->addr_ptr += 1; - - return (0); -} - -static uint8_t -vf_nand_read_byte(device_t dev) -{ - struct vf_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint8_t data; - int sr1, sr2; - int b; - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - sr1 = READ4(sc, NFC_SR1); - sr2 = READ4(sc, NFC_SR2); - - data = 0; - if (fcm->addr_type == ADDR_ID) { - b = 32 - ((fcm->read_ptr + 1) * 8); - data = (sr1 >> b) & 0xff; - fcm->read_ptr++; - } else if (fcm->command == NAND_CMD_STATUS) { - data = sr2 & 0xff; - } - - nand_debug(NDBG_DRV,"vf_nand: read %x", data); - return (data); -} - -static void -vf_nand_read_buf(device_t dev, void* buf, uint32_t len) -{ - struct vf_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint16_t *tmp; - uint8_t *b; - int i; - - b = (uint8_t*)buf; - sc = device_get_softc(dev); - fcm = &sc->fcm; - - nand_debug(NDBG_DRV, "vf_nand: read_buf len %d", len); - - if (fcm->command == NAND_CMD_READ_PARAMETER) { - tmp = malloc(len, M_DEVBUF, M_NOWAIT); - bus_read_region_2(sc->res[0], 0x0, tmp, len); - - for (i = 0; i < len; i += 2) { - b[i] = tmp[i+1]; - b[i+1] = tmp[i]; - } - - free(tmp, M_DEVBUF); - -#ifdef NAND_DEBUG - for (i = 0; i < len; i++) { - if (!(i % 16)) - printf("%s", i == 0 ? "vf_nand:\n" : "\n"); - printf(" %x", b[i]); - if (i == len - 1) - printf("\n"); - } -#endif - - } else { - - for (i = 0; i < len; i++) { - b[i] = READ1(sc, i); - -#ifdef NAND_DEBUG - if (!(i % 16)) - printf("%s", i == 0 ? "vf_nand:\n" : "\n"); - printf(" %x", b[i]); - if (i == len - 1) - printf("\n"); -#endif - } - - } -} - -static void -vf_nand_write_buf(device_t dev, void* buf, uint32_t len) -{ - struct vf_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint8_t *b; - int i; - - b = (uint8_t*)buf; - sc = device_get_softc(dev); - fcm = &sc->fcm; - - nand_debug(NDBG_DRV,"vf_nand: write_buf len %d", len); - - for (i = 0; i < len; i++) { - WRITE1(sc, i, b[i]); - -#ifdef NAND_DEBUG - if (!(i % 16)) - printf("%s", i == 0 ? "vf_nand:\n" : "\n"); - printf(" %x", b[i]); - if (i == len - 1) - printf("\n"); -#endif - - } -} - -static int -vf_nand_select_cs(device_t dev, uint8_t cs) -{ - - if (cs > 0) - return (ENODEV); - - return (0); -} - -static int -vf_nand_read_rnb(device_t dev) -{ - - /* no-op */ - return (0); /* ready */ -} Property changes on: head/sys/arm/freescale/vybrid/vf_nfc.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/arm/mv/files.arm7 =================================================================== --- head/sys/arm/mv/files.arm7 (revision 349351) +++ head/sys/arm/mv/files.arm7 (revision 349352) @@ -1,38 +1,37 @@ # $FreeBSD$ arm/mv/armada38x/armada38x.c standard arm/mv/armadaxp/armadaxp.c standard arm/mv/gpio.c optional gpio arm/mv/mv_common.c standard arm/mv/mv_localbus.c standard arm/mv/mv_armv7_machdep.c standard arm/mv/mv_pci_ctrl.c optional pci | fdt arm/mv/mv_pci.c optional pci arm/mv/mv_ts.c standard arm/mv/timer.c standard arm/mv/mpic.c standard arm/mv/armada/thermal.c optional fdt arm/mv/armada/wdt.c optional fdt arm/mv/armada38x/armada38x_mp.c optional smp arm/mv/armada38x/pmsu.c standard arm/mv/armada38x/armada38x_rtc.c standard arm/mv/armada38x/armada38x_pl310.c optional pl310 arm/mv/mv_spi.c optional mv_spi spibus dev/sdhci/sdhci_fdt.c optional sdhci arm/mv/rtc.c standard arm/mv/armadaxp/armadaxp_mp.c optional smp arm/mv/armadaxp/mptramp.S optional smp dev/cesa/cesa.c optional cesa dev/iicbus/twsi/mv_twsi.c optional twsi dev/mge/if_mge.c optional mge dev/neta/if_mvneta_fdt.c optional neta fdt dev/neta/if_mvneta.c optional neta mdio mii -dev/nand/nfc_mv.c optional nand dev/mvs/mvs_soc.c optional mvs dev/uart/uart_dev_ns8250.c optional uart dev/uart/uart_dev_snps.c optional uart dev/usb/controller/ehci_mv.c optional ehci dev/usb/controller/generic_xhci.c optional xhci dev/ahci/ahci_mv_fdt.c optional ahci Index: head/sys/arm/mv/files.mv =================================================================== --- head/sys/arm/mv/files.mv (revision 349351) +++ head/sys/arm/mv/files.mv (revision 349352) @@ -1,35 +1,34 @@ # $FreeBSD$ # # The Marvell CPU cores # - Compliant with V5TE architecture # - Super scalar dual issue CPU # - Big/Little Endian # - MMU/MPU # - L1 Cache: Supports streaming and write allocate # - Variable pipeline stages # - Out-of-order execution # - Branch Prediction # - JTAG/ICE # - Vector Floating Point (VFP) unit # arm/mv/gpio.c optional gpio arm/mv/mv_common.c standard arm/mv/mv_localbus.c standard arm/mv/armv5_machdep.c standard arm/mv/mv_pci_ctrl.c optional pci | fdt arm/mv/mv_pci.c optional pci arm/mv/mv_ts.c standard arm/mv/timer.c optional !soc_mv_armada38x dev/cesa/cesa.c optional cesa dev/iicbus/twsi/mv_twsi.c optional twsi dev/mge/if_mge.c optional mge dev/neta/if_mvneta_fdt.c optional neta fdt dev/neta/if_mvneta.c optional neta mdio mii -dev/nand/nfc_mv.c optional nand dev/mvs/mvs_soc.c optional mvs dev/uart/uart_dev_ns8250.c optional uart dev/uart/uart_dev_snps.c optional uart dev/usb/controller/ehci_mv.c optional ehci dev/usb/controller/generic_xhci.c optional xhci dev/ahci/ahci_mv_fdt.c optional ahci Index: head/sys/cam/ata/ata_all.c =================================================================== --- head/sys/cam/ata/ata_all.c (revision 349351) +++ head/sys/cam/ata/ata_all.c (revision 349352) @@ -1,1265 +1,1240 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2009 Alexander Motin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL #include "opt_scsi.h" #include #include #include #include #else #include #include #include #include #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #endif #endif #include #include #include #include #include #include #include #include int ata_version(int ver) { int bit; if (ver == 0xffff) return 0; for (bit = 15; bit >= 0; bit--) if (ver & (1<control & 0x04) return ("SOFT_RESET"); switch (cmd->command) { case 0x00: switch (cmd->features) { case 0x00: return ("NOP FLUSHQUEUE"); case 0x01: return ("NOP AUTOPOLL"); } return ("NOP"); case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR"); case 0x06: switch (cmd->features) { case 0x01: return ("DSM TRIM"); } return "DSM"; case 0x07: switch (cmd->features) { case 0x01: return ("DSM_XL TRIM"); } return "DSM_XL"; case 0x08: return ("DEVICE_RESET"); case 0x0b: return ("REQUEST_SENSE_DATA_EXT"); case 0x12: return ("GET_PHYSICAL_ELEMENT_STATUS"); case 0x20: return ("READ"); case 0x24: return ("READ48"); case 0x25: return ("READ_DMA48"); case 0x26: return ("READ_DMA_QUEUED48"); case 0x27: return ("READ_NATIVE_MAX_ADDRESS48"); case 0x29: return ("READ_MUL48"); case 0x2a: return ("READ_STREAM_DMA48"); case 0x2b: return ("READ_STREAM48"); case 0x2f: return ("READ_LOG_EXT"); case 0x30: return ("WRITE"); case 0x34: return ("WRITE48"); case 0x35: return ("WRITE_DMA48"); case 0x36: return ("WRITE_DMA_QUEUED48"); case 0x37: return ("SET_MAX_ADDRESS48"); case 0x39: return ("WRITE_MUL48"); case 0x3a: return ("WRITE_STREAM_DMA48"); case 0x3b: return ("WRITE_STREAM48"); case 0x3d: return ("WRITE_DMA_FUA48"); case 0x3e: return ("WRITE_DMA_QUEUED_FUA48"); case 0x3f: return ("WRITE_LOG_EXT"); case 0x40: return ("READ_VERIFY"); case 0x42: return ("READ_VERIFY48"); case 0x44: switch (cmd->features) { case 0x01: return ("ZERO_EXT TRIM"); } return "ZERO_EXT"; case 0x45: switch (cmd->features) { case 0x55: return ("WRITE_UNCORRECTABLE48 PSEUDO"); case 0xaa: return ("WRITE_UNCORRECTABLE48 FLAGGED"); } return "WRITE_UNCORRECTABLE48"; case 0x47: return ("READ_LOG_DMA_EXT"); case 0x4a: return ("ZAC_MANAGEMENT_IN"); case 0x51: return ("CONFIGURE_STREAM"); case 0x57: return ("WRITE_LOG_DMA_EXT"); case 0x5b: return ("TRUSTED_NON_DATA"); case 0x5c: return ("TRUSTED_RECEIVE"); case 0x5d: return ("TRUSTED_RECEIVE_DMA"); case 0x5e: return ("TRUSTED_SEND"); case 0x5f: return ("TRUSTED_SEND_DMA"); case 0x60: return ("READ_FPDMA_QUEUED"); case 0x61: return ("WRITE_FPDMA_QUEUED"); case 0x63: switch (cmd->features & 0xf) { case 0x00: return ("NCQ_NON_DATA ABORT NCQ QUEUE"); case 0x01: return ("NCQ_NON_DATA DEADLINE HANDLING"); case 0x02: return ("NCQ_NON_DATA HYBRID DEMOTE BY SIZE"); case 0x03: return ("NCQ_NON_DATA HYBRID CHANGE BY LBA RANGE"); case 0x04: return ("NCQ_NON_DATA HYBRID CONTROL"); case 0x05: return ("NCQ_NON_DATA SET FEATURES"); /* * XXX KDM need common decoding between NCQ and non-NCQ * versions of SET FEATURES. */ case 0x06: return ("NCQ_NON_DATA ZERO EXT"); case 0x07: return ("NCQ_NON_DATA ZAC MANAGEMENT OUT"); } return ("NCQ_NON_DATA"); case 0x64: switch (cmd->sector_count_exp & 0xf) { case 0x00: return ("SEND_FPDMA_QUEUED DATA SET MANAGEMENT"); case 0x01: return ("SEND_FPDMA_QUEUED HYBRID EVICT"); case 0x02: return ("SEND_FPDMA_QUEUED WRITE LOG DMA EXT"); case 0x03: return ("SEND_FPDMA_QUEUED ZAC MANAGEMENT OUT"); case 0x04: return ("SEND_FPDMA_QUEUED DATA SET MANAGEMENT XL"); } return ("SEND_FPDMA_QUEUED"); case 0x65: switch (cmd->sector_count_exp & 0xf) { case 0x01: return ("RECEIVE_FPDMA_QUEUED READ LOG DMA EXT"); case 0x02: return ("RECEIVE_FPDMA_QUEUED ZAC MANAGEMENT IN"); } return ("RECEIVE_FPDMA_QUEUED"); case 0x67: if (cmd->features == 0xec) return ("SEP_ATTN IDENTIFY"); switch (cmd->lba_low) { case 0x00: return ("SEP_ATTN READ BUFFER"); case 0x02: return ("SEP_ATTN RECEIVE DIAGNOSTIC RESULTS"); case 0x80: return ("SEP_ATTN WRITE BUFFER"); case 0x82: return ("SEP_ATTN SEND DIAGNOSTIC"); } return ("SEP_ATTN"); case 0x70: return ("SEEK"); case 0x77: return ("SET_DATE_TIME_EXT"); case 0x78: return ("ACCESSIBLE_MAX_ADDRESS_CONFIGURATION"); case 0x7C: return ("REMOVE_ELEMENT_AND_TRUNCATE"); case 0x87: return ("CFA_TRANSLATE_SECTOR"); case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC"); case 0x92: return ("DOWNLOAD_MICROCODE"); case 0x93: return ("DOWNLOAD_MICROCODE_DMA"); case 0x9a: return ("ZAC_MANAGEMENT_OUT"); case 0xa0: return ("PACKET"); case 0xa1: return ("ATAPI_IDENTIFY"); case 0xa2: return ("SERVICE"); case 0xb0: switch(cmd->features) { case 0xd0: return ("SMART READ ATTR VALUES"); case 0xd1: return ("SMART READ ATTR THRESHOLDS"); case 0xd3: return ("SMART SAVE ATTR VALUES"); case 0xd4: return ("SMART EXECUTE OFFLINE IMMEDIATE"); case 0xd5: return ("SMART READ LOG"); case 0xd6: return ("SMART WRITE LOG"); case 0xd8: return ("SMART ENABLE OPERATION"); case 0xd9: return ("SMART DISABLE OPERATION"); case 0xda: return ("SMART RETURN STATUS"); } return ("SMART"); case 0xb1: return ("DEVICE CONFIGURATION"); case 0xb2: return ("SET_SECTOR_CONFIGURATION_EXT"); case 0xb4: return ("SANITIZE_DEVICE"); case 0xc0: return ("CFA_ERASE"); case 0xc4: return ("READ_MUL"); case 0xc5: return ("WRITE_MUL"); case 0xc6: return ("SET_MULTI"); case 0xc7: return ("READ_DMA_QUEUED"); case 0xc8: return ("READ_DMA"); case 0xca: return ("WRITE_DMA"); case 0xcc: return ("WRITE_DMA_QUEUED"); case 0xcd: return ("CFA_WRITE_MULTIPLE_WITHOUT_ERASE"); case 0xce: return ("WRITE_MUL_FUA48"); case 0xd1: return ("CHECK_MEDIA_CARD_TYPE"); case 0xda: return ("GET_MEDIA_STATUS"); case 0xde: return ("MEDIA_LOCK"); case 0xdf: return ("MEDIA_UNLOCK"); case 0xe0: return ("STANDBY_IMMEDIATE"); case 0xe1: return ("IDLE_IMMEDIATE"); case 0xe2: return ("STANDBY"); case 0xe3: return ("IDLE"); case 0xe4: return ("READ_BUFFER/PM"); case 0xe5: return ("CHECK_POWER_MODE"); case 0xe6: return ("SLEEP"); case 0xe7: return ("FLUSHCACHE"); case 0xe8: return ("WRITE_BUFFER/PM"); case 0xe9: return ("READ_BUFFER_DMA"); case 0xea: return ("FLUSHCACHE48"); case 0xeb: return ("WRITE_BUFFER_DMA"); case 0xec: return ("ATA_IDENTIFY"); case 0xed: return ("MEDIA_EJECT"); case 0xef: /* * XXX KDM need common decoding between NCQ and non-NCQ * versions of SET FEATURES. */ switch (cmd->features) { case 0x02: return ("SETFEATURES ENABLE WCACHE"); case 0x03: return ("SETFEATURES SET TRANSFER MODE"); case 0x05: return ("SETFEATURES ENABLE APM"); case 0x06: return ("SETFEATURES ENABLE PUIS"); case 0x07: return ("SETFEATURES SPIN-UP"); case 0x0b: return ("SETFEATURES ENABLE WRITE READ VERIFY"); case 0x0c: return ("SETFEATURES ENABLE DEVICE LIFE CONTROL"); case 0x10: return ("SETFEATURES ENABLE SATA FEATURE"); case 0x41: return ("SETFEATURES ENABLE FREEFALL CONTROL"); case 0x43: return ("SETFEATURES SET MAX HOST INT SECT TIMES"); case 0x45: return ("SETFEATURES SET RATE BASIS"); case 0x4a: return ("SETFEATURES EXTENDED POWER CONDITIONS"); case 0x50: return ("SETFEATURES ADVANCED BACKGROUD OPERATION"); case 0x55: return ("SETFEATURES DISABLE RCACHE"); case 0x5d: return ("SETFEATURES ENABLE RELIRQ"); case 0x5e: return ("SETFEATURES ENABLE SRVIRQ"); case 0x62: return ("SETFEATURES LONG PHYS SECT ALIGN ERC"); case 0x63: return ("SETFEATURES DSN"); case 0x66: return ("SETFEATURES DISABLE DEFAULTS"); case 0x82: return ("SETFEATURES DISABLE WCACHE"); case 0x85: return ("SETFEATURES DISABLE APM"); case 0x86: return ("SETFEATURES DISABLE PUIS"); case 0x8b: return ("SETFEATURES DISABLE WRITE READ VERIFY"); case 0x8c: return ("SETFEATURES DISABLE DEVICE LIFE CONTROL"); case 0x90: return ("SETFEATURES DISABLE SATA FEATURE"); case 0xaa: return ("SETFEATURES ENABLE RCACHE"); case 0xC1: return ("SETFEATURES DISABLE FREEFALL CONTROL"); case 0xC3: return ("SETFEATURES SENSE DATA REPORTING"); case 0xC4: return ("SETFEATURES NCQ SENSE DATA RETURN"); case 0xCC: return ("SETFEATURES ENABLE DEFAULTS"); case 0xdd: return ("SETFEATURES DISABLE RELIRQ"); case 0xde: return ("SETFEATURES DISABLE SRVIRQ"); } return "SETFEATURES"; case 0xf1: return ("SECURITY_SET_PASSWORD"); case 0xf2: return ("SECURITY_UNLOCK"); case 0xf3: return ("SECURITY_ERASE_PREPARE"); case 0xf4: return ("SECURITY_ERASE_UNIT"); case 0xf5: return ("SECURITY_FREEZE_LOCK"); case 0xf6: return ("SECURITY_DISABLE_PASSWORD"); case 0xf8: return ("READ_NATIVE_MAX_ADDRESS"); case 0xf9: return ("SET_MAX_ADDRESS"); } return "UNKNOWN"; } char * ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len) { struct sbuf sb; int error; if (len == 0) return (""); sbuf_new(&sb, cmd_string, len, SBUF_FIXEDLEN); ata_cmd_sbuf(cmd, &sb); error = sbuf_finish(&sb); if (error != 0 && error != ENOMEM) return (""); return(sbuf_data(&sb)); } void ata_cmd_sbuf(struct ata_cmd *cmd, struct sbuf *sb) { sbuf_printf(sb, "%02x %02x %02x %02x " "%02x %02x %02x %02x %02x %02x %02x %02x", cmd->command, cmd->features, cmd->lba_low, cmd->lba_mid, cmd->lba_high, cmd->device, cmd->lba_low_exp, cmd->lba_mid_exp, cmd->lba_high_exp, cmd->features_exp, cmd->sector_count, cmd->sector_count_exp); } char * ata_res_string(struct ata_res *res, char *res_string, size_t len) { struct sbuf sb; int error; if (len == 0) return (""); sbuf_new(&sb, res_string, len, SBUF_FIXEDLEN); ata_res_sbuf(res, &sb); error = sbuf_finish(&sb); if (error != 0 && error != ENOMEM) return (""); return(sbuf_data(&sb)); } int ata_res_sbuf(struct ata_res *res, struct sbuf *sb) { sbuf_printf(sb, "%02x %02x %02x %02x " "%02x %02x %02x %02x %02x %02x %02x", res->status, res->error, res->lba_low, res->lba_mid, res->lba_high, res->device, res->lba_low_exp, res->lba_mid_exp, res->lba_high_exp, res->sector_count, res->sector_count_exp); return (0); } /* * ata_command_sbuf() returns 0 for success and -1 for failure. */ int ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) { sbuf_printf(sb, "%s. ACB: ", ata_op_string(&ataio->cmd)); ata_cmd_sbuf(&ataio->cmd, sb); return(0); } /* * ata_status_abuf() returns 0 for success and -1 for failure. */ int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb) { sbuf_printf(sb, "ATA status: %02x (%s%s%s%s%s%s%s%s)", ataio->res.status, (ataio->res.status & 0x80) ? "BSY " : "", (ataio->res.status & 0x40) ? "DRDY " : "", (ataio->res.status & 0x20) ? "DF " : "", (ataio->res.status & 0x10) ? "SERV " : "", (ataio->res.status & 0x08) ? "DRQ " : "", (ataio->res.status & 0x04) ? "CORR " : "", (ataio->res.status & 0x02) ? "IDX " : "", (ataio->res.status & 0x01) ? "ERR" : ""); if (ataio->res.status & 1) { sbuf_printf(sb, ", error: %02x (%s%s%s%s%s%s%s%s)", ataio->res.error, (ataio->res.error & 0x80) ? "ICRC " : "", (ataio->res.error & 0x40) ? "UNC " : "", (ataio->res.error & 0x20) ? "MC " : "", (ataio->res.error & 0x10) ? "IDNF " : "", (ataio->res.error & 0x08) ? "MCR " : "", (ataio->res.error & 0x04) ? "ABRT " : "", (ataio->res.error & 0x02) ? "NM " : "", (ataio->res.error & 0x01) ? "ILI" : ""); } return(0); } void ata_print_ident(struct ata_params *ident_data) { const char *proto; char ata[12], sata[12]; ata_print_ident_short(ident_data); proto = (ident_data->config == ATA_PROTO_CFA) ? "CFA" : (ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA"; if (ata_version(ident_data->version_major) == 0) { snprintf(ata, sizeof(ata), "%s", proto); } else if (ata_version(ident_data->version_major) <= 7) { snprintf(ata, sizeof(ata), "%s-%d", proto, ata_version(ident_data->version_major)); } else if (ata_version(ident_data->version_major) == 8) { snprintf(ata, sizeof(ata), "%s8-ACS", proto); } else { snprintf(ata, sizeof(ata), "ACS-%d %s", ata_version(ident_data->version_major) - 7, proto); } if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) { if (ident_data->satacapabilities & ATA_SATA_GEN3) snprintf(sata, sizeof(sata), " SATA 3.x"); else if (ident_data->satacapabilities & ATA_SATA_GEN2) snprintf(sata, sizeof(sata), " SATA 2.x"); else if (ident_data->satacapabilities & ATA_SATA_GEN1) snprintf(sata, sizeof(sata), " SATA 1.x"); else snprintf(sata, sizeof(sata), " SATA"); } else sata[0] = 0; printf(" %s%s device\n", ata, sata); } void ata_print_ident_sbuf(struct ata_params *ident_data, struct sbuf *sb) { const char *proto, *sata; int version; ata_print_ident_short_sbuf(ident_data, sb); sbuf_printf(sb, " "); proto = (ident_data->config == ATA_PROTO_CFA) ? "CFA" : (ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA"; version = ata_version(ident_data->version_major); switch (version) { case 0: sbuf_printf(sb, "%s", proto); break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: sbuf_printf(sb, "%s-%d", proto, version); break; case 8: sbuf_printf(sb, "%s8-ACS", proto); break; default: sbuf_printf(sb, "ACS-%d %s", version - 7, proto); break; } if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) { if (ident_data->satacapabilities & ATA_SATA_GEN3) sata = " SATA 3.x"; else if (ident_data->satacapabilities & ATA_SATA_GEN2) sata = " SATA 2.x"; else if (ident_data->satacapabilities & ATA_SATA_GEN1) sata = " SATA 1.x"; else sata = " SATA"; } else sata = ""; sbuf_printf(sb, "%s device\n", sata); } void ata_print_ident_short(struct ata_params *ident_data) { char product[48], revision[16]; cam_strvis(product, ident_data->model, sizeof(ident_data->model), sizeof(product)); cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision), sizeof(revision)); printf("<%s %s>", product, revision); } void ata_print_ident_short_sbuf(struct ata_params *ident_data, struct sbuf *sb) { sbuf_printf(sb, "<"); cam_strvis_sbuf(sb, ident_data->model, sizeof(ident_data->model), 0); sbuf_printf(sb, " "); cam_strvis_sbuf(sb, ident_data->revision, sizeof(ident_data->revision), 0); sbuf_printf(sb, ">"); } void semb_print_ident(struct sep_identify_data *ident_data) { char in[7], ins[5]; semb_print_ident_short(ident_data); cam_strvis(in, ident_data->interface_id, 6, sizeof(in)); cam_strvis(ins, ident_data->interface_rev, 4, sizeof(ins)); printf(" SEMB %s %s device\n", in, ins); } void semb_print_ident_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb) { semb_print_ident_short_sbuf(ident_data, sb); sbuf_printf(sb, " SEMB "); cam_strvis_sbuf(sb, ident_data->interface_id, 6, 0); sbuf_printf(sb, " "); cam_strvis_sbuf(sb, ident_data->interface_rev, 4, 0); sbuf_printf(sb, " device\n"); } void semb_print_ident_short(struct sep_identify_data *ident_data) { char vendor[9], product[17], revision[5], fw[5]; cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor)); cam_strvis(product, ident_data->product_id, 16, sizeof(product)); cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision)); cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw)); printf("<%s %s %s %s>", vendor, product, revision, fw); } void semb_print_ident_short_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb) { sbuf_printf(sb, "<"); cam_strvis_sbuf(sb, ident_data->vendor_id, 8, 0); sbuf_printf(sb, " "); cam_strvis_sbuf(sb, ident_data->product_id, 16, 0); sbuf_printf(sb, " "); cam_strvis_sbuf(sb, ident_data->product_rev, 4, 0); sbuf_printf(sb, " "); cam_strvis_sbuf(sb, ident_data->firmware_rev, 4, 0); sbuf_printf(sb, ">"); } uint32_t ata_logical_sector_size(struct ata_params *ident_data) { if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE && (ident_data->pss & ATA_PSS_LSSABOVE512)) { return (((u_int32_t)ident_data->lss_1 | ((u_int32_t)ident_data->lss_2 << 16)) * 2); } return (512); } uint64_t ata_physical_sector_size(struct ata_params *ident_data) { if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE) { if (ident_data->pss & ATA_PSS_MULTLS) { return ((uint64_t)ata_logical_sector_size(ident_data) * (1 << (ident_data->pss & ATA_PSS_LSPPS))); } else { return (uint64_t)ata_logical_sector_size(ident_data); } } return (512); } uint64_t ata_logical_sector_offset(struct ata_params *ident_data) { if ((ident_data->lsalign & 0xc000) == 0x4000) { return ((uint64_t)ata_logical_sector_size(ident_data) * (ident_data->lsalign & 0x3fff)); } return (0); } void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count) { bzero(&ataio->cmd, sizeof(ataio->cmd)); ataio->cmd.flags = 0; if (cmd == ATA_READ_DMA || cmd == ATA_READ_DMA_QUEUED || cmd == ATA_WRITE_DMA || cmd == ATA_WRITE_DMA_QUEUED || cmd == ATA_TRUSTED_RECEIVE_DMA || cmd == ATA_TRUSTED_SEND_DMA || cmd == ATA_DOWNLOAD_MICROCODE_DMA || cmd == ATA_READ_BUFFER_DMA || cmd == ATA_WRITE_BUFFER_DMA) ataio->cmd.flags |= CAM_ATAIO_DMA; ataio->cmd.command = cmd; ataio->cmd.features = features; ataio->cmd.lba_low = lba; ataio->cmd.lba_mid = lba >> 8; ataio->cmd.lba_high = lba >> 16; ataio->cmd.device = ATA_DEV_LBA | ((lba >> 24) & 0x0f); ataio->cmd.sector_count = sector_count; } void ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features, uint64_t lba, uint16_t sector_count) { ataio->cmd.flags = CAM_ATAIO_48BIT; if (cmd == ATA_READ_DMA48 || cmd == ATA_READ_DMA_QUEUED48 || cmd == ATA_READ_STREAM_DMA48 || cmd == ATA_WRITE_DMA48 || cmd == ATA_WRITE_DMA_FUA48 || cmd == ATA_WRITE_DMA_QUEUED48 || cmd == ATA_WRITE_DMA_QUEUED_FUA48 || cmd == ATA_WRITE_STREAM_DMA48 || cmd == ATA_DATA_SET_MANAGEMENT || cmd == ATA_READ_LOG_DMA_EXT || cmd == ATA_WRITE_LOG_DMA_EXT) ataio->cmd.flags |= CAM_ATAIO_DMA; ataio->cmd.command = cmd; ataio->cmd.features = features; ataio->cmd.lba_low = lba; ataio->cmd.lba_mid = lba >> 8; ataio->cmd.lba_high = lba >> 16; ataio->cmd.device = ATA_DEV_LBA; ataio->cmd.lba_low_exp = lba >> 24; ataio->cmd.lba_mid_exp = lba >> 32; ataio->cmd.lba_high_exp = lba >> 40; ataio->cmd.features_exp = features >> 8; ataio->cmd.sector_count = sector_count; ataio->cmd.sector_count_exp = sector_count >> 8; ataio->cmd.control = 0; } void ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint64_t lba, uint16_t sector_count) { ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_FPDMA; ataio->cmd.command = cmd; ataio->cmd.features = sector_count; ataio->cmd.lba_low = lba; ataio->cmd.lba_mid = lba >> 8; ataio->cmd.lba_high = lba >> 16; ataio->cmd.device = ATA_DEV_LBA; ataio->cmd.lba_low_exp = lba >> 24; ataio->cmd.lba_mid_exp = lba >> 32; ataio->cmd.lba_high_exp = lba >> 40; ataio->cmd.features_exp = sector_count >> 8; ataio->cmd.sector_count = 0; ataio->cmd.sector_count_exp = 0; ataio->cmd.control = 0; } void ata_reset_cmd(struct ccb_ataio *ataio) { bzero(&ataio->cmd, sizeof(ataio->cmd)); ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT; ataio->cmd.control = 0x04; } void ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port) { bzero(&ataio->cmd, sizeof(ataio->cmd)); ataio->cmd.flags = CAM_ATAIO_NEEDRESULT; ataio->cmd.command = ATA_READ_PM; ataio->cmd.features = reg; ataio->cmd.device = port & 0x0f; } void ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val) { bzero(&ataio->cmd, sizeof(ataio->cmd)); ataio->cmd.flags = 0; ataio->cmd.command = ATA_WRITE_PM; ataio->cmd.features = reg; ataio->cmd.sector_count = val; ataio->cmd.lba_low = val >> 8; ataio->cmd.lba_mid = val >> 16; ataio->cmd.lba_high = val >> 24; ataio->cmd.device = port & 0x0f; } void ata_read_log(struct ccb_ataio *ataio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t log_address, uint32_t page_number, uint16_t block_count, uint32_t protocol, uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout) { uint64_t lba; cam_fill_ataio(ataio, /*retries*/ 1, /*cbfcnp*/ cbfcnp, /*flags*/ CAM_DIR_IN, /*tag_action*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*timeout*/ timeout); lba = (((uint64_t)page_number & 0xff00) << 32) | ((page_number & 0x00ff) << 8) | (log_address & 0xff); ata_48bit_cmd(ataio, /*cmd*/ (protocol & CAM_ATAIO_DMA) ? ATA_READ_LOG_DMA_EXT : ATA_READ_LOG_EXT, /*features*/ 0, /*lba*/ lba, /*sector_count*/ block_count); } void ata_bswap(int8_t *buf, int len) { u_int16_t *ptr = (u_int16_t*)(buf + len); while (--ptr >= (u_int16_t*)buf) *ptr = be16toh(*ptr); } void ata_btrim(int8_t *buf, int len) { int8_t *ptr; for (ptr = buf; ptr < buf+len; ++ptr) if (!*ptr || *ptr == '_') *ptr = ' '; for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr) *ptr = 0; } void ata_bpack(int8_t *src, int8_t *dst, int len) { int i, j, blank; for (i = j = blank = 0 ; i < len; i++) { if (blank && src[i] == ' ') continue; if (blank && src[i] != ' ') { dst[j++] = src[i]; blank = 0; continue; } if (src[i] == ' ') { blank = 1; if (i == 0) continue; } dst[j++] = src[i]; } while (j < len) dst[j++] = 0x00; } int ata_max_pmode(struct ata_params *ap) { if (ap->atavalid & ATA_FLAG_64_70) { if (ap->apiomodes & 0x02) return ATA_PIO4; if (ap->apiomodes & 0x01) return ATA_PIO3; } if (ap->mwdmamodes & 0x04) return ATA_PIO4; if (ap->mwdmamodes & 0x02) return ATA_PIO3; if (ap->mwdmamodes & 0x01) return ATA_PIO2; if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200) return ATA_PIO2; if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100) return ATA_PIO1; if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000) return ATA_PIO0; return ATA_PIO0; } int ata_max_wmode(struct ata_params *ap) { if (ap->mwdmamodes & 0x04) return ATA_WDMA2; if (ap->mwdmamodes & 0x02) return ATA_WDMA1; if (ap->mwdmamodes & 0x01) return ATA_WDMA0; return -1; } int ata_max_umode(struct ata_params *ap) { if (ap->atavalid & ATA_FLAG_88) { if (ap->udmamodes & 0x40) return ATA_UDMA6; if (ap->udmamodes & 0x20) return ATA_UDMA5; if (ap->udmamodes & 0x10) return ATA_UDMA4; if (ap->udmamodes & 0x08) return ATA_UDMA3; if (ap->udmamodes & 0x04) return ATA_UDMA2; if (ap->udmamodes & 0x02) return ATA_UDMA1; if (ap->udmamodes & 0x01) return ATA_UDMA0; } return -1; } int ata_max_mode(struct ata_params *ap, int maxmode) { if (maxmode == 0) maxmode = ATA_DMA_MAX; if (maxmode >= ATA_UDMA0 && ata_max_umode(ap) > 0) return (min(maxmode, ata_max_umode(ap))); if (maxmode >= ATA_WDMA0 && ata_max_wmode(ap) > 0) return (min(maxmode, ata_max_wmode(ap))); return (min(maxmode, ata_max_pmode(ap))); } char * ata_mode2string(int mode) { switch (mode) { case -1: return "UNSUPPORTED"; case 0: return "NONE"; case ATA_PIO0: return "PIO0"; case ATA_PIO1: return "PIO1"; case ATA_PIO2: return "PIO2"; case ATA_PIO3: return "PIO3"; case ATA_PIO4: return "PIO4"; case ATA_WDMA0: return "WDMA0"; case ATA_WDMA1: return "WDMA1"; case ATA_WDMA2: return "WDMA2"; case ATA_UDMA0: return "UDMA0"; case ATA_UDMA1: return "UDMA1"; case ATA_UDMA2: return "UDMA2"; case ATA_UDMA3: return "UDMA3"; case ATA_UDMA4: return "UDMA4"; case ATA_UDMA5: return "UDMA5"; case ATA_UDMA6: return "UDMA6"; default: if (mode & ATA_DMA_MASK) return "BIOSDMA"; else return "BIOSPIO"; } } int ata_string2mode(char *str) { if (!strcasecmp(str, "PIO0")) return (ATA_PIO0); if (!strcasecmp(str, "PIO1")) return (ATA_PIO1); if (!strcasecmp(str, "PIO2")) return (ATA_PIO2); if (!strcasecmp(str, "PIO3")) return (ATA_PIO3); if (!strcasecmp(str, "PIO4")) return (ATA_PIO4); if (!strcasecmp(str, "WDMA0")) return (ATA_WDMA0); if (!strcasecmp(str, "WDMA1")) return (ATA_WDMA1); if (!strcasecmp(str, "WDMA2")) return (ATA_WDMA2); if (!strcasecmp(str, "UDMA0")) return (ATA_UDMA0); if (!strcasecmp(str, "UDMA16")) return (ATA_UDMA0); if (!strcasecmp(str, "UDMA1")) return (ATA_UDMA1); if (!strcasecmp(str, "UDMA25")) return (ATA_UDMA1); if (!strcasecmp(str, "UDMA2")) return (ATA_UDMA2); if (!strcasecmp(str, "UDMA33")) return (ATA_UDMA2); if (!strcasecmp(str, "UDMA3")) return (ATA_UDMA3); if (!strcasecmp(str, "UDMA44")) return (ATA_UDMA3); if (!strcasecmp(str, "UDMA4")) return (ATA_UDMA4); if (!strcasecmp(str, "UDMA66")) return (ATA_UDMA4); if (!strcasecmp(str, "UDMA5")) return (ATA_UDMA5); if (!strcasecmp(str, "UDMA100")) return (ATA_UDMA5); if (!strcasecmp(str, "UDMA6")) return (ATA_UDMA6); if (!strcasecmp(str, "UDMA133")) return (ATA_UDMA6); return (-1); } u_int ata_mode2speed(int mode) { switch (mode) { case ATA_PIO0: default: return (3300); case ATA_PIO1: return (5200); case ATA_PIO2: return (8300); case ATA_PIO3: return (11100); case ATA_PIO4: return (16700); case ATA_WDMA0: return (4200); case ATA_WDMA1: return (13300); case ATA_WDMA2: return (16700); case ATA_UDMA0: return (16700); case ATA_UDMA1: return (25000); case ATA_UDMA2: return (33300); case ATA_UDMA3: return (44400); case ATA_UDMA4: return (66700); case ATA_UDMA5: return (100000); case ATA_UDMA6: return (133000); } } u_int ata_revision2speed(int revision) { switch (revision) { case 1: default: return (150000); case 2: return (300000); case 3: return (600000); } } int ata_speed2revision(u_int speed) { switch (speed) { case 0: return (0); case 150000: return (1); case 300000: return (2); case 600000: return (3); default: return (-1); } } int ata_identify_match(caddr_t identbuffer, caddr_t table_entry) { struct scsi_inquiry_pattern *entry; struct ata_params *ident; entry = (struct scsi_inquiry_pattern *)table_entry; ident = (struct ata_params *)identbuffer; if ((cam_strmatch(ident->model, entry->product, sizeof(ident->model)) == 0) && (cam_strmatch(ident->revision, entry->revision, sizeof(ident->revision)) == 0)) { return (0); } return (-1); } int ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry) { struct scsi_static_inquiry_pattern *entry; struct ata_params *ident; entry = (struct scsi_static_inquiry_pattern *)table_entry; ident = (struct ata_params *)identbuffer; if ((cam_strmatch(ident->model, entry->product, sizeof(ident->model)) == 0) && (cam_strmatch(ident->revision, entry->revision, sizeof(ident->revision)) == 0)) { return (0); } return (-1); } void semb_receive_diagnostic_results(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*), uint8_t tag_action, int pcv, uint8_t page_code, uint8_t *data_ptr, uint16_t length, uint32_t timeout) { length = min(length, 1020); length = (length + 3) & ~3; cam_fill_ataio(ataio, retries, cbfcnp, /*flags*/CAM_DIR_IN, tag_action, data_ptr, length, timeout); ata_28bit_cmd(ataio, ATA_SEP_ATTN, pcv ? page_code : 0, 0x02, length / 4); } void semb_send_diagnostic(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout) { length = min(length, 1020); length = (length + 3) & ~3; cam_fill_ataio(ataio, retries, cbfcnp, /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE, tag_action, data_ptr, length, timeout); ata_28bit_cmd(ataio, ATA_SEP_ATTN, length > 0 ? data_ptr[0] : 0, 0x82, length / 4); } void semb_read_buffer(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*), uint8_t tag_action, uint8_t page_code, uint8_t *data_ptr, uint16_t length, uint32_t timeout) { length = min(length, 1020); length = (length + 3) & ~3; cam_fill_ataio(ataio, retries, cbfcnp, /*flags*/CAM_DIR_IN, tag_action, data_ptr, length, timeout); ata_28bit_cmd(ataio, ATA_SEP_ATTN, page_code, 0x00, length / 4); } void semb_write_buffer(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout) { length = min(length, 1020); length = (length + 3) & ~3; cam_fill_ataio(ataio, retries, cbfcnp, /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE, tag_action, data_ptr, length, timeout); ata_28bit_cmd(ataio, ATA_SEP_ATTN, length > 0 ? data_ptr[0] : 0, 0x80, length / 4); } void ata_zac_mgmt_out(struct ccb_ataio *ataio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), int use_ncq, uint8_t zm_action, uint64_t zone_id, uint8_t zone_flags, uint16_t sector_count, uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout) { uint8_t command_out, ata_flags; uint16_t features_out, sectors_out; uint32_t auxiliary; if (use_ncq == 0) { command_out = ATA_ZAC_MANAGEMENT_OUT; features_out = (zm_action & 0xf) | (zone_flags << 8); if (dxfer_len == 0) { ata_flags = 0; sectors_out = 0; } else { ata_flags = CAM_ATAIO_DMA; /* XXX KDM use sector count? */ sectors_out = ((dxfer_len >> 9) & 0xffff); } auxiliary = 0; } else { if (dxfer_len == 0) { command_out = ATA_NCQ_NON_DATA; features_out = ATA_NCQ_ZAC_MGMT_OUT; sectors_out = 0; } else { command_out = ATA_SEND_FPDMA_QUEUED; /* Note that we're defaulting to normal priority */ sectors_out = ATA_SFPDMA_ZAC_MGMT_OUT << 8; /* * For SEND FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means * that 65536 512 byte blocks are to be tranferred. * In practice, it seems unlikely that we'll see * a transfer that large. */ if (dxfer_len == (65536 * 512)) { features_out = 0; } else { /* * Yes, the caller can theoretically send a * transfer larger than we can handle. * Anyone using this function needs enough * knowledge to avoid doing that. */ features_out = ((dxfer_len >> 9) & 0xffff); } } auxiliary = (zm_action & 0xf) | (zone_flags << 8); ata_flags = CAM_ATAIO_FPDMA; } cam_fill_ataio(ataio, /*retries*/ retries, /*cbfcnp*/ cbfcnp, /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, /*tag_action*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*timeout*/ timeout); ata_48bit_cmd(ataio, /*cmd*/ command_out, /*features*/ features_out, /*lba*/ zone_id, /*sector_count*/ sectors_out); ataio->cmd.flags |= ata_flags; if (auxiliary != 0) { ataio->ata_flags |= ATA_FLAG_AUX; ataio->aux = auxiliary; } } void ata_zac_mgmt_in(struct ccb_ataio *ataio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), int use_ncq, uint8_t zm_action, uint64_t zone_id, uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout) { uint8_t command_out, ata_flags; uint16_t features_out, sectors_out; uint32_t auxiliary; if (use_ncq == 0) { command_out = ATA_ZAC_MANAGEMENT_IN; /* XXX KDM put a macro here */ features_out = (zm_action & 0xf) | (zone_flags << 8); ata_flags = CAM_ATAIO_DMA; sectors_out = ((dxfer_len >> 9) & 0xffff); auxiliary = 0; } else { command_out = ATA_RECV_FPDMA_QUEUED; sectors_out = ATA_RFPDMA_ZAC_MGMT_IN << 8; auxiliary = (zm_action & 0xf) | (zone_flags << 8); ata_flags = CAM_ATAIO_FPDMA; /* * For RECEIVE FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means * that 65536 512 byte blocks are to be tranferred. * In practice, it is unlikely we will see a transfer that * large. */ if (dxfer_len == (65536 * 512)) { features_out = 0; } else { /* * Yes, the caller can theoretically request a * transfer larger than we can handle. * Anyone using this function needs enough * knowledge to avoid doing that. */ features_out = ((dxfer_len >> 9) & 0xffff); } } cam_fill_ataio(ataio, /*retries*/ retries, /*cbfcnp*/ cbfcnp, /*flags*/ CAM_DIR_IN, /*tag_action*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*timeout*/ timeout); ata_48bit_cmd(ataio, /*cmd*/ command_out, /*features*/ features_out, /*lba*/ zone_id, /*sector_count*/ sectors_out); ataio->cmd.flags |= ata_flags; if (auxiliary != 0) { ataio->ata_flags |= ATA_FLAG_AUX; ataio->aux = auxiliary; } } - -void -ata_param_fixup(struct ata_params *ident_buf) -{ - int16_t *ptr; - - for (ptr = (int16_t *)ident_buf; - ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) { - *ptr = le16toh(*ptr); - } - if (strncmp(ident_buf->model, "FX", 2) && - strncmp(ident_buf->model, "NEC", 3) && - strncmp(ident_buf->model, "Pioneer", 7) && - strncmp(ident_buf->model, "SHARP", 5)) { - ata_bswap(ident_buf->model, sizeof(ident_buf->model)); - ata_bswap(ident_buf->revision, sizeof(ident_buf->revision)); - ata_bswap(ident_buf->serial, sizeof(ident_buf->serial)); - } - ata_btrim(ident_buf->model, sizeof(ident_buf->model)); - ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model)); - ata_btrim(ident_buf->revision, sizeof(ident_buf->revision)); - ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision)); - ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); - ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); -} Index: head/sys/cam/ata/ata_all.h =================================================================== --- head/sys/cam/ata/ata_all.h (revision 349351) +++ head/sys/cam/ata/ata_all.h (revision 349352) @@ -1,194 +1,193 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2009 Alexander Motin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD$ */ #ifndef CAM_ATA_ALL_H #define CAM_ATA_ALL_H 1 #include struct ccb_ataio; struct cam_periph; union ccb; #define SID_DMA48 0x01 /* Abuse inq_flags bit to track enabled DMA48. */ #define SID_AEN 0x04 /* Abuse inq_flags bit to track enabled AEN. */ #define SID_DMA 0x10 /* Abuse inq_flags bit to track enabled DMA. */ struct ata_cmd { u_int8_t flags; /* ATA command flags */ #define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */ #define CAM_ATAIO_FPDMA 0x02 /* FPDMA command */ #define CAM_ATAIO_CONTROL 0x04 /* Control, not a command */ #define CAM_ATAIO_NEEDRESULT 0x08 /* Request requires result. */ #define CAM_ATAIO_DMA 0x10 /* DMA command */ u_int8_t command; u_int8_t features; u_int8_t lba_low; u_int8_t lba_mid; u_int8_t lba_high; u_int8_t device; u_int8_t lba_low_exp; u_int8_t lba_mid_exp; u_int8_t lba_high_exp; u_int8_t features_exp; u_int8_t sector_count; u_int8_t sector_count_exp; u_int8_t control; }; struct ata_res { u_int8_t flags; /* ATA command flags */ #define CAM_ATAIO_48BIT 0x01 /* Command has 48-bit format */ u_int8_t status; u_int8_t error; u_int8_t lba_low; u_int8_t lba_mid; u_int8_t lba_high; u_int8_t device; u_int8_t lba_low_exp; u_int8_t lba_mid_exp; u_int8_t lba_high_exp; u_int8_t sector_count; u_int8_t sector_count_exp; }; struct sep_identify_data { uint8_t length; /* Enclosure descriptor length */ uint8_t subenc_id; /* Sub-enclosure identifier */ uint8_t logical_id[8]; /* Enclosure logical identifier (WWN) */ uint8_t vendor_id[8]; /* Vendor identification string */ uint8_t product_id[16]; /* Product identification string */ uint8_t product_rev[4]; /* Product revision string */ uint8_t channel_id; /* Channel identifier */ uint8_t firmware_rev[4];/* Firmware revision */ uint8_t interface_id[6];/* Interface spec ("S-E-S "/"SAF-TE")*/ uint8_t interface_rev[4];/* Interface spec revision */ uint8_t vend_spec[11]; /* Vendor specific information */ }; int ata_version(int ver); char * ata_op_string(struct ata_cmd *cmd); char * ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len); void ata_cmd_sbuf(struct ata_cmd *cmd, struct sbuf *sb); char * ata_res_string(struct ata_res *res, char *res_string, size_t len); int ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); int ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb); int ata_res_sbuf(struct ata_res *res, struct sbuf *sb); void ata_print_ident(struct ata_params *ident_data); void ata_print_ident_sbuf(struct ata_params *ident_data, struct sbuf *sb); void ata_print_ident_short(struct ata_params *ident_data); void ata_print_ident_short_sbuf(struct ata_params *ident_data, struct sbuf *sb); uint32_t ata_logical_sector_size(struct ata_params *ident_data); uint64_t ata_physical_sector_size(struct ata_params *ident_data); uint64_t ata_logical_sector_offset(struct ata_params *ident_data); void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features, uint32_t lba, uint8_t sector_count); void ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features, uint64_t lba, uint16_t sector_count); void ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint64_t lba, uint16_t sector_count); void ata_reset_cmd(struct ccb_ataio *ataio); void ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port); void ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val); void ata_read_log(struct ccb_ataio *ataio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint32_t log_address, uint32_t page_number, uint16_t block_count, uint32_t protocol, uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout); -void ata_param_fixup(struct ata_params *ident_buf); void ata_bswap(int8_t *buf, int len); void ata_btrim(int8_t *buf, int len); void ata_bpack(int8_t *src, int8_t *dst, int len); int ata_max_pmode(struct ata_params *ap); int ata_max_wmode(struct ata_params *ap); int ata_max_umode(struct ata_params *ap); int ata_max_mode(struct ata_params *ap, int maxmode); char * ata_mode2string(int mode); int ata_string2mode(char *str); u_int ata_mode2speed(int mode); u_int ata_revision2speed(int revision); int ata_speed2revision(u_int speed); int ata_identify_match(caddr_t identbuffer, caddr_t table_entry); int ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry); void semb_print_ident(struct sep_identify_data *ident_data); void semb_print_ident_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb); void semb_print_ident_short(struct sep_identify_data *ident_data); void semb_print_ident_short_sbuf(struct sep_identify_data *ident_data, struct sbuf *sb); void semb_receive_diagnostic_results(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*), uint8_t tag_action, int pcv, uint8_t page_code, uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout); void semb_send_diagnostic(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length, uint32_t timeout); void semb_read_buffer(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*), uint8_t tag_action, uint8_t page_code, uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout); void semb_write_buffer(struct ccb_ataio *ataio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length, uint32_t timeout); void ata_zac_mgmt_out(struct ccb_ataio *ataio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), int use_ncq __unused, uint8_t zm_action, uint64_t zone_id, uint8_t zone_flags, uint16_t sector_count, uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout); void ata_zac_mgmt_in(struct ccb_ataio *ataio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), int use_ncq __unused, uint8_t zm_action, uint64_t zone_id, uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len, uint32_t timeout); #endif Index: head/sys/cam/ata/ata_xpt.c =================================================================== --- head/sys/cam/ata/ata_xpt.c (revision 349351) +++ head/sys/cam/ata/ata_xpt.c (revision 349352) @@ -1,2264 +1,2279 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2009 Alexander Motin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for xpt_print below */ #include "opt_cam.h" struct ata_quirk_entry { struct scsi_inquiry_pattern inq_pat; u_int8_t quirks; #define CAM_QUIRK_MAXTAGS 0x01 u_int mintags; u_int maxtags; }; static periph_init_t probe_periph_init; static struct periph_driver probe_driver = { probe_periph_init, "aprobe", TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0, CAM_PERIPH_DRV_EARLY }; PERIPHDRIVER_DECLARE(aprobe, probe_driver); typedef enum { PROBE_RESET, PROBE_IDENTIFY, PROBE_SPINUP, PROBE_SETMODE, PROBE_SETPM, PROBE_SETAPST, PROBE_SETDMAAA, PROBE_SETAN, PROBE_SET_MULTI, PROBE_INQUIRY, PROBE_FULL_INQUIRY, PROBE_PM_PID, PROBE_PM_PRV, PROBE_IDENTIFY_SES, PROBE_IDENTIFY_SAFTE, PROBE_DONE, PROBE_INVALID } probe_action; static char *probe_action_text[] = { "PROBE_RESET", "PROBE_IDENTIFY", "PROBE_SPINUP", "PROBE_SETMODE", "PROBE_SETPM", "PROBE_SETAPST", "PROBE_SETDMAAA", "PROBE_SETAN", "PROBE_SET_MULTI", "PROBE_INQUIRY", "PROBE_FULL_INQUIRY", "PROBE_PM_PID", "PROBE_PM_PRV", "PROBE_IDENTIFY_SES", "PROBE_IDENTIFY_SAFTE", "PROBE_DONE", "PROBE_INVALID" }; #define PROBE_SET_ACTION(softc, newaction) \ do { \ char **text; \ text = probe_action_text; \ CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE, \ ("Probe %s to %s\n", text[(softc)->action], \ text[(newaction)])); \ (softc)->action = (newaction); \ } while(0) typedef enum { PROBE_NO_ANNOUNCE = 0x04 } probe_flags; typedef struct { TAILQ_HEAD(, ccb_hdr) request_ccbs; struct ata_params ident_data; probe_action action; probe_flags flags; uint32_t pm_pid; uint32_t pm_prv; int restart; int spinup; int faults; u_int caps; struct cam_periph *periph; } probe_softc; static struct ata_quirk_entry ata_quirk_table[] = { { /* Default tagged queuing parameters for all devices */ { T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, /*vendor*/"*", /*product*/"*", /*revision*/"*" }, /*quirks*/0, /*mintags*/0, /*maxtags*/0 }, }; static cam_status proberegister(struct cam_periph *periph, void *arg); static void probeschedule(struct cam_periph *probe_periph); static void probestart(struct cam_periph *periph, union ccb *start_ccb); static void proberequestdefaultnegotiation(struct cam_periph *periph); static void probedone(struct cam_periph *periph, union ccb *done_ccb); static void probecleanup(struct cam_periph *periph); static void ata_find_quirk(struct cam_ed *device); static void ata_scan_bus(struct cam_periph *periph, union ccb *ccb); static void ata_scan_lun(struct cam_periph *periph, struct cam_path *path, cam_flags flags, union ccb *ccb); static void xptscandone(struct cam_periph *periph, union ccb *done_ccb); static struct cam_ed * ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id); static void ata_device_transport(struct cam_path *path); static void ata_get_transfer_settings(struct ccb_trans_settings *cts); static void ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_path *path, int async_update); static void ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, struct cam_ed *device, void *async_arg); static void ata_action(union ccb *start_ccb); static void ata_announce_periph(struct cam_periph *periph); static void ata_announce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb); static void ata_proto_announce(struct cam_ed *device); static void ata_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb); static void ata_proto_denounce(struct cam_ed *device); static void ata_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb); static void ata_proto_debug_out(union ccb *ccb); static void semb_proto_announce(struct cam_ed *device); static void semb_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb); static void semb_proto_denounce(struct cam_ed *device); static void semb_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb); static int ata_dma = 1; static int atapi_dma = 1; TUNABLE_INT("hw.ata.ata_dma", &ata_dma); TUNABLE_INT("hw.ata.atapi_dma", &atapi_dma); static struct xpt_xport_ops ata_xport_ops = { .alloc_device = ata_alloc_device, .action = ata_action, .async = ata_dev_async, .announce = ata_announce_periph, .announce_sbuf = ata_announce_periph_sbuf, }; #define ATA_XPT_XPORT(x, X) \ static struct xpt_xport ata_xport_ ## x = { \ .xport = XPORT_ ## X, \ .name = #x, \ .ops = &ata_xport_ops, \ }; \ CAM_XPT_XPORT(ata_xport_ ## x); ATA_XPT_XPORT(ata, ATA); ATA_XPT_XPORT(sata, SATA); #undef ATA_XPORT_XPORT static struct xpt_proto_ops ata_proto_ops_ata = { .announce = ata_proto_announce, .announce_sbuf = ata_proto_announce_sbuf, .denounce = ata_proto_denounce, .denounce_sbuf = ata_proto_denounce_sbuf, .debug_out = ata_proto_debug_out, }; static struct xpt_proto ata_proto_ata = { .proto = PROTO_ATA, .name = "ata", .ops = &ata_proto_ops_ata, }; static struct xpt_proto_ops ata_proto_ops_satapm = { .announce = ata_proto_announce, .announce_sbuf = ata_proto_announce_sbuf, .denounce = ata_proto_denounce, .denounce_sbuf = ata_proto_denounce_sbuf, .debug_out = ata_proto_debug_out, }; static struct xpt_proto ata_proto_satapm = { .proto = PROTO_SATAPM, .name = "satapm", .ops = &ata_proto_ops_satapm, }; static struct xpt_proto_ops ata_proto_ops_semb = { .announce = semb_proto_announce, .announce_sbuf = semb_proto_announce_sbuf, .denounce = semb_proto_denounce, .denounce_sbuf = semb_proto_denounce_sbuf, .debug_out = ata_proto_debug_out, }; static struct xpt_proto ata_proto_semb = { .proto = PROTO_SEMB, .name = "semb", .ops = &ata_proto_ops_semb, }; CAM_XPT_PROTO(ata_proto_ata); CAM_XPT_PROTO(ata_proto_satapm); CAM_XPT_PROTO(ata_proto_semb); static void probe_periph_init() { } static cam_status proberegister(struct cam_periph *periph, void *arg) { union ccb *request_ccb; /* CCB representing the probe request */ probe_softc *softc; request_ccb = (union ccb *)arg; if (request_ccb == NULL) { printf("proberegister: no probe CCB, " "can't register device\n"); return(CAM_REQ_CMP_ERR); } softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_ZERO | M_NOWAIT); if (softc == NULL) { printf("proberegister: Unable to probe new device. " "Unable to allocate softc\n"); return(CAM_REQ_CMP_ERR); } TAILQ_INIT(&softc->request_ccbs); TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, periph_links.tqe); softc->flags = 0; periph->softc = softc; softc->periph = periph; softc->action = PROBE_INVALID; if (cam_periph_acquire(periph) != 0) return (CAM_REQ_CMP_ERR); CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n")); ata_device_transport(periph->path); probeschedule(periph); return(CAM_REQ_CMP); } static void probeschedule(struct cam_periph *periph) { union ccb *ccb; probe_softc *softc; softc = (probe_softc *)periph->softc; ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs); if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) || periph->path->device->protocol == PROTO_SATAPM || periph->path->device->protocol == PROTO_SEMB) PROBE_SET_ACTION(softc, PROBE_RESET); else PROBE_SET_ACTION(softc, PROBE_IDENTIFY); if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE) softc->flags |= PROBE_NO_ANNOUNCE; else softc->flags &= ~PROBE_NO_ANNOUNCE; xpt_schedule(periph, CAM_PRIORITY_XPT); } static void probestart(struct cam_periph *periph, union ccb *start_ccb) { struct ccb_trans_settings cts; struct ccb_ataio *ataio; struct ccb_scsiio *csio; probe_softc *softc; struct cam_path *path; struct ata_params *ident_buf; CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n")); softc = (probe_softc *)periph->softc; path = start_ccb->ccb_h.path; ataio = &start_ccb->ataio; csio = &start_ccb->csio; ident_buf = &periph->path->device->ident_data; if (softc->restart) { softc->restart = 0; if ((path->device->flags & CAM_DEV_UNCONFIGURED) || path->device->protocol == PROTO_SATAPM || path->device->protocol == PROTO_SEMB) softc->action = PROBE_RESET; else softc->action = PROBE_IDENTIFY; } switch (softc->action) { case PROBE_RESET: cam_fill_ataio(ataio, 0, probedone, /*flags*/CAM_DIR_NONE, 0, /*data_ptr*/NULL, /*dxfer_len*/0, 15 * 1000); ata_reset_cmd(ataio); break; case PROBE_IDENTIFY: cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_IN, 0, /*data_ptr*/(u_int8_t *)&softc->ident_data, /*dxfer_len*/sizeof(softc->ident_data), 30 * 1000); if (periph->path->device->protocol == PROTO_ATA) ata_28bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0); else ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0); break; case PROBE_SPINUP: if (bootverbose) xpt_print(path, "Spinning up device\n"); cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_NONE | CAM_HIGH_POWER, 0, /*data_ptr*/NULL, /*dxfer_len*/0, 30 * 1000); ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_PUIS_SPINUP, 0, 0); break; case PROBE_SETMODE: { int mode, wantmode; mode = 0; /* Fetch user modes from SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_ATA) { if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE) mode = cts.xport_specific.ata.mode; } else { if (cts.xport_specific.sata.valid & CTS_SATA_VALID_MODE) mode = cts.xport_specific.sata.mode; } if (periph->path->device->protocol == PROTO_ATA) { if (ata_dma == 0 && (mode == 0 || mode > ATA_PIO_MAX)) mode = ATA_PIO_MAX; } else { if (atapi_dma == 0 && (mode == 0 || mode > ATA_PIO_MAX)) mode = ATA_PIO_MAX; } negotiate: /* Honor device capabilities. */ wantmode = mode = ata_max_mode(ident_buf, mode); /* Report modes to SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { cts.xport_specific.ata.mode = mode; cts.xport_specific.ata.valid = CTS_ATA_VALID_MODE; } else { cts.xport_specific.sata.mode = mode; cts.xport_specific.sata.valid = CTS_SATA_VALID_MODE; } xpt_action((union ccb *)&cts); /* Fetch current modes from SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_ATA) { if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE) mode = cts.xport_specific.ata.mode; } else { if (cts.xport_specific.ata.valid & CTS_SATA_VALID_MODE) mode = cts.xport_specific.sata.mode; } /* If SIM disagree - renegotiate. */ if (mode != wantmode) goto negotiate; /* Remember what transport thinks about DMA. */ if (mode < ATA_DMA) path->device->inq_flags &= ~SID_DMA; else path->device->inq_flags |= SID_DMA; xpt_async(AC_GETDEV_CHANGED, path, NULL); cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_NONE, 0, /*data_ptr*/NULL, /*dxfer_len*/0, 30 * 1000); ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode); break; } case PROBE_SETPM: cam_fill_ataio(ataio, 1, probedone, CAM_DIR_NONE, 0, NULL, 0, 30*1000); ata_28bit_cmd(ataio, ATA_SETFEATURES, (softc->caps & CTS_SATA_CAPS_H_PMREQ) ? 0x10 : 0x90, 0, 0x03); break; case PROBE_SETAPST: cam_fill_ataio(ataio, 1, probedone, CAM_DIR_NONE, 0, NULL, 0, 30*1000); ata_28bit_cmd(ataio, ATA_SETFEATURES, (softc->caps & CTS_SATA_CAPS_H_APST) ? 0x10 : 0x90, 0, 0x07); break; case PROBE_SETDMAAA: cam_fill_ataio(ataio, 1, probedone, CAM_DIR_NONE, 0, NULL, 0, 30*1000); ata_28bit_cmd(ataio, ATA_SETFEATURES, (softc->caps & CTS_SATA_CAPS_H_DMAAA) ? 0x10 : 0x90, 0, 0x02); break; case PROBE_SETAN: /* Remember what transport thinks about AEN. */ if (softc->caps & CTS_SATA_CAPS_H_AN) path->device->inq_flags |= SID_AEN; else path->device->inq_flags &= ~SID_AEN; xpt_async(AC_GETDEV_CHANGED, path, NULL); cam_fill_ataio(ataio, 1, probedone, CAM_DIR_NONE, 0, NULL, 0, 30*1000); ata_28bit_cmd(ataio, ATA_SETFEATURES, (softc->caps & CTS_SATA_CAPS_H_AN) ? 0x10 : 0x90, 0, 0x05); break; case PROBE_SET_MULTI: { u_int sectors, bytecount; bytecount = 8192; /* SATA maximum */ /* Fetch user bytecount from SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_ATA) { if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) bytecount = cts.xport_specific.ata.bytecount; } else { if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) bytecount = cts.xport_specific.sata.bytecount; } /* Honor device capabilities. */ sectors = max(1, min(ident_buf->sectors_intr & 0xff, bytecount / ata_logical_sector_size(ident_buf))); /* Report bytecount to SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { cts.xport_specific.ata.bytecount = sectors * ata_logical_sector_size(ident_buf); cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; } else { cts.xport_specific.sata.bytecount = sectors * ata_logical_sector_size(ident_buf); cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; } xpt_action((union ccb *)&cts); /* Fetch current bytecount from SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_ATA) { if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) bytecount = cts.xport_specific.ata.bytecount; } else { if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) bytecount = cts.xport_specific.sata.bytecount; } sectors = bytecount / ata_logical_sector_size(ident_buf); cam_fill_ataio(ataio, 1, probedone, CAM_DIR_NONE, 0, NULL, 0, 30*1000); ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, sectors); break; } case PROBE_INQUIRY: { u_int bytecount; bytecount = 8192; /* SATA maximum */ /* Fetch user bytecount from SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_ATA) { if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT) bytecount = cts.xport_specific.ata.bytecount; } else { if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT) bytecount = cts.xport_specific.sata.bytecount; } /* Honor device capabilities. */ bytecount &= ~1; bytecount = max(2, min(65534, bytecount)); if (ident_buf->satacapabilities != 0x0000 && ident_buf->satacapabilities != 0xffff) { bytecount = min(8192, bytecount); } /* Report bytecount to SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_ATA) { cts.xport_specific.ata.bytecount = bytecount; cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT; } else { cts.xport_specific.sata.bytecount = bytecount; cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT; } xpt_action((union ccb *)&cts); /* FALLTHROUGH */ } case PROBE_FULL_INQUIRY: { u_int inquiry_len; struct scsi_inquiry_data *inq_buf = &periph->path->device->inq_data; if (softc->action == PROBE_INQUIRY) inquiry_len = SHORT_INQUIRY_LENGTH; else inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf); /* * Some parallel SCSI devices fail to send an * ignore wide residue message when dealing with * odd length inquiry requests. Round up to be * safe. */ inquiry_len = roundup2(inquiry_len, 2); scsi_inquiry(csio, /*retries*/1, probedone, MSG_SIMPLE_Q_TAG, (u_int8_t *)inq_buf, inquiry_len, /*evpd*/FALSE, /*page_code*/0, SSD_MIN_SIZE, /*timeout*/60 * 1000); break; } case PROBE_PM_PID: cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_NONE, 0, /*data_ptr*/NULL, /*dxfer_len*/0, 10 * 1000); ata_pm_read_cmd(ataio, 0, 15); break; case PROBE_PM_PRV: cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_NONE, 0, /*data_ptr*/NULL, /*dxfer_len*/0, 10 * 1000); ata_pm_read_cmd(ataio, 1, 15); break; case PROBE_IDENTIFY_SES: cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_IN, 0, /*data_ptr*/(u_int8_t *)&softc->ident_data, /*dxfer_len*/sizeof(softc->ident_data), 30 * 1000); ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x02, sizeof(softc->ident_data) / 4); break; case PROBE_IDENTIFY_SAFTE: cam_fill_ataio(ataio, 1, probedone, /*flags*/CAM_DIR_IN, 0, /*data_ptr*/(u_int8_t *)&softc->ident_data, /*dxfer_len*/sizeof(softc->ident_data), 30 * 1000); ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x00, sizeof(softc->ident_data) / 4); break; default: panic("probestart: invalid action state 0x%x\n", softc->action); } start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; xpt_action(start_ccb); } static void proberequestdefaultnegotiation(struct cam_periph *periph) { struct ccb_trans_settings cts; xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) return; cts.xport_specific.valid = 0; cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); } static void probedone(struct cam_periph *periph, union ccb *done_ccb) { struct ccb_trans_settings cts; struct ata_params *ident_buf; struct scsi_inquiry_data *inq_buf; probe_softc *softc; struct cam_path *path; cam_status status; u_int32_t priority; u_int caps; int changed = 1, found = 1; static const uint8_t fake_device_id_hdr[8] = {0, SVPD_DEVICE_ID, 0, 12, SVPD_ID_CODESET_BINARY, SVPD_ID_TYPE_NAA, 0, 8}; CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n")); softc = (probe_softc *)periph->softc; path = done_ccb->ccb_h.path; priority = done_ccb->ccb_h.pinfo.priority; ident_buf = &path->device->ident_data; inq_buf = &path->device->inq_data; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (cam_periph_error(done_ccb, 0, softc->restart ? (SF_NO_RECOVERY | SF_NO_RETRY) : 0 ) == ERESTART) { out: /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ cam_release_devq(path, 0, 0, 0, FALSE); return; } if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge the queue */ xpt_release_devq(path, /*count*/1, /*run_queue*/TRUE); } status = done_ccb->ccb_h.status & CAM_STATUS_MASK; if (softc->restart) { softc->faults++; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_CMD_TIMEOUT) softc->faults += 4; if (softc->faults < 10) goto done; else softc->restart = 0; /* Old PIO2 devices may not support mode setting. */ } else if (softc->action == PROBE_SETMODE && status == CAM_ATA_STATUS_ERROR && ata_max_pmode(ident_buf) <= ATA_PIO2 && (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0) { goto noerror; /* * Some old WD SATA disks report supported and enabled * device-initiated interface power management, but return * ABORT on attempt to disable it. */ } else if (softc->action == PROBE_SETPM && status == CAM_ATA_STATUS_ERROR) { goto noerror; /* * Some old WD SATA disks have broken SPINUP handling. * If we really fail to spin up the disk, then there will be * some media access errors later on, but at least we will * have a device to interact with for recovery attempts. */ } else if (softc->action == PROBE_SPINUP && status == CAM_ATA_STATUS_ERROR) { goto noerror; /* * Some HP SATA disks report supported DMA Auto-Activation, * but return ABORT on attempt to enable it. */ } else if (softc->action == PROBE_SETDMAAA && status == CAM_ATA_STATUS_ERROR) { goto noerror; /* * SES and SAF-TE SEPs have different IDENTIFY commands, * but SATA specification doesn't tell how to identify them. * Until better way found, just try another if first fail. */ } else if (softc->action == PROBE_IDENTIFY_SES && status == CAM_ATA_STATUS_ERROR) { PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } /* * If we get to this point, we got an error status back * from the inquiry and the error status doesn't require * automatically retrying the command. Therefore, the * inquiry failed. If we had inquiry information before * for this device, but this latest inquiry command failed, * the device has probably gone away. If this device isn't * already marked unconfigured, notify the peripheral * drivers that this device is no more. */ device_fail: if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0) xpt_async(AC_LOST_DEVICE, path, NULL); PROBE_SET_ACTION(softc, PROBE_INVALID); found = 0; goto done; } noerror: if (softc->restart) goto done; switch (softc->action) { case PROBE_RESET: { int sign = (done_ccb->ataio.res.lba_high << 8) + done_ccb->ataio.res.lba_mid; CAM_DEBUG(path, CAM_DEBUG_PROBE, ("SIGNATURE: %04x\n", sign)); if (sign == 0x0000 && done_ccb->ccb_h.target_id != 15) { path->device->protocol = PROTO_ATA; PROBE_SET_ACTION(softc, PROBE_IDENTIFY); } else if (sign == 0x9669 && done_ccb->ccb_h.target_id == 15) { /* Report SIM that PM is present. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.pm_present = 1; cts.xport_specific.sata.valid = CTS_SATA_VALID_PM; xpt_action((union ccb *)&cts); path->device->protocol = PROTO_SATAPM; PROBE_SET_ACTION(softc, PROBE_PM_PID); } else if (sign == 0xc33c && done_ccb->ccb_h.target_id != 15) { path->device->protocol = PROTO_SEMB; PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SES); } else if (sign == 0xeb14 && done_ccb->ccb_h.target_id != 15) { path->device->protocol = PROTO_SCSI; PROBE_SET_ACTION(softc, PROBE_IDENTIFY); } else { if (done_ccb->ccb_h.target_id != 15) { xpt_print(path, "Unexpected signature 0x%04x\n", sign); } goto device_fail; } xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } case PROBE_IDENTIFY: { struct ccb_pathinq cpi; + int16_t *ptr; int veto = 0; - /* - * Convert to host byte order, and fix the strings. - */ ident_buf = &softc->ident_data; - ata_param_fixup(ident_buf); + for (ptr = (int16_t *)ident_buf; + ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) { + *ptr = le16toh(*ptr); + } /* * Allow others to veto this ATA disk attachment. This * is mainly used by VMs, whose disk controllers may * share the disks with the simulated ATA controllers. */ EVENTHANDLER_INVOKE(ada_probe_veto, path, ident_buf, &veto); if (veto) { goto device_fail; } + if (strncmp(ident_buf->model, "FX", 2) && + strncmp(ident_buf->model, "NEC", 3) && + strncmp(ident_buf->model, "Pioneer", 7) && + strncmp(ident_buf->model, "SHARP", 5)) { + ata_bswap(ident_buf->model, sizeof(ident_buf->model)); + ata_bswap(ident_buf->revision, sizeof(ident_buf->revision)); + ata_bswap(ident_buf->serial, sizeof(ident_buf->serial)); + } + ata_btrim(ident_buf->model, sizeof(ident_buf->model)); + ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model)); + ata_btrim(ident_buf->revision, sizeof(ident_buf->revision)); + ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision)); + ata_btrim(ident_buf->serial, sizeof(ident_buf->serial)); + ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial)); /* Device may need spin-up before IDENTIFY become valid. */ if ((ident_buf->specconf == 0x37c8 || ident_buf->specconf == 0x738c) && ((ident_buf->config & ATA_RESP_INCOMPLETE) || softc->spinup == 0)) { PROBE_SET_ACTION(softc, PROBE_SPINUP); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } ident_buf = &path->device->ident_data; if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { /* Check that it is the same device. */ if (bcmp(softc->ident_data.model, ident_buf->model, sizeof(ident_buf->model)) || bcmp(softc->ident_data.revision, ident_buf->revision, sizeof(ident_buf->revision)) || bcmp(softc->ident_data.serial, ident_buf->serial, sizeof(ident_buf->serial))) { /* Device changed. */ xpt_async(AC_LOST_DEVICE, path, NULL); } else { bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); changed = 0; } } if (changed) { bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); /* Clean up from previous instance of this device */ if (path->device->serial_num != NULL) { free(path->device->serial_num, M_CAMXPT); path->device->serial_num = NULL; path->device->serial_num_len = 0; } if (path->device->device_id != NULL) { free(path->device->device_id, M_CAMXPT); path->device->device_id = NULL; path->device->device_id_len = 0; } path->device->serial_num = (u_int8_t *)malloc((sizeof(ident_buf->serial) + 1), M_CAMXPT, M_NOWAIT); if (path->device->serial_num != NULL) { bcopy(ident_buf->serial, path->device->serial_num, sizeof(ident_buf->serial)); path->device->serial_num[sizeof(ident_buf->serial)] = '\0'; path->device->serial_num_len = strlen(path->device->serial_num); } if (ident_buf->enabled.extension & ATA_SUPPORT_64BITWWN) { path->device->device_id = malloc(16, M_CAMXPT, M_NOWAIT); if (path->device->device_id != NULL) { path->device->device_id_len = 16; bcopy(&fake_device_id_hdr, path->device->device_id, 8); bcopy(ident_buf->wwn, path->device->device_id + 8, 8); ata_bswap(path->device->device_id + 8, 8); } } path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; xpt_async(AC_GETDEV_CHANGED, path, NULL); } if (ident_buf->satacapabilities & ATA_SUPPORT_NCQ) { path->device->mintags = 2; path->device->maxtags = ATA_QUEUE_LEN(ident_buf->queue) + 1; } ata_find_quirk(path->device); if (path->device->mintags != 0 && path->bus->sim->max_tagged_dev_openings != 0) { /* Check if the SIM does not want queued commands. */ xpt_path_inq(&cpi, path); if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_inquiry & PI_TAG_ABLE)) { /* Report SIM which tags are allowed. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.tags = path->device->maxtags; cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS; xpt_action((union ccb *)&cts); } } ata_device_transport(path); if (changed) proberequestdefaultnegotiation(periph); PROBE_SET_ACTION(softc, PROBE_SETMODE); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } case PROBE_SPINUP: if (bootverbose) xpt_print(path, "Spin-up done\n"); softc->spinup = 1; PROBE_SET_ACTION(softc, PROBE_IDENTIFY); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; case PROBE_SETMODE: /* Set supported bits. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_SATA && cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H; else if (path->device->transport == XPORT_ATA && cts.xport_specific.ata.valid & CTS_ATA_VALID_CAPS) caps = cts.xport_specific.ata.caps & CTS_ATA_CAPS_H; else caps = 0; if (path->device->transport == XPORT_SATA && ident_buf->satacapabilities != 0xffff) { if (ident_buf->satacapabilities & ATA_SUPPORT_IFPWRMNGTRCV) caps |= CTS_SATA_CAPS_D_PMREQ; if (ident_buf->satacapabilities & ATA_SUPPORT_HAPST) caps |= CTS_SATA_CAPS_D_APST; } /* Mask unwanted bits. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); if (path->device->transport == XPORT_SATA && cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) caps &= cts.xport_specific.sata.caps; else if (path->device->transport == XPORT_ATA && cts.xport_specific.ata.valid & CTS_ATA_VALID_CAPS) caps &= cts.xport_specific.ata.caps; else caps = 0; /* * Remember what transport thinks about 48-bit DMA. If * capability information is not provided or transport is * SATA, we take support for granted. */ if (!(path->device->inq_flags & SID_DMA) || (path->device->transport == XPORT_ATA && (cts.xport_specific.ata.valid & CTS_ATA_VALID_CAPS) && !(caps & CTS_ATA_CAPS_H_DMA48))) path->device->inq_flags &= ~SID_DMA48; else path->device->inq_flags |= SID_DMA48; /* Store result to SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; if (path->device->transport == XPORT_SATA) { cts.xport_specific.sata.caps = caps; cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS; } else { cts.xport_specific.ata.caps = caps; cts.xport_specific.ata.valid = CTS_ATA_VALID_CAPS; } xpt_action((union ccb *)&cts); softc->caps = caps; if (path->device->transport != XPORT_SATA) goto notsata; if ((ident_buf->satasupport & ATA_SUPPORT_IFPWRMNGT) && (!(softc->caps & CTS_SATA_CAPS_H_PMREQ)) != (!(ident_buf->sataenabled & ATA_SUPPORT_IFPWRMNGT))) { PROBE_SET_ACTION(softc, PROBE_SETPM); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } /* FALLTHROUGH */ case PROBE_SETPM: if (ident_buf->satacapabilities != 0xffff && (ident_buf->satacapabilities & ATA_SUPPORT_DAPST) && (!(softc->caps & CTS_SATA_CAPS_H_APST)) != (!(ident_buf->sataenabled & ATA_ENABLED_DAPST))) { PROBE_SET_ACTION(softc, PROBE_SETAPST); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } /* FALLTHROUGH */ case PROBE_SETAPST: if ((ident_buf->satasupport & ATA_SUPPORT_AUTOACTIVATE) && (!(softc->caps & CTS_SATA_CAPS_H_DMAAA)) != (!(ident_buf->sataenabled & ATA_SUPPORT_AUTOACTIVATE))) { PROBE_SET_ACTION(softc, PROBE_SETDMAAA); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } /* FALLTHROUGH */ case PROBE_SETDMAAA: if (path->device->protocol != PROTO_ATA && (ident_buf->satasupport & ATA_SUPPORT_ASYNCNOTIF) && (!(softc->caps & CTS_SATA_CAPS_H_AN)) != (!(ident_buf->sataenabled & ATA_SUPPORT_ASYNCNOTIF))) { PROBE_SET_ACTION(softc, PROBE_SETAN); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } /* FALLTHROUGH */ case PROBE_SETAN: notsata: if (path->device->protocol == PROTO_ATA) { PROBE_SET_ACTION(softc, PROBE_SET_MULTI); } else { PROBE_SET_ACTION(softc, PROBE_INQUIRY); } xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; case PROBE_SET_MULTI: if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; case PROBE_INQUIRY: case PROBE_FULL_INQUIRY: { u_int8_t periph_qual, len; path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID; periph_qual = SID_QUAL(inq_buf); if (periph_qual != SID_QUAL_LU_CONNECTED && periph_qual != SID_QUAL_LU_OFFLINE) break; /* * We conservatively request only * SHORT_INQUIRY_LEN bytes of inquiry * information during our first try * at sending an INQUIRY. If the device * has more information to give, * perform a second request specifying * the amount of information the device * is willing to give. */ len = inq_buf->additional_length + offsetof(struct scsi_inquiry_data, additional_length) + 1; if (softc->action == PROBE_INQUIRY && len > SHORT_INQUIRY_LENGTH) { PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; } ata_device_transport(path); if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; } case PROBE_PM_PID: if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0) bzero(ident_buf, sizeof(*ident_buf)); softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) + (done_ccb->ataio.res.lba_mid << 16) + (done_ccb->ataio.res.lba_low << 8) + done_ccb->ataio.res.sector_count; ((uint32_t *)ident_buf)[0] = softc->pm_pid; snprintf(ident_buf->model, sizeof(ident_buf->model), "Port Multiplier %08x", softc->pm_pid); PROBE_SET_ACTION(softc, PROBE_PM_PRV); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); goto out; case PROBE_PM_PRV: softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) + (done_ccb->ataio.res.lba_mid << 16) + (done_ccb->ataio.res.lba_low << 8) + done_ccb->ataio.res.sector_count; ((uint32_t *)ident_buf)[1] = softc->pm_prv; snprintf(ident_buf->revision, sizeof(ident_buf->revision), "%04x", softc->pm_prv); path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; ata_device_transport(path); if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) proberequestdefaultnegotiation(periph); /* Set supported bits. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb *)&cts); if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H; else caps = 0; /* All PMPs must support PM requests. */ caps |= CTS_SATA_CAPS_D_PMREQ; /* Mask unwanted bits. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_USER_SETTINGS; xpt_action((union ccb *)&cts); if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS) caps &= cts.xport_specific.sata.caps; else caps = 0; /* Remember what transport thinks about AEN. */ if ((caps & CTS_SATA_CAPS_H_AN) && path->device->protocol != PROTO_ATA) path->device->inq_flags |= SID_AEN; else path->device->inq_flags &= ~SID_AEN; /* Store result to SIM. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.caps = caps; cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS; xpt_action((union ccb *)&cts); softc->caps = caps; xpt_async(AC_GETDEV_CHANGED, path, NULL); if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); } else { done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); xpt_async(AC_SCSI_AEN, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; case PROBE_IDENTIFY_SES: case PROBE_IDENTIFY_SAFTE: if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { /* Check that it is the same device. */ if (bcmp(&softc->ident_data, ident_buf, 53)) { /* Device changed. */ xpt_async(AC_LOST_DEVICE, path, NULL); } else { bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); changed = 0; } } if (changed) { bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params)); /* Clean up from previous instance of this device */ if (path->device->device_id != NULL) { free(path->device->device_id, M_CAMXPT); path->device->device_id = NULL; path->device->device_id_len = 0; } path->device->device_id = malloc(16, M_CAMXPT, M_NOWAIT); if (path->device->device_id != NULL) { path->device->device_id_len = 16; bcopy(&fake_device_id_hdr, path->device->device_id, 8); bcopy(((uint8_t*)ident_buf) + 2, path->device->device_id + 8, 8); } path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID; } ata_device_transport(path); if (changed) proberequestdefaultnegotiation(periph); if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); xpt_async(AC_FOUND_DEVICE, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; default: panic("probedone: invalid action state 0x%x\n", softc->action); } done: if (softc->restart) { softc->restart = 0; xpt_release_ccb(done_ccb); probeschedule(periph); goto out; } xpt_release_ccb(done_ccb); CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n")); while ((done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs))) { TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe); done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR; xpt_done(done_ccb); } /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ cam_release_devq(path, 0, 0, 0, FALSE); cam_periph_invalidate(periph); cam_periph_release_locked(periph); } static void probecleanup(struct cam_periph *periph) { free(periph->softc, M_CAMXPT); } static void ata_find_quirk(struct cam_ed *device) { struct ata_quirk_entry *quirk; caddr_t match; match = cam_quirkmatch((caddr_t)&device->ident_data, (caddr_t)ata_quirk_table, nitems(ata_quirk_table), sizeof(*ata_quirk_table), ata_identify_match); if (match == NULL) panic("xpt_find_quirk: device didn't match wildcard entry!!"); quirk = (struct ata_quirk_entry *)match; device->quirk = quirk; if (quirk->quirks & CAM_QUIRK_MAXTAGS) { device->mintags = quirk->mintags; device->maxtags = quirk->maxtags; } } typedef struct { union ccb *request_ccb; struct ccb_pathinq *cpi; int counter; } ata_scan_bus_info; /* * To start a scan, request_ccb is an XPT_SCAN_BUS ccb. * As the scan progresses, xpt_scan_bus is used as the * callback on completion function. */ static void ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb) { struct cam_path *path; ata_scan_bus_info *scan_info; union ccb *work_ccb, *reset_ccb; struct mtx *mtx; cam_status status; CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_scan_bus\n")); switch (request_ccb->ccb_h.func_code) { case XPT_SCAN_BUS: case XPT_SCAN_TGT: /* Find out the characteristics of the bus */ work_ccb = xpt_alloc_ccb_nowait(); if (work_ccb == NULL) { request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(request_ccb); return; } xpt_path_inq(&work_ccb->cpi, request_ccb->ccb_h.path); if (work_ccb->ccb_h.status != CAM_REQ_CMP) { request_ccb->ccb_h.status = work_ccb->ccb_h.status; xpt_free_ccb(work_ccb); xpt_done(request_ccb); return; } /* We may need to reset bus first, if we haven't done it yet. */ if ((work_ccb->cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) && !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) && !timevalisset(&request_ccb->ccb_h.path->bus->last_reset)) { reset_ccb = xpt_alloc_ccb_nowait(); if (reset_ccb == NULL) { request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_free_ccb(work_ccb); xpt_done(request_ccb); return; } xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path, CAM_PRIORITY_NONE); reset_ccb->ccb_h.func_code = XPT_RESET_BUS; xpt_action(reset_ccb); if (reset_ccb->ccb_h.status != CAM_REQ_CMP) { request_ccb->ccb_h.status = reset_ccb->ccb_h.status; xpt_free_ccb(reset_ccb); xpt_free_ccb(work_ccb); xpt_done(request_ccb); return; } xpt_free_ccb(reset_ccb); } /* Save some state for use while we probe for devices */ scan_info = (ata_scan_bus_info *) malloc(sizeof(ata_scan_bus_info), M_CAMXPT, M_NOWAIT); if (scan_info == NULL) { request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_free_ccb(work_ccb); xpt_done(request_ccb); return; } scan_info->request_ccb = request_ccb; scan_info->cpi = &work_ccb->cpi; /* If PM supported, probe it first. */ if (scan_info->cpi->hba_inquiry & PI_SATAPM) scan_info->counter = scan_info->cpi->max_target; else scan_info->counter = 0; work_ccb = xpt_alloc_ccb_nowait(); if (work_ccb == NULL) { free(scan_info, M_CAMXPT); request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL; xpt_done(request_ccb); break; } mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path); goto scan_next; case XPT_SCAN_LUN: work_ccb = request_ccb; /* Reuse the same CCB to query if a device was really found */ scan_info = (ata_scan_bus_info *)work_ccb->ccb_h.ppriv_ptr0; mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path); mtx_lock(mtx); /* If there is PMP... */ if ((scan_info->cpi->hba_inquiry & PI_SATAPM) && (scan_info->counter == scan_info->cpi->max_target)) { if (work_ccb->ccb_h.status == CAM_REQ_CMP) { /* everything else will be probed by it */ /* Free the current request path- we're done with it. */ xpt_free_path(work_ccb->ccb_h.path); goto done; } else { struct ccb_trans_settings cts; /* Report SIM that PM is absent. */ bzero(&cts, sizeof(cts)); xpt_setup_ccb(&cts.ccb_h, work_ccb->ccb_h.path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.xport_specific.sata.pm_present = 0; cts.xport_specific.sata.valid = CTS_SATA_VALID_PM; xpt_action((union ccb *)&cts); } } /* Free the current request path- we're done with it. */ xpt_free_path(work_ccb->ccb_h.path); if (scan_info->counter == ((scan_info->cpi->hba_inquiry & PI_SATAPM) ? 0 : scan_info->cpi->max_target)) { done: mtx_unlock(mtx); xpt_free_ccb(work_ccb); xpt_free_ccb((union ccb *)scan_info->cpi); request_ccb = scan_info->request_ccb; free(scan_info, M_CAMXPT); request_ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(request_ccb); break; } /* Take next device. Wrap from max (PMP) to 0. */ scan_info->counter = (scan_info->counter + 1 ) % (scan_info->cpi->max_target + 1); scan_next: status = xpt_create_path(&path, NULL, scan_info->request_ccb->ccb_h.path_id, scan_info->counter, 0); if (status != CAM_REQ_CMP) { if (request_ccb->ccb_h.func_code == XPT_SCAN_LUN) mtx_unlock(mtx); printf("xpt_scan_bus: xpt_create_path failed" " with status %#x, bus scan halted\n", status); xpt_free_ccb(work_ccb); xpt_free_ccb((union ccb *)scan_info->cpi); request_ccb = scan_info->request_ccb; free(scan_info, M_CAMXPT); request_ccb->ccb_h.status = status; xpt_done(request_ccb); break; } xpt_setup_ccb(&work_ccb->ccb_h, path, scan_info->request_ccb->ccb_h.pinfo.priority); work_ccb->ccb_h.func_code = XPT_SCAN_LUN; work_ccb->ccb_h.cbfcnp = ata_scan_bus; work_ccb->ccb_h.flags |= CAM_UNLOCKED; work_ccb->ccb_h.ppriv_ptr0 = scan_info; work_ccb->crcn.flags = scan_info->request_ccb->crcn.flags; mtx_unlock(mtx); if (request_ccb->ccb_h.func_code == XPT_SCAN_LUN) mtx = NULL; xpt_action(work_ccb); if (mtx != NULL) mtx_lock(mtx); break; default: break; } } static void ata_scan_lun(struct cam_periph *periph, struct cam_path *path, cam_flags flags, union ccb *request_ccb) { struct ccb_pathinq cpi; cam_status status; struct cam_path *new_path; struct cam_periph *old_periph; int lock; CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_scan_lun\n")); xpt_path_inq(&cpi, path); if (cpi.ccb_h.status != CAM_REQ_CMP) { if (request_ccb != NULL) { request_ccb->ccb_h.status = cpi.ccb_h.status; xpt_done(request_ccb); } return; } if (request_ccb == NULL) { request_ccb = xpt_alloc_ccb_nowait(); if (request_ccb == NULL) { xpt_print(path, "xpt_scan_lun: can't allocate CCB, " "can't continue\n"); return; } status = xpt_create_path(&new_path, NULL, path->bus->path_id, path->target->target_id, path->device->lun_id); if (status != CAM_REQ_CMP) { xpt_print(path, "xpt_scan_lun: can't create path, " "can't continue\n"); xpt_free_ccb(request_ccb); return; } xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_XPT); request_ccb->ccb_h.cbfcnp = xptscandone; request_ccb->ccb_h.flags |= CAM_UNLOCKED; request_ccb->ccb_h.func_code = XPT_SCAN_LUN; request_ccb->crcn.flags = flags; } lock = (xpt_path_owned(path) == 0); if (lock) xpt_path_lock(path); if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) { if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) { probe_softc *softc; softc = (probe_softc *)old_periph->softc; TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, periph_links.tqe); softc->restart = 1; } else { request_ccb->ccb_h.status = CAM_REQ_CMP_ERR; xpt_done(request_ccb); } } else { status = cam_periph_alloc(proberegister, NULL, probecleanup, probestart, "aprobe", CAM_PERIPH_BIO, request_ccb->ccb_h.path, NULL, 0, request_ccb); if (status != CAM_REQ_CMP) { xpt_print(path, "xpt_scan_lun: cam_alloc_periph " "returned an error, can't continue probe\n"); request_ccb->ccb_h.status = status; xpt_done(request_ccb); } } if (lock) xpt_path_unlock(path); } static void xptscandone(struct cam_periph *periph, union ccb *done_ccb) { xpt_free_path(done_ccb->ccb_h.path); xpt_free_ccb(done_ccb); } static struct cam_ed * ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id) { struct ata_quirk_entry *quirk; struct cam_ed *device; device = xpt_alloc_device(bus, target, lun_id); if (device == NULL) return (NULL); /* * Take the default quirk entry until we have inquiry * data and can determine a better quirk to use. */ quirk = &ata_quirk_table[nitems(ata_quirk_table) - 1]; device->quirk = (void *)quirk; device->mintags = 0; device->maxtags = 0; bzero(&device->inq_data, sizeof(device->inq_data)); device->inq_flags = 0; device->queue_flags = 0; device->serial_num = NULL; device->serial_num_len = 0; return (device); } static void ata_device_transport(struct cam_path *path) { struct ccb_pathinq cpi; struct ccb_trans_settings cts; struct scsi_inquiry_data *inq_buf = NULL; struct ata_params *ident_buf = NULL; /* Get transport information from the SIM */ xpt_path_inq(&cpi, path); path->device->transport = cpi.transport; if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) inq_buf = &path->device->inq_data; if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) != 0) ident_buf = &path->device->ident_data; if (path->device->protocol == PROTO_ATA) { path->device->protocol_version = ident_buf ? ata_version(ident_buf->version_major) : cpi.protocol_version; } else if (path->device->protocol == PROTO_SCSI) { path->device->protocol_version = inq_buf ? SID_ANSI_REV(inq_buf) : cpi.protocol_version; } path->device->transport_version = ident_buf ? ata_version(ident_buf->version_major) : cpi.transport_version; /* Tell the controller what we think */ xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cts.transport = path->device->transport; cts.transport_version = path->device->transport_version; cts.protocol = path->device->protocol; cts.protocol_version = path->device->protocol_version; cts.proto_specific.valid = 0; if (ident_buf) { if (path->device->transport == XPORT_ATA) { cts.xport_specific.ata.atapi = (ident_buf->config == ATA_PROTO_CFA) ? 0 : ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 : ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0; cts.xport_specific.ata.valid = CTS_ATA_VALID_ATAPI; } else { cts.xport_specific.sata.atapi = (ident_buf->config == ATA_PROTO_CFA) ? 0 : ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 : ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0; cts.xport_specific.sata.valid = CTS_SATA_VALID_ATAPI; } } else cts.xport_specific.valid = 0; xpt_action((union ccb *)&cts); } static void ata_dev_advinfo(union ccb *start_ccb) { struct cam_ed *device; struct ccb_dev_advinfo *cdai; off_t amt; start_ccb->ccb_h.status = CAM_REQ_INVALID; device = start_ccb->ccb_h.path->device; cdai = &start_ccb->cdai; switch(cdai->buftype) { case CDAI_TYPE_SCSI_DEVID: if (cdai->flags & CDAI_FLAG_STORE) return; cdai->provsiz = device->device_id_len; if (device->device_id_len == 0) break; amt = device->device_id_len; if (cdai->provsiz > cdai->bufsiz) amt = cdai->bufsiz; memcpy(cdai->buf, device->device_id, amt); break; case CDAI_TYPE_SERIAL_NUM: if (cdai->flags & CDAI_FLAG_STORE) return; cdai->provsiz = device->serial_num_len; if (device->serial_num_len == 0) break; amt = device->serial_num_len; if (cdai->provsiz > cdai->bufsiz) amt = cdai->bufsiz; memcpy(cdai->buf, device->serial_num, amt); break; case CDAI_TYPE_PHYS_PATH: if (cdai->flags & CDAI_FLAG_STORE) { if (device->physpath != NULL) free(device->physpath, M_CAMXPT); device->physpath_len = cdai->bufsiz; /* Clear existing buffer if zero length */ if (cdai->bufsiz == 0) break; device->physpath = malloc(cdai->bufsiz, M_CAMXPT, M_NOWAIT); if (device->physpath == NULL) { start_ccb->ccb_h.status = CAM_REQ_ABORTED; return; } memcpy(device->physpath, cdai->buf, cdai->bufsiz); } else { cdai->provsiz = device->physpath_len; if (device->physpath_len == 0) break; amt = device->physpath_len; if (cdai->provsiz > cdai->bufsiz) amt = cdai->bufsiz; memcpy(cdai->buf, device->physpath, amt); } break; default: return; } start_ccb->ccb_h.status = CAM_REQ_CMP; if (cdai->flags & CDAI_FLAG_STORE) { xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path, (void *)(uintptr_t)cdai->buftype); } } static void ata_action(union ccb *start_ccb) { switch (start_ccb->ccb_h.func_code) { case XPT_SET_TRAN_SETTINGS: { ata_set_transfer_settings(&start_ccb->cts, start_ccb->ccb_h.path, /*async_update*/FALSE); break; } case XPT_SCAN_BUS: case XPT_SCAN_TGT: ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb); break; case XPT_SCAN_LUN: ata_scan_lun(start_ccb->ccb_h.path->periph, start_ccb->ccb_h.path, start_ccb->crcn.flags, start_ccb); break; case XPT_GET_TRAN_SETTINGS: { ata_get_transfer_settings(&start_ccb->cts); break; } case XPT_SCSI_IO: { struct cam_ed *device; u_int maxlen = 0; device = start_ccb->ccb_h.path->device; if (device->protocol == PROTO_SCSI && (device->flags & CAM_DEV_IDENTIFY_DATA_VALID)) { uint16_t p = device->ident_data.config & ATA_PROTO_MASK; maxlen = (device->ident_data.config == ATA_PROTO_CFA) ? 0 : (p == ATA_PROTO_ATAPI_16) ? 16 : (p == ATA_PROTO_ATAPI_12) ? 12 : 0; } if (start_ccb->csio.cdb_len > maxlen) { start_ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(start_ccb); break; } xpt_action_default(start_ccb); break; } case XPT_DEV_ADVINFO: { ata_dev_advinfo(start_ccb); break; } default: xpt_action_default(start_ccb); break; } } static void ata_get_transfer_settings(struct ccb_trans_settings *cts) { struct ccb_trans_settings_ata *ata; struct ccb_trans_settings_scsi *scsi; struct cam_ed *device; device = cts->ccb_h.path->device; xpt_action_default((union ccb *)cts); if (cts->protocol == PROTO_UNKNOWN || cts->protocol == PROTO_UNSPECIFIED) { cts->protocol = device->protocol; cts->protocol_version = device->protocol_version; } if (cts->protocol == PROTO_ATA) { ata = &cts->proto_specific.ata; if ((ata->valid & CTS_ATA_VALID_TQ) == 0) { ata->valid |= CTS_ATA_VALID_TQ; if (cts->type == CTS_TYPE_USER_SETTINGS || (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || (device->inq_flags & SID_CmdQue) != 0) ata->flags |= CTS_ATA_FLAGS_TAG_ENB; } } if (cts->protocol == PROTO_SCSI) { scsi = &cts->proto_specific.scsi; if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) { scsi->valid |= CTS_SCSI_VALID_TQ; if (cts->type == CTS_TYPE_USER_SETTINGS || (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || (device->inq_flags & SID_CmdQue) != 0) scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; } } if (cts->transport == XPORT_UNKNOWN || cts->transport == XPORT_UNSPECIFIED) { cts->transport = device->transport; cts->transport_version = device->transport_version; } } static void ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_path *path, int async_update) { struct ccb_pathinq cpi; struct ccb_trans_settings_ata *ata; struct ccb_trans_settings_scsi *scsi; struct ata_params *ident_data; struct scsi_inquiry_data *inq_data; struct cam_ed *device; if (path == NULL || (device = path->device) == NULL) { cts->ccb_h.status = CAM_PATH_INVALID; xpt_done((union ccb *)cts); return; } if (cts->protocol == PROTO_UNKNOWN || cts->protocol == PROTO_UNSPECIFIED) { cts->protocol = device->protocol; cts->protocol_version = device->protocol_version; } if (cts->protocol_version == PROTO_VERSION_UNKNOWN || cts->protocol_version == PROTO_VERSION_UNSPECIFIED) cts->protocol_version = device->protocol_version; if (cts->protocol != device->protocol) { xpt_print(path, "Uninitialized Protocol %x:%x?\n", cts->protocol, device->protocol); cts->protocol = device->protocol; } if (cts->protocol_version > device->protocol_version) { if (bootverbose) { xpt_print(path, "Down reving Protocol " "Version from %d to %d?\n", cts->protocol_version, device->protocol_version); } cts->protocol_version = device->protocol_version; } if (cts->transport == XPORT_UNKNOWN || cts->transport == XPORT_UNSPECIFIED) { cts->transport = device->transport; cts->transport_version = device->transport_version; } if (cts->transport_version == XPORT_VERSION_UNKNOWN || cts->transport_version == XPORT_VERSION_UNSPECIFIED) cts->transport_version = device->transport_version; if (cts->transport != device->transport) { xpt_print(path, "Uninitialized Transport %x:%x?\n", cts->transport, device->transport); cts->transport = device->transport; } if (cts->transport_version > device->transport_version) { if (bootverbose) { xpt_print(path, "Down reving Transport " "Version from %d to %d?\n", cts->transport_version, device->transport_version); } cts->transport_version = device->transport_version; } ident_data = &device->ident_data; inq_data = &device->inq_data; if (cts->protocol == PROTO_ATA) ata = &cts->proto_specific.ata; else ata = NULL; if (cts->protocol == PROTO_SCSI) scsi = &cts->proto_specific.scsi; else scsi = NULL; xpt_path_inq(&cpi, path); /* Sanity checking */ if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0 || (ata && (ident_data->satacapabilities & ATA_SUPPORT_NCQ) == 0) || (scsi && (INQ_DATA_TQ_ENABLED(inq_data)) == 0) || (device->queue_flags & SCP_QUEUE_DQUE) != 0 || (device->mintags == 0)) { /* * Can't tag on hardware that doesn't support tags, * doesn't have it enabled, or has broken tag support. */ if (ata) ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB; if (scsi) scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; } /* Start/stop tags use. */ if (cts->type == CTS_TYPE_CURRENT_SETTINGS && ((ata && (ata->valid & CTS_ATA_VALID_TQ) != 0) || (scsi && (scsi->valid & CTS_SCSI_VALID_TQ) != 0))) { int nowt, newt = 0; nowt = ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 || (device->inq_flags & SID_CmdQue) != 0); if (ata) newt = (ata->flags & CTS_ATA_FLAGS_TAG_ENB) != 0; if (scsi) newt = (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0; if (newt && !nowt) { /* * Delay change to use tags until after a * few commands have gone to this device so * the controller has time to perform transfer * negotiations without tagged messages getting * in the way. */ device->tag_delay_count = CAM_TAG_DELAY_COUNT; device->flags |= CAM_DEV_TAG_AFTER_COUNT; } else if (nowt && !newt) xpt_stop_tags(path); } if (async_update == FALSE) xpt_action_default((union ccb *)cts); } /* * Handle any per-device event notifications that require action by the XPT. */ static void ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target, struct cam_ed *device, void *async_arg) { cam_status status; struct cam_path newpath; /* * We only need to handle events for real devices. */ if (target->target_id == CAM_TARGET_WILDCARD || device->lun_id == CAM_LUN_WILDCARD) return; /* * We need our own path with wildcards expanded to * handle certain types of events. */ if ((async_code == AC_SENT_BDR) || (async_code == AC_BUS_RESET) || (async_code == AC_INQ_CHANGED)) status = xpt_compile_path(&newpath, NULL, bus->path_id, target->target_id, device->lun_id); else status = CAM_REQ_CMP_ERR; if (status == CAM_REQ_CMP) { if (async_code == AC_INQ_CHANGED) { /* * We've sent a start unit command, or * something similar to a device that * may have caused its inquiry data to * change. So we re-scan the device to * refresh the inquiry data for it. */ ata_scan_lun(newpath.periph, &newpath, CAM_EXPECT_INQ_CHANGE, NULL); } else { /* We need to reinitialize device after reset. */ ata_scan_lun(newpath.periph, &newpath, 0, NULL); } xpt_release_path(&newpath); } else if (async_code == AC_LOST_DEVICE && (device->flags & CAM_DEV_UNCONFIGURED) == 0) { device->flags |= CAM_DEV_UNCONFIGURED; xpt_release_device(device); } else if (async_code == AC_TRANSFER_NEG) { struct ccb_trans_settings *settings; struct cam_path path; settings = (struct ccb_trans_settings *)async_arg; xpt_compile_path(&path, NULL, bus->path_id, target->target_id, device->lun_id); ata_set_transfer_settings(settings, &path, /*async_update*/TRUE); xpt_release_path(&path); } } static void _ata_announce_periph(struct cam_periph *periph, struct ccb_trans_settings *cts, u_int *speed) { struct ccb_pathinq cpi; struct cam_path *path = periph->path; cam_periph_assert(periph, MA_OWNED); xpt_setup_ccb(&cts->ccb_h, path, CAM_PRIORITY_NORMAL); cts->ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts->type = CTS_TYPE_CURRENT_SETTINGS; xpt_action((union ccb*)cts); if ((cts->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) return; /* Ask the SIM for its base transfer speed */ xpt_path_inq(&cpi, path); /* Report connection speed */ *speed = cpi.base_transfer_speed; if (cts->transport == XPORT_ATA) { struct ccb_trans_settings_pata *pata = &cts->xport_specific.ata; if (pata->valid & CTS_ATA_VALID_MODE) *speed = ata_mode2speed(pata->mode); } if (cts->transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &cts->xport_specific.sata; if (sata->valid & CTS_SATA_VALID_REVISION) *speed = ata_revision2speed(sata->revision); } } static void ata_announce_periph(struct cam_periph *periph) { struct ccb_trans_settings cts; u_int speed, mb; _ata_announce_periph(periph, &cts, &speed); if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) return; mb = speed / 1000; if (mb > 0) printf("%s%d: %d.%03dMB/s transfers", periph->periph_name, periph->unit_number, mb, speed % 1000); else printf("%s%d: %dKB/s transfers", periph->periph_name, periph->unit_number, speed); /* Report additional information about connection */ if (cts.transport == XPORT_ATA) { struct ccb_trans_settings_pata *pata = &cts.xport_specific.ata; printf(" ("); if (pata->valid & CTS_ATA_VALID_MODE) printf("%s, ", ata_mode2string(pata->mode)); if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) printf("ATAPI %dbytes, ", pata->atapi); if (pata->valid & CTS_ATA_VALID_BYTECOUNT) printf("PIO %dbytes", pata->bytecount); printf(")"); } if (cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &cts.xport_specific.sata; printf(" ("); if (sata->valid & CTS_SATA_VALID_REVISION) printf("SATA %d.x, ", sata->revision); else printf("SATA, "); if (sata->valid & CTS_SATA_VALID_MODE) printf("%s, ", ata_mode2string(sata->mode)); if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) printf("ATAPI %dbytes, ", sata->atapi); if (sata->valid & CTS_SATA_VALID_BYTECOUNT) printf("PIO %dbytes", sata->bytecount); printf(")"); } printf("\n"); } static void ata_announce_periph_sbuf(struct cam_periph *periph, struct sbuf *sb) { struct ccb_trans_settings cts; u_int speed, mb; _ata_announce_periph(periph, &cts, &speed); if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) return; mb = speed / 1000; if (mb > 0) sbuf_printf(sb, "%s%d: %d.%03dMB/s transfers", periph->periph_name, periph->unit_number, mb, speed % 1000); else sbuf_printf(sb, "%s%d: %dKB/s transfers", periph->periph_name, periph->unit_number, speed); /* Report additional information about connection */ if (cts.transport == XPORT_ATA) { struct ccb_trans_settings_pata *pata = &cts.xport_specific.ata; sbuf_printf(sb, " ("); if (pata->valid & CTS_ATA_VALID_MODE) sbuf_printf(sb, "%s, ", ata_mode2string(pata->mode)); if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0) sbuf_printf(sb, "ATAPI %dbytes, ", pata->atapi); if (pata->valid & CTS_ATA_VALID_BYTECOUNT) sbuf_printf(sb, "PIO %dbytes", pata->bytecount); sbuf_printf(sb, ")"); } if (cts.transport == XPORT_SATA) { struct ccb_trans_settings_sata *sata = &cts.xport_specific.sata; sbuf_printf(sb, " ("); if (sata->valid & CTS_SATA_VALID_REVISION) sbuf_printf(sb, "SATA %d.x, ", sata->revision); else sbuf_printf(sb, "SATA, "); if (sata->valid & CTS_SATA_VALID_MODE) sbuf_printf(sb, "%s, ", ata_mode2string(sata->mode)); if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0) sbuf_printf(sb, "ATAPI %dbytes, ", sata->atapi); if (sata->valid & CTS_SATA_VALID_BYTECOUNT) sbuf_printf(sb, "PIO %dbytes", sata->bytecount); sbuf_printf(sb, ")"); } sbuf_printf(sb, "\n"); } static void ata_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb) { ata_print_ident_sbuf(&device->ident_data, sb); } static void ata_proto_announce(struct cam_ed *device) { ata_print_ident(&device->ident_data); } static void ata_proto_denounce(struct cam_ed *device) { ata_print_ident_short(&device->ident_data); } static void ata_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb) { ata_print_ident_short_sbuf(&device->ident_data, sb); } static void semb_proto_announce_sbuf(struct cam_ed *device, struct sbuf *sb) { semb_print_ident_sbuf((struct sep_identify_data *)&device->ident_data, sb); } static void semb_proto_announce(struct cam_ed *device) { semb_print_ident((struct sep_identify_data *)&device->ident_data); } static void semb_proto_denounce(struct cam_ed *device) { semb_print_ident_short((struct sep_identify_data *)&device->ident_data); } static void semb_proto_denounce_sbuf(struct cam_ed *device, struct sbuf *sb) { semb_print_ident_short_sbuf((struct sep_identify_data *)&device->ident_data, sb); } static void ata_proto_debug_out(union ccb *ccb) { char cdb_str[(sizeof(struct ata_cmd) * 3) + 1]; if (ccb->ccb_h.func_code != XPT_ATA_IO) return; CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_CDB,("%s. ACB: %s\n", ata_op_string(&ccb->ataio.cmd), ata_cmd_string(&ccb->ataio.cmd, cdb_str, sizeof(cdb_str)))); } Index: head/sys/cam/scsi/scsi_da.c =================================================================== --- head/sys/cam/scsi/scsi_da.c (revision 349351) +++ head/sys/cam/scsi/scsi_da.c (revision 349352) @@ -1,6541 +1,6548 @@ /*- * Implementation of SCSI Direct Access Peripheral driver for CAM. * * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 1997 Justin T. Gibbs. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions, and the following disclaimer, * without modification, immediately at the beginning of the file. * 2. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL #include "opt_da.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /* _KERNEL */ #ifndef _KERNEL #include #include #endif /* _KERNEL */ #include #include #include #include -#ifdef _KERNEL -#include -#endif /* _KERNEL */ #include #include #include #include #ifdef _KERNEL /* * Note that there are probe ordering dependencies here. The order isn't * controlled by this enumeration, but by explicit state transitions in * dastart() and dadone(). Here are some of the dependencies: * * 1. RC should come first, before RC16, unless there is evidence that RC16 * is supported. * 2. BDC needs to come before any of the ATA probes, or the ZONE probe. * 3. The ATA probes should go in this order: * ATA -> LOGDIR -> IDDIR -> SUP -> ATA_ZONE */ typedef enum { DA_STATE_PROBE_WP, DA_STATE_PROBE_RC, DA_STATE_PROBE_RC16, DA_STATE_PROBE_LBP, DA_STATE_PROBE_BLK_LIMITS, DA_STATE_PROBE_BDC, DA_STATE_PROBE_ATA, DA_STATE_PROBE_ATA_LOGDIR, DA_STATE_PROBE_ATA_IDDIR, DA_STATE_PROBE_ATA_SUP, DA_STATE_PROBE_ATA_ZONE, DA_STATE_PROBE_ZONE, DA_STATE_NORMAL } da_state; typedef enum { DA_FLAG_PACK_INVALID = 0x000001, DA_FLAG_NEW_PACK = 0x000002, DA_FLAG_PACK_LOCKED = 0x000004, DA_FLAG_PACK_REMOVABLE = 0x000008, DA_FLAG_NEED_OTAG = 0x000020, DA_FLAG_WAS_OTAG = 0x000040, DA_FLAG_RETRY_UA = 0x000080, DA_FLAG_OPEN = 0x000100, DA_FLAG_SCTX_INIT = 0x000200, DA_FLAG_CAN_RC16 = 0x000400, DA_FLAG_PROBED = 0x000800, DA_FLAG_DIRTY = 0x001000, DA_FLAG_ANNOUNCED = 0x002000, DA_FLAG_CAN_ATA_DMA = 0x004000, DA_FLAG_CAN_ATA_LOG = 0x008000, DA_FLAG_CAN_ATA_IDLOG = 0x010000, DA_FLAG_CAN_ATA_SUPCAP = 0x020000, DA_FLAG_CAN_ATA_ZONE = 0x040000, DA_FLAG_TUR_PENDING = 0x080000 } da_flags; typedef enum { DA_Q_NONE = 0x00, DA_Q_NO_SYNC_CACHE = 0x01, DA_Q_NO_6_BYTE = 0x02, DA_Q_NO_PREVENT = 0x04, DA_Q_4K = 0x08, DA_Q_NO_RC16 = 0x10, DA_Q_NO_UNMAP = 0x20, DA_Q_RETRY_BUSY = 0x40, DA_Q_SMR_DM = 0x80, DA_Q_STRICT_UNMAP = 0x100, DA_Q_128KB = 0x200 } da_quirks; #define DA_Q_BIT_STRING \ "\020" \ "\001NO_SYNC_CACHE" \ "\002NO_6_BYTE" \ "\003NO_PREVENT" \ "\0044K" \ "\005NO_RC16" \ "\006NO_UNMAP" \ "\007RETRY_BUSY" \ "\010SMR_DM" \ "\011STRICT_UNMAP" \ "\012128KB" typedef enum { DA_CCB_PROBE_RC = 0x01, DA_CCB_PROBE_RC16 = 0x02, DA_CCB_PROBE_LBP = 0x03, DA_CCB_PROBE_BLK_LIMITS = 0x04, DA_CCB_PROBE_BDC = 0x05, DA_CCB_PROBE_ATA = 0x06, DA_CCB_BUFFER_IO = 0x07, DA_CCB_DUMP = 0x0A, DA_CCB_DELETE = 0x0B, DA_CCB_TUR = 0x0C, DA_CCB_PROBE_ZONE = 0x0D, DA_CCB_PROBE_ATA_LOGDIR = 0x0E, DA_CCB_PROBE_ATA_IDDIR = 0x0F, DA_CCB_PROBE_ATA_SUP = 0x10, DA_CCB_PROBE_ATA_ZONE = 0x11, DA_CCB_PROBE_WP = 0x12, DA_CCB_TYPE_MASK = 0x1F, DA_CCB_RETRY_UA = 0x20 } da_ccb_state; /* * Order here is important for method choice * * We prefer ATA_TRIM as tests run against a Sandforce 2281 SSD attached to * LSI 2008 (mps) controller (FW: v12, Drv: v14) resulted 20% quicker deletes * using ATA_TRIM than the corresponding UNMAP results for a real world mysql * import taking 5mins. * */ typedef enum { DA_DELETE_NONE, DA_DELETE_DISABLE, DA_DELETE_ATA_TRIM, DA_DELETE_UNMAP, DA_DELETE_WS16, DA_DELETE_WS10, DA_DELETE_ZERO, DA_DELETE_MIN = DA_DELETE_ATA_TRIM, DA_DELETE_MAX = DA_DELETE_ZERO } da_delete_methods; /* * For SCSI, host managed drives show up as a separate device type. For * ATA, host managed drives also have a different device signature. * XXX KDM figure out the ATA host managed signature. */ typedef enum { DA_ZONE_NONE = 0x00, DA_ZONE_DRIVE_MANAGED = 0x01, DA_ZONE_HOST_AWARE = 0x02, DA_ZONE_HOST_MANAGED = 0x03 } da_zone_mode; /* * We distinguish between these interface cases in addition to the drive type: * o ATA drive behind a SCSI translation layer that knows about ZBC/ZAC * o ATA drive behind a SCSI translation layer that does not know about * ZBC/ZAC, and so needs to be managed via ATA passthrough. In this * case, we would need to share the ATA code with the ada(4) driver. * o SCSI drive. */ typedef enum { DA_ZONE_IF_SCSI, DA_ZONE_IF_ATA_PASS, DA_ZONE_IF_ATA_SAT, } da_zone_interface; typedef enum { DA_ZONE_FLAG_RZ_SUP = 0x0001, DA_ZONE_FLAG_OPEN_SUP = 0x0002, DA_ZONE_FLAG_CLOSE_SUP = 0x0004, DA_ZONE_FLAG_FINISH_SUP = 0x0008, DA_ZONE_FLAG_RWP_SUP = 0x0010, DA_ZONE_FLAG_SUP_MASK = (DA_ZONE_FLAG_RZ_SUP | DA_ZONE_FLAG_OPEN_SUP | DA_ZONE_FLAG_CLOSE_SUP | DA_ZONE_FLAG_FINISH_SUP | DA_ZONE_FLAG_RWP_SUP), DA_ZONE_FLAG_URSWRZ = 0x0020, DA_ZONE_FLAG_OPT_SEQ_SET = 0x0040, DA_ZONE_FLAG_OPT_NONSEQ_SET = 0x0080, DA_ZONE_FLAG_MAX_SEQ_SET = 0x0100, DA_ZONE_FLAG_SET_MASK = (DA_ZONE_FLAG_OPT_SEQ_SET | DA_ZONE_FLAG_OPT_NONSEQ_SET | DA_ZONE_FLAG_MAX_SEQ_SET) } da_zone_flags; static struct da_zone_desc { da_zone_flags value; const char *desc; } da_zone_desc_table[] = { {DA_ZONE_FLAG_RZ_SUP, "Report Zones" }, {DA_ZONE_FLAG_OPEN_SUP, "Open" }, {DA_ZONE_FLAG_CLOSE_SUP, "Close" }, {DA_ZONE_FLAG_FINISH_SUP, "Finish" }, {DA_ZONE_FLAG_RWP_SUP, "Reset Write Pointer" }, }; typedef void da_delete_func_t (struct cam_periph *periph, union ccb *ccb, struct bio *bp); static da_delete_func_t da_delete_trim; static da_delete_func_t da_delete_unmap; static da_delete_func_t da_delete_ws; static const void * da_delete_functions[] = { NULL, NULL, da_delete_trim, da_delete_unmap, da_delete_ws, da_delete_ws, da_delete_ws }; static const char *da_delete_method_names[] = { "NONE", "DISABLE", "ATA_TRIM", "UNMAP", "WS16", "WS10", "ZERO" }; static const char *da_delete_method_desc[] = { "NONE", "DISABLED", "ATA TRIM", "UNMAP", "WRITE SAME(16) with UNMAP", "WRITE SAME(10) with UNMAP", "ZERO" }; /* Offsets into our private area for storing information */ #define ccb_state ppriv_field0 #define ccb_bp ppriv_ptr1 struct disk_params { u_int8_t heads; u_int32_t cylinders; u_int8_t secs_per_track; u_int32_t secsize; /* Number of bytes/sector */ u_int64_t sectors; /* total number sectors */ u_int stripesize; u_int stripeoffset; }; #define UNMAP_RANGE_MAX 0xffffffff #define UNMAP_HEAD_SIZE 8 #define UNMAP_RANGE_SIZE 16 #define UNMAP_MAX_RANGES 2048 /* Protocol Max is 4095 */ #define UNMAP_BUF_SIZE ((UNMAP_MAX_RANGES * UNMAP_RANGE_SIZE) + \ UNMAP_HEAD_SIZE) #define WS10_MAX_BLKS 0xffff #define WS16_MAX_BLKS 0xffffffff #define ATA_TRIM_MAX_RANGES ((UNMAP_BUF_SIZE / \ (ATA_DSM_RANGE_SIZE * ATA_DSM_BLK_SIZE)) * ATA_DSM_BLK_SIZE) #define DA_WORK_TUR (1 << 16) typedef enum { DA_REF_OPEN = 1, DA_REF_OPEN_HOLD, DA_REF_CLOSE_HOLD, DA_REF_PROBE_HOLD, DA_REF_TUR, DA_REF_GEOM, DA_REF_SYSCTL, DA_REF_REPROBE, DA_REF_MAX /* KEEP LAST */ } da_ref_token; struct da_softc { struct cam_iosched_softc *cam_iosched; struct bio_queue_head delete_run_queue; LIST_HEAD(, ccb_hdr) pending_ccbs; int refcount; /* Active xpt_action() calls */ da_state state; da_flags flags; da_quirks quirks; int minimum_cmd_size; int error_inject; int trim_max_ranges; int delete_available; /* Delete methods possibly available */ da_zone_mode zone_mode; da_zone_interface zone_interface; da_zone_flags zone_flags; struct ata_gp_log_dir ata_logdir; int valid_logdir_len; struct ata_identify_log_pages ata_iddir; int valid_iddir_len; uint64_t optimal_seq_zones; uint64_t optimal_nonseq_zones; uint64_t max_seq_zones; u_int maxio; uint32_t unmap_max_ranges; uint32_t unmap_max_lba; /* Max LBAs in UNMAP req */ uint32_t unmap_gran; uint32_t unmap_gran_align; uint64_t ws_max_blks; uint64_t trim_count; uint64_t trim_ranges; uint64_t trim_lbas; da_delete_methods delete_method_pref; da_delete_methods delete_method; da_delete_func_t *delete_func; int unmappedio; int rotating; int p_type; struct disk_params params; struct disk *disk; union ccb saved_ccb; struct task sysctl_task; struct sysctl_ctx_list sysctl_ctx; struct sysctl_oid *sysctl_tree; struct callout sendordered_c; uint64_t wwpn; uint8_t unmap_buf[UNMAP_BUF_SIZE]; struct scsi_read_capacity_data_long rcaplong; struct callout mediapoll_c; int ref_flags[DA_REF_MAX]; #ifdef CAM_IO_STATS struct sysctl_ctx_list sysctl_stats_ctx; struct sysctl_oid *sysctl_stats_tree; u_int errors; u_int timeouts; u_int invalidations; #endif #define DA_ANNOUNCETMP_SZ 160 char announce_temp[DA_ANNOUNCETMP_SZ]; #define DA_ANNOUNCE_SZ 400 char announcebuf[DA_ANNOUNCE_SZ]; }; #define dadeleteflag(softc, delete_method, enable) \ if (enable) { \ softc->delete_available |= (1 << delete_method); \ } else { \ softc->delete_available &= ~(1 << delete_method); \ } struct da_quirk_entry { struct scsi_inquiry_pattern inq_pat; da_quirks quirks; }; static const char quantum[] = "QUANTUM"; static const char microp[] = "MICROP"; static struct da_quirk_entry da_quirk_table[] = { /* SPI, FC devices */ { /* * Fujitsu M2513A MO drives. * Tested devices: M2513A2 firmware versions 1200 & 1300. * (dip switch selects whether T_DIRECT or T_OPTICAL device) * Reported by: W.Scholten */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* See above. */ {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * This particular Fujitsu drive doesn't like the * synchronize cache command. * Reported by: Tom Jackson */ {T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * This drive doesn't like the synchronize cache command * either. Reported by: Matthew Jacob * in NetBSD PR kern/6027, August 24, 1998. */ {T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * This drive doesn't like the synchronize cache command * either. Reported by: Hellmuth Michaelis (hm@kts.org) * (PR 8882). */ {T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Doesn't like the synchronize cache command. * Reported by: Blaz Zupan */ {T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Doesn't like the synchronize cache command. * Reported by: Blaz Zupan */ {T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Doesn't like the synchronize cache command. */ {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Doesn't like the synchronize cache command. * Reported by: walter@pelissero.de */ {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Doesn't work correctly with 6 byte reads/writes. * Returns illegal request, and points to byte 9 of the * 6-byte CDB. * Reported by: Adam McDougall */ {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"}, /*quirks*/ DA_Q_NO_6_BYTE }, { /* See above. */ {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"}, /*quirks*/ DA_Q_NO_6_BYTE }, { /* * Doesn't like the synchronize cache command. * Reported by: walter@pelissero.de */ {T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * The CISS RAID controllers do not support SYNC_CACHE */ {T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * The STEC SSDs sometimes hang on UNMAP. */ {T_DIRECT, SIP_MEDIA_FIXED, "STEC", "*", "*"}, /*quirks*/ DA_Q_NO_UNMAP }, { /* * VMware returns BUSY status when storage has transient * connectivity problems, so better wait. * Also VMware returns odd errors on misaligned UNMAPs. */ {T_DIRECT, SIP_MEDIA_FIXED, "VMware*", "*", "*"}, /*quirks*/ DA_Q_RETRY_BUSY | DA_Q_STRICT_UNMAP }, /* USB mass storage devices supported by umass(4) */ { /* * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player * PR: kern/51675 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Power Quotient Int. (PQI) USB flash key * PR: kern/53067 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Creative Nomad MUVO mp3 player (USB) * PR: kern/53094 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT }, { /* * Jungsoft NEXDISK USB flash key * PR: kern/54737 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * FreeDik USB Mini Data Drive * PR: kern/54786 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "FreeDik*", "Mini Data Drive", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Sigmatel USB Flash MP3 Player * PR: kern/57046 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT }, { /* * Neuros USB Digital Audio Computer * PR: kern/63645 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * SEAGRAND NP-900 MP3 Player * PR: kern/64563 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT }, { /* * iRiver iFP MP3 player (with UMS Firmware) * PR: kern/54881, i386/63941, kern/66124 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "iRiver", "iFP*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01 * PR: kern/70158 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * ZICPlay USB MP3 Player with FM * PR: kern/75057 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * TEAC USB floppy mechanisms */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Kingston DataTraveler II+ USB Pen-Drive. * Reported by: Pawel Jakub Dawidek */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * USB DISK Pro PMAP * Reported by: jhs * PR: usb/96381 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, " ", "USB DISK Pro", "PMAP"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Motorola E398 Mobile Phone (TransFlash memory card). * Reported by: Wojciech A. Koszek * PR: usb/89889 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Motorola" , "Motorola Phone", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Qware BeatZkey! Pro * PR: usb/79164 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "GENERIC", "USB DISK DEVICE", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Time DPA20B 1GB MP3 Player * PR: usb/81846 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB2.0*", "(FS) FLASH DISK*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Samsung USB key 128Mb * PR: usb/90081 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB-DISK", "FreeDik-FlashUsb", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Kingston DataTraveler 2.0 USB Flash memory. * PR: usb/89196 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler 2.0", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Creative MUVO Slim mp3 player (USB) * PR: usb/86131 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT }, { /* * United MP5512 Portable MP3 Player (2-in-1 USB DISK/MP3) * PR: usb/80487 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "MUSIC DISK", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * SanDisk Micro Cruzer 128MB * PR: usb/75970 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk" , "Micro Cruzer", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * TOSHIBA TransMemory USB sticks * PR: kern/94660 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "TOSHIBA", "TransMemory", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * PNY USB 3.0 Flash Drives */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "PNY", "USB 3.0 FD*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_RC16 }, { /* * PNY USB Flash keys * PR: usb/75578, usb/72344, usb/65436 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Genesys GL3224 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*", "120?"}, /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_4K | DA_Q_NO_RC16 }, { /* * Genesys 6-in-1 Card Reader * PR: usb/94647 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Rekam Digital CAMERA * PR: usb/98713 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "CAMERA*", "4MP-9J6*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * iRiver H10 MP3 player * PR: usb/102547 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "H10*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * iRiver U10 MP3 player * PR: usb/92306 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "U10*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * X-Micro Flash Disk * PR: usb/96901 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "X-Micro", "Flash Disk", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * EasyMP3 EM732X USB 2.0 Flash MP3 Player * PR: usb/96546 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "EM732X", "MP3 Player*", "1.00"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Denver MP3 player * PR: usb/107101 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "DENVER", "MP3 PLAYER", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Philips USB Key Audio KEY013 * PR: usb/68412 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "PHILIPS", "Key*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT }, { /* * JNC MP3 Player * PR: usb/94439 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "JNC*" , "MP3 Player*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * SAMSUNG MP0402H * PR: usb/108427 */ {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "MP0402H", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * I/O Magic USB flash - Giga Bank * PR: usb/108810 */ {T_DIRECT, SIP_MEDIA_FIXED, "GS-Magic", "stor*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * JoyFly 128mb USB Flash Drive * PR: 96133 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "Flash Disk*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * ChipsBnk usb stick * PR: 103702 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "ChipsBnk", "USB*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Storcase (Kingston) InfoStation IFS FC2/SATA-R 201A * PR: 129858 */ {T_DIRECT, SIP_MEDIA_FIXED, "IFS", "FC2/SATA-R*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Samsung YP-U3 mp3-player * PR: 125398 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Samsung", "YP-U3", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { {T_DIRECT, SIP_MEDIA_REMOVABLE, "Netac", "OnlyDisk*", "2000"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Sony Cyber-Shot DSC cameras * PR: usb/137035 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT }, { {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler G3", "1.00"}, /*quirks*/ DA_Q_NO_PREVENT }, { /* At least several Transcent USB sticks lie on RC16. */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "JetFlash", "Transcend*", "*"}, /*quirks*/ DA_Q_NO_RC16 }, { /* * I-O Data USB Flash Disk * PR: usb/211716 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "I-O DATA", "USB Flash Disk*", "*"}, /*quirks*/ DA_Q_NO_RC16 }, { /* * SLC CHIPFANCIER USB drives * PR: usb/234503 (RC10 right, RC16 wrong) * 16GB, 32GB and 128GB confirmed to have same issue */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "*SLC", "CHIPFANCIER", "*"}, /*quirks*/ DA_Q_NO_RC16 }, /* ATA/SATA devices over SAS/USB/... */ { /* Sandisk X400 */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SanDisk SD8SB8U1*", "*" }, /*quirks*/DA_Q_128KB }, { /* Hitachi Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "Hitachi", "H??????????E3*", "*" }, /*quirks*/DA_Q_4K }, { /* Micron Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Micron 5100 MTFDDAK*", "*" }, /*quirks*/DA_Q_4K }, { /* Samsung Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD155UI*", "*" }, /*quirks*/DA_Q_4K }, { /* Samsung Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD155UI*", "*" }, /*quirks*/DA_Q_4K }, { /* Samsung Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD204UI*", "*" }, /*quirks*/DA_Q_4K }, { /* Samsung Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD204UI*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Barracuda Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DL*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Barracuda Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST????DL", "*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Barracuda Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???DM*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Barracuda Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST???DM*", "*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Barracuda Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DM*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Barracuda Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST????DM", "*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500423AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "3AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500424AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "4AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640423AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "3AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640424AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "4AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750420AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "0AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750422AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "2AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750423AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "3AS*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Thin Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???LT*", "*" }, /*quirks*/DA_Q_4K }, { /* Seagate Momentus Thin Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ST???LT*", "*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RS*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RS*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RX*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RX*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RS*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RS*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RX*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Caviar Green Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RX*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Black Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PKT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Black Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PKT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Black Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PKT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Black Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PKT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Blue Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PVT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Blue Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PVT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Blue Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PVT*", "*" }, /*quirks*/DA_Q_4K }, { /* WDC Scorpio Blue Advanced Format (4k) drives */ { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PVT*", "*" }, /*quirks*/DA_Q_4K }, { /* * Olympus digital cameras (C-3040ZOOM, C-2040ZOOM, C-1) * PR: usb/97472 */ { T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "C*", "*"}, /*quirks*/ DA_Q_NO_6_BYTE | DA_Q_NO_SYNC_CACHE }, { /* * Olympus digital cameras (D-370) * PR: usb/97472 */ { T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "D*", "*"}, /*quirks*/ DA_Q_NO_6_BYTE }, { /* * Olympus digital cameras (E-100RS, E-10). * PR: usb/97472 */ { T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "E*", "*"}, /*quirks*/ DA_Q_NO_6_BYTE | DA_Q_NO_SYNC_CACHE }, { /* * Olympus FE-210 camera */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "FE210*", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Pentax Digital Camera * PR: usb/93389 */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "PENTAX", "DIGITAL CAMERA", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * LG UP3S MP3 player */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "LG", "UP3S", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * Laser MP3-2GA13 MP3 player */ {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "(HS) Flash Disk", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, { /* * LaCie external 250GB Hard drive des by Porsche * Submitted by: Ben Stuyts * PR: 121474 */ {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HM250JI", "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE }, /* SATA SSDs */ { /* * Corsair Force 2 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair CSSD-F*", "*" }, /*quirks*/DA_Q_4K }, { /* * Corsair Force 3 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair Force 3*", "*" }, /*quirks*/DA_Q_4K }, { /* * Corsair Neutron GTX SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Neutron GTX*", "*" }, /*quirks*/DA_Q_4K }, { /* * Corsair Force GT & GS SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair Force G*", "*" }, /*quirks*/DA_Q_4K }, { /* * Crucial M4 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "M4-CT???M4SSD2*", "*" }, /*quirks*/DA_Q_4K }, { /* * Crucial RealSSD C300 SSDs * 4k optimised */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "C300-CTFDDAC???MAG*", "*" }, /*quirks*/DA_Q_4K }, { /* * Intel 320 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSA2CW*", "*" }, /*quirks*/DA_Q_4K }, { /* * Intel 330 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2CT*", "*" }, /*quirks*/DA_Q_4K }, { /* * Intel 510 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2MH*", "*" }, /*quirks*/DA_Q_4K }, { /* * Intel 520 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2BW*", "*" }, /*quirks*/DA_Q_4K }, { /* * Intel S3610 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2BX*", "*" }, /*quirks*/DA_Q_4K }, { /* * Intel X25-M Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSA2M*", "*" }, /*quirks*/DA_Q_4K }, { /* * Kingston E100 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "KINGSTON SE100S3*", "*" }, /*quirks*/DA_Q_4K }, { /* * Kingston HyperX 3k SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "KINGSTON SH103S3*", "*" }, /*quirks*/DA_Q_4K }, { /* * Marvell SSDs (entry taken from OpenSolaris) * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "MARVELL SD88SA02*", "*" }, /*quirks*/DA_Q_4K }, { /* * OCZ Agility 2 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY2*", "*" }, /*quirks*/DA_Q_4K }, { /* * OCZ Agility 3 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-AGILITY3*", "*" }, /*quirks*/DA_Q_4K }, { /* * OCZ Deneva R Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "DENRSTE251M45*", "*" }, /*quirks*/DA_Q_4K }, { /* * OCZ Vertex 2 SSDs (inc pro series) * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ?VERTEX2*", "*" }, /*quirks*/DA_Q_4K }, { /* * OCZ Vertex 3 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX3*", "*" }, /*quirks*/DA_Q_4K }, { /* * OCZ Vertex 4 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX4*", "*" }, /*quirks*/DA_Q_4K }, { /* * Samsung 750 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 750*", "*" }, /*quirks*/DA_Q_4K }, { /* * Samsung 830 Series SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG SSD 830 Series*", "*" }, /*quirks*/DA_Q_4K }, { /* * Samsung 840 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 840*", "*" }, /*quirks*/DA_Q_4K }, { /* * Samsung 845 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 845*", "*" }, /*quirks*/DA_Q_4K }, { /* * Samsung 850 SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Samsung SSD 850*", "*" }, /*quirks*/DA_Q_4K }, { /* * Samsung 843T Series SSDs (MZ7WD*) * Samsung PM851 Series SSDs (MZ7TE*) * Samsung PM853T Series SSDs (MZ7GE*) * Samsung SM863 Series SSDs (MZ7KM*) * 4k optimised */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG MZ7*", "*" }, /*quirks*/DA_Q_4K }, { /* * Same as for SAMSUNG MZ7* but enable the quirks for SSD * starting with MZ7* too */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "MZ7*", "*" }, /*quirks*/DA_Q_4K }, { /* * SuperTalent TeraDrive CT SSDs * 4k optimised & trim only works in 4k requests + 4k aligned */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "FTM??CT25H*", "*" }, /*quirks*/DA_Q_4K }, { /* * XceedIOPS SATA SSDs * 4k optimised */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SG9XCS2D*", "*" }, /*quirks*/DA_Q_4K }, { /* * Hama Innostor USB-Stick */ { T_DIRECT, SIP_MEDIA_REMOVABLE, "Innostor", "Innostor*", "*" }, /*quirks*/DA_Q_NO_RC16 }, { /* * Seagate Lamarr 8TB Shingled Magnetic Recording (SMR) * Drive Managed SATA hard drive. This drive doesn't report * in firmware that it is a drive managed SMR drive. */ { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST8000AS000[23]*", "*" }, /*quirks*/DA_Q_SMR_DM }, { /* * MX-ES USB Drive by Mach Xtreme */ { T_DIRECT, SIP_MEDIA_REMOVABLE, "MX", "MXUB3*", "*"}, /*quirks*/DA_Q_NO_RC16 }, }; static disk_strategy_t dastrategy; static dumper_t dadump; static periph_init_t dainit; static void daasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg); static void dasysctlinit(void *context, int pending); static int dasysctlsofttimeout(SYSCTL_HANDLER_ARGS); static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS); static int dadeletemethodsysctl(SYSCTL_HANDLER_ARGS); static int dazonemodesysctl(SYSCTL_HANDLER_ARGS); static int dazonesupsysctl(SYSCTL_HANDLER_ARGS); static int dadeletemaxsysctl(SYSCTL_HANDLER_ARGS); static void dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method); static off_t dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method); static void dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method); static void daprobedone(struct cam_periph *periph, union ccb *ccb); static periph_ctor_t daregister; static periph_dtor_t dacleanup; static periph_start_t dastart; static periph_oninv_t daoninvalidate; static void dazonedone(struct cam_periph *periph, union ccb *ccb); static void dadone(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probewp(struct cam_periph *periph, union ccb *done_ccb); static void dadone_proberc(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probelbp(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probeblklimits(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probebdc(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probeata(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probeatalogdir(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probeataiddir(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probeatasup(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probeatazone(struct cam_periph *periph, union ccb *done_ccb); static void dadone_probezone(struct cam_periph *periph, union ccb *done_ccb); static void dadone_tur(struct cam_periph *periph, union ccb *done_ccb); static int daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); static void daprevent(struct cam_periph *periph, int action); static void dareprobe(struct cam_periph *periph); static void dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector, struct scsi_read_capacity_data_long *rcaplong, size_t rcap_size); static timeout_t dasendorderedtag; static void dashutdown(void *arg, int howto); static timeout_t damediapoll; #ifndef DA_DEFAULT_POLL_PERIOD #define DA_DEFAULT_POLL_PERIOD 3 #endif #ifndef DA_DEFAULT_TIMEOUT #define DA_DEFAULT_TIMEOUT 60 /* Timeout in seconds */ #endif #ifndef DA_DEFAULT_SOFTTIMEOUT #define DA_DEFAULT_SOFTTIMEOUT 0 #endif #ifndef DA_DEFAULT_RETRY #define DA_DEFAULT_RETRY 4 #endif #ifndef DA_DEFAULT_SEND_ORDERED #define DA_DEFAULT_SEND_ORDERED 1 #endif static int da_poll_period = DA_DEFAULT_POLL_PERIOD; static int da_retry_count = DA_DEFAULT_RETRY; static int da_default_timeout = DA_DEFAULT_TIMEOUT; static sbintime_t da_default_softtimeout = DA_DEFAULT_SOFTTIMEOUT; static int da_send_ordered = DA_DEFAULT_SEND_ORDERED; static int da_disable_wp_detection = 0; static SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0, "CAM Direct Access Disk driver"); SYSCTL_INT(_kern_cam_da, OID_AUTO, poll_period, CTLFLAG_RWTUN, &da_poll_period, 0, "Media polling period in seconds"); SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RWTUN, &da_retry_count, 0, "Normal I/O retry count"); SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RWTUN, &da_default_timeout, 0, "Normal I/O timeout (in seconds)"); SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFLAG_RWTUN, &da_send_ordered, 0, "Send Ordered Tags"); SYSCTL_INT(_kern_cam_da, OID_AUTO, disable_wp_detection, CTLFLAG_RWTUN, &da_disable_wp_detection, 0, "Disable detection of write-protected disks"); SYSCTL_PROC(_kern_cam_da, OID_AUTO, default_softtimeout, CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, dasysctlsofttimeout, "I", "Soft I/O timeout (ms)"); TUNABLE_INT64("kern.cam.da.default_softtimeout", &da_default_softtimeout); /* * DA_ORDEREDTAG_INTERVAL determines how often, relative * to the default timeout, we check to see whether an ordered * tagged transaction is appropriate to prevent simple tag * starvation. Since we'd like to ensure that there is at least * 1/2 of the timeout length left for a starved transaction to * complete after we've sent an ordered tag, we must poll at least * four times in every timeout period. This takes care of the worst * case where a starved transaction starts during an interval that * meets the requirement "don't send an ordered tag" test so it takes * us two intervals to determine that a tag must be sent. */ #ifndef DA_ORDEREDTAG_INTERVAL #define DA_ORDEREDTAG_INTERVAL 4 #endif static struct periph_driver dadriver = { dainit, "da", TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0 }; PERIPHDRIVER_DECLARE(da, dadriver); static MALLOC_DEFINE(M_SCSIDA, "scsi_da", "scsi_da buffers"); /* * This driver takes out references / holds in well defined pairs, never * recursively. These macros / inline functions enforce those rules. They * are only enabled with DA_TRACK_REFS or INVARIANTS. If DA_TRACK_REFS is * defined to be 2 or larger, the tracking also includes debug printfs. */ #if defined(DA_TRACK_REFS) || defined(INVARIANTS) #ifndef DA_TRACK_REFS #define DA_TRACK_REFS 1 #endif #if DA_TRACK_REFS > 1 static const char *da_ref_text[] = { "bogus", "open", "open hold", "close hold", "reprobe hold", "Test Unit Ready", "Geom", "sysctl", "reprobe", "max -- also bogus" }; #define DA_PERIPH_PRINT(periph, msg, args...) \ CAM_PERIPH_PRINT(periph, msg, ##args) #else #define DA_PERIPH_PRINT(periph, msg, args...) #endif static inline void token_sanity(da_ref_token token) { if ((unsigned)token >= DA_REF_MAX) panic("Bad token value passed in %d\n", token); } static inline int da_periph_hold(struct cam_periph *periph, int priority, da_ref_token token) { int err = cam_periph_hold(periph, priority); token_sanity(token); DA_PERIPH_PRINT(periph, "Holding device %s (%d): %d\n", da_ref_text[token], token, err); if (err == 0) { int cnt; struct da_softc *softc = periph->softc; cnt = atomic_fetchadd_int(&softc->ref_flags[token], 1); if (cnt != 0) panic("Re-holding for reason %d, cnt = %d", token, cnt); } return (err); } static inline void da_periph_unhold(struct cam_periph *periph, da_ref_token token) { int cnt; struct da_softc *softc = periph->softc; token_sanity(token); DA_PERIPH_PRINT(periph, "Unholding device %s (%d)\n", da_ref_text[token], token); cnt = atomic_fetchadd_int(&softc->ref_flags[token], -1); if (cnt != 1) panic("Unholding %d with cnt = %d", token, cnt); cam_periph_unhold(periph); } static inline int da_periph_acquire(struct cam_periph *periph, da_ref_token token) { int err = cam_periph_acquire(periph); token_sanity(token); DA_PERIPH_PRINT(periph, "acquiring device %s (%d): %d\n", da_ref_text[token], token, err); if (err == 0) { int cnt; struct da_softc *softc = periph->softc; cnt = atomic_fetchadd_int(&softc->ref_flags[token], 1); if (cnt != 0) panic("Re-refing for reason %d, cnt = %d", token, cnt); } return (err); } static inline void da_periph_release(struct cam_periph *periph, da_ref_token token) { int cnt; struct da_softc *softc = periph->softc; token_sanity(token); DA_PERIPH_PRINT(periph, "releasing device %s (%d)\n", da_ref_text[token], token); cnt = atomic_fetchadd_int(&softc->ref_flags[token], -1); if (cnt != 1) panic("Releasing %d with cnt = %d", token, cnt); cam_periph_release(periph); } static inline void da_periph_release_locked(struct cam_periph *periph, da_ref_token token) { int cnt; struct da_softc *softc = periph->softc; token_sanity(token); DA_PERIPH_PRINT(periph, "releasing device (locked) %s (%d)\n", da_ref_text[token], token); cnt = atomic_fetchadd_int(&softc->ref_flags[token], -1); if (cnt != 1) panic("Unholding %d with cnt = %d", token, cnt); cam_periph_release_locked(periph); } #define cam_periph_hold POISON #define cam_periph_unhold POISON #define cam_periph_acquire POISON #define cam_periph_release POISON #define cam_periph_release_locked POISON #else #define da_periph_hold(periph, prio, token) cam_periph_hold((periph), (prio)) #define da_periph_unhold(periph, token) cam_periph_unhold((periph)) #define da_periph_acquire(periph, token) cam_periph_acquire((periph)) #define da_periph_release(periph, token) cam_periph_release((periph)) #define da_periph_release_locked(periph, token) cam_periph_release_locked((periph)) #endif static int daopen(struct disk *dp) { struct cam_periph *periph; struct da_softc *softc; int error; periph = (struct cam_periph *)dp->d_drv1; if (da_periph_acquire(periph, DA_REF_OPEN) != 0) { return (ENXIO); } cam_periph_lock(periph); if ((error = da_periph_hold(periph, PRIBIO|PCATCH, DA_REF_OPEN_HOLD)) != 0) { cam_periph_unlock(periph); da_periph_release(periph, DA_REF_OPEN); return (error); } CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, ("daopen\n")); softc = (struct da_softc *)periph->softc; dareprobe(periph); /* Wait for the disk size update. */ error = cam_periph_sleep(periph, &softc->disk->d_mediasize, PRIBIO, "dareprobe", 0); if (error != 0) xpt_print(periph->path, "unable to retrieve capacity data\n"); if (periph->flags & CAM_PERIPH_INVALID) error = ENXIO; if (error == 0 && (softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && (softc->quirks & DA_Q_NO_PREVENT) == 0) daprevent(periph, PR_PREVENT); if (error == 0) { softc->flags &= ~DA_FLAG_PACK_INVALID; softc->flags |= DA_FLAG_OPEN; } da_periph_unhold(periph, DA_REF_OPEN_HOLD); cam_periph_unlock(periph); if (error != 0) da_periph_release(periph, DA_REF_OPEN); return (error); } static int daclose(struct disk *dp) { struct cam_periph *periph; struct da_softc *softc; union ccb *ccb; periph = (struct cam_periph *)dp->d_drv1; softc = (struct da_softc *)periph->softc; cam_periph_lock(periph); CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH, ("daclose\n")); if (da_periph_hold(periph, PRIBIO, DA_REF_CLOSE_HOLD) == 0) { /* Flush disk cache. */ if ((softc->flags & DA_FLAG_DIRTY) != 0 && (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0 && (softc->flags & DA_FLAG_PACK_INVALID) == 0) { ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); scsi_synchronize_cache(&ccb->csio, /*retries*/1, /*cbfcnp*/NULL, MSG_SIMPLE_Q_TAG, /*begin_lba*/0, /*lb_count*/0, SSD_FULL_SIZE, 5 * 60 * 1000); cam_periph_runccb(ccb, daerror, /*cam_flags*/0, /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR, softc->disk->d_devstat); softc->flags &= ~DA_FLAG_DIRTY; xpt_release_ccb(ccb); } /* Allow medium removal. */ if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 && (softc->quirks & DA_Q_NO_PREVENT) == 0) daprevent(periph, PR_ALLOW); da_periph_unhold(periph, DA_REF_CLOSE_HOLD); } /* * If we've got removeable media, mark the blocksize as * unavailable, since it could change when new media is * inserted. */ if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE; softc->flags &= ~DA_FLAG_OPEN; while (softc->refcount != 0) cam_periph_sleep(periph, &softc->refcount, PRIBIO, "daclose", 1); cam_periph_unlock(periph); da_periph_release(periph, DA_REF_OPEN); return (0); } static void daschedule(struct cam_periph *periph) { struct da_softc *softc = (struct da_softc *)periph->softc; if (softc->state != DA_STATE_NORMAL) return; cam_iosched_schedule(softc->cam_iosched, periph); } /* * Actually translate the requested transfer into one the physical driver * can understand. The transfer is described by a buf and will include * only one physical transfer. */ static void dastrategy(struct bio *bp) { struct cam_periph *periph; struct da_softc *softc; periph = (struct cam_periph *)bp->bio_disk->d_drv1; softc = (struct da_softc *)periph->softc; cam_periph_lock(periph); /* * If the device has been made invalid, error out */ if ((softc->flags & DA_FLAG_PACK_INVALID)) { cam_periph_unlock(periph); biofinish(bp, NULL, ENXIO); return; } CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastrategy(%p)\n", bp)); /* * Zone commands must be ordered, because they can depend on the * effects of previously issued commands, and they may affect * commands after them. */ if (bp->bio_cmd == BIO_ZONE) bp->bio_flags |= BIO_ORDERED; /* * Place it in the queue of disk activities for this disk */ cam_iosched_queue_work(softc->cam_iosched, bp); /* * Schedule ourselves for performing the work. */ daschedule(periph); cam_periph_unlock(periph); return; } static int dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length) { struct cam_periph *periph; struct da_softc *softc; u_int secsize; struct ccb_scsiio csio; struct disk *dp; int error = 0; dp = arg; periph = dp->d_drv1; softc = (struct da_softc *)periph->softc; secsize = softc->params.secsize; if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) return (ENXIO); memset(&csio, 0, sizeof(csio)); if (length > 0) { xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); csio.ccb_h.ccb_state = DA_CCB_DUMP; scsi_read_write(&csio, /*retries*/0, /*cbfcnp*/NULL, MSG_ORDERED_Q_TAG, /*read*/SCSI_RW_WRITE, /*byte2*/0, /*minimum_cmd_size*/ softc->minimum_cmd_size, offset / secsize, length / secsize, /*data_ptr*/(u_int8_t *) virtual, /*dxfer_len*/length, /*sense_len*/SSD_FULL_SIZE, da_default_timeout * 1000); error = cam_periph_runccb((union ccb *)&csio, cam_periph_error, 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL); if (error != 0) printf("Aborting dump due to I/O error.\n"); return (error); } /* * Sync the disk cache contents to the physical media. */ if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL); csio.ccb_h.ccb_state = DA_CCB_DUMP; scsi_synchronize_cache(&csio, /*retries*/0, /*cbfcnp*/NULL, MSG_SIMPLE_Q_TAG, /*begin_lba*/0,/* Cover the whole disk */ /*lb_count*/0, SSD_FULL_SIZE, 5 * 1000); error = cam_periph_runccb((union ccb *)&csio, cam_periph_error, 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL); if (error != 0) xpt_print(periph->path, "Synchronize cache failed\n"); } return (error); } static int dagetattr(struct bio *bp) { int ret; struct cam_periph *periph; periph = (struct cam_periph *)bp->bio_disk->d_drv1; cam_periph_lock(periph); ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute, periph->path); cam_periph_unlock(periph); if (ret == 0) bp->bio_completed = bp->bio_length; return ret; } static void dainit(void) { cam_status status; /* * Install a global async callback. This callback will * receive async callbacks like "new device found". */ status = xpt_register_async(AC_FOUND_DEVICE, daasync, NULL, NULL); if (status != CAM_REQ_CMP) { printf("da: Failed to attach master async callback " "due to status 0x%x!\n", status); } else if (da_send_ordered) { /* Register our shutdown event handler */ if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, NULL, SHUTDOWN_PRI_DEFAULT)) == NULL) printf("dainit: shutdown event registration failed!\n"); } } /* * Callback from GEOM, called when it has finished cleaning up its * resources. */ static void dadiskgonecb(struct disk *dp) { struct cam_periph *periph; periph = (struct cam_periph *)dp->d_drv1; da_periph_release(periph, DA_REF_GEOM); } static void daoninvalidate(struct cam_periph *periph) { struct da_softc *softc; cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; /* * De-register any async callbacks. */ xpt_register_async(0, daasync, periph, periph->path); softc->flags |= DA_FLAG_PACK_INVALID; #ifdef CAM_IO_STATS softc->invalidations++; #endif /* * Return all queued I/O with ENXIO. * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ cam_iosched_flush(softc->cam_iosched, NULL, ENXIO); /* * Tell GEOM that we've gone away, we'll get a callback when it is * done cleaning up its resources. */ disk_gone(softc->disk); } static void dacleanup(struct cam_periph *periph) { struct da_softc *softc; softc = (struct da_softc *)periph->softc; cam_periph_unlock(periph); cam_iosched_fini(softc->cam_iosched); /* * If we can't free the sysctl tree, oh well... */ if ((softc->flags & DA_FLAG_SCTX_INIT) != 0) { #ifdef CAM_IO_STATS if (sysctl_ctx_free(&softc->sysctl_stats_ctx) != 0) xpt_print(periph->path, "can't remove sysctl stats context\n"); #endif if (sysctl_ctx_free(&softc->sysctl_ctx) != 0) xpt_print(periph->path, "can't remove sysctl context\n"); } callout_drain(&softc->mediapoll_c); disk_destroy(softc->disk); callout_drain(&softc->sendordered_c); free(softc, M_DEVBUF); cam_periph_lock(periph); } static void daasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) { struct cam_periph *periph; struct da_softc *softc; periph = (struct cam_periph *)callback_arg; switch (code) { case AC_FOUND_DEVICE: /* callback to create periph, no locking yet */ { struct ccb_getdev *cgd; cam_status status; cgd = (struct ccb_getdev *)arg; if (cgd == NULL) break; if (cgd->protocol != PROTO_SCSI) break; if (SID_QUAL(&cgd->inq_data) != SID_QUAL_LU_CONNECTED) break; if (SID_TYPE(&cgd->inq_data) != T_DIRECT && SID_TYPE(&cgd->inq_data) != T_RBC && SID_TYPE(&cgd->inq_data) != T_OPTICAL && SID_TYPE(&cgd->inq_data) != T_ZBC_HM) break; /* * Allocate a peripheral instance for * this device and start the probe * process. */ status = cam_periph_alloc(daregister, daoninvalidate, dacleanup, dastart, "da", CAM_PERIPH_BIO, path, daasync, AC_FOUND_DEVICE, cgd); if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) printf("daasync: Unable to attach to new device " "due to status 0x%x\n", status); return; } case AC_ADVINFO_CHANGED: /* Doesn't touch periph */ { uintptr_t buftype; buftype = (uintptr_t)arg; if (buftype == CDAI_TYPE_PHYS_PATH) { struct da_softc *softc; softc = periph->softc; disk_attr_changed(softc->disk, "GEOM::physpath", M_NOWAIT); } break; } case AC_UNIT_ATTENTION: { union ccb *ccb; int error_code, sense_key, asc, ascq; softc = (struct da_softc *)periph->softc; ccb = (union ccb *)arg; /* * Handle all UNIT ATTENTIONs except our own, as they will be * handled by daerror(). Since this comes from a different periph, * that periph's lock is held, not ours, so we have to take it ours * out to touch softc flags. */ if (xpt_path_periph(ccb->ccb_h.path) != periph && scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)) { if (asc == 0x2A && ascq == 0x09) { xpt_print(ccb->ccb_h.path, "Capacity data has changed\n"); cam_periph_lock(periph); softc->flags &= ~DA_FLAG_PROBED; cam_periph_unlock(periph); dareprobe(periph); } else if (asc == 0x28 && ascq == 0x00) { cam_periph_lock(periph); softc->flags &= ~DA_FLAG_PROBED; cam_periph_unlock(periph); disk_media_changed(softc->disk, M_NOWAIT); } else if (asc == 0x3F && ascq == 0x03) { xpt_print(ccb->ccb_h.path, "INQUIRY data has changed\n"); cam_periph_lock(periph); softc->flags &= ~DA_FLAG_PROBED; cam_periph_unlock(periph); dareprobe(periph); } } break; } case AC_SCSI_AEN: /* Called for this path: periph locked */ /* * Appears to be currently unused for SCSI devices, only ata SIMs * generate this. */ cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; if (!cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR) && (softc->flags & DA_FLAG_TUR_PENDING) == 0) { if (da_periph_acquire(periph, DA_REF_TUR) == 0) { cam_iosched_set_work_flags(softc->cam_iosched, DA_WORK_TUR); daschedule(periph); } } /* FALLTHROUGH */ case AC_SENT_BDR: /* Called for this path: periph locked */ case AC_BUS_RESET: /* Called for this path: periph locked */ { struct ccb_hdr *ccbh; cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; /* * Don't fail on the expected unit attention * that will occur. */ softc->flags |= DA_FLAG_RETRY_UA; LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le) ccbh->ccb_state |= DA_CCB_RETRY_UA; break; } case AC_INQ_CHANGED: /* Called for this path: periph locked */ cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; softc->flags &= ~DA_FLAG_PROBED; dareprobe(periph); break; default: break; } cam_periph_async(periph, code, path, arg); } static void dasysctlinit(void *context, int pending) { struct cam_periph *periph; struct da_softc *softc; char tmpstr[32], tmpstr2[16]; struct ccb_trans_settings cts; periph = (struct cam_periph *)context; /* * periph was held for us when this task was enqueued */ if (periph->flags & CAM_PERIPH_INVALID) { da_periph_release(periph, DA_REF_SYSCTL); return; } softc = (struct da_softc *)periph->softc; snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number); snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number); sysctl_ctx_init(&softc->sysctl_ctx); cam_periph_lock(periph); softc->flags |= DA_FLAG_SCTX_INIT; cam_periph_unlock(periph); softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2, CTLFLAG_RD, 0, tmpstr, "device_index"); if (softc->sysctl_tree == NULL) { printf("dasysctlinit: unable to allocate sysctl tree\n"); da_periph_release(periph, DA_REF_SYSCTL); return; } /* * Now register the sysctl handler, so the user can change the value on * the fly. */ SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RWTUN, softc, 0, dadeletemethodsysctl, "A", "BIO_DELETE execution method"); SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "delete_max", CTLTYPE_U64 | CTLFLAG_RW, softc, 0, dadeletemaxsysctl, "Q", "Maximum BIO_DELETE size"); SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW, &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I", "Minimum CDB size"); SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "trim_count", CTLFLAG_RD, &softc->trim_count, "Total number of unmap/dsm commands sent"); SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "trim_ranges", CTLFLAG_RD, &softc->trim_ranges, "Total number of ranges in unmap/dsm commands"); SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "trim_lbas", CTLFLAG_RD, &softc->trim_lbas, "Total lbas in the unmap/dsm commands sent"); SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "zone_mode", CTLTYPE_STRING | CTLFLAG_RD, softc, 0, dazonemodesysctl, "A", "Zone Mode"); SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "zone_support", CTLTYPE_STRING | CTLFLAG_RD, softc, 0, dazonesupsysctl, "A", "Zone Support"); SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "optimal_seq_zones", CTLFLAG_RD, &softc->optimal_seq_zones, "Optimal Number of Open Sequential Write Preferred Zones"); SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "optimal_nonseq_zones", CTLFLAG_RD, &softc->optimal_nonseq_zones, "Optimal Number of Non-Sequentially Written Sequential Write " "Preferred Zones"); SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "max_seq_zones", CTLFLAG_RD, &softc->max_seq_zones, "Maximum Number of Open Sequential Write Required Zones"); SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "error_inject", CTLFLAG_RW, &softc->error_inject, 0, "error_inject leaf"); SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "unmapped_io", CTLFLAG_RD, &softc->unmappedio, 0, "Unmapped I/O support"); SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "rotating", CTLFLAG_RD, &softc->rotating, 0, "Rotating media"); SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "p_type", CTLFLAG_RD, &softc->p_type, 0, "DIF protection type"); #ifdef CAM_TEST_FAILURE SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "invalidate", CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE, periph, 0, cam_periph_invalidate_sysctl, "I", "Write 1 to invalidate the drive immediately"); #endif /* * Add some addressing info. */ memset(&cts, 0, sizeof (cts)); xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE); cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS; cts.type = CTS_TYPE_CURRENT_SETTINGS; cam_periph_lock(periph); xpt_action((union ccb *)&cts); cam_periph_unlock(periph); if (cts.ccb_h.status != CAM_REQ_CMP) { da_periph_release(periph, DA_REF_SYSCTL); return; } if (cts.protocol == PROTO_SCSI && cts.transport == XPORT_FC) { struct ccb_trans_settings_fc *fc = &cts.xport_specific.fc; if (fc->valid & CTS_FC_VALID_WWPN) { softc->wwpn = fc->wwpn; SYSCTL_ADD_UQUAD(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "wwpn", CTLFLAG_RD, &softc->wwpn, "World Wide Port Name"); } } #ifdef CAM_IO_STATS /* * Now add some useful stats. * XXX These should live in cam_periph and be common to all periphs */ softc->sysctl_stats_tree = SYSCTL_ADD_NODE(&softc->sysctl_stats_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "stats", CTLFLAG_RD, 0, "Statistics"); SYSCTL_ADD_INT(&softc->sysctl_stats_ctx, SYSCTL_CHILDREN(softc->sysctl_stats_tree), OID_AUTO, "errors", CTLFLAG_RD, &softc->errors, 0, "Transport errors reported by the SIM"); SYSCTL_ADD_INT(&softc->sysctl_stats_ctx, SYSCTL_CHILDREN(softc->sysctl_stats_tree), OID_AUTO, "timeouts", CTLFLAG_RD, &softc->timeouts, 0, "Device timeouts reported by the SIM"); SYSCTL_ADD_INT(&softc->sysctl_stats_ctx, SYSCTL_CHILDREN(softc->sysctl_stats_tree), OID_AUTO, "pack_invalidations", CTLFLAG_RD, &softc->invalidations, 0, "Device pack invalidations"); #endif cam_iosched_sysctl_init(softc->cam_iosched, &softc->sysctl_ctx, softc->sysctl_tree); da_periph_release(periph, DA_REF_SYSCTL); } static int dadeletemaxsysctl(SYSCTL_HANDLER_ARGS) { int error; uint64_t value; struct da_softc *softc; softc = (struct da_softc *)arg1; value = softc->disk->d_delmaxsize; error = sysctl_handle_64(oidp, &value, 0, req); if ((error != 0) || (req->newptr == NULL)) return (error); /* only accept values smaller than the calculated value */ if (value > dadeletemaxsize(softc, softc->delete_method)) { return (EINVAL); } softc->disk->d_delmaxsize = value; return (0); } static int dacmdsizesysctl(SYSCTL_HANDLER_ARGS) { int error, value; value = *(int *)arg1; error = sysctl_handle_int(oidp, &value, 0, req); if ((error != 0) || (req->newptr == NULL)) return (error); /* * Acceptable values here are 6, 10, 12 or 16. */ if (value < 6) value = 6; else if ((value > 6) && (value <= 10)) value = 10; else if ((value > 10) && (value <= 12)) value = 12; else if (value > 12) value = 16; *(int *)arg1 = value; return (0); } static int dasysctlsofttimeout(SYSCTL_HANDLER_ARGS) { sbintime_t value; int error; value = da_default_softtimeout / SBT_1MS; error = sysctl_handle_int(oidp, (int *)&value, 0, req); if ((error != 0) || (req->newptr == NULL)) return (error); /* XXX Should clip this to a reasonable level */ if (value > da_default_timeout * 1000) return (EINVAL); da_default_softtimeout = value * SBT_1MS; return (0); } static void dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method) { softc->delete_method = delete_method; softc->disk->d_delmaxsize = dadeletemaxsize(softc, delete_method); softc->delete_func = da_delete_functions[delete_method]; if (softc->delete_method > DA_DELETE_DISABLE) softc->disk->d_flags |= DISKFLAG_CANDELETE; else softc->disk->d_flags &= ~DISKFLAG_CANDELETE; } static off_t dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method) { off_t sectors; switch(delete_method) { case DA_DELETE_UNMAP: sectors = (off_t)softc->unmap_max_lba; break; case DA_DELETE_ATA_TRIM: sectors = (off_t)ATA_DSM_RANGE_MAX * softc->trim_max_ranges; break; case DA_DELETE_WS16: sectors = omin(softc->ws_max_blks, WS16_MAX_BLKS); break; case DA_DELETE_ZERO: case DA_DELETE_WS10: sectors = omin(softc->ws_max_blks, WS10_MAX_BLKS); break; default: return 0; } return (off_t)softc->params.secsize * omin(sectors, softc->params.sectors); } static void daprobedone(struct cam_periph *periph, union ccb *ccb) { struct da_softc *softc; softc = (struct da_softc *)periph->softc; cam_periph_assert(periph, MA_OWNED); dadeletemethodchoose(softc, DA_DELETE_NONE); if (bootverbose && (softc->flags & DA_FLAG_ANNOUNCED) == 0) { char buf[80]; int i, sep; snprintf(buf, sizeof(buf), "Delete methods: <"); sep = 0; for (i = 0; i <= DA_DELETE_MAX; i++) { if ((softc->delete_available & (1 << i)) == 0 && i != softc->delete_method) continue; if (sep) strlcat(buf, ",", sizeof(buf)); strlcat(buf, da_delete_method_names[i], sizeof(buf)); if (i == softc->delete_method) strlcat(buf, "(*)", sizeof(buf)); sep = 1; } strlcat(buf, ">", sizeof(buf)); printf("%s%d: %s\n", periph->periph_name, periph->unit_number, buf); } if ((softc->disk->d_flags & DISKFLAG_WRITE_PROTECT) != 0 && (softc->flags & DA_FLAG_ANNOUNCED) == 0) { printf("%s%d: Write Protected\n", periph->periph_name, periph->unit_number); } /* * Since our peripheral may be invalidated by an error * above or an external event, we must release our CCB * before releasing the probe lock on the peripheral. * The peripheral will only go away once the last lock * is removed, and we need it around for the CCB release * operation. */ xpt_release_ccb(ccb); softc->state = DA_STATE_NORMAL; softc->flags |= DA_FLAG_PROBED; daschedule(periph); wakeup(&softc->disk->d_mediasize); if ((softc->flags & DA_FLAG_ANNOUNCED) == 0) { softc->flags |= DA_FLAG_ANNOUNCED; da_periph_unhold(periph, DA_REF_PROBE_HOLD); } else da_periph_release_locked(periph, DA_REF_REPROBE); } static void dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method) { int i, methods; /* If available, prefer the method requested by user. */ i = softc->delete_method_pref; methods = softc->delete_available | (1 << DA_DELETE_DISABLE); if (methods & (1 << i)) { dadeletemethodset(softc, i); return; } /* Use the pre-defined order to choose the best performing delete. */ for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) { if (i == DA_DELETE_ZERO) continue; if (softc->delete_available & (1 << i)) { dadeletemethodset(softc, i); return; } } /* Fallback to default. */ dadeletemethodset(softc, default_method); } static int dadeletemethodsysctl(SYSCTL_HANDLER_ARGS) { char buf[16]; const char *p; struct da_softc *softc; int i, error, value; softc = (struct da_softc *)arg1; value = softc->delete_method; if (value < 0 || value > DA_DELETE_MAX) p = "UNKNOWN"; else p = da_delete_method_names[value]; strncpy(buf, p, sizeof(buf)); error = sysctl_handle_string(oidp, buf, sizeof(buf), req); if (error != 0 || req->newptr == NULL) return (error); for (i = 0; i <= DA_DELETE_MAX; i++) { if (strcmp(buf, da_delete_method_names[i]) == 0) break; } if (i > DA_DELETE_MAX) return (EINVAL); softc->delete_method_pref = i; dadeletemethodchoose(softc, DA_DELETE_NONE); return (0); } static int dazonemodesysctl(SYSCTL_HANDLER_ARGS) { char tmpbuf[40]; struct da_softc *softc; int error; softc = (struct da_softc *)arg1; switch (softc->zone_mode) { case DA_ZONE_DRIVE_MANAGED: snprintf(tmpbuf, sizeof(tmpbuf), "Drive Managed"); break; case DA_ZONE_HOST_AWARE: snprintf(tmpbuf, sizeof(tmpbuf), "Host Aware"); break; case DA_ZONE_HOST_MANAGED: snprintf(tmpbuf, sizeof(tmpbuf), "Host Managed"); break; case DA_ZONE_NONE: default: snprintf(tmpbuf, sizeof(tmpbuf), "Not Zoned"); break; } error = sysctl_handle_string(oidp, tmpbuf, sizeof(tmpbuf), req); return (error); } static int dazonesupsysctl(SYSCTL_HANDLER_ARGS) { char tmpbuf[180]; struct da_softc *softc; struct sbuf sb; int error, first; unsigned int i; softc = (struct da_softc *)arg1; error = 0; first = 1; sbuf_new(&sb, tmpbuf, sizeof(tmpbuf), 0); for (i = 0; i < sizeof(da_zone_desc_table) / sizeof(da_zone_desc_table[0]); i++) { if (softc->zone_flags & da_zone_desc_table[i].value) { if (first == 0) sbuf_printf(&sb, ", "); else first = 0; sbuf_cat(&sb, da_zone_desc_table[i].desc); } } if (first == 1) sbuf_printf(&sb, "None"); sbuf_finish(&sb); error = sysctl_handle_string(oidp, sbuf_data(&sb), sbuf_len(&sb), req); return (error); } static cam_status daregister(struct cam_periph *periph, void *arg) { struct da_softc *softc; struct ccb_pathinq cpi; struct ccb_getdev *cgd; char tmpstr[80]; caddr_t match; cgd = (struct ccb_getdev *)arg; if (cgd == NULL) { printf("daregister: no getdev CCB, can't register device\n"); return(CAM_REQ_CMP_ERR); } softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF, M_NOWAIT|M_ZERO); if (softc == NULL) { printf("daregister: Unable to probe new device. " "Unable to allocate softc\n"); return(CAM_REQ_CMP_ERR); } if (cam_iosched_init(&softc->cam_iosched, periph) != 0) { printf("daregister: Unable to probe new device. " "Unable to allocate iosched memory\n"); free(softc, M_DEVBUF); return(CAM_REQ_CMP_ERR); } LIST_INIT(&softc->pending_ccbs); softc->state = DA_STATE_PROBE_WP; bioq_init(&softc->delete_run_queue); if (SID_IS_REMOVABLE(&cgd->inq_data)) softc->flags |= DA_FLAG_PACK_REMOVABLE; softc->unmap_max_ranges = UNMAP_MAX_RANGES; softc->unmap_max_lba = UNMAP_RANGE_MAX; softc->unmap_gran = 0; softc->unmap_gran_align = 0; softc->ws_max_blks = WS16_MAX_BLKS; softc->trim_max_ranges = ATA_TRIM_MAX_RANGES; softc->rotating = 1; periph->softc = softc; /* * See if this device has any quirks. */ match = cam_quirkmatch((caddr_t)&cgd->inq_data, (caddr_t)da_quirk_table, nitems(da_quirk_table), sizeof(*da_quirk_table), scsi_inquiry_match); if (match != NULL) softc->quirks = ((struct da_quirk_entry *)match)->quirks; else softc->quirks = DA_Q_NONE; /* Check if the SIM does not want 6 byte commands */ xpt_path_inq(&cpi, periph->path); if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE)) softc->quirks |= DA_Q_NO_6_BYTE; if (SID_TYPE(&cgd->inq_data) == T_ZBC_HM) softc->zone_mode = DA_ZONE_HOST_MANAGED; else if (softc->quirks & DA_Q_SMR_DM) softc->zone_mode = DA_ZONE_DRIVE_MANAGED; else softc->zone_mode = DA_ZONE_NONE; if (softc->zone_mode != DA_ZONE_NONE) { if (scsi_vpd_supported_page(periph, SVPD_ATA_INFORMATION)) { if (scsi_vpd_supported_page(periph, SVPD_ZONED_BDC)) softc->zone_interface = DA_ZONE_IF_ATA_SAT; else softc->zone_interface = DA_ZONE_IF_ATA_PASS; } else softc->zone_interface = DA_ZONE_IF_SCSI; } TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph); /* * Take an exclusive section lock qon the periph while dastart is called * to finish the probe. The lock will be dropped in dadone at the end * of probe. This locks out daopen and daclose from racing with the * probe. * * XXX if cam_periph_hold returns an error, we don't hold a refcount. */ (void)da_periph_hold(periph, PRIBIO, DA_REF_PROBE_HOLD); /* * Schedule a periodic event to occasionally send an * ordered tag to a device. */ callout_init_mtx(&softc->sendordered_c, cam_periph_mtx(periph), 0); callout_reset(&softc->sendordered_c, (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL, dasendorderedtag, periph); cam_periph_unlock(periph); /* * RBC devices don't have to support READ(6), only READ(10). */ if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC) softc->minimum_cmd_size = 10; else softc->minimum_cmd_size = 6; /* * Load the user's default, if any. */ snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size", periph->unit_number); TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size); /* * 6, 10, 12 and 16 are the currently permissible values. */ if (softc->minimum_cmd_size > 12) softc->minimum_cmd_size = 16; else if (softc->minimum_cmd_size > 10) softc->minimum_cmd_size = 12; else if (softc->minimum_cmd_size > 6) softc->minimum_cmd_size = 10; else softc->minimum_cmd_size = 6; /* Predict whether device may support READ CAPACITY(16). */ if (SID_ANSI_REV(&cgd->inq_data) >= SCSI_REV_SPC3 && (softc->quirks & DA_Q_NO_RC16) == 0) { softc->flags |= DA_FLAG_CAN_RC16; } /* * Register this media as a disk. */ softc->disk = disk_alloc(); softc->disk->d_devstat = devstat_new_entry(periph->periph_name, periph->unit_number, 0, DEVSTAT_BS_UNAVAILABLE, SID_TYPE(&cgd->inq_data) | XPORT_DEVSTAT_TYPE(cpi.transport), DEVSTAT_PRIORITY_DISK); softc->disk->d_open = daopen; softc->disk->d_close = daclose; softc->disk->d_strategy = dastrategy; softc->disk->d_dump = dadump; softc->disk->d_getattr = dagetattr; softc->disk->d_gone = dadiskgonecb; softc->disk->d_name = "da"; softc->disk->d_drv1 = periph; if (cpi.maxio == 0) softc->maxio = DFLTPHYS; /* traditional default */ else if (cpi.maxio > MAXPHYS) softc->maxio = MAXPHYS; /* for safety */ else softc->maxio = cpi.maxio; if (softc->quirks & DA_Q_128KB) softc->maxio = min(softc->maxio, 128 * 1024); softc->disk->d_maxsize = softc->maxio; softc->disk->d_unit = periph->unit_number; softc->disk->d_flags = DISKFLAG_DIRECT_COMPLETION | DISKFLAG_CANZONE; if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; if ((cpi.hba_misc & PIM_UNMAPPED) != 0) { softc->unmappedio = 1; softc->disk->d_flags |= DISKFLAG_UNMAPPED_BIO; } cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor, sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr)); strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr)); cam_strvis(&softc->disk->d_descr[strlen(softc->disk->d_descr)], cgd->inq_data.product, sizeof(cgd->inq_data.product), sizeof(softc->disk->d_descr) - strlen(softc->disk->d_descr)); softc->disk->d_hba_vendor = cpi.hba_vendor; softc->disk->d_hba_device = cpi.hba_device; softc->disk->d_hba_subvendor = cpi.hba_subvendor; softc->disk->d_hba_subdevice = cpi.hba_subdevice; /* * Acquire a reference to the periph before we register with GEOM. * We'll release this reference once GEOM calls us back (via * dadiskgonecb()) telling us that our provider has been freed. */ if (da_periph_acquire(periph, DA_REF_GEOM) != 0) { xpt_print(periph->path, "%s: lost periph during " "registration!\n", __func__); cam_periph_lock(periph); return (CAM_REQ_CMP_ERR); } disk_create(softc->disk, DISK_VERSION); cam_periph_lock(periph); /* * Add async callbacks for events of interest. * I don't bother checking if this fails as, * in most cases, the system will function just * fine without them and the only alternative * would be to not attach the device on failure. */ xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE | AC_ADVINFO_CHANGED | AC_SCSI_AEN | AC_UNIT_ATTENTION | AC_INQ_CHANGED, daasync, periph, periph->path); /* * Emit an attribute changed notification just in case * physical path information arrived before our async * event handler was registered, but after anyone attaching * to our disk device polled it. */ disk_attr_changed(softc->disk, "GEOM::physpath", M_NOWAIT); /* * Schedule a periodic media polling events. */ callout_init_mtx(&softc->mediapoll_c, cam_periph_mtx(periph), 0); if ((softc->flags & DA_FLAG_PACK_REMOVABLE) && (cgd->inq_flags & SID_AEN) == 0 && da_poll_period != 0) callout_reset(&softc->mediapoll_c, da_poll_period * hz, damediapoll, periph); xpt_schedule(periph, CAM_PRIORITY_DEV); return(CAM_REQ_CMP); } static int da_zone_bio_to_scsi(int disk_zone_cmd) { switch (disk_zone_cmd) { case DISK_ZONE_OPEN: return ZBC_OUT_SA_OPEN; case DISK_ZONE_CLOSE: return ZBC_OUT_SA_CLOSE; case DISK_ZONE_FINISH: return ZBC_OUT_SA_FINISH; case DISK_ZONE_RWP: return ZBC_OUT_SA_RWP; } return -1; } static int da_zone_cmd(struct cam_periph *periph, union ccb *ccb, struct bio *bp, int *queue_ccb) { struct da_softc *softc; int error; error = 0; if (bp->bio_cmd != BIO_ZONE) { error = EINVAL; goto bailout; } softc = periph->softc; switch (bp->bio_zone.zone_cmd) { case DISK_ZONE_OPEN: case DISK_ZONE_CLOSE: case DISK_ZONE_FINISH: case DISK_ZONE_RWP: { int zone_flags; int zone_sa; uint64_t lba; zone_sa = da_zone_bio_to_scsi(bp->bio_zone.zone_cmd); if (zone_sa == -1) { xpt_print(periph->path, "Cannot translate zone " "cmd %#x to SCSI\n", bp->bio_zone.zone_cmd); error = EINVAL; goto bailout; } zone_flags = 0; lba = bp->bio_zone.zone_params.rwp.id; if (bp->bio_zone.zone_params.rwp.flags & DISK_ZONE_RWP_FLAG_ALL) zone_flags |= ZBC_OUT_ALL; if (softc->zone_interface != DA_ZONE_IF_ATA_PASS) { scsi_zbc_out(&ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*service_action*/ zone_sa, /*zone_id*/ lba, /*zone_flags*/ zone_flags, /*data_ptr*/ NULL, /*dxfer_len*/ 0, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); } else { /* * Note that in this case, even though we can * technically use NCQ, we don't bother for several * reasons: * 1. It hasn't been tested on a SAT layer that * supports it. This is new as of SAT-4. * 2. Even when there is a SAT layer that supports * it, that SAT layer will also probably support * ZBC -> ZAC translation, since they are both * in the SAT-4 spec. * 3. Translation will likely be preferable to ATA * passthrough. LSI / Avago at least single * steps ATA passthrough commands in the HBA, * regardless of protocol, so unless that * changes, there is a performance penalty for * doing ATA passthrough no matter whether * you're using NCQ/FPDMA, DMA or PIO. * 4. It requires a 32-byte CDB, which at least at * this point in CAM requires a CDB pointer, which * would require us to allocate an additional bit * of storage separate from the CCB. */ error = scsi_ata_zac_mgmt_out(&ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*use_ncq*/ 0, /*zm_action*/ zone_sa, /*zone_id*/ lba, /*zone_flags*/ zone_flags, /*data_ptr*/ NULL, /*dxfer_len*/ 0, /*cdb_storage*/ NULL, /*cdb_storage_len*/ 0, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); if (error != 0) { error = EINVAL; xpt_print(periph->path, "scsi_ata_zac_mgmt_out() returned an " "error!"); goto bailout; } } *queue_ccb = 1; break; } case DISK_ZONE_REPORT_ZONES: { uint8_t *rz_ptr; uint32_t num_entries, alloc_size; struct disk_zone_report *rep; rep = &bp->bio_zone.zone_params.report; num_entries = rep->entries_allocated; if (num_entries == 0) { xpt_print(periph->path, "No entries allocated for " "Report Zones request\n"); error = EINVAL; goto bailout; } alloc_size = sizeof(struct scsi_report_zones_hdr) + (sizeof(struct scsi_report_zones_desc) * num_entries); alloc_size = min(alloc_size, softc->disk->d_maxsize); rz_ptr = malloc(alloc_size, M_SCSIDA, M_NOWAIT | M_ZERO); if (rz_ptr == NULL) { xpt_print(periph->path, "Unable to allocate memory " "for Report Zones request\n"); error = ENOMEM; goto bailout; } if (softc->zone_interface != DA_ZONE_IF_ATA_PASS) { scsi_zbc_in(&ccb->csio, /*retries*/ da_retry_count, /*cbcfnp*/ dadone, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*service_action*/ ZBC_IN_SA_REPORT_ZONES, /*zone_start_lba*/ rep->starting_id, /*zone_options*/ rep->rep_options, /*data_ptr*/ rz_ptr, /*dxfer_len*/ alloc_size, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); } else { /* * Note that in this case, even though we can * technically use NCQ, we don't bother for several * reasons: * 1. It hasn't been tested on a SAT layer that * supports it. This is new as of SAT-4. * 2. Even when there is a SAT layer that supports * it, that SAT layer will also probably support * ZBC -> ZAC translation, since they are both * in the SAT-4 spec. * 3. Translation will likely be preferable to ATA * passthrough. LSI / Avago at least single * steps ATA passthrough commands in the HBA, * regardless of protocol, so unless that * changes, there is a performance penalty for * doing ATA passthrough no matter whether * you're using NCQ/FPDMA, DMA or PIO. * 4. It requires a 32-byte CDB, which at least at * this point in CAM requires a CDB pointer, which * would require us to allocate an additional bit * of storage separate from the CCB. */ error = scsi_ata_zac_mgmt_in(&ccb->csio, /*retries*/ da_retry_count, /*cbcfnp*/ dadone, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*use_ncq*/ 0, /*zm_action*/ ATA_ZM_REPORT_ZONES, /*zone_id*/ rep->starting_id, /*zone_flags*/ rep->rep_options, /*data_ptr*/ rz_ptr, /*dxfer_len*/ alloc_size, /*cdb_storage*/ NULL, /*cdb_storage_len*/ 0, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); if (error != 0) { error = EINVAL; xpt_print(periph->path, "scsi_ata_zac_mgmt_in() returned an " "error!"); goto bailout; } } /* * For BIO_ZONE, this isn't normally needed. However, it * is used by devstat_end_transaction_bio() to determine * how much data was transferred. */ /* * XXX KDM we have a problem. But I'm not sure how to fix * it. devstat uses bio_bcount - bio_resid to calculate * the amount of data transferred. The GEOM disk code * uses bio_length - bio_resid to calculate the amount of * data in bio_completed. We have different structure * sizes above and below the ada(4) driver. So, if we * use the sizes above, the amount transferred won't be * quite accurate for devstat. If we use different sizes * for bio_bcount and bio_length (above and below * respectively), then the residual needs to match one or * the other. Everything is calculated after the bio * leaves the driver, so changing the values around isn't * really an option. For now, just set the count to the * passed in length. This means that the calculations * above (e.g. bio_completed) will be correct, but the * amount of data reported to devstat will be slightly * under or overstated. */ bp->bio_bcount = bp->bio_length; *queue_ccb = 1; break; } case DISK_ZONE_GET_PARAMS: { struct disk_zone_disk_params *params; params = &bp->bio_zone.zone_params.disk_params; bzero(params, sizeof(*params)); switch (softc->zone_mode) { case DA_ZONE_DRIVE_MANAGED: params->zone_mode = DISK_ZONE_MODE_DRIVE_MANAGED; break; case DA_ZONE_HOST_AWARE: params->zone_mode = DISK_ZONE_MODE_HOST_AWARE; break; case DA_ZONE_HOST_MANAGED: params->zone_mode = DISK_ZONE_MODE_HOST_MANAGED; break; default: case DA_ZONE_NONE: params->zone_mode = DISK_ZONE_MODE_NONE; break; } if (softc->zone_flags & DA_ZONE_FLAG_URSWRZ) params->flags |= DISK_ZONE_DISK_URSWRZ; if (softc->zone_flags & DA_ZONE_FLAG_OPT_SEQ_SET) { params->optimal_seq_zones = softc->optimal_seq_zones; params->flags |= DISK_ZONE_OPT_SEQ_SET; } if (softc->zone_flags & DA_ZONE_FLAG_OPT_NONSEQ_SET) { params->optimal_nonseq_zones = softc->optimal_nonseq_zones; params->flags |= DISK_ZONE_OPT_NONSEQ_SET; } if (softc->zone_flags & DA_ZONE_FLAG_MAX_SEQ_SET) { params->max_seq_zones = softc->max_seq_zones; params->flags |= DISK_ZONE_MAX_SEQ_SET; } if (softc->zone_flags & DA_ZONE_FLAG_RZ_SUP) params->flags |= DISK_ZONE_RZ_SUP; if (softc->zone_flags & DA_ZONE_FLAG_OPEN_SUP) params->flags |= DISK_ZONE_OPEN_SUP; if (softc->zone_flags & DA_ZONE_FLAG_CLOSE_SUP) params->flags |= DISK_ZONE_CLOSE_SUP; if (softc->zone_flags & DA_ZONE_FLAG_FINISH_SUP) params->flags |= DISK_ZONE_FINISH_SUP; if (softc->zone_flags & DA_ZONE_FLAG_RWP_SUP) params->flags |= DISK_ZONE_RWP_SUP; break; } default: break; } bailout: return (error); } static void dastart(struct cam_periph *periph, union ccb *start_ccb) { struct da_softc *softc; cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n")); skipstate: switch (softc->state) { case DA_STATE_NORMAL: { struct bio *bp; uint8_t tag_code; more: bp = cam_iosched_next_bio(softc->cam_iosched); if (bp == NULL) { if (cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR)) { softc->flags |= DA_FLAG_TUR_PENDING; cam_iosched_clr_work_flags(softc->cam_iosched, DA_WORK_TUR); scsi_test_unit_ready(&start_ccb->csio, /*retries*/ da_retry_count, dadone_tur, MSG_SIMPLE_Q_TAG, SSD_FULL_SIZE, da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_TUR; xpt_action(start_ccb); } else xpt_release_ccb(start_ccb); break; } if (bp->bio_cmd == BIO_DELETE) { if (softc->delete_func != NULL) { softc->delete_func(periph, start_ccb, bp); goto out; } else { /* * Not sure this is possible, but failsafe by * lying and saying "sure, done." */ biofinish(bp, NULL, 0); goto more; } } if (cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR)) { cam_iosched_clr_work_flags(softc->cam_iosched, DA_WORK_TUR); da_periph_release_locked(periph, DA_REF_TUR); } if ((bp->bio_flags & BIO_ORDERED) != 0 || (softc->flags & DA_FLAG_NEED_OTAG) != 0) { softc->flags &= ~DA_FLAG_NEED_OTAG; softc->flags |= DA_FLAG_WAS_OTAG; tag_code = MSG_ORDERED_Q_TAG; } else { tag_code = MSG_SIMPLE_Q_TAG; } switch (bp->bio_cmd) { case BIO_WRITE: case BIO_READ: { void *data_ptr; int rw_op; biotrack(bp, __func__); if (bp->bio_cmd == BIO_WRITE) { softc->flags |= DA_FLAG_DIRTY; rw_op = SCSI_RW_WRITE; } else { rw_op = SCSI_RW_READ; } data_ptr = bp->bio_data; if ((bp->bio_flags & (BIO_UNMAPPED|BIO_VLIST)) != 0) { rw_op |= SCSI_RW_BIO; data_ptr = bp; } scsi_read_write(&start_ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone, /*tag_action*/tag_code, rw_op, /*byte2*/0, softc->minimum_cmd_size, /*lba*/bp->bio_pblkno, /*block_count*/bp->bio_bcount / softc->params.secsize, data_ptr, /*dxfer_len*/ bp->bio_bcount, /*sense_len*/SSD_FULL_SIZE, da_default_timeout * 1000); #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) start_ccb->csio.bio = bp; #endif break; } case BIO_FLUSH: /* * If we don't support sync cache, or the disk * isn't dirty, FLUSH is a no-op. Use the * allocated CCB for the next bio if one is * available. */ if ((softc->quirks & DA_Q_NO_SYNC_CACHE) != 0 || (softc->flags & DA_FLAG_DIRTY) == 0) { biodone(bp); goto skipstate; } /* * BIO_FLUSH doesn't currently communicate * range data, so we synchronize the cache * over the whole disk. */ scsi_synchronize_cache(&start_ccb->csio, /*retries*/1, /*cbfcnp*/dadone, /*tag_action*/tag_code, /*begin_lba*/0, /*lb_count*/0, SSD_FULL_SIZE, da_default_timeout*1000); /* * Clear the dirty flag before sending the command. * Either this sync cache will be successful, or it * will fail after a retry. If it fails, it is * unlikely to be successful if retried later, so * we'll save ourselves time by just marking the * device clean. */ softc->flags &= ~DA_FLAG_DIRTY; break; case BIO_ZONE: { int error, queue_ccb; queue_ccb = 0; error = da_zone_cmd(periph, start_ccb, bp,&queue_ccb); if ((error != 0) || (queue_ccb == 0)) { biofinish(bp, NULL, error); xpt_release_ccb(start_ccb); return; } break; } } start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO; start_ccb->ccb_h.flags |= CAM_UNLOCKED; start_ccb->ccb_h.softtimeout = sbttotv(da_default_softtimeout); out: LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h, periph_links.le); /* We expect a unit attention from this device */ if ((softc->flags & DA_FLAG_RETRY_UA) != 0) { start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA; softc->flags &= ~DA_FLAG_RETRY_UA; } start_ccb->ccb_h.ccb_bp = bp; softc->refcount++; cam_periph_unlock(periph); xpt_action(start_ccb); cam_periph_lock(periph); /* May have more work to do, so ensure we stay scheduled */ daschedule(periph); break; } case DA_STATE_PROBE_WP: { void *mode_buf; int mode_buf_len; if (da_disable_wp_detection) { if ((softc->flags & DA_FLAG_CAN_RC16) != 0) softc->state = DA_STATE_PROBE_RC16; else softc->state = DA_STATE_PROBE_RC; goto skipstate; } mode_buf_len = 192; mode_buf = malloc(mode_buf_len, M_SCSIDA, M_NOWAIT); if (mode_buf == NULL) { xpt_print(periph->path, "Unable to send mode sense - " "malloc failure\n"); if ((softc->flags & DA_FLAG_CAN_RC16) != 0) softc->state = DA_STATE_PROBE_RC16; else softc->state = DA_STATE_PROBE_RC; goto skipstate; } scsi_mode_sense_len(&start_ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone_probewp, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*dbd*/ FALSE, /*pc*/ SMS_PAGE_CTRL_CURRENT, /*page*/ SMS_ALL_PAGES_PAGE, /*param_buf*/ mode_buf, /*param_len*/ mode_buf_len, /*minimum_cmd_size*/ softc->minimum_cmd_size, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_WP; xpt_action(start_ccb); break; } case DA_STATE_PROBE_RC: { struct scsi_read_capacity_data *rcap; rcap = (struct scsi_read_capacity_data *) malloc(sizeof(*rcap), M_SCSIDA, M_NOWAIT|M_ZERO); if (rcap == NULL) { printf("dastart: Couldn't malloc read_capacity data\n"); /* da_free_periph??? */ break; } scsi_read_capacity(&start_ccb->csio, /*retries*/da_retry_count, dadone_proberc, MSG_SIMPLE_Q_TAG, rcap, SSD_FULL_SIZE, /*timeout*/5000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_RC; xpt_action(start_ccb); break; } case DA_STATE_PROBE_RC16: { struct scsi_read_capacity_data_long *rcaplong; rcaplong = (struct scsi_read_capacity_data_long *) malloc(sizeof(*rcaplong), M_SCSIDA, M_NOWAIT|M_ZERO); if (rcaplong == NULL) { printf("dastart: Couldn't malloc read_capacity data\n"); /* da_free_periph??? */ break; } scsi_read_capacity_16(&start_ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone_proberc, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*lba*/ 0, /*reladr*/ 0, /*pmi*/ 0, /*rcap_buf*/ (uint8_t *)rcaplong, /*rcap_buf_len*/ sizeof(*rcaplong), /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_RC16; xpt_action(start_ccb); break; } case DA_STATE_PROBE_LBP: { struct scsi_vpd_logical_block_prov *lbp; if (!scsi_vpd_supported_page(periph, SVPD_LBP)) { /* * If we get here we don't support any SBC-3 delete * methods with UNMAP as the Logical Block Provisioning * VPD page support is required for devices which * support it according to T10/1799-D Revision 31 * however older revisions of the spec don't mandate * this so we currently don't remove these methods * from the available set. */ softc->state = DA_STATE_PROBE_BLK_LIMITS; goto skipstate; } lbp = (struct scsi_vpd_logical_block_prov *) malloc(sizeof(*lbp), M_SCSIDA, M_NOWAIT|M_ZERO); if (lbp == NULL) { printf("dastart: Couldn't malloc lbp data\n"); /* da_free_periph??? */ break; } scsi_inquiry(&start_ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone_probelbp, /*tag_action*/MSG_SIMPLE_Q_TAG, /*inq_buf*/(u_int8_t *)lbp, /*inq_len*/sizeof(*lbp), /*evpd*/TRUE, /*page_code*/SVPD_LBP, /*sense_len*/SSD_MIN_SIZE, /*timeout*/da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_LBP; xpt_action(start_ccb); break; } case DA_STATE_PROBE_BLK_LIMITS: { struct scsi_vpd_block_limits *block_limits; if (!scsi_vpd_supported_page(periph, SVPD_BLOCK_LIMITS)) { /* Not supported skip to next probe */ softc->state = DA_STATE_PROBE_BDC; goto skipstate; } block_limits = (struct scsi_vpd_block_limits *) malloc(sizeof(*block_limits), M_SCSIDA, M_NOWAIT|M_ZERO); if (block_limits == NULL) { printf("dastart: Couldn't malloc block_limits data\n"); /* da_free_periph??? */ break; } scsi_inquiry(&start_ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone_probeblklimits, /*tag_action*/MSG_SIMPLE_Q_TAG, /*inq_buf*/(u_int8_t *)block_limits, /*inq_len*/sizeof(*block_limits), /*evpd*/TRUE, /*page_code*/SVPD_BLOCK_LIMITS, /*sense_len*/SSD_MIN_SIZE, /*timeout*/da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BLK_LIMITS; xpt_action(start_ccb); break; } case DA_STATE_PROBE_BDC: { struct scsi_vpd_block_characteristics *bdc; if (!scsi_vpd_supported_page(periph, SVPD_BDC)) { softc->state = DA_STATE_PROBE_ATA; goto skipstate; } bdc = (struct scsi_vpd_block_characteristics *) malloc(sizeof(*bdc), M_SCSIDA, M_NOWAIT|M_ZERO); if (bdc == NULL) { printf("dastart: Couldn't malloc bdc data\n"); /* da_free_periph??? */ break; } scsi_inquiry(&start_ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone_probebdc, /*tag_action*/MSG_SIMPLE_Q_TAG, /*inq_buf*/(u_int8_t *)bdc, /*inq_len*/sizeof(*bdc), /*evpd*/TRUE, /*page_code*/SVPD_BDC, /*sense_len*/SSD_MIN_SIZE, /*timeout*/da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BDC; xpt_action(start_ccb); break; } case DA_STATE_PROBE_ATA: { struct ata_params *ata_params; if (!scsi_vpd_supported_page(periph, SVPD_ATA_INFORMATION)) { if ((softc->zone_mode == DA_ZONE_HOST_AWARE) || (softc->zone_mode == DA_ZONE_HOST_MANAGED)) { /* * Note that if the ATA VPD page isn't * supported, we aren't talking to an ATA * device anyway. Support for that VPD * page is mandatory for SCSI to ATA (SAT) * translation layers. */ softc->state = DA_STATE_PROBE_ZONE; goto skipstate; } daprobedone(periph, start_ccb); break; } - ata_params = &periph->path->device->ident_data; + ata_params = (struct ata_params*) + malloc(sizeof(*ata_params), M_SCSIDA,M_NOWAIT|M_ZERO); + if (ata_params == NULL) { + xpt_print(periph->path, "Couldn't malloc ata_params " + "data\n"); + /* da_free_periph??? */ + break; + } + scsi_ata_identify(&start_ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone_probeata, /*tag_action*/MSG_SIMPLE_Q_TAG, /*data_ptr*/(u_int8_t *)ata_params, /*dxfer_len*/sizeof(*ata_params), /*sense_len*/SSD_FULL_SIZE, /*timeout*/da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA; xpt_action(start_ccb); break; } case DA_STATE_PROBE_ATA_LOGDIR: { struct ata_gp_log_dir *log_dir; int retval; retval = 0; if ((softc->flags & DA_FLAG_CAN_ATA_LOG) == 0) { /* * If we don't have log support, not much point in * trying to probe zone support. */ daprobedone(periph, start_ccb); break; } /* * If we have an ATA device (the SCSI ATA Information VPD * page should be present and the ATA identify should have * succeeded) and it supports logs, ask for the log directory. */ log_dir = malloc(sizeof(*log_dir), M_SCSIDA, M_NOWAIT|M_ZERO); if (log_dir == NULL) { xpt_print(periph->path, "Couldn't malloc log_dir " "data\n"); daprobedone(periph, start_ccb); break; } retval = scsi_ata_read_log(&start_ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone_probeatalogdir, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*log_address*/ ATA_LOG_DIRECTORY, /*page_number*/ 0, /*block_count*/ 1, /*protocol*/ softc->flags & DA_FLAG_CAN_ATA_DMA ? AP_PROTO_DMA : AP_PROTO_PIO_IN, /*data_ptr*/ (uint8_t *)log_dir, /*dxfer_len*/ sizeof(*log_dir), /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); if (retval != 0) { xpt_print(periph->path, "scsi_ata_read_log() failed!"); free(log_dir, M_SCSIDA); daprobedone(periph, start_ccb); break; } start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA_LOGDIR; xpt_action(start_ccb); break; } case DA_STATE_PROBE_ATA_IDDIR: { struct ata_identify_log_pages *id_dir; int retval; retval = 0; /* * Check here to see whether the Identify Device log is * supported in the directory of logs. If so, continue * with requesting the log of identify device pages. */ if ((softc->flags & DA_FLAG_CAN_ATA_IDLOG) == 0) { daprobedone(periph, start_ccb); break; } id_dir = malloc(sizeof(*id_dir), M_SCSIDA, M_NOWAIT | M_ZERO); if (id_dir == NULL) { xpt_print(periph->path, "Couldn't malloc id_dir " "data\n"); daprobedone(periph, start_ccb); break; } retval = scsi_ata_read_log(&start_ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone_probeataiddir, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*log_address*/ ATA_IDENTIFY_DATA_LOG, /*page_number*/ ATA_IDL_PAGE_LIST, /*block_count*/ 1, /*protocol*/ softc->flags & DA_FLAG_CAN_ATA_DMA ? AP_PROTO_DMA : AP_PROTO_PIO_IN, /*data_ptr*/ (uint8_t *)id_dir, /*dxfer_len*/ sizeof(*id_dir), /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); if (retval != 0) { xpt_print(periph->path, "scsi_ata_read_log() failed!"); free(id_dir, M_SCSIDA); daprobedone(periph, start_ccb); break; } start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA_IDDIR; xpt_action(start_ccb); break; } case DA_STATE_PROBE_ATA_SUP: { struct ata_identify_log_sup_cap *sup_cap; int retval; retval = 0; /* * Check here to see whether the Supported Capabilities log * is in the list of Identify Device logs. */ if ((softc->flags & DA_FLAG_CAN_ATA_SUPCAP) == 0) { daprobedone(periph, start_ccb); break; } sup_cap = malloc(sizeof(*sup_cap), M_SCSIDA, M_NOWAIT|M_ZERO); if (sup_cap == NULL) { xpt_print(periph->path, "Couldn't malloc sup_cap " "data\n"); daprobedone(periph, start_ccb); break; } retval = scsi_ata_read_log(&start_ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone_probeatasup, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*log_address*/ ATA_IDENTIFY_DATA_LOG, /*page_number*/ ATA_IDL_SUP_CAP, /*block_count*/ 1, /*protocol*/ softc->flags & DA_FLAG_CAN_ATA_DMA ? AP_PROTO_DMA : AP_PROTO_PIO_IN, /*data_ptr*/ (uint8_t *)sup_cap, /*dxfer_len*/ sizeof(*sup_cap), /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); if (retval != 0) { xpt_print(periph->path, "scsi_ata_read_log() failed!"); free(sup_cap, M_SCSIDA); daprobedone(periph, start_ccb); break; } start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA_SUP; xpt_action(start_ccb); break; } case DA_STATE_PROBE_ATA_ZONE: { struct ata_zoned_info_log *ata_zone; int retval; retval = 0; /* * Check here to see whether the zoned device information * page is supported. If so, continue on to request it. * If not, skip to DA_STATE_PROBE_LOG or done. */ if ((softc->flags & DA_FLAG_CAN_ATA_ZONE) == 0) { daprobedone(periph, start_ccb); break; } ata_zone = malloc(sizeof(*ata_zone), M_SCSIDA, M_NOWAIT|M_ZERO); if (ata_zone == NULL) { xpt_print(periph->path, "Couldn't malloc ata_zone " "data\n"); daprobedone(periph, start_ccb); break; } retval = scsi_ata_read_log(&start_ccb->csio, /*retries*/ da_retry_count, /*cbfcnp*/ dadone_probeatazone, /*tag_action*/ MSG_SIMPLE_Q_TAG, /*log_address*/ ATA_IDENTIFY_DATA_LOG, /*page_number*/ ATA_IDL_ZDI, /*block_count*/ 1, /*protocol*/ softc->flags & DA_FLAG_CAN_ATA_DMA ? AP_PROTO_DMA : AP_PROTO_PIO_IN, /*data_ptr*/ (uint8_t *)ata_zone, /*dxfer_len*/ sizeof(*ata_zone), /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ da_default_timeout * 1000); if (retval != 0) { xpt_print(periph->path, "scsi_ata_read_log() failed!"); free(ata_zone, M_SCSIDA); daprobedone(periph, start_ccb); break; } start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA_ZONE; xpt_action(start_ccb); break; } case DA_STATE_PROBE_ZONE: { struct scsi_vpd_zoned_bdc *bdc; /* * Note that this page will be supported for SCSI protocol * devices that support ZBC (SMR devices), as well as ATA * protocol devices that are behind a SAT (SCSI to ATA * Translation) layer that supports converting ZBC commands * to their ZAC equivalents. */ if (!scsi_vpd_supported_page(periph, SVPD_ZONED_BDC)) { daprobedone(periph, start_ccb); break; } bdc = (struct scsi_vpd_zoned_bdc *) malloc(sizeof(*bdc), M_SCSIDA, M_NOWAIT|M_ZERO); if (bdc == NULL) { xpt_release_ccb(start_ccb); xpt_print(periph->path, "Couldn't malloc zone VPD " "data\n"); break; } scsi_inquiry(&start_ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone_probezone, /*tag_action*/MSG_SIMPLE_Q_TAG, /*inq_buf*/(u_int8_t *)bdc, /*inq_len*/sizeof(*bdc), /*evpd*/TRUE, /*page_code*/SVPD_ZONED_BDC, /*sense_len*/SSD_FULL_SIZE, /*timeout*/da_default_timeout * 1000); start_ccb->ccb_h.ccb_bp = NULL; start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ZONE; xpt_action(start_ccb); break; } } } /* * In each of the methods below, while its the caller's * responsibility to ensure the request will fit into a * single device request, we might have changed the delete * method due to the device incorrectly advertising either * its supported methods or limits. * * To prevent this causing further issues we validate the * against the methods limits, and warn which would * otherwise be unnecessary. */ static void da_delete_unmap(struct cam_periph *periph, union ccb *ccb, struct bio *bp) { struct da_softc *softc = (struct da_softc *)periph->softc;; struct bio *bp1; uint8_t *buf = softc->unmap_buf; struct scsi_unmap_desc *d = (void *)&buf[UNMAP_HEAD_SIZE]; uint64_t lba, lastlba = (uint64_t)-1; uint64_t totalcount = 0; uint64_t count; uint32_t c, lastcount = 0, ranges = 0; /* * Currently this doesn't take the UNMAP * Granularity and Granularity Alignment * fields into account. * * This could result in both unoptimal unmap * requests as as well as UNMAP calls unmapping * fewer LBA's than requested. */ bzero(softc->unmap_buf, sizeof(softc->unmap_buf)); bp1 = bp; do { /* * Note: ada and da are different in how they store the * pending bp's in a trim. ada stores all of them in the * trim_req.bps. da stores all but the first one in the * delete_run_queue. ada then completes all the bps in * its adadone() loop. da completes all the bps in the * delete_run_queue in dadone, and relies on the biodone * after to complete. This should be reconciled since there's * no real reason to do it differently. XXX */ if (bp1 != bp) bioq_insert_tail(&softc->delete_run_queue, bp1); lba = bp1->bio_pblkno; count = bp1->bio_bcount / softc->params.secsize; /* Try to extend the previous range. */ if (lba == lastlba) { c = omin(count, UNMAP_RANGE_MAX - lastcount); lastlba += c; lastcount += c; scsi_ulto4b(lastcount, d[ranges - 1].length); count -= c; lba += c; totalcount += c; } else if ((softc->quirks & DA_Q_STRICT_UNMAP) && softc->unmap_gran != 0) { /* Align length of the previous range. */ if ((c = lastcount % softc->unmap_gran) != 0) { if (lastcount <= c) { totalcount -= lastcount; lastlba = (uint64_t)-1; lastcount = 0; ranges--; } else { totalcount -= c; lastlba -= c; lastcount -= c; scsi_ulto4b(lastcount, d[ranges - 1].length); } } /* Align beginning of the new range. */ c = (lba - softc->unmap_gran_align) % softc->unmap_gran; if (c != 0) { c = softc->unmap_gran - c; if (count <= c) { count = 0; } else { lba += c; count -= c; } } } while (count > 0) { c = omin(count, UNMAP_RANGE_MAX); if (totalcount + c > softc->unmap_max_lba || ranges >= softc->unmap_max_ranges) { xpt_print(periph->path, "%s issuing short delete %ld > %ld" "|| %d >= %d", da_delete_method_desc[softc->delete_method], totalcount + c, softc->unmap_max_lba, ranges, softc->unmap_max_ranges); break; } scsi_u64to8b(lba, d[ranges].lba); scsi_ulto4b(c, d[ranges].length); lba += c; totalcount += c; ranges++; count -= c; lastlba = lba; lastcount = c; } bp1 = cam_iosched_next_trim(softc->cam_iosched); if (bp1 == NULL) break; if (ranges >= softc->unmap_max_ranges || totalcount + bp1->bio_bcount / softc->params.secsize > softc->unmap_max_lba) { cam_iosched_put_back_trim(softc->cam_iosched, bp1); break; } } while (1); /* Align length of the last range. */ if ((softc->quirks & DA_Q_STRICT_UNMAP) && softc->unmap_gran != 0 && (c = lastcount % softc->unmap_gran) != 0) { if (lastcount <= c) ranges--; else scsi_ulto4b(lastcount - c, d[ranges - 1].length); } scsi_ulto2b(ranges * 16 + 6, &buf[0]); scsi_ulto2b(ranges * 16, &buf[2]); scsi_unmap(&ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone, /*tag_action*/MSG_SIMPLE_Q_TAG, /*byte2*/0, /*data_ptr*/ buf, /*dxfer_len*/ ranges * 16 + 8, /*sense_len*/SSD_FULL_SIZE, da_default_timeout * 1000); ccb->ccb_h.ccb_state = DA_CCB_DELETE; ccb->ccb_h.flags |= CAM_UNLOCKED; softc->trim_count++; softc->trim_ranges += ranges; softc->trim_lbas += totalcount; cam_iosched_submit_trim(softc->cam_iosched); } static void da_delete_trim(struct cam_periph *periph, union ccb *ccb, struct bio *bp) { struct da_softc *softc = (struct da_softc *)periph->softc; struct bio *bp1; uint8_t *buf = softc->unmap_buf; uint64_t lastlba = (uint64_t)-1; uint64_t count; uint64_t lba; uint32_t lastcount = 0, c, requestcount; int ranges = 0, off, block_count; bzero(softc->unmap_buf, sizeof(softc->unmap_buf)); bp1 = bp; do { if (bp1 != bp)//XXX imp XXX bioq_insert_tail(&softc->delete_run_queue, bp1); lba = bp1->bio_pblkno; count = bp1->bio_bcount / softc->params.secsize; requestcount = count; /* Try to extend the previous range. */ if (lba == lastlba) { c = omin(count, ATA_DSM_RANGE_MAX - lastcount); lastcount += c; off = (ranges - 1) * 8; buf[off + 6] = lastcount & 0xff; buf[off + 7] = (lastcount >> 8) & 0xff; count -= c; lba += c; } while (count > 0) { c = omin(count, ATA_DSM_RANGE_MAX); off = ranges * 8; buf[off + 0] = lba & 0xff; buf[off + 1] = (lba >> 8) & 0xff; buf[off + 2] = (lba >> 16) & 0xff; buf[off + 3] = (lba >> 24) & 0xff; buf[off + 4] = (lba >> 32) & 0xff; buf[off + 5] = (lba >> 40) & 0xff; buf[off + 6] = c & 0xff; buf[off + 7] = (c >> 8) & 0xff; lba += c; ranges++; count -= c; lastcount = c; if (count != 0 && ranges == softc->trim_max_ranges) { xpt_print(periph->path, "%s issuing short delete %ld > %ld\n", da_delete_method_desc[softc->delete_method], requestcount, (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX); break; } } lastlba = lba; bp1 = cam_iosched_next_trim(softc->cam_iosched); if (bp1 == NULL) break; if (bp1->bio_bcount / softc->params.secsize > (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX) { cam_iosched_put_back_trim(softc->cam_iosched, bp1); break; } } while (1); block_count = howmany(ranges, ATA_DSM_BLK_RANGES); scsi_ata_trim(&ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone, /*tag_action*/MSG_SIMPLE_Q_TAG, block_count, /*data_ptr*/buf, /*dxfer_len*/block_count * ATA_DSM_BLK_SIZE, /*sense_len*/SSD_FULL_SIZE, da_default_timeout * 1000); ccb->ccb_h.ccb_state = DA_CCB_DELETE; ccb->ccb_h.flags |= CAM_UNLOCKED; cam_iosched_submit_trim(softc->cam_iosched); } /* * We calculate ws_max_blks here based off d_delmaxsize instead * of using softc->ws_max_blks as it is absolute max for the * device not the protocol max which may well be lower. */ static void da_delete_ws(struct cam_periph *periph, union ccb *ccb, struct bio *bp) { struct da_softc *softc; struct bio *bp1; uint64_t ws_max_blks; uint64_t lba; uint64_t count; /* forward compat with WS32 */ softc = (struct da_softc *)periph->softc; ws_max_blks = softc->disk->d_delmaxsize / softc->params.secsize; lba = bp->bio_pblkno; count = 0; bp1 = bp; do { if (bp1 != bp)//XXX imp XXX bioq_insert_tail(&softc->delete_run_queue, bp1); count += bp1->bio_bcount / softc->params.secsize; if (count > ws_max_blks) { xpt_print(periph->path, "%s issuing short delete %ld > %ld\n", da_delete_method_desc[softc->delete_method], count, ws_max_blks); count = omin(count, ws_max_blks); break; } bp1 = cam_iosched_next_trim(softc->cam_iosched); if (bp1 == NULL) break; if (lba + count != bp1->bio_pblkno || count + bp1->bio_bcount / softc->params.secsize > ws_max_blks) { cam_iosched_put_back_trim(softc->cam_iosched, bp1); break; } } while (1); scsi_write_same(&ccb->csio, /*retries*/da_retry_count, /*cbfcnp*/dadone, /*tag_action*/MSG_SIMPLE_Q_TAG, /*byte2*/softc->delete_method == DA_DELETE_ZERO ? 0 : SWS_UNMAP, softc->delete_method == DA_DELETE_WS16 ? 16 : 10, /*lba*/lba, /*block_count*/count, /*data_ptr*/ __DECONST(void *, zero_region), /*dxfer_len*/ softc->params.secsize, /*sense_len*/SSD_FULL_SIZE, da_default_timeout * 1000); ccb->ccb_h.ccb_state = DA_CCB_DELETE; ccb->ccb_h.flags |= CAM_UNLOCKED; cam_iosched_submit_trim(softc->cam_iosched); } static int cmd6workaround(union ccb *ccb) { struct scsi_rw_6 cmd6; struct scsi_rw_10 *cmd10; struct da_softc *softc; u_int8_t *cdb; struct bio *bp; int frozen; cdb = ccb->csio.cdb_io.cdb_bytes; softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc; if (ccb->ccb_h.ccb_state == DA_CCB_DELETE) { da_delete_methods old_method = softc->delete_method; /* * Typically there are two reasons for failure here * 1. Delete method was detected as supported but isn't * 2. Delete failed due to invalid params e.g. too big * * While we will attempt to choose an alternative delete method * this may result in short deletes if the existing delete * requests from geom are big for the new method chosen. * * This method assumes that the error which triggered this * will not retry the io otherwise a panic will occur */ dadeleteflag(softc, old_method, 0); dadeletemethodchoose(softc, DA_DELETE_DISABLE); if (softc->delete_method == DA_DELETE_DISABLE) xpt_print(ccb->ccb_h.path, "%s failed, disabling BIO_DELETE\n", da_delete_method_desc[old_method]); else xpt_print(ccb->ccb_h.path, "%s failed, switching to %s BIO_DELETE\n", da_delete_method_desc[old_method], da_delete_method_desc[softc->delete_method]); while ((bp = bioq_takefirst(&softc->delete_run_queue)) != NULL) cam_iosched_queue_work(softc->cam_iosched, bp); cam_iosched_queue_work(softc->cam_iosched, (struct bio *)ccb->ccb_h.ccb_bp); ccb->ccb_h.ccb_bp = NULL; return (0); } /* Detect unsupported PREVENT ALLOW MEDIUM REMOVAL. */ if ((ccb->ccb_h.flags & CAM_CDB_POINTER) == 0 && (*cdb == PREVENT_ALLOW) && (softc->quirks & DA_Q_NO_PREVENT) == 0) { if (bootverbose) xpt_print(ccb->ccb_h.path, "PREVENT ALLOW MEDIUM REMOVAL not supported.\n"); softc->quirks |= DA_Q_NO_PREVENT; return (0); } /* Detect unsupported SYNCHRONIZE CACHE(10). */ if ((ccb->ccb_h.flags & CAM_CDB_POINTER) == 0 && (*cdb == SYNCHRONIZE_CACHE) && (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { if (bootverbose) xpt_print(ccb->ccb_h.path, "SYNCHRONIZE CACHE(10) not supported.\n"); softc->quirks |= DA_Q_NO_SYNC_CACHE; softc->disk->d_flags &= ~DISKFLAG_CANFLUSHCACHE; return (0); } /* Translation only possible if CDB is an array and cmd is R/W6 */ if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 || (*cdb != READ_6 && *cdb != WRITE_6)) return 0; xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, " "increasing minimum_cmd_size to 10.\n"); softc->minimum_cmd_size = 10; bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6)); cmd10 = (struct scsi_rw_10 *)cdb; cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10; cmd10->byte2 = 0; scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr); cmd10->reserved = 0; scsi_ulto2b(cmd6.length, cmd10->length); cmd10->control = cmd6.control; ccb->csio.cdb_len = sizeof(*cmd10); /* Requeue request, unfreezing queue if necessary */ frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0; ccb->ccb_h.status = CAM_REQUEUE_REQ; xpt_action(ccb); if (frozen) { cam_release_devq(ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } return (ERESTART); } static void dazonedone(struct cam_periph *periph, union ccb *ccb) { struct da_softc *softc; struct bio *bp; softc = periph->softc; bp = (struct bio *)ccb->ccb_h.ccb_bp; switch (bp->bio_zone.zone_cmd) { case DISK_ZONE_OPEN: case DISK_ZONE_CLOSE: case DISK_ZONE_FINISH: case DISK_ZONE_RWP: break; case DISK_ZONE_REPORT_ZONES: { uint32_t avail_len; struct disk_zone_report *rep; struct scsi_report_zones_hdr *hdr; struct scsi_report_zones_desc *desc; struct disk_zone_rep_entry *entry; uint32_t hdr_len, num_avail; uint32_t num_to_fill, i; int ata; rep = &bp->bio_zone.zone_params.report; avail_len = ccb->csio.dxfer_len - ccb->csio.resid; /* * Note that bio_resid isn't normally used for zone * commands, but it is used by devstat_end_transaction_bio() * to determine how much data was transferred. Because * the size of the SCSI/ATA data structures is different * than the size of the BIO interface structures, the * amount of data actually transferred from the drive will * be different than the amount of data transferred to * the user. */ bp->bio_resid = ccb->csio.resid; hdr = (struct scsi_report_zones_hdr *)ccb->csio.data_ptr; if (avail_len < sizeof(*hdr)) { /* * Is there a better error than EIO here? We asked * for at least the header, and we got less than * that. */ bp->bio_error = EIO; bp->bio_flags |= BIO_ERROR; bp->bio_resid = bp->bio_bcount; break; } if (softc->zone_interface == DA_ZONE_IF_ATA_PASS) ata = 1; else ata = 0; hdr_len = ata ? le32dec(hdr->length) : scsi_4btoul(hdr->length); if (hdr_len > 0) rep->entries_available = hdr_len / sizeof(*desc); else rep->entries_available = 0; /* * NOTE: using the same values for the BIO version of the * same field as the SCSI/ATA values. This means we could * get some additional values that aren't defined in bio.h * if more values of the same field are defined later. */ rep->header.same = hdr->byte4 & SRZ_SAME_MASK; rep->header.maximum_lba = ata ? le64dec(hdr->maximum_lba) : scsi_8btou64(hdr->maximum_lba); /* * If the drive reports no entries that match the query, * we're done. */ if (hdr_len == 0) { rep->entries_filled = 0; break; } num_avail = min((avail_len - sizeof(*hdr)) / sizeof(*desc), hdr_len / sizeof(*desc)); /* * If the drive didn't return any data, then we're done. */ if (num_avail == 0) { rep->entries_filled = 0; break; } num_to_fill = min(num_avail, rep->entries_allocated); /* * If the user didn't allocate any entries for us to fill, * we're done. */ if (num_to_fill == 0) { rep->entries_filled = 0; break; } for (i = 0, desc = &hdr->desc_list[0], entry=&rep->entries[0]; i < num_to_fill; i++, desc++, entry++) { /* * NOTE: we're mapping the values here directly * from the SCSI/ATA bit definitions to the bio.h * definitons. There is also a warning in * disk_zone.h, but the impact is that if * additional values are added in the SCSI/ATA * specs these will be visible to consumers of * this interface. */ entry->zone_type = desc->zone_type & SRZ_TYPE_MASK; entry->zone_condition = (desc->zone_flags & SRZ_ZONE_COND_MASK) >> SRZ_ZONE_COND_SHIFT; entry->zone_flags |= desc->zone_flags & (SRZ_ZONE_NON_SEQ|SRZ_ZONE_RESET); entry->zone_length = ata ? le64dec(desc->zone_length) : scsi_8btou64(desc->zone_length); entry->zone_start_lba = ata ? le64dec(desc->zone_start_lba) : scsi_8btou64(desc->zone_start_lba); entry->write_pointer_lba = ata ? le64dec(desc->write_pointer_lba) : scsi_8btou64(desc->write_pointer_lba); } rep->entries_filled = num_to_fill; break; } case DISK_ZONE_GET_PARAMS: default: /* * In theory we should not get a GET_PARAMS bio, since it * should be handled without queueing the command to the * drive. */ panic("%s: Invalid zone command %d", __func__, bp->bio_zone.zone_cmd); break; } if (bp->bio_zone.zone_cmd == DISK_ZONE_REPORT_ZONES) free(ccb->csio.data_ptr, M_SCSIDA); } static void dadone(struct cam_periph *periph, union ccb *done_ccb) { struct bio *bp, *bp1; struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; da_ccb_state state; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) if (csio->bio != NULL) biotrack(csio->bio, __func__); #endif state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK; cam_periph_lock(periph); bp = (struct bio *)done_ccb->ccb_h.ccb_bp; if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { int error; int sf; if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0) sf = SF_RETRY_UA; else sf = 0; error = daerror(done_ccb, CAM_RETRY_SELTO, sf); if (error == ERESTART) { /* A retry was scheduled, so just return. */ cam_periph_unlock(periph); return; } bp = (struct bio *)done_ccb->ccb_h.ccb_bp; if (error != 0) { int queued_error; /* * return all queued I/O with EIO, so that * the client can retry these I/Os in the * proper order should it attempt to recover. */ queued_error = EIO; if (error == ENXIO && (softc->flags & DA_FLAG_PACK_INVALID)== 0) { /* * Catastrophic error. Mark our pack as * invalid. * * XXX See if this is really a media * XXX change first? */ xpt_print(periph->path, "Invalidating pack\n"); softc->flags |= DA_FLAG_PACK_INVALID; #ifdef CAM_IO_STATS softc->invalidations++; #endif queued_error = ENXIO; } cam_iosched_flush(softc->cam_iosched, NULL, queued_error); if (bp != NULL) { bp->bio_error = error; bp->bio_resid = bp->bio_bcount; bp->bio_flags |= BIO_ERROR; } } else if (bp != NULL) { if (state == DA_CCB_DELETE) bp->bio_resid = 0; else bp->bio_resid = csio->resid; bp->bio_error = 0; if (bp->bio_resid != 0) bp->bio_flags |= BIO_ERROR; } if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } else if (bp != NULL) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) panic("REQ_CMP with QFRZN"); if (bp->bio_cmd == BIO_ZONE) dazonedone(periph, done_ccb); else if (state == DA_CCB_DELETE) bp->bio_resid = 0; else bp->bio_resid = csio->resid; if ((csio->resid > 0) && (bp->bio_cmd != BIO_ZONE)) bp->bio_flags |= BIO_ERROR; if (softc->error_inject != 0) { bp->bio_error = softc->error_inject; bp->bio_resid = bp->bio_bcount; bp->bio_flags |= BIO_ERROR; softc->error_inject = 0; } } if (bp != NULL) biotrack(bp, __func__); LIST_REMOVE(&done_ccb->ccb_h, periph_links.le); if (LIST_EMPTY(&softc->pending_ccbs)) softc->flags |= DA_FLAG_WAS_OTAG; /* * We need to call cam_iosched before we call biodone so that we don't * measure any activity that happens in the completion routine, which in * the case of sendfile can be quite extensive. Release the periph * refcount taken in dastart() for each CCB. */ cam_iosched_bio_complete(softc->cam_iosched, bp, done_ccb); xpt_release_ccb(done_ccb); KASSERT(softc->refcount >= 1, ("dadone softc %p refcount %d", softc, softc->refcount)); softc->refcount--; if (state == DA_CCB_DELETE) { TAILQ_HEAD(, bio) queue; TAILQ_INIT(&queue); TAILQ_CONCAT(&queue, &softc->delete_run_queue.queue, bio_queue); softc->delete_run_queue.insert_point = NULL; /* * Normally, the xpt_release_ccb() above would make sure * that when we have more work to do, that work would * get kicked off. However, we specifically keep * delete_running set to 0 before the call above to * allow other I/O to progress when many BIO_DELETE * requests are pushed down. We set delete_running to 0 * and call daschedule again so that we don't stall if * there are no other I/Os pending apart from BIO_DELETEs. */ cam_iosched_trim_done(softc->cam_iosched); daschedule(periph); cam_periph_unlock(periph); while ((bp1 = TAILQ_FIRST(&queue)) != NULL) { TAILQ_REMOVE(&queue, bp1, bio_queue); bp1->bio_error = bp->bio_error; if (bp->bio_flags & BIO_ERROR) { bp1->bio_flags |= BIO_ERROR; bp1->bio_resid = bp1->bio_bcount; } else bp1->bio_resid = 0; biodone(bp1); } } else { daschedule(periph); cam_periph_unlock(periph); } if (bp != NULL) biodone(bp); return; } static void dadone_probewp(struct cam_periph *periph, union ccb *done_ccb) { struct scsi_mode_header_6 *mode_hdr6; struct scsi_mode_header_10 *mode_hdr10; struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; uint8_t dev_spec; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probewp\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if (softc->minimum_cmd_size > 6) { mode_hdr10 = (struct scsi_mode_header_10 *)csio->data_ptr; dev_spec = mode_hdr10->dev_spec; } else { mode_hdr6 = (struct scsi_mode_header_6 *)csio->data_ptr; dev_spec = mode_hdr6->dev_spec; } if (cam_ccb_status(done_ccb) == CAM_REQ_CMP) { if ((dev_spec & 0x80) != 0) softc->disk->d_flags |= DISKFLAG_WRITE_PROTECT; else softc->disk->d_flags &= ~DISKFLAG_WRITE_PROTECT; } else { int error; error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(csio->data_ptr, M_SCSIDA); xpt_release_ccb(done_ccb); if ((softc->flags & DA_FLAG_CAN_RC16) != 0) softc->state = DA_STATE_PROBE_RC16; else softc->state = DA_STATE_PROBE_RC; xpt_schedule(periph, priority); return; } static void dadone_proberc(struct cam_periph *periph, union ccb *done_ccb) { struct scsi_read_capacity_data *rdcap; struct scsi_read_capacity_data_long *rcaplong; struct da_softc *softc; struct ccb_scsiio *csio; da_ccb_state state; char *announce_buf; u_int32_t priority; int lbp, n; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_proberc\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK; lbp = 0; rdcap = NULL; rcaplong = NULL; /* XXX TODO: can this be a malloc? */ announce_buf = softc->announce_temp; bzero(announce_buf, DA_ANNOUNCETMP_SZ); if (state == DA_CCB_PROBE_RC) rdcap =(struct scsi_read_capacity_data *)csio->data_ptr; else rcaplong = (struct scsi_read_capacity_data_long *) csio->data_ptr; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { struct disk_params *dp; uint32_t block_size; uint64_t maxsector; u_int lalba; /* Lowest aligned LBA. */ if (state == DA_CCB_PROBE_RC) { block_size = scsi_4btoul(rdcap->length); maxsector = scsi_4btoul(rdcap->addr); lalba = 0; /* * According to SBC-2, if the standard 10 * byte READ CAPACITY command returns 2^32, * we should issue the 16 byte version of * the command, since the device in question * has more sectors than can be represented * with the short version of the command. */ if (maxsector == 0xffffffff) { free(rdcap, M_SCSIDA); xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_RC16; xpt_schedule(periph, priority); return; } } else { block_size = scsi_4btoul(rcaplong->length); maxsector = scsi_8btou64(rcaplong->addr); lalba = scsi_2btoul(rcaplong->lalba_lbp); } /* * Because GEOM code just will panic us if we * give them an 'illegal' value we'll avoid that * here. */ if (block_size == 0) { block_size = 512; if (maxsector == 0) maxsector = -1; } if (block_size >= MAXPHYS) { xpt_print(periph->path, "unsupportable block size %ju\n", (uintmax_t) block_size); announce_buf = NULL; cam_periph_invalidate(periph); } else { /* * We pass rcaplong into dasetgeom(), * because it will only use it if it is * non-NULL. */ dasetgeom(periph, block_size, maxsector, rcaplong, sizeof(*rcaplong)); lbp = (lalba & SRC16_LBPME_A); dp = &softc->params; n = snprintf(announce_buf, DA_ANNOUNCETMP_SZ, "%juMB (%ju %u byte sectors", ((uintmax_t)dp->secsize * dp->sectors) / (1024 * 1024), (uintmax_t)dp->sectors, dp->secsize); if (softc->p_type != 0) { n += snprintf(announce_buf + n, DA_ANNOUNCETMP_SZ - n, ", DIF type %d", softc->p_type); } snprintf(announce_buf + n, DA_ANNOUNCETMP_SZ - n, ")"); } } else { int error; /* * Retry any UNIT ATTENTION type errors. They * are expected at boot. */ error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) { /* * A retry was scheuled, so * just return. */ return; } else if (error != 0) { int asc, ascq; int sense_key, error_code; int have_sense; cam_status status; struct ccb_getdev cgd; /* Don't wedge this device's queue */ status = done_ccb->ccb_h.status; if ((status & CAM_DEV_QFRZN) != 0) cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); xpt_setup_ccb(&cgd.ccb_h, done_ccb->ccb_h.path, CAM_PRIORITY_NORMAL); cgd.ccb_h.func_code = XPT_GDEV_TYPE; xpt_action((union ccb *)&cgd); if (scsi_extract_sense_ccb(done_ccb, &error_code, &sense_key, &asc, &ascq)) have_sense = TRUE; else have_sense = FALSE; /* * If we tried READ CAPACITY(16) and failed, * fallback to READ CAPACITY(10). */ if ((state == DA_CCB_PROBE_RC16) && (softc->flags & DA_FLAG_CAN_RC16) && (((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) || ((have_sense) && (error_code == SSD_CURRENT_ERROR || error_code == SSD_DESC_CURRENT_ERROR) && (sense_key == SSD_KEY_ILLEGAL_REQUEST)))) { cam_periph_assert(periph, MA_OWNED); softc->flags &= ~DA_FLAG_CAN_RC16; free(rdcap, M_SCSIDA); xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_RC; xpt_schedule(periph, priority); return; } /* * Attach to anything that claims to be a * direct access or optical disk device, * as long as it doesn't return a "Logical * unit not supported" (0x25) error. * "Internal Target Failure" (0x44) is also * special and typically means that the * device is a SATA drive behind a SATL * translation that's fallen into a * terminally fatal state. */ if ((have_sense) && (asc != 0x25) && (asc != 0x44) && (error_code == SSD_CURRENT_ERROR || error_code == SSD_DESC_CURRENT_ERROR)) { const char *sense_key_desc; const char *asc_desc; dasetgeom(periph, 512, -1, NULL, 0); scsi_sense_desc(sense_key, asc, ascq, &cgd.inq_data, &sense_key_desc, &asc_desc); snprintf(announce_buf, DA_ANNOUNCETMP_SZ, "Attempt to query device " "size failed: %s, %s", sense_key_desc, asc_desc); } else { if (have_sense) scsi_sense_print(&done_ccb->csio); else { xpt_print(periph->path, "got CAM status %#x\n", done_ccb->ccb_h.status); } xpt_print(periph->path, "fatal error, " "failed to attach to device\n"); announce_buf = NULL; /* * Free up resources. */ cam_periph_invalidate(periph); } } } free(csio->data_ptr, M_SCSIDA); if (announce_buf != NULL && ((softc->flags & DA_FLAG_ANNOUNCED) == 0)) { struct sbuf sb; sbuf_new(&sb, softc->announcebuf, DA_ANNOUNCE_SZ, SBUF_FIXEDLEN); xpt_announce_periph_sbuf(periph, &sb, announce_buf); xpt_announce_quirks_sbuf(periph, &sb, softc->quirks, DA_Q_BIT_STRING); sbuf_finish(&sb); sbuf_putbuf(&sb); /* * Create our sysctl variables, now that we know * we have successfully attached. */ /* increase the refcount */ if (da_periph_acquire(periph, DA_REF_SYSCTL) == 0) { taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task); } else { /* XXX This message is useless! */ xpt_print(periph->path, "fatal error, " "could not acquire reference count\n"); } } /* We already probed the device. */ if (softc->flags & DA_FLAG_PROBED) { daprobedone(periph, done_ccb); return; } /* Ensure re-probe doesn't see old delete. */ softc->delete_available = 0; dadeleteflag(softc, DA_DELETE_ZERO, 1); if (lbp && (softc->quirks & DA_Q_NO_UNMAP) == 0) { /* * Based on older SBC-3 spec revisions * any of the UNMAP methods "may" be * available via LBP given this flag so * we flag all of them as available and * then remove those which further * probes confirm aren't available * later. * * We could also check readcap(16) p_type * flag to exclude one or more invalid * write same (X) types here */ dadeleteflag(softc, DA_DELETE_WS16, 1); dadeleteflag(softc, DA_DELETE_WS10, 1); dadeleteflag(softc, DA_DELETE_UNMAP, 1); xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_LBP; xpt_schedule(periph, priority); return; } xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_BDC; xpt_schedule(periph, priority); return; } static void dadone_probelbp(struct cam_periph *periph, union ccb *done_ccb) { struct scsi_vpd_logical_block_prov *lbp; struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probelbp\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; lbp = (struct scsi_vpd_logical_block_prov *)csio->data_ptr; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { /* * T10/1799-D Revision 31 states at least one of these * must be supported but we don't currently enforce this. */ dadeleteflag(softc, DA_DELETE_WS16, (lbp->flags & SVPD_LBP_WS16)); dadeleteflag(softc, DA_DELETE_WS10, (lbp->flags & SVPD_LBP_WS10)); dadeleteflag(softc, DA_DELETE_UNMAP, (lbp->flags & SVPD_LBP_UNMAP)); } else { int error; error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } /* * Failure indicates we don't support any SBC-3 * delete methods with UNMAP */ } } free(lbp, M_SCSIDA); xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_BLK_LIMITS; xpt_schedule(periph, priority); return; } static void dadone_probeblklimits(struct cam_periph *periph, union ccb *done_ccb) { struct scsi_vpd_block_limits *block_limits; struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeblklimits\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; block_limits = (struct scsi_vpd_block_limits *)csio->data_ptr; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { uint32_t max_txfer_len = scsi_4btoul( block_limits->max_txfer_len); uint32_t max_unmap_lba_cnt = scsi_4btoul( block_limits->max_unmap_lba_cnt); uint32_t max_unmap_blk_cnt = scsi_4btoul( block_limits->max_unmap_blk_cnt); uint32_t unmap_gran = scsi_4btoul( block_limits->opt_unmap_grain); uint32_t unmap_gran_align = scsi_4btoul( block_limits->unmap_grain_align); uint64_t ws_max_blks = scsi_8btou64( block_limits->max_write_same_length); if (max_txfer_len != 0) { softc->disk->d_maxsize = MIN(softc->maxio, (off_t)max_txfer_len * softc->params.secsize); } /* * We should already support UNMAP but we check lba * and block count to be sure */ if (max_unmap_lba_cnt != 0x00L && max_unmap_blk_cnt != 0x00L) { softc->unmap_max_lba = max_unmap_lba_cnt; softc->unmap_max_ranges = min(max_unmap_blk_cnt, UNMAP_MAX_RANGES); if (unmap_gran > 1) { softc->unmap_gran = unmap_gran; if (unmap_gran_align & 0x80000000) { softc->unmap_gran_align = unmap_gran_align & 0x7fffffff; } } } else { /* * Unexpected UNMAP limits which means the * device doesn't actually support UNMAP */ dadeleteflag(softc, DA_DELETE_UNMAP, 0); } if (ws_max_blks != 0x00L) softc->ws_max_blks = ws_max_blks; } else { int error; error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } /* * Failure here doesn't mean UNMAP is not * supported as this is an optional page. */ softc->unmap_max_lba = 1; softc->unmap_max_ranges = 1; } } free(block_limits, M_SCSIDA); xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_BDC; xpt_schedule(periph, priority); return; } static void dadone_probebdc(struct cam_periph *periph, union ccb *done_ccb) { struct scsi_vpd_block_device_characteristics *bdc; struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probebdc\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; bdc = (struct scsi_vpd_block_device_characteristics *)csio->data_ptr; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { uint32_t valid_len; /* * Disable queue sorting for non-rotational media * by default. */ u_int16_t old_rate = softc->disk->d_rotation_rate; valid_len = csio->dxfer_len - csio->resid; if (SBDC_IS_PRESENT(bdc, valid_len, medium_rotation_rate)) { softc->disk->d_rotation_rate = scsi_2btoul(bdc->medium_rotation_rate); if (softc->disk->d_rotation_rate == SVPD_BDC_RATE_NON_ROTATING) { cam_iosched_set_sort_queue( softc->cam_iosched, 0); softc->rotating = 0; } if (softc->disk->d_rotation_rate != old_rate) { disk_attr_changed(softc->disk, "GEOM::rotation_rate", M_NOWAIT); } } if ((SBDC_IS_PRESENT(bdc, valid_len, flags)) && (softc->zone_mode == DA_ZONE_NONE)) { int ata_proto; if (scsi_vpd_supported_page(periph, SVPD_ATA_INFORMATION)) ata_proto = 1; else ata_proto = 0; /* * The Zoned field will only be set for * Drive Managed and Host Aware drives. If * they are Host Managed, the device type * in the standard INQUIRY data should be * set to T_ZBC_HM (0x14). */ if ((bdc->flags & SVPD_ZBC_MASK) == SVPD_HAW_ZBC) { softc->zone_mode = DA_ZONE_HOST_AWARE; softc->zone_interface = (ata_proto) ? DA_ZONE_IF_ATA_SAT : DA_ZONE_IF_SCSI; } else if ((bdc->flags & SVPD_ZBC_MASK) == SVPD_DM_ZBC) { softc->zone_mode =DA_ZONE_DRIVE_MANAGED; softc->zone_interface = (ata_proto) ? DA_ZONE_IF_ATA_SAT : DA_ZONE_IF_SCSI; } else if ((bdc->flags & SVPD_ZBC_MASK) != SVPD_ZBC_NR) { xpt_print(periph->path, "Unknown zoned " "type %#x", bdc->flags & SVPD_ZBC_MASK); } } } else { int error; error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(bdc, M_SCSIDA); xpt_release_ccb(done_ccb); softc->state = DA_STATE_PROBE_ATA; xpt_schedule(periph, priority); return; } static void dadone_probeata(struct cam_periph *periph, union ccb *done_ccb) { struct ata_params *ata_params; struct ccb_scsiio *csio; struct da_softc *softc; u_int32_t priority; int continue_probe; - int error; + int error, i; int16_t *ptr; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeata\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; ata_params = (struct ata_params *)csio->data_ptr; ptr = (uint16_t *)ata_params; continue_probe = 0; error = 0; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { uint16_t old_rate; - ata_param_fixup(ata_params); + for (i = 0; i < sizeof(*ata_params) / 2; i++) + ptr[i] = le16toh(ptr[i]); if (ata_params->support_dsm & ATA_SUPPORT_DSM_TRIM && (softc->quirks & DA_Q_NO_UNMAP) == 0) { dadeleteflag(softc, DA_DELETE_ATA_TRIM, 1); if (ata_params->max_dsm_blocks != 0) softc->trim_max_ranges = min( softc->trim_max_ranges, ata_params->max_dsm_blocks * ATA_DSM_BLK_RANGES); } /* * Disable queue sorting for non-rotational media * by default. */ old_rate = softc->disk->d_rotation_rate; softc->disk->d_rotation_rate = ata_params->media_rotation_rate; if (softc->disk->d_rotation_rate == ATA_RATE_NON_ROTATING) { cam_iosched_set_sort_queue(softc->cam_iosched, 0); softc->rotating = 0; } if (softc->disk->d_rotation_rate != old_rate) { disk_attr_changed(softc->disk, "GEOM::rotation_rate", M_NOWAIT); } cam_periph_assert(periph, MA_OWNED); if (ata_params->capabilities1 & ATA_SUPPORT_DMA) softc->flags |= DA_FLAG_CAN_ATA_DMA; if (ata_params->support.extension & ATA_SUPPORT_GENLOG) softc->flags |= DA_FLAG_CAN_ATA_LOG; /* * At this point, if we have a SATA host aware drive, * we communicate via ATA passthrough unless the * SAT layer supports ZBC -> ZAC translation. In * that case, * * XXX KDM figure out how to detect a host managed * SATA drive. */ if (softc->zone_mode == DA_ZONE_NONE) { /* * Note that we don't override the zone * mode or interface if it has already been * set. This is because it has either been * set as a quirk, or when we probed the * SCSI Block Device Characteristics page, * the zoned field was set. The latter * means that the SAT layer supports ZBC to * ZAC translation, and we would prefer to * use that if it is available. */ if ((ata_params->support3 & ATA_SUPPORT_ZONE_MASK) == ATA_SUPPORT_ZONE_HOST_AWARE) { softc->zone_mode = DA_ZONE_HOST_AWARE; softc->zone_interface = DA_ZONE_IF_ATA_PASS; } else if ((ata_params->support3 & ATA_SUPPORT_ZONE_MASK) == ATA_SUPPORT_ZONE_DEV_MANAGED) { softc->zone_mode =DA_ZONE_DRIVE_MANAGED; softc->zone_interface = DA_ZONE_IF_ATA_PASS; } } } else { error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } + free(ata_params, M_SCSIDA); if ((softc->zone_mode == DA_ZONE_HOST_AWARE) || (softc->zone_mode == DA_ZONE_HOST_MANAGED)) { /* * If the ATA IDENTIFY failed, we could be talking * to a SCSI drive, although that seems unlikely, * since the drive did report that it supported the * ATA Information VPD page. If the ATA IDENTIFY * succeeded, and the SAT layer doesn't support * ZBC -> ZAC translation, continue on to get the * directory of ATA logs, and complete the rest of * the ZAC probe. If the SAT layer does support * ZBC -> ZAC translation, we want to use that, * and we'll probe the SCSI Zoned Block Device * Characteristics VPD page next. */ if ((error == 0) && (softc->flags & DA_FLAG_CAN_ATA_LOG) && (softc->zone_interface == DA_ZONE_IF_ATA_PASS)) softc->state = DA_STATE_PROBE_ATA_LOGDIR; else softc->state = DA_STATE_PROBE_ZONE; continue_probe = 1; } if (continue_probe != 0) { xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } else daprobedone(periph, done_ccb); return; } static void dadone_probeatalogdir(struct cam_periph *periph, union ccb *done_ccb) { struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; int error; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeatalogdir\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { error = 0; softc->valid_logdir_len = 0; bzero(&softc->ata_logdir, sizeof(softc->ata_logdir)); softc->valid_logdir_len = csio->dxfer_len - csio->resid; if (softc->valid_logdir_len > 0) bcopy(csio->data_ptr, &softc->ata_logdir, min(softc->valid_logdir_len, sizeof(softc->ata_logdir))); /* * Figure out whether the Identify Device log is * supported. The General Purpose log directory * has a header, and lists the number of pages * available for each GP log identified by the * offset into the list. */ if ((softc->valid_logdir_len >= ((ATA_IDENTIFY_DATA_LOG + 1) * sizeof(uint16_t))) && (le16dec(softc->ata_logdir.header) == ATA_GP_LOG_DIR_VERSION) && (le16dec(&softc->ata_logdir.num_pages[ (ATA_IDENTIFY_DATA_LOG * sizeof(uint16_t)) - sizeof(uint16_t)]) > 0)){ softc->flags |= DA_FLAG_CAN_ATA_IDLOG; } else { softc->flags &= ~DA_FLAG_CAN_ATA_IDLOG; } } else { error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { /* * If we can't get the ATA log directory, * then ATA logs are effectively not * supported even if the bit is set in the * identify data. */ softc->flags &= ~(DA_FLAG_CAN_ATA_LOG | DA_FLAG_CAN_ATA_IDLOG); if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(csio->data_ptr, M_SCSIDA); if ((error == 0) && (softc->flags & DA_FLAG_CAN_ATA_IDLOG)) { softc->state = DA_STATE_PROBE_ATA_IDDIR; xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } daprobedone(periph, done_ccb); return; } static void dadone_probeataiddir(struct cam_periph *periph, union ccb *done_ccb) { struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; int error; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeataiddir\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { off_t entries_offset, max_entries; error = 0; softc->valid_iddir_len = 0; bzero(&softc->ata_iddir, sizeof(softc->ata_iddir)); softc->flags &= ~(DA_FLAG_CAN_ATA_SUPCAP | DA_FLAG_CAN_ATA_ZONE); softc->valid_iddir_len = csio->dxfer_len - csio->resid; if (softc->valid_iddir_len > 0) bcopy(csio->data_ptr, &softc->ata_iddir, min(softc->valid_iddir_len, sizeof(softc->ata_iddir))); entries_offset = __offsetof(struct ata_identify_log_pages,entries); max_entries = softc->valid_iddir_len - entries_offset; if ((softc->valid_iddir_len > (entries_offset + 1)) && (le64dec(softc->ata_iddir.header) == ATA_IDLOG_REVISION) && (softc->ata_iddir.entry_count > 0)) { int num_entries, i; num_entries = softc->ata_iddir.entry_count; num_entries = min(num_entries, softc->valid_iddir_len - entries_offset); for (i = 0; i < num_entries && i < max_entries; i++) { if (softc->ata_iddir.entries[i] == ATA_IDL_SUP_CAP) softc->flags |= DA_FLAG_CAN_ATA_SUPCAP; else if (softc->ata_iddir.entries[i] == ATA_IDL_ZDI) softc->flags |= DA_FLAG_CAN_ATA_ZONE; if ((softc->flags & DA_FLAG_CAN_ATA_SUPCAP) && (softc->flags & DA_FLAG_CAN_ATA_ZONE)) break; } } } else { error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { /* * If we can't get the ATA Identify Data log * directory, then it effectively isn't * supported even if the ATA Log directory * a non-zero number of pages present for * this log. */ softc->flags &= ~DA_FLAG_CAN_ATA_IDLOG; if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(csio->data_ptr, M_SCSIDA); if ((error == 0) && (softc->flags & DA_FLAG_CAN_ATA_SUPCAP)) { softc->state = DA_STATE_PROBE_ATA_SUP; xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } daprobedone(periph, done_ccb); return; } static void dadone_probeatasup(struct cam_periph *periph, union ccb *done_ccb) { struct da_softc *softc; struct ccb_scsiio *csio; u_int32_t priority; int error; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeatasup\n")); softc = (struct da_softc *)periph->softc; priority = done_ccb->ccb_h.pinfo.priority; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { uint32_t valid_len; size_t needed_size; struct ata_identify_log_sup_cap *sup_cap; error = 0; sup_cap = (struct ata_identify_log_sup_cap *)csio->data_ptr; valid_len = csio->dxfer_len - csio->resid; needed_size = __offsetof(struct ata_identify_log_sup_cap, sup_zac_cap) + 1 + sizeof(sup_cap->sup_zac_cap); if (valid_len >= needed_size) { uint64_t zoned, zac_cap; zoned = le64dec(sup_cap->zoned_cap); if (zoned & ATA_ZONED_VALID) { /* * This should have already been * set, because this is also in the * ATA identify data. */ if ((zoned & ATA_ZONED_MASK) == ATA_SUPPORT_ZONE_HOST_AWARE) softc->zone_mode = DA_ZONE_HOST_AWARE; else if ((zoned & ATA_ZONED_MASK) == ATA_SUPPORT_ZONE_DEV_MANAGED) softc->zone_mode = DA_ZONE_DRIVE_MANAGED; } zac_cap = le64dec(sup_cap->sup_zac_cap); if (zac_cap & ATA_SUP_ZAC_CAP_VALID) { if (zac_cap & ATA_REPORT_ZONES_SUP) softc->zone_flags |= DA_ZONE_FLAG_RZ_SUP; if (zac_cap & ATA_ND_OPEN_ZONE_SUP) softc->zone_flags |= DA_ZONE_FLAG_OPEN_SUP; if (zac_cap & ATA_ND_CLOSE_ZONE_SUP) softc->zone_flags |= DA_ZONE_FLAG_CLOSE_SUP; if (zac_cap & ATA_ND_FINISH_ZONE_SUP) softc->zone_flags |= DA_ZONE_FLAG_FINISH_SUP; if (zac_cap & ATA_ND_RWP_SUP) softc->zone_flags |= DA_ZONE_FLAG_RWP_SUP; } else { /* * This field was introduced in * ACS-4, r08 on April 28th, 2015. * If the drive firmware was written * to an earlier spec, it won't have * the field. So, assume all * commands are supported. */ softc->zone_flags |= DA_ZONE_FLAG_SUP_MASK; } } } else { error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { /* * If we can't get the ATA Identify Data * Supported Capabilities page, clear the * flag... */ softc->flags &= ~DA_FLAG_CAN_ATA_SUPCAP; /* * And clear zone capabilities. */ softc->zone_flags &= ~DA_ZONE_FLAG_SUP_MASK; if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(csio->data_ptr, M_SCSIDA); if ((error == 0) && (softc->flags & DA_FLAG_CAN_ATA_ZONE)) { softc->state = DA_STATE_PROBE_ATA_ZONE; xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); return; } daprobedone(periph, done_ccb); return; } static void dadone_probeatazone(struct cam_periph *periph, union ccb *done_ccb) { struct da_softc *softc; struct ccb_scsiio *csio; int error; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probeatazone\n")); softc = (struct da_softc *)periph->softc; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { struct ata_zoned_info_log *zi_log; uint32_t valid_len; size_t needed_size; zi_log = (struct ata_zoned_info_log *)csio->data_ptr; valid_len = csio->dxfer_len - csio->resid; needed_size = __offsetof(struct ata_zoned_info_log, version_info) + 1 + sizeof(zi_log->version_info); if (valid_len >= needed_size) { uint64_t tmpvar; tmpvar = le64dec(zi_log->zoned_cap); if (tmpvar & ATA_ZDI_CAP_VALID) { if (tmpvar & ATA_ZDI_CAP_URSWRZ) softc->zone_flags |= DA_ZONE_FLAG_URSWRZ; else softc->zone_flags &= ~DA_ZONE_FLAG_URSWRZ; } tmpvar = le64dec(zi_log->optimal_seq_zones); if (tmpvar & ATA_ZDI_OPT_SEQ_VALID) { softc->zone_flags |= DA_ZONE_FLAG_OPT_SEQ_SET; softc->optimal_seq_zones = (tmpvar & ATA_ZDI_OPT_SEQ_MASK); } else { softc->zone_flags &= ~DA_ZONE_FLAG_OPT_SEQ_SET; softc->optimal_seq_zones = 0; } tmpvar =le64dec(zi_log->optimal_nonseq_zones); if (tmpvar & ATA_ZDI_OPT_NS_VALID) { softc->zone_flags |= DA_ZONE_FLAG_OPT_NONSEQ_SET; softc->optimal_nonseq_zones = (tmpvar & ATA_ZDI_OPT_NS_MASK); } else { softc->zone_flags &= ~DA_ZONE_FLAG_OPT_NONSEQ_SET; softc->optimal_nonseq_zones = 0; } tmpvar = le64dec(zi_log->max_seq_req_zones); if (tmpvar & ATA_ZDI_MAX_SEQ_VALID) { softc->zone_flags |= DA_ZONE_FLAG_MAX_SEQ_SET; softc->max_seq_zones = (tmpvar & ATA_ZDI_MAX_SEQ_MASK); } else { softc->zone_flags &= ~DA_ZONE_FLAG_MAX_SEQ_SET; softc->max_seq_zones = 0; } } } else { error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { softc->flags &= ~DA_FLAG_CAN_ATA_ZONE; softc->flags &= ~DA_ZONE_FLAG_SET_MASK; if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(csio->data_ptr, M_SCSIDA); daprobedone(periph, done_ccb); return; } static void dadone_probezone(struct cam_periph *periph, union ccb *done_ccb) { struct da_softc *softc; struct ccb_scsiio *csio; int error; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_probezone\n")); softc = (struct da_softc *)periph->softc; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { uint32_t valid_len; size_t needed_len; struct scsi_vpd_zoned_bdc *zoned_bdc; error = 0; zoned_bdc = (struct scsi_vpd_zoned_bdc *)csio->data_ptr; valid_len = csio->dxfer_len - csio->resid; needed_len = __offsetof(struct scsi_vpd_zoned_bdc, max_seq_req_zones) + 1 + sizeof(zoned_bdc->max_seq_req_zones); if ((valid_len >= needed_len) && (scsi_2btoul(zoned_bdc->page_length) >= SVPD_ZBDC_PL)) { if (zoned_bdc->flags & SVPD_ZBDC_URSWRZ) softc->zone_flags |= DA_ZONE_FLAG_URSWRZ; else softc->zone_flags &= ~DA_ZONE_FLAG_URSWRZ; softc->optimal_seq_zones = scsi_4btoul(zoned_bdc->optimal_seq_zones); softc->zone_flags |= DA_ZONE_FLAG_OPT_SEQ_SET; softc->optimal_nonseq_zones = scsi_4btoul( zoned_bdc->optimal_nonseq_zones); softc->zone_flags |= DA_ZONE_FLAG_OPT_NONSEQ_SET; softc->max_seq_zones = scsi_4btoul(zoned_bdc->max_seq_req_zones); softc->zone_flags |= DA_ZONE_FLAG_MAX_SEQ_SET; } /* * All of the zone commands are mandatory for SCSI * devices. * * XXX KDM this is valid as of September 2015. * Re-check this assumption once the SAT spec is * updated to support SCSI ZBC to ATA ZAC mapping. * Since ATA allows zone commands to be reported * as supported or not, this may not necessarily * be true for an ATA device behind a SAT (SCSI to * ATA Translation) layer. */ softc->zone_flags |= DA_ZONE_FLAG_SUP_MASK; } else { error = daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA|SF_NO_PRINT); if (error == ERESTART) return; else if (error != 0) { if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge this device's queue */ cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } } } free(csio->data_ptr, M_SCSIDA); daprobedone(periph, done_ccb); return; } static void dadone_tur(struct cam_periph *periph, union ccb *done_ccb) { struct da_softc *softc; struct ccb_scsiio *csio; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone_tur\n")); softc = (struct da_softc *)periph->softc; csio = &done_ccb->csio; cam_periph_assert(periph, MA_OWNED); if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (daerror(done_ccb, CAM_RETRY_SELTO, SF_RETRY_UA | SF_NO_RECOVERY | SF_NO_PRINT) == ERESTART) return; /* Will complete again, keep reference */ if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(done_ccb->ccb_h.path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, /*getcount_only*/0); } xpt_release_ccb(done_ccb); softc->flags &= ~DA_FLAG_TUR_PENDING; da_periph_release_locked(periph, DA_REF_TUR); return; } static void dareprobe(struct cam_periph *periph) { struct da_softc *softc; int status; softc = (struct da_softc *)periph->softc; /* Probe in progress; don't interfere. */ if (softc->state != DA_STATE_NORMAL) return; status = da_periph_acquire(periph, DA_REF_REPROBE); KASSERT(status == 0, ("dareprobe: cam_periph_acquire failed")); softc->state = DA_STATE_PROBE_WP; xpt_schedule(periph, CAM_PRIORITY_DEV); } static int daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) { struct da_softc *softc; struct cam_periph *periph; int error, error_code, sense_key, asc, ascq; #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING) if (ccb->csio.bio != NULL) biotrack(ccb->csio.bio, __func__); #endif periph = xpt_path_periph(ccb->ccb_h.path); softc = (struct da_softc *)periph->softc; cam_periph_assert(periph, MA_OWNED); /* * Automatically detect devices that do not support * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs. */ error = 0; if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) { error = cmd6workaround(ccb); } else if (scsi_extract_sense_ccb(ccb, &error_code, &sense_key, &asc, &ascq)) { if (sense_key == SSD_KEY_ILLEGAL_REQUEST) error = cmd6workaround(ccb); /* * If the target replied with CAPACITY DATA HAS CHANGED UA, * query the capacity and notify upper layers. */ else if (sense_key == SSD_KEY_UNIT_ATTENTION && asc == 0x2A && ascq == 0x09) { xpt_print(periph->path, "Capacity data has changed\n"); softc->flags &= ~DA_FLAG_PROBED; dareprobe(periph); sense_flags |= SF_NO_PRINT; } else if (sense_key == SSD_KEY_UNIT_ATTENTION && asc == 0x28 && ascq == 0x00) { softc->flags &= ~DA_FLAG_PROBED; disk_media_changed(softc->disk, M_NOWAIT); } else if (sense_key == SSD_KEY_UNIT_ATTENTION && asc == 0x3F && ascq == 0x03) { xpt_print(periph->path, "INQUIRY data has changed\n"); softc->flags &= ~DA_FLAG_PROBED; dareprobe(periph); sense_flags |= SF_NO_PRINT; } else if (sense_key == SSD_KEY_NOT_READY && asc == 0x3a && (softc->flags & DA_FLAG_PACK_INVALID) == 0) { softc->flags |= DA_FLAG_PACK_INVALID; disk_media_gone(softc->disk, M_NOWAIT); } } if (error == ERESTART) return (ERESTART); #ifdef CAM_IO_STATS switch (ccb->ccb_h.status & CAM_STATUS_MASK) { case CAM_CMD_TIMEOUT: softc->timeouts++; break; case CAM_REQ_ABORTED: case CAM_REQ_CMP_ERR: case CAM_REQ_TERMIO: case CAM_UNREC_HBA_ERROR: case CAM_DATA_RUN_ERR: softc->errors++; break; default: break; } #endif /* * XXX * Until we have a better way of doing pack validation, * don't treat UAs as errors. */ sense_flags |= SF_RETRY_UA; if (softc->quirks & DA_Q_RETRY_BUSY) sense_flags |= SF_RETRY_BUSY; return(cam_periph_error(ccb, cam_flags, sense_flags)); } static void damediapoll(void *arg) { struct cam_periph *periph = arg; struct da_softc *softc = periph->softc; if (!cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR) && (softc->flags & DA_FLAG_TUR_PENDING) == 0 && LIST_EMPTY(&softc->pending_ccbs)) { if (da_periph_acquire(periph, DA_REF_TUR) == 0) { cam_iosched_set_work_flags(softc->cam_iosched, DA_WORK_TUR); daschedule(periph); } } /* Queue us up again */ if (da_poll_period != 0) callout_schedule(&softc->mediapoll_c, da_poll_period * hz); } static void daprevent(struct cam_periph *periph, int action) { struct da_softc *softc; union ccb *ccb; int error; cam_periph_assert(periph, MA_OWNED); softc = (struct da_softc *)periph->softc; if (((action == PR_ALLOW) && (softc->flags & DA_FLAG_PACK_LOCKED) == 0) || ((action == PR_PREVENT) && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) { return; } ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); scsi_prevent(&ccb->csio, /*retries*/1, /*cbcfp*/NULL, MSG_SIMPLE_Q_TAG, action, SSD_FULL_SIZE, 5000); error = cam_periph_runccb(ccb, daerror, CAM_RETRY_SELTO, SF_RETRY_UA | SF_NO_PRINT, softc->disk->d_devstat); if (error == 0) { if (action == PR_ALLOW) softc->flags &= ~DA_FLAG_PACK_LOCKED; else softc->flags |= DA_FLAG_PACK_LOCKED; } xpt_release_ccb(ccb); } static void dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector, struct scsi_read_capacity_data_long *rcaplong, size_t rcap_len) { struct ccb_calc_geometry ccg; struct da_softc *softc; struct disk_params *dp; u_int lbppbe, lalba; int error; softc = (struct da_softc *)periph->softc; dp = &softc->params; dp->secsize = block_len; dp->sectors = maxsector + 1; if (rcaplong != NULL) { lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE; lalba = scsi_2btoul(rcaplong->lalba_lbp); lalba &= SRC16_LALBA_A; if (rcaplong->prot & SRC16_PROT_EN) softc->p_type = ((rcaplong->prot & SRC16_P_TYPE) >> SRC16_P_TYPE_SHIFT) + 1; else softc->p_type = 0; } else { lbppbe = 0; lalba = 0; softc->p_type = 0; } if (lbppbe > 0) { dp->stripesize = block_len << lbppbe; dp->stripeoffset = (dp->stripesize - block_len * lalba) % dp->stripesize; } else if (softc->quirks & DA_Q_4K) { dp->stripesize = 4096; dp->stripeoffset = 0; } else if (softc->unmap_gran != 0) { dp->stripesize = block_len * softc->unmap_gran; dp->stripeoffset = (dp->stripesize - block_len * softc->unmap_gran_align) % dp->stripesize; } else { dp->stripesize = 0; dp->stripeoffset = 0; } /* * Have the controller provide us with a geometry * for this disk. The only time the geometry * matters is when we boot and the controller * is the only one knowledgeable enough to come * up with something that will make this a bootable * device. */ xpt_setup_ccb(&ccg.ccb_h, periph->path, CAM_PRIORITY_NORMAL); ccg.ccb_h.func_code = XPT_CALC_GEOMETRY; ccg.block_size = dp->secsize; ccg.volume_size = dp->sectors; ccg.heads = 0; ccg.secs_per_track = 0; ccg.cylinders = 0; xpt_action((union ccb*)&ccg); if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { /* * We don't know what went wrong here- but just pick * a geometry so we don't have nasty things like divide * by zero. */ dp->heads = 255; dp->secs_per_track = 255; dp->cylinders = dp->sectors / (255 * 255); if (dp->cylinders == 0) { dp->cylinders = 1; } } else { dp->heads = ccg.heads; dp->secs_per_track = ccg.secs_per_track; dp->cylinders = ccg.cylinders; } /* * If the user supplied a read capacity buffer, and if it is * different than the previous buffer, update the data in the EDT. * If it's the same, we don't bother. This avoids sending an * update every time someone opens this device. */ if ((rcaplong != NULL) && (bcmp(rcaplong, &softc->rcaplong, min(sizeof(softc->rcaplong), rcap_len)) != 0)) { struct ccb_dev_advinfo cdai; xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL); cdai.ccb_h.func_code = XPT_DEV_ADVINFO; cdai.buftype = CDAI_TYPE_RCAPLONG; cdai.flags = CDAI_FLAG_STORE; cdai.bufsiz = rcap_len; cdai.buf = (uint8_t *)rcaplong; xpt_action((union ccb *)&cdai); if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0) cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE); if (cdai.ccb_h.status != CAM_REQ_CMP) { xpt_print(periph->path, "%s: failed to set read " "capacity advinfo\n", __func__); /* Use cam_error_print() to decode the status */ cam_error_print((union ccb *)&cdai, CAM_ESF_CAM_STATUS, CAM_EPF_ALL); } else { bcopy(rcaplong, &softc->rcaplong, min(sizeof(softc->rcaplong), rcap_len)); } } softc->disk->d_sectorsize = softc->params.secsize; softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors; softc->disk->d_stripesize = softc->params.stripesize; softc->disk->d_stripeoffset = softc->params.stripeoffset; /* XXX: these are not actually "firmware" values, so they may be wrong */ softc->disk->d_fwsectors = softc->params.secs_per_track; softc->disk->d_fwheads = softc->params.heads; softc->disk->d_devstat->block_size = softc->params.secsize; softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE; error = disk_resize(softc->disk, M_NOWAIT); if (error != 0) xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error); } static void dasendorderedtag(void *arg) { struct cam_periph *periph = arg; struct da_softc *softc = periph->softc; cam_periph_assert(periph, MA_OWNED); if (da_send_ordered) { if (!LIST_EMPTY(&softc->pending_ccbs)) { if ((softc->flags & DA_FLAG_WAS_OTAG) == 0) softc->flags |= DA_FLAG_NEED_OTAG; softc->flags &= ~DA_FLAG_WAS_OTAG; } } /* Queue us up again */ callout_reset(&softc->sendordered_c, (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL, dasendorderedtag, periph); } /* * Step through all DA peripheral drivers, and if the device is still open, * sync the disk cache to physical media. */ static void dashutdown(void * arg, int howto) { struct cam_periph *periph; struct da_softc *softc; union ccb *ccb; int error; CAM_PERIPH_FOREACH(periph, &dadriver) { softc = (struct da_softc *)periph->softc; if (SCHEDULER_STOPPED()) { /* If we paniced with the lock held, do not recurse. */ if (!cam_periph_owned(periph) && (softc->flags & DA_FLAG_OPEN)) { dadump(softc->disk, NULL, 0, 0, 0); } continue; } cam_periph_lock(periph); /* * We only sync the cache if the drive is still open, and * if the drive is capable of it.. */ if (((softc->flags & DA_FLAG_OPEN) == 0) || (softc->quirks & DA_Q_NO_SYNC_CACHE)) { cam_periph_unlock(periph); continue; } ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); scsi_synchronize_cache(&ccb->csio, /*retries*/0, /*cbfcnp*/NULL, MSG_SIMPLE_Q_TAG, /*begin_lba*/0, /* whole disk */ /*lb_count*/0, SSD_FULL_SIZE, 60 * 60 * 1000); error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0, /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, softc->disk->d_devstat); if (error != 0) xpt_print(periph->path, "Synchronize cache failed\n"); xpt_release_ccb(ccb); cam_periph_unlock(periph); } } #else /* !_KERNEL */ /* * XXX These are only left out of the kernel build to silence warnings. If, * for some reason these functions are used in the kernel, the ifdefs should * be moved so they are included both in the kernel and userland. */ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout) { struct scsi_format_unit *scsi_cmd; scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes; scsi_cmd->opcode = FORMAT_UNIT; scsi_cmd->byte2 = byte2; scsi_ulto2b(ileave, scsi_cmd->interleave); cam_fill_csio(csio, retries, cbfcnp, /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, tag_action, data_ptr, dxfer_len, sense_len, sizeof(*scsi_cmd), timeout); } void scsi_read_defects(struct ccb_scsiio *csio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t list_format, uint32_t addr_desc_index, uint8_t *data_ptr, uint32_t dxfer_len, int minimum_cmd_size, uint8_t sense_len, uint32_t timeout) { uint8_t cdb_len; /* * These conditions allow using the 10 byte command. Otherwise we * need to use the 12 byte command. */ if ((minimum_cmd_size <= 10) && (addr_desc_index == 0) && (dxfer_len <= SRDD10_MAX_LENGTH)) { struct scsi_read_defect_data_10 *cdb10; cdb10 = (struct scsi_read_defect_data_10 *) &csio->cdb_io.cdb_bytes; cdb_len = sizeof(*cdb10); bzero(cdb10, cdb_len); cdb10->opcode = READ_DEFECT_DATA_10; cdb10->format = list_format; scsi_ulto2b(dxfer_len, cdb10->alloc_length); } else { struct scsi_read_defect_data_12 *cdb12; cdb12 = (struct scsi_read_defect_data_12 *) &csio->cdb_io.cdb_bytes; cdb_len = sizeof(*cdb12); bzero(cdb12, cdb_len); cdb12->opcode = READ_DEFECT_DATA_12; cdb12->format = list_format; scsi_ulto4b(dxfer_len, cdb12->alloc_length); scsi_ulto4b(addr_desc_index, cdb12->address_descriptor_index); } cam_fill_csio(csio, retries, cbfcnp, /*flags*/ CAM_DIR_IN, tag_action, data_ptr, dxfer_len, sense_len, cdb_len, timeout); } void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int8_t byte2, u_int16_t control, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout) { struct scsi_sanitize *scsi_cmd; scsi_cmd = (struct scsi_sanitize *)&csio->cdb_io.cdb_bytes; scsi_cmd->opcode = SANITIZE; scsi_cmd->byte2 = byte2; scsi_cmd->control = control; scsi_ulto2b(dxfer_len, scsi_cmd->length); cam_fill_csio(csio, retries, cbfcnp, /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, tag_action, data_ptr, dxfer_len, sense_len, sizeof(*scsi_cmd), timeout); } #endif /* _KERNEL */ void scsi_zbc_out(struct ccb_scsiio *csio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t service_action, uint64_t zone_id, uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len, uint8_t sense_len, uint32_t timeout) { struct scsi_zbc_out *scsi_cmd; scsi_cmd = (struct scsi_zbc_out *)&csio->cdb_io.cdb_bytes; scsi_cmd->opcode = ZBC_OUT; scsi_cmd->service_action = service_action; scsi_u64to8b(zone_id, scsi_cmd->zone_id); scsi_cmd->zone_flags = zone_flags; cam_fill_csio(csio, retries, cbfcnp, /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, tag_action, data_ptr, dxfer_len, sense_len, sizeof(*scsi_cmd), timeout); } void scsi_zbc_in(struct ccb_scsiio *csio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, uint8_t service_action, uint64_t zone_start_lba, uint8_t zone_options, uint8_t *data_ptr, uint32_t dxfer_len, uint8_t sense_len, uint32_t timeout) { struct scsi_zbc_in *scsi_cmd; scsi_cmd = (struct scsi_zbc_in *)&csio->cdb_io.cdb_bytes; scsi_cmd->opcode = ZBC_IN; scsi_cmd->service_action = service_action; scsi_ulto4b(dxfer_len, scsi_cmd->length); scsi_u64to8b(zone_start_lba, scsi_cmd->zone_start_lba); scsi_cmd->zone_options = zone_options; cam_fill_csio(csio, retries, cbfcnp, /*flags*/ (dxfer_len > 0) ? CAM_DIR_IN : CAM_DIR_NONE, tag_action, data_ptr, dxfer_len, sense_len, sizeof(*scsi_cmd), timeout); } int scsi_ata_zac_mgmt_out(struct ccb_scsiio *csio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int use_ncq, uint8_t zm_action, uint64_t zone_id, uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage, size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout) { uint8_t command_out, protocol, ata_flags; uint16_t features_out; uint32_t sectors_out, auxiliary; int retval; retval = 0; if (use_ncq == 0) { command_out = ATA_ZAC_MANAGEMENT_OUT; features_out = (zm_action & 0xf) | (zone_flags << 8); ata_flags = AP_FLAG_BYT_BLOK_BLOCKS; if (dxfer_len == 0) { protocol = AP_PROTO_NON_DATA; ata_flags |= AP_FLAG_TLEN_NO_DATA; sectors_out = 0; } else { protocol = AP_PROTO_DMA; ata_flags |= AP_FLAG_TLEN_SECT_CNT | AP_FLAG_TDIR_TO_DEV; sectors_out = ((dxfer_len >> 9) & 0xffff); } auxiliary = 0; } else { ata_flags = AP_FLAG_BYT_BLOK_BLOCKS; if (dxfer_len == 0) { command_out = ATA_NCQ_NON_DATA; features_out = ATA_NCQ_ZAC_MGMT_OUT; /* * We're assuming the SCSI to ATA translation layer * will set the NCQ tag number in the tag field. * That isn't clear from the SAT-4 spec (as of rev 05). */ sectors_out = 0; ata_flags |= AP_FLAG_TLEN_NO_DATA; } else { command_out = ATA_SEND_FPDMA_QUEUED; /* * Note that we're defaulting to normal priority, * and assuming that the SCSI to ATA translation * layer will insert the NCQ tag number in the tag * field. That isn't clear in the SAT-4 spec (as * of rev 05). */ sectors_out = ATA_SFPDMA_ZAC_MGMT_OUT << 8; ata_flags |= AP_FLAG_TLEN_FEAT | AP_FLAG_TDIR_TO_DEV; /* * For SEND FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means * that 65536 512 byte blocks are to be tranferred. * In practice, it seems unlikely that we'll see * a transfer that large, and it may confuse the * the SAT layer, because generally that means that * 0 bytes should be transferred. */ if (dxfer_len == (65536 * 512)) { features_out = 0; } else if (dxfer_len <= (65535 * 512)) { features_out = ((dxfer_len >> 9) & 0xffff); } else { /* The transfer is too big. */ retval = 1; goto bailout; } } auxiliary = (zm_action & 0xf) | (zone_flags << 8); protocol = AP_PROTO_FPDMA; } protocol |= AP_EXTEND; retval = scsi_ata_pass(csio, retries, cbfcnp, /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, tag_action, /*protocol*/ protocol, /*ata_flags*/ ata_flags, /*features*/ features_out, /*sector_count*/ sectors_out, /*lba*/ zone_id, /*command*/ command_out, /*device*/ 0, /*icc*/ 0, /*auxiliary*/ auxiliary, /*control*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ dxfer_len, /*cdb_storage*/ cdb_storage, /*cdb_storage_len*/ cdb_storage_len, /*minimum_cmd_size*/ 0, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ timeout); bailout: return (retval); } int scsi_ata_zac_mgmt_in(struct ccb_scsiio *csio, uint32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), uint8_t tag_action, int use_ncq, uint8_t zm_action, uint64_t zone_id, uint8_t zone_flags, uint8_t *data_ptr, uint32_t dxfer_len, uint8_t *cdb_storage, size_t cdb_storage_len, uint8_t sense_len, uint32_t timeout) { uint8_t command_out, protocol; uint16_t features_out, sectors_out; uint32_t auxiliary; int ata_flags; int retval; retval = 0; ata_flags = AP_FLAG_TDIR_FROM_DEV | AP_FLAG_BYT_BLOK_BLOCKS; if (use_ncq == 0) { command_out = ATA_ZAC_MANAGEMENT_IN; /* XXX KDM put a macro here */ features_out = (zm_action & 0xf) | (zone_flags << 8); sectors_out = dxfer_len >> 9; /* XXX KDM macro */ protocol = AP_PROTO_DMA; ata_flags |= AP_FLAG_TLEN_SECT_CNT; auxiliary = 0; } else { ata_flags |= AP_FLAG_TLEN_FEAT; command_out = ATA_RECV_FPDMA_QUEUED; sectors_out = ATA_RFPDMA_ZAC_MGMT_IN << 8; /* * For RECEIVE FPDMA QUEUED, the transfer length is * encoded in the FEATURE register, and 0 means * that 65536 512 byte blocks are to be tranferred. * In practice, it seems unlikely that we'll see * a transfer that large, and it may confuse the * the SAT layer, because generally that means that * 0 bytes should be transferred. */ if (dxfer_len == (65536 * 512)) { features_out = 0; } else if (dxfer_len <= (65535 * 512)) { features_out = ((dxfer_len >> 9) & 0xffff); } else { /* The transfer is too big. */ retval = 1; goto bailout; } auxiliary = (zm_action & 0xf) | (zone_flags << 8), protocol = AP_PROTO_FPDMA; } protocol |= AP_EXTEND; retval = scsi_ata_pass(csio, retries, cbfcnp, /*flags*/ CAM_DIR_IN, tag_action, /*protocol*/ protocol, /*ata_flags*/ ata_flags, /*features*/ features_out, /*sector_count*/ sectors_out, /*lba*/ zone_id, /*command*/ command_out, /*device*/ 0, /*icc*/ 0, /*auxiliary*/ auxiliary, /*control*/ 0, /*data_ptr*/ data_ptr, /*dxfer_len*/ (dxfer_len >> 9) * 512, /* XXX KDM */ /*cdb_storage*/ cdb_storage, /*cdb_storage_len*/ cdb_storage_len, /*minimum_cmd_size*/ 0, /*sense_len*/ SSD_FULL_SIZE, /*timeout*/ timeout); bailout: return (retval); } Index: head/sys/conf/files =================================================================== --- head/sys/conf/files (revision 349351) +++ head/sys/conf/files (revision 349352) @@ -1,4955 +1,4926 @@ # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # acpi_quirks.h optional acpi \ dependency "$S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ no-obj no-implicit-rule before-depend \ clean "acpi_quirks.h" bhnd_nvram_map.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map.h" bhnd_nvram_map_data.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map_data.h" fdt_static_dtb.h optional fdt fdt_dtb_static \ compile-with "sh -c 'MACHINE=${MACHINE} $S/tools/fdt/make_dtbh.sh ${FDT_DTS_FILE} ${.CURDIR}'" \ dependency "${FDT_DTS_FILE:T:R}.dtb" \ no-obj no-implicit-rule before-depend \ clean "fdt_static_dtb.h" feeder_eq_gen.h optional sound \ dependency "$S/tools/sound/feeder_eq_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > feeder_eq_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_eq_gen.h" feeder_rate_gen.h optional sound \ dependency "$S/tools/sound/feeder_rate_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_rate_gen.h" snd_fxdiv_gen.h optional sound \ dependency "$S/tools/sound/snd_fxdiv_gen.awk" \ compile-with "${AWK} -f $S/tools/sound/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \ no-obj no-implicit-rule before-depend \ clean "snd_fxdiv_gen.h" miidevs.h optional miibus | mii \ dependency "$S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ compile-with "${AWK} -f $S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ no-obj no-implicit-rule before-depend \ clean "miidevs.h" pccarddevs.h standard \ dependency "$S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \ compile-with "${AWK} -f $S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \ no-obj no-implicit-rule before-depend \ clean "pccarddevs.h" kbdmuxmap.h optional kbdmux_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -L ${KBDMUX_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > kbdmuxmap.h" \ no-obj no-implicit-rule before-depend \ clean "kbdmuxmap.h" teken_state.h optional sc | vt \ dependency "$S/teken/gensequences $S/teken/sequences" \ compile-with "${AWK} -f $S/teken/gensequences $S/teken/sequences > teken_state.h" \ no-obj no-implicit-rule before-depend \ clean "teken_state.h" usbdevs.h optional usb \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h" \ no-obj no-implicit-rule before-depend \ clean "usbdevs.h" usbdevs_data.h optional usb \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -d" \ no-obj no-implicit-rule before-depend \ clean "usbdevs_data.h" sdiodevs.h optional mmccam \ dependency "$S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs" \ compile-with "${AWK} -f $S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs -h" \ no-obj no-implicit-rule before-depend \ clean "sdiodevs.h" sdiodevs_data.h optional mmccam \ dependency "$S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs" \ compile-with "${AWK} -f $S/tools/sdiodevs2h.awk $S/dev/sdio/sdiodevs -d" \ no-obj no-implicit-rule before-depend \ clean "sdiodevs_data.h" cam/cam.c optional scbus cam/cam_compat.c optional scbus cam/cam_iosched.c optional scbus cam/cam_periph.c optional scbus cam/cam_queue.c optional scbus cam/cam_sim.c optional scbus cam/cam_xpt.c optional scbus cam/ata/ata_all.c optional scbus cam/ata/ata_xpt.c optional scbus cam/ata/ata_pmp.c optional scbus cam/nvme/nvme_all.c optional scbus cam/nvme/nvme_da.c optional nda | da cam/nvme/nvme_xpt.c optional scbus cam/scsi/scsi_xpt.c optional scbus cam/scsi/scsi_all.c optional scbus cam/scsi/scsi_cd.c optional cd cam/scsi/scsi_ch.c optional ch cam/ata/ata_da.c optional ada | da cam/ctl/ctl.c optional ctl cam/ctl/ctl_backend.c optional ctl cam/ctl/ctl_backend_block.c optional ctl cam/ctl/ctl_backend_ramdisk.c optional ctl cam/ctl/ctl_cmd_table.c optional ctl cam/ctl/ctl_frontend.c optional ctl cam/ctl/ctl_frontend_cam_sim.c optional ctl cam/ctl/ctl_frontend_ioctl.c optional ctl cam/ctl/ctl_frontend_iscsi.c optional ctl cfiscsi cam/ctl/ctl_ha.c optional ctl cam/ctl/ctl_scsi_all.c optional ctl cam/ctl/ctl_tpc.c optional ctl cam/ctl/ctl_tpc_local.c optional ctl cam/ctl/ctl_error.c optional ctl cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl cam/mmc/mmc_xpt.c optional scbus mmccam cam/mmc/mmc_da.c optional scbus mmccam da cam/scsi/scsi_da.c optional da cam/scsi/scsi_pass.c optional pass cam/scsi/scsi_pt.c optional pt cam/scsi/scsi_sa.c optional sa cam/scsi/scsi_enc.c optional ses cam/scsi/scsi_enc_ses.c optional ses cam/scsi/scsi_enc_safte.c optional ses cam/scsi/scsi_sg.c optional sg cam/scsi/scsi_targ_bh.c optional targbh cam/scsi/scsi_target.c optional targ cam/scsi/smp_all.c optional scbus # shared between zfs and dtrace cddl/compat/opensolaris/kern/opensolaris.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_cmn_err.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_kmem.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_misc.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_proc.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_sunddi.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_taskq.c optional zfs | dtrace compile-with "${CDDL_C}" # zfs specific cddl/compat/opensolaris/kern/opensolaris_acl.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_dtrace.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_kobj.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_kstat.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_lookup.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_policy.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_string.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_sysevent.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_uio.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_vfs.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_vm.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_zone.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/acl/acl_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/avl/avl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/nvpair/opensolaris_fnvpair.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair_alloc_fixed.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/unicode/u8_textprep.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfeature_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_comutil.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_deleg.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_fletcher.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_prop.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zpool_prop.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zprop_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/vnode.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/abd.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/aggsum.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bplist.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bqueue.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/cityhash.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf_stats.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/ddt_zap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c optional zfs compile-with "${ZFS_C}" \ warning "kernel contains CDDL licensed ZFS filesystem" cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_bookmark.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_synctask.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/gzip.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lzjb.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/multilist.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/range_tree.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/sha256.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/skein_zfs.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_checkpoint.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_errlog.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/space_reftree.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/unique.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect_births.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect_mapping.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_initialize.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_removal.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap_leaf.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zcp.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_get.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_global.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_iter.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zcp_synctask.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_byteswap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_debug.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_rlock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_sa.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zle.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zthr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/callb.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/fm.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/list.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/nvpair_alloc_system.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/adler32.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/deflate.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/inffast.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/inflate.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/inftrees.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/trees.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zmod.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zmod_subr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zutil.c optional zfs compile-with "${ZFS_C}" # zfs lua support cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lapi.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lauxlib.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbaselib.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lbitlib.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcode.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcompat.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lcorolib.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lctype.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldebug.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldo.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ldump.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lfunc.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lgc.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/llex.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lmem.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lobject.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lopcodes.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lparser.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstate.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstring.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lstrlib.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltable.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltablib.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/ltm.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lundump.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lvm.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lua/lzio.c optional zfs compile-with "${ZFS_C}" # dtrace specific cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \ warning "kernel contains CDDL licensed DTRACE" cddl/contrib/opensolaris/uts/common/dtrace/dtrace_xoroshiro128_plus.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/dtmalloc/dtmalloc.c optional dtmalloc | dtraceall compile-with "${CDDL_C}" cddl/dev/profile/profile.c optional dtrace_profile | dtraceall compile-with "${CDDL_C}" cddl/dev/sdt/sdt.c optional dtrace_sdt | dtraceall compile-with "${CDDL_C}" cddl/dev/fbt/fbt.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/systrace/systrace.c optional dtrace_systrace | dtraceall compile-with "${CDDL_C}" cddl/dev/prototype.c optional dtrace_prototype | dtraceall compile-with "${CDDL_C}" fs/nfsclient/nfs_clkdtrace.c optional dtnfscl nfscl | dtraceall nfscl compile-with "${CDDL_C}" compat/cloudabi/cloudabi_clock.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_errno.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_fd.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_file.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_futex.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_mem.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_proc.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_random.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_sock.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_thread.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_vdso.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi32/cloudabi32_fd.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_module.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_poll.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_sock.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_syscalls.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_sysent.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_thread.c optional compat_cloudabi32 compat/cloudabi64/cloudabi64_fd.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_module.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_poll.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_sock.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_syscalls.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_sysent.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_thread.c optional compat_cloudabi64 compat/freebsd32/freebsd32_capability.c optional compat_freebsd32 compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32 compat/freebsd32/freebsd32_misc.c optional compat_freebsd32 compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32 compat/freebsd32/freebsd32_sysent.c optional compat_freebsd32 contrib/ck/src/ck_array.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_centralized.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_combining.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_dissemination.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_mcs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_tournament.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_epoch.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hp.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_ht.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_rhs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/dev/acpica/common/ahids.c optional acpi acpi_debug contrib/dev/acpica/common/ahuuids.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbcmds.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbconvert.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbdisply.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbexec.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbhistry.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbinput.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbmethod.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbnames.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbobject.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbstats.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbtest.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbutils.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbxface.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmbuffer.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmcstyle.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmdeferred.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmnames.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmopcode.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrc.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl2.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcs.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmutils.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmwalk.c optional acpi acpi_debug contrib/dev/acpica/components/dispatcher/dsargs.c optional acpi contrib/dev/acpica/components/dispatcher/dscontrol.c optional acpi contrib/dev/acpica/components/dispatcher/dsdebug.c optional acpi contrib/dev/acpica/components/dispatcher/dsfield.c optional acpi contrib/dev/acpica/components/dispatcher/dsinit.c optional acpi contrib/dev/acpica/components/dispatcher/dsmethod.c optional acpi contrib/dev/acpica/components/dispatcher/dsmthdat.c optional acpi contrib/dev/acpica/components/dispatcher/dsobject.c optional acpi contrib/dev/acpica/components/dispatcher/dsopcode.c optional acpi contrib/dev/acpica/components/dispatcher/dspkginit.c optional acpi contrib/dev/acpica/components/dispatcher/dsutils.c optional acpi contrib/dev/acpica/components/dispatcher/dswexec.c optional acpi contrib/dev/acpica/components/dispatcher/dswload.c optional acpi contrib/dev/acpica/components/dispatcher/dswload2.c optional acpi contrib/dev/acpica/components/dispatcher/dswscope.c optional acpi contrib/dev/acpica/components/dispatcher/dswstate.c optional acpi contrib/dev/acpica/components/events/evevent.c optional acpi contrib/dev/acpica/components/events/evglock.c optional acpi contrib/dev/acpica/components/events/evgpe.c optional acpi contrib/dev/acpica/components/events/evgpeblk.c optional acpi contrib/dev/acpica/components/events/evgpeinit.c optional acpi contrib/dev/acpica/components/events/evgpeutil.c optional acpi contrib/dev/acpica/components/events/evhandler.c optional acpi contrib/dev/acpica/components/events/evmisc.c optional acpi contrib/dev/acpica/components/events/evregion.c optional acpi contrib/dev/acpica/components/events/evrgnini.c optional acpi contrib/dev/acpica/components/events/evsci.c optional acpi contrib/dev/acpica/components/events/evxface.c optional acpi contrib/dev/acpica/components/events/evxfevnt.c optional acpi contrib/dev/acpica/components/events/evxfgpe.c optional acpi contrib/dev/acpica/components/events/evxfregn.c optional acpi contrib/dev/acpica/components/executer/exconcat.c optional acpi contrib/dev/acpica/components/executer/exconfig.c optional acpi contrib/dev/acpica/components/executer/exconvrt.c optional acpi contrib/dev/acpica/components/executer/excreate.c optional acpi contrib/dev/acpica/components/executer/exdebug.c optional acpi contrib/dev/acpica/components/executer/exdump.c optional acpi contrib/dev/acpica/components/executer/exfield.c optional acpi contrib/dev/acpica/components/executer/exfldio.c optional acpi contrib/dev/acpica/components/executer/exmisc.c optional acpi contrib/dev/acpica/components/executer/exmutex.c optional acpi contrib/dev/acpica/components/executer/exnames.c optional acpi contrib/dev/acpica/components/executer/exoparg1.c optional acpi contrib/dev/acpica/components/executer/exoparg2.c optional acpi contrib/dev/acpica/components/executer/exoparg3.c optional acpi contrib/dev/acpica/components/executer/exoparg6.c optional acpi contrib/dev/acpica/components/executer/exprep.c optional acpi contrib/dev/acpica/components/executer/exregion.c optional acpi contrib/dev/acpica/components/executer/exresnte.c optional acpi contrib/dev/acpica/components/executer/exresolv.c optional acpi contrib/dev/acpica/components/executer/exresop.c optional acpi contrib/dev/acpica/components/executer/exserial.c optional acpi contrib/dev/acpica/components/executer/exstore.c optional acpi contrib/dev/acpica/components/executer/exstoren.c optional acpi contrib/dev/acpica/components/executer/exstorob.c optional acpi contrib/dev/acpica/components/executer/exsystem.c optional acpi contrib/dev/acpica/components/executer/extrace.c optional acpi contrib/dev/acpica/components/executer/exutils.c optional acpi contrib/dev/acpica/components/hardware/hwacpi.c optional acpi contrib/dev/acpica/components/hardware/hwesleep.c optional acpi contrib/dev/acpica/components/hardware/hwgpe.c optional acpi contrib/dev/acpica/components/hardware/hwpci.c optional acpi contrib/dev/acpica/components/hardware/hwregs.c optional acpi contrib/dev/acpica/components/hardware/hwsleep.c optional acpi contrib/dev/acpica/components/hardware/hwtimer.c optional acpi contrib/dev/acpica/components/hardware/hwvalid.c optional acpi contrib/dev/acpica/components/hardware/hwxface.c optional acpi contrib/dev/acpica/components/hardware/hwxfsleep.c optional acpi contrib/dev/acpica/components/namespace/nsaccess.c optional acpi contrib/dev/acpica/components/namespace/nsalloc.c optional acpi contrib/dev/acpica/components/namespace/nsarguments.c optional acpi contrib/dev/acpica/components/namespace/nsconvert.c optional acpi contrib/dev/acpica/components/namespace/nsdump.c optional acpi contrib/dev/acpica/components/namespace/nseval.c optional acpi contrib/dev/acpica/components/namespace/nsinit.c optional acpi contrib/dev/acpica/components/namespace/nsload.c optional acpi contrib/dev/acpica/components/namespace/nsnames.c optional acpi contrib/dev/acpica/components/namespace/nsobject.c optional acpi contrib/dev/acpica/components/namespace/nsparse.c optional acpi contrib/dev/acpica/components/namespace/nspredef.c optional acpi contrib/dev/acpica/components/namespace/nsprepkg.c optional acpi contrib/dev/acpica/components/namespace/nsrepair.c optional acpi contrib/dev/acpica/components/namespace/nsrepair2.c optional acpi contrib/dev/acpica/components/namespace/nssearch.c optional acpi contrib/dev/acpica/components/namespace/nsutils.c optional acpi contrib/dev/acpica/components/namespace/nswalk.c optional acpi contrib/dev/acpica/components/namespace/nsxfeval.c optional acpi contrib/dev/acpica/components/namespace/nsxfname.c optional acpi contrib/dev/acpica/components/namespace/nsxfobj.c optional acpi contrib/dev/acpica/components/parser/psargs.c optional acpi contrib/dev/acpica/components/parser/psloop.c optional acpi contrib/dev/acpica/components/parser/psobject.c optional acpi contrib/dev/acpica/components/parser/psopcode.c optional acpi contrib/dev/acpica/components/parser/psopinfo.c optional acpi contrib/dev/acpica/components/parser/psparse.c optional acpi contrib/dev/acpica/components/parser/psscope.c optional acpi contrib/dev/acpica/components/parser/pstree.c optional acpi contrib/dev/acpica/components/parser/psutils.c optional acpi contrib/dev/acpica/components/parser/pswalk.c optional acpi contrib/dev/acpica/components/parser/psxface.c optional acpi contrib/dev/acpica/components/resources/rsaddr.c optional acpi contrib/dev/acpica/components/resources/rscalc.c optional acpi contrib/dev/acpica/components/resources/rscreate.c optional acpi contrib/dev/acpica/components/resources/rsdump.c optional acpi acpi_debug contrib/dev/acpica/components/resources/rsdumpinfo.c optional acpi contrib/dev/acpica/components/resources/rsinfo.c optional acpi contrib/dev/acpica/components/resources/rsio.c optional acpi contrib/dev/acpica/components/resources/rsirq.c optional acpi contrib/dev/acpica/components/resources/rslist.c optional acpi contrib/dev/acpica/components/resources/rsmemory.c optional acpi contrib/dev/acpica/components/resources/rsmisc.c optional acpi contrib/dev/acpica/components/resources/rsserial.c optional acpi contrib/dev/acpica/components/resources/rsutils.c optional acpi contrib/dev/acpica/components/resources/rsxface.c optional acpi contrib/dev/acpica/components/tables/tbdata.c optional acpi contrib/dev/acpica/components/tables/tbfadt.c optional acpi contrib/dev/acpica/components/tables/tbfind.c optional acpi contrib/dev/acpica/components/tables/tbinstal.c optional acpi contrib/dev/acpica/components/tables/tbprint.c optional acpi contrib/dev/acpica/components/tables/tbutils.c optional acpi contrib/dev/acpica/components/tables/tbxface.c optional acpi contrib/dev/acpica/components/tables/tbxfload.c optional acpi contrib/dev/acpica/components/tables/tbxfroot.c optional acpi contrib/dev/acpica/components/utilities/utaddress.c optional acpi contrib/dev/acpica/components/utilities/utalloc.c optional acpi contrib/dev/acpica/components/utilities/utascii.c optional acpi contrib/dev/acpica/components/utilities/utbuffer.c optional acpi contrib/dev/acpica/components/utilities/utcache.c optional acpi contrib/dev/acpica/components/utilities/utcopy.c optional acpi contrib/dev/acpica/components/utilities/utdebug.c optional acpi contrib/dev/acpica/components/utilities/utdecode.c optional acpi contrib/dev/acpica/components/utilities/utdelete.c optional acpi contrib/dev/acpica/components/utilities/uterror.c optional acpi contrib/dev/acpica/components/utilities/uteval.c optional acpi contrib/dev/acpica/components/utilities/utexcep.c optional acpi contrib/dev/acpica/components/utilities/utglobal.c optional acpi contrib/dev/acpica/components/utilities/uthex.c optional acpi contrib/dev/acpica/components/utilities/utids.c optional acpi contrib/dev/acpica/components/utilities/utinit.c optional acpi contrib/dev/acpica/components/utilities/utlock.c optional acpi contrib/dev/acpica/components/utilities/utmath.c optional acpi contrib/dev/acpica/components/utilities/utmisc.c optional acpi contrib/dev/acpica/components/utilities/utmutex.c optional acpi contrib/dev/acpica/components/utilities/utnonansi.c optional acpi contrib/dev/acpica/components/utilities/utobject.c optional acpi contrib/dev/acpica/components/utilities/utosi.c optional acpi contrib/dev/acpica/components/utilities/utownerid.c optional acpi contrib/dev/acpica/components/utilities/utpredef.c optional acpi contrib/dev/acpica/components/utilities/utresdecode.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utresrc.c optional acpi contrib/dev/acpica/components/utilities/utstate.c optional acpi contrib/dev/acpica/components/utilities/utstring.c optional acpi contrib/dev/acpica/components/utilities/utstrsuppt.c optional acpi contrib/dev/acpica/components/utilities/utstrtoul64.c optional acpi contrib/dev/acpica/components/utilities/utuuid.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utxface.c optional acpi contrib/dev/acpica/components/utilities/utxferror.c optional acpi contrib/dev/acpica/components/utilities/utxfinit.c optional acpi contrib/dev/acpica/os_specific/service_layers/osgendbg.c optional acpi acpi_debug contrib/ipfilter/netinet/fil.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_auth.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_fil_freebsd.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_frag.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_log.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_nat.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_proxy.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_state.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_lookup.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -Wno-error -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_pool.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_htable.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter ${NO_WTAUTOLOGICAL_POINTER_COMPARE}" contrib/ipfilter/netinet/ip_sync.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_nat6.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_rules.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_scan.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_dstlist.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/radix_ipf.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/libfdt/fdt.c optional fdt contrib/libfdt/fdt_ro.c optional fdt contrib/libfdt/fdt_rw.c optional fdt contrib/libfdt/fdt_strerror.c optional fdt contrib/libfdt/fdt_sw.c optional fdt contrib/libfdt/fdt_wip.c optional fdt contrib/libnv/cnvlist.c standard contrib/libnv/dnvlist.c standard contrib/libnv/nvlist.c standard contrib/libnv/nvpair.c standard contrib/ngatm/netnatm/api/cc_conn.c optional ngatm_ccatm \ compile-with "${NORMAL_C_NOWERROR} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_data.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_dump.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_port.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_sig.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_user.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/unisap.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/misc/straddr.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/misc/unimsg_common.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/traffic.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/uni_ie.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/uni_msg.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/saal/saal_sscfu.c optional ngatm_sscfu \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/saal/saal_sscop.c optional ngatm_sscop \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_call.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_coord.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_party.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_print.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_reset.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_uni.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_unimsgcpy.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_verify.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" # xz dev/xz/xz_mod.c optional xz \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_crc32.c optional xz \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_bcj.c optional xz \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c optional xz \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_stream.c optional xz \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" # Zstd contrib/zstd/lib/freebsd/zstd_kmalloc.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/zstd_common.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/fse_decompress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/entropy_common.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/error_private.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/common/xxhash.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/fse_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/hist.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/huf_compress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_double_fast.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_fast.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_lazy.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_ldm.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/compress/zstd_opt.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_ddict.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_decompress.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/zstd_decompress_block.c optional zstdio compile-with ${ZSTD_C} contrib/zstd/lib/decompress/huf_decompress.c optional zstdio compile-with ${ZSTD_C} # Blake 2 contrib/libb2/blake2b-ref.c optional crypto | ipsec | ipsec_support \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual -DSUFFIX=_ref -Wno-unused-function" contrib/libb2/blake2s-ref.c optional crypto | ipsec | ipsec_support \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual -DSUFFIX=_ref -Wno-unused-function" crypto/blake2/blake2-sw.c optional crypto | ipsec | ipsec_support \ compile-with "${NORMAL_C} -I$S/crypto/blake2 -Wno-cast-qual" crypto/blowfish/bf_ecb.c optional ipsec | ipsec_support crypto/blowfish/bf_skey.c optional crypto | ipsec | ipsec_support crypto/camellia/camellia.c optional crypto | ipsec | ipsec_support crypto/camellia/camellia-api.c optional crypto | ipsec | ipsec_support crypto/chacha20/chacha.c optional crypto | ipsec | ipsec_support crypto/chacha20/chacha-sw.c optional crypto | ipsec | ipsec_support crypto/des/des_ecb.c optional crypto | ipsec | ipsec_support | netsmb crypto/des/des_setkey.c optional crypto | ipsec | ipsec_support | netsmb crypto/rc4/rc4.c optional netgraph_mppc_encryption | kgssapi crypto/rijndael/rijndael-alg-fst.c optional crypto | ekcd | geom_bde | \ ipsec | ipsec_support | !random_loadable | wlan_ccmp crypto/rijndael/rijndael-api-fst.c optional ekcd | geom_bde | !random_loadable crypto/rijndael/rijndael-api.c optional crypto | ipsec | ipsec_support | \ wlan_ccmp crypto/sha1.c optional carp | crypto | ether | ipsec | \ ipsec_support | netgraph_mppc_encryption | sctp crypto/sha2/sha256c.c optional crypto | ekcd | geom_bde | ipsec | \ ipsec_support | !random_loadable | sctp | zfs crypto/sha2/sha512c.c optional crypto | geom_bde | ipsec | \ ipsec_support | zfs crypto/skein/skein.c optional crypto | zfs crypto/skein/skein_block.c optional crypto | zfs crypto/siphash/siphash.c optional inet | inet6 crypto/siphash/siphash_test.c optional inet | inet6 ddb/db_access.c optional ddb ddb/db_break.c optional ddb ddb/db_capture.c optional ddb ddb/db_command.c optional ddb ddb/db_examine.c optional ddb ddb/db_expr.c optional ddb ddb/db_input.c optional ddb ddb/db_lex.c optional ddb ddb/db_main.c optional ddb ddb/db_output.c optional ddb ddb/db_print.c optional ddb ddb/db_ps.c optional ddb ddb/db_run.c optional ddb ddb/db_script.c optional ddb ddb/db_sym.c optional ddb ddb/db_thread.c optional ddb ddb/db_textdump.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb dev/aac/aac.c optional aac dev/aac/aac_cam.c optional aacp aac dev/aac/aac_debug.c optional aac dev/aac/aac_disk.c optional aac dev/aac/aac_linux.c optional aac compat_linux dev/aac/aac_pci.c optional aac pci dev/aacraid/aacraid.c optional aacraid dev/aacraid/aacraid_cam.c optional aacraid scbus dev/aacraid/aacraid_debug.c optional aacraid dev/aacraid/aacraid_linux.c optional aacraid compat_linux dev/aacraid/aacraid_pci.c optional aacraid pci dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi dev/acpi_support/acpi_asus.c optional acpi_asus acpi dev/acpi_support/acpi_asus_wmi.c optional acpi_asus_wmi acpi dev/acpi_support/acpi_fujitsu.c optional acpi_fujitsu acpi dev/acpi_support/acpi_hp.c optional acpi_hp acpi dev/acpi_support/acpi_ibm.c optional acpi_ibm acpi dev/acpi_support/acpi_panasonic.c optional acpi_panasonic acpi dev/acpi_support/acpi_sony.c optional acpi_sony acpi dev/acpi_support/acpi_toshiba.c optional acpi_toshiba acpi dev/acpi_support/atk0110.c optional aibs acpi dev/acpica/Osd/OsdDebug.c optional acpi dev/acpica/Osd/OsdHardware.c optional acpi dev/acpica/Osd/OsdInterrupt.c optional acpi dev/acpica/Osd/OsdMemory.c optional acpi dev/acpica/Osd/OsdSchedule.c optional acpi dev/acpica/Osd/OsdStream.c optional acpi dev/acpica/Osd/OsdSynch.c optional acpi dev/acpica/Osd/OsdTable.c optional acpi dev/acpica/acpi.c optional acpi dev/acpica/acpi_acad.c optional acpi dev/acpica/acpi_battery.c optional acpi dev/acpica/acpi_button.c optional acpi dev/acpica/acpi_cmbat.c optional acpi dev/acpica/acpi_cpu.c optional acpi dev/acpica/acpi_ec.c optional acpi dev/acpica/acpi_isab.c optional acpi isa dev/acpica/acpi_lid.c optional acpi dev/acpica/acpi_package.c optional acpi dev/acpica/acpi_perf.c optional acpi dev/acpica/acpi_powerres.c optional acpi dev/acpica/acpi_quirk.c optional acpi dev/acpica/acpi_resource.c optional acpi dev/acpica/acpi_container.c optional acpi dev/acpica/acpi_smbat.c optional acpi dev/acpica/acpi_thermal.c optional acpi dev/acpica/acpi_throttle.c optional acpi dev/acpica/acpi_video.c optional acpi_video acpi dev/acpica/acpi_dock.c optional acpi_dock acpi dev/adlink/adlink.c optional adlink dev/ae/if_ae.c optional ae pci dev/age/if_age.c optional age pci dev/agp/agp.c optional agp pci dev/agp/agp_if.m optional agp pci dev/ahci/ahci.c optional ahci dev/ahci/ahciem.c optional ahci dev/ahci/ahci_pci.c optional ahci pci dev/aic7xxx/ahc_isa.c optional ahc isa dev/aic7xxx/ahc_pci.c optional ahc pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/ahd_pci.c optional ahd pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/aic7770.c optional ahc dev/aic7xxx/aic79xx.c optional ahd pci dev/aic7xxx/aic79xx_osm.c optional ahd pci dev/aic7xxx/aic79xx_pci.c optional ahd pci dev/aic7xxx/aic79xx_reg_print.c optional ahd pci ahd_reg_pretty_print dev/aic7xxx/aic7xxx.c optional ahc dev/aic7xxx/aic7xxx_93cx6.c optional ahc dev/aic7xxx/aic7xxx_osm.c optional ahc dev/aic7xxx/aic7xxx_pci.c optional ahc pci dev/aic7xxx/aic7xxx_reg_print.c optional ahc ahc_reg_pretty_print dev/al_eth/al_eth.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" dev/al_eth/al_init_eth_lm.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" dev/al_eth/al_init_eth_kr.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_iofic.c optional al_iofic \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_25g.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_hssp.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_config.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_debug.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_iofic.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_main.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_serdes.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_kr.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_main.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" dev/alc/if_alc.c optional alc pci dev/ale/if_ale.c optional ale pci dev/alpm/alpm.c optional alpm pci dev/altera/avgen/altera_avgen.c optional altera_avgen dev/altera/avgen/altera_avgen_fdt.c optional altera_avgen fdt dev/altera/avgen/altera_avgen_nexus.c optional altera_avgen dev/altera/msgdma/msgdma.c optional altera_msgdma xdma dev/altera/sdcard/altera_sdcard.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_disk.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_io.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_fdt.c optional altera_sdcard fdt dev/altera/sdcard/altera_sdcard_nexus.c optional altera_sdcard dev/altera/softdma/softdma.c optional altera_softdma xdma fdt dev/altera/pio/pio.c optional altera_pio dev/altera/pio/pio_if.m optional altera_pio dev/amdpm/amdpm.c optional amdpm pci | nfpm pci dev/amdsmb/amdsmb.c optional amdsmb pci dev/amr/amr.c optional amr dev/amr/amr_cam.c optional amrp amr dev/amr/amr_disk.c optional amr dev/amr/amr_linux.c optional amr compat_linux dev/amr/amr_pci.c optional amr pci dev/an/if_an.c optional an dev/an/if_an_isa.c optional an isa dev/an/if_an_pccard.c optional an pccard dev/an/if_an_pci.c optional an pci # dev/ata/ata_if.m optional ata | atacore dev/ata/ata-all.c optional ata | atacore dev/ata/ata-dma.c optional ata | atacore dev/ata/ata-lowlevel.c optional ata | atacore dev/ata/ata-sata.c optional ata | atacore dev/ata/ata-card.c optional ata pccard | atapccard dev/ata/ata-isa.c optional ata isa | ataisa dev/ata/ata-pci.c optional ata pci | atapci dev/ata/chipsets/ata-acard.c optional ata pci | ataacard dev/ata/chipsets/ata-acerlabs.c optional ata pci | ataacerlabs dev/ata/chipsets/ata-amd.c optional ata pci | ataamd dev/ata/chipsets/ata-ati.c optional ata pci | ataati dev/ata/chipsets/ata-cenatek.c optional ata pci | atacenatek dev/ata/chipsets/ata-cypress.c optional ata pci | atacypress dev/ata/chipsets/ata-cyrix.c optional ata pci | atacyrix dev/ata/chipsets/ata-highpoint.c optional ata pci | atahighpoint dev/ata/chipsets/ata-intel.c optional ata pci | ataintel dev/ata/chipsets/ata-ite.c optional ata pci | ataite dev/ata/chipsets/ata-jmicron.c optional ata pci | atajmicron dev/ata/chipsets/ata-marvell.c optional ata pci | atamarvell dev/ata/chipsets/ata-micron.c optional ata pci | atamicron dev/ata/chipsets/ata-national.c optional ata pci | atanational dev/ata/chipsets/ata-netcell.c optional ata pci | atanetcell dev/ata/chipsets/ata-nvidia.c optional ata pci | atanvidia dev/ata/chipsets/ata-promise.c optional ata pci | atapromise dev/ata/chipsets/ata-serverworks.c optional ata pci | ataserverworks dev/ata/chipsets/ata-siliconimage.c optional ata pci | atasiliconimage | ataati dev/ata/chipsets/ata-sis.c optional ata pci | atasis dev/ata/chipsets/ata-via.c optional ata pci | atavia # dev/ath/if_ath_pci.c optional ath_pci pci \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/ath/if_ath_ahb.c optional ath_ahb \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/ath/if_ath.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_alq.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_beacon.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_btcoex.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_btcoex_mci.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_debug.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_descdma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_keycache.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_ioctl.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_led.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_lna_div.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tx.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tx_edma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tx_ht.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tdma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_sysctl.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_rx.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_rx_edma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_spectral.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ah_osdep.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/ath/ath_hal/ah.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v1.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v3.c optional ath_hal | ath_ar5211 | ath_ar5212 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v14.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v4k.c \ optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_9287.c \ optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_regdomain.c optional ath \ compile-with "${NORMAL_C} ${NO_WSHIFT_COUNT_NEGATIVE} ${NO_WSHIFT_COUNT_OVERFLOW} -I$S/dev/ath" # ar5210 dev/ath/ath_hal/ar5210/ar5210_attach.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_beacon.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_interrupts.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_keycache.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_misc.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_phy.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_power.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_recv.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_reset.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_xmit.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar5211 dev/ath/ath_hal/ar5211/ar5211_attach.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_beacon.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_interrupts.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_keycache.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_misc.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_phy.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_power.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_recv.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_reset.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_xmit.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar5212 dev/ath/ath_hal/ar5212/ar5212_ani.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_attach.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_beacon.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_eeprom.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_gpio.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_interrupts.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_keycache.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_misc.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_phy.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_power.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_recv.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_reset.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_rfgain.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_xmit.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar5416 (depends on ar5212) dev/ath/ath_hal/ar5416/ar5416_ani.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_attach.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_beacon.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_btcoex.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_iq.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_eeprom.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_gpio.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_interrupts.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_keycache.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_misc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_phy.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_power.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_radar.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_recv.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_reset.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_spectral.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_xmit.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9130 (depends upon ar5416) - also requires AH_SUPPORT_AR9130 # # Since this is an embedded MAC SoC, there's no need to compile it into the # default HAL. dev/ath/ath_hal/ar9001/ar9130_attach.c optional ath_ar9130 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9001/ar9130_phy.c optional ath_ar9130 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9001/ar9130_eeprom.c optional ath_ar9130 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9160 (depends on ar5416) dev/ath/ath_hal/ar9001/ar9160_attach.c optional ath_hal | ath_ar9160 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9280 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9280_attach.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280_olc.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9285 (depends on ar5416 and ar9280) dev/ath/ath_hal/ar9002/ar9285_attach.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_btcoex.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_reset.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_cal.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_phy.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_diversity.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9287 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9287_attach.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_reset.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_cal.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_olc.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9300 contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_beacon.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WCONSTANT_CONVERSION}" contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_interrupts.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_keycache.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_paprd.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_power.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radar.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radio.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv_ds.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WSOMETIMES_UNINITIALIZED} -Wno-unused-function" contrib/dev/ath/ath_hal/ar9300/ar9300_stub.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_spectral.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_timer.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit_ds.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" # rf backends dev/ath/ath_hal/ar5212/ar2316.c optional ath_rf2316 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2317.c optional ath_rf2317 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2413.c optional ath_hal | ath_rf2413 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2425.c optional ath_hal | ath_rf2425 | ath_rf2417 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5111.c optional ath_hal | ath_rf5111 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5112.c optional ath_hal | ath_rf5112 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5413.c optional ath_hal | ath_rf5413 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar2133.c optional ath_hal | ath_ar5416 | \ ath_ar9130 | ath_ar9160 | ath_ar9280 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280.c optional ath_hal | ath_ar9280 | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ath rate control algorithms dev/ath/ath_rate/amrr/amrr.c optional ath_rate_amrr \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_rate/onoe/onoe.c optional ath_rate_onoe \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_rate/sample/sample.c optional ath_rate_sample \ compile-with "${NORMAL_C} -I$S/dev/ath" # ath DFS modules dev/ath/ath_dfs/null/dfs_null.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/bce/if_bce.c optional bce dev/bfe/if_bfe.c optional bfe dev/bge/if_bge.c optional bge dev/bhnd/bhnd.c optional bhnd dev/bhnd/bhnd_erom.c optional bhnd dev/bhnd/bhnd_erom_if.m optional bhnd dev/bhnd/bhnd_subr.c optional bhnd dev/bhnd/bhnd_bus_if.m optional bhnd dev/bhnd/bhndb/bhnd_bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_bus_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_hwdata.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_pci.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndb_pci bhndb bhnd pci dev/bhnd/bhndb/bhndb_subr.c optional bhndb bhnd dev/bhnd/bcma/bcma.c optional bcma bhnd dev/bhnd/bcma/bcma_bhndb.c optional bcma bhnd bhndb dev/bhnd/bcma/bcma_erom.c optional bcma bhnd dev/bhnd/bcma/bcma_subr.c optional bcma bhnd dev/bhnd/cores/chipc/bhnd_chipc_if.m optional bhnd dev/bhnd/cores/chipc/bhnd_sprom_chipc.c optional bhnd dev/bhnd/cores/chipc/bhnd_pmu_chipc.c optional bhnd dev/bhnd/cores/chipc/chipc.c optional bhnd dev/bhnd/cores/chipc/chipc_cfi.c optional bhnd cfi dev/bhnd/cores/chipc/chipc_gpio.c optional bhnd gpio dev/bhnd/cores/chipc/chipc_slicer.c optional bhnd cfi | bhnd spibus dev/bhnd/cores/chipc/chipc_spi.c optional bhnd spibus dev/bhnd/cores/chipc/chipc_subr.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_if.m optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_hostb_if.m optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c optional bhnd dev/bhnd/cores/pci/bhnd_pci.c optional bhnd pci dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2.c optional bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2b.c optional bhnd_pcie2b bhnd pci dev/bhnd/cores/pmu/bhnd_pmu.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_core.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_if.m optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcm.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_btxt.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_tlv.c optional bhnd dev/bhnd/nvram/bhnd_nvram_if.m optional bhnd dev/bhnd/nvram/bhnd_nvram_io.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iobuf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_ioptr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iores.c optional bhnd dev/bhnd/nvram/bhnd_nvram_plist.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_fmts.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_prf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_subr.c optional bhnd dev/bhnd/nvram/bhnd_sprom.c optional bhnd dev/bhnd/siba/siba.c optional siba bhnd dev/bhnd/siba/siba_bhndb.c optional siba bhnd bhndb dev/bhnd/siba/siba_erom.c optional siba bhnd dev/bhnd/siba/siba_subr.c optional siba bhnd # dev/bktr/bktr_audio.c optional bktr pci dev/bktr/bktr_card.c optional bktr pci dev/bktr/bktr_core.c optional bktr pci dev/bktr/bktr_i2c.c optional bktr pci smbus dev/bktr/bktr_os.c optional bktr pci dev/bktr/bktr_tuner.c optional bktr pci dev/bktr/msp34xx.c optional bktr pci dev/bnxt/bnxt_hwrm.c optional bnxt iflib pci dev/bnxt/bnxt_sysctl.c optional bnxt iflib pci dev/bnxt/bnxt_txrx.c optional bnxt iflib pci dev/bnxt/if_bnxt.c optional bnxt iflib pci dev/bwi/bwimac.c optional bwi dev/bwi/bwiphy.c optional bwi dev/bwi/bwirf.c optional bwi dev/bwi/if_bwi.c optional bwi dev/bwi/if_bwi_pci.c optional bwi pci dev/bwn/if_bwn.c optional bwn bhnd dev/bwn/if_bwn_pci.c optional bwn pci bhnd bhndb bhndb_pci dev/bwn/if_bwn_phy_common.c optional bwn bhnd dev/bwn/if_bwn_phy_g.c optional bwn bhnd dev/bwn/if_bwn_phy_lp.c optional bwn bhnd dev/bwn/if_bwn_phy_n.c optional bwn bhnd dev/bwn/if_bwn_util.c optional bwn bhnd dev/cardbus/cardbus.c optional cardbus dev/cardbus/cardbus_cis.c optional cardbus dev/cardbus/cardbus_device.c optional cardbus dev/cas/if_cas.c optional cas dev/cfi/cfi_bus_fdt.c optional cfi fdt dev/cfi/cfi_bus_nexus.c optional cfi dev/cfi/cfi_core.c optional cfi dev/cfi/cfi_dev.c optional cfi dev/cfi/cfi_disk.c optional cfid dev/chromebook_platform/chromebook_platform.c optional chromebook_platform dev/ciss/ciss.c optional ciss dev/cmx/cmx.c optional cmx dev/cmx/cmx_pccard.c optional cmx pccard dev/cpufreq/ichss.c optional cpufreq pci dev/cxgb/cxgb_main.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_sge.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mc5.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc7323.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_ael1002.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_aq100x.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_xgmac.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_t3_hw.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_tn1010.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/sys/uipc_mvec.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_t3fw.c optional cxgb cxgb_t3fw \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgbe/t4_clip.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_filter.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_if.m optional cxgbe pci dev/cxgbe/t4_iov.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_mp_ring.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_main.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_netmap.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sched.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sge.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_smt.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_l2t.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_tracer.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_vf.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4_hw.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4vf_hw.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_common.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_flash_utils.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_lib.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/cudbg_wtp.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/fastlz.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/cudbg/fastlz_api.c optional cxgbe \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" t4fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "t4fw_cfg.c" t4fw_cfg.fwo optional cxgbe \ dependency "t4fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg.fwo" t4fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg.fw" t4fw_cfg_uwire.fwo optional cxgbe \ dependency "t4fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg_uwire.fwo" t4fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg_uwire.fw" t4fw.fwo optional cxgbe \ dependency "t4fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw.fwo" t4fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw-1.23.0.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t4fw.fw" t5fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t5fw_cfg.fw:t5fw_cfg t5fw_cfg_uwire.fw:t5fw_cfg_uwire t5fw.fw:t5fw -mt5fw_cfg -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "t5fw_cfg.c" t5fw_cfg.fwo optional cxgbe \ dependency "t5fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg.fwo" t5fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg.fw" t5fw_cfg_uwire.fwo optional cxgbe \ dependency "t5fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg_uwire.fwo" t5fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg_uwire.fw" t5fw.fwo optional cxgbe \ dependency "t5fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw.fwo" t5fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw-1.23.0.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t5fw.fw" t6fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t6fw_cfg.fw:t6fw_cfg t6fw_cfg_uwire.fw:t6fw_cfg_uwire t6fw.fw:t6fw -mt6fw_cfg -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "t6fw_cfg.c" t6fw_cfg.fwo optional cxgbe \ dependency "t6fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg.fwo" t6fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg.fw" t6fw_cfg_uwire.fwo optional cxgbe \ dependency "t6fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg_uwire.fwo" t6fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg_uwire.fw" t6fw.fwo optional cxgbe \ dependency "t6fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw.fwo" t6fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw-1.23.0.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t6fw.fw" dev/cxgbe/crypto/t4_crypto.c optional ccr \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cy/cy.c optional cy dev/cy/cy_isa.c optional cy isa dev/cy/cy_pci.c optional cy pci dev/cyapa/cyapa.c optional cyapa iicbus dev/dc/if_dc.c optional dc pci dev/dc/dcphy.c optional dc pci dev/dc/pnphy.c optional dc pci dev/dcons/dcons.c optional dcons dev/dcons/dcons_crom.c optional dcons_crom dev/dcons/dcons_os.c optional dcons dev/dme/if_dme.c optional dme dev/drm2/drm_agpsupport.c optional drm2 dev/drm2/drm_auth.c optional drm2 dev/drm2/drm_bufs.c optional drm2 dev/drm2/drm_buffer.c optional drm2 dev/drm2/drm_context.c optional drm2 dev/drm2/drm_crtc.c optional drm2 dev/drm2/drm_crtc_helper.c optional drm2 dev/drm2/drm_dma.c optional drm2 dev/drm2/drm_dp_helper.c optional drm2 dev/drm2/drm_dp_iic_helper.c optional drm2 dev/drm2/drm_drv.c optional drm2 dev/drm2/drm_edid.c optional drm2 dev/drm2/drm_fb_helper.c optional drm2 dev/drm2/drm_fops.c optional drm2 dev/drm2/drm_gem.c optional drm2 dev/drm2/drm_gem_names.c optional drm2 dev/drm2/drm_global.c optional drm2 dev/drm2/drm_hashtab.c optional drm2 dev/drm2/drm_ioctl.c optional drm2 dev/drm2/drm_irq.c optional drm2 dev/drm2/drm_linux_list_sort.c optional drm2 dev/drm2/drm_lock.c optional drm2 dev/drm2/drm_memory.c optional drm2 dev/drm2/drm_mm.c optional drm2 dev/drm2/drm_modes.c optional drm2 dev/drm2/drm_pci.c optional drm2 dev/drm2/drm_platform.c optional drm2 dev/drm2/drm_scatter.c optional drm2 dev/drm2/drm_stub.c optional drm2 dev/drm2/drm_sysctl.c optional drm2 dev/drm2/drm_vm.c optional drm2 dev/drm2/drm_os_freebsd.c optional drm2 dev/drm2/ttm/ttm_agp_backend.c optional drm2 dev/drm2/ttm/ttm_lock.c optional drm2 dev/drm2/ttm/ttm_object.c optional drm2 dev/drm2/ttm/ttm_tt.c optional drm2 dev/drm2/ttm/ttm_bo_util.c optional drm2 dev/drm2/ttm/ttm_bo.c optional drm2 dev/drm2/ttm/ttm_bo_manager.c optional drm2 dev/drm2/ttm/ttm_execbuf_util.c optional drm2 dev/drm2/ttm/ttm_memory.c optional drm2 dev/drm2/ttm/ttm_page_alloc.c optional drm2 dev/drm2/ttm/ttm_bo_vm.c optional drm2 dev/efidev/efidev.c optional efirt dev/efidev/efirt.c optional efirt dev/efidev/efirtc.c optional efirt dev/e1000/if_em.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/em_txrx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/igb_txrx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_80003es2lan.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82540.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82541.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82542.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82543.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82571.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82575.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_ich8lan.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_i210.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_api.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mac.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_manage.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_nvm.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_phy.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_vf.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mbx.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_osdep.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/et/if_et.c optional et dev/ena/ena.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" dev/ena/ena_sysctl.c optional ena \ compile-with "${NORMAL_C} -I$S/contrib" contrib/ena-com/ena_com.c optional ena contrib/ena-com/ena_eth_com.c optional ena dev/esp/esp_pci.c optional esp pci dev/esp/ncr53c9x.c optional esp dev/etherswitch/arswitch/arswitch.c optional arswitch dev/etherswitch/arswitch/arswitch_reg.c optional arswitch dev/etherswitch/arswitch/arswitch_phy.c optional arswitch dev/etherswitch/arswitch/arswitch_8216.c optional arswitch dev/etherswitch/arswitch/arswitch_8226.c optional arswitch dev/etherswitch/arswitch/arswitch_8316.c optional arswitch dev/etherswitch/arswitch/arswitch_8327.c optional arswitch dev/etherswitch/arswitch/arswitch_7240.c optional arswitch dev/etherswitch/arswitch/arswitch_9340.c optional arswitch dev/etherswitch/arswitch/arswitch_vlans.c optional arswitch dev/etherswitch/etherswitch.c optional etherswitch dev/etherswitch/etherswitch_if.m optional etherswitch dev/etherswitch/ip17x/ip17x.c optional ip17x dev/etherswitch/ip17x/ip175c.c optional ip17x dev/etherswitch/ip17x/ip175d.c optional ip17x dev/etherswitch/ip17x/ip17x_phy.c optional ip17x dev/etherswitch/ip17x/ip17x_vlans.c optional ip17x dev/etherswitch/miiproxy.c optional miiproxy dev/etherswitch/rtl8366/rtl8366rb.c optional rtl8366rb dev/etherswitch/e6000sw/e6000sw.c optional e6000sw dev/etherswitch/e6000sw/e6060sw.c optional e6060sw dev/etherswitch/infineon/adm6996fc.c optional adm6996fc dev/etherswitch/micrel/ksz8995ma.c optional ksz8995ma dev/etherswitch/ukswitch/ukswitch.c optional ukswitch dev/evdev/cdev.c optional evdev dev/evdev/evdev.c optional evdev dev/evdev/evdev_mt.c optional evdev dev/evdev/evdev_utils.c optional evdev dev/evdev/uinput.c optional evdev uinput dev/exca/exca.c optional cbb dev/extres/clk/clk.c optional ext_resources clk fdt dev/extres/clk/clkdev_if.m optional ext_resources clk fdt dev/extres/clk/clknode_if.m optional ext_resources clk fdt dev/extres/clk/clk_bus.c optional ext_resources clk fdt dev/extres/clk/clk_div.c optional ext_resources clk fdt dev/extres/clk/clk_fixed.c optional ext_resources clk fdt dev/extres/clk/clk_gate.c optional ext_resources clk fdt dev/extres/clk/clk_mux.c optional ext_resources clk fdt dev/extres/phy/phy.c optional ext_resources phy fdt dev/extres/phy/phydev_if.m optional ext_resources phy fdt dev/extres/phy/phynode_if.m optional ext_resources phy fdt dev/extres/phy/phy_usb.c optional ext_resources phy fdt dev/extres/phy/phynode_usb_if.m optional ext_resources phy fdt dev/extres/hwreset/hwreset.c optional ext_resources hwreset fdt dev/extres/hwreset/hwreset_if.m optional ext_resources hwreset fdt dev/extres/nvmem/nvmem.c optional ext_resources nvmem fdt dev/extres/nvmem/nvmem_if.m optional ext_resources nvmem fdt dev/extres/regulator/regdev_if.m optional ext_resources regulator fdt dev/extres/regulator/regnode_if.m optional ext_resources regulator fdt dev/extres/regulator/regulator.c optional ext_resources regulator fdt dev/extres/regulator/regulator_bus.c optional ext_resources regulator fdt dev/extres/regulator/regulator_fixed.c optional ext_resources regulator fdt dev/extres/syscon/syscon.c optional ext_resources syscon dev/extres/syscon/syscon_generic.c optional ext_resources syscon fdt dev/extres/syscon/syscon_if.m optional ext_resources syscon dev/fb/fbd.c optional fbd | vt dev/fb/fb_if.m standard dev/fb/splash.c optional sc splash dev/fdt/fdt_clock.c optional fdt fdt_clock dev/fdt/fdt_clock_if.m optional fdt fdt_clock dev/fdt/fdt_common.c optional fdt dev/fdt/fdt_pinctrl.c optional fdt fdt_pinctrl dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl -dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand | fdt mx25l | fdt n25q | fdt at45d +dev/fdt/fdt_slicer.c optional fdt cfi | fdt mx25l | fdt n25q | fdt at45d dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \ dependency "${FDT_DTS_FILE:T:R}.dtb" dev/fdt/simplebus.c optional fdt dev/fdt/simple_mfd.c optional fdt dev/filemon/filemon.c optional filemon dev/firewire/firewire.c optional firewire dev/firewire/fwcrom.c optional firewire dev/firewire/fwdev.c optional firewire dev/firewire/fwdma.c optional firewire dev/firewire/fwmem.c optional firewire dev/firewire/fwohci.c optional firewire dev/firewire/fwohci_pci.c optional firewire pci dev/firewire/if_fwe.c optional fwe dev/firewire/if_fwip.c optional fwip dev/firewire/sbp.c optional sbp dev/firewire/sbp_targ.c optional sbp_targ dev/flash/at45d.c optional at45d dev/flash/cqspi.c optional cqspi fdt xdma dev/flash/mx25l.c optional mx25l dev/flash/n25q.c optional n25q fdt dev/flash/qspi_if.m optional cqspi fdt | n25q fdt dev/fxp/if_fxp.c optional fxp dev/fxp/inphy.c optional fxp dev/gem/if_gem.c optional gem dev/gem/if_gem_pci.c optional gem pci dev/gem/if_gem_sbus.c optional gem sbus dev/gpio/gpiobacklight.c optional gpiobacklight fdt dev/gpio/gpiokeys.c optional gpiokeys fdt dev/gpio/gpiokeys_codes.c optional gpiokeys fdt dev/gpio/gpiobus.c optional gpio \ dependency "gpiobus_if.h" dev/gpio/gpioc.c optional gpio \ dependency "gpio_if.h" dev/gpio/gpioiic.c optional gpioiic dev/gpio/gpioled.c optional gpioled !fdt dev/gpio/gpioled_fdt.c optional gpioled fdt dev/gpio/gpiopower.c optional gpiopower fdt dev/gpio/gpioregulator.c optional gpioregulator fdt ext_resources dev/gpio/gpiospi.c optional gpiospi dev/gpio/gpioths.c optional gpioths dev/gpio/gpio_if.m optional gpio dev/gpio/gpiobus_if.m optional gpio dev/gpio/gpiopps.c optional gpiopps fdt dev/gpio/ofw_gpiobus.c optional fdt gpio dev/hifn/hifn7751.c optional hifn dev/hme/if_hme.c optional hme dev/hme/if_hme_pci.c optional hme pci dev/hme/if_hme_sbus.c optional hme sbus dev/hptiop/hptiop.c optional hptiop scbus dev/hwpmc/hwpmc_logging.c optional hwpmc dev/hwpmc/hwpmc_mod.c optional hwpmc dev/hwpmc/hwpmc_soft.c optional hwpmc dev/ichiic/ig4_acpi.c optional ig4 acpi iicbus dev/ichiic/ig4_iic.c optional ig4 iicbus dev/ichiic/ig4_pci.c optional ig4 pci iicbus dev/ichsmb/ichsmb.c optional ichsmb dev/ichsmb/ichsmb_pci.c optional ichsmb pci dev/ida/ida.c optional ida dev/ida/ida_disk.c optional ida dev/ida/ida_pci.c optional ida pci dev/iicbus/ad7418.c optional ad7418 dev/iicbus/ds1307.c optional ds1307 dev/iicbus/ds13rtc.c optional ds13rtc | ds133x | ds1374 dev/iicbus/ds1672.c optional ds1672 dev/iicbus/ds3231.c optional ds3231 dev/iicbus/rtc8583.c optional rtc8583 dev/iicbus/syr827.c optional syr827 ext_resources fdt dev/iicbus/icee.c optional icee dev/iicbus/if_ic.c optional ic dev/iicbus/iic.c optional iic dev/iicbus/iic_recover_bus.c optional iicbus dev/iicbus/iicbb.c optional iicbb dev/iicbus/iicbb_if.m optional iicbb dev/iicbus/iicbus.c optional iicbus dev/iicbus/iicbus_if.m optional iicbus dev/iicbus/iiconf.c optional iicbus dev/iicbus/iicsmb.c optional iicsmb \ dependency "iicbus_if.h" dev/iicbus/iicoc.c optional iicoc dev/iicbus/isl12xx.c optional isl12xx dev/iicbus/lm75.c optional lm75 dev/iicbus/nxprtc.c optional nxprtc | pcf8563 dev/iicbus/ofw_iicbus.c optional fdt iicbus dev/iicbus/rtc8583.c optional rtc8583 dev/iicbus/s35390a.c optional s35390a dev/iicbus/sy8106a.c optional sy8106a ext_resources fdt dev/iir/iir.c optional iir dev/iir/iir_ctrl.c optional iir dev/iir/iir_pci.c optional iir pci dev/intpm/intpm.c optional intpm pci # XXX Work around clang warning, until maintainer approves fix. dev/ips/ips.c optional ips \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/ips/ips_commands.c optional ips dev/ips/ips_disk.c optional ips dev/ips/ips_ioctl.c optional ips dev/ips/ips_pci.c optional ips pci dev/ipw/if_ipw.c optional ipw ipwbssfw.c optional ipwbssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_bss.fw:ipw_bss:130 -lintel_ipw -mipw_bss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "ipwbssfw.c" ipw_bss.fwo optional ipwbssfw | ipwfw \ dependency "ipw_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_bss.fwo" ipw_bss.fw optional ipwbssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_bss.fw" ipwibssfw.c optional ipwibssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_ibss.fw:ipw_ibss:130 -lintel_ipw -mipw_ibss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "ipwibssfw.c" ipw_ibss.fwo optional ipwibssfw | ipwfw \ dependency "ipw_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_ibss.fwo" ipw_ibss.fw optional ipwibssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-i.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_ibss.fw" ipwmonitorfw.c optional ipwmonitorfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_monitor.fw:ipw_monitor:130 -lintel_ipw -mipw_monitor -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "ipwmonitorfw.c" ipw_monitor.fwo optional ipwmonitorfw | ipwfw \ dependency "ipw_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_monitor.fwo" ipw_monitor.fw optional ipwmonitorfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-p.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_monitor.fw" dev/iscsi/icl.c optional iscsi dev/iscsi/icl_conn_if.m optional cfiscsi | iscsi dev/iscsi/icl_soft.c optional iscsi dev/iscsi/icl_soft_proxy.c optional iscsi dev/iscsi/iscsi.c optional iscsi scbus dev/iscsi_initiator/iscsi.c optional iscsi_initiator scbus dev/iscsi_initiator/iscsi_subr.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_cam.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_soc.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_sm.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_subr.c optional iscsi_initiator scbus dev/ismt/ismt.c optional ismt dev/isl/isl.c optional isl iicbus dev/isp/isp.c optional isp dev/isp/isp_freebsd.c optional isp dev/isp/isp_library.c optional isp dev/isp/isp_pci.c optional isp pci dev/isp/isp_sbus.c optional isp sbus dev/isp/isp_target.c optional isp dev/ispfw/ispfw.c optional ispfw dev/iwi/if_iwi.c optional iwi iwibssfw.c optional iwibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_bss.fw:iwi_bss:300 -lintel_iwi -miwi_bss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwibssfw.c" iwi_bss.fwo optional iwibssfw | iwifw \ dependency "iwi_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_bss.fwo" iwi_bss.fw optional iwibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-bss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_bss.fw" iwiibssfw.c optional iwiibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_ibss.fw:iwi_ibss:300 -lintel_iwi -miwi_ibss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwiibssfw.c" iwi_ibss.fwo optional iwiibssfw | iwifw \ dependency "iwi_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_ibss.fwo" iwi_ibss.fw optional iwiibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-ibss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_ibss.fw" iwimonitorfw.c optional iwimonitorfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_monitor.fw:iwi_monitor:300 -lintel_iwi -miwi_monitor -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwimonitorfw.c" iwi_monitor.fwo optional iwimonitorfw | iwifw \ dependency "iwi_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_monitor.fwo" iwi_monitor.fw optional iwimonitorfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-sniffer.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_monitor.fw" dev/iwm/if_iwm.c optional iwm dev/iwm/if_iwm_7000.c optional iwm dev/iwm/if_iwm_8000.c optional iwm dev/iwm/if_iwm_binding.c optional iwm dev/iwm/if_iwm_fw.c optional iwm dev/iwm/if_iwm_led.c optional iwm dev/iwm/if_iwm_mac_ctxt.c optional iwm dev/iwm/if_iwm_notif_wait.c optional iwm dev/iwm/if_iwm_pcie_trans.c optional iwm dev/iwm/if_iwm_phy_ctxt.c optional iwm dev/iwm/if_iwm_phy_db.c optional iwm dev/iwm/if_iwm_power.c optional iwm dev/iwm/if_iwm_scan.c optional iwm dev/iwm/if_iwm_sf.c optional iwm dev/iwm/if_iwm_sta.c optional iwm dev/iwm/if_iwm_time_event.c optional iwm dev/iwm/if_iwm_util.c optional iwm iwm3160fw.c optional iwm3160fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3160.fw:iwm3160fw -miwm3160fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm3160fw.c" iwm3160fw.fwo optional iwm3160fw | iwmfw \ dependency "iwm3160.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3160fw.fwo" iwm3160.fw optional iwm3160fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3160-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3160.fw" iwm3168fw.c optional iwm3168fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3168.fw:iwm3168fw -miwm3168fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm3168fw.c" iwm3168fw.fwo optional iwm3168fw | iwmfw \ dependency "iwm3168.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3168fw.fwo" iwm3168.fw optional iwm3168fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3168-22.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3168.fw" iwm7260fw.c optional iwm7260fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7260.fw:iwm7260fw -miwm7260fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm7260fw.c" iwm7260fw.fwo optional iwm7260fw | iwmfw \ dependency "iwm7260.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7260fw.fwo" iwm7260.fw optional iwm7260fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7260-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7260.fw" iwm7265fw.c optional iwm7265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265.fw:iwm7265fw -miwm7265fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm7265fw.c" iwm7265fw.fwo optional iwm7265fw | iwmfw \ dependency "iwm7265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265fw.fwo" iwm7265.fw optional iwm7265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265.fw" iwm7265Dfw.c optional iwm7265Dfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265D.fw:iwm7265Dfw -miwm7265Dfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm7265Dfw.c" iwm7265Dfw.fwo optional iwm7265Dfw | iwmfw \ dependency "iwm7265D.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265Dfw.fwo" iwm7265D.fw optional iwm7265Dfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265D-17.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265D.fw" iwm8000Cfw.c optional iwm8000Cfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8000C.fw:iwm8000Cfw -miwm8000Cfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm8000Cfw.c" iwm8000Cfw.fwo optional iwm8000Cfw | iwmfw \ dependency "iwm8000C.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8000Cfw.fwo" iwm8000C.fw optional iwm8000Cfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8000C-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8000C.fw" iwm8265.fw optional iwm8265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8265-22.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8265.fw" iwm8265fw.c optional iwm8265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8265.fw:iwm8265fw -miwm8265fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm8265fw.c" iwm8265fw.fwo optional iwm8265fw | iwmfw \ dependency "iwm8265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8265fw.fwo" dev/iwn/if_iwn.c optional iwn iwn1000fw.c optional iwn1000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn1000fw.c" iwn1000fw.fwo optional iwn1000fw | iwnfw \ dependency "iwn1000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn1000fw.fwo" iwn1000.fw optional iwn1000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-1000-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn1000.fw" iwn100fw.c optional iwn100fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn100.fw:iwn100fw -miwn100fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn100fw.c" iwn100fw.fwo optional iwn100fw | iwnfw \ dependency "iwn100.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn100fw.fwo" iwn100.fw optional iwn100fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-100-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn100.fw" iwn105fw.c optional iwn105fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn105.fw:iwn105fw -miwn105fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn105fw.c" iwn105fw.fwo optional iwn105fw | iwnfw \ dependency "iwn105.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn105fw.fwo" iwn105.fw optional iwn105fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-105-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn105.fw" iwn135fw.c optional iwn135fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn135.fw:iwn135fw -miwn135fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn135fw.c" iwn135fw.fwo optional iwn135fw | iwnfw \ dependency "iwn135.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn135fw.fwo" iwn135.fw optional iwn135fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-135-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn135.fw" iwn2000fw.c optional iwn2000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2000.fw:iwn2000fw -miwn2000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn2000fw.c" iwn2000fw.fwo optional iwn2000fw | iwnfw \ dependency "iwn2000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2000fw.fwo" iwn2000.fw optional iwn2000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-2000-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2000.fw" iwn2030fw.c optional iwn2030fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2030.fw:iwn2030fw -miwn2030fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn2030fw.c" iwn2030fw.fwo optional iwn2030fw | iwnfw \ dependency "iwn2030.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2030fw.fwo" iwn2030.fw optional iwn2030fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwnwifi-2030-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2030.fw" iwn4965fw.c optional iwn4965fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn4965.fw:iwn4965fw -miwn4965fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn4965fw.c" iwn4965fw.fwo optional iwn4965fw | iwnfw \ dependency "iwn4965.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn4965fw.fwo" iwn4965.fw optional iwn4965fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn4965.fw" iwn5000fw.c optional iwn5000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5000.fw:iwn5000fw -miwn5000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn5000fw.c" iwn5000fw.fwo optional iwn5000fw | iwnfw \ dependency "iwn5000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5000fw.fwo" iwn5000.fw optional iwn5000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5000-8.83.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5000.fw" iwn5150fw.c optional iwn5150fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5150.fw:iwn5150fw -miwn5150fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn5150fw.c" iwn5150fw.fwo optional iwn5150fw | iwnfw \ dependency "iwn5150.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5150fw.fwo" iwn5150.fw optional iwn5150fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu"\ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5150.fw" iwn6000fw.c optional iwn6000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000.fw:iwn6000fw -miwn6000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6000fw.c" iwn6000fw.fwo optional iwn6000fw | iwnfw \ dependency "iwn6000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000fw.fwo" iwn6000.fw optional iwn6000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000-9.221.4.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000.fw" iwn6000g2afw.c optional iwn6000g2afw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2a.fw:iwn6000g2afw -miwn6000g2afw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6000g2afw.c" iwn6000g2afw.fwo optional iwn6000g2afw | iwnfw \ dependency "iwn6000g2a.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2afw.fwo" iwn6000g2a.fw optional iwn6000g2afw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2a-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2a.fw" iwn6000g2bfw.c optional iwn6000g2bfw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2b.fw:iwn6000g2bfw -miwn6000g2bfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6000g2bfw.c" iwn6000g2bfw.fwo optional iwn6000g2bfw | iwnfw \ dependency "iwn6000g2b.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2bfw.fwo" iwn6000g2b.fw optional iwn6000g2bfw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2b.fw" iwn6050fw.c optional iwn6050fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6050.fw:iwn6050fw -miwn6050fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6050fw.c" iwn6050fw.fwo optional iwn6050fw | iwnfw \ dependency "iwn6050.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6050fw.fwo" iwn6050.fw optional iwn6050fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6050-41.28.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6050.fw" dev/ixgbe/if_ix.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_ixv.c optional ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_bypass.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/if_fdir.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/if_sriov.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ix_txrx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_osdep.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_phy.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_api.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_common.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_mbx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_vf.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x540.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x550.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/jedec_dimm/jedec_dimm.c optional jedec_dimm smbus dev/jme/if_jme.c optional jme pci dev/kbd/kbd.c optional atkbd | pckbd | sc | ukbd | vt dev/kbdmux/kbdmux.c optional kbdmux dev/ksyms/ksyms.c optional ksyms dev/le/am7990.c optional le dev/le/am79900.c optional le dev/le/if_le_pci.c optional le pci dev/le/lance.c optional le dev/led/led.c standard dev/lge/if_lge.c optional lge dev/liquidio/base/cn23xx_pf_device.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_console.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_ctrl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_device.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_droq.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_mem_ops.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_request_manager.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/base/lio_response_manager.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_core.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_ioctl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_main.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_rss.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_rxtx.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" dev/liquidio/lio_sysctl.c optional lio \ compile-with "${NORMAL_C} \ -I$S/dev/liquidio -I$S/dev/liquidio/base -DSMP" lio.c optional lio \ compile-with "${AWK} -f $S/tools/fw_stub.awk lio_23xx_nic.bin.fw:lio_23xx_nic.bin -mlio_23xx_nic.bin -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "lio.c" lio_23xx_nic.bin.fw.fwo optional lio \ dependency "lio_23xx_nic.bin.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "lio_23xx_nic.bin.fw.fwo" lio_23xx_nic.bin.fw optional lio \ dependency "$S/contrib/dev/liquidio/lio_23xx_nic.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "lio_23xx_nic.bin.fw" dev/malo/if_malo.c optional malo dev/malo/if_malohal.c optional malo dev/malo/if_malo_pci.c optional malo pci dev/mc146818/mc146818.c optional mc146818 dev/md/md.c optional md dev/mdio/mdio_if.m optional miiproxy | mdio dev/mdio/mdio.c optional miiproxy | mdio dev/mem/memdev.c optional mem dev/mem/memutil.c optional mem dev/mfi/mfi.c optional mfi dev/mfi/mfi_debug.c optional mfi dev/mfi/mfi_pci.c optional mfi pci dev/mfi/mfi_disk.c optional mfi dev/mfi/mfi_syspd.c optional mfi dev/mfi/mfi_tbolt.c optional mfi dev/mfi/mfi_linux.c optional mfi compat_linux dev/mfi/mfi_cam.c optional mfip scbus dev/mii/acphy.c optional miibus | acphy dev/mii/amphy.c optional miibus | amphy dev/mii/atphy.c optional miibus | atphy dev/mii/axphy.c optional miibus | axphy dev/mii/bmtphy.c optional miibus | bmtphy dev/mii/brgphy.c optional miibus | brgphy dev/mii/ciphy.c optional miibus | ciphy dev/mii/e1000phy.c optional miibus | e1000phy dev/mii/gentbi.c optional miibus | gentbi dev/mii/icsphy.c optional miibus | icsphy dev/mii/ip1000phy.c optional miibus | ip1000phy dev/mii/jmphy.c optional miibus | jmphy dev/mii/lxtphy.c optional miibus | lxtphy dev/mii/micphy.c optional miibus fdt | micphy fdt dev/mii/mii.c optional miibus | mii dev/mii/mii_bitbang.c optional miibus | mii_bitbang dev/mii/mii_physubr.c optional miibus | mii dev/mii/mii_fdt.c optional miibus fdt | mii fdt dev/mii/miibus_if.m optional miibus | mii dev/mii/mlphy.c optional miibus | mlphy dev/mii/nsgphy.c optional miibus | nsgphy dev/mii/nsphy.c optional miibus | nsphy dev/mii/nsphyter.c optional miibus | nsphyter dev/mii/pnaphy.c optional miibus | pnaphy dev/mii/qsphy.c optional miibus | qsphy dev/mii/rdcphy.c optional miibus | rdcphy dev/mii/rgephy.c optional miibus | rgephy dev/mii/rlphy.c optional miibus | rlphy dev/mii/rlswitch.c optional rlswitch dev/mii/smcphy.c optional miibus | smcphy dev/mii/smscphy.c optional miibus | smscphy dev/mii/tdkphy.c optional miibus | tdkphy dev/mii/tlphy.c optional miibus | tlphy dev/mii/truephy.c optional miibus | truephy dev/mii/ukphy.c optional miibus | mii dev/mii/ukphy_subr.c optional miibus | mii dev/mii/vscphy.c optional miibus | vscphy dev/mii/xmphy.c optional miibus | xmphy dev/mk48txx/mk48txx.c optional mk48txx dev/mlxfw/mlxfw_fsm.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlxfw/mlxfw_mfa2.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlxfw/mlxfw_mfa2_tlv_multi.c optional mlxfw \ compile-with "${MLXFW_C}" dev/mlx/mlx.c optional mlx dev/mlx/mlx_disk.c optional mlx dev/mlx/mlx_pci.c optional mlx pci dev/mly/mly.c optional mly dev/mmc/mmc_subr.c optional mmc | mmcsd !mmccam dev/mmc/mmc.c optional mmc !mmccam dev/mmc/mmcbr_if.m standard dev/mmc/mmcbus_if.m standard dev/mmc/mmcsd.c optional mmcsd !mmccam dev/mmcnull/mmcnull.c optional mmcnull dev/mn/if_mn.c optional mn pci dev/mpr/mpr.c optional mpr dev/mpr/mpr_config.c optional mpr # XXX Work around clang warning, until maintainer approves fix. dev/mpr/mpr_mapping.c optional mpr \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mpr/mpr_pci.c optional mpr pci dev/mpr/mpr_sas.c optional mpr \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mpr/mpr_sas_lsi.c optional mpr dev/mpr/mpr_table.c optional mpr dev/mpr/mpr_user.c optional mpr dev/mps/mps.c optional mps dev/mps/mps_config.c optional mps # XXX Work around clang warning, until maintainer approves fix. dev/mps/mps_mapping.c optional mps \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mps/mps_pci.c optional mps pci dev/mps/mps_sas.c optional mps \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mps/mps_sas_lsi.c optional mps dev/mps/mps_table.c optional mps dev/mps/mps_user.c optional mps dev/mpt/mpt.c optional mpt dev/mpt/mpt_cam.c optional mpt dev/mpt/mpt_debug.c optional mpt dev/mpt/mpt_pci.c optional mpt pci dev/mpt/mpt_raid.c optional mpt dev/mpt/mpt_user.c optional mpt dev/mrsas/mrsas.c optional mrsas dev/mrsas/mrsas_cam.c optional mrsas dev/mrsas/mrsas_ioctl.c optional mrsas dev/mrsas/mrsas_fp.c optional mrsas dev/msk/if_msk.c optional msk dev/mvs/mvs.c optional mvs dev/mvs/mvs_if.m optional mvs dev/mvs/mvs_pci.c optional mvs pci dev/mwl/if_mwl.c optional mwl dev/mwl/if_mwl_pci.c optional mwl pci dev/mwl/mwlhal.c optional mwl mwlfw.c optional mwlfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk mw88W8363.fw:mw88W8363fw mwlboot.fw:mwlboot -mmwl -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "mwlfw.c" mw88W8363.fwo optional mwlfw \ dependency "mw88W8363.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mw88W8363.fwo" mw88W8363.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mw88W8363.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mw88W8363.fw" mwlboot.fwo optional mwlfw \ dependency "mwlboot.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mwlboot.fwo" mwlboot.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mwlboot.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mwlboot.fw" dev/mxge/if_mxge.c optional mxge pci dev/mxge/mxge_eth_z8e.c optional mxge pci dev/mxge/mxge_ethp_z8e.c optional mxge pci dev/mxge/mxge_rss_eth_z8e.c optional mxge pci dev/mxge/mxge_rss_ethp_z8e.c optional mxge pci dev/my/if_my.c optional my -dev/nand/nand.c optional nand -dev/nand/nand_bbt.c optional nand -dev/nand/nand_cdev.c optional nand -dev/nand/nand_generic.c optional nand -dev/nand/nand_geom.c optional nand -dev/nand/nand_id.c optional nand -dev/nand/nandbus.c optional nand -dev/nand/nandbus_if.m optional nand -dev/nand/nand_if.m optional nand -dev/nand/nandsim.c optional nandsim nand -dev/nand/nandsim_chip.c optional nandsim nand -dev/nand/nandsim_ctrl.c optional nandsim nand -dev/nand/nandsim_log.c optional nandsim nand -dev/nand/nandsim_swap.c optional nandsim nand -dev/nand/nfc_if.m optional nand dev/netmap/if_ptnet.c optional netmap inet dev/netmap/netmap.c optional netmap dev/netmap/netmap_bdg.c optional netmap dev/netmap/netmap_freebsd.c optional netmap dev/netmap/netmap_generic.c optional netmap dev/netmap/netmap_kloop.c optional netmap dev/netmap/netmap_legacy.c optional netmap dev/netmap/netmap_mbq.c optional netmap dev/netmap/netmap_mem2.c optional netmap dev/netmap/netmap_monitor.c optional netmap dev/netmap/netmap_null.c optional netmap dev/netmap/netmap_offloadings.c optional netmap dev/netmap/netmap_pipe.c optional netmap dev/netmap/netmap_pt.c optional netmap dev/netmap/netmap_vale.c optional netmap # compile-with "${NORMAL_C} -Wconversion -Wextra" dev/nfsmb/nfsmb.c optional nfsmb pci dev/nge/if_nge.c optional nge dev/nmdm/nmdm.c optional nmdm dev/nsp/nsp.c optional nsp dev/nsp/nsp_pccard.c optional nsp pccard dev/null/null.c standard dev/nvd/nvd.c optional nvd nvme dev/nvme/nvme.c optional nvme dev/nvme/nvme_ctrlr.c optional nvme dev/nvme/nvme_ctrlr_cmd.c optional nvme dev/nvme/nvme_ns.c optional nvme dev/nvme/nvme_ns_cmd.c optional nvme dev/nvme/nvme_qpair.c optional nvme dev/nvme/nvme_sim.c optional nvme scbus dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/oce/oce_hw.c optional oce pci dev/oce/oce_if.c optional oce pci dev/oce/oce_mbox.c optional oce pci dev/oce/oce_queue.c optional oce pci dev/oce/oce_sysctl.c optional oce pci dev/oce/oce_util.c optional oce pci dev/ocs_fc/ocs_pci.c optional ocs_fc pci dev/ocs_fc/ocs_ioctl.c optional ocs_fc pci dev/ocs_fc/ocs_os.c optional ocs_fc pci dev/ocs_fc/ocs_utils.c optional ocs_fc pci dev/ocs_fc/ocs_hw.c optional ocs_fc pci dev/ocs_fc/ocs_hw_queues.c optional ocs_fc pci dev/ocs_fc/sli4.c optional ocs_fc pci dev/ocs_fc/ocs_sm.c optional ocs_fc pci dev/ocs_fc/ocs_device.c optional ocs_fc pci dev/ocs_fc/ocs_xport.c optional ocs_fc pci dev/ocs_fc/ocs_domain.c optional ocs_fc pci dev/ocs_fc/ocs_sport.c optional ocs_fc pci dev/ocs_fc/ocs_els.c optional ocs_fc pci dev/ocs_fc/ocs_fabric.c optional ocs_fc pci dev/ocs_fc/ocs_io.c optional ocs_fc pci dev/ocs_fc/ocs_node.c optional ocs_fc pci dev/ocs_fc/ocs_scsi.c optional ocs_fc pci dev/ocs_fc/ocs_unsol.c optional ocs_fc pci dev/ocs_fc/ocs_ddump.c optional ocs_fc pci dev/ocs_fc/ocs_mgmt.c optional ocs_fc pci dev/ocs_fc/ocs_cam.c optional ocs_fc pci dev/ofw/ofw_bus_if.m optional fdt dev/ofw/ofw_bus_subr.c optional fdt dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofw_fdt.c optional fdt dev/ofw/ofw_if.m optional fdt dev/ofw/ofw_graph.c optional fdt dev/ofw/ofw_subr.c optional fdt dev/ofw/ofwbus.c optional fdt dev/ofw/openfirm.c optional fdt dev/ofw/openfirmio.c optional fdt dev/ow/ow.c optional ow \ dependency "owll_if.h" \ dependency "own_if.h" dev/ow/owll_if.m optional ow dev/ow/own_if.m optional ow dev/ow/ow_temp.c optional ow_temp dev/ow/owc_gpiobus.c optional owc gpio dev/pbio/pbio.c optional pbio isa dev/pccard/card_if.m standard dev/pccard/pccard.c optional pccard dev/pccard/pccard_cis.c optional pccard dev/pccard/pccard_cis_quirks.c optional pccard dev/pccard/pccard_device.c optional pccard dev/pccard/power_if.m standard dev/pccbb/pccbb.c optional cbb dev/pccbb/pccbb_isa.c optional cbb isa dev/pccbb/pccbb_pci.c optional cbb pci dev/pcf/pcf.c optional pcf dev/pci/fixup_pci.c optional pci dev/pci/hostb_pci.c optional pci dev/pci/ignore_pci.c optional pci dev/pci/isa_pci.c optional pci isa dev/pci/pci.c optional pci dev/pci/pci_if.m standard dev/pci/pci_iov.c optional pci pci_iov dev/pci/pci_iov_if.m standard dev/pci/pci_iov_schema.c optional pci pci_iov dev/pci/pci_pci.c optional pci dev/pci/pci_subr.c optional pci dev/pci/pci_user.c optional pci dev/pci/pcib_if.m standard dev/pci/pcib_support.c standard dev/pci/vga_pci.c optional pci dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saframe.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sahw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sainit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampicmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampirsp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saphy.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasata.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sassp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/satimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sautil.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saioctlcmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpidebug.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmsmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmdisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/sminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsatcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdesgl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdioctl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdhw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/ossacmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tddmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdsmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdtimers.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdio.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itddisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/ossasat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/ppbus/if_plip.c optional plip dev/ppbus/immio.c optional vpo dev/ppbus/lpbb.c optional lpbb dev/ppbus/lpt.c optional lpt dev/ppbus/pcfclock.c optional pcfclock dev/ppbus/ppb_1284.c optional ppbus dev/ppbus/ppb_base.c optional ppbus dev/ppbus/ppb_msq.c optional ppbus dev/ppbus/ppbconf.c optional ppbus dev/ppbus/ppbus_if.m optional ppbus dev/ppbus/ppi.c optional ppi dev/ppbus/pps.c optional pps dev/ppbus/vpo.c optional vpo dev/ppbus/vpoio.c optional vpo dev/ppc/ppc.c optional ppc dev/ppc/ppc_acpi.c optional ppc acpi dev/ppc/ppc_isa.c optional ppc isa dev/ppc/ppc_pci.c optional ppc pci dev/ppc/ppc_puc.c optional ppc puc dev/proto/proto_bus_isa.c optional proto acpi | proto isa dev/proto/proto_bus_pci.c optional proto pci dev/proto/proto_busdma.c optional proto dev/proto/proto_core.c optional proto dev/pst/pst-iop.c optional pst dev/pst/pst-pci.c optional pst pci dev/pst/pst-raid.c optional pst dev/pty/pty.c optional pty dev/puc/puc.c optional puc dev/puc/puc_cfg.c optional puc dev/puc/puc_pccard.c optional puc pccard dev/puc/puc_pci.c optional puc pci dev/pwm/pwmc.c optional pwm | pwmc dev/pwm/pwmbus.c optional pwm | pwmbus dev/pwm/pwmbus_if.m optional pwm | pwmbus dev/pwm/ofw_pwm.c optional pwm fdt | pwmbus fdt dev/pwm/ofw_pwmbus.c optional pwm fdt | pwmbus fdt dev/quicc/quicc_core.c optional quicc dev/ral/rt2560.c optional ral dev/ral/rt2661.c optional ral dev/ral/rt2860.c optional ral dev/ral/if_ral_pci.c optional ral pci rt2561fw.c optional rt2561fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561.fw:rt2561fw -mrt2561 -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2561fw.c" rt2561fw.fwo optional rt2561fw | ralfw \ dependency "rt2561.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561fw.fwo" rt2561.fw optional rt2561fw | ralfw \ dependency "$S/contrib/dev/ral/rt2561.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561.fw" rt2561sfw.c optional rt2561sfw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561s.fw:rt2561sfw -mrt2561s -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2561sfw.c" rt2561sfw.fwo optional rt2561sfw | ralfw \ dependency "rt2561s.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561sfw.fwo" rt2561s.fw optional rt2561sfw | ralfw \ dependency "$S/contrib/dev/ral/rt2561s.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561s.fw" rt2661fw.c optional rt2661fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2661.fw:rt2661fw -mrt2661 -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2661fw.c" rt2661fw.fwo optional rt2661fw | ralfw \ dependency "rt2661.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2661fw.fwo" rt2661.fw optional rt2661fw | ralfw \ dependency "$S/contrib/dev/ral/rt2661.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2661.fw" rt2860fw.c optional rt2860fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2860.fw:rt2860fw -mrt2860 -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2860fw.c" rt2860fw.fwo optional rt2860fw | ralfw \ dependency "rt2860.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2860fw.fwo" rt2860.fw optional rt2860fw | ralfw \ dependency "$S/contrib/dev/ral/rt2860.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2860.fw" dev/random/random_infra.c standard dev/random/random_harvestq.c standard dev/random/randomdev.c optional !random_loadable dev/random/fortuna.c optional !random_loadable dev/random/hash.c optional !random_loadable dev/rc/rc.c optional rc dev/rccgpio/rccgpio.c optional rccgpio gpio dev/re/if_re.c optional re dev/rl/if_rl.c optional rl pci dev/rndtest/rndtest.c optional rndtest dev/rp/rp.c optional rp dev/rp/rp_isa.c optional rp isa dev/rp/rp_pci.c optional rp pci # dev/rtwn/if_rtwn.c optional rtwn dev/rtwn/if_rtwn_beacon.c optional rtwn dev/rtwn/if_rtwn_calib.c optional rtwn dev/rtwn/if_rtwn_cam.c optional rtwn dev/rtwn/if_rtwn_efuse.c optional rtwn dev/rtwn/if_rtwn_fw.c optional rtwn dev/rtwn/if_rtwn_rx.c optional rtwn dev/rtwn/if_rtwn_task.c optional rtwn dev/rtwn/if_rtwn_tx.c optional rtwn # dev/rtwn/pci/rtwn_pci_attach.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_reg.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_rx.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_tx.c optional rtwn_pci pci # dev/rtwn/usb/rtwn_usb_attach.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_ep.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_reg.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_rx.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_tx.c optional rtwn_usb # RTL8188E dev/rtwn/rtl8188e/r88e_beacon.c optional rtwn dev/rtwn/rtl8188e/r88e_calib.c optional rtwn dev/rtwn/rtl8188e/r88e_chan.c optional rtwn dev/rtwn/rtl8188e/r88e_fw.c optional rtwn dev/rtwn/rtl8188e/r88e_init.c optional rtwn dev/rtwn/rtl8188e/r88e_led.c optional rtwn dev/rtwn/rtl8188e/r88e_tx.c optional rtwn dev/rtwn/rtl8188e/r88e_rf.c optional rtwn dev/rtwn/rtl8188e/r88e_rom.c optional rtwn dev/rtwn/rtl8188e/r88e_rx.c optional rtwn dev/rtwn/rtl8188e/pci/r88ee_attach.c optional rtwn_pci pci dev/rtwn/rtl8188e/pci/r88ee_init.c optional rtwn_pci pci dev/rtwn/rtl8188e/pci/r88ee_rx.c optional rtwn_pci pci dev/rtwn/rtl8188e/usb/r88eu_attach.c optional rtwn_usb dev/rtwn/rtl8188e/usb/r88eu_init.c optional rtwn_usb # RTL8192C dev/rtwn/rtl8192c/r92c_attach.c optional rtwn dev/rtwn/rtl8192c/r92c_beacon.c optional rtwn dev/rtwn/rtl8192c/r92c_calib.c optional rtwn dev/rtwn/rtl8192c/r92c_chan.c optional rtwn dev/rtwn/rtl8192c/r92c_fw.c optional rtwn dev/rtwn/rtl8192c/r92c_init.c optional rtwn dev/rtwn/rtl8192c/r92c_llt.c optional rtwn dev/rtwn/rtl8192c/r92c_rf.c optional rtwn dev/rtwn/rtl8192c/r92c_rom.c optional rtwn dev/rtwn/rtl8192c/r92c_rx.c optional rtwn dev/rtwn/rtl8192c/r92c_tx.c optional rtwn dev/rtwn/rtl8192c/pci/r92ce_attach.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_calib.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_fw.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_init.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_led.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_rx.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_tx.c optional rtwn_pci pci dev/rtwn/rtl8192c/usb/r92cu_attach.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_init.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_led.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_rx.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_tx.c optional rtwn_usb # RTL8192E dev/rtwn/rtl8192e/r92e_chan.c optional rtwn dev/rtwn/rtl8192e/r92e_fw.c optional rtwn dev/rtwn/rtl8192e/r92e_init.c optional rtwn dev/rtwn/rtl8192e/r92e_led.c optional rtwn dev/rtwn/rtl8192e/r92e_rf.c optional rtwn dev/rtwn/rtl8192e/r92e_rom.c optional rtwn dev/rtwn/rtl8192e/r92e_rx.c optional rtwn dev/rtwn/rtl8192e/usb/r92eu_attach.c optional rtwn_usb dev/rtwn/rtl8192e/usb/r92eu_init.c optional rtwn_usb # RTL8812A dev/rtwn/rtl8812a/r12a_beacon.c optional rtwn dev/rtwn/rtl8812a/r12a_calib.c optional rtwn dev/rtwn/rtl8812a/r12a_caps.c optional rtwn dev/rtwn/rtl8812a/r12a_chan.c optional rtwn dev/rtwn/rtl8812a/r12a_fw.c optional rtwn dev/rtwn/rtl8812a/r12a_init.c optional rtwn dev/rtwn/rtl8812a/r12a_led.c optional rtwn dev/rtwn/rtl8812a/r12a_rf.c optional rtwn dev/rtwn/rtl8812a/r12a_rom.c optional rtwn dev/rtwn/rtl8812a/r12a_rx.c optional rtwn dev/rtwn/rtl8812a/r12a_tx.c optional rtwn dev/rtwn/rtl8812a/usb/r12au_attach.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_init.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_rx.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_tx.c optional rtwn_usb # RTL8821A dev/rtwn/rtl8821a/r21a_beacon.c optional rtwn dev/rtwn/rtl8821a/r21a_calib.c optional rtwn dev/rtwn/rtl8821a/r21a_chan.c optional rtwn dev/rtwn/rtl8821a/r21a_fw.c optional rtwn dev/rtwn/rtl8821a/r21a_init.c optional rtwn dev/rtwn/rtl8821a/r21a_led.c optional rtwn dev/rtwn/rtl8821a/r21a_rom.c optional rtwn dev/rtwn/rtl8821a/r21a_rx.c optional rtwn dev/rtwn/rtl8821a/usb/r21au_attach.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_dfs.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_init.c optional rtwn_usb rtwn-rtl8188eefw.c optional rtwn-rtl8188eefw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eefw.fw:rtwn-rtl8188eefw:111 -mrtwn-rtl8188eefw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8188eefw.c" rtwn-rtl8188eefw.fwo optional rtwn-rtl8188eefw | rtwnfw \ dependency "rtwn-rtl8188eefw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eefw.fwo" rtwn-rtl8188eefw.fw optional rtwn-rtl8188eefw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eefw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eefw.fw" rtwn-rtl8188eufw.c optional rtwn-rtl8188eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eufw.fw:rtwn-rtl8188eufw:111 -mrtwn-rtl8188eufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8188eufw.c" rtwn-rtl8188eufw.fwo optional rtwn-rtl8188eufw | rtwnfw \ dependency "rtwn-rtl8188eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eufw.fwo" rtwn-rtl8188eufw.fw optional rtwn-rtl8188eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eufw.fw" rtwn-rtl8192cfwE.c optional rtwn-rtl8192cfwE | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE.fw:rtwn-rtl8192cfwE:111 -mrtwn-rtl8192cfwE -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE.c" rtwn-rtl8192cfwE.fwo optional rtwn-rtl8192cfwE | rtwnfw \ dependency "rtwn-rtl8192cfwE.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE.fwo" rtwn-rtl8192cfwE.fw optional rtwn-rtl8192cfwE | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE.fw" rtwn-rtl8192cfwE_B.c optional rtwn-rtl8192cfwE_B | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE_B.fw:rtwn-rtl8192cfwE_B:111 -mrtwn-rtl8192cfwE_B -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE_B.c" rtwn-rtl8192cfwE_B.fwo optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "rtwn-rtl8192cfwE_B.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fwo" rtwn-rtl8192cfwE_B.fw optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE_B.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fw" rtwn-rtl8192cfwT.c optional rtwn-rtl8192cfwT | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwT.fw:rtwn-rtl8192cfwT:111 -mrtwn-rtl8192cfwT -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwT.c" rtwn-rtl8192cfwT.fwo optional rtwn-rtl8192cfwT | rtwnfw \ dependency "rtwn-rtl8192cfwT.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwT.fwo" rtwn-rtl8192cfwT.fw optional rtwn-rtl8192cfwT | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwT.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwT.fw" rtwn-rtl8192cfwU.c optional rtwn-rtl8192cfwU | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwU.fw:rtwn-rtl8192cfwU:111 -mrtwn-rtl8192cfwU -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwU.c" rtwn-rtl8192cfwU.fwo optional rtwn-rtl8192cfwU | rtwnfw \ dependency "rtwn-rtl8192cfwU.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwU.fwo" rtwn-rtl8192cfwU.fw optional rtwn-rtl8192cfwU | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwU.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwU.fw" rtwn-rtl8192eufw.c optional rtwn-rtl8192eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192eufw.fw:rtwn-rtl8192eufw:111 -mrtwn-rtl8192eufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192eufw.c" rtwn-rtl8192eufw.fwo optional rtwn-rtl8192eufw | rtwnfw \ dependency "rtwn-rtl8192eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192eufw.fwo" rtwn-rtl8192eufw.fw optional rtwn-rtl8192eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192eufw.fw" rtwn-rtl8812aufw.c optional rtwn-rtl8812aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8812aufw.fw:rtwn-rtl8812aufw:111 -mrtwn-rtl8812aufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8812aufw.c" rtwn-rtl8812aufw.fwo optional rtwn-rtl8812aufw | rtwnfw \ dependency "rtwn-rtl8812aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8812aufw.fwo" rtwn-rtl8812aufw.fw optional rtwn-rtl8812aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8812aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8812aufw.fw" rtwn-rtl8821aufw.c optional rtwn-rtl8821aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8821aufw.fw:rtwn-rtl8821aufw:111 -mrtwn-rtl8821aufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8821aufw.c" rtwn-rtl8821aufw.fwo optional rtwn-rtl8821aufw | rtwnfw \ dependency "rtwn-rtl8821aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8821aufw.fwo" rtwn-rtl8821aufw.fw optional rtwn-rtl8821aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8821aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8821aufw.fw" dev/safe/safe.c optional safe dev/scc/scc_if.m optional scc dev/scc/scc_bfe_ebus.c optional scc ebus dev/scc/scc_bfe_quicc.c optional scc quicc dev/scc/scc_bfe_sbus.c optional scc fhc | scc sbus dev/scc/scc_core.c optional scc dev/scc/scc_dev_quicc.c optional scc quicc dev/scc/scc_dev_sab82532.c optional scc dev/scc/scc_dev_z8530.c optional scc dev/sdhci/sdhci.c optional sdhci dev/sdhci/sdhci_fdt.c optional sdhci fdt dev/sdhci/sdhci_fdt_gpio.c optional sdhci fdt gpio dev/sdhci/sdhci_if.m optional sdhci dev/sdhci/sdhci_acpi.c optional sdhci acpi dev/sdhci/sdhci_pci.c optional sdhci pci dev/sdio/sdio_if.m optional mmccam dev/sdio/sdio_subr.c optional mmccam dev/sdio/sdiob.c optional mmccam dev/sge/if_sge.c optional sge pci dev/siis/siis.c optional siis pci dev/sis/if_sis.c optional sis pci dev/sk/if_sk.c optional sk pci dev/smbus/smb.c optional smb dev/smbus/smbconf.c optional smbus dev/smbus/smbus.c optional smbus dev/smbus/smbus_if.m optional smbus dev/smc/if_smc.c optional smc dev/smc/if_smc_fdt.c optional smc fdt dev/snp/snp.c optional snp dev/sound/clone.c optional sound dev/sound/unit.c optional sound dev/sound/isa/ad1816.c optional snd_ad1816 isa dev/sound/isa/ess.c optional snd_ess isa dev/sound/isa/gusc.c optional snd_gusc isa dev/sound/isa/mss.c optional snd_mss isa dev/sound/isa/sb16.c optional snd_sb16 isa dev/sound/isa/sb8.c optional snd_sb8 isa dev/sound/isa/sbc.c optional snd_sbc isa dev/sound/isa/sndbuf_dma.c optional sound isa dev/sound/pci/als4000.c optional snd_als4000 pci dev/sound/pci/atiixp.c optional snd_atiixp pci dev/sound/pci/cmi.c optional snd_cmi pci dev/sound/pci/cs4281.c optional snd_cs4281 pci dev/sound/pci/csa.c optional snd_csa pci dev/sound/pci/csapcm.c optional snd_csa pci dev/sound/pci/ds1.c optional snd_ds1 pci dev/sound/pci/emu10k1.c optional snd_emu10k1 pci dev/sound/pci/emu10kx.c optional snd_emu10kx pci dev/sound/pci/emu10kx-pcm.c optional snd_emu10kx pci dev/sound/pci/emu10kx-midi.c optional snd_emu10kx pci dev/sound/pci/envy24.c optional snd_envy24 pci dev/sound/pci/envy24ht.c optional snd_envy24ht pci dev/sound/pci/es137x.c optional snd_es137x pci dev/sound/pci/fm801.c optional snd_fm801 pci dev/sound/pci/ich.c optional snd_ich pci dev/sound/pci/maestro.c optional snd_maestro pci dev/sound/pci/maestro3.c optional snd_maestro3 pci dev/sound/pci/neomagic.c optional snd_neomagic pci dev/sound/pci/solo.c optional snd_solo pci dev/sound/pci/spicds.c optional snd_spicds pci dev/sound/pci/t4dwave.c optional snd_t4dwave pci dev/sound/pci/via8233.c optional snd_via8233 pci dev/sound/pci/via82c686.c optional snd_via82c686 pci dev/sound/pci/vibes.c optional snd_vibes pci dev/sound/pci/hda/hdaa.c optional snd_hda pci dev/sound/pci/hda/hdaa_patches.c optional snd_hda pci dev/sound/pci/hda/hdac.c optional snd_hda pci dev/sound/pci/hda/hdac_if.m optional snd_hda pci dev/sound/pci/hda/hdacc.c optional snd_hda pci dev/sound/pci/hdspe.c optional snd_hdspe pci dev/sound/pci/hdspe-pcm.c optional snd_hdspe pci dev/sound/pcm/ac97.c optional sound dev/sound/pcm/ac97_if.m optional sound dev/sound/pcm/ac97_patch.c optional sound dev/sound/pcm/buffer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/channel.c optional sound dev/sound/pcm/channel_if.m optional sound dev/sound/pcm/dsp.c optional sound dev/sound/pcm/feeder.c optional sound dev/sound/pcm/feeder_chain.c optional sound dev/sound/pcm/feeder_eq.c optional sound \ dependency "feeder_eq_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_if.m optional sound dev/sound/pcm/feeder_format.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_matrix.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_mixer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_rate.c optional sound \ dependency "feeder_rate_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_volume.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/mixer.c optional sound dev/sound/pcm/mixer_if.m optional sound dev/sound/pcm/sndstat.c optional sound dev/sound/pcm/sound.c optional sound dev/sound/pcm/vchan.c optional sound dev/sound/usb/uaudio.c optional snd_uaudio usb dev/sound/usb/uaudio_pcm.c optional snd_uaudio usb dev/sound/midi/midi.c optional sound dev/sound/midi/mpu401.c optional sound dev/sound/midi/mpu_if.m optional sound dev/sound/midi/mpufoi_if.m optional sound dev/sound/midi/sequencer.c optional sound dev/sound/midi/synth_if.m optional sound dev/spibus/ofw_spibus.c optional fdt spibus dev/spibus/spibus.c optional spibus \ dependency "spibus_if.h" dev/spibus/spigen.c optional spigen dev/spibus/spibus_if.m optional spibus dev/ste/if_ste.c optional ste pci dev/stge/if_stge.c optional stge dev/sym/sym_hipd.c optional sym \ dependency "$S/dev/sym/sym_{conf,defs}.h" dev/syscons/blank/blank_saver.c optional blank_saver dev/syscons/daemon/daemon_saver.c optional daemon_saver dev/syscons/dragon/dragon_saver.c optional dragon_saver dev/syscons/fade/fade_saver.c optional fade_saver dev/syscons/fire/fire_saver.c optional fire_saver dev/syscons/green/green_saver.c optional green_saver dev/syscons/logo/logo.c optional logo_saver dev/syscons/logo/logo_saver.c optional logo_saver dev/syscons/rain/rain_saver.c optional rain_saver dev/syscons/schistory.c optional sc dev/syscons/scmouse.c optional sc dev/syscons/scterm.c optional sc dev/syscons/scterm-dumb.c optional sc !SC_NO_TERM_DUMB dev/syscons/scterm-sc.c optional sc !SC_NO_TERM_SC dev/syscons/scterm-teken.c optional sc !SC_NO_TERM_TEKEN dev/syscons/scvidctl.c optional sc dev/syscons/scvtb.c optional sc dev/syscons/snake/snake_saver.c optional snake_saver dev/syscons/star/star_saver.c optional star_saver dev/syscons/syscons.c optional sc dev/syscons/sysmouse.c optional sc dev/syscons/warp/warp_saver.c optional warp_saver dev/tcp_log/tcp_log_dev.c optional tcp_blackbox inet | tcp_blackbox inet6 dev/tdfx/tdfx_linux.c optional tdfx_linux tdfx compat_linux dev/tdfx/tdfx_pci.c optional tdfx pci dev/ti/if_ti.c optional ti pci dev/trm/trm.c optional trm dev/twa/tw_cl_init.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_intr.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_io.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_misc.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_osl_cam.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_osl_freebsd.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twe/twe.c optional twe dev/twe/twe_freebsd.c optional twe dev/tws/tws.c optional tws dev/tws/tws_cam.c optional tws dev/tws/tws_hdm.c optional tws dev/tws/tws_services.c optional tws dev/tws/tws_user.c optional tws dev/uart/uart_bus_acpi.c optional uart acpi dev/uart/uart_bus_ebus.c optional uart ebus dev/uart/uart_bus_fdt.c optional uart fdt dev/uart/uart_bus_isa.c optional uart isa dev/uart/uart_bus_pccard.c optional uart pccard dev/uart/uart_bus_pci.c optional uart pci dev/uart/uart_bus_puc.c optional uart puc dev/uart/uart_bus_scc.c optional uart scc dev/uart/uart_core.c optional uart dev/uart/uart_cpu_acpi.c optional uart acpi dev/uart/uart_dbg.c optional uart gdb dev/uart/uart_dev_msm.c optional uart uart_msm fdt dev/uart/uart_dev_mvebu.c optional uart uart_mvebu dev/uart/uart_dev_ns8250.c optional uart uart_ns8250 | uart uart_snps dev/uart/uart_dev_pl011.c optional uart pl011 dev/uart/uart_dev_quicc.c optional uart quicc dev/uart/uart_dev_sab82532.c optional uart uart_sab82532 dev/uart/uart_dev_sab82532.c optional uart scc dev/uart/uart_dev_snps.c optional uart uart_snps fdt dev/uart/uart_dev_z8530.c optional uart uart_z8530 dev/uart/uart_dev_z8530.c optional uart scc dev/uart/uart_if.m optional uart dev/uart/uart_subr.c optional uart dev/uart/uart_tty.c optional uart dev/ubsec/ubsec.c optional ubsec # # USB controller drivers # dev/usb/controller/musb_otg.c optional musb dev/usb/controller/dwc_otg.c optional dwcotg dev/usb/controller/dwc_otg_fdt.c optional dwcotg fdt dev/usb/controller/ehci.c optional ehci dev/usb/controller/ehci_msm.c optional ehci_msm fdt dev/usb/controller/ehci_pci.c optional ehci pci dev/usb/controller/ohci.c optional ohci dev/usb/controller/ohci_pci.c optional ohci pci dev/usb/controller/uhci.c optional uhci dev/usb/controller/uhci_pci.c optional uhci pci dev/usb/controller/xhci.c optional xhci dev/usb/controller/xhci_pci.c optional xhci pci dev/usb/controller/saf1761_otg.c optional saf1761otg dev/usb/controller/saf1761_otg_fdt.c optional saf1761otg fdt dev/usb/controller/uss820dci.c optional uss820dci dev/usb/controller/usb_controller.c optional usb # # USB storage drivers # dev/usb/storage/cfumass.c optional cfumass ctl dev/usb/storage/umass.c optional umass dev/usb/storage/urio.c optional urio dev/usb/storage/ustorage_fs.c optional usfs # # USB core # dev/usb/usb_busdma.c optional usb dev/usb/usb_core.c optional usb dev/usb/usb_debug.c optional usb dev/usb/usb_dev.c optional usb dev/usb/usb_device.c optional usb dev/usb/usb_dynamic.c optional usb dev/usb/usb_error.c optional usb dev/usb/usb_fdt_support.c optional usb fdt dev/usb/usb_generic.c optional usb dev/usb/usb_handle_request.c optional usb dev/usb/usb_hid.c optional usb dev/usb/usb_hub.c optional usb dev/usb/usb_hub_acpi.c optional usb acpi dev/usb/usb_if.m optional usb dev/usb/usb_lookup.c optional usb dev/usb/usb_mbuf.c optional usb dev/usb/usb_msctest.c optional usb dev/usb/usb_parse.c optional usb dev/usb/usb_pf.c optional usb dev/usb/usb_process.c optional usb dev/usb/usb_request.c optional usb dev/usb/usb_transfer.c optional usb dev/usb/usb_util.c optional usb # # USB network drivers # dev/usb/net/if_aue.c optional aue dev/usb/net/if_axe.c optional axe dev/usb/net/if_axge.c optional axge dev/usb/net/if_cdce.c optional cdce dev/usb/net/if_cue.c optional cue dev/usb/net/if_ipheth.c optional ipheth dev/usb/net/if_kue.c optional kue dev/usb/net/if_mos.c optional mos dev/usb/net/if_muge.c optional muge dev/usb/net/if_rue.c optional rue dev/usb/net/if_smsc.c optional smsc dev/usb/net/if_udav.c optional udav dev/usb/net/if_ure.c optional ure dev/usb/net/if_usie.c optional usie dev/usb/net/if_urndis.c optional urndis dev/usb/net/ruephy.c optional rue dev/usb/net/usb_ethernet.c optional uether | aue | axe | axge | cdce | \ cue | ipheth | kue | mos | rue | \ smsc | udav | ure | urndis | muge dev/usb/net/uhso.c optional uhso # # USB WLAN drivers # dev/usb/wlan/if_rsu.c optional rsu rsu-rtl8712fw.c optional rsu-rtl8712fw | rsufw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rsu-rtl8712fw.fw:rsu-rtl8712fw:120 -mrsu-rtl8712fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rsu-rtl8712fw.c" rsu-rtl8712fw.fwo optional rsu-rtl8712fw | rsufw \ dependency "rsu-rtl8712fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rsu-rtl8712fw.fwo" rsu-rtl8712fw.fw optional rsu-rtl8712.fw | rsufw \ dependency "$S/contrib/dev/rsu/rsu-rtl8712fw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rsu-rtl8712fw.fw" dev/usb/wlan/if_rum.c optional rum dev/usb/wlan/if_run.c optional run runfw.c optional runfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk run.fw:runfw -mrunfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "runfw.c" runfw.fwo optional runfw \ dependency "run.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "runfw.fwo" run.fw optional runfw \ dependency "$S/contrib/dev/run/rt2870.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "run.fw" dev/usb/wlan/if_uath.c optional uath dev/usb/wlan/if_upgt.c optional upgt dev/usb/wlan/if_ural.c optional ural dev/usb/wlan/if_urtw.c optional urtw dev/usb/wlan/if_zyd.c optional zyd # # USB serial and parallel port drivers # dev/usb/serial/u3g.c optional u3g dev/usb/serial/uark.c optional uark dev/usb/serial/ubsa.c optional ubsa dev/usb/serial/ubser.c optional ubser dev/usb/serial/uchcom.c optional uchcom dev/usb/serial/ucycom.c optional ucycom dev/usb/serial/ufoma.c optional ufoma dev/usb/serial/uftdi.c optional uftdi dev/usb/serial/ugensa.c optional ugensa dev/usb/serial/uipaq.c optional uipaq dev/usb/serial/ulpt.c optional ulpt dev/usb/serial/umcs.c optional umcs dev/usb/serial/umct.c optional umct dev/usb/serial/umodem.c optional umodem dev/usb/serial/umoscom.c optional umoscom dev/usb/serial/uplcom.c optional uplcom dev/usb/serial/uslcom.c optional uslcom dev/usb/serial/uvisor.c optional uvisor dev/usb/serial/uvscom.c optional uvscom dev/usb/serial/usb_serial.c optional ucom | u3g | uark | ubsa | ubser | \ uchcom | ucycom | ufoma | uftdi | \ ugensa | uipaq | umcs | umct | \ umodem | umoscom | uplcom | usie | \ uslcom | uvisor | uvscom # # USB misc drivers # dev/usb/misc/ufm.c optional ufm dev/usb/misc/udbp.c optional udbp dev/usb/misc/ugold.c optional ugold dev/usb/misc/uled.c optional uled # # USB input drivers # dev/usb/input/atp.c optional atp dev/usb/input/uep.c optional uep dev/usb/input/uhid.c optional uhid dev/usb/input/uhid_snes.c optional uhid_snes dev/usb/input/ukbd.c optional ukbd dev/usb/input/ums.c optional ums dev/usb/input/wmt.c optional wmt dev/usb/input/wsp.c optional wsp # # USB quirks # dev/usb/quirk/usb_quirk.c optional usb # # USB templates # dev/usb/template/usb_template.c optional usb_template dev/usb/template/usb_template_audio.c optional usb_template dev/usb/template/usb_template_cdce.c optional usb_template dev/usb/template/usb_template_kbd.c optional usb_template dev/usb/template/usb_template_modem.c optional usb_template dev/usb/template/usb_template_mouse.c optional usb_template dev/usb/template/usb_template_msc.c optional usb_template dev/usb/template/usb_template_mtp.c optional usb_template dev/usb/template/usb_template_phone.c optional usb_template dev/usb/template/usb_template_serialnet.c optional usb_template dev/usb/template/usb_template_midi.c optional usb_template dev/usb/template/usb_template_multi.c optional usb_template # # USB video drivers # dev/usb/video/udl.c optional udl # # USB END # dev/videomode/videomode.c optional videomode dev/videomode/edid.c optional videomode dev/videomode/pickmode.c optional videomode dev/videomode/vesagtf.c optional videomode dev/veriexec/verified_exec.c optional veriexec mac_veriexec dev/vge/if_vge.c optional vge dev/viapm/viapm.c optional viapm pci dev/virtio/virtio.c optional virtio dev/virtio/virtqueue.c optional virtio dev/virtio/virtio_bus_if.m optional virtio dev/virtio/virtio_if.m optional virtio dev/virtio/pci/virtio_pci.c optional virtio_pci dev/virtio/mmio/virtio_mmio.c optional virtio_mmio dev/virtio/mmio/virtio_mmio_acpi.c optional virtio_mmio acpi dev/virtio/mmio/virtio_mmio_fdt.c optional virtio_mmio fdt dev/virtio/mmio/virtio_mmio_if.m optional virtio_mmio dev/virtio/network/if_vtnet.c optional vtnet dev/virtio/block/virtio_blk.c optional virtio_blk dev/virtio/balloon/virtio_balloon.c optional virtio_balloon dev/virtio/scsi/virtio_scsi.c optional virtio_scsi dev/virtio/random/virtio_random.c optional virtio_random dev/virtio/console/virtio_console.c optional virtio_console dev/vkbd/vkbd.c optional vkbd dev/vr/if_vr.c optional vr pci dev/vt/colors/vt_termcolors.c optional vt dev/vt/font/vt_font_default.c optional vt dev/vt/font/vt_mouse_cursor.c optional vt dev/vt/hw/efifb/efifb.c optional vt_efifb dev/vt/hw/fb/vt_fb.c optional vt dev/vt/hw/vga/vt_vga.c optional vt vt_vga dev/vt/logo/logo_freebsd.c optional vt splash dev/vt/logo/logo_beastie.c optional vt splash dev/vt/vt_buf.c optional vt dev/vt/vt_consolectl.c optional vt dev/vt/vt_core.c optional vt dev/vt/vt_cpulogos.c optional vt splash dev/vt/vt_font.c optional vt dev/vt/vt_sysmouse.c optional vt dev/vte/if_vte.c optional vte pci dev/vx/if_vx.c optional vx dev/vx/if_vx_pci.c optional vx pci dev/watchdog/watchdog.c standard dev/wi/if_wi.c optional wi dev/wi/if_wi_pccard.c optional wi pccard dev/wi/if_wi_pci.c optional wi pci dev/wpi/if_wpi.c optional wpi pci wpifw.c optional wpifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:153229 -mwpi -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "wpifw.c" wpifw.fwo optional wpifw \ dependency "wpi.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "wpifw.fwo" wpi.fw optional wpifw \ dependency "$S/contrib/dev/wpi/iwlwifi-3945-15.32.2.9.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "wpi.fw" dev/xdma/controller/pl330.c optional xdma pl330 dev/xdma/xdma.c optional xdma dev/xdma/xdma_bank.c optional xdma dev/xdma/xdma_bio.c optional xdma dev/xdma/xdma_fdt_test.c optional xdma xdma_test fdt dev/xdma/xdma_if.m optional xdma dev/xdma/xdma_mbuf.c optional xdma dev/xdma/xdma_queue.c optional xdma dev/xdma/xdma_sg.c optional xdma dev/xdma/xdma_sglist.c optional xdma dev/xen/balloon/balloon.c optional xenhvm dev/xen/blkfront/blkfront.c optional xenhvm dev/xen/blkback/blkback.c optional xenhvm dev/xen/console/xen_console.c optional xenhvm dev/xen/control/control.c optional xenhvm dev/xen/grant_table/grant_table.c optional xenhvm dev/xen/netback/netback.c optional xenhvm dev/xen/netfront/netfront.c optional xenhvm dev/xen/xenpci/xenpci.c optional xenpci dev/xen/timer/timer.c optional xenhvm dev/xen/pvcpu/pvcpu.c optional xenhvm dev/xen/xenstore/xenstore.c optional xenhvm dev/xen/xenstore/xenstore_dev.c optional xenhvm dev/xen/xenstore/xenstored_dev.c optional xenhvm dev/xen/evtchn/evtchn_dev.c optional xenhvm dev/xen/privcmd/privcmd.c optional xenhvm dev/xen/gntdev/gntdev.c optional xenhvm dev/xen/debug/debug.c optional xenhvm dev/xl/if_xl.c optional xl pci dev/xl/xlphy.c optional xl pci fs/autofs/autofs.c optional autofs fs/autofs/autofs_vfsops.c optional autofs fs/autofs/autofs_vnops.c optional autofs fs/deadfs/dead_vnops.c standard fs/devfs/devfs_devs.c standard fs/devfs/devfs_dir.c standard fs/devfs/devfs_rule.c standard fs/devfs/devfs_vfsops.c standard fs/devfs/devfs_vnops.c standard fs/fdescfs/fdesc_vfsops.c optional fdescfs fs/fdescfs/fdesc_vnops.c optional fdescfs fs/fifofs/fifo_vnops.c standard fs/cuse/cuse.c optional cuse fs/fuse/fuse_device.c optional fusefs fs/fuse/fuse_file.c optional fusefs fs/fuse/fuse_internal.c optional fusefs fs/fuse/fuse_io.c optional fusefs fs/fuse/fuse_ipc.c optional fusefs fs/fuse/fuse_main.c optional fusefs fs/fuse/fuse_node.c optional fusefs fs/fuse/fuse_vfsops.c optional fusefs fs/fuse/fuse_vnops.c optional fusefs fs/msdosfs/msdosfs_conv.c optional msdosfs fs/msdosfs/msdosfs_denode.c optional msdosfs fs/msdosfs/msdosfs_fat.c optional msdosfs fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv fs/msdosfs/msdosfs_lookup.c optional msdosfs fs/msdosfs/msdosfs_vfsops.c optional msdosfs fs/msdosfs/msdosfs_vnops.c optional msdosfs -fs/nandfs/bmap.c optional nandfs -fs/nandfs/nandfs_alloc.c optional nandfs -fs/nandfs/nandfs_bmap.c optional nandfs -fs/nandfs/nandfs_buffer.c optional nandfs -fs/nandfs/nandfs_cleaner.c optional nandfs -fs/nandfs/nandfs_cpfile.c optional nandfs -fs/nandfs/nandfs_dat.c optional nandfs -fs/nandfs/nandfs_dir.c optional nandfs -fs/nandfs/nandfs_ifile.c optional nandfs -fs/nandfs/nandfs_segment.c optional nandfs -fs/nandfs/nandfs_subr.c optional nandfs -fs/nandfs/nandfs_sufile.c optional nandfs -fs/nandfs/nandfs_vfsops.c optional nandfs -fs/nandfs/nandfs_vnops.c optional nandfs fs/nfs/nfs_commonkrpc.c optional nfscl | nfsd fs/nfs/nfs_commonsubs.c optional nfscl | nfsd fs/nfs/nfs_commonport.c optional nfscl | nfsd fs/nfs/nfs_commonacl.c optional nfscl | nfsd fs/nfsclient/nfs_clcomsubs.c optional nfscl fs/nfsclient/nfs_clsubs.c optional nfscl fs/nfsclient/nfs_clstate.c optional nfscl fs/nfsclient/nfs_clkrpc.c optional nfscl fs/nfsclient/nfs_clrpcops.c optional nfscl fs/nfsclient/nfs_clvnops.c optional nfscl fs/nfsclient/nfs_clnode.c optional nfscl fs/nfsclient/nfs_clvfsops.c optional nfscl fs/nfsclient/nfs_clport.c optional nfscl fs/nfsclient/nfs_clbio.c optional nfscl fs/nfsclient/nfs_clnfsiod.c optional nfscl fs/nfsserver/nfs_fha_new.c optional nfsd inet fs/nfsserver/nfs_nfsdsocket.c optional nfsd inet fs/nfsserver/nfs_nfsdsubs.c optional nfsd inet fs/nfsserver/nfs_nfsdstate.c optional nfsd inet fs/nfsserver/nfs_nfsdkrpc.c optional nfsd inet fs/nfsserver/nfs_nfsdserv.c optional nfsd inet fs/nfsserver/nfs_nfsdport.c optional nfsd inet fs/nfsserver/nfs_nfsdcache.c optional nfsd inet fs/nullfs/null_subr.c optional nullfs fs/nullfs/null_vfsops.c optional nullfs fs/nullfs/null_vnops.c optional nullfs fs/procfs/procfs.c optional procfs fs/procfs/procfs_dbregs.c optional procfs fs/procfs/procfs_fpregs.c optional procfs fs/procfs/procfs_ioctl.c optional procfs fs/procfs/procfs_map.c optional procfs fs/procfs/procfs_mem.c optional procfs fs/procfs/procfs_note.c optional procfs fs/procfs/procfs_osrel.c optional procfs fs/procfs/procfs_regs.c optional procfs fs/procfs/procfs_rlimit.c optional procfs fs/procfs/procfs_status.c optional procfs fs/procfs/procfs_type.c optional procfs fs/pseudofs/pseudofs.c optional pseudofs fs/pseudofs/pseudofs_fileno.c optional pseudofs fs/pseudofs/pseudofs_vncache.c optional pseudofs fs/pseudofs/pseudofs_vnops.c optional pseudofs fs/smbfs/smbfs_io.c optional smbfs fs/smbfs/smbfs_node.c optional smbfs fs/smbfs/smbfs_smb.c optional smbfs fs/smbfs/smbfs_subr.c optional smbfs fs/smbfs/smbfs_vfsops.c optional smbfs fs/smbfs/smbfs_vnops.c optional smbfs fs/udf/osta.c optional udf fs/udf/udf_iconv.c optional udf_iconv fs/udf/udf_vfsops.c optional udf fs/udf/udf_vnops.c optional udf fs/unionfs/union_subr.c optional unionfs fs/unionfs/union_vfsops.c optional unionfs fs/unionfs/union_vnops.c optional unionfs fs/tmpfs/tmpfs_vnops.c optional tmpfs fs/tmpfs/tmpfs_fifoops.c optional tmpfs fs/tmpfs/tmpfs_vfsops.c optional tmpfs fs/tmpfs/tmpfs_subr.c optional tmpfs gdb/gdb_cons.c optional gdb gdb/gdb_main.c optional gdb gdb/gdb_packet.c optional gdb geom/bde/g_bde.c optional geom_bde geom/bde/g_bde_crypt.c optional geom_bde geom/bde/g_bde_lock.c optional geom_bde geom/bde/g_bde_work.c optional geom_bde geom/cache/g_cache.c optional geom_cache geom/concat/g_concat.c optional geom_concat geom/eli/g_eli.c optional geom_eli geom/eli/g_eli_crypto.c optional geom_eli geom/eli/g_eli_ctl.c optional geom_eli geom/eli/g_eli_hmac.c optional geom_eli geom/eli/g_eli_integrity.c optional geom_eli geom/eli/g_eli_key.c optional geom_eli geom/eli/g_eli_key_cache.c optional geom_eli geom/eli/g_eli_privacy.c optional geom_eli geom/eli/pkcs5v2.c optional geom_eli geom/gate/g_gate.c optional geom_gate geom/geom_bsd.c optional geom_bsd geom/geom_bsd_enc.c optional geom_bsd | geom_part_bsd geom/geom_ccd.c optional ccd | geom_ccd geom/geom_ctl.c standard geom/geom_dev.c standard geom/geom_disk.c standard geom/geom_dump.c standard geom/geom_event.c standard geom/geom_fox.c optional geom_fox -geom/geom_flashmap.c optional fdt cfi | fdt nand | fdt mx25l | mmcsd | fdt n25q | fdt at45d +geom/geom_flashmap.c optional fdt cfi | fdt mx25l | mmcsd | fdt n25q | fdt at45d geom/geom_io.c standard geom/geom_kern.c standard geom/geom_map.c optional geom_map geom/geom_mbr.c optional geom_mbr geom/geom_mbr_enc.c optional geom_mbr geom/geom_redboot.c optional geom_redboot geom/geom_slice.c standard geom/geom_subr.c standard geom/geom_sunlabel.c optional geom_sunlabel geom/geom_sunlabel_enc.c optional geom_sunlabel geom/geom_vfs.c standard geom/geom_vol_ffs.c optional geom_vol geom/journal/g_journal.c optional geom_journal geom/journal/g_journal_ufs.c optional geom_journal geom/label/g_label.c optional geom_label | geom_label_gpt geom/label/g_label_ext2fs.c optional geom_label geom/label/g_label_flashmap.c optional geom_label geom/label/g_label_iso9660.c optional geom_label geom/label/g_label_msdosfs.c optional geom_label geom/label/g_label_ntfs.c optional geom_label geom/label/g_label_reiserfs.c optional geom_label geom/label/g_label_ufs.c optional geom_label geom/label/g_label_gpt.c optional geom_label | geom_label_gpt geom/label/g_label_disk_ident.c optional geom_label geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm geom/mirror/g_mirror.c optional geom_mirror geom/mirror/g_mirror_ctl.c optional geom_mirror geom/mountver/g_mountver.c optional geom_mountver geom/multipath/g_multipath.c optional geom_multipath geom/nop/g_nop.c optional geom_nop geom/part/g_part.c standard geom/part/g_part_if.m standard geom/part/g_part_apm.c optional geom_part_apm geom/part/g_part_bsd.c optional geom_part_bsd geom/part/g_part_bsd64.c optional geom_part_bsd64 geom/part/g_part_ebr.c optional geom_part_ebr geom/part/g_part_gpt.c optional geom_part_gpt geom/part/g_part_ldm.c optional geom_part_ldm geom/part/g_part_mbr.c optional geom_part_mbr geom/part/g_part_vtoc8.c optional geom_part_vtoc8 geom/raid/g_raid.c optional geom_raid geom/raid/g_raid_ctl.c optional geom_raid geom/raid/g_raid_md_if.m optional geom_raid geom/raid/g_raid_tr_if.m optional geom_raid geom/raid/md_ddf.c optional geom_raid geom/raid/md_intel.c optional geom_raid geom/raid/md_jmicron.c optional geom_raid geom/raid/md_nvidia.c optional geom_raid geom/raid/md_promise.c optional geom_raid geom/raid/md_sii.c optional geom_raid geom/raid/tr_concat.c optional geom_raid geom/raid/tr_raid0.c optional geom_raid geom/raid/tr_raid1.c optional geom_raid geom/raid/tr_raid1e.c optional geom_raid geom/raid/tr_raid5.c optional geom_raid geom/raid3/g_raid3.c optional geom_raid3 geom/raid3/g_raid3_ctl.c optional geom_raid3 geom/shsec/g_shsec.c optional geom_shsec geom/stripe/g_stripe.c optional geom_stripe geom/uzip/g_uzip.c optional geom_uzip geom/uzip/g_uzip_lzma.c optional geom_uzip geom/uzip/g_uzip_wrkthr.c optional geom_uzip geom/uzip/g_uzip_zlib.c optional geom_uzip geom/vinum/geom_vinum.c optional geom_vinum geom/vinum/geom_vinum_create.c optional geom_vinum geom/vinum/geom_vinum_drive.c optional geom_vinum geom/vinum/geom_vinum_plex.c optional geom_vinum geom/vinum/geom_vinum_volume.c optional geom_vinum geom/vinum/geom_vinum_subr.c optional geom_vinum geom/vinum/geom_vinum_raid5.c optional geom_vinum geom/vinum/geom_vinum_share.c optional geom_vinum geom/vinum/geom_vinum_list.c optional geom_vinum geom/vinum/geom_vinum_rm.c optional geom_vinum geom/vinum/geom_vinum_init.c optional geom_vinum geom/vinum/geom_vinum_state.c optional geom_vinum geom/vinum/geom_vinum_rename.c optional geom_vinum geom/vinum/geom_vinum_move.c optional geom_vinum geom/vinum/geom_vinum_events.c optional geom_vinum geom/virstor/binstream.c optional geom_virstor geom/virstor/g_virstor.c optional geom_virstor geom/virstor/g_virstor_md.c optional geom_virstor geom/zero/g_zero.c optional geom_zero fs/ext2fs/ext2_acl.c optional ext2fs fs/ext2fs/ext2_alloc.c optional ext2fs fs/ext2fs/ext2_balloc.c optional ext2fs fs/ext2fs/ext2_bmap.c optional ext2fs fs/ext2fs/ext2_csum.c optional ext2fs fs/ext2fs/ext2_extattr.c optional ext2fs fs/ext2fs/ext2_extents.c optional ext2fs fs/ext2fs/ext2_inode.c optional ext2fs fs/ext2fs/ext2_inode_cnv.c optional ext2fs fs/ext2fs/ext2_hash.c optional ext2fs fs/ext2fs/ext2_htree.c optional ext2fs fs/ext2fs/ext2_lookup.c optional ext2fs fs/ext2fs/ext2_subr.c optional ext2fs fs/ext2fs/ext2_vfsops.c optional ext2fs fs/ext2fs/ext2_vnops.c optional ext2fs # isa/isa_if.m standard isa/isa_common.c optional isa isa/isahint.c optional isa isa/pnp.c optional isa isapnp isa/pnpparse.c optional isa isapnp fs/cd9660/cd9660_bmap.c optional cd9660 fs/cd9660/cd9660_lookup.c optional cd9660 fs/cd9660/cd9660_node.c optional cd9660 fs/cd9660/cd9660_rrip.c optional cd9660 fs/cd9660/cd9660_util.c optional cd9660 fs/cd9660/cd9660_vfsops.c optional cd9660 fs/cd9660/cd9660_vnops.c optional cd9660 fs/cd9660/cd9660_iconv.c optional cd9660_iconv gnu/gcov/gcc_4_7.c optional gcov \ warning "kernel contains GPL licensed gcov support" gnu/gcov/gcov_fs.c optional gcov lindebugfs \ compile-with "${LINUXKPI_C}" gnu/gcov/gcov_subr.c optional gcov kern/bus_if.m standard kern/clock_if.m standard kern/cpufreq_if.m standard kern/device_if.m standard kern/imgact_binmisc.c optional imagact_binmisc kern/imgact_elf.c standard kern/imgact_elf32.c optional compat_freebsd32 kern/imgact_shell.c standard kern/init_main.c standard kern/init_sysent.c standard kern/ksched.c optional _kposix_priority_scheduling kern/kern_acct.c standard kern/kern_alq.c optional alq kern/kern_clock.c standard kern/kern_condvar.c standard kern/kern_conf.c standard kern/kern_cons.c standard kern/kern_cpu.c standard kern/kern_cpuset.c standard kern/kern_context.c standard kern/kern_descrip.c standard kern/kern_dtrace.c optional kdtrace_hooks kern/kern_dump.c standard kern/kern_environment.c standard kern/kern_et.c standard kern/kern_event.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fail.c standard kern/kern_ffclock.c standard kern/kern_fork.c standard kern/kern_hhook.c standard kern/kern_idle.c standard kern/kern_intr.c standard kern/kern_jail.c standard kern/kern_kcov.c optional kcov \ compile-with "${NORMAL_C:N-fsanitize*}" kern/kern_khelp.c standard kern/kern_kthread.c standard kern/kern_ktr.c optional ktr kern/kern_ktrace.c standard kern/kern_linker.c standard kern/kern_lock.c standard kern/kern_lockf.c standard kern/kern_lockstat.c optional kdtrace_hooks kern/kern_loginclass.c standard kern/kern_malloc.c standard kern/kern_mbuf.c standard kern/kern_mib.c standard kern/kern_module.c standard kern/kern_mtxpool.c standard kern/kern_mutex.c standard kern/kern_ntptime.c standard kern/kern_osd.c standard kern/kern_physio.c standard kern/kern_pmc.c standard kern/kern_poll.c optional device_polling kern/kern_priv.c standard kern/kern_proc.c standard kern/kern_procctl.c standard kern/kern_prot.c standard kern/kern_racct.c standard kern/kern_rangelock.c standard kern/kern_rctl.c standard kern/kern_resource.c standard kern/kern_rmlock.c standard kern/kern_rwlock.c standard kern/kern_sdt.c optional kdtrace_hooks kern/kern_sema.c standard kern/kern_sendfile.c standard kern/kern_sharedpage.c standard kern/kern_shutdown.c standard kern/kern_sig.c standard kern/kern_switch.c standard kern/kern_sx.c standard kern/kern_synch.c standard kern/kern_syscalls.c standard kern/kern_sysctl.c standard kern/kern_tc.c standard kern/kern_thr.c standard kern/kern_thread.c standard kern/kern_time.c standard kern/kern_timeout.c standard kern/kern_tslog.c optional tslog kern/kern_ubsan.c optional kubsan kern/kern_umtx.c standard kern/kern_uuid.c standard kern/kern_xxx.c standard kern/link_elf.c standard kern/linker_if.m standard kern/md4c.c optional netsmb kern/md5c.c standard kern/p1003_1b.c standard kern/posix4_mib.c standard kern/sched_4bsd.c optional sched_4bsd kern/sched_ule.c optional sched_ule kern/serdev_if.m standard kern/stack_protector.c standard \ compile-with "${NORMAL_C:N-fstack-protector*}" kern/subr_acl_nfs4.c optional ufs_acl | zfs kern/subr_acl_posix1e.c optional ufs_acl kern/subr_autoconf.c standard kern/subr_blist.c standard kern/subr_boot.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard kern/subr_capability.c standard kern/subr_clock.c standard kern/subr_compressor.c standard \ compile-with "${NORMAL_C} -I$S/contrib/zstd/lib/freebsd" kern/subr_coverage.c optional coverage \ compile-with "${NORMAL_C:N-fsanitize*}" kern/subr_counter.c standard kern/subr_devstat.c standard kern/subr_disk.c standard kern/subr_early.c standard kern/subr_epoch.c standard kern/subr_eventhandler.c standard kern/subr_fattime.c standard kern/subr_firmware.c optional firmware kern/subr_gtaskqueue.c standard kern/subr_hash.c standard kern/subr_hints.c standard kern/subr_inflate.c optional gzip kern/subr_kdb.c standard kern/subr_kobj.c standard kern/subr_lock.c standard kern/subr_log.c standard kern/subr_mchain.c optional libmchain kern/subr_module.c standard kern/subr_msgbuf.c standard kern/subr_param.c standard kern/subr_pcpu.c standard kern/subr_pctrie.c standard kern/subr_pidctrl.c standard kern/subr_power.c standard kern/subr_prf.c standard kern/subr_prof.c standard kern/subr_rangeset.c standard kern/subr_rman.c standard kern/subr_rtc.c standard kern/subr_sbuf.c standard kern/subr_scanf.c standard kern/subr_sglist.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard kern/subr_stack.c optional ddb | stack | ktr kern/subr_taskqueue.c standard kern/subr_terminal.c optional vt kern/subr_trap.c standard kern/subr_turnstile.c standard kern/subr_uio.c standard kern/subr_unit.c standard kern/subr_vmem.c standard kern/subr_witness.c optional witness kern/sys_capability.c standard kern/sys_generic.c standard kern/sys_getrandom.c standard kern/sys_pipe.c standard kern/sys_procdesc.c standard kern/sys_process.c standard kern/sys_socket.c standard kern/syscalls.c standard kern/sysv_ipc.c standard kern/sysv_msg.c optional sysvmsg kern/sysv_sem.c optional sysvsem kern/sysv_shm.c optional sysvshm kern/tty.c standard kern/tty_compat.c optional compat_43tty kern/tty_info.c standard kern/tty_inq.c standard kern/tty_outq.c standard kern/tty_pts.c standard kern/tty_tty.c standard kern/tty_ttydisc.c standard kern/uipc_accf.c standard kern/uipc_debug.c optional ddb kern/uipc_domain.c standard kern/uipc_mbuf.c standard kern/uipc_mbuf2.c standard kern/uipc_mbufhash.c standard kern/uipc_mqueue.c optional p1003_1b_mqueue kern/uipc_sem.c optional p1003_1b_semaphores kern/uipc_shm.c standard kern/uipc_sockbuf.c standard kern/uipc_socket.c standard kern/uipc_syscalls.c standard kern/uipc_usrreq.c standard kern/vfs_acl.c standard kern/vfs_aio.c standard kern/vfs_bio.c standard kern/vfs_cache.c standard kern/vfs_cluster.c standard kern/vfs_default.c standard kern/vfs_export.c standard kern/vfs_extattr.c standard kern/vfs_hash.c standard kern/vfs_init.c standard kern/vfs_lookup.c standard kern/vfs_mount.c standard kern/vfs_mountroot.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard # # Kernel GSS-API # gssd.h optional kgssapi \ dependency "$S/kgssapi/gssd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/kgssapi/gssd.x | grep -v pthread.h > gssd.h" \ no-obj no-implicit-rule before-depend local \ clean "gssd.h" gssd_xdr.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/kgssapi/gssd.x -o gssd_xdr.c" \ no-implicit-rule before-depend local \ clean "gssd_xdr.c" gssd_clnt.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/kgssapi/gssd.x | grep -v string.h > gssd_clnt.c" \ no-implicit-rule before-depend local \ clean "gssd_clnt.c" kgssapi/gss_accept_sec_context.c optional kgssapi kgssapi/gss_add_oid_set_member.c optional kgssapi kgssapi/gss_acquire_cred.c optional kgssapi kgssapi/gss_canonicalize_name.c optional kgssapi kgssapi/gss_create_empty_oid_set.c optional kgssapi kgssapi/gss_delete_sec_context.c optional kgssapi kgssapi/gss_display_status.c optional kgssapi kgssapi/gss_export_name.c optional kgssapi kgssapi/gss_get_mic.c optional kgssapi kgssapi/gss_init_sec_context.c optional kgssapi kgssapi/gss_impl.c optional kgssapi kgssapi/gss_import_name.c optional kgssapi kgssapi/gss_names.c optional kgssapi kgssapi/gss_pname_to_uid.c optional kgssapi kgssapi/gss_release_buffer.c optional kgssapi kgssapi/gss_release_cred.c optional kgssapi kgssapi/gss_release_name.c optional kgssapi kgssapi/gss_release_oid_set.c optional kgssapi kgssapi/gss_set_cred_option.c optional kgssapi kgssapi/gss_test_oid_set_member.c optional kgssapi kgssapi/gss_unwrap.c optional kgssapi kgssapi/gss_verify_mic.c optional kgssapi kgssapi/gss_wrap.c optional kgssapi kgssapi/gss_wrap_size_limit.c optional kgssapi kgssapi/gssd_prot.c optional kgssapi kgssapi/krb5/krb5_mech.c optional kgssapi kgssapi/krb5/kcrypto.c optional kgssapi kgssapi/krb5/kcrypto_aes.c optional kgssapi kgssapi/krb5/kcrypto_arcfour.c optional kgssapi kgssapi/krb5/kcrypto_des.c optional kgssapi kgssapi/krb5/kcrypto_des3.c optional kgssapi kgssapi/kgss_if.m optional kgssapi kgssapi/gsstest.c optional kgssapi_debug # These files in libkern/ are those needed by all architectures. Some # of the files in libkern/ are only needed on some architectures, e.g., # libkern/divdi3.c is needed by i386 but not alpha. Also, some of these # routines may be optimized for a particular platform. In either case, # the file should be moved to conf/files. from here. # libkern/arc4random.c standard crypto/chacha20/chacha.c standard libkern/asprintf.c standard libkern/bcd.c standard libkern/bsearch.c standard libkern/explicit_bzero.c standard libkern/fnmatch.c standard libkern/gsb_crc32.c standard libkern/iconv.c optional libiconv libkern/iconv_converter_if.m optional libiconv libkern/iconv_ucs.c optional libiconv libkern/iconv_xlat.c optional libiconv libkern/iconv_xlat16.c optional libiconv libkern/inet_aton.c standard libkern/inet_ntoa.c standard libkern/inet_ntop.c standard libkern/inet_pton.c standard libkern/jenkins_hash.c standard libkern/murmur3_32.c standard libkern/mcount.c optional profiling-routine libkern/memcchr.c standard libkern/memchr.c standard libkern/memmem.c optional gdb libkern/qsort.c standard libkern/qsort_r.c standard libkern/random.c standard libkern/scanc.c standard libkern/strcasecmp.c standard libkern/strcat.c standard libkern/strchr.c standard libkern/strcmp.c standard libkern/strcpy.c standard libkern/strcspn.c standard libkern/strdup.c standard libkern/strndup.c standard libkern/strlcat.c standard libkern/strlcpy.c standard libkern/strlen.c standard libkern/strncat.c standard libkern/strncmp.c standard libkern/strncpy.c standard libkern/strnlen.c standard libkern/strrchr.c standard libkern/strsep.c standard libkern/strspn.c standard libkern/strstr.c standard libkern/strtol.c standard libkern/strtoq.c standard libkern/strtoul.c standard libkern/strtouq.c standard libkern/strvalid.c standard libkern/timingsafe_bcmp.c standard libkern/zlib.c optional crypto | geom_uzip | ipsec | \ ipsec_support | mxge | netgraph_deflate | ddb_ctf | gzio net/altq/altq_cbq.c optional altq net/altq/altq_codel.c optional altq net/altq/altq_hfsc.c optional altq net/altq/altq_fairq.c optional altq net/altq/altq_priq.c optional altq net/altq/altq_red.c optional altq net/altq/altq_rio.c optional altq net/altq/altq_rmclass.c optional altq net/altq/altq_subr.c optional altq net/bpf.c standard net/bpf_buffer.c optional bpf net/bpf_jitter.c optional bpf_jitter net/bpf_filter.c optional bpf | netgraph_bpf net/bpf_zerocopy.c optional bpf net/bridgestp.c optional bridge | if_bridge net/flowtable.c optional flowtable inet | flowtable inet6 net/ieee8023ad_lacp.c optional lagg net/if.c standard net/if_bridge.c optional bridge inet | if_bridge inet net/if_clone.c standard net/if_dead.c standard net/if_debug.c optional ddb net/if_disc.c optional disc net/if_edsc.c optional edsc net/if_enc.c optional enc inet | enc inet6 net/if_epair.c optional epair net/if_ethersubr.c optional ether net/if_fwsubr.c optional fwip net/if_gif.c optional gif inet | gif inet6 | \ netgraph_gif inet | netgraph_gif inet6 net/if_gre.c optional gre inet | gre inet6 net/if_ipsec.c optional inet ipsec | inet6 ipsec net/if_lagg.c optional lagg net/if_loop.c optional loop net/if_llatbl.c standard net/if_me.c optional me inet net/if_media.c standard net/if_mib.c standard net/if_spppfr.c optional sppp | netgraph_sppp net/if_spppsubr.c optional sppp | netgraph_sppp net/if_stf.c optional stf inet inet6 net/if_tuntap.c optional tuntap net/if_vlan.c optional vlan net/if_vxlan.c optional vxlan inet | vxlan inet6 net/ifdi_if.m optional ether pci iflib net/iflib.c optional ether pci iflib net/iflib_clone.c optional ether pci iflib net/mp_ring.c optional ether iflib net/mppcc.c optional netgraph_mppc_compression net/mppcd.c optional netgraph_mppc_compression net/netisr.c standard net/pfil.c optional ether | inet net/radix.c standard net/radix_mpath.c standard net/raw_cb.c standard net/raw_usrreq.c standard net/route.c standard net/rss_config.c optional inet rss | inet6 rss net/rtsock.c standard net/slcompress.c optional netgraph_vjc | sppp | \ netgraph_sppp net/toeplitz.c optional inet rss | inet6 rss net/vnet.c optional vimage net80211/ieee80211.c optional wlan net80211/ieee80211_acl.c optional wlan wlan_acl net80211/ieee80211_action.c optional wlan net80211/ieee80211_adhoc.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ageq.c optional wlan net80211/ieee80211_amrr.c optional wlan | wlan_amrr net80211/ieee80211_crypto.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp net80211/ieee80211_crypto_none.c optional wlan net80211/ieee80211_crypto_tkip.c optional wlan wlan_tkip net80211/ieee80211_crypto_wep.c optional wlan wlan_wep net80211/ieee80211_ddb.c optional wlan ddb net80211/ieee80211_dfs.c optional wlan net80211/ieee80211_freebsd.c optional wlan net80211/ieee80211_hostap.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ht.c optional wlan net80211/ieee80211_hwmp.c optional wlan ieee80211_support_mesh net80211/ieee80211_input.c optional wlan net80211/ieee80211_ioctl.c optional wlan net80211/ieee80211_mesh.c optional wlan ieee80211_support_mesh \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_monitor.c optional wlan net80211/ieee80211_node.c optional wlan net80211/ieee80211_output.c optional wlan net80211/ieee80211_phy.c optional wlan net80211/ieee80211_power.c optional wlan net80211/ieee80211_proto.c optional wlan net80211/ieee80211_radiotap.c optional wlan net80211/ieee80211_ratectl.c optional wlan net80211/ieee80211_ratectl_none.c optional wlan net80211/ieee80211_regdomain.c optional wlan net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt net80211/ieee80211_scan.c optional wlan net80211/ieee80211_scan_sta.c optional wlan net80211/ieee80211_sta.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_superg.c optional wlan ieee80211_support_superg net80211/ieee80211_scan_sw.c optional wlan net80211/ieee80211_tdma.c optional wlan ieee80211_support_tdma net80211/ieee80211_vht.c optional wlan net80211/ieee80211_wds.c optional wlan net80211/ieee80211_xauth.c optional wlan wlan_xauth net80211/ieee80211_alq.c optional wlan ieee80211_alq netgraph/atm/ccatm/ng_ccatm.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/ngatmbase.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/sscfu/ng_sscfu.c optional ngatm_sscfu \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/sscop/ng_sscop.c optional ngatm_sscop \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/uni/ng_uni.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/bluetooth/common/ng_bluetooth.c optional netgraph_bluetooth netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c optional netgraph_bluetooth_bt3c netgraph/bluetooth/drivers/h4/ng_h4.c optional netgraph_bluetooth_h4 netgraph/bluetooth/drivers/ubt/ng_ubt.c optional netgraph_bluetooth_ubt usb netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c optional netgraph_bluetooth_ubtbcmfw usb netgraph/bluetooth/hci/ng_hci_cmds.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_evnt.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_main.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_misc.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_ulpi.c optional netgraph_bluetooth_hci netgraph/bluetooth/l2cap/ng_l2cap_cmds.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_evnt.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_llpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_main.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_misc.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/socket/ng_btsocket.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_hci_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_rfcomm.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_sco.c optional netgraph_bluetooth_socket netgraph/netflow/netflow.c optional netgraph_netflow netgraph/netflow/netflow_v9.c optional netgraph_netflow netgraph/netflow/ng_netflow.c optional netgraph_netflow netgraph/ng_UI.c optional netgraph_UI netgraph/ng_async.c optional netgraph_async netgraph/ng_atmllc.c optional netgraph_atmllc netgraph/ng_base.c optional netgraph netgraph/ng_bpf.c optional netgraph_bpf netgraph/ng_bridge.c optional netgraph_bridge netgraph/ng_car.c optional netgraph_car netgraph/ng_checksum.c optional netgraph_checksum netgraph/ng_cisco.c optional netgraph_cisco netgraph/ng_deflate.c optional netgraph_deflate netgraph/ng_device.c optional netgraph_device netgraph/ng_echo.c optional netgraph_echo netgraph/ng_eiface.c optional netgraph_eiface netgraph/ng_ether.c optional netgraph_ether netgraph/ng_ether_echo.c optional netgraph_ether_echo netgraph/ng_frame_relay.c optional netgraph_frame_relay netgraph/ng_gif.c optional netgraph_gif inet6 | netgraph_gif inet netgraph/ng_gif_demux.c optional netgraph_gif_demux netgraph/ng_hole.c optional netgraph_hole netgraph/ng_iface.c optional netgraph_iface netgraph/ng_ip_input.c optional netgraph_ip_input netgraph/ng_ipfw.c optional netgraph_ipfw inet ipfirewall netgraph/ng_ksocket.c optional netgraph_ksocket netgraph/ng_l2tp.c optional netgraph_l2tp netgraph/ng_lmi.c optional netgraph_lmi netgraph/ng_mppc.c optional netgraph_mppc_compression | \ netgraph_mppc_encryption netgraph/ng_nat.c optional netgraph_nat inet libalias netgraph/ng_one2many.c optional netgraph_one2many netgraph/ng_parse.c optional netgraph netgraph/ng_patch.c optional netgraph_patch netgraph/ng_pipe.c optional netgraph_pipe netgraph/ng_ppp.c optional netgraph_ppp netgraph/ng_pppoe.c optional netgraph_pppoe netgraph/ng_pptpgre.c optional netgraph_pptpgre netgraph/ng_pred1.c optional netgraph_pred1 netgraph/ng_rfc1490.c optional netgraph_rfc1490 netgraph/ng_socket.c optional netgraph_socket netgraph/ng_split.c optional netgraph_split netgraph/ng_sppp.c optional netgraph_sppp netgraph/ng_tag.c optional netgraph_tag netgraph/ng_tcpmss.c optional netgraph_tcpmss netgraph/ng_tee.c optional netgraph_tee netgraph/ng_tty.c optional netgraph_tty netgraph/ng_vjc.c optional netgraph_vjc netgraph/ng_vlan.c optional netgraph_vlan netinet/accf_data.c optional accept_filter_data inet netinet/accf_dns.c optional accept_filter_dns inet netinet/accf_http.c optional accept_filter_http inet netinet/if_ether.c optional inet ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_debug.c optional inet ddb netinet/in_kdtrace.c optional inet | inet6 netinet/ip_carp.c optional inet carp | inet6 carp netinet/in_fib.c optional inet netinet/in_gif.c optional gif inet | netgraph_gif inet netinet/ip_gre.c optional gre inet netinet/ip_id.c optional inet netinet/in_jail.c optional inet netinet/in_mcast.c optional inet netinet/in_pcb.c optional inet | inet6 netinet/in_pcbgroup.c optional inet pcbgroup | inet6 pcbgroup netinet/in_prot.c optional inet | inet6 netinet/in_proto.c optional inet | inet6 netinet/in_rmx.c optional inet netinet/in_rss.c optional inet rss netinet/ip_divert.c optional inet ipdivert ipfirewall netinet/ip_ecn.c optional inet | inet6 netinet/ip_encap.c optional inet | inet6 netinet/ip_fastfwd.c optional inet netinet/ip_icmp.c optional inet | inet6 netinet/ip_input.c optional inet netinet/ip_mroute.c optional mrouting inet netinet/ip_options.c optional inet netinet/ip_output.c optional inet netinet/ip_reass.c optional inet netinet/raw_ip.c optional inet | inet6 netinet/cc/cc.c optional inet | inet6 netinet/cc/cc_newreno.c optional inet | inet6 netinet/sctp_asconf.c optional inet sctp | inet6 sctp netinet/sctp_auth.c optional inet sctp | inet6 sctp netinet/sctp_bsd_addr.c optional inet sctp | inet6 sctp netinet/sctp_cc_functions.c optional inet sctp | inet6 sctp netinet/sctp_crc32.c optional inet | inet6 netinet/sctp_indata.c optional inet sctp | inet6 sctp netinet/sctp_input.c optional inet sctp | inet6 sctp netinet/sctp_output.c optional inet sctp | inet6 sctp netinet/sctp_pcb.c optional inet sctp | inet6 sctp netinet/sctp_peeloff.c optional inet sctp | inet6 sctp netinet/sctp_ss_functions.c optional inet sctp | inet6 sctp netinet/sctp_syscalls.c optional inet sctp | inet6 sctp netinet/sctp_sysctl.c optional inet sctp | inet6 sctp netinet/sctp_timer.c optional inet sctp | inet6 sctp netinet/sctp_usrreq.c optional inet sctp | inet6 sctp netinet/sctputil.c optional inet sctp | inet6 sctp netinet/siftr.c optional inet siftr alq | inet6 siftr alq netinet/tcp_debug.c optional tcpdebug netinet/tcp_fastopen.c optional inet tcp_rfc7413 | inet6 tcp_rfc7413 netinet/tcp_hostcache.c optional inet | inet6 netinet/tcp_input.c optional inet | inet6 netinet/tcp_log_buf.c optional tcp_blackbox inet | tcp_blackbox inet6 netinet/tcp_lro.c optional inet | inet6 netinet/tcp_output.c optional inet | inet6 netinet/tcp_offload.c optional tcp_offload inet | tcp_offload inet6 netinet/tcp_hpts.c optional tcphpts inet | tcphpts inet6 netinet/tcp_pcap.c optional inet tcppcap | inet6 tcppcap netinet/tcp_reass.c optional inet | inet6 netinet/tcp_sack.c optional inet | inet6 netinet/tcp_subr.c optional inet | inet6 netinet/tcp_syncache.c optional inet | inet6 netinet/tcp_timer.c optional inet | inet6 netinet/tcp_timewait.c optional inet | inet6 netinet/tcp_usrreq.c optional inet | inet6 netinet/udp_usrreq.c optional inet | inet6 netinet/libalias/alias.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_db.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_mod.c optional libalias | netgraph_nat netinet/libalias/alias_proxy.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_util.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_sctp.c optional libalias inet | netgraph_nat inet netinet/netdump/netdump_client.c optional inet netdump netinet6/dest6.c optional inet6 netinet6/frag6.c optional inet6 netinet6/icmp6.c optional inet6 netinet6/in6.c optional inet6 netinet6/in6_cksum.c optional inet6 netinet6/in6_fib.c optional inet6 netinet6/in6_gif.c optional gif inet6 | netgraph_gif inet6 netinet6/in6_ifattach.c optional inet6 netinet6/in6_jail.c optional inet6 netinet6/in6_mcast.c optional inet6 netinet6/in6_pcb.c optional inet6 netinet6/in6_pcbgroup.c optional inet6 pcbgroup netinet6/in6_proto.c optional inet6 netinet6/in6_rmx.c optional inet6 netinet6/in6_rss.c optional inet6 rss netinet6/in6_src.c optional inet6 netinet6/ip6_fastfwd.c optional inet6 netinet6/ip6_forward.c optional inet6 netinet6/ip6_gre.c optional gre inet6 netinet6/ip6_id.c optional inet6 netinet6/ip6_input.c optional inet6 netinet6/ip6_mroute.c optional mrouting inet6 netinet6/ip6_output.c optional inet6 netinet6/mld6.c optional inet6 netinet6/nd6.c optional inet6 netinet6/nd6_nbr.c optional inet6 netinet6/nd6_rtr.c optional inet6 netinet6/raw_ip6.c optional inet6 netinet6/route6.c optional inet6 netinet6/scope6.c optional inet6 netinet6/sctp6_usrreq.c optional inet6 sctp netinet6/udp6_usrreq.c optional inet6 netipsec/ipsec.c optional ipsec inet | ipsec inet6 netipsec/ipsec_input.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mbuf.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mod.c optional ipsec inet | ipsec inet6 netipsec/ipsec_output.c optional ipsec inet | ipsec inet6 netipsec/ipsec_pcb.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/key.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/key_debug.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/keysock.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/subr_ipsec.c optional ipsec inet | ipsec inet6 | \ ipsec_support inet | ipsec_support inet6 netipsec/udpencap.c optional ipsec inet netipsec/xform_ah.c optional ipsec inet | ipsec inet6 netipsec/xform_esp.c optional ipsec inet | ipsec inet6 netipsec/xform_ipcomp.c optional ipsec inet | ipsec inet6 netipsec/xform_tcp.c optional ipsec inet tcp_signature | \ ipsec inet6 tcp_signature | ipsec_support inet tcp_signature | \ ipsec_support inet6 tcp_signature netpfil/ipfw/dn_aqm_codel.c optional inet dummynet netpfil/ipfw/dn_aqm_pie.c optional inet dummynet netpfil/ipfw/dn_heap.c optional inet dummynet netpfil/ipfw/dn_sched_fifo.c optional inet dummynet netpfil/ipfw/dn_sched_fq_codel.c optional inet dummynet netpfil/ipfw/dn_sched_fq_pie.c optional inet dummynet netpfil/ipfw/dn_sched_prio.c optional inet dummynet netpfil/ipfw/dn_sched_qfq.c optional inet dummynet netpfil/ipfw/dn_sched_rr.c optional inet dummynet netpfil/ipfw/dn_sched_wf2q.c optional inet dummynet netpfil/ipfw/ip_dummynet.c optional inet dummynet netpfil/ipfw/ip_dn_io.c optional inet dummynet netpfil/ipfw/ip_dn_glue.c optional inet dummynet netpfil/ipfw/ip_fw2.c optional inet ipfirewall netpfil/ipfw/ip_fw_bpf.c optional inet ipfirewall netpfil/ipfw/ip_fw_dynamic.c optional inet ipfirewall \ compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/ip_fw_eaction.c optional inet ipfirewall netpfil/ipfw/ip_fw_log.c optional inet ipfirewall netpfil/ipfw/ip_fw_pfil.c optional inet ipfirewall netpfil/ipfw/ip_fw_sockopt.c optional inet ipfirewall netpfil/ipfw/ip_fw_table.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_algo.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_value.c optional inet ipfirewall netpfil/ipfw/ip_fw_iface.c optional inet ipfirewall netpfil/ipfw/ip_fw_nat.c optional inet ipfirewall_nat netpfil/ipfw/nat64/ip_fw_nat64.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64clat.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64clat_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64lsn.c optional inet inet6 ipfirewall \ ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/nat64/nat64lsn_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include" netpfil/ipfw/nat64/nat64stl.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64stl_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64_translate.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nptv6/ip_fw_nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/nptv6/nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/pmod/ip_fw_pmod.c optional inet ipfirewall_pmod netpfil/ipfw/pmod/tcpmod.c optional inet ipfirewall_pmod netpfil/pf/if_pflog.c optional pflog pf inet netpfil/pf/if_pfsync.c optional pfsync pf inet netpfil/pf/pf.c optional pf inet netpfil/pf/pf_if.c optional pf inet netpfil/pf/pf_ioctl.c optional pf inet netpfil/pf/pf_lb.c optional pf inet netpfil/pf/pf_norm.c optional pf inet netpfil/pf/pf_osfp.c optional pf inet netpfil/pf/pf_ruleset.c optional pf inet netpfil/pf/pf_table.c optional pf inet netpfil/pf/in4_cksum.c optional pf inet netsmb/smb_conn.c optional netsmb netsmb/smb_crypt.c optional netsmb netsmb/smb_dev.c optional netsmb netsmb/smb_iod.c optional netsmb netsmb/smb_rq.c optional netsmb 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 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 nlm/nlm_prot_server.c optional nfslockd | nfsd nlm/nlm_prot_svc.c optional nfslockd | nfsd nlm/nlm_prot_xdr.c optional nfslockd | nfsd nlm/sm_inter_xdr.c optional nfslockd | nfsd # Linux Kernel Programming Interface compat/linuxkpi/common/src/linux_kmod.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_compat.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_current.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_hrtimer.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_kthread.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_lock.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_page.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_pci.c optional compat_linuxkpi pci \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_tasklet.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_idr.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_radix.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_rcu.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C} -I$S/contrib/ck/include" compat/linuxkpi/common/src/linux_schedule.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_slab.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_usb.c optional compat_linuxkpi usb \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_work.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_seq_file.c optional compat_linuxkpi | lindebugfs \ compile-with "${LINUXKPI_C}" compat/lindebugfs/lindebugfs.c optional lindebugfs \ compile-with "${LINUXKPI_C}" # OpenFabrics Enterprise Distribution (Infiniband) ofed/drivers/infiniband/core/ib_addr.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_agent.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cache.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cma.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_cq.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_device.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_fmr_pool.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwcm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwpm_msg.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_iwpm_util.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_mad.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_mad_rmpp.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_multicast.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_packer.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_roce_gid_mgmt.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_sa_query.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_smi.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_sysfs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ucm.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ucma.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_ud_header.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_umem.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_user_mad.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_cmd.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_main.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_uverbs_marshall.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/core/ib_verbs.c optional ofed \ compile-with "${OFED_C}" ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_fs.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_verbs.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/sdp/sdp_bcopy.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_main.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_rx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_cma.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_tx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" dev/mthca/mthca_allocator.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_av.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_catas.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_cmd.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_cq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_eq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mad.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_main.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mcg.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_memfree.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_mr.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_pd.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_profile.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_provider.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_qp.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_reset.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_srq.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mthca/mthca_uar.c optional mthca pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_alias_GUID.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mcg.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_sysfs.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cm.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_ah.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_doorbell.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mad.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_main.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mr.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_qp.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_srq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_wc.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_alloc.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_catas.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cmd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_eq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw_qos.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_icm.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_intf.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_main.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mcg.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mr.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_pd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_port.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_profile.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_qp.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_reset.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_sense.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_srq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_resource_tracker.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_cq.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_main.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_netdev.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_port.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_resources.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_rx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_tx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_ah.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_cong.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_cq.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_doorbell.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_gsi.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mad.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_main.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mem.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_mr.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_qp.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_srq.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_ib/mlx5_ib_virt.c optional mlx5ib pci ofed \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_alloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_diagnostics.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_eq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_tree.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fw.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fwdump.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fwdump_regmaps.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_health.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mad.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_main.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mcg.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mr.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pagealloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_port.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_qp.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_rl.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_srq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_transobj.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_uar.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vport.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vsc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_wq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_lib/mlx5_gid.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_dim.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_ethtool.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_main.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_tx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_flow_table.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rl.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_txrx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" # crypto support opencrypto/cast.c optional crypto | ipsec | ipsec_support opencrypto/criov.c optional crypto | ipsec | ipsec_support opencrypto/crypto.c optional crypto | ipsec | ipsec_support opencrypto/cryptodev.c optional cryptodev opencrypto/cryptodev_if.m optional crypto | ipsec | ipsec_support opencrypto/cryptosoft.c optional crypto | ipsec | ipsec_support opencrypto/cryptodeflate.c optional crypto | ipsec | ipsec_support opencrypto/gmac.c optional crypto | ipsec | ipsec_support opencrypto/gfmult.c optional crypto | ipsec | ipsec_support opencrypto/rmd160.c optional crypto | ipsec | ipsec_support opencrypto/skipjack.c optional crypto | ipsec | ipsec_support opencrypto/xform.c optional crypto | ipsec | ipsec_support opencrypto/xform_poly1305.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" contrib/libsodium/src/libsodium/crypto_verify/sodium/verify.c \ optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include/sodium -I$S/crypto/libsodium" crypto/libsodium/randombytes.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" crypto/libsodium/utils.c optional crypto \ compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium" opencrypto/cbc_mac.c optional crypto opencrypto/xform_cbc_mac.c optional crypto 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 rpc/rpcsec_gss/rpcsec_gss_prot.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/svc_rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi security/audit/audit.c optional audit security/audit/audit_arg.c optional audit security/audit/audit_bsm.c optional audit security/audit/audit_bsm_db.c optional audit security/audit/audit_bsm_klib.c optional audit security/audit/audit_dtrace.c optional dtaudit audit | dtraceall audit compile-with "${CDDL_C}" security/audit/audit_pipe.c optional audit security/audit/audit_syscalls.c standard security/audit/audit_trigger.c optional audit security/audit/audit_worker.c optional audit security/audit/bsm_domain.c optional audit security/audit/bsm_errno.c optional audit security/audit/bsm_fcntl.c optional audit security/audit/bsm_socket_type.c optional audit security/audit/bsm_token.c optional audit security/mac/mac_audit.c optional mac audit security/mac/mac_cred.c optional mac security/mac/mac_framework.c optional mac security/mac/mac_inet.c optional mac inet | mac inet6 security/mac/mac_inet6.c optional mac inet6 security/mac/mac_label.c optional mac security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac security/mac/mac_posix_shm.c optional mac security/mac/mac_priv.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac security/mac/mac_syscalls.c standard security/mac/mac_system.c optional mac security/mac/mac_sysv_msg.c optional mac security/mac/mac_sysv_sem.c optional mac security/mac/mac_sysv_shm.c optional mac security/mac/mac_vfs.c optional mac security/mac_biba/mac_biba.c optional mac_biba security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended security/mac_ifoff/mac_ifoff.c optional mac_ifoff security/mac_lomac/mac_lomac.c optional mac_lomac security/mac_mls/mac_mls.c optional mac_mls security/mac_none/mac_none.c optional mac_none security/mac_ntpd/mac_ntpd.c optional mac_ntpd security/mac_partition/mac_partition.c optional mac_partition security/mac_portacl/mac_portacl.c optional mac_portacl security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test security/mac_veriexec/mac_veriexec.c optional mac_veriexec security/mac_veriexec/veriexec_fingerprint.c optional mac_veriexec security/mac_veriexec/veriexec_metadata.c optional mac_veriexec security/mac_veriexec_parser/mac_veriexec_parser.c optional mac_veriexec mac_veriexec_parser security/mac_veriexec/mac_veriexec_rmd160.c optional mac_veriexec_rmd160 security/mac_veriexec/mac_veriexec_sha1.c optional mac_veriexec_sha1 security/mac_veriexec/mac_veriexec_sha256.c optional mac_veriexec_sha256 security/mac_veriexec/mac_veriexec_sha384.c optional mac_veriexec_sha384 security/mac_veriexec/mac_veriexec_sha512.c optional mac_veriexec_sha512 teken/teken.c optional sc !SC_NO_TERM_TEKEN | vt ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_balloc.c optional ffs ufs/ffs/ffs_inode.c optional ffs ufs/ffs/ffs_snapshot.c optional ffs ufs/ffs/ffs_softdep.c optional ffs ufs/ffs/ffs_subr.c optional ffs | geom_label ufs/ffs/ffs_tables.c optional ffs | geom_label ufs/ffs/ffs_vfsops.c optional ffs ufs/ffs/ffs_vnops.c optional ffs ufs/ffs/ffs_rawread.c optional ffs directio ufs/ffs/ffs_suspend.c optional ffs ufs/ufs/ufs_acl.c optional ffs ufs/ufs/ufs_bmap.c optional ffs ufs/ufs/ufs_dirhash.c optional ffs ufs/ufs/ufs_extattr.c optional ffs ufs/ufs/ufs_gjournal.c optional ffs UFS_GJOURNAL ufs/ufs/ufs_inode.c optional ffs ufs/ufs/ufs_lookup.c optional ffs ufs/ufs/ufs_quota.c optional ffs ufs/ufs/ufs_vfsops.c optional ffs ufs/ufs/ufs_vnops.c optional ffs vm/default_pager.c standard vm/device_pager.c standard vm/phys_pager.c standard vm/redzone.c optional DEBUG_REDZONE vm/sg_pager.c standard vm/swap_pager.c standard vm/uma_core.c standard vm/uma_dbg.c standard vm/memguard.c optional DEBUG_MEMGUARD vm/vm_domainset.c standard vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard vm/vm_kern.c standard vm/vm_map.c standard vm/vm_meter.c standard vm/vm_mmap.c standard vm/vm_object.c standard vm/vm_page.c standard vm/vm_pageout.c standard vm/vm_pager.c standard vm/vm_phys.c standard vm/vm_radix.c standard vm/vm_reserv.c standard vm/vm_swapout.c optional !NO_SWAPPING vm/vm_swapout_dummy.c optional NO_SWAPPING vm/vm_unix.c standard vm/vnode_pager.c standard xen/features.c optional xenhvm xen/xenbus/xenbus_if.m optional xenhvm xen/xenbus/xenbus.c optional xenhvm xen/xenbus/xenbusb_if.m optional xenhvm xen/xenbus/xenbusb.c optional xenhvm xen/xenbus/xenbusb_front.c optional xenhvm xen/xenbus/xenbusb_back.c optional xenhvm xen/xenmem/xenmem_if.m optional xenhvm 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 Index: head/sys/conf/files.powerpc =================================================================== --- head/sys/conf/files.powerpc (revision 349351) +++ head/sys/conf/files.powerpc (revision 349352) @@ -1,277 +1,275 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # # font.h optional sc \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" # # There is only an asm version on ppc64. cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs powerpc | dtrace powerpc | zfs powerpcspe | dtrace powerpcspe compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/atomic/powerpc64/opensolaris_atomic.S optional zfs powerpc64 | dtrace powerpc64 compile-with "${ZFS_S}" cddl/dev/dtrace/powerpc/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/powerpc/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/powerpc/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | ipsec_support | netsmb dev/adb/adb_bus.c optional adb dev/adb/adb_kbd.c optional adb dev/adb/adb_mouse.c optional adb dev/adb/adb_hb_if.m optional adb dev/adb/adb_if.m optional adb dev/adb/adb_buttons.c optional adb dev/agp/agp_apple.c optional agp powermac dev/fb/fb.c optional sc dev/hwpmc/hwpmc_e500.c optional hwpmc dev/hwpmc/hwpmc_mpc7xxx.c optional hwpmc dev/hwpmc/hwpmc_powerpc.c optional hwpmc dev/hwpmc/hwpmc_ppc970.c optional hwpmc dev/iicbus/ad7417.c optional ad7417 powermac dev/iicbus/adm1030.c optional powermac windtunnel | adm1030 powermac dev/iicbus/adt746x.c optional adt746x powermac dev/iicbus/ds1631.c optional ds1631 powermac dev/iicbus/ds1775.c optional ds1775 powermac dev/iicbus/max6690.c optional max6690 powermac dev/iicbus/ofw_iicbus.c optional iicbus aim dev/ipmi/ipmi.c optional ipmi dev/ipmi/ipmi_opal.c optional powernv ipmi -dev/nand/nfc_fsl.c optional nand mpc85xx -dev/nand/nfc_rb.c optional nand mpc85xx # Most ofw stuff below is brought in by conf/files for options FDT, but # we always want it, even on non-FDT platforms. dev/fdt/simplebus.c standard dev/ofw/openfirm.c standard dev/ofw/openfirmio.c standard dev/ofw/ofw_bus_if.m standard dev/ofw/ofw_cpu.c standard dev/ofw/ofw_if.m standard dev/ofw/ofw_bus_subr.c standard dev/ofw/ofw_console.c optional aim dev/ofw/ofw_disk.c optional ofwd aim dev/ofw/ofwbus.c standard dev/ofw/ofwpci.c optional pci dev/ofw/ofw_standard.c optional aim powerpc dev/ofw/ofw_subr.c standard dev/powermac_nvram/powermac_nvram.c optional powermac_nvram powermac dev/quicc/quicc_bfe_fdt.c optional quicc mpc85xx dev/random/darn.c optional powerpc64 !random_loadable dev/scc/scc_bfe_macio.c optional scc powermac dev/sdhci/fsl_sdhci.c optional mpc85xx sdhci dev/sec/sec.c optional sec mpc85xx dev/sound/macio/aoa.c optional snd_davbus | snd_ai2s powermac dev/sound/macio/davbus.c optional snd_davbus powermac dev/sound/macio/i2s.c optional snd_ai2s powermac dev/sound/macio/onyx.c optional snd_ai2s iicbus powermac dev/sound/macio/snapper.c optional snd_ai2s iicbus powermac dev/sound/macio/tumbler.c optional snd_ai2s iicbus powermac dev/syscons/scgfbrndr.c optional sc dev/tsec/if_tsec.c optional tsec dev/tsec/if_tsec_fdt.c optional tsec dev/uart/uart_cpu_powerpc.c optional uart dev/usb/controller/ehci_fsl.c optional ehci mpc85xx dev/vt/hw/ofwfb/ofwfb.c optional vt aim kern/kern_clocksource.c standard kern/subr_dummy_vdso_tc.c standard kern/syscalls.c optional ktr kern/subr_sfbuf.c standard libkern/ashldi3.c optional powerpc | powerpcspe libkern/ashrdi3.c optional powerpc | powerpcspe libkern/bcmp.c standard libkern/bcopy.c standard libkern/cmpdi2.c optional powerpc | powerpcspe libkern/divdi3.c optional powerpc | powerpcspe libkern/ffs.c standard libkern/ffsl.c standard libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/lshrdi3.c optional powerpc | powerpcspe libkern/memcmp.c standard libkern/memset.c standard libkern/moddi3.c optional powerpc | powerpcspe libkern/qdivrem.c optional powerpc | powerpcspe libkern/ucmpdi2.c optional powerpc | powerpcspe libkern/udivdi3.c optional powerpc | powerpcspe libkern/umoddi3.c optional powerpc | powerpcspe powerpc/aim/locore.S optional aim no-obj powerpc/aim/aim_machdep.c optional aim powerpc/aim/mmu_oea.c optional aim powerpc powerpc/aim/mmu_oea64.c optional aim powerpc/aim/moea64_if.m optional aim powerpc/aim/moea64_native.c optional aim powerpc/aim/mp_cpudep.c optional aim powerpc/aim/slb.c optional aim powerpc64 powerpc/booke/locore.S optional booke no-obj powerpc/booke/booke_machdep.c optional booke powerpc/booke/machdep_e500.c optional booke_e500 powerpc/booke/mp_cpudep.c optional booke smp powerpc/booke/platform_bare.c optional booke powerpc/booke/pmap.c optional booke powerpc/booke/spe.c optional powerpcspe powerpc/cpufreq/dfs.c optional cpufreq powerpc/cpufreq/mpc85xx_jog.c optional cpufreq mpc85xx powerpc/cpufreq/pcr.c optional cpufreq aim powerpc/cpufreq/pmcr.c optional cpufreq aim powerpc64 powerpc/cpufreq/pmufreq.c optional cpufreq aim pmu powerpc/fpu/fpu_add.c optional fpu_emu | powerpcspe powerpc/fpu/fpu_compare.c optional fpu_emu | powerpcspe powerpc/fpu/fpu_div.c optional fpu_emu | powerpcspe powerpc/fpu/fpu_emu.c optional fpu_emu powerpc/fpu/fpu_explode.c optional fpu_emu | powerpcspe powerpc/fpu/fpu_implode.c optional fpu_emu | powerpcspe powerpc/fpu/fpu_mul.c optional fpu_emu | powerpcspe powerpc/fpu/fpu_sqrt.c optional fpu_emu powerpc/fpu/fpu_subr.c optional fpu_emu | powerpcspe powerpc/mambo/mambocall.S optional mambo powerpc/mambo/mambo.c optional mambo powerpc/mambo/mambo_console.c optional mambo powerpc/mambo/mambo_disk.c optional mambo powerpc/mikrotik/platform_rb.c optional mikrotik powerpc/mikrotik/rb_led.c optional mikrotik powerpc/mpc85xx/atpic.c optional mpc85xx isa powerpc/mpc85xx/ds1553_bus_fdt.c optional ds1553 powerpc/mpc85xx/ds1553_core.c optional ds1553 powerpc/mpc85xx/fsl_diu.c optional mpc85xx diu powerpc/mpc85xx/fsl_espi.c optional mpc85xx spibus powerpc/mpc85xx/fsl_sata.c optional mpc85xx ata powerpc/mpc85xx/i2c.c optional iicbus powerpc/mpc85xx/isa.c optional mpc85xx isa powerpc/mpc85xx/lbc.c optional mpc85xx powerpc/mpc85xx/mpc85xx.c optional mpc85xx powerpc/mpc85xx/mpc85xx_cache.c optional mpc85xx powerpc/mpc85xx/mpc85xx_gpio.c optional mpc85xx gpio powerpc/mpc85xx/platform_mpc85xx.c optional mpc85xx powerpc/mpc85xx/pci_mpc85xx.c optional pci mpc85xx powerpc/mpc85xx/pci_mpc85xx_pcib.c optional pci mpc85xx powerpc/mpc85xx/qoriq_gpio.c optional mpc85xx gpio powerpc/ofw/ofw_machdep.c standard powerpc/ofw/ofw_pcibus.c optional pci powerpc/ofw/ofw_pcib_pci.c optional pci powerpc/ofw/ofw_real.c optional aim powerpc/ofw/ofw_syscons.c optional sc aim powerpc/ofw/ofwcall32.S optional aim powerpc powerpc/ofw/ofwcall64.S optional aim powerpc64 powerpc/ofw/openpic_ofw.c standard powerpc/ofw/rtas.c optional aim powerpc/ofw/ofw_initrd.c optional md_root_mem powerpc64 powerpc/powermac/ata_kauai.c optional powermac ata | powermac atamacio powerpc/powermac/ata_macio.c optional powermac ata | powermac atamacio powerpc/powermac/ata_dbdma.c optional powermac ata | powermac atamacio powerpc/powermac/atibl.c optional powermac atibl powerpc/powermac/cuda.c optional powermac cuda powerpc/powermac/cpcht.c optional powermac pci powerpc/powermac/dbdma.c optional powermac pci powerpc/powermac/fcu.c optional powermac fcu powerpc/powermac/grackle.c optional powermac pci powerpc/powermac/hrowpic.c optional powermac pci powerpc/powermac/kiic.c optional powermac kiic powerpc/powermac/macgpio.c optional powermac pci powerpc/powermac/macio.c optional powermac pci powerpc/powermac/nvbl.c optional powermac nvbl powerpc/powermac/platform_powermac.c optional powermac powerpc/powermac/powermac_thermal.c optional powermac powerpc/powermac/pswitch.c optional powermac pswitch powerpc/powermac/pmu.c optional powermac pmu powerpc/powermac/smu.c optional powermac smu powerpc/powermac/smusat.c optional powermac smu powerpc/powermac/uninorth.c optional powermac powerpc/powermac/uninorthpci.c optional powermac pci powerpc/powermac/vcoregpio.c optional powermac powerpc/powernv/opal.c optional powernv powerpc/powernv/opal_async.c optional powernv powerpc/powernv/opal_console.c optional powernv powerpc/powernv/opal_dev.c optional powernv powerpc/powernv/opal_flash.c optional powernv opalflash powerpc/powernv/opal_hmi.c optional powernv powerpc/powernv/opal_i2c.c optional iicbus fdt powernv powerpc/powernv/opal_i2cm.c optional iicbus fdt powernv powerpc/powernv/opal_pci.c optional powernv pci powerpc/powernv/opal_sensor.c optional powernv powerpc/powernv/opalcall.S optional powernv powerpc/powernv/platform_powernv.c optional powernv powerpc/powernv/powernv_centaur.c optional powernv powerpc/powernv/powernv_xscom.c optional powernv powerpc/powernv/xive.c optional powernv powerpc/powerpc/altivec.c optional powerpc | powerpc64 powerpc/powerpc/autoconf.c standard powerpc/powerpc/bus_machdep.c standard powerpc/powerpc/busdma_machdep.c standard powerpc/powerpc/clock.c standard powerpc/powerpc/copyinout.c standard powerpc/powerpc/copystr.c standard powerpc/powerpc/cpu.c standard powerpc/powerpc/cpu_subr64.S optional powerpc64 powerpc/powerpc/db_disasm.c optional ddb powerpc/powerpc/db_hwwatch.c optional ddb powerpc/powerpc/db_interface.c optional ddb powerpc/powerpc/db_trace.c optional ddb powerpc/powerpc/dump_machdep.c standard powerpc/powerpc/elf32_machdep.c optional powerpc | powerpcspe | compat_freebsd32 powerpc/powerpc/elf64_machdep.c optional powerpc64 powerpc/powerpc/exec_machdep.c standard powerpc/powerpc/fpu.c standard powerpc/powerpc/gdb_machdep.c optional gdb powerpc/powerpc/in_cksum.c optional inet | inet6 powerpc/powerpc/interrupt.c standard powerpc/powerpc/intr_machdep.c standard powerpc/powerpc/iommu_if.m standard powerpc/powerpc/machdep.c standard powerpc/powerpc/mem.c optional mem powerpc/powerpc/mmu_if.m standard powerpc/powerpc/mp_machdep.c optional smp powerpc/powerpc/nexus.c standard powerpc/powerpc/openpic.c standard powerpc/powerpc/pic_if.m standard powerpc/powerpc/pmap_dispatch.c standard powerpc/powerpc/platform.c standard powerpc/powerpc/platform_if.m standard powerpc/powerpc/ptrace_machdep.c standard powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard powerpc/powerpc/sigcode32.S optional powerpc | powerpcspe | compat_freebsd32 powerpc/powerpc/sigcode64.S optional powerpc64 powerpc/powerpc/swtch32.S optional powerpc | powerpcspe powerpc/powerpc/swtch64.S optional powerpc64 powerpc/powerpc/stack_machdep.c optional ddb | stack powerpc/powerpc/syncicache.c standard powerpc/powerpc/sys_machdep.c standard powerpc/powerpc/trap.c standard powerpc/powerpc/uio_machdep.c standard powerpc/powerpc/uma_machdep.c standard powerpc/powerpc/vm_machdep.c standard powerpc/ps3/ehci_ps3.c optional ps3 ehci powerpc/ps3/ohci_ps3.c optional ps3 ohci powerpc/ps3/if_glc.c optional ps3 glc powerpc/ps3/mmu_ps3.c optional ps3 powerpc/ps3/platform_ps3.c optional ps3 powerpc/ps3/ps3bus.c optional ps3 powerpc/ps3/ps3cdrom.c optional ps3 scbus powerpc/ps3/ps3disk.c optional ps3 powerpc/ps3/ps3pic.c optional ps3 powerpc/ps3/ps3_syscons.c optional ps3 vt powerpc/ps3/ps3-hvcall.S optional ps3 powerpc/pseries/phyp-hvcall.S optional pseries powerpc64 powerpc/pseries/mmu_phyp.c optional pseries powerpc64 powerpc/pseries/phyp_console.c optional pseries powerpc64 uart powerpc/pseries/phyp_llan.c optional llan powerpc/pseries/phyp_vscsi.c optional pseries powerpc64 scbus powerpc/pseries/platform_chrp.c optional pseries powerpc/pseries/plpar_iommu.c optional pseries powerpc64 powerpc/pseries/plpar_pcibus.c optional pseries powerpc64 pci powerpc/pseries/rtas_dev.c optional pseries powerpc/pseries/rtas_pci.c optional pseries pci powerpc/pseries/vdevice.c optional pseries powerpc64 powerpc/pseries/xics.c optional pseries powerpc64 powerpc/psim/iobus.c optional psim powerpc/psim/ata_iobus.c optional ata psim powerpc/psim/openpic_iobus.c optional psim powerpc/psim/uart_iobus.c optional uart psim Index: head/sys/conf/kern.opts.mk =================================================================== --- head/sys/conf/kern.opts.mk (revision 349351) +++ head/sys/conf/kern.opts.mk (revision 349352) @@ -1,178 +1,177 @@ # $FreeBSD$ # Options set in the build system that affect the kernel somehow. # # Define MK_* variables (which are either "yes" or "no") for users # to set via WITH_*/WITHOUT_* in /etc/src.conf and override in the # make(1) environment. # These should be tested with `== "no"' or `!= "no"' in makefiles. # The NO_* variables should only be set by makefiles for variables # that haven't been converted over. # # Note: bsd.own.mk must be included before the rest of kern.opts.mk to make # building on 10.x and earlier work. This should be removed when that's no # longer supported since it confounds the defaults (since it uses the host's # notion of defaults rather than what's default in current when building # within sys/modules). .include # These options are used by the kernel build process (kern.mk and kmod.mk) # They have to be listed here so we can build modules outside of the # src tree. KLDXREF_CMD?= kldxref __DEFAULT_YES_OPTIONS = \ AUTOFS \ BHYVE \ BLUETOOTH \ CCD \ CDDL \ CRYPT \ CUSE \ EFI \ FORMAT_EXTENSIONS \ INET \ INET6 \ IPFILTER \ IPSEC_SUPPORT \ ISCSI \ KERNEL_SYMBOLS \ NETGRAPH \ PF \ REPRODUCIBLE_BUILD \ SOURCELESS_HOST \ SOURCELESS_UCODE \ TESTS \ USB_GADGET_EXAMPLES \ ZFS __DEFAULT_NO_OPTIONS = \ EXTRA_TCP_STACKS \ KERNEL_RETPOLINE \ - NAND \ OFED \ RATELIMIT # Some options are totally broken on some architectures. We disable # them. If you need to enable them on an experimental basis, you # must change this code. # Note: These only apply to the list of modules we build by default # and sometimes what is in the opt_*.h files by default. # Kernel config files are unaffected, though some targets can be # affected by KERNEL_SYMBOLS, FORMAT_EXTENSIONS, CTF and SSP. # Things that don't work based on the CPU .if ${MACHINE_CPUARCH} == "arm" . if ${MACHINE_ARCH:Marmv[67]*} == "" BROKEN_OPTIONS+= CDDL ZFS . endif .endif .if ${MACHINE_CPUARCH} == "mips" BROKEN_OPTIONS+= CDDL ZFS SSP .endif .if ${MACHINE_CPUARCH} == "powerpc" && ${MACHINE_ARCH} == "powerpc" BROKEN_OPTIONS+= ZFS .endif .if ${MACHINE_CPUARCH} == "riscv" BROKEN_OPTIONS+= FORMAT_EXTENSIONS .endif # Things that don't work because the kernel doesn't have the support # for them. .if ${MACHINE} != "i386" && ${MACHINE} != "amd64" BROKEN_OPTIONS+= OFED .endif # Things that don't work based on toolchain support. .if ${MACHINE} != "i386" && ${MACHINE} != "amd64" BROKEN_OPTIONS+= KERNEL_RETPOLINE .endif # EFI doesn't exist on mips, powerpc, sparc or riscv. .if ${MACHINE:Mmips} || ${MACHINE:Mpowerpc} || ${MACHINE:Msparc64} || ${MACHINE:Mriscv} BROKEN_OPTIONS+=EFI .endif # expanded inline from bsd.mkopt.mk to avoid share/mk dependency # Those that default to yes .for var in ${__DEFAULT_YES_OPTIONS} .if !defined(MK_${var}) .if defined(WITHOUT_${var}) # WITHOUT always wins MK_${var}:= no .else MK_${var}:= yes .endif .else .if ${MK_${var}} != "yes" && ${MK_${var}} != "no" .error "Illegal value for MK_${var}: ${MK_${var}}" .endif .endif # !defined(MK_${var}) .endfor .undef __DEFAULT_YES_OPTIONS # Those that default to no .for var in ${__DEFAULT_NO_OPTIONS} .if !defined(MK_${var}) .if defined(WITH_${var}) && !defined(WITHOUT_${var}) # WITHOUT always wins MK_${var}:= yes .else MK_${var}:= no .endif .else .if ${MK_${var}} != "yes" && ${MK_${var}} != "no" .error "Illegal value for MK_${var}: ${MK_${var}}" .endif .endif # !defined(MK_${var}) .endfor .undef __DEFAULT_NO_OPTIONS # # MK_* options which are always no, usually because they are # unsupported/badly broken on this architecture. # .for var in ${BROKEN_OPTIONS} MK_${var}:= no .endfor .undef BROKEN_OPTIONS #end of bsd.mkopt.mk expanded inline. # # MK_*_SUPPORT options which default to "yes" unless their corresponding # MK_* variable is set to "no". # .for var in \ INET \ INET6 .if defined(WITHOUT_${var}_SUPPORT) || ${MK_${var}} == "no" MK_${var}_SUPPORT:= no .else .if defined(KERNBUILDDIR) # See if there's an opt_foo.h .if !defined(OPT_${var}) OPT_${var}!= cat ${KERNBUILDDIR}/opt_${var:tl}.h; echo .export OPT_${var} .endif .if ${OPT_${var}} == "" # nothing -> no MK_${var}_SUPPORT:= no .else MK_${var}_SUPPORT:= yes .endif .else # otherwise, yes MK_${var}_SUPPORT:= yes .endif .endif .endfor # Some modules only compile successfully if option FDT is set, due to #ifdef FDT # wrapped around declarations. Module makefiles can optionally compile such # things using .if !empty(OPT_FDT) .if !defined(OPT_FDT) && defined(KERNBUILDDIR) OPT_FDT!= sed -n '/FDT/p' ${KERNBUILDDIR}/opt_platform.h .export OPT_FDT .endif Index: head/sys/dev/nand/nandbus_if.m =================================================================== --- head/sys/dev/nand/nandbus_if.m (revision 349351) +++ head/sys/dev/nand/nandbus_if.m (nonexistent) @@ -1,100 +0,0 @@ -#- -# Copyright (C) 2009-2012 Semihalf -# 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$ - -# NAND bus interface description -# - -#include -#include - -INTERFACE nandbus; - -METHOD int get_status { - device_t dev; - uint8_t * status; -}; - -METHOD void read_buffer { - device_t dev; - void * buf; - uint32_t len; -}; - -METHOD int select_cs { - device_t dev; - uint8_t cs; -}; - -METHOD int send_command { - device_t dev; - uint8_t command; -}; - -METHOD int send_address { - device_t dev; - uint8_t address; -}; - -METHOD int start_command { - device_t dev; -}; - -METHOD int wait_ready { - device_t dev; - uint8_t * status; -} - -METHOD void write_buffer { - device_t dev; - void * buf; - uint32_t len; -}; - -METHOD int get_ecc { - device_t dev; - void * buf; - uint32_t pagesize; - void * ecc; - int * needwrite; -}; - -METHOD int correct_ecc { - device_t dev; - void * buf; - int pagesize; - void * readecc; - void * calcecc; -}; - -METHOD void lock { - device_t dev; -}; - -METHOD void unlock { - device_t dev; -}; - Property changes on: head/sys/dev/nand/nandbus_if.m ___________________________________________________________________ Deleted: svn::keyword ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/sys/dev/nand/nand_generic.c =================================================================== --- head/sys/dev/nand/nand_generic.c (revision 349351) +++ head/sys/dev/nand/nand_generic.c (nonexistent) @@ -1,1366 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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. - */ - -/* Generic NAND driver */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "nfc_if.h" -#include "nand_if.h" -#include "nandbus_if.h" - - -static int onfi_nand_probe(device_t dev); -static int large_nand_probe(device_t dev); -static int small_nand_probe(device_t dev); -static int generic_nand_attach(device_t dev); -static int generic_nand_detach(device_t dev); - -static int generic_erase_block(device_t, uint32_t); -static int generic_erase_block_intlv(device_t, uint32_t); -static int generic_read_page (device_t, uint32_t, void *, uint32_t, uint32_t); -static int generic_read_oob(device_t, uint32_t, void *, uint32_t, uint32_t); -static int generic_program_page(device_t, uint32_t, void *, uint32_t, uint32_t); -static int generic_program_page_intlv(device_t, uint32_t, void *, uint32_t, - uint32_t); -static int generic_program_oob(device_t, uint32_t, void *, uint32_t, uint32_t); -static int generic_is_blk_bad(device_t, uint32_t, uint8_t *); -static int generic_get_ecc(device_t, void *, void *, int *); -static int generic_correct_ecc(device_t, void *, void *, void *); - -static int small_read_page(device_t, uint32_t, void *, uint32_t, uint32_t); -static int small_read_oob(device_t, uint32_t, void *, uint32_t, uint32_t); -static int small_program_page(device_t, uint32_t, void *, uint32_t, uint32_t); -static int small_program_oob(device_t, uint32_t, void *, uint32_t, uint32_t); - -static int onfi_is_blk_bad(device_t, uint32_t, uint8_t *); -static int onfi_read_parameter(struct nand_chip *, struct onfi_chip_params *); - -static int nand_send_address(device_t, int32_t, int32_t, int8_t); - -static device_method_t onand_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, onfi_nand_probe), - DEVMETHOD(device_attach, generic_nand_attach), - DEVMETHOD(device_detach, generic_nand_detach), - - DEVMETHOD(nand_read_page, generic_read_page), - DEVMETHOD(nand_program_page, generic_program_page), - DEVMETHOD(nand_program_page_intlv, generic_program_page_intlv), - DEVMETHOD(nand_read_oob, generic_read_oob), - DEVMETHOD(nand_program_oob, generic_program_oob), - DEVMETHOD(nand_erase_block, generic_erase_block), - DEVMETHOD(nand_erase_block_intlv, generic_erase_block_intlv), - - DEVMETHOD(nand_is_blk_bad, onfi_is_blk_bad), - DEVMETHOD(nand_get_ecc, generic_get_ecc), - DEVMETHOD(nand_correct_ecc, generic_correct_ecc), - { 0, 0 } -}; - -static device_method_t lnand_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, large_nand_probe), - DEVMETHOD(device_attach, generic_nand_attach), - DEVMETHOD(device_detach, generic_nand_detach), - - DEVMETHOD(nand_read_page, generic_read_page), - DEVMETHOD(nand_program_page, generic_program_page), - DEVMETHOD(nand_read_oob, generic_read_oob), - DEVMETHOD(nand_program_oob, generic_program_oob), - DEVMETHOD(nand_erase_block, generic_erase_block), - - DEVMETHOD(nand_is_blk_bad, generic_is_blk_bad), - DEVMETHOD(nand_get_ecc, generic_get_ecc), - DEVMETHOD(nand_correct_ecc, generic_correct_ecc), - { 0, 0 } -}; - -static device_method_t snand_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, small_nand_probe), - DEVMETHOD(device_attach, generic_nand_attach), - DEVMETHOD(device_detach, generic_nand_detach), - - DEVMETHOD(nand_read_page, small_read_page), - DEVMETHOD(nand_program_page, small_program_page), - DEVMETHOD(nand_read_oob, small_read_oob), - DEVMETHOD(nand_program_oob, small_program_oob), - DEVMETHOD(nand_erase_block, generic_erase_block), - - DEVMETHOD(nand_is_blk_bad, generic_is_blk_bad), - DEVMETHOD(nand_get_ecc, generic_get_ecc), - DEVMETHOD(nand_correct_ecc, generic_correct_ecc), - { 0, 0 } -}; - -devclass_t onand_devclass; -devclass_t lnand_devclass; -devclass_t snand_devclass; - -driver_t onand_driver = { - "onand", - onand_methods, - sizeof(struct nand_chip) -}; - -driver_t lnand_driver = { - "lnand", - lnand_methods, - sizeof(struct nand_chip) -}; - -driver_t snand_driver = { - "snand", - snand_methods, - sizeof(struct nand_chip) -}; - -DRIVER_MODULE(onand, nandbus, onand_driver, onand_devclass, 0, 0); -DRIVER_MODULE(lnand, nandbus, lnand_driver, lnand_devclass, 0, 0); -DRIVER_MODULE(snand, nandbus, snand_driver, snand_devclass, 0, 0); - -static int -onfi_nand_probe(device_t dev) -{ - struct nandbus_ivar *ivar; - - ivar = device_get_ivars(dev); - if (ivar && ivar->is_onfi) { - device_set_desc(dev, "ONFI compliant NAND"); - return (BUS_PROBE_DEFAULT); - } - - return (ENODEV); -} - -static int -large_nand_probe(device_t dev) -{ - struct nandbus_ivar *ivar; - - ivar = device_get_ivars(dev); - if (ivar && !ivar->is_onfi && ivar->params->page_size >= 512) { - device_set_desc(dev, ivar->params->name); - return (BUS_PROBE_DEFAULT); - } - - return (ENODEV); -} - -static int -small_nand_probe(device_t dev) -{ - struct nandbus_ivar *ivar; - - ivar = device_get_ivars(dev); - if (ivar && !ivar->is_onfi && ivar->params->page_size == 512) { - device_set_desc(dev, ivar->params->name); - return (BUS_PROBE_DEFAULT); - } - - return (ENODEV); -} - -static int -generic_nand_attach(device_t dev) -{ - struct nand_chip *chip; - struct nandbus_ivar *ivar; - struct onfi_chip_params *onfi_chip_params; - device_t nandbus, nfc; - int err; - - chip = device_get_softc(dev); - chip->dev = dev; - - ivar = device_get_ivars(dev); - chip->id.man_id = ivar->man_id; - chip->id.dev_id = ivar->dev_id; - chip->num = ivar->cs; - - /* TODO remove when HW ECC supported */ - nandbus = device_get_parent(dev); - nfc = device_get_parent(nandbus); - - chip->nand = device_get_softc(nfc); - - if (ivar->is_onfi) { - onfi_chip_params = malloc(sizeof(struct onfi_chip_params), - M_NAND, M_WAITOK | M_ZERO); - - if (onfi_read_parameter(chip, onfi_chip_params)) { - nand_debug(NDBG_GEN,"Could not read parameter page!\n"); - free(onfi_chip_params, M_NAND); - return (ENXIO); - } - - nand_onfi_set_params(chip, onfi_chip_params); - /* Set proper column and row cycles */ - ivar->cols = (onfi_chip_params->address_cycles >> 4) & 0xf; - ivar->rows = onfi_chip_params->address_cycles & 0xf; - free(onfi_chip_params, M_NAND); - - } else { - nand_set_params(chip, ivar->params); - } - - err = nand_init_stat(chip); - if (err) { - generic_nand_detach(dev); - return (err); - } - - err = nand_init_bbt(chip); - if (err) { - generic_nand_detach(dev); - return (err); - } - - err = nand_make_dev(chip); - if (err) { - generic_nand_detach(dev); - return (err); - } - - err = create_geom_disk(chip); - if (err) { - generic_nand_detach(dev); - return (err); - } - - return (0); -} - -static int -generic_nand_detach(device_t dev) -{ - struct nand_chip *chip; - - chip = device_get_softc(dev); - - nand_destroy_bbt(chip); - destroy_geom_disk(chip); - nand_destroy_dev(chip); - nand_destroy_stat(chip); - - return (0); -} - -static int -can_write(device_t nandbus) -{ - uint8_t status; - - if (NANDBUS_WAIT_READY(nandbus, &status)) - return (0); - - if (!(status & NAND_STATUS_WP)) { - nand_debug(NDBG_GEN,"Chip is write-protected"); - return (0); - } - - return (1); -} - -static int -check_fail(device_t nandbus) -{ - uint8_t status; - - NANDBUS_WAIT_READY(nandbus, &status); - if (status & NAND_STATUS_FAIL) { - nand_debug(NDBG_GEN,"Status failed %x", status); - return (ENXIO); - } - - return (0); -} - -static uint16_t -onfi_crc(const void *buf, size_t buflen) -{ - int i, j; - uint16_t crc; - const uint8_t *bufptr; - - bufptr = buf; - crc = 0x4f4e; - for (j = 0; j < buflen; j++) { - crc ^= *bufptr++ << 8; - for (i = 0; i < 8; i++) - if (crc & 0x8000) - crc = (crc << 1) ^ 0x8005; - else - crc <<= 1; - } - return crc; -} - -static int -onfi_read_parameter(struct nand_chip *chip, struct onfi_chip_params *chip_params) -{ - device_t nandbus; - struct onfi_params params; - int found, sigcount, trycopy; - - nand_debug(NDBG_GEN,"read parameter"); - - nandbus = device_get_parent(chip->dev); - - NANDBUS_SELECT_CS(nandbus, chip->num); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_READ_PARAMETER)) - return (ENXIO); - - if (nand_send_address(chip->dev, -1, -1, PAGE_PARAMETER_DEF)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - /* - * XXX Bogus DELAY, we really need a nandbus_wait_ready() here, but it's - * not accessible from here (static to nandbus). - */ - DELAY(1000); - - /* - * The ONFI spec mandates a minimum of three copies of the parameter - * data, so loop up to 3 times trying to find good data. Each copy is - * validated by a signature of "ONFI" and a crc. There is a very strange - * rule that the signature is valid if any 2 of the 4 bytes are correct. - */ - for (found= 0, trycopy = 0; !found && trycopy < 3; trycopy++) { - NANDBUS_READ_BUFFER(nandbus, ¶ms, sizeof(struct onfi_params)); - sigcount = params.signature[0] == 'O'; - sigcount += params.signature[1] == 'N'; - sigcount += params.signature[2] == 'F'; - sigcount += params.signature[3] == 'I'; - if (sigcount < 2) - continue; - if (onfi_crc(¶ms, 254) != params.crc) - continue; - found = 1; - } - if (!found) - return (ENXIO); - - chip_params->luns = params.luns; - chip_params->blocks_per_lun = le32dec(¶ms.blocks_per_lun); - chip_params->pages_per_block = le32dec(¶ms.pages_per_block); - chip_params->bytes_per_page = le32dec(¶ms.bytes_per_page); - chip_params->spare_bytes_per_page = le16dec(¶ms.spare_bytes_per_page); - chip_params->t_bers = le16dec(¶ms.t_bers); - chip_params->t_prog = le16dec(¶ms.t_prog); - chip_params->t_r = le16dec(¶ms.t_r); - chip_params->t_ccs = le16dec(¶ms.t_ccs); - chip_params->features = le16dec(¶ms.features); - chip_params->address_cycles = params.address_cycles; - - return (0); -} - -static int -send_read_page(device_t nand, uint8_t start_command, uint8_t end_command, - uint32_t row, uint32_t column) -{ - device_t nandbus = device_get_parent(nand); - - if (NANDBUS_SEND_COMMAND(nandbus, start_command)) - return (ENXIO); - - if (nand_send_address(nand, row, column, -1)) - return (ENXIO); - - if (NANDBUS_SEND_COMMAND(nandbus, end_command)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - return (0); -} - -static int -generic_read_page(device_t nand, uint32_t page, void *buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p raw read page %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row, - offset)) - return (ENXIO); - - DELAY(chip->t_r); - - NANDBUS_READ_BUFFER(nandbus, buf, len); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_read++; - - return (0); -} - -static int -generic_read_oob(device_t nand, uint32_t page, void* buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p raw read oob %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) { - nand_debug(NDBG_GEN,"page boundary check failed: %08x\n", page); - return (ENXIO); - } - - page_to_row(&chip->chip_geom, page, &row); - - offset += chip->chip_geom.page_size; - - if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row, - offset)) - return (ENXIO); - - DELAY(chip->t_r); - - NANDBUS_READ_BUFFER(nandbus, buf, len); - - if (check_fail(nandbus)) - return (ENXIO); - - return (0); -} - -static int -send_start_program_page(device_t nand, uint32_t row, uint32_t column) -{ - device_t nandbus = device_get_parent(nand); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_PROG)) - return (ENXIO); - - if (nand_send_address(nand, row, column, -1)) - return (ENXIO); - - return (0); -} - -static int -send_end_program_page(device_t nandbus, uint8_t end_command) -{ - - if (NANDBUS_SEND_COMMAND(nandbus, end_command)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - return (0); -} - -static int -generic_program_page(device_t nand, uint32_t page, void *buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p raw prog page %x[%x] at %x", nand, page, len, - offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (send_start_program_page(nand, row, offset)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_END)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_written++; - - return (0); -} - -static int -generic_program_page_intlv(device_t nand, uint32_t page, void *buf, - uint32_t len, uint32_t offset) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p raw prog page %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (send_start_program_page(nand, row, offset)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_INTLV)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_written++; - - return (0); -} - -static int -generic_program_oob(device_t nand, uint32_t page, void* buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p raw prog oob %x[%x] at %x", nand, page, len, - offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - offset += chip->chip_geom.page_size; - - if (!can_write(nandbus)) - return (ENXIO); - - if (send_start_program_page(nand, row, offset)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_END)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - return (0); -} - -static int -send_erase_block(device_t nand, uint32_t row, uint8_t second_command) -{ - device_t nandbus = device_get_parent(nand); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_ERASE)) - return (ENXIO); - - if (nand_send_address(nand, row, -1, -1)) - return (ENXIO); - - if (NANDBUS_SEND_COMMAND(nandbus, second_command)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - return (0); -} - -static int -generic_erase_block(device_t nand, uint32_t block) -{ - struct block_stat *blk_stat; - struct nand_chip *chip; - device_t nandbus; - int row; - - nand_debug(NDBG_GEN,"%p erase block %x", nand, block); - nandbus = device_get_parent(nand); - chip = device_get_softc(nand); - - if (block >= (chip->chip_geom.blks_per_lun * chip->chip_geom.luns)) - return (ENXIO); - - row = (block << chip->chip_geom.blk_shift) & - chip->chip_geom.blk_mask; - - nand_debug(NDBG_GEN,"%p erase block row %x", nand, row); - - if (!can_write(nandbus)) - return (ENXIO); - - send_erase_block(nand, row, NAND_CMD_ERASE_END); - - DELAY(chip->t_bers); - - if (check_fail(nandbus)) - return (ENXIO); - - blk_stat = &(chip->blk_stat[block]); - blk_stat->block_erased++; - - return (0); -} - -static int -generic_erase_block_intlv(device_t nand, uint32_t block) -{ - struct block_stat *blk_stat; - struct nand_chip *chip; - device_t nandbus; - int row; - - nand_debug(NDBG_GEN,"%p erase block %x", nand, block); - nandbus = device_get_parent(nand); - chip = device_get_softc(nand); - - if (block >= (chip->chip_geom.blks_per_lun * chip->chip_geom.luns)) - return (ENXIO); - - row = (block << chip->chip_geom.blk_shift) & - chip->chip_geom.blk_mask; - - if (!can_write(nandbus)) - return (ENXIO); - - send_erase_block(nand, row, NAND_CMD_ERASE_INTLV); - - DELAY(chip->t_bers); - - if (check_fail(nandbus)) - return (ENXIO); - - blk_stat = &(chip->blk_stat[block]); - blk_stat->block_erased++; - - return (0); - -} - -static int -onfi_is_blk_bad(device_t device, uint32_t block_number, uint8_t *bad) -{ - struct nand_chip *chip; - int page_number, i, j, err; - uint8_t *oob; - - chip = device_get_softc(device); - - oob = malloc(chip->chip_geom.oob_size, M_NAND, M_WAITOK); - - page_number = block_number * chip->chip_geom.pgs_per_blk; - *bad = 0; - /* Check OOB of first and last page */ - for (i = 0; i < 2; i++, page_number+= chip->chip_geom.pgs_per_blk - 1) { - err = generic_read_oob(device, page_number, oob, - chip->chip_geom.oob_size, 0); - if (err) { - device_printf(device, "%s: cannot allocate oob\n", - __func__); - free(oob, M_NAND); - return (ENOMEM); - } - - for (j = 0; j < chip->chip_geom.oob_size; j++) { - if (!oob[j]) { - *bad = 1; - free(oob, M_NAND); - return (0); - } - } - } - - free(oob, M_NAND); - - return (0); -} - -static int -send_small_read_page(device_t nand, uint8_t start_command, - uint32_t row, uint32_t column) -{ - device_t nandbus = device_get_parent(nand); - - if (NANDBUS_SEND_COMMAND(nandbus, start_command)) - return (ENXIO); - - if (nand_send_address(nand, row, column, -1)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - return (0); -} - - -static int -small_read_page(device_t nand, uint32_t page, void *buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p small read page %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (offset < 256) { - if (send_small_read_page(nand, NAND_CMD_SMALLA, row, offset)) - return (ENXIO); - } else { - offset -= 256; - if (send_small_read_page(nandbus, NAND_CMD_SMALLB, row, offset)) - return (ENXIO); - } - - DELAY(chip->t_r); - - NANDBUS_READ_BUFFER(nandbus, buf, len); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_read++; - - return (0); -} - -static int -small_read_oob(device_t nand, uint32_t page, void *buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p small read oob %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (send_small_read_page(nand, NAND_CMD_SMALLOOB, row, 0)) - return (ENXIO); - - DELAY(chip->t_r); - - NANDBUS_READ_BUFFER(nandbus, buf, len); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_read++; - - return (0); -} - -static int -small_program_page(device_t nand, uint32_t page, void* buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p small prog page %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (offset < 256) { - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SMALLA)) - return (ENXIO); - } else { - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SMALLB)) - return (ENXIO); - } - - if (send_start_program_page(nand, row, offset)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_END)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - return (0); -} - -static int -small_program_oob(device_t nand, uint32_t page, void* buf, uint32_t len, - uint32_t offset) -{ - struct nand_chip *chip; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"%p small prog oob %x[%x] at %x", nand, page, len, offset); - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SMALLOOB)) - return (ENXIO); - - if (send_start_program_page(nand, row, offset)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_END)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - return (0); -} - -int -nand_send_address(device_t nand, int32_t row, int32_t col, int8_t id) -{ - struct nandbus_ivar *ivar; - device_t nandbus; - uint8_t addr; - int err = 0; - int i; - - nandbus = device_get_parent(nand); - ivar = device_get_ivars(nand); - - if (id != -1) { - nand_debug(NDBG_GEN,"send_address: send id %02x", id); - err = NANDBUS_SEND_ADDRESS(nandbus, id); - } - - if (!err && col != -1) { - for (i = 0; i < ivar->cols; i++, col >>= 8) { - addr = (uint8_t)(col & 0xff); - nand_debug(NDBG_GEN,"send_address: send address column " - "%02x", addr); - err = NANDBUS_SEND_ADDRESS(nandbus, addr); - if (err) - break; - } - } - - if (!err && row != -1) { - for (i = 0; i < ivar->rows; i++, row >>= 8) { - addr = (uint8_t)(row & 0xff); - nand_debug(NDBG_GEN,"send_address: send address row " - "%02x", addr); - err = NANDBUS_SEND_ADDRESS(nandbus, addr); - if (err) - break; - } - } - - return (err); -} - -static int -generic_is_blk_bad(device_t dev, uint32_t block, uint8_t *bad) -{ - struct nand_chip *chip; - int page_number, err, i; - uint8_t *oob; - - chip = device_get_softc(dev); - - oob = malloc(chip->chip_geom.oob_size, M_NAND, M_WAITOK); - - page_number = block * chip->chip_geom.pgs_per_blk; - *bad = 0; - - /* Check OOB of first and second page */ - for (i = 0; i < 2; i++) { - err = NAND_READ_OOB(dev, page_number + i, oob, - chip->chip_geom.oob_size, 0); - if (err) { - device_printf(dev, "%s: cannot allocate OOB\n", - __func__); - free(oob, M_NAND); - return (ENOMEM); - } - - if (!oob[0]) { - *bad = 1; - free(oob, M_NAND); - return (0); - } - } - - free(oob, M_NAND); - - return (0); -} - -static int -generic_get_ecc(device_t dev, void *buf, void *ecc, int *needwrite) -{ - struct nand_chip *chip = device_get_softc(dev); - struct chip_geom *cg = &chip->chip_geom; - - return (NANDBUS_GET_ECC(device_get_parent(dev), buf, cg->page_size, - ecc, needwrite)); -} - -static int -generic_correct_ecc(device_t dev, void *buf, void *readecc, void *calcecc) -{ - struct nand_chip *chip = device_get_softc(dev); - struct chip_geom *cg = &chip->chip_geom; - - return (NANDBUS_CORRECT_ECC(device_get_parent(dev), buf, - cg->page_size, readecc, calcecc)); -} - - -#if 0 -int -nand_chng_read_col(device_t nand, uint32_t col, void *buf, size_t len) -{ - struct nand_chip *chip; - device_t nandbus; - - chip = device_get_softc(nand); - nandbus = device_get_parent(nand); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_READ_COL)) - return (ENXIO); - - if (NANDBUS_SEND_ADDRESS(nandbus, -1, col, -1)) - return (ENXIO); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_READ_COL_END)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - if (buf != NULL && len > 0) - NANDBUS_READ_BUFFER(nandbus, buf, len); - - return (0); -} - -int -nand_chng_write_col(device_t dev, uint32_t col, void *buf, - size_t len) -{ - struct nand_chip *chip; - device_t nandbus; - - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_WRITE_COL)) - return (ENXIO); - - if (NANDBUS_SEND_ADDRESS(nandbus, -1, col, -1)) - return (ENXIO); - - if (buf != NULL && len > 0) - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_READ_COL_END)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - return (0); -} - -int -nand_copyback_read(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN," raw read page %x[%x] at %x", page, col, len); - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_CPBK, row, 0)) - return (ENXIO); - - DELAY(chip->t_r); - if (check_fail(nandbus)) - return (ENXIO); - - if (buf != NULL && len > 0) - NANDBUS_READ_BUFFER(nandbus, buf, len); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_read++; - - return (0); -} - -int -nand_copyback_prog(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"copyback prog page %x[%x]", page, len); - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_CHNG_WRITE_COL)) - return (ENXIO); - - if (NANDBUS_SEND_ADDRESS(nandbus, row, col, -1)) - return (ENXIO); - - if (buf != NULL && len > 0) - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_END)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_written++; - - return (0); -} - -int -nand_copyback_prog_intlv(device_t dev, uint32_t page) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - - nand_debug(NDBG_GEN,"cache prog page %x", page); - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (send_start_program_page(nand, row, 0)) - return (ENXIO); - - if (send_end_program_page(nandbus, NAND_CMD_PROG_INTLV)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_written++; - - return (0); -} - -int -nand_prog_cache(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len, uint8_t end) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - uint8_t command; - - nand_debug(NDBG_GEN,"cache prog page %x[%x]", page, len); - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (!can_write(nandbus)) - return (ENXIO); - - if (send_start_program_page(dev, row, 0)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, len); - - if (end) - command = NAND_CMD_PROG_END; - else - command = NAND_CMD_PROG_CACHE; - - if (send_end_program_page(nandbus, command)) - return (ENXIO); - - DELAY(chip->t_prog); - - if (check_fail(nandbus)) - return (ENXIO); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_written++; - - return (0); -} - -int -nand_read_cache(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len, uint8_t end) -{ - struct nand_chip *chip; - struct page_stat *pg_stat; - device_t nandbus; - uint32_t row; - uint8_t command; - - nand_debug(NDBG_GEN,"cache read page %x[%x] ", page, len); - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (nand_check_page_boundary(chip, page)) - return (ENXIO); - - page_to_row(&chip->chip_geom, page, &row); - - if (page != -1) { - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_READ)) - return (ENXIO); - - if (NANDBUS_SEND_ADDRESS(nandbus, row, col, -1)) - return (ENXIO); - } - - if (end) - command = NAND_CMD_READ_CACHE_END; - else - command = NAND_CMD_READ_CACHE; - - if (NANDBUS_SEND_COMMAND(nandbus, command)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - DELAY(chip->t_r); - if (check_fail(nandbus)) - return (ENXIO); - - if (buf != NULL && len > 0) - NANDBUS_READ_BUFFER(nandbus, buf, len); - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_raw_read++; - - return (0); -} - -int -nand_get_feature(device_t dev, uint8_t feat, void *buf) -{ - struct nand_chip *chip; - device_t nandbus; - - nand_debug(NDBG_GEN,"nand get feature"); - - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_GET_FEATURE)) - return (ENXIO); - - if (NANDBUS_SEND_ADDRESS(nandbus, -1, -1, feat)) - return (ENXIO); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - DELAY(chip->t_r); - NANDBUS_READ_BUFFER(nandbus, buf, 4); - - return (0); -} - -int -nand_set_feature(device_t dev, uint8_t feat, void *buf) -{ - struct nand_chip *chip; - device_t nandbus; - - nand_debug(NDBG_GEN,"nand set feature"); - - chip = device_get_softc(dev); - nandbus = device_get_parent(dev); - - if (NANDBUS_SEND_COMMAND(nandbus, NAND_CMD_SET_FEATURE)) - return (ENXIO); - - if (NANDBUS_SEND_ADDRESS(nandbus, -1, -1, feat)) - return (ENXIO); - - NANDBUS_WRITE_BUFFER(nandbus, buf, 4); - - if (NANDBUS_START_COMMAND(nandbus)) - return (ENXIO); - - return (0); -} -#endif Property changes on: head/sys/dev/nand/nand_generic.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand_ecc_pos.h =================================================================== --- head/sys/dev/nand/nand_ecc_pos.h (revision 349351) +++ head/sys/dev/nand/nand_ecc_pos.h (nonexistent) @@ -1,58 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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_NAND_ECC_POS_H_ -#define _DEV_NAND_ECC_POS_H_ - -static uint16_t default_software_ecc_positions_16[] = {2, 0, 1, 7, 4, 6}; - -static uint16_t default_software_ecc_positions_64[] = { - - 42, 40, 41, 45, 43, 44, 48, 46, - 47, 51, 49, 50, 54, 52, 53, 57, - 55, 56, 60, 58, 59, 63, 61, 62 -}; - -static uint16_t default_software_ecc_positions_128[] = { - 8, 9, 10, 11, 12, 13, - 18, 19, 20, 21, 22, 23, - 28, 29, 30, 31, 32, 33, - 38, 39, 40, 41, 42, 43, - 48, 49, 50, 51, 52, 53, - 58, 59, 60, 61, 62, 63, - 68, 69, 70, 71, 72, 73, - 78, 79, 80, 81, 82, 83, - 88, 89, 90, 91, 92, 93, - 98, 99, 100, 101, 102, 103, - 108, 109, 110, 111, 112, 113, - 118, 119, 120, 121, 122, 123, -}; -#endif /* _DEV_NAND_ECC_POS_H_ */ - Property changes on: head/sys/dev/nand/nand_ecc_pos.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_swap.c =================================================================== --- head/sys/dev/nand/nandsim_swap.c (revision 349351) +++ head/sys/dev/nand/nandsim_swap.c (nonexistent) @@ -1,383 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -static int init_block_state(struct chip_swap *); -static void destroy_block_state(struct chip_swap *); - -static int create_buffers(struct chip_swap *); -static void destroy_buffers(struct chip_swap *); - -static int swap_file_open(struct chip_swap *, const char *); -static void swap_file_close(struct chip_swap *); -static int swap_file_write(struct chip_swap *, struct block_state *); -static int swap_file_read(struct chip_swap *, struct block_state *); - -#define CHIP_SWAP_CMODE 0600 -#define CHIP_SWAP_BLOCKSPACES 2 - -static int -init_block_state(struct chip_swap *swap) -{ - struct block_state *blk_state; - int i; - - if (swap == NULL) - return (-1); - - blk_state = malloc(swap->nof_blks * sizeof(struct block_state), - M_NANDSIM, M_WAITOK | M_ZERO); - - for (i = 0; i < swap->nof_blks; i++) - blk_state[i].offset = 0xffffffff; - - swap->blk_state = blk_state; - - return (0); -} - -static void -destroy_block_state(struct chip_swap *swap) -{ - - if (swap == NULL) - return; - - if (swap->blk_state != NULL) - free(swap->blk_state, M_NANDSIM); -} - -static int -create_buffers(struct chip_swap *swap) -{ - struct block_space *block_space; - void *block; - int i; - - for (i = 0; i < CHIP_SWAP_BLOCKSPACES; i++) { - block_space = malloc(sizeof(*block_space), M_NANDSIM, M_WAITOK); - block = malloc(swap->blk_size, M_NANDSIM, M_WAITOK); - block_space->blk_ptr = block; - SLIST_INSERT_HEAD(&swap->free_bs, block_space, free_link); - nand_debug(NDBG_SIM,"created blk_space %p[%p]\n", block_space, - block); - } - - if (i == 0) - return (-1); - - return (0); -} - -static void -destroy_buffers(struct chip_swap *swap) -{ - struct block_space *blk_space; - - if (swap == NULL) - return; - - blk_space = SLIST_FIRST(&swap->free_bs); - while (blk_space) { - SLIST_REMOVE_HEAD(&swap->free_bs, free_link); - nand_debug(NDBG_SIM,"destroyed blk_space %p[%p]\n", - blk_space, blk_space->blk_ptr); - free(blk_space->blk_ptr, M_NANDSIM); - free(blk_space, M_NANDSIM); - blk_space = SLIST_FIRST(&swap->free_bs); - } - - blk_space = STAILQ_FIRST(&swap->used_bs); - while (blk_space) { - STAILQ_REMOVE_HEAD(&swap->used_bs, used_link); - nand_debug(NDBG_SIM,"destroyed blk_space %p[%p]\n", - blk_space, blk_space->blk_ptr); - free(blk_space->blk_ptr, M_NANDSIM); - free(blk_space, M_NANDSIM); - blk_space = STAILQ_FIRST(&swap->used_bs); - } -} - -static int -swap_file_open(struct chip_swap *swap, const char *swap_file) -{ - struct nameidata nd; - int flags, error; - - NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, swap_file, - curthread); - - flags = FWRITE | FREAD | O_NOFOLLOW | O_CREAT | O_TRUNC; - - error = vn_open(&nd, &flags, CHIP_SWAP_CMODE, NULL); - if (error) { - nand_debug(NDBG_SIM,"Cannot create swap file %s", swap_file); - NDFREE(&nd, NDF_ONLY_PNBUF); - return (error); - } - - swap->swap_cred = crhold(curthread->td_ucred); - NDFREE(&nd, NDF_ONLY_PNBUF); - - /* We just unlock so we hold a reference */ - VOP_UNLOCK(nd.ni_vp, 0); - - swap->swap_vp = nd.ni_vp; - - return (0); -} - -static void -swap_file_close(struct chip_swap *swap) -{ - - if (swap == NULL) - return; - - if (swap->swap_vp == NULL) - return; - - vn_close(swap->swap_vp, FWRITE, swap->swap_cred, curthread); - crfree(swap->swap_cred); -} - -static int -swap_file_write(struct chip_swap *swap, struct block_state *blk_state) -{ - struct block_space *blk_space; - struct thread *td; - struct mount *mp; - struct vnode *vp; - struct uio auio; - struct iovec aiov; - - if (swap == NULL || blk_state == NULL) - return (-1); - - blk_space = blk_state->blk_sp; - if (blk_state->offset == -1) { - blk_state->offset = swap->swap_offset; - swap->swap_offset += swap->blk_size; - } - - nand_debug(NDBG_SIM,"saving %p[%p] at %x\n", - blk_space, blk_space->blk_ptr, blk_state->offset); - - bzero(&aiov, sizeof(aiov)); - bzero(&auio, sizeof(auio)); - - aiov.iov_base = blk_space->blk_ptr; - aiov.iov_len = swap->blk_size; - td = curthread; - vp = swap->swap_vp; - - auio.uio_iov = &aiov; - auio.uio_offset = blk_state->offset; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_WRITE; - auio.uio_iovcnt = 1; - auio.uio_resid = swap->blk_size; - auio.uio_td = td; - - vn_start_write(vp, &mp, V_WAIT); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - VOP_WRITE(vp, &auio, IO_UNIT, swap->swap_cred); - VOP_UNLOCK(vp, 0); - vn_finished_write(mp); - - return (0); -} - -static int -swap_file_read(struct chip_swap *swap, struct block_state *blk_state) -{ - struct block_space *blk_space; - struct thread *td; - struct vnode *vp; - struct uio auio; - struct iovec aiov; - - if (swap == NULL || blk_state == NULL) - return (-1); - - blk_space = blk_state->blk_sp; - - nand_debug(NDBG_SIM,"restore %p[%p] at %x\n", - blk_space, blk_space->blk_ptr, blk_state->offset); - - bzero(&aiov, sizeof(aiov)); - bzero(&auio, sizeof(auio)); - - aiov.iov_base = blk_space->blk_ptr; - aiov.iov_len = swap->blk_size; - td = curthread; - vp = swap->swap_vp; - - auio.uio_iov = &aiov; - auio.uio_offset = blk_state->offset; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_READ; - auio.uio_iovcnt = 1; - auio.uio_resid = swap->blk_size; - auio.uio_td = td; - - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - VOP_READ(vp, &auio, 0, swap->swap_cred); - VOP_UNLOCK(vp, 0); - - return (0); -} - -struct chip_swap * -nandsim_swap_init(const char *swap_file, uint32_t nof_blks, uint32_t blk_size) -{ - struct chip_swap *swap; - int err = 0; - - if ((swap_file == NULL) || (nof_blks == 0) || (blk_size == 0)) - return (NULL); - - swap = malloc(sizeof(*swap), M_NANDSIM, M_WAITOK | M_ZERO); - - SLIST_INIT(&swap->free_bs); - STAILQ_INIT(&swap->used_bs); - swap->blk_size = blk_size; - swap->nof_blks = nof_blks; - - err = init_block_state(swap); - if (err) { - nandsim_swap_destroy(swap); - return (NULL); - } - - err = create_buffers(swap); - if (err) { - nandsim_swap_destroy(swap); - return (NULL); - } - - err = swap_file_open(swap, swap_file); - if (err) { - nandsim_swap_destroy(swap); - return (NULL); - } - - return (swap); -} - -void -nandsim_swap_destroy(struct chip_swap *swap) -{ - - if (swap == NULL) - return; - - destroy_block_state(swap); - destroy_buffers(swap); - swap_file_close(swap); - free(swap, M_NANDSIM); -} - -struct block_space * -get_bs(struct chip_swap *swap, uint32_t block, uint8_t writing) -{ - struct block_state *blk_state, *old_blk_state = NULL; - struct block_space *blk_space; - - if (swap == NULL || (block >= swap->nof_blks)) - return (NULL); - - blk_state = &swap->blk_state[block]; - nand_debug(NDBG_SIM,"blk_state %x\n", blk_state->status); - - if (blk_state->status & BLOCK_ALLOCATED) { - blk_space = blk_state->blk_sp; - } else { - blk_space = SLIST_FIRST(&swap->free_bs); - if (blk_space) { - SLIST_REMOVE_HEAD(&swap->free_bs, free_link); - STAILQ_INSERT_TAIL(&swap->used_bs, blk_space, - used_link); - } else { - blk_space = STAILQ_FIRST(&swap->used_bs); - old_blk_state = blk_space->blk_state; - STAILQ_REMOVE_HEAD(&swap->used_bs, used_link); - STAILQ_INSERT_TAIL(&swap->used_bs, blk_space, - used_link); - if (old_blk_state->status & BLOCK_DIRTY) { - swap_file_write(swap, old_blk_state); - old_blk_state->status &= ~BLOCK_DIRTY; - old_blk_state->status |= BLOCK_SWAPPED; - } - } - } - - if (blk_space == NULL) - return (NULL); - - if (old_blk_state != NULL) { - old_blk_state->status &= ~BLOCK_ALLOCATED; - old_blk_state->blk_sp = NULL; - } - - blk_state->blk_sp = blk_space; - blk_space->blk_state = blk_state; - - if (!(blk_state->status & BLOCK_ALLOCATED)) { - if (blk_state->status & BLOCK_SWAPPED) - swap_file_read(swap, blk_state); - else - memset(blk_space->blk_ptr, 0xff, swap->blk_size); - blk_state->status |= BLOCK_ALLOCATED; - } - - if (writing) - blk_state->status |= BLOCK_DIRTY; - - nand_debug(NDBG_SIM,"get_bs returned %p[%p] state %x\n", blk_space, - blk_space->blk_ptr, blk_state->status); - - return (blk_space); -} Property changes on: head/sys/dev/nand/nandsim_swap.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandbus.c =================================================================== --- head/sys/dev/nand/nandbus.c (revision 349351) +++ head/sys/dev/nand/nandbus.c (nonexistent) @@ -1,542 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "nand_if.h" -#include "nandbus_if.h" -#include "nfc_if.h" - -#define NAND_NCS 4 - -static int nandbus_probe(device_t dev); -static int nandbus_attach(device_t dev); -static int nandbus_detach(device_t dev); - -static int nandbus_child_location_str(device_t, device_t, char *, size_t); -static int nandbus_child_pnpinfo_str(device_t, device_t, char *, size_t); - -static int nandbus_get_status(device_t, uint8_t *); -static void nandbus_read_buffer(device_t, void *, uint32_t); -static int nandbus_select_cs(device_t, uint8_t); -static int nandbus_send_command(device_t, uint8_t); -static int nandbus_send_address(device_t, uint8_t); -static int nandbus_start_command(device_t); -static int nandbus_wait_ready(device_t, uint8_t *); -static void nandbus_write_buffer(device_t, void *, uint32_t); -static int nandbus_get_ecc(device_t, void *, uint32_t, void *, int *); -static int nandbus_correct_ecc(device_t, void *, int, void *, void *); -static void nandbus_lock(device_t); -static void nandbus_unlock(device_t); - -static int nand_readid(device_t, uint8_t *, uint8_t *); -static int nand_probe_onfi(device_t, uint8_t *); -static int nand_reset(device_t); - -struct nandbus_softc { - device_t dev; - struct cv nandbus_cv; - struct mtx nandbus_mtx; - uint8_t busy; -}; - -static device_method_t nandbus_methods[] = { - /* device interface */ - DEVMETHOD(device_probe, nandbus_probe), - DEVMETHOD(device_attach, nandbus_attach), - DEVMETHOD(device_detach, nandbus_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - - /* bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_child_pnpinfo_str, nandbus_child_pnpinfo_str), - DEVMETHOD(bus_child_location_str, nandbus_child_location_str), - - /* nandbus interface */ - DEVMETHOD(nandbus_get_status, nandbus_get_status), - DEVMETHOD(nandbus_read_buffer, nandbus_read_buffer), - DEVMETHOD(nandbus_select_cs, nandbus_select_cs), - DEVMETHOD(nandbus_send_command, nandbus_send_command), - DEVMETHOD(nandbus_send_address, nandbus_send_address), - DEVMETHOD(nandbus_start_command,nandbus_start_command), - DEVMETHOD(nandbus_wait_ready, nandbus_wait_ready), - DEVMETHOD(nandbus_write_buffer, nandbus_write_buffer), - DEVMETHOD(nandbus_get_ecc, nandbus_get_ecc), - DEVMETHOD(nandbus_correct_ecc, nandbus_correct_ecc), - DEVMETHOD(nandbus_lock, nandbus_lock), - DEVMETHOD(nandbus_unlock, nandbus_unlock), - { 0, 0 } -}; - -devclass_t nandbus_devclass; - -driver_t nandbus_driver = { - "nandbus", - nandbus_methods, - sizeof(struct nandbus_softc) -}; - -DRIVER_MODULE(nandbus, nand, nandbus_driver, nandbus_devclass, 0, 0); - -int -nandbus_create(device_t nfc) -{ - device_t child; - - child = device_add_child(nfc, "nandbus", -1); - if (!child) - return (ENODEV); - - bus_generic_attach(nfc); - - return(0); -} - -void -nandbus_destroy(device_t nfc) -{ - device_t *children; - int nchildren, i; - - mtx_lock(&Giant); - /* Detach & delete all children */ - if (!device_get_children(nfc, &children, &nchildren)) { - for (i = 0; i < nchildren; i++) - device_delete_child(nfc, children[i]); - - free(children, M_TEMP); - } - mtx_unlock(&Giant); -} - -static int -nandbus_probe(device_t dev) -{ - - device_set_desc(dev, "NAND bus"); - - return (0); -} - -static int -nandbus_attach(device_t dev) -{ - device_t child, nfc; - struct nand_id chip_id; - struct nandbus_softc *sc; - struct nandbus_ivar *ivar; - struct nand_softc *nfc_sc; - struct nand_params *chip_params; - uint8_t cs, onfi; - - sc = device_get_softc(dev); - sc->dev = dev; - - nfc = device_get_parent(dev); - nfc_sc = device_get_softc(nfc); - - mtx_init(&sc->nandbus_mtx, "nandbus lock", NULL, MTX_DEF); - cv_init(&sc->nandbus_cv, "nandbus cv"); - - /* Check each possible CS for existing nand devices */ - for (cs = 0; cs < NAND_NCS; cs++) { - nand_debug(NDBG_BUS,"probe chip select %x", cs); - - /* Select & reset chip */ - if (nandbus_select_cs(dev, cs)) - break; - - if (nand_reset(dev)) - continue; - - /* Read manufacturer and device id */ - if (nand_readid(dev, &chip_id.man_id, &chip_id.dev_id)) - continue; - - if (chip_id.man_id == 0xff) - continue; - - /* - * First try to get info from the table. If that fails, see if - * the chip can provide ONFI info. We check the table first to - * allow table entries to override info from chips that are - * known to provide bad ONFI data. - */ - onfi = 0; - chip_params = nand_get_params(&chip_id); - if (chip_params == NULL) { - nand_probe_onfi(dev, &onfi); - } - - /* - * At this point it appears there is a chip at this chipselect, - * so if we can't work with it, whine about it. - */ - if (chip_params == NULL && onfi == 0) { - if (bootverbose || (nand_debug_flag & NDBG_BUS)) - printf("Chip params not found, chipsel: %d " - "(manuf: 0x%0x, chipid: 0x%0x, onfi: %d)\n", - cs, chip_id.man_id, chip_id.dev_id, onfi); - continue; - } - - ivar = malloc(sizeof(struct nandbus_ivar), - M_NAND, M_WAITOK); - - if (onfi == 1) { - ivar->cs = cs; - ivar->cols = 0; - ivar->rows = 0; - ivar->params = NULL; - ivar->man_id = chip_id.man_id; - ivar->dev_id = chip_id.dev_id; - ivar->is_onfi = onfi; - ivar->chip_cdev_name = nfc_sc->chip_cdev_name; - - child = device_add_child(dev, NULL, -1); - device_set_ivars(child, ivar); - continue; - } - - ivar->cs = cs; - ivar->cols = 1; - ivar->rows = 2; - ivar->params = chip_params; - ivar->man_id = chip_id.man_id; - ivar->dev_id = chip_id.dev_id; - ivar->is_onfi = onfi; - ivar->chip_cdev_name = nfc_sc->chip_cdev_name; - - /* - * Check what type of device we have. - * devices bigger than 32MiB have on more row (3) - */ - if (chip_params->chip_size > 32) - ivar->rows++; - /* Large page devices have one more col (2) */ - if (chip_params->chip_size >= 128 && - chip_params->page_size > 512) - ivar->cols++; - - child = device_add_child(dev, NULL, -1); - device_set_ivars(child, ivar); - } - - bus_generic_attach(dev); - return (0); -} - -static int -nandbus_detach(device_t dev) -{ - struct nandbus_softc *sc; - - sc = device_get_softc(dev); - - bus_generic_detach(dev); - - mtx_destroy(&sc->nandbus_mtx); - cv_destroy(&sc->nandbus_cv); - - return (0); -} - -static int -nandbus_child_location_str(device_t bus, device_t child, char *buf, - size_t buflen) -{ - struct nandbus_ivar *ivar = device_get_ivars(child); - - snprintf(buf, buflen, "at cs#%d", ivar->cs); - return (0); -} - -static int -nandbus_child_pnpinfo_str(device_t bus, device_t child, char *buf, - size_t buflen) -{ - // XXX man id, model id ???? - *buf = '\0'; - return (0); -} - -static int -nand_readid(device_t bus, uint8_t *man_id, uint8_t *dev_id) -{ - device_t nfc; - - if (!bus || !man_id || !dev_id) - return (EINVAL); - - nand_debug(NDBG_BUS,"read id"); - - nfc = device_get_parent(bus); - - if (NFC_SEND_COMMAND(nfc, NAND_CMD_READ_ID)) { - nand_debug(NDBG_BUS,"Error : could not send READ ID command"); - return (ENXIO); - } - - if (NFC_SEND_ADDRESS(nfc, 0)) { - nand_debug(NDBG_BUS,"Error : could not sent address to chip"); - return (ENXIO); - } - - if (NFC_START_COMMAND(nfc) != 0) { - nand_debug(NDBG_BUS,"Error : could not start command"); - return (ENXIO); - } - - DELAY(25); - - *man_id = NFC_READ_BYTE(nfc); - *dev_id = NFC_READ_BYTE(nfc); - - nand_debug(NDBG_BUS,"manufacturer id: %x chip id: %x", *man_id, - *dev_id); - - return (0); -} - -static int -nand_probe_onfi(device_t bus, uint8_t *onfi_compliant) -{ - device_t nfc; - char onfi_id[] = {'O', 'N', 'F', 'I', '\0'}; - int i; - - nand_debug(NDBG_BUS,"probing ONFI"); - - nfc = device_get_parent(bus); - - if (NFC_SEND_COMMAND(nfc, NAND_CMD_READ_ID)) { - nand_debug(NDBG_BUS,"Error : could not sent READ ID command"); - return (ENXIO); - } - - if (NFC_SEND_ADDRESS(nfc, ONFI_SIG_ADDR)) { - nand_debug(NDBG_BUS,"Error : could not sent address to chip"); - return (ENXIO); - } - - if (NFC_START_COMMAND(nfc) != 0) { - nand_debug(NDBG_BUS,"Error : could not start command"); - return (ENXIO); - } - for (i = 0; onfi_id[i] != '\0'; i++) - if (NFC_READ_BYTE(nfc) != onfi_id[i]) { - nand_debug(NDBG_BUS,"ONFI non-compliant"); - *onfi_compliant = 0; - return (0); - } - - nand_debug(NDBG_BUS,"ONFI compliant"); - *onfi_compliant = 1; - - return (0); -} - -static int -nand_reset(device_t bus) -{ - device_t nfc; - nand_debug(NDBG_BUS,"resetting..."); - - nfc = device_get_parent(bus); - - if (NFC_SEND_COMMAND(nfc, NAND_CMD_RESET) != 0) { - nand_debug(NDBG_BUS,"Error : could not sent RESET command"); - return (ENXIO); - } - - if (NFC_START_COMMAND(nfc) != 0) { - nand_debug(NDBG_BUS,"Error : could not start RESET command"); - return (ENXIO); - } - - DELAY(1000); - - return (0); -} - -void -nandbus_lock(device_t dev) -{ - struct nandbus_softc *sc; - - sc = device_get_softc(dev); - - mtx_lock(&sc->nandbus_mtx); - if (sc->busy) - cv_wait(&sc->nandbus_cv, &sc->nandbus_mtx); - sc->busy = 1; - mtx_unlock(&sc->nandbus_mtx); -} - -void -nandbus_unlock(device_t dev) -{ - struct nandbus_softc *sc; - - sc = device_get_softc(dev); - - mtx_lock(&sc->nandbus_mtx); - sc->busy = 0; - cv_signal(&sc->nandbus_cv); - mtx_unlock(&sc->nandbus_mtx); -} - -int -nandbus_select_cs(device_t dev, uint8_t cs) -{ - - return (NFC_SELECT_CS(device_get_parent(dev), cs)); -} - -int -nandbus_send_command(device_t dev, uint8_t command) -{ - int err; - - if ((err = NFC_SEND_COMMAND(device_get_parent(dev), command))) - nand_debug(NDBG_BUS,"Err: Could not send command %x, err %x", - command, err); - - return (err); -} - -int -nandbus_send_address(device_t dev, uint8_t address) -{ - int err; - - if ((err = NFC_SEND_ADDRESS(device_get_parent(dev), address))) - nand_debug(NDBG_BUS,"Err: Could not send address %x, err %x", - address, err); - - return (err); -} - -int -nandbus_start_command(device_t dev) -{ - int err; - - if ((err = NFC_START_COMMAND(device_get_parent(dev)))) - nand_debug(NDBG_BUS,"Err: Could not start command, err %x", - err); - - return (err); -} - -void -nandbus_read_buffer(device_t dev, void *buf, uint32_t len) -{ - - NFC_READ_BUF(device_get_parent(dev), buf, len); -} - -void -nandbus_write_buffer(device_t dev, void *buf, uint32_t len) -{ - - NFC_WRITE_BUF(device_get_parent(dev), buf, len); -} - -int -nandbus_get_status(device_t dev, uint8_t *status) -{ - int err; - - if ((err = NANDBUS_SEND_COMMAND(dev, NAND_CMD_STATUS))) - return (err); - if ((err = NANDBUS_START_COMMAND(dev))) - return (err); - - *status = NFC_READ_BYTE(device_get_parent(dev)); - - return (0); -} - -int -nandbus_wait_ready(device_t dev, uint8_t *status) -{ - struct timeval tv, tv2; - - tv2.tv_sec = 0; - tv2.tv_usec = 50 * 5000; /* 250ms */ - - getmicrotime(&tv); - timevaladd(&tv, &tv2); - - do { - if (NANDBUS_GET_STATUS(dev, status)) - return (ENXIO); - - if (*status & NAND_STATUS_RDY) - return (0); - - getmicrotime(&tv2); - } while (timevalcmp(&tv2, &tv, <=)); - - return (EBUSY); -} - -int -nandbus_get_ecc(device_t dev, void *buf, uint32_t pagesize, void *ecc, - int *needwrite) -{ - - return (NFC_GET_ECC(device_get_parent(dev), buf, pagesize, ecc, needwrite)); -} - -int -nandbus_correct_ecc(device_t dev, void *buf, int pagesize, void *readecc, - void *calcecc) -{ - - return (NFC_CORRECT_ECC(device_get_parent(dev), buf, pagesize, - readecc, calcecc)); -} - Property changes on: head/sys/dev/nand/nandbus.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nfc_fsl.h =================================================================== --- head/sys/dev/nand/nfc_fsl.h (revision 349351) +++ head/sys/dev/nand/nfc_fsl.h (nonexistent) @@ -1,99 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2012 Juniper Networks, Inc. - * Copyright (C) 2009-2012 Semihalf - * 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 _NAND_NFC_FSL_H_ -#define _NAND_NFC_FSL_H_ - -/* LBC BR/OR Registers layout definitions */ -#define BR_V 0x00000001 -#define BR_V_SHIFT 0 -#define BR_MSEL 0x000000E0 -#define BR_MSEL_SHIFT 5 -#define BR_DECC_CHECK_MODE 0x00000600 -#define BR_DECC_CHECK_GEN 0x00000400 - -#define OR_FCM_PAGESIZE 0x00000400 - -/* Options definitions */ -#define NAND_OPT_ECC_MODE_HW 1 -#define NAND_OPT_ECC_MODE_SOFT (1 << 1) - -/* FMR - Flash Mode Register */ -#define FMR_CWTO 0xF000 -#define FMR_CWTO_SHIFT 12 -#define FMR_BOOT 0x0800 -#define FMR_ECCM 0x0100 -#define FMR_AL 0x0030 -#define FMR_AL_SHIFT 4 -#define FMR_OP 0x0003 -#define FMR_OP_SHIFT 0 - -#define FIR_OP_NOP 0x0 /* No operation and end of sequence */ -#define FIR_OP_CA 0x1 /* Issue current column address */ -#define FIR_OP_PA 0x2 /* Issue current block+page address */ -#define FIR_OP_UA 0x3 /* Issue user defined address */ -#define FIR_OP_CM(x) (4 + (x)) /* Issue command from FCR[CMD(x)] */ -#define FIR_OP_WB 0x8 /* Write FBCR bytes from FCM buffer */ -#define FIR_OP_WS 0x9 /* Write 1 or 2 bytes from MDR[AS] */ -#define FIR_OP_RB 0xA /* Read FBCR bytes to FCM buffer */ -#define FIR_OP_RS 0xB /* Read 1 or 2 bytes to MDR[AS] */ -#define FIR_OP_CW0 0xC /* Wait then issue FCR[CMD0] */ -#define FIR_OP_CW1 0xD /* Wait then issue FCR[CMD1] */ -#define FIR_OP_RBW 0xE /* Wait then read FBCR bytes */ -#define FIR_OP_RSW 0xF /* Wait then read 1 or 2 bytes */ - -/* LTESR - Transfer Error Status Register */ -#define LTESR_BM 0x80000000 -#define LTESR_FCT 0x40000000 -#define LTESR_PAR 0x20000000 -#define LTESR_WP 0x04000000 -#define LTESR_ATMW 0x00800000 -#define LTESR_ATMR 0x00400000 -#define LTESR_CS 0x00080000 -#define LTESR_CC 0x00000001 - -#define LTESR_NAND_MASK (LTESR_FCT | LTESR_CC | LTESR_CS) - -/* FPAR - Flash Page Address Register */ -#define FPAR_SP_PI 0x00007C00 -#define FPAR_SP_PI_SHIFT 10 -#define FPAR_SP_MS 0x00000200 -#define FPAR_SP_CI 0x000001FF -#define FPAR_SP_CI_SHIFT 0 -#define FPAR_LP_PI 0x0003F000 -#define FPAR_LP_PI_SHIFT 12 -#define FPAR_LP_MS 0x00000800 -#define FPAR_LP_CI 0x000007FF -#define FPAR_LP_CI_SHIFT 0 - -#define FSL_FCM_WAIT_TIMEOUT 10 - -#endif /* _NAND_NFC_FSL_H_ */ Property changes on: head/sys/dev/nand/nfc_fsl.h ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/sys/dev/nand/nfc_mv.c =================================================================== --- head/sys/dev/nand/nfc_mv.c (revision 349351) +++ head/sys/dev/nand/nfc_mv.c (nonexistent) @@ -1,238 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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. - */ - -/* Integrated NAND controller driver */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include "nfc_if.h" - -#define MV_NAND_DATA (0x00) -#define MV_NAND_COMMAND (0x01) -#define MV_NAND_ADDRESS (0x02) - -struct mv_nand_softc { - struct nand_softc nand_dev; - bus_space_handle_t sc_handle; - bus_space_tag_t sc_tag; - struct resource *res; - int rid; -}; - -static int mv_nand_attach(device_t); -static int mv_nand_probe(device_t); -static int mv_nand_send_command(device_t, uint8_t); -static int mv_nand_send_address(device_t, uint8_t); -static uint8_t mv_nand_read_byte(device_t); -static void mv_nand_read_buf(device_t, void *, uint32_t); -static void mv_nand_write_buf(device_t, void *, uint32_t); -static int mv_nand_select_cs(device_t, uint8_t); -static int mv_nand_read_rnb(device_t); - -static device_method_t mv_nand_methods[] = { - DEVMETHOD(device_probe, mv_nand_probe), - DEVMETHOD(device_attach, mv_nand_attach), - - DEVMETHOD(nfc_send_command, mv_nand_send_command), - DEVMETHOD(nfc_send_address, mv_nand_send_address), - DEVMETHOD(nfc_read_byte, mv_nand_read_byte), - DEVMETHOD(nfc_read_buf, mv_nand_read_buf), - DEVMETHOD(nfc_write_buf, mv_nand_write_buf), - DEVMETHOD(nfc_select_cs, mv_nand_select_cs), - DEVMETHOD(nfc_read_rnb, mv_nand_read_rnb), - - { 0, 0 }, -}; - -static driver_t mv_nand_driver = { - "nand", - mv_nand_methods, - sizeof(struct mv_nand_softc), -}; - -static devclass_t mv_nand_devclass; -DRIVER_MODULE(mv_nand, localbus, mv_nand_driver, mv_nand_devclass, 0, 0); - -static int -mv_nand_probe(device_t dev) -{ - - if (!ofw_bus_is_compatible(dev, "mrvl,nfc")) - return (ENXIO); - - device_set_desc(dev, "Marvell NAND controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -mv_nand_attach(device_t dev) -{ - struct mv_nand_softc *sc; - int err; - - sc = device_get_softc(dev); - sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, - RF_ACTIVE); - if (sc->res == NULL) { - device_printf(dev, "could not allocate resources!\n"); - return (ENXIO); - } - - sc->sc_tag = rman_get_bustag(sc->res); - sc->sc_handle = rman_get_bushandle(sc->res); - - nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); - - err = nandbus_create(dev); - - return (err); -} - -static int -mv_nand_send_command(device_t dev, uint8_t command) -{ - struct mv_nand_softc *sc; - - nand_debug(NDBG_DRV,"mv_nand: send command %x", command); - - sc = device_get_softc(dev); - bus_space_write_1(sc->sc_tag, sc->sc_handle, MV_NAND_COMMAND, command); - return (0); -} - -static int -mv_nand_send_address(device_t dev, uint8_t addr) -{ - struct mv_nand_softc *sc; - - nand_debug(NDBG_DRV,"mv_nand: send address %x", addr); - - sc = device_get_softc(dev); - bus_space_write_1(sc->sc_tag, sc->sc_handle, MV_NAND_ADDRESS, addr); - return (0); -} - -static uint8_t -mv_nand_read_byte(device_t dev) -{ - struct mv_nand_softc *sc; - uint8_t data; - - sc = device_get_softc(dev); - data = bus_space_read_1(sc->sc_tag, sc->sc_handle, MV_NAND_DATA); - - nand_debug(NDBG_DRV,"mv_nand: read %x", data); - - return (data); -} - -static void -mv_nand_read_buf(device_t dev, void* buf, uint32_t len) -{ - struct mv_nand_softc *sc; - int i; - uint8_t *b = (uint8_t*)buf; - - sc = device_get_softc(dev); - - for (i = 0; i < len; i++) { - b[i] = bus_space_read_1(sc->sc_tag, sc->sc_handle, - MV_NAND_DATA); -#ifdef NAND_DEBUG - if (!(i % 16)) - printf("%s", i == 0 ? "mv_nand:\n" : "\n"); - printf(" %x", b[i]); - if (i == len - 1) - printf("\n"); -#endif - } -} - -static void -mv_nand_write_buf(device_t dev, void* buf, uint32_t len) -{ - struct mv_nand_softc *sc; - int i; - uint8_t *b = (uint8_t*)buf; - - sc = device_get_softc(dev); - - for (i = 0; i < len; i++) { -#ifdef NAND_DEBUG - if (!(i % 16)) - printf("%s", i == 0 ? "mv_nand:\n" : "\n"); - printf(" %x", b[i]); - if (i == len - 1) - printf("\n"); -#endif - bus_space_write_1(sc->sc_tag, sc->sc_handle, MV_NAND_DATA, - b[i]); - } -} - -static int -mv_nand_select_cs(device_t dev, uint8_t cs) -{ - - if (cs > 0) - return (ENODEV); - - return (0); -} - -static int -mv_nand_read_rnb(device_t dev) -{ - - /* no-op */ - return (0); /* ready */ -} Property changes on: head/sys/dev/nand/nfc_mv.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand_if.m =================================================================== --- head/sys/dev/nand/nand_if.m (revision 349351) +++ head/sys/dev/nand/nand_if.m (nonexistent) @@ -1,168 +0,0 @@ -#- -# Copyright (C) 2009-2012 Semihalf -# 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$ - -# NAND chip interface description -# - -#include -#include - -INTERFACE nand; - -CODE { - static int nand_method_not_supported(device_t dev) - { - return (ENOENT); - } -}; - -# Read NAND page -# -# Return values: -# 0: Success -# -METHOD int read_page { - device_t dev; - uint32_t page; - void* buf; - uint32_t len; - uint32_t offset; -}; - -# Program NAND page -# -# Return values: -# 0: Success -# -METHOD int program_page { - device_t dev; - uint32_t page; - void* buf; - uint32_t len; - uint32_t offset; -}; - -# Program NAND page interleaved -# -# Return values: -# 0: Success -# -METHOD int program_page_intlv { - device_t dev; - uint32_t page; - void* buf; - uint32_t len; - uint32_t offset; -} DEFAULT nand_method_not_supported; - -# Read NAND oob -# -# Return values: -# 0: Success -# -METHOD int read_oob { - device_t dev; - uint32_t page; - void* buf; - uint32_t len; - uint32_t offset; -}; - -# Program NAND oob -# -# Return values: -# 0: Success -# -METHOD int program_oob { - device_t dev; - uint32_t page; - void* buf; - uint32_t len; - uint32_t offset; -}; - -# Erase NAND block -# -# Return values: -# 0: Success -# -METHOD int erase_block { - device_t dev; - uint32_t block; -}; - -# Erase NAND block interleaved -# -# Return values: -# 0: Success -# -METHOD int erase_block_intlv { - device_t dev; - uint32_t block; -} DEFAULT nand_method_not_supported; - -# NAND get status -# -# Return values: -# 0: Success -# -METHOD int get_status { - device_t dev; - uint8_t *status; -}; - -# NAND check if block is bad -# -# Return values: -# 0: Success -# -METHOD int is_blk_bad { - device_t dev; - uint32_t block_number; - uint8_t *bad; -}; - -# NAND get ECC -# -# -METHOD int get_ecc { - device_t dev; - void *buf; - void *ecc; - int *needwrite; -}; - -# NAND correct ECC -# -# -METHOD int correct_ecc { - device_t dev; - void *buf; - void *readecc; - void *calcecc; -}; - Property changes on: head/sys/dev/nand/nand_if.m ___________________________________________________________________ Deleted: svn::keyword ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/sys/dev/nand/nand_bbt.c =================================================================== --- head/sys/dev/nand/nand_bbt.c (revision 349351) +++ head/sys/dev/nand/nand_bbt.c (nonexistent) @@ -1,275 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include "nand_if.h" - -#define BBT_PRIMARY_PATTERN 0x01020304 -#define BBT_SECONDARY_PATTERN 0x05060708 - -enum bbt_place { - BBT_NONE, - BBT_PRIMARY, - BBT_SECONDARY -}; - -struct nand_bbt { - struct nand_chip *chip; - uint32_t primary_map; - uint32_t secondary_map; - enum bbt_place active; - struct bbt_header *hdr; - uint32_t tab_len; - uint32_t *table; -}; - -struct bbt_header { - uint32_t pattern; - int32_t seq_nr; -}; - -static int nand_bbt_save(struct nand_bbt *); -static int nand_bbt_load_hdr(struct nand_bbt *, struct bbt_header *, int8_t); -static int nand_bbt_load_table(struct nand_bbt *); -static int nand_bbt_prescan(struct nand_bbt *); - -int -nand_init_bbt(struct nand_chip *chip) -{ - struct chip_geom *cg; - struct nand_bbt *bbt; - int err; - - cg = &chip->chip_geom; - - bbt = malloc(sizeof(struct nand_bbt), M_NAND, M_ZERO | M_WAITOK); - if (!bbt) { - device_printf(chip->dev, - "Cannot allocate memory for bad block struct"); - return (ENOMEM); - } - - bbt->chip = chip; - bbt->active = BBT_NONE; - bbt->primary_map = cg->chip_size - cg->block_size; - bbt->secondary_map = cg->chip_size - 2 * cg->block_size; - bbt->tab_len = cg->blks_per_chip * sizeof(uint32_t); - bbt->hdr = malloc(sizeof(struct bbt_header) + bbt->tab_len, M_NAND, - M_WAITOK); - if (!bbt->hdr) { - device_printf(chip->dev, "Cannot allocate %d bytes for BB " - "Table", bbt->tab_len); - free(bbt, M_NAND); - return (ENOMEM); - } - bbt->hdr->seq_nr = 0; - bbt->table = (uint32_t *)((uint8_t *)bbt->hdr + - sizeof(struct bbt_header)); - - err = nand_bbt_load_table(bbt); - if (err) { - free(bbt->table, M_NAND); - free(bbt, M_NAND); - return (err); - } - - chip->bbt = bbt; - if (bbt->active == BBT_NONE) { - bbt->active = BBT_PRIMARY; - memset(bbt->table, 0xff, bbt->tab_len); - nand_bbt_prescan(bbt); - nand_bbt_save(bbt); - } else - device_printf(chip->dev, "Found BBT table for chip\n"); - - return (0); -} - -void -nand_destroy_bbt(struct nand_chip *chip) -{ - - if (chip->bbt) { - nand_bbt_save(chip->bbt); - - free(chip->bbt->hdr, M_NAND); - free(chip->bbt, M_NAND); - chip->bbt = NULL; - } -} - -int -nand_update_bbt(struct nand_chip *chip) -{ - - nand_bbt_save(chip->bbt); - - return (0); -} - -static int -nand_bbt_save(struct nand_bbt *bbt) -{ - enum bbt_place next; - uint32_t addr; - int32_t err; - - if (bbt->active == BBT_PRIMARY) { - addr = bbt->secondary_map; - bbt->hdr->pattern = BBT_SECONDARY_PATTERN; - next = BBT_SECONDARY; - } else { - addr = bbt->primary_map; - bbt->hdr->pattern = BBT_PRIMARY_PATTERN; - next = BBT_PRIMARY; - } - - err = nand_erase_blocks(bbt->chip, addr, - bbt->chip->chip_geom.block_size); - if (err) - return (err); - - bbt->hdr->seq_nr++; - - err = nand_prog_pages_raw(bbt->chip, addr, bbt->hdr, - bbt->tab_len + sizeof(struct bbt_header)); - if (err) - return (err); - - bbt->active = next; - return (0); -} - -static int -nand_bbt_load_hdr(struct nand_bbt *bbt, struct bbt_header *hdr, int8_t primary) -{ - uint32_t addr; - - if (primary) - addr = bbt->primary_map; - else - addr = bbt->secondary_map; - - return (nand_read_pages_raw(bbt->chip, addr, hdr, - sizeof(struct bbt_header))); -} - -static int -nand_bbt_load_table(struct nand_bbt *bbt) -{ - struct bbt_header hdr1, hdr2; - uint32_t address = 0; - int err = 0; - - bzero(&hdr1, sizeof(hdr1)); - bzero(&hdr2, sizeof(hdr2)); - - nand_bbt_load_hdr(bbt, &hdr1, 1); - if (hdr1.pattern == BBT_PRIMARY_PATTERN) { - bbt->active = BBT_PRIMARY; - address = bbt->primary_map; - } else - bzero(&hdr1, sizeof(hdr1)); - - - nand_bbt_load_hdr(bbt, &hdr2, 0); - if ((hdr2.pattern == BBT_SECONDARY_PATTERN) && - (hdr2.seq_nr > hdr1.seq_nr)) { - bbt->active = BBT_SECONDARY; - address = bbt->secondary_map; - } else - bzero(&hdr2, sizeof(hdr2)); - - if (bbt->active != BBT_NONE) - err = nand_read_pages_raw(bbt->chip, address, bbt->hdr, - bbt->tab_len + sizeof(struct bbt_header)); - - return (err); -} - -static int -nand_bbt_prescan(struct nand_bbt *bbt) -{ - int32_t i; - uint8_t bad; - bool printed_hash = 0; - - device_printf(bbt->chip->dev, "No BBT found. Prescan chip...\n"); - for (i = 0; i < bbt->chip->chip_geom.blks_per_chip; i++) { - if (NAND_IS_BLK_BAD(bbt->chip->dev, i, &bad)) - return (ENXIO); - - if (bad) { - device_printf(bbt->chip->dev, "Bad block(%d)\n", i); - bbt->table[i] = 0x0FFFFFFF; - } - if (!(i % 100)) { - printf("#"); - printed_hash = 1; - } - } - - if (printed_hash) - printf("\n"); - - return (0); -} - -int -nand_check_bad_block(struct nand_chip *chip, uint32_t block_number) -{ - - if (!chip || !chip->bbt) - return (0); - - if ((chip->bbt->table[block_number] & 0xF0000000) == 0) - return (1); - - return (0); -} - -int -nand_mark_bad_block(struct nand_chip *chip, uint32_t block_number) -{ - - chip->bbt->table[block_number] = 0x0FFFFFFF; - - return (0); -} Property changes on: head/sys/dev/nand/nand_bbt.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_swap.h =================================================================== --- head/sys/dev/nand/nandsim_swap.h (revision 349351) +++ head/sys/dev/nand/nandsim_swap.h (nonexistent) @@ -1,66 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 _NANDSIM_SWAP_CHIP_H_ -#define _NANDSIM_SWAP_CHIP_H_ - -struct block_space { - SLIST_ENTRY(block_space) free_link; - STAILQ_ENTRY(block_space) used_link; - struct block_state *blk_state; - uint8_t *blk_ptr; -}; - -#define BLOCK_ALLOCATED 0x1 -#define BLOCK_SWAPPED 0x2 -#define BLOCK_DIRTY 0x4 - -struct block_state { - struct block_space *blk_sp; - uint32_t offset; - uint8_t status; -}; - -struct chip_swap { - struct block_state *blk_state; - SLIST_HEAD(,block_space) free_bs; - STAILQ_HEAD(,block_space) used_bs; - struct ucred *swap_cred; - struct vnode *swap_vp; - uint32_t swap_offset; - uint32_t blk_size; - uint32_t nof_blks; -}; - -struct chip_swap *nandsim_swap_init(const char *, uint32_t, uint32_t); -void nandsim_swap_destroy(struct chip_swap *); -struct block_space *get_bs(struct chip_swap *, uint32_t, uint8_t); - -#endif /* _NANDSIM_SWAP_CHIP_H_ */ Property changes on: head/sys/dev/nand/nandsim_swap.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandbus.h =================================================================== --- head/sys/dev/nand/nandbus.h (revision 349351) +++ head/sys/dev/nand/nandbus.h (nonexistent) @@ -1,51 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 _NANDBUS_H_ -#define _NANDBUS_H_ - -struct nandbus_ivar { - uint8_t cs; - uint8_t cols; - uint8_t rows; - uint8_t man_id; - uint8_t dev_id; - uint8_t is_onfi; - char *chip_cdev_name; - struct nand_params *params; -}; - -extern devclass_t nandbus_devclass; -extern driver_t nandbus_driver; - -int nandbus_create(device_t nfc); -void nandbus_destroy(device_t nfc); - -#endif /* _NANDBUS_H_ */ Property changes on: head/sys/dev/nand/nandbus.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nfc_rb.c =================================================================== --- head/sys/dev/nand/nfc_rb.c (revision 349351) +++ head/sys/dev/nand/nfc_rb.c (nonexistent) @@ -1,321 +0,0 @@ -/*- - * Copyright (C) 2015 Justin Hibbits - * 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. - */ - -/* RouterBoard 600/800 NAND controller driver. */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include - -#include -#include - -#include - -#include "nfc_if.h" -#include "gpio_if.h" - -#define RB_NAND_DATA (0x00) - -struct rb_nand_softc { - struct nand_softc nand_dev; - struct resource *sc_mem; - int rid; - device_t sc_gpio; - uint32_t sc_rdy_pin; - uint32_t sc_nce_pin; - uint32_t sc_cle_pin; - uint32_t sc_ale_pin; -}; - -static int rb_nand_attach(device_t); -static int rb_nand_probe(device_t); -static int rb_nand_send_command(device_t, uint8_t); -static int rb_nand_send_address(device_t, uint8_t); -static uint8_t rb_nand_read_byte(device_t); -static void rb_nand_read_buf(device_t, void *, uint32_t); -static void rb_nand_write_buf(device_t, void *, uint32_t); -static int rb_nand_select_cs(device_t, uint8_t); -static int rb_nand_read_rnb(device_t); - -static device_method_t rb_nand_methods[] = { - DEVMETHOD(device_probe, rb_nand_probe), - DEVMETHOD(device_attach, rb_nand_attach), - - DEVMETHOD(nfc_send_command, rb_nand_send_command), - DEVMETHOD(nfc_send_address, rb_nand_send_address), - DEVMETHOD(nfc_read_byte, rb_nand_read_byte), - DEVMETHOD(nfc_read_buf, rb_nand_read_buf), - DEVMETHOD(nfc_write_buf, rb_nand_write_buf), - DEVMETHOD(nfc_select_cs, rb_nand_select_cs), - DEVMETHOD(nfc_read_rnb, rb_nand_read_rnb), - - { 0, 0 }, -}; - -static driver_t rb_nand_driver = { - "nand", - rb_nand_methods, - sizeof(struct rb_nand_softc), -}; - -static devclass_t rb_nand_devclass; -DRIVER_MODULE(rb_nand, ofwbus, rb_nand_driver, rb_nand_devclass, 0, 0); - -#if 0 -static const struct nand_ecc_data rb_ecc = { - .eccsize = 6, - .eccmode = NAND_ECC_SOFT, - .eccbytes = 6, - .eccpositions = { 8, 9, 10, 13, 14, 15 }, -}; -#endif - -/* Slicer operates on the NAND controller, so we have to find the chip. */ -static int -rb_nand_slicer(device_t dev, const char *provider __unused, - struct flash_slice *slices, int *nslices) -{ - struct nand_chip *chip; - device_t *children; - int n; - - if (device_get_children(dev, &children, &n) != 0) { - panic("Slicer called on controller with no child!"); - } - dev = children[0]; - free(children, M_TEMP); - - if (device_get_children(dev, &children, &n) != 0) { - panic("Slicer called on controller with nandbus but no child!"); - } - dev = children[0]; - free(children, M_TEMP); - - chip = device_get_softc(dev); - *nslices = 2; - slices[0].base = 0; - slices[0].size = 4 * 1024 * 1024; - slices[0].label = "boot"; - - slices[1].base = 4 * 1024 * 1024; - slices[1].size = chip->ndisk->d_mediasize - slices[0].size; - slices[1].label = "rootfs"; - - return (0); -} - -static int -rb_nand_probe(device_t dev) -{ - const char *device_type; - - device_type = ofw_bus_get_type(dev); - - if (!device_type || strcmp(device_type, "rb,nand")) - return (ENXIO); - - device_set_desc(dev, "RouterBoard 333/600/800 NAND controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -rb_nand_attach(device_t dev) -{ - struct rb_nand_softc *sc; - phandle_t node; - uint32_t ale[2],cle[2],nce[2],rdy[2]; - u_long size,start; - int err; - - sc = device_get_softc(dev); - node = ofw_bus_get_node(dev); - - if (OF_getprop(node, "ale", ale, sizeof(ale)) <= 0) { - return (ENXIO); - } - if (OF_getprop(node, "cle", cle, sizeof(cle)) <= 0) { - return (ENXIO); - } - if (OF_getprop(node, "nce", nce, sizeof(nce)) <= 0) { - return (ENXIO); - } - if (OF_getprop(node, "rdy", rdy, sizeof(rdy)) <= 0) { - return (ENXIO); - } - - if (ale[0] != cle[0] || ale[0] != nce[0] || ale[0] != rdy[0]) { - device_printf(dev, "GPIO handles for signals must match.\n"); - return (ENXIO); - } - sc->sc_ale_pin = ale[1]; - sc->sc_cle_pin = cle[1]; - sc->sc_nce_pin = nce[1]; - sc->sc_rdy_pin = rdy[1]; - - sc->sc_gpio = OF_device_from_xref(ale[0]); - if (sc->sc_gpio == NULL) { - device_printf(dev, "No GPIO resource found!\n"); - return (ENXIO); - } - - sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, - RF_ACTIVE); - if (sc->sc_mem == NULL) { - device_printf(dev, "could not allocate resources!\n"); - return (ENXIO); - } - - start = rman_get_start(sc->sc_mem); - size = rman_get_size(sc->sc_mem); - if (law_enable(OCP85XX_TGTIF_LBC, start, size) != 0) { - bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->sc_mem); - device_printf(dev, "could not allocate local address window.\n"); - return (ENXIO); - } - - flash_register_slicer(rb_nand_slicer, FLASH_SLICES_TYPE_NAND, TRUE); - - nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); - - err = nandbus_create(dev); - - return (err); -} - -static int -rb_nand_send_command(device_t dev, uint8_t command) -{ - struct rb_nand_softc *sc; - - nand_debug(NDBG_DRV,"rb_nand: send command %x", command); - - sc = device_get_softc(dev); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 1); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0); - bus_write_1(sc->sc_mem, RB_NAND_DATA, command); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0); - return (0); -} - -static int -rb_nand_send_address(device_t dev, uint8_t addr) -{ - struct rb_nand_softc *sc; - - nand_debug(NDBG_DRV,"rb_nand: send address %x", addr); - - sc = device_get_softc(dev); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_cle_pin, 0); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 1); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_nce_pin, 0); - bus_write_1(sc->sc_mem, RB_NAND_DATA, addr); - GPIO_PIN_SET(sc->sc_gpio, sc->sc_ale_pin, 0); - return (0); -} - -static uint8_t -rb_nand_read_byte(device_t dev) -{ - struct rb_nand_softc *sc; - uint8_t data; - - sc = device_get_softc(dev); - data = bus_read_1(sc->sc_mem, RB_NAND_DATA); - - nand_debug(NDBG_DRV,"rb_nand: read %x", data); - - return (data); -} - -static void -rb_nand_read_buf(device_t dev, void* buf, uint32_t len) -{ - struct rb_nand_softc *sc; - - sc = device_get_softc(dev); - - bus_read_region_1(sc->sc_mem, RB_NAND_DATA, buf, len); -} - -static void -rb_nand_write_buf(device_t dev, void* buf, uint32_t len) -{ - struct rb_nand_softc *sc; - int i; - uint8_t *b = (uint8_t*)buf; - - sc = device_get_softc(dev); - - for (i = 0; i < len; i++) { -#ifdef NAND_DEBUG - if (!(i % 16)) - printf("%s", i == 0 ? "rb_nand:\n" : "\n"); - printf(" %x", b[i]); - if (i == len - 1) - printf("\n"); -#endif - bus_write_1(sc->sc_mem, RB_NAND_DATA, b[i]); - } -} - -static int -rb_nand_select_cs(device_t dev, uint8_t cs) -{ - - if (cs > 0) - return (ENODEV); - - return (0); -} - -static int -rb_nand_read_rnb(device_t dev) -{ - struct rb_nand_softc *sc; - uint32_t rdy_bit; - - sc = device_get_softc(dev); - GPIO_PIN_GET(sc->sc_gpio, sc->sc_rdy_pin, &rdy_bit); - - return (rdy_bit); /* ready */ -} Property changes on: head/sys/dev/nand/nfc_rb.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand_dev.h =================================================================== --- head/sys/dev/nand/nand_dev.h (revision 349351) +++ head/sys/dev/nand/nand_dev.h (nonexistent) @@ -1,92 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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_NAND_CDEV_H_ -#define _DEV_NAND_CDEV_H_ - -#include -#include - -struct nand_raw_rw { - off_t off; - off_t len; - uint8_t *data; -}; - -struct nand_oob_rw { - uint32_t page; - off_t len; - uint8_t *data; -}; - -#define NAND_IOCTL_GROUP 'N' -#define NAND_IO_ERASE _IOWR(NAND_IOCTL_GROUP, 0x0, off_t[2]) - -#define NAND_IO_OOB_READ _IOWR(NAND_IOCTL_GROUP, 0x1, struct nand_oob_rw) - -#define NAND_IO_OOB_PROG _IOWR(NAND_IOCTL_GROUP, 0x2, struct nand_oob_rw) - -#define NAND_IO_RAW_READ _IOWR(NAND_IOCTL_GROUP, 0x3, struct nand_raw_rw) - -#define NAND_IO_RAW_PROG _IOWR(NAND_IOCTL_GROUP, 0x4, struct nand_raw_rw) - -#define NAND_IO_GET_STATUS _IOWR(NAND_IOCTL_GROUP, 0x5, uint8_t) - -struct page_stat_io { - uint32_t page_num; - uint32_t page_read; - uint32_t page_written; - uint32_t page_raw_read; - uint32_t page_raw_written; - uint32_t ecc_succeded; - uint32_t ecc_corrected; - uint32_t ecc_failed; -}; -#define NAND_IO_PAGE_STAT _IOWR(NAND_IOCTL_GROUP, 0x6, \ - struct page_stat_io) - -struct block_stat_io { - uint32_t block_num; - uint32_t block_erased; -}; -#define NAND_IO_BLOCK_STAT _IOWR(NAND_IOCTL_GROUP, 0x7, \ - struct block_stat_io) - -struct chip_param_io { - uint32_t page_size; - uint32_t oob_size; - - uint32_t blocks; - uint32_t pages_per_block; -}; -#define NAND_IO_GET_CHIP_PARAM _IOWR(NAND_IOCTL_GROUP, 0x8, \ - struct chip_param_io) - -#endif /* _DEV_NAND_CDEV_H_ */ Property changes on: head/sys/dev/nand/nand_dev.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_log.c =================================================================== --- head/sys/dev/nand/nandsim_log.c (revision 349351) +++ head/sys/dev/nand/nandsim_log.c (nonexistent) @@ -1,188 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -int nandsim_log_level; -int nandsim_log_output; -int log_size = NANDSIM_RAM_LOG_SIZE; - -static int nandsim_entry_size = NANDSIM_ENTRY_SIZE; -static int nandsim_entry_count = NANDSIM_ENTRY_COUNT; -static int str_index = 0; -static char string[NANDSIM_ENTRY_SIZE + 1] = {0}; - -int -nandsim_log_init(struct nandsim_softc *sc, char *filename) -{ - int error = 0; - - if (nandsim_log_output == NANDSIM_OUTPUT_FILE) { - error = alq_open(&sc->alq, filename, - curthread->td_ucred, 0644, - nandsim_entry_size, nandsim_entry_count); - } else if (nandsim_log_output == NANDSIM_OUTPUT_RAM) { - sc->log_buff = malloc(log_size, M_NANDSIM, M_WAITOK | M_ZERO); - if (!sc->log_buff) - error = ENOMEM; - } - - return (error); -} - -void -nandsim_log_close(struct nandsim_softc *sc) -{ - - if (nandsim_log_output == NANDSIM_OUTPUT_FILE) { - memset(&string[str_index], 0, NANDSIM_ENTRY_SIZE - str_index); - alq_write(sc->alq, (void *) string, ALQ_NOWAIT); - str_index = 0; - string[0] = '\0'; - alq_close(sc->alq); - } else if (nandsim_log_output == NANDSIM_OUTPUT_RAM) { - free(sc->log_buff, M_NANDSIM); - sc->log_buff = NULL; - } -} - -void -nandsim_log(struct nandsim_chip *chip, int level, const char *fmt, ...) -{ - char hdr[TIME_STR_SIZE]; - char tmp[NANDSIM_ENTRY_SIZE]; - struct nandsim_softc *sc; - struct timeval currtime; - va_list ap; - int hdr_len, len, rest; - - if (nandsim_log_output == NANDSIM_OUTPUT_NONE) - return; - - if (chip == NULL) - return; - - sc = chip->sc; - if (!sc->alq && nandsim_log_output == NANDSIM_OUTPUT_FILE) - return; - - if (level <= nandsim_log_level) { - microtime(&currtime); - hdr_len = sprintf(hdr, "%08jd.%08li [chip:%d, ctrl:%d]: ", - (intmax_t)currtime.tv_sec, currtime.tv_usec, - chip->chip_num, chip->ctrl_num); - - switch(nandsim_log_output) { - case NANDSIM_OUTPUT_CONSOLE: - printf("%s", hdr); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - break; - case NANDSIM_OUTPUT_RAM: - va_start(ap, fmt); - len = vsnprintf(tmp, NANDSIM_ENTRY_SIZE - 1, fmt, ap); - tmp[NANDSIM_ENTRY_SIZE - 1] = 0; - va_end(ap); - - rest = log_size - sc->log_idx - 1; - if (rest >= hdr_len) { - bcopy(hdr, &sc->log_buff[sc->log_idx], - hdr_len); - sc->log_idx += hdr_len; - sc->log_buff[sc->log_idx] = 0; - } else { - bcopy(hdr, &sc->log_buff[sc->log_idx], rest); - bcopy(&hdr[rest], sc->log_buff, - hdr_len - rest); - sc->log_idx = hdr_len - rest; - sc->log_buff[sc->log_idx] = 0; - } - - rest = log_size - sc->log_idx - 1; - if (rest >= len) { - bcopy(tmp, &sc->log_buff[sc->log_idx], len); - sc->log_idx += len; - sc->log_buff[sc->log_idx] = 0; - } else { - bcopy(tmp, &sc->log_buff[sc->log_idx], rest); - bcopy(&tmp[rest], sc->log_buff, len - rest); - sc->log_idx = len - rest; - sc->log_buff[sc->log_idx] = 0; - } - - break; - - case NANDSIM_OUTPUT_FILE: - va_start(ap, fmt); - len = vsnprintf(tmp, NANDSIM_ENTRY_SIZE - 1, fmt, ap); - tmp[NANDSIM_ENTRY_SIZE - 1] = 0; - va_end(ap); - - rest = NANDSIM_ENTRY_SIZE - str_index; - if (rest >= hdr_len) { - strcat(string, hdr); - str_index += hdr_len; - } else { - strlcat(string, hdr, NANDSIM_ENTRY_SIZE + 1); - alq_write(sc->alq, (void *) string, - ALQ_NOWAIT); - strcpy(string, &hdr[rest]); - str_index = hdr_len - rest; - } - rest = NANDSIM_ENTRY_SIZE - str_index; - if (rest >= len) { - strcat(string, tmp); - str_index += len; - } else { - strlcat(string, tmp, NANDSIM_ENTRY_SIZE + 1); - alq_write(sc->alq, (void *) string, - ALQ_NOWAIT); - strcpy(string, &tmp[rest]); - str_index = len - rest; - } - break; - default: - break; - } - } -} Property changes on: head/sys/dev/nand/nandsim_log.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim.c =================================================================== --- head/sys/dev/nand/nandsim.c (revision 349351) +++ head/sys/dev/nand/nandsim.c (nonexistent) @@ -1,670 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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. - */ - -/* Simulated NAND controller driver */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -struct sim_param sim; -struct sim_ctrl_conf ctrls[MAX_SIM_DEV]; - -static struct cdev *nandsim_dev; -static d_ioctl_t nandsim_ioctl; - -static void nandsim_init_sim_param(struct sim_param *); -static int nandsim_create_ctrl(struct sim_ctrl *); -static int nandsim_destroy_ctrl(int); -static int nandsim_ctrl_status(struct sim_ctrl *); -static int nandsim_create_chip(struct sim_chip *); -static int nandsim_destroy_chip(struct sim_ctrl_chip *); -static int nandsim_chip_status(struct sim_chip *); -static int nandsim_start_ctrl(int); -static int nandsim_stop_ctrl(int); -static int nandsim_inject_error(struct sim_error *); -static int nandsim_get_block_state(struct sim_block_state *); -static int nandsim_set_block_state(struct sim_block_state *); -static int nandsim_modify(struct sim_mod *); -static int nandsim_dump(struct sim_dump *); -static int nandsim_restore(struct sim_dump *); -static int nandsim_freeze(struct sim_ctrl_chip *); -static void nandsim_print_log(struct sim_log *); -static struct nandsim_chip *get_nandsim_chip(uint8_t, uint8_t); - -static struct cdevsw nandsim_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, - .d_ioctl = nandsim_ioctl, - .d_name = "nandsim", -}; - -int -nandsim_ioctl(struct cdev *dev, u_long cmd, caddr_t data, - int flags, struct thread *td) -{ - int ret = 0; - - switch (cmd) { - case NANDSIM_SIM_PARAM: - nandsim_init_sim_param((struct sim_param *)data); - break; - case NANDSIM_CREATE_CTRL: - ret = nandsim_create_ctrl((struct sim_ctrl *)data); - break; - case NANDSIM_DESTROY_CTRL: - ret = nandsim_destroy_ctrl(*(int *)data); - break; - case NANDSIM_STATUS_CTRL: - ret = nandsim_ctrl_status((struct sim_ctrl *)data); - break; - case NANDSIM_CREATE_CHIP: - ret = nandsim_create_chip((struct sim_chip *)data); - break; - case NANDSIM_DESTROY_CHIP: - ret = nandsim_destroy_chip((struct sim_ctrl_chip *)data); - break; - case NANDSIM_STATUS_CHIP: - ret = nandsim_chip_status((struct sim_chip *)data); - break; - case NANDSIM_MODIFY: - ret = nandsim_modify((struct sim_mod *)data); - break; - case NANDSIM_START_CTRL: - ret = nandsim_start_ctrl(*(int *)data); - break; - case NANDSIM_STOP_CTRL: - ret = nandsim_stop_ctrl(*(int *)data); - break; - case NANDSIM_INJECT_ERROR: - ret = nandsim_inject_error((struct sim_error *)data); - break; - case NANDSIM_SET_BLOCK_STATE: - ret = nandsim_set_block_state((struct sim_block_state *)data); - break; - case NANDSIM_GET_BLOCK_STATE: - ret = nandsim_get_block_state((struct sim_block_state *)data); - break; - case NANDSIM_PRINT_LOG: - nandsim_print_log((struct sim_log *)data); - break; - case NANDSIM_DUMP: - ret = nandsim_dump((struct sim_dump *)data); - break; - case NANDSIM_RESTORE: - ret = nandsim_restore((struct sim_dump *)data); - break; - case NANDSIM_FREEZE: - ret = nandsim_freeze((struct sim_ctrl_chip *)data); - break; - default: - ret = EINVAL; - break; - } - - return (ret); -} - -static void -nandsim_init_sim_param(struct sim_param *param) -{ - - if (!param) - return; - - nand_debug(NDBG_SIM,"log level:%d output %d", param->log_level, - param->log_output); - nandsim_log_level = param->log_level; - nandsim_log_output = param->log_output; -} - -static int -nandsim_create_ctrl(struct sim_ctrl *ctrl) -{ - struct sim_ctrl_conf *sim_ctrl; - - nand_debug(NDBG_SIM,"create controller num:%d cs:%d",ctrl->num, - ctrl->num_cs); - - if (ctrl->num >= MAX_SIM_DEV) { - return (EINVAL); - } - - sim_ctrl = &ctrls[ctrl->num]; - if(sim_ctrl->created) - return (EEXIST); - - sim_ctrl->num = ctrl->num; - sim_ctrl->num_cs = ctrl->num_cs; - sim_ctrl->ecc = ctrl->ecc; - memcpy(sim_ctrl->ecc_layout, ctrl->ecc_layout, - MAX_ECC_BYTES * sizeof(ctrl->ecc_layout[0])); - strlcpy(sim_ctrl->filename, ctrl->filename, - FILENAME_SIZE); - sim_ctrl->created = 1; - - return (0); -} - -static int -nandsim_destroy_ctrl(int ctrl_num) -{ - - nand_debug(NDBG_SIM,"destroy controller num:%d", ctrl_num); - - if (ctrl_num >= MAX_SIM_DEV) { - return (EINVAL); - } - - if (!ctrls[ctrl_num].created) { - return (ENODEV); - } - - if (ctrls[ctrl_num].running) { - return (EBUSY); - } - - memset(&ctrls[ctrl_num], 0, sizeof(ctrls[ctrl_num])); - - return (0); -} - -static int -nandsim_ctrl_status(struct sim_ctrl *ctrl) -{ - - nand_debug(NDBG_SIM,"status controller num:%d cs:%d",ctrl->num, - ctrl->num_cs); - - if (ctrl->num >= MAX_SIM_DEV) { - return (EINVAL); - } - - ctrl->num_cs = ctrls[ctrl->num].num_cs; - ctrl->ecc = ctrls[ctrl->num].ecc; - memcpy(ctrl->ecc_layout, ctrls[ctrl->num].ecc_layout, - MAX_ECC_BYTES * sizeof(ctrl->ecc_layout[0])); - strlcpy(ctrl->filename, ctrls[ctrl->num].filename, - FILENAME_SIZE); - ctrl->running = ctrls[ctrl->num].running; - ctrl->created = ctrls[ctrl->num].created; - - return (0); -} - -static int -nandsim_create_chip(struct sim_chip *chip) -{ - struct sim_chip *sim_chip; - - nand_debug(NDBG_SIM,"create chip num:%d at ctrl:%d", chip->num, - chip->ctrl_num); - - if (chip->ctrl_num >= MAX_SIM_DEV || - chip->num >= MAX_CTRL_CS) { - return (EINVAL); - } - - if (ctrls[chip->ctrl_num].chips[chip->num]) { - return (EEXIST); - } - - sim_chip = malloc(sizeof(*sim_chip), M_NANDSIM, - M_WAITOK); - if (sim_chip == NULL) { - return (ENOMEM); - } - - memcpy(sim_chip, chip, sizeof(*sim_chip)); - ctrls[chip->ctrl_num].chips[chip->num] = sim_chip; - sim_chip->created = 1; - - return (0); -} - -static int -nandsim_destroy_chip(struct sim_ctrl_chip *chip) -{ - struct sim_ctrl_conf *ctrl_conf; - - nand_debug(NDBG_SIM,"destroy chip num:%d at ctrl:%d", chip->chip_num, - chip->ctrl_num); - - if (chip->ctrl_num >= MAX_SIM_DEV || - chip->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - ctrl_conf = &ctrls[chip->ctrl_num]; - - if (!ctrl_conf->created || !ctrl_conf->chips[chip->chip_num]) - return (ENODEV); - - if (ctrl_conf->running) - return (EBUSY); - - free(ctrl_conf->chips[chip->chip_num], M_NANDSIM); - ctrl_conf->chips[chip->chip_num] = NULL; - - return (0); -} - -static int -nandsim_chip_status(struct sim_chip *chip) -{ - struct sim_ctrl_conf *ctrl_conf; - - nand_debug(NDBG_SIM,"status for chip num:%d at ctrl:%d", chip->num, - chip->ctrl_num); - - if (chip->ctrl_num >= MAX_SIM_DEV || - chip->num >= MAX_CTRL_CS) - return (EINVAL); - - ctrl_conf = &ctrls[chip->ctrl_num]; - if (!ctrl_conf->chips[chip->num]) - chip->created = 0; - else - memcpy(chip, ctrl_conf->chips[chip->num], sizeof(*chip)); - - return (0); -} - -static int -nandsim_start_ctrl(int num) -{ - device_t nexus, ndev; - devclass_t nexus_devclass; - int ret = 0; - - nand_debug(NDBG_SIM,"start ctlr num:%d", num); - - if (num >= MAX_SIM_DEV) - return (EINVAL); - - if (!ctrls[num].created) - return (ENODEV); - - if (ctrls[num].running) - return (EBUSY); - - /* We will add our device as a child of the nexus0 device */ - if (!(nexus_devclass = devclass_find("nexus")) || - !(nexus = devclass_get_device(nexus_devclass, 0))) - return (EFAULT); - - /* - * Create a newbus device representing this frontend instance - * - * XXX powerpc nexus doesn't implement bus_add_child, so child - * must be added by device_add_child(). - */ -#if defined(__powerpc__) - ndev = device_add_child(nexus, "nandsim", num); -#else - ndev = BUS_ADD_CHILD(nexus, 0, "nandsim", num); -#endif - if (!ndev) - return (EFAULT); - - mtx_lock(&Giant); - ret = device_probe_and_attach(ndev); - mtx_unlock(&Giant); - - if (ret == 0) { - ctrls[num].sim_ctrl_dev = ndev; - ctrls[num].running = 1; - } - - return (ret); -} - -static int -nandsim_stop_ctrl(int num) -{ - device_t nexus; - devclass_t nexus_devclass; - int ret = 0; - - nand_debug(NDBG_SIM,"stop controller num:%d", num); - - if (num >= MAX_SIM_DEV) { - return (EINVAL); - } - - if (!ctrls[num].created || !ctrls[num].running) { - return (ENODEV); - } - - /* We will add our device as a child of the nexus0 device */ - if (!(nexus_devclass = devclass_find("nexus")) || - !(nexus = devclass_get_device(nexus_devclass, 0))) { - return (ENODEV); - } - - mtx_lock(&Giant); - if (ctrls[num].sim_ctrl_dev) { - ret = device_delete_child(nexus, ctrls[num].sim_ctrl_dev); - ctrls[num].sim_ctrl_dev = NULL; - } - mtx_unlock(&Giant); - - ctrls[num].running = 0; - - return (ret); -} - -static struct nandsim_chip * -get_nandsim_chip(uint8_t ctrl_num, uint8_t chip_num) -{ - struct nandsim_softc *sc; - - if (!ctrls[ctrl_num].sim_ctrl_dev) - return (NULL); - - sc = device_get_softc(ctrls[ctrl_num].sim_ctrl_dev); - return (sc->chips[chip_num]); -} - -static void -nandsim_print_log(struct sim_log *sim_log) -{ - struct nandsim_softc *sc; - int len1, len2; - - if (!ctrls[sim_log->ctrl_num].sim_ctrl_dev) - return; - - sc = device_get_softc(ctrls[sim_log->ctrl_num].sim_ctrl_dev); - if (sc->log_buff) { - len1 = strlen(&sc->log_buff[sc->log_idx + 1]); - if (len1 >= sim_log->len) - len1 = sim_log->len; - copyout(&sc->log_buff[sc->log_idx + 1], sim_log->log, len1); - len2 = strlen(sc->log_buff); - if (len2 >= (sim_log->len - len1)) - len2 = (sim_log->len - len1); - copyout(sc->log_buff, &sim_log->log[len1], len2); - sim_log->len = len1 + len2; - } -} - -static int -nandsim_inject_error(struct sim_error *error) -{ - struct nandsim_chip *chip; - struct block_space *bs; - struct onfi_params *param; - int page, page_size, block, offset; - - nand_debug(NDBG_SIM,"inject error for chip %d at ctrl %d\n", - error->chip_num, error->ctrl_num); - - if (error->ctrl_num >= MAX_SIM_DEV || - error->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - if (!ctrls[error->ctrl_num].created || !ctrls[error->ctrl_num].running) - return (ENODEV); - - chip = get_nandsim_chip(error->ctrl_num, error->chip_num); - param = &chip->params; - page_size = param->bytes_per_page + param->spare_bytes_per_page; - block = error->page_num / param->pages_per_block; - page = error->page_num % param->pages_per_block; - - bs = get_bs(chip->swap, block, 1); - if (!bs) - return (EINVAL); - - offset = (page * page_size) + error->column; - memset(&bs->blk_ptr[offset], error->pattern, error->len); - - return (0); -} - -static int -nandsim_set_block_state(struct sim_block_state *bs) -{ - struct onfi_params *params; - struct nandsim_chip *chip; - int blocks; - - nand_debug(NDBG_SIM,"set block state for %d:%d block %d\n", - bs->chip_num, bs->ctrl_num, bs->block_num); - - if (bs->ctrl_num >= MAX_SIM_DEV || - bs->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - chip = get_nandsim_chip(bs->ctrl_num, bs->chip_num); - params = &chip->params; - blocks = params->luns * params->blocks_per_lun; - - if (bs->block_num > blocks) - return (EINVAL); - - chip->blk_state[bs->block_num].is_bad = bs->state; - - if (bs->wearout >= 0) - chip->blk_state[bs->block_num].wear_lev = bs->wearout; - - return (0); -} - -static int -nandsim_get_block_state(struct sim_block_state *bs) -{ - struct onfi_params *params; - struct nandsim_chip *chip; - int blocks; - - if (bs->ctrl_num >= MAX_SIM_DEV || - bs->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - nand_debug(NDBG_SIM,"get block state for %d:%d block %d\n", - bs->chip_num, bs->ctrl_num, bs->block_num); - - chip = get_nandsim_chip(bs->ctrl_num, bs->chip_num); - params = &chip->params; - blocks = params->luns * params->blocks_per_lun; - - if (bs->block_num > blocks) - return (EINVAL); - - bs->state = chip->blk_state[bs->block_num].is_bad; - bs->wearout = chip->blk_state[bs->block_num].wear_lev; - - return (0); -} - -static int -nandsim_dump(struct sim_dump *dump) -{ - struct nandsim_chip *chip; - struct block_space *bs; - int blk_size; - - nand_debug(NDBG_SIM,"dump chip %d %d\n", dump->ctrl_num, dump->chip_num); - - if (dump->ctrl_num >= MAX_SIM_DEV || - dump->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - chip = get_nandsim_chip(dump->ctrl_num, dump->chip_num); - blk_size = chip->cg.block_size + - (chip->cg.oob_size * chip->cg.pgs_per_blk); - - bs = get_bs(chip->swap, dump->block_num, 0); - if (!bs) - return (EINVAL); - - if (dump->len > blk_size) - dump->len = blk_size; - - copyout(bs->blk_ptr, dump->data, dump->len); - - return (0); -} - -static int -nandsim_restore(struct sim_dump *dump) -{ - struct nandsim_chip *chip; - struct block_space *bs; - int blk_size; - - nand_debug(NDBG_SIM,"restore chip %d %d\n", dump->ctrl_num, - dump->chip_num); - - if (dump->ctrl_num >= MAX_SIM_DEV || - dump->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - chip = get_nandsim_chip(dump->ctrl_num, dump->chip_num); - blk_size = chip->cg.block_size + - (chip->cg.oob_size * chip->cg.pgs_per_blk); - - bs = get_bs(chip->swap, dump->block_num, 1); - if (!bs) - return (EINVAL); - - if (dump->len > blk_size) - dump->len = blk_size; - - - copyin(dump->data, bs->blk_ptr, dump->len); - - return (0); -} - -static int -nandsim_freeze(struct sim_ctrl_chip *ctrl_chip) -{ - struct nandsim_chip *chip; - - if (ctrl_chip->ctrl_num >= MAX_SIM_DEV || - ctrl_chip->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - chip = get_nandsim_chip(ctrl_chip->ctrl_num, ctrl_chip->chip_num); - nandsim_chip_freeze(chip); - - return (0); -} - -static int -nandsim_modify(struct sim_mod *mod) -{ - struct sim_chip *sim_conf = NULL; - struct nandsim_chip *sim_chip = NULL; - - nand_debug(NDBG_SIM,"modify ctlr %d chip %d", mod->ctrl_num, - mod->chip_num); - - if (mod->field != SIM_MOD_LOG_LEVEL) { - if (mod->ctrl_num >= MAX_SIM_DEV || - mod->chip_num >= MAX_CTRL_CS) - return (EINVAL); - - sim_conf = ctrls[mod->ctrl_num].chips[mod->chip_num]; - sim_chip = get_nandsim_chip(mod->ctrl_num, mod->chip_num); - } - - switch (mod->field) { - case SIM_MOD_LOG_LEVEL: - nandsim_log_level = mod->new_value; - break; - case SIM_MOD_ERASE_TIME: - sim_conf->erase_time = sim_chip->erase_delay = mod->new_value; - break; - case SIM_MOD_PROG_TIME: - sim_conf->prog_time = sim_chip->prog_delay = mod->new_value; - break; - case SIM_MOD_READ_TIME: - sim_conf->read_time = sim_chip->read_delay = mod->new_value; - break; - case SIM_MOD_ERROR_RATIO: - sim_conf->error_ratio = mod->new_value; - sim_chip->error_ratio = mod->new_value; - break; - default: - break; - } - - return (0); -} -static int -nandsim_modevent(module_t mod __unused, int type, void *data __unused) -{ - struct sim_ctrl_chip chip_ctrl; - int i, j; - - switch (type) { - case MOD_LOAD: - nandsim_dev = make_dev(&nandsim_cdevsw, 0, - UID_ROOT, GID_WHEEL, 0600, "nandsim.ioctl"); - break; - case MOD_UNLOAD: - for (i = 0; i < MAX_SIM_DEV; i++) { - nandsim_stop_ctrl(i); - chip_ctrl.ctrl_num = i; - for (j = 0; j < MAX_CTRL_CS; j++) { - chip_ctrl.chip_num = j; - nandsim_destroy_chip(&chip_ctrl); - } - nandsim_destroy_ctrl(i); - } - destroy_dev(nandsim_dev); - break; - case MOD_SHUTDOWN: - break; - default: - return (EOPNOTSUPP); - } - return (0); -} - -DEV_MODULE(nandsim, nandsim_modevent, NULL); -MODULE_VERSION(nandsim, 1); -MODULE_DEPEND(nandsim, nand, 1, 1, 1); -MODULE_DEPEND(nandsim, alq, 1, 1, 1); Property changes on: head/sys/dev/nand/nandsim.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand_geom.c =================================================================== --- head/sys/dev/nand/nand_geom.c (revision 349351) +++ head/sys/dev/nand/nand_geom.c (nonexistent) @@ -1,467 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "nand_if.h" -#include "nandbus_if.h" - -#define BIO_NAND_STD ((void *)1) -#define BIO_NAND_RAW ((void *)2) - -static disk_ioctl_t nand_ioctl; -static disk_getattr_t nand_getattr; -static disk_strategy_t nand_strategy; -static disk_strategy_t nand_strategy_raw; - -static int -nand_read(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len) -{ - - nand_debug(NDBG_GEOM, "Read from chip %d [%p] at %d", chip->num, chip, - offset); - - return (nand_read_pages(chip, offset, buf, len)); -} - -static int -nand_write(struct nand_chip *chip, uint32_t offset, void* buf, uint32_t len) -{ - - nand_debug(NDBG_GEOM, "Write to chip %d [%p] at %d", chip->num, chip, - offset); - - return (nand_prog_pages(chip, offset, buf, len)); -} - -static int -nand_read_raw(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len) -{ - nand_debug(NDBG_GEOM, "Raw read from chip %d [%p] at %d", chip->num, - chip, offset); - - return (nand_read_pages_raw(chip, offset, buf, len)); -} - -static int -nand_write_raw(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len) -{ - - nand_debug(NDBG_GEOM, "Raw write to chip %d [%p] at %d", chip->num, - chip, offset); - - return (nand_prog_pages_raw(chip, offset, buf, len)); -} - -static void -nand_strategy(struct bio *bp) -{ - struct nand_chip *chip; - - chip = (struct nand_chip *)bp->bio_disk->d_drv1; - - bp->bio_driver1 = BIO_NAND_STD; - - nand_debug(NDBG_GEOM, "Strategy %s on chip %d [%p]", - bp->bio_cmd == BIO_READ ? "READ" : - (bp->bio_cmd == BIO_WRITE ? "WRITE" : - (bp->bio_cmd == BIO_DELETE ? "DELETE" : "UNKNOWN")), - chip->num, chip); - - mtx_lock(&chip->qlock); - bioq_insert_tail(&chip->bioq, bp); - mtx_unlock(&chip->qlock); - taskqueue_enqueue(chip->tq, &chip->iotask); -} - -static void -nand_strategy_raw(struct bio *bp) -{ - struct nand_chip *chip; - - chip = (struct nand_chip *)bp->bio_disk->d_drv1; - - /* Inform taskqueue that it's a raw access */ - bp->bio_driver1 = BIO_NAND_RAW; - - nand_debug(NDBG_GEOM, "Strategy %s on chip %d [%p]", - bp->bio_cmd == BIO_READ ? "READ" : - (bp->bio_cmd == BIO_WRITE ? "WRITE" : - (bp->bio_cmd == BIO_DELETE ? "DELETE" : "UNKNOWN")), - chip->num, chip); - - mtx_lock(&chip->qlock); - bioq_insert_tail(&chip->bioq, bp); - mtx_unlock(&chip->qlock); - taskqueue_enqueue(chip->tq, &chip->iotask); -} - -static int -nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset, - uint32_t len, uint8_t *data, uint8_t write) -{ - struct chip_geom *cg; - int ret = 0; - - cg = &chip->chip_geom; - - if (!write) - ret = nand_read_oob(chip, page, data, cg->oob_size); - else - ret = nand_prog_oob(chip, page, data, cg->oob_size); - - return (ret); -} - -static int -nand_getattr(struct bio *bp) -{ - struct nand_chip *chip; - struct chip_geom *cg; - device_t dev; - int val; - - if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL) - return (ENXIO); - - chip = (struct nand_chip *)bp->bio_disk->d_drv1; - cg = &(chip->chip_geom); - - dev = device_get_parent(chip->dev); - dev = device_get_parent(dev); - - if (strcmp(bp->bio_attribute, "NAND::device") == 0) { - if (bp->bio_length != sizeof(dev)) - return (EFAULT); - bcopy(&dev, bp->bio_data, sizeof(dev)); - } else { - if (strcmp(bp->bio_attribute, "NAND::oobsize") == 0) - val = cg->oob_size; - else if (strcmp(bp->bio_attribute, "NAND::pagesize") == 0) - val = cg->page_size; - else if (strcmp(bp->bio_attribute, "NAND::blocksize") == 0) - val = cg->block_size; - else - return (-1); - if (bp->bio_length != sizeof(val)) - return (EFAULT); - bcopy(&val, bp->bio_data, sizeof(val)); - } - bp->bio_completed = bp->bio_length; - return (0); -} - -static int -nand_ioctl(struct disk *ndisk, u_long cmd, void *data, int fflag, - struct thread *td) -{ - struct nand_chip *chip; - struct chip_geom *cg; - struct nand_oob_rw *oob_rw = NULL; - struct nand_raw_rw *raw_rw = NULL; - device_t nandbus; - size_t bufsize = 0, len = 0; - size_t raw_size; - off_t off; - uint8_t *buf = NULL; - int ret = 0; - uint8_t status; - - chip = (struct nand_chip *)ndisk->d_drv1; - cg = &chip->chip_geom; - nandbus = device_get_parent(chip->dev); - - if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) { - raw_rw = (struct nand_raw_rw *)data; - raw_size = cg->pgs_per_blk * (cg->page_size + cg->oob_size); - - /* Check if len is not bigger than chip size */ - if (raw_rw->len > raw_size) - return (EFBIG); - - /* - * Do not ask for too much memory, in case of large transfers - * read/write in 16-pages chunks - */ - bufsize = 16 * (cg->page_size + cg->oob_size); - if (raw_rw->len < bufsize) - bufsize = raw_rw->len; - - buf = malloc(bufsize, M_NAND, M_WAITOK); - len = raw_rw->len; - off = 0; - } - - switch (cmd) { - case NAND_IO_ERASE: - ret = nand_erase_blocks(chip, ((off_t *)data)[0], - ((off_t *)data)[1]); - break; - - case NAND_IO_OOB_READ: - oob_rw = (struct nand_oob_rw *)data; - ret = nand_oob_access(chip, oob_rw->page, 0, - oob_rw->len, oob_rw->data, 0); - break; - - case NAND_IO_OOB_PROG: - oob_rw = (struct nand_oob_rw *)data; - ret = nand_oob_access(chip, oob_rw->page, 0, - oob_rw->len, oob_rw->data, 1); - break; - - case NAND_IO_GET_STATUS: - NANDBUS_LOCK(nandbus); - ret = NANDBUS_GET_STATUS(nandbus, &status); - if (ret == 0) - *(uint8_t *)data = status; - NANDBUS_UNLOCK(nandbus); - break; - - case NAND_IO_RAW_PROG: - while (len > 0) { - if (len < bufsize) - bufsize = len; - - ret = copyin(raw_rw->data + off, buf, bufsize); - if (ret) - break; - ret = nand_prog_pages_raw(chip, raw_rw->off + off, buf, - bufsize); - if (ret) - break; - len -= bufsize; - off += bufsize; - } - break; - - case NAND_IO_RAW_READ: - while (len > 0) { - if (len < bufsize) - bufsize = len; - - ret = nand_read_pages_raw(chip, raw_rw->off + off, buf, - bufsize); - if (ret) - break; - - ret = copyout(buf, raw_rw->data + off, bufsize); - if (ret) - break; - len -= bufsize; - off += bufsize; - } - break; - - case NAND_IO_GET_CHIP_PARAM: - nand_get_chip_param(chip, (struct chip_param_io *)data); - break; - - default: - printf("Unknown nand_ioctl request \n"); - ret = EIO; - } - - if (buf) - free(buf, M_NAND); - - return (ret); -} - -static void -nand_io_proc(void *arg, int pending) -{ - struct nand_chip *chip = arg; - struct bio *bp; - int err = 0; - - for (;;) { - mtx_lock(&chip->qlock); - bp = bioq_takefirst(&chip->bioq); - mtx_unlock(&chip->qlock); - if (bp == NULL) - break; - - if (bp->bio_driver1 == BIO_NAND_STD) { - if (bp->bio_cmd == BIO_READ) { - err = nand_read(chip, - bp->bio_offset & 0xffffffff, - bp->bio_data, bp->bio_bcount); - } else if (bp->bio_cmd == BIO_WRITE) { - err = nand_write(chip, - bp->bio_offset & 0xffffffff, - bp->bio_data, bp->bio_bcount); - } - } else if (bp->bio_driver1 == BIO_NAND_RAW) { - if (bp->bio_cmd == BIO_READ) { - err = nand_read_raw(chip, - bp->bio_offset & 0xffffffff, - bp->bio_data, bp->bio_bcount); - } else if (bp->bio_cmd == BIO_WRITE) { - err = nand_write_raw(chip, - bp->bio_offset & 0xffffffff, - bp->bio_data, bp->bio_bcount); - } - } else - panic("Unknown access type in bio->bio_driver1\n"); - - if (bp->bio_cmd == BIO_DELETE) { - nand_debug(NDBG_GEOM, "Delete on chip%d offset %lld " - "length %ld\n", chip->num, bp->bio_offset, - bp->bio_bcount); - err = nand_erase_blocks(chip, - bp->bio_offset & 0xffffffff, - bp->bio_bcount); - } - - if (err == 0 || err == ECC_CORRECTABLE) - bp->bio_resid = 0; - else { - nand_debug(NDBG_GEOM,"nand_[read|write|erase_blocks] " - "error: %d\n", err); - - bp->bio_error = EIO; - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; - } - biodone(bp); - } -} - -int -create_geom_disk(struct nand_chip *chip) -{ - struct disk *ndisk, *rdisk; - - /* Create the disk device */ - ndisk = disk_alloc(); - ndisk->d_strategy = nand_strategy; - ndisk->d_ioctl = nand_ioctl; - ndisk->d_getattr = nand_getattr; - ndisk->d_name = "gnand"; - ndisk->d_drv1 = chip; - ndisk->d_maxsize = chip->chip_geom.block_size; - ndisk->d_sectorsize = chip->chip_geom.page_size; - ndisk->d_mediasize = chip->chip_geom.chip_size; - ndisk->d_unit = chip->num + - 10 * device_get_unit(device_get_parent(chip->dev)); - - /* - * When using BBT, make two last blocks of device unavailable - * to user (because those are used to store BBT table). - */ - if (chip->bbt != NULL) - ndisk->d_mediasize -= (2 * chip->chip_geom.block_size); - - ndisk->d_flags = DISKFLAG_CANDELETE; - - snprintf(ndisk->d_ident, sizeof(ndisk->d_ident), - "nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, chip->id.dev_id); - ndisk->d_rotation_rate = DISK_RR_NON_ROTATING; - - disk_create(ndisk, DISK_VERSION); - - /* Create the RAW disk device */ - rdisk = disk_alloc(); - rdisk->d_strategy = nand_strategy_raw; - rdisk->d_ioctl = nand_ioctl; - rdisk->d_getattr = nand_getattr; - rdisk->d_name = "gnand.raw"; - rdisk->d_drv1 = chip; - rdisk->d_maxsize = chip->chip_geom.block_size; - rdisk->d_sectorsize = chip->chip_geom.page_size; - rdisk->d_mediasize = chip->chip_geom.chip_size; - rdisk->d_unit = chip->num + - 10 * device_get_unit(device_get_parent(chip->dev)); - - rdisk->d_flags = DISKFLAG_CANDELETE; - - snprintf(rdisk->d_ident, sizeof(rdisk->d_ident), - "nand_raw: Man:0x%02x Dev:0x%02x", chip->id.man_id, - chip->id.dev_id); - rdisk->d_rotation_rate = DISK_RR_NON_ROTATING; - - disk_create(rdisk, DISK_VERSION); - - chip->ndisk = ndisk; - chip->rdisk = rdisk; - - mtx_init(&chip->qlock, "NAND I/O lock", NULL, MTX_DEF); - bioq_init(&chip->bioq); - - TASK_INIT(&chip->iotask, 0, nand_io_proc, chip); - chip->tq = taskqueue_create("nand_taskq", M_WAITOK, - taskqueue_thread_enqueue, &chip->tq); - taskqueue_start_threads(&chip->tq, 1, PI_DISK, "nand taskq"); - - if (bootverbose) - device_printf(chip->dev, "Created gnand%d for chip [0x%0x, " - "0x%0x]\n", ndisk->d_unit, chip->id.man_id, - chip->id.dev_id); - - return (0); -} - -void -destroy_geom_disk(struct nand_chip *chip) -{ - struct bio *bp; - - taskqueue_free(chip->tq); - disk_destroy(chip->ndisk); - disk_destroy(chip->rdisk); - - mtx_lock(&chip->qlock); - for (;;) { - bp = bioq_takefirst(&chip->bioq); - if (bp == NULL) - break; - bp->bio_error = EIO; - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; - - biodone(bp); - } - mtx_unlock(&chip->qlock); - - mtx_destroy(&chip->qlock); -} Property changes on: head/sys/dev/nand/nand_geom.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_log.h =================================================================== --- head/sys/dev/nand/nandsim_log.h (revision 349351) +++ head/sys/dev/nand/nandsim_log.h (nonexistent) @@ -1,54 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 _NANDSIM_LOG_H -#define _NANDSIM_LOG_H - -#include - -#define NANDSIM_ENTRY_SIZE 128 -#define NANDSIM_ENTRY_COUNT 1024 -#define NANDSIM_RAM_LOG_SIZE 16384 -#define TIME_STR_SIZE 40 - -#define NANDSIM_LOG_ERR 1 -#define NANDSIM_LOG_SM 5 -#define NANDSIM_LOG_EV 10 -#define NANDSIM_LOG_DATA 15 - -extern int nandsim_log_level; -extern int nandsim_log_output; - -int nandsim_log_init(struct nandsim_softc *, char *); -void nandsim_log_close(struct nandsim_softc *); -void nandsim_log(struct nandsim_chip *, int, const char *, ...); - -#endif /* _NANDSIM_LOG_H */ - Property changes on: head/sys/dev/nand/nandsim_log.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_chip.c =================================================================== --- head/sys/dev/nand/nandsim_chip.c (revision 349351) +++ head/sys/dev/nand/nandsim_chip.c (nonexistent) @@ -1,898 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -MALLOC_DEFINE(M_NANDSIM, "NANDsim", "NANDsim dynamic data"); - -#define NANDSIM_CHIP_LOCK(chip) mtx_lock(&(chip)->ns_lock) -#define NANDSIM_CHIP_UNLOCK(chip) mtx_unlock(&(chip)->ns_lock) - -static nandsim_evh_t erase_evh; -static nandsim_evh_t idle_evh; -static nandsim_evh_t poweron_evh; -static nandsim_evh_t reset_evh; -static nandsim_evh_t read_evh; -static nandsim_evh_t readid_evh; -static nandsim_evh_t readparam_evh; -static nandsim_evh_t write_evh; - -static void nandsim_loop(void *); -static void nandsim_undefined(struct nandsim_chip *, uint8_t); -static void nandsim_bad_address(struct nandsim_chip *, uint8_t *); -static void nandsim_ignore_address(struct nandsim_chip *, uint8_t); -static void nandsim_sm_error(struct nandsim_chip *); -static void nandsim_start_handler(struct nandsim_chip *, nandsim_evh_t); - -static void nandsim_callout_eh(void *); -static int nandsim_delay(struct nandsim_chip *, int); - -static int nandsim_bbm_init(struct nandsim_chip *, uint32_t, uint32_t *); -static int nandsim_blk_state_init(struct nandsim_chip *, uint32_t, uint32_t); -static void nandsim_blk_state_destroy(struct nandsim_chip *); -static int nandchip_is_block_valid(struct nandsim_chip *, int); - -static void nandchip_set_status(struct nandsim_chip *, uint8_t); -static void nandchip_clear_status(struct nandsim_chip *, uint8_t); - -struct proc *nandsim_proc; - -struct nandsim_chip * -nandsim_chip_init(struct nandsim_softc* sc, uint8_t chip_num, - struct sim_chip *sim_chip) -{ - struct nandsim_chip *chip; - struct onfi_params *chip_param; - char swapfile[20]; - uint32_t size; - int error; - - chip = malloc(sizeof(*chip), M_NANDSIM, M_WAITOK | M_ZERO); - - mtx_init(&chip->ns_lock, "nandsim lock", NULL, MTX_DEF); - callout_init(&chip->ns_callout, 1); - STAILQ_INIT(&chip->nandsim_events); - - chip->chip_num = chip_num; - chip->ctrl_num = sim_chip->ctrl_num; - chip->sc = sc; - - if (!sim_chip->is_wp) - nandchip_set_status(chip, NAND_STATUS_WP); - - chip_param = &chip->params; - - chip->id.dev_id = sim_chip->device_id; - chip->id.man_id = sim_chip->manufact_id; - - chip->error_ratio = sim_chip->error_ratio; - chip->wear_level = sim_chip->wear_level; - chip->prog_delay = sim_chip->prog_time; - chip->erase_delay = sim_chip->erase_time; - chip->read_delay = sim_chip->read_time; - - chip_param->t_prog = sim_chip->prog_time; - chip_param->t_bers = sim_chip->erase_time; - chip_param->t_r = sim_chip->read_time; - bcopy("onfi", &chip_param->signature, 4); - - chip_param->manufacturer_id = sim_chip->manufact_id; - strncpy(chip_param->manufacturer_name, sim_chip->manufacturer, 12); - chip_param->manufacturer_name[11] = 0; - strncpy(chip_param->device_model, sim_chip->device_model, 20); - chip_param->device_model[19] = 0; - - chip_param->bytes_per_page = sim_chip->page_size; - chip_param->spare_bytes_per_page = sim_chip->oob_size; - chip_param->pages_per_block = sim_chip->pgs_per_blk; - chip_param->blocks_per_lun = sim_chip->blks_per_lun; - chip_param->luns = sim_chip->luns; - - init_chip_geom(&chip->cg, chip_param->luns, chip_param->blocks_per_lun, - chip_param->pages_per_block, chip_param->bytes_per_page, - chip_param->spare_bytes_per_page); - - chip_param->address_cycles = sim_chip->row_addr_cycles | - (sim_chip->col_addr_cycles << 4); - chip_param->features = sim_chip->features; - if (sim_chip->width == 16) - chip_param->features |= ONFI_FEAT_16BIT; - - size = chip_param->blocks_per_lun * chip_param->luns; - - error = nandsim_blk_state_init(chip, size, sim_chip->wear_level); - if (error) { - mtx_destroy(&chip->ns_lock); - free(chip, M_NANDSIM); - return (NULL); - } - - error = nandsim_bbm_init(chip, size, sim_chip->bad_block_map); - if (error) { - mtx_destroy(&chip->ns_lock); - nandsim_blk_state_destroy(chip); - free(chip, M_NANDSIM); - return (NULL); - } - - nandsim_start_handler(chip, poweron_evh); - - nand_debug(NDBG_SIM,"Create thread for chip%d [%8p]", chip->chip_num, - chip); - /* Create chip thread */ - error = kproc_kthread_add(nandsim_loop, chip, &nandsim_proc, - &chip->nandsim_td, RFSTOPPED | RFHIGHPID, - 0, "nandsim", "chip"); - if (error) { - mtx_destroy(&chip->ns_lock); - nandsim_blk_state_destroy(chip); - free(chip, M_NANDSIM); - return (NULL); - } - - thread_lock(chip->nandsim_td); - sched_class(chip->nandsim_td, PRI_REALTIME); - sched_add(chip->nandsim_td, SRQ_BORING); - thread_unlock(chip->nandsim_td); - - size = (chip_param->bytes_per_page + - chip_param->spare_bytes_per_page) * - chip_param->pages_per_block; - - sprintf(swapfile, "chip%d%d.swp", chip->ctrl_num, chip->chip_num); - chip->swap = nandsim_swap_init(swapfile, chip_param->blocks_per_lun * - chip_param->luns, size); - if (!chip->swap) - nandsim_chip_destroy(chip); - - /* Wait for new thread to enter main loop */ - tsleep(chip->nandsim_td, PWAIT, "ns_chip", 1 * hz); - - return (chip); -} - -static int -nandsim_blk_state_init(struct nandsim_chip *chip, uint32_t size, - uint32_t wear_lev) -{ - int i; - - if (!chip || size == 0) - return (-1); - - chip->blk_state = malloc(size * sizeof(struct nandsim_block_state), - M_NANDSIM, M_WAITOK | M_ZERO); - - for (i = 0; i < size; i++) { - if (wear_lev) - chip->blk_state[i].wear_lev = wear_lev; - else - chip->blk_state[i].wear_lev = -1; - } - - return (0); -} - -static void -nandsim_blk_state_destroy(struct nandsim_chip *chip) -{ - - if (chip && chip->blk_state) - free(chip->blk_state, M_NANDSIM); -} - -static int -nandsim_bbm_init(struct nandsim_chip *chip, uint32_t size, - uint32_t *sim_bbm) -{ - uint32_t index; - int i; - - if ((chip == NULL) || (size == 0)) - return (-1); - - if (chip->blk_state == NULL) - return (-1); - - if (sim_bbm == NULL) - return (0); - - for (i = 0; i < MAX_BAD_BLOCKS; i++) { - index = sim_bbm[i]; - - if (index == 0xffffffff) - break; - else if (index > size) - return (-1); - else - chip->blk_state[index].is_bad = 1; - } - - return (0); -} - -void -nandsim_chip_destroy(struct nandsim_chip *chip) -{ - struct nandsim_ev *ev; - - ev = create_event(chip, NANDSIM_EV_EXIT, 0); - if (ev) - send_event(ev); -} - -void -nandsim_chip_freeze(struct nandsim_chip *chip) -{ - - chip->flags |= NANDSIM_CHIP_FROZEN; -} - -static void -nandsim_loop(void *arg) -{ - struct nandsim_chip *chip = (struct nandsim_chip *)arg; - struct nandsim_ev *ev; - - nand_debug(NDBG_SIM,"Start main loop for chip%d [%8p]", chip->chip_num, - chip); - for(;;) { - NANDSIM_CHIP_LOCK(chip); - if (!(chip->flags & NANDSIM_CHIP_ACTIVE)) { - chip->flags |= NANDSIM_CHIP_ACTIVE; - wakeup(chip->nandsim_td); - } - - if (STAILQ_EMPTY(&chip->nandsim_events)) { - nand_debug(NDBG_SIM,"Chip%d [%8p] going sleep", - chip->chip_num, chip); - msleep(chip, &chip->ns_lock, PRIBIO, "nandev", 0); - } - - ev = STAILQ_FIRST(&chip->nandsim_events); - STAILQ_REMOVE_HEAD(&chip->nandsim_events, links); - NANDSIM_CHIP_UNLOCK(chip); - if (ev->type == NANDSIM_EV_EXIT) { - NANDSIM_CHIP_LOCK(chip); - destroy_event(ev); - wakeup(ev); - while (!STAILQ_EMPTY(&chip->nandsim_events)) { - ev = STAILQ_FIRST(&chip->nandsim_events); - STAILQ_REMOVE_HEAD(&chip->nandsim_events, - links); - destroy_event(ev); - wakeup(ev); - } - NANDSIM_CHIP_UNLOCK(chip); - nandsim_log(chip, NANDSIM_LOG_SM, "destroyed\n"); - mtx_destroy(&chip->ns_lock); - nandsim_blk_state_destroy(chip); - nandsim_swap_destroy(chip->swap); - free(chip, M_NANDSIM); - nandsim_proc = NULL; - - kthread_exit(); - } - - if (!(chip->flags & NANDSIM_CHIP_FROZEN)) { - nand_debug(NDBG_SIM,"Chip [%x] get event [%x]", - chip->chip_num, ev->type); - chip->ev_handler(chip, ev->type, ev->data); - } - - wakeup(ev); - destroy_event(ev); - } - -} - -struct nandsim_ev * -create_event(struct nandsim_chip *chip, uint8_t type, uint8_t data_size) -{ - struct nandsim_ev *ev; - - ev = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO); - if (!ev) { - nand_debug(NDBG_SIM,"Cannot create event"); - return (NULL); - } - - if (data_size > 0) - ev->data = malloc(sizeof(*ev), M_NANDSIM, M_NOWAIT | M_ZERO); - ev->type = type; - ev->chip = chip; - - return (ev); -} - -void -destroy_event(struct nandsim_ev *ev) -{ - - if (ev->data) - free(ev->data, M_NANDSIM); - free(ev, M_NANDSIM); -} - -int -send_event(struct nandsim_ev *ev) -{ - struct nandsim_chip *chip = ev->chip; - - if (!(chip->flags & NANDSIM_CHIP_FROZEN)) { - nand_debug(NDBG_SIM,"Chip%d [%p] send event %x", - chip->chip_num, chip, ev->type); - - NANDSIM_CHIP_LOCK(chip); - STAILQ_INSERT_TAIL(&chip->nandsim_events, ev, links); - NANDSIM_CHIP_UNLOCK(chip); - - wakeup(chip); - if ((ev->type != NANDSIM_EV_TIMEOUT) && chip->nandsim_td && - (curthread != chip->nandsim_td)) - tsleep(ev, PWAIT, "ns_ev", 5 * hz); - } - - return (0); -} - -static void -nandsim_callout_eh(void *arg) -{ - struct nandsim_ev *ev = (struct nandsim_ev *)arg; - - send_event(ev); -} - -static int -nandsim_delay(struct nandsim_chip *chip, int timeout) -{ - struct nandsim_ev *ev; - struct timeval delay; - int tm; - - nand_debug(NDBG_SIM,"Chip[%d] Set delay: %d", chip->chip_num, timeout); - - ev = create_event(chip, NANDSIM_EV_TIMEOUT, 0); - if (!ev) - return (-1); - - chip->sm_state = NANDSIM_STATE_TIMEOUT; - tm = (timeout/10000) * (hz / 100); - if (callout_reset(&chip->ns_callout, tm, nandsim_callout_eh, ev)) - return (-1); - - delay.tv_sec = chip->read_delay / 1000000; - delay.tv_usec = chip->read_delay % 1000000; - timevaladd(&chip->delay_tv, &delay); - - return (0); -} - -static void -nandsim_start_handler(struct nandsim_chip *chip, nandsim_evh_t evh) -{ - struct nandsim_ev *ev; - - chip->ev_handler = evh; - - nand_debug(NDBG_SIM,"Start handler %p for chip%d [%p]", evh, - chip->chip_num, chip); - ev = create_event(chip, NANDSIM_EV_START, 0); - if (!ev) - nandsim_sm_error(chip); - - send_event(ev); -} - -static void -nandchip_set_data(struct nandsim_chip *chip, uint8_t *data, uint32_t len, - uint32_t idx) -{ - - nand_debug(NDBG_SIM,"Chip [%x] data %p [%x] at %x", chip->chip_num, - data, len, idx); - chip->data.data_ptr = data; - chip->data.size = len; - chip->data.index = idx; -} - -static int -nandchip_chip_space(struct nandsim_chip *chip, int32_t row, int32_t column, - size_t size, uint8_t writing) -{ - struct block_space *blk_space; - uint32_t lun, block, page, offset, block_size; - int err; - - block_size = chip->cg.block_size + - (chip->cg.oob_size * chip->cg.pgs_per_blk); - - err = nand_row_to_blkpg(&chip->cg, row, &lun, &block, &page); - if (err) { - nand_debug(NDBG_SIM,"cannot get address\n"); - return (-1); - } - - if (!nandchip_is_block_valid(chip, block)) { - nandchip_set_data(chip, NULL, 0, 0); - return (-1); - } - - blk_space = get_bs(chip->swap, block, writing); - if (!blk_space) { - nandchip_set_data(chip, NULL, 0, 0); - return (-1); - } - - if (size > block_size) - size = block_size; - - if (size == block_size) { - offset = 0; - column = 0; - } else - offset = page * (chip->cg.page_size + chip->cg.oob_size); - - nandchip_set_data(chip, &blk_space->blk_ptr[offset], size, column); - - return (0); -} - -static int -nandchip_get_addr_byte(struct nandsim_chip *chip, void *data, uint32_t *value) -{ - int ncycles = 0; - uint8_t byte; - uint8_t *buffer; - - buffer = (uint8_t *)value; - byte = *((uint8_t *)data); - - KASSERT((chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW || - chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL), - ("unexpected state")); - - if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { - ncycles = chip->params.address_cycles & 0xf; - buffer[chip->sm_addr_cycle++] = byte; - } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) { - ncycles = (chip->params.address_cycles >> 4) & 0xf; - buffer[chip->sm_addr_cycle++] = byte; - } - - nand_debug(NDBG_SIM, "Chip [%x] read addr byte: %02x (%d of %d)\n", - chip->chip_num, byte, chip->sm_addr_cycle, ncycles); - - if (chip->sm_addr_cycle == ncycles) { - chip->sm_addr_cycle = 0; - return (0); - } - - return (1); -} - -static int -nandchip_is_block_valid(struct nandsim_chip *chip, int block_num) -{ - - if (!chip || !chip->blk_state) - return (0); - - if (chip->blk_state[block_num].wear_lev == 0 || - chip->blk_state[block_num].is_bad) - return (0); - - return (1); -} - -static void -nandchip_set_status(struct nandsim_chip *chip, uint8_t flags) -{ - - chip->chip_status |= flags; -} - -static void -nandchip_clear_status(struct nandsim_chip *chip, uint8_t flags) -{ - - chip->chip_status &= ~flags; -} - -uint8_t -nandchip_get_status(struct nandsim_chip *chip) -{ - return (chip->chip_status); -} - -void -nandsim_chip_timeout(struct nandsim_chip *chip) -{ - struct timeval tv; - - getmicrotime(&tv); - - if (chip->sm_state == NANDSIM_STATE_TIMEOUT && - timevalcmp(&tv, &chip->delay_tv, >=)) { - nandchip_set_status(chip, NAND_STATUS_RDY); - } -} -void -poweron_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - uint8_t cmd; - - if (type == NANDSIM_EV_START) - chip->sm_state = NANDSIM_STATE_IDLE; - else if (type == NANDSIM_EV_CMD) { - cmd = *(uint8_t *)data; - switch(cmd) { - case NAND_CMD_RESET: - nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n"); - nandsim_start_handler(chip, reset_evh); - break; - default: - nandsim_undefined(chip, type); - break; - } - } else - nandsim_undefined(chip, type); -} - -void -idle_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - uint8_t cmd; - - if (type == NANDSIM_EV_START) { - nandsim_log(chip, NANDSIM_LOG_SM, "in IDLE state\n"); - chip->sm_state = NANDSIM_STATE_WAIT_CMD; - } else if (type == NANDSIM_EV_CMD) { - nandchip_clear_status(chip, NAND_STATUS_FAIL); - getmicrotime(&chip->delay_tv); - cmd = *(uint8_t *)data; - switch(cmd) { - case NAND_CMD_READ_ID: - nandsim_start_handler(chip, readid_evh); - break; - case NAND_CMD_READ_PARAMETER: - nandsim_start_handler(chip, readparam_evh); - break; - case NAND_CMD_READ: - nandsim_start_handler(chip, read_evh); - break; - case NAND_CMD_PROG: - nandsim_start_handler(chip, write_evh); - break; - case NAND_CMD_ERASE: - nandsim_start_handler(chip, erase_evh); - break; - default: - nandsim_undefined(chip, type); - break; - } - } else - nandsim_undefined(chip, type); -} - -void -readid_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - struct onfi_params *params; - uint8_t addr; - - params = &chip->params; - - if (type == NANDSIM_EV_START) { - nandsim_log(chip, NANDSIM_LOG_SM, "in READID state\n"); - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE; - } else if (type == NANDSIM_EV_ADDR) { - - addr = *((uint8_t *)data); - - if (addr == 0x0) - nandchip_set_data(chip, (uint8_t *)&chip->id, 2, 0); - else if (addr == ONFI_SIG_ADDR) - nandchip_set_data(chip, (uint8_t *)¶ms->signature, - 4, 0); - else - nandsim_bad_address(chip, &addr); - - nandsim_start_handler(chip, idle_evh); - } else - nandsim_undefined(chip, type); -} - -void -readparam_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - struct onfi_params *params; - uint8_t addr; - - params = &chip->params; - - if (type == NANDSIM_EV_START) { - nandsim_log(chip, NANDSIM_LOG_SM, "in READPARAM state\n"); - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_BYTE; - } else if (type == NANDSIM_EV_ADDR) { - addr = *((uint8_t *)data); - - if (addr == 0) { - nandchip_set_data(chip, (uint8_t *)params, - sizeof(*params), 0); - } else - nandsim_bad_address(chip, &addr); - - nandsim_start_handler(chip, idle_evh); - } else - nandsim_undefined(chip, type); -} - -void -read_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - static uint32_t column = 0, row = 0; - uint32_t size; - uint8_t cmd; - - size = chip->cg.page_size + chip->cg.oob_size; - - switch (type) { - case NANDSIM_EV_START: - nandsim_log(chip, NANDSIM_LOG_SM, "in READ state\n"); - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL; - break; - case NANDSIM_EV_ADDR: - if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) { - if (nandchip_get_addr_byte(chip, data, &column)) - break; - - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW; - } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { - if (nandchip_get_addr_byte(chip, data, &row)) - break; - - chip->sm_state = NANDSIM_STATE_WAIT_CMD; - } else - nandsim_ignore_address(chip, *((uint8_t *)data)); - break; - case NANDSIM_EV_CMD: - cmd = *(uint8_t *)data; - if (chip->sm_state == NANDSIM_STATE_WAIT_CMD && - cmd == NAND_CMD_READ_END) { - if (chip->read_delay != 0 && - nandsim_delay(chip, chip->read_delay) == 0) - nandchip_clear_status(chip, NAND_STATUS_RDY); - else { - nandchip_chip_space(chip, row, column, size, 0); - nandchip_set_status(chip, NAND_STATUS_RDY); - nandsim_start_handler(chip, idle_evh); - } - } else - nandsim_undefined(chip, type); - break; - case NANDSIM_EV_TIMEOUT: - if (chip->sm_state == NANDSIM_STATE_TIMEOUT) { - nandchip_chip_space(chip, row, column, size, 0); - nandchip_set_status(chip, NAND_STATUS_RDY); - nandsim_start_handler(chip, idle_evh); - } else - nandsim_undefined(chip, type); - break; - } -} -void -write_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - static uint32_t column, row; - uint32_t size; - uint8_t cmd; - int err; - - size = chip->cg.page_size + chip->cg.oob_size; - - switch(type) { - case NANDSIM_EV_START: - nandsim_log(chip, NANDSIM_LOG_SM, "in WRITE state\n"); - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_COL; - break; - case NANDSIM_EV_ADDR: - if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_COL) { - if (nandchip_get_addr_byte(chip, data, &column)) - break; - - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW; - } else if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { - if (nandchip_get_addr_byte(chip, data, &row)) - break; - - err = nandchip_chip_space(chip, row, column, size, 1); - if (err == -1) - nandchip_set_status(chip, NAND_STATUS_FAIL); - - chip->sm_state = NANDSIM_STATE_WAIT_CMD; - } else - nandsim_ignore_address(chip, *((uint8_t *)data)); - break; - case NANDSIM_EV_CMD: - cmd = *(uint8_t *)data; - if (chip->sm_state == NANDSIM_STATE_WAIT_CMD && - cmd == NAND_CMD_PROG_END) { - if (chip->prog_delay != 0 && - nandsim_delay(chip, chip->prog_delay) == 0) - nandchip_clear_status(chip, NAND_STATUS_RDY); - else { - nandchip_set_status(chip, NAND_STATUS_RDY); - nandsim_start_handler(chip, idle_evh); - } - } else - nandsim_undefined(chip, type); - break; - case NANDSIM_EV_TIMEOUT: - if (chip->sm_state == NANDSIM_STATE_TIMEOUT) { - nandsim_start_handler(chip, idle_evh); - nandchip_set_status(chip, NAND_STATUS_RDY); - } else - nandsim_undefined(chip, type); - break; - } -} - -void -erase_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - static uint32_t row, block_size; - uint32_t lun, block, page; - int err; - uint8_t cmd; - - block_size = chip->cg.block_size + - (chip->cg.oob_size * chip->cg.pgs_per_blk); - - switch (type) { - case NANDSIM_EV_START: - nandsim_log(chip, NANDSIM_LOG_SM, "in ERASE state\n"); - chip->sm_state = NANDSIM_STATE_WAIT_ADDR_ROW; - break; - case NANDSIM_EV_CMD: - cmd = *(uint8_t *)data; - if (chip->sm_state == NANDSIM_STATE_WAIT_CMD && - cmd == NAND_CMD_ERASE_END) { - if (chip->data.data_ptr != NULL && - chip->data.size == block_size) - memset(chip->data.data_ptr, 0xff, block_size); - else - nand_debug(NDBG_SIM,"Bad block erase data\n"); - - err = nand_row_to_blkpg(&chip->cg, row, &lun, - &block, &page); - if (!err) { - if (chip->blk_state[block].wear_lev > 0) - chip->blk_state[block].wear_lev--; - } - - if (chip->erase_delay != 0 && - nandsim_delay(chip, chip->erase_delay) == 0) - nandchip_clear_status(chip, NAND_STATUS_RDY); - else { - nandchip_set_status(chip, NAND_STATUS_RDY); - nandsim_start_handler(chip, idle_evh); - } - } else - nandsim_undefined(chip, type); - break; - case NANDSIM_EV_ADDR: - if (chip->sm_state == NANDSIM_STATE_WAIT_ADDR_ROW) { - if (nandchip_get_addr_byte(chip, data, &row)) - break; - - err = nandchip_chip_space(chip, row, 0, block_size, 1); - if (err == -1) { - nandchip_set_status(chip, NAND_STATUS_FAIL); - } - chip->sm_state = NANDSIM_STATE_WAIT_CMD; - } else - nandsim_ignore_address(chip, *((uint8_t *)data)); - break; - case NANDSIM_EV_TIMEOUT: - if (chip->sm_state == NANDSIM_STATE_TIMEOUT) { - nandchip_set_status(chip, NAND_STATUS_RDY); - nandsim_start_handler(chip, idle_evh); - } else - nandsim_undefined(chip, type); - break; - } -} - -void -reset_evh(struct nandsim_chip *chip, uint32_t type, void *data) -{ - - if (type == NANDSIM_EV_START) { - nandsim_log(chip, NANDSIM_LOG_SM, "in RESET state\n"); - chip->sm_state = NANDSIM_STATE_TIMEOUT; - nandchip_set_data(chip, NULL, 0, 0); - DELAY(500); - nandsim_start_handler(chip, idle_evh); - } else - nandsim_undefined(chip, type); -} - -static void -nandsim_undefined(struct nandsim_chip *chip, uint8_t type) -{ - - nandsim_log(chip, NANDSIM_LOG_ERR, - "ERR: Chip received ev %x in state %x\n", - type, chip->sm_state); - nandsim_start_handler(chip, idle_evh); -} - -static void -nandsim_bad_address(struct nandsim_chip *chip, uint8_t *addr) -{ - - nandsim_log(chip, NANDSIM_LOG_ERR, - "ERR: Chip received out of range address" - "%02x%02x - %02x%02x%02x\n", addr[0], addr[1], addr[2], - addr[3], addr[4]); -} - -static void -nandsim_ignore_address(struct nandsim_chip *chip, uint8_t byte) -{ - nandsim_log(chip, NANDSIM_LOG_SM, "ignored address byte: %d\n", byte); -} - -static void -nandsim_sm_error(struct nandsim_chip *chip) -{ - - nandsim_log(chip, NANDSIM_LOG_ERR, "ERR: State machine error." - "Restart required.\n"); -} Property changes on: head/sys/dev/nand/nandsim_chip.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim.h =================================================================== --- head/sys/dev/nand/nandsim.h (revision 349351) +++ head/sys/dev/nand/nandsim.h (nonexistent) @@ -1,177 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 _NANDSIM_H_ -#define _NANDSIM_H_ - -#include -#include - -#define MAX_SIM_DEV 4 -#define MAX_CTRL_CS 4 -#define MAX_ECC_BYTES 512 -#define MAX_BAD_BLOCKS 512 -#define DEV_MODEL_STR_SIZE 21 -#define MAN_STR_SIZE 13 -#define FILENAME_SIZE 20 - -#define MAX_CHIPS (MAX_SIM_DEV*MAX_CTRL_CS) - -#define NANDSIM_OUTPUT_NONE 0x0 -#define NANDSIM_OUTPUT_CONSOLE 0x1 -#define NANDSIM_OUTPUT_RAM 0x2 -#define NANDSIM_OUTPUT_FILE 0x3 - -struct sim_ctrl_chip { - uint8_t ctrl_num; - uint8_t chip_num; -}; - -#define NANDSIM_BASE 'A' - -struct sim_param { - uint8_t log_level; - uint8_t log_output; -}; - -#define NANDSIM_SIM_PARAM _IOW(NANDSIM_BASE, 1, struct sim_param) - -struct sim_ctrl { - uint8_t running; - uint8_t created; - uint8_t num; - uint8_t num_cs; - uint8_t ecc; - char filename[FILENAME_SIZE]; - uint16_t ecc_layout[MAX_ECC_BYTES]; -}; -#define NANDSIM_CREATE_CTRL _IOW(NANDSIM_BASE, 2, struct sim_ctrl) -#define NANDSIM_DESTROY_CTRL _IOW(NANDSIM_BASE, 3, int) - -struct sim_chip { - uint8_t num; - uint8_t ctrl_num; - uint8_t created; - uint8_t device_id; - uint8_t manufact_id; - char device_model[DEV_MODEL_STR_SIZE]; - char manufacturer[MAN_STR_SIZE]; - uint8_t col_addr_cycles; - uint8_t row_addr_cycles; - uint8_t features; - uint8_t width; - uint32_t page_size; - uint32_t oob_size; - uint32_t pgs_per_blk; - uint32_t blks_per_lun; - uint32_t luns; - - uint32_t prog_time; - uint32_t erase_time; - uint32_t read_time; - uint32_t ccs_time; - - uint32_t error_ratio; - uint32_t wear_level; - uint32_t bad_block_map[MAX_BAD_BLOCKS]; - uint8_t is_wp; -}; - -#define NANDSIM_CREATE_CHIP _IOW(NANDSIM_BASE, 3, struct sim_chip) - -struct sim_chip_destroy { - uint8_t ctrl_num; - uint8_t chip_num; -}; -#define NANDSIM_DESTROY_CHIP _IOW(NANDSIM_BASE, 4, struct sim_chip_destroy) - -#define NANDSIM_START_CTRL _IOW(NANDSIM_BASE, 5, int) -#define NANDSIM_STOP_CTRL _IOW(NANDSIM_BASE, 6, int) -#define NANDSIM_RESTART_CTRL _IOW(NANDSIM_BASE, 7, int) - -#define NANDSIM_STATUS_CTRL _IOWR(NANDSIM_BASE, 8, struct sim_ctrl) -#define NANDSIM_STATUS_CHIP _IOWR(NANDSIM_BASE, 9, struct sim_chip) - -struct sim_mod { - uint8_t chip_num; - uint8_t ctrl_num; - uint32_t field; - uint32_t new_value; -}; -#define SIM_MOD_LOG_LEVEL 0 -#define SIM_MOD_ERASE_TIME 1 -#define SIM_MOD_PROG_TIME 2 -#define SIM_MOD_READ_TIME 3 -#define SIM_MOD_CCS_TIME 4 -#define SIM_MOD_ERROR_RATIO 5 - -#define NANDSIM_MODIFY _IOW(NANDSIM_BASE, 10, struct sim_mod) -#define NANDSIM_FREEZE _IOW(NANDSIM_BASE, 11, struct sim_ctrl_chip) - -struct sim_error { - uint8_t ctrl_num; - uint8_t chip_num; - uint32_t page_num; - uint32_t column; - uint32_t len; - uint32_t pattern; -}; -#define NANDSIM_INJECT_ERROR _IOW(NANDSIM_BASE, 20, struct sim_error) - -#define NANDSIM_GOOD_BLOCK 0 -#define NANDSIM_BAD_BLOCK 1 -struct sim_block_state { - uint8_t ctrl_num; - uint8_t chip_num; - uint32_t block_num; - int wearout; - uint8_t state; -}; -#define NANDSIM_SET_BLOCK_STATE _IOW(NANDSIM_BASE, 21, struct sim_block_state) -#define NANDSIM_GET_BLOCK_STATE _IOWR(NANDSIM_BASE, 22, struct sim_block_state) - -struct sim_log { - uint8_t ctrl_num; - char* log; - size_t len; -}; -#define NANDSIM_PRINT_LOG _IOWR(NANDSIM_BASE, 23, struct sim_log) - -struct sim_dump { - uint8_t ctrl_num; - uint8_t chip_num; - uint32_t block_num; - uint32_t len; - void* data; -}; -#define NANDSIM_DUMP _IOWR(NANDSIM_BASE, 24, struct sim_dump) -#define NANDSIM_RESTORE _IOWR(NANDSIM_BASE, 25, struct sim_dump) - -#endif /* _NANDSIM_H_ */ Property changes on: head/sys/dev/nand/nandsim.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand.c =================================================================== --- head/sys/dev/nand/nand.c (revision 349351) +++ head/sys/dev/nand/nand.c (nonexistent) @@ -1,826 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "nfc_if.h" -#include "nand_if.h" -#include "nandbus_if.h" -#include - -#define NAND_RESET_DELAY 1000 /* tRST */ -#define NAND_ERASE_DELAY 3000 /* tBERS */ -#define NAND_PROG_DELAY 700 /* tPROG */ -#define NAND_READ_DELAY 50 /* tR */ - -#define BIT0(x) ((x) & 0x1) -#define BIT1(x) (BIT0(x >> 1)) -#define BIT2(x) (BIT0(x >> 2)) -#define BIT3(x) (BIT0(x >> 3)) -#define BIT4(x) (BIT0(x >> 4)) -#define BIT5(x) (BIT0(x >> 5)) -#define BIT6(x) (BIT0(x >> 6)) -#define BIT7(x) (BIT0(x >> 7)) - -#define SOFTECC_SIZE 256 -#define SOFTECC_BYTES 3 - -int nand_debug_flag = 0; -SYSCTL_INT(_debug, OID_AUTO, nand_debug, CTLFLAG_RWTUN, &nand_debug_flag, 0, - "NAND subsystem debug flag"); - -MALLOC_DEFINE(M_NAND, "NAND", "NAND dynamic data"); - -static void calculate_ecc(const uint8_t *, uint8_t *); -static int correct_ecc(uint8_t *, uint8_t *, uint8_t *); - -void -nand_debug(int level, const char *fmt, ...) -{ - va_list ap; - - if (!(nand_debug_flag & level)) - return; - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - printf("\n"); -} - -void -nand_init(struct nand_softc *nand, device_t dev, int ecc_mode, - int ecc_bytes, int ecc_size, uint16_t *eccposition, char *cdev_name) -{ - - nand->ecc.eccmode = ecc_mode; - nand->chip_cdev_name = cdev_name; - - if (ecc_mode == NAND_ECC_SOFT) { - nand->ecc.eccbytes = SOFTECC_BYTES; - nand->ecc.eccsize = SOFTECC_SIZE; - } else if (ecc_mode != NAND_ECC_NONE) { - nand->ecc.eccbytes = ecc_bytes; - nand->ecc.eccsize = ecc_size; - if (eccposition) - nand->ecc.eccpositions = eccposition; - } -} - -void -nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params) -{ - struct chip_geom *cg; - - cg = &chip->chip_geom; - - init_chip_geom(cg, params->luns, params->blocks_per_lun, - params->pages_per_block, params->bytes_per_page, - params->spare_bytes_per_page); - chip->t_bers = params->t_bers; - chip->t_prog = params->t_prog; - chip->t_r = params->t_r; - chip->t_ccs = params->t_ccs; - - if (params->features & ONFI_FEAT_16BIT) - chip->flags |= NAND_16_BIT; -} - -void -nand_set_params(struct nand_chip *chip, struct nand_params *params) -{ - struct chip_geom *cg; - uint32_t blocks_per_chip; - - cg = &chip->chip_geom; - blocks_per_chip = (params->chip_size << 20) / - (params->page_size * params->pages_per_block); - - init_chip_geom(cg, 1, blocks_per_chip, - params->pages_per_block, params->page_size, - params->oob_size); - - chip->t_bers = NAND_ERASE_DELAY; - chip->t_prog = NAND_PROG_DELAY; - chip->t_r = NAND_READ_DELAY; - chip->t_ccs = 0; - - if (params->flags & NAND_16_BIT) - chip->flags |= NAND_16_BIT; -} - -int -nand_init_stat(struct nand_chip *chip) -{ - struct block_stat *blk_stat; - struct page_stat *pg_stat; - struct chip_geom *cg; - uint32_t blks, pgs; - - cg = &chip->chip_geom; - blks = cg->blks_per_lun * cg->luns; - blk_stat = malloc(sizeof(struct block_stat) * blks, M_NAND, - M_WAITOK | M_ZERO); - if (!blk_stat) - return (ENOMEM); - - pgs = blks * cg->pgs_per_blk; - pg_stat = malloc(sizeof(struct page_stat) * pgs, M_NAND, - M_WAITOK | M_ZERO); - if (!pg_stat) { - free(blk_stat, M_NAND); - return (ENOMEM); - } - - chip->blk_stat = blk_stat; - chip->pg_stat = pg_stat; - - return (0); -} - -void -nand_destroy_stat(struct nand_chip *chip) -{ - - free(chip->pg_stat, M_NAND); - free(chip->blk_stat, M_NAND); -} - -int -init_chip_geom(struct chip_geom *cg, uint32_t luns, uint32_t blks_per_lun, - uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size) -{ - int shift; - - if (!cg) - return (-1); - - cg->luns = luns; - cg->blks_per_lun = blks_per_lun; - cg->blks_per_chip = blks_per_lun * luns; - cg->pgs_per_blk = pgs_per_blk; - - cg->page_size = pg_size; - cg->oob_size = oob_size; - cg->block_size = cg->page_size * cg->pgs_per_blk; - cg->chip_size = cg->block_size * cg->blks_per_chip; - - shift = fls(cg->pgs_per_blk - 1); - cg->pg_mask = (1 << shift) - 1; - cg->blk_shift = shift; - - if (cg->blks_per_lun > 0) { - shift = fls(cg->blks_per_lun - 1); - cg->blk_mask = ((1 << shift) - 1) << cg->blk_shift; - } else { - shift = 0; - cg->blk_mask = 0; - } - - cg->lun_shift = shift + cg->blk_shift; - shift = fls(cg->luns - 1); - cg->lun_mask = ((1 << shift) - 1) << cg->lun_shift; - - nand_debug(NDBG_NAND, "Masks: lun 0x%x blk 0x%x page 0x%x\n" - "Shifts: lun %d blk %d", - cg->lun_mask, cg->blk_mask, cg->pg_mask, - cg->lun_shift, cg->blk_shift); - - return (0); -} - -int -nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun, - uint32_t *blk, uint32_t *pg) -{ - - if (!cg || !lun || !blk || !pg) - return (-1); - - if (row & ~(cg->lun_mask | cg->blk_mask | cg->pg_mask)) { - nand_debug(NDBG_NAND,"Address out of bounds\n"); - return (-1); - } - - *lun = (row & cg->lun_mask) >> cg->lun_shift; - *blk = (row & cg->blk_mask) >> cg->blk_shift; - *pg = (row & cg->pg_mask); - - nand_debug(NDBG_NAND,"address %x-%x-%x\n", *lun, *blk, *pg); - - return (0); -} - -int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row) -{ - uint32_t lun, block, pg_in_blk; - - if (!cg || !row) - return (-1); - - block = page / cg->pgs_per_blk; - pg_in_blk = page % cg->pgs_per_blk; - - lun = block / cg->blks_per_lun; - block = block % cg->blks_per_lun; - - *row = (lun << cg->lun_shift) & cg->lun_mask; - *row |= ((block << cg->blk_shift) & cg->blk_mask); - *row |= (pg_in_blk & cg->pg_mask); - - return (0); -} - -int -nand_check_page_boundary(struct nand_chip *chip, uint32_t page) -{ - struct chip_geom* cg; - - cg = &chip->chip_geom; - if (page >= (cg->pgs_per_blk * cg->blks_per_lun * cg->luns)) { - nand_debug(NDBG_GEN,"%s: page number too big %#x\n", - __func__, page); - return (1); - } - - return (0); -} - -void -nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param) -{ - struct chip_geom *cg; - - cg = &chip->chip_geom; - param->page_size = cg->page_size; - param->oob_size = cg->oob_size; - - param->blocks = cg->blks_per_lun * cg->luns; - param->pages_per_block = cg->pgs_per_blk; -} - -static uint16_t * -default_software_ecc_positions(struct nand_chip *chip) -{ - /* If positions have been set already, use them. */ - if (chip->nand->ecc.eccpositions) - return (chip->nand->ecc.eccpositions); - - /* - * XXX Note that the following logic isn't really sufficient, especially - * in the ONFI case where the number of ECC bytes can be dictated by - * values in the parameters page, and that could lead to needing more - * byte positions than exist within the tables of software-ecc defaults. - */ - if (chip->chip_geom.oob_size >= 128) - return (default_software_ecc_positions_128); - if (chip->chip_geom.oob_size >= 64) - return (default_software_ecc_positions_64); - else if (chip->chip_geom.oob_size >= 16) - return (default_software_ecc_positions_16); - - return (NULL); -} - -static void -calculate_ecc(const uint8_t *buf, uint8_t *ecc) -{ - uint8_t p8, byte; - int i; - - memset(ecc, 0, 3); - - for (i = 0; i < 256; i++) { - byte = buf[i]; - ecc[0] ^= (BIT0(byte) ^ BIT2(byte) ^ BIT4(byte) ^ - BIT6(byte)) << 2; - ecc[0] ^= (BIT1(byte) ^ BIT3(byte) ^ BIT5(byte) ^ - BIT7(byte)) << 3; - ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT4(byte) ^ - BIT5(byte)) << 4; - ecc[0] ^= (BIT2(byte) ^ BIT3(byte) ^ BIT6(byte) ^ - BIT7(byte)) << 5; - ecc[0] ^= (BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^ - BIT3(byte)) << 6; - ecc[0] ^= (BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^ - BIT7(byte)) << 7; - - p8 = BIT0(byte) ^ BIT1(byte) ^ BIT2(byte) ^ - BIT3(byte) ^ BIT4(byte) ^ BIT5(byte) ^ BIT6(byte) ^ - BIT7(byte); - - if (p8) { - ecc[2] ^= (0x1 << BIT0(i)); - ecc[2] ^= (0x4 << BIT1(i)); - ecc[2] ^= (0x10 << BIT2(i)); - ecc[2] ^= (0x40 << BIT3(i)); - - ecc[1] ^= (0x1 << BIT4(i)); - ecc[1] ^= (0x4 << BIT5(i)); - ecc[1] ^= (0x10 << BIT6(i)); - ecc[1] ^= (0x40 << BIT7(i)); - } - } - ecc[0] = ~ecc[0]; - ecc[1] = ~ecc[1]; - ecc[2] = ~ecc[2]; - ecc[0] |= 3; -} - -static int -correct_ecc(uint8_t *buf, uint8_t *calc_ecc, uint8_t *read_ecc) -{ - uint8_t ecc0, ecc1, ecc2, onesnum, bit, byte; - uint16_t addr = 0; - - ecc0 = calc_ecc[0] ^ read_ecc[0]; - ecc1 = calc_ecc[1] ^ read_ecc[1]; - ecc2 = calc_ecc[2] ^ read_ecc[2]; - - if (!ecc0 && !ecc1 && !ecc2) - return (ECC_OK); - - addr = BIT3(ecc0) | (BIT5(ecc0) << 1) | (BIT7(ecc0) << 2); - addr |= (BIT1(ecc2) << 3) | (BIT3(ecc2) << 4) | - (BIT5(ecc2) << 5) | (BIT7(ecc2) << 6); - addr |= (BIT1(ecc1) << 7) | (BIT3(ecc1) << 8) | - (BIT5(ecc1) << 9) | (BIT7(ecc1) << 10); - - onesnum = 0; - while (ecc0 || ecc1 || ecc2) { - if (ecc0 & 1) - onesnum++; - if (ecc1 & 1) - onesnum++; - if (ecc2 & 1) - onesnum++; - - ecc0 >>= 1; - ecc1 >>= 1; - ecc2 >>= 1; - } - - if (onesnum == 11) { - /* Correctable error */ - bit = addr & 7; - byte = addr >> 3; - buf[byte] ^= (1 << bit); - return (ECC_CORRECTABLE); - } else if (onesnum == 1) { - /* ECC error */ - return (ECC_ERROR_ECC); - } else { - /* Uncorrectable error */ - return (ECC_UNCORRECTABLE); - } - - return (0); -} - -int -nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc) -{ - int steps = pagesize / SOFTECC_SIZE; - int i = 0, j = 0; - - for (; i < (steps * SOFTECC_BYTES); - i += SOFTECC_BYTES, j += SOFTECC_SIZE) { - calculate_ecc(&buf[j], &ecc[i]); - } - - return (0); -} - -int -nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize, - uint8_t *readecc, uint8_t *calcecc) -{ - int steps = pagesize / SOFTECC_SIZE; - int i = 0, j = 0, ret = 0; - - for (i = 0; i < (steps * SOFTECC_BYTES); - i += SOFTECC_BYTES, j += SOFTECC_SIZE) { - ret += correct_ecc(&buf[j], &calcecc[i], &readecc[i]); - if (ret < 0) - return (ret); - } - - return (ret); -} - -static int -offset_to_page(struct chip_geom *cg, uint32_t offset) -{ - - return (offset / cg->page_size); -} - -int -nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf, - uint32_t len) -{ - struct chip_geom *cg; - struct nand_ecc_data *eccd; - struct page_stat *pg_stat; - device_t nandbus; - void *oob = NULL; - uint8_t *ptr; - uint16_t *eccpos = NULL; - uint32_t page, num, steps = 0; - int i, retval = 0, needwrite; - - nand_debug(NDBG_NAND,"%p read page %x[%x]", chip, offset, len); - cg = &chip->chip_geom; - eccd = &chip->nand->ecc; - page = offset_to_page(cg, offset); - num = len / cg->page_size; - - if (eccd->eccmode != NAND_ECC_NONE) { - steps = cg->page_size / eccd->eccsize; - eccpos = default_software_ecc_positions(chip); - oob = malloc(cg->oob_size, M_NAND, M_WAITOK); - } - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - ptr = (uint8_t *)buf; - while (num--) { - pg_stat = &(chip->pg_stat[page]); - - if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) { - retval = ENXIO; - break; - } - - if (eccd->eccmode != NAND_ECC_NONE) { - if (NAND_GET_ECC(chip->dev, ptr, eccd->ecccalculated, - &needwrite)) { - retval = ENXIO; - break; - } - nand_debug(NDBG_ECC,"%s: ECC calculated:", - __func__); - if (nand_debug_flag & NDBG_ECC) - for (i = 0; i < (eccd->eccbytes * steps); i++) - printf("%x ", eccd->ecccalculated[i]); - - nand_debug(NDBG_ECC,"\n"); - - if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size, - 0)) { - retval = ENXIO; - break; - } - for (i = 0; i < (eccd->eccbytes * steps); i++) - eccd->eccread[i] = ((uint8_t *)oob)[eccpos[i]]; - - nand_debug(NDBG_ECC,"%s: ECC read:", __func__); - if (nand_debug_flag & NDBG_ECC) - for (i = 0; i < (eccd->eccbytes * steps); i++) - printf("%x ", eccd->eccread[i]); - nand_debug(NDBG_ECC,"\n"); - - retval = NAND_CORRECT_ECC(chip->dev, ptr, eccd->eccread, - eccd->ecccalculated); - - nand_debug(NDBG_ECC, "NAND_CORRECT_ECC() returned %d", - retval); - - if (retval == 0) - pg_stat->ecc_stat.ecc_succeded++; - else if (retval > 0) { - pg_stat->ecc_stat.ecc_corrected += retval; - retval = ECC_CORRECTABLE; - } else { - pg_stat->ecc_stat.ecc_failed++; - break; - } - } - - pg_stat->page_read++; - page++; - ptr += cg->page_size; - } - - NANDBUS_UNLOCK(nandbus); - - if (oob) - free(oob, M_NAND); - - return (retval); -} - -int -nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf, - uint32_t len) -{ - struct chip_geom *cg; - device_t nandbus; - uint8_t *ptr; - uint32_t page, num, end, begin = 0, begin_off; - int retval = 0; - - cg = &chip->chip_geom; - page = offset_to_page(cg, offset); - begin_off = offset - page * cg->page_size; - if (begin_off) { - begin = cg->page_size - begin_off; - len -= begin; - } - num = len / cg->page_size; - end = len % cg->page_size; - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - ptr = (uint8_t *)buf; - if (begin_off) { - if (NAND_READ_PAGE(chip->dev, page, ptr, begin, begin_off)) { - NANDBUS_UNLOCK(nandbus); - return (ENXIO); - } - - page++; - ptr += begin; - } - - while (num--) { - if (NAND_READ_PAGE(chip->dev, page, ptr, cg->page_size, 0)) { - NANDBUS_UNLOCK(nandbus); - return (ENXIO); - } - - page++; - ptr += cg->page_size; - } - - if (end) - if (NAND_READ_PAGE(chip->dev, page, ptr, end, 0)) { - NANDBUS_UNLOCK(nandbus); - return (ENXIO); - } - - NANDBUS_UNLOCK(nandbus); - - return (retval); -} - - -int -nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf, - uint32_t len) -{ - struct chip_geom *cg; - struct page_stat *pg_stat; - struct nand_ecc_data *eccd; - device_t nandbus; - uint32_t page, num; - uint8_t *oob = NULL; - uint16_t *eccpos = NULL; - int steps = 0, i, needwrite, err = 0; - - nand_debug(NDBG_NAND,"%p prog page %x[%x]", chip, offset, len); - - eccd = &chip->nand->ecc; - cg = &chip->chip_geom; - page = offset_to_page(cg, offset); - num = len / cg->page_size; - - if (eccd->eccmode != NAND_ECC_NONE) { - steps = cg->page_size / eccd->eccsize; - oob = malloc(cg->oob_size, M_NAND, M_WAITOK); - eccpos = default_software_ecc_positions(chip); - } - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - while (num--) { - if (NAND_PROGRAM_PAGE(chip->dev, page, buf, cg->page_size, 0)) { - err = ENXIO; - break; - } - - if (eccd->eccmode != NAND_ECC_NONE) { - if (NAND_GET_ECC(chip->dev, buf, &eccd->ecccalculated, - &needwrite)) { - err = ENXIO; - break; - } - nand_debug(NDBG_ECC,"ECC calculated:"); - if (nand_debug_flag & NDBG_ECC) - for (i = 0; i < (eccd->eccbytes * steps); i++) - printf("%x ", eccd->ecccalculated[i]); - - nand_debug(NDBG_ECC,"\n"); - - if (needwrite) { - if (NAND_READ_OOB(chip->dev, page, oob, cg->oob_size, - 0)) { - err = ENXIO; - break; - } - - for (i = 0; i < (eccd->eccbytes * steps); i++) - oob[eccpos[i]] = eccd->ecccalculated[i]; - - if (NAND_PROGRAM_OOB(chip->dev, page, oob, - cg->oob_size, 0)) { - err = ENXIO; - break; - } - } - } - - pg_stat = &(chip->pg_stat[page]); - pg_stat->page_written++; - - page++; - buf += cg->page_size; - } - - NANDBUS_UNLOCK(nandbus); - - if (oob) - free(oob, M_NAND); - - return (err); -} - -int -nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf, - uint32_t len) -{ - struct chip_geom *cg; - device_t nandbus; - uint8_t *ptr; - uint32_t page, num, end, begin = 0, begin_off; - int retval = 0; - - cg = &chip->chip_geom; - page = offset_to_page(cg, offset); - begin_off = offset - page * cg->page_size; - if (begin_off) { - begin = cg->page_size - begin_off; - len -= begin; - } - num = len / cg->page_size; - end = len % cg->page_size; - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - ptr = (uint8_t *)buf; - if (begin_off) { - if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, begin, begin_off)) { - NANDBUS_UNLOCK(nandbus); - return (ENXIO); - } - - page++; - ptr += begin; - } - - while (num--) { - if (NAND_PROGRAM_PAGE(chip->dev, page, ptr, cg->page_size, 0)) { - NANDBUS_UNLOCK(nandbus); - return (ENXIO); - } - - page++; - ptr += cg->page_size; - } - - if (end) - retval = NAND_PROGRAM_PAGE(chip->dev, page, ptr, end, 0); - - NANDBUS_UNLOCK(nandbus); - - return (retval); -} - -int -nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf, - uint32_t len) -{ - device_t nandbus; - int retval = 0; - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - retval = NAND_READ_OOB(chip->dev, page, buf, len, 0); - - NANDBUS_UNLOCK(nandbus); - - return (retval); -} - - -int -nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf, - uint32_t len) -{ - device_t nandbus; - int retval = 0; - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - retval = NAND_PROGRAM_OOB(chip->dev, page, buf, len, 0); - - NANDBUS_UNLOCK(nandbus); - - return (retval); -} - -int -nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len) -{ - device_t nandbus; - struct chip_geom *cg; - uint32_t block, num_blocks; - int err = 0; - - cg = &chip->chip_geom; - if ((offset % cg->block_size) || (len % cg->block_size)) - return (EINVAL); - - block = offset / cg->block_size; - num_blocks = len / cg->block_size; - nand_debug(NDBG_NAND,"%p erase blocks %d[%d]", chip, block, num_blocks); - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - while (num_blocks--) { - if (!nand_check_bad_block(chip, block)) { - if (NAND_ERASE_BLOCK(chip->dev, block)) { - nand_debug(NDBG_NAND,"%p erase blocks %d error", - chip, block); - nand_mark_bad_block(chip, block); - err = ENXIO; - } - } else - err = ENXIO; - - block++; - } - - NANDBUS_UNLOCK(nandbus); - - if (err) - nand_update_bbt(chip); - - return (err); -} - -MODULE_VERSION(nand, 1); Property changes on: head/sys/dev/nand/nand.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand_id.c =================================================================== --- head/sys/dev/nand/nand_id.c (revision 349351) +++ head/sys/dev/nand/nand_id.c (nonexistent) @@ -1,70 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -#include - -struct nand_params nand_ids[] = { - { { NAND_MAN_SAMSUNG, 0x75 }, "Samsung K9F5608U0B NAND 32MiB 8-bit", - 0x20, 0x200, 0x10, 0x20, 0 }, - { { NAND_MAN_SAMSUNG, 0xf1 }, "Samsung K9F1G08U0A NAND 128MiB 3,3V 8-bit", - 0x80, 0x800, 0x40, 0x40, 0 }, - { { NAND_MAN_SAMSUNG, 0xda }, "Samsung K9F2G08U0A NAND 256MiB 3,3V 8-bit", - 0x100, 0x800, 0x40, 0x40, 0 }, - { { NAND_MAN_SAMSUNG, 0xdc }, "Samsung NAND 512MiB 3,3V 8-bit", - 0x200, 0x800, 0x40, 0x40, 0 }, - { { NAND_MAN_SAMSUNG, 0xd3 }, "Samsung NAND 1GiB 3,3V 8-bit", - 0x400, 0x800, 0x40, 0x40, 0 }, - { { NAND_MAN_HYNIX, 0x76 }, "Hynix NAND 64MiB 3,3V 8-bit", - 0x40, 0x200, 0x10, 0x20, 0 }, - { { NAND_MAN_HYNIX, 0xdc }, "Hynix NAND 512MiB 3,3V 8-bit", - 0x200, 0x800, 0x40, 0x40, 0 }, - { { NAND_MAN_HYNIX, 0x79 }, "Hynix NAND 128MB 3,3V 8-bit", - 0x80, 0x200, 0x10, 0x20, 0 }, - { { NAND_MAN_STMICRO, 0xf1 }, "STMicro 128MB 3,3V 8-bit", - 0x80, 2048, 64, 0x40, 0 }, - { { NAND_MAN_MICRON, 0xcc }, "Micron NAND 512MiB 3,3V 16-bit", - 0x200, 2048, 64, 0x40, 0 }, -}; - -struct nand_params *nand_get_params(struct nand_id *id) -{ - int i; - - for (i = 0; i < nitems(nand_ids); i++) - if (nand_ids[i].id.man_id == id->man_id && - nand_ids[i].id.dev_id == id->dev_id) - return (&nand_ids[i]); - - return (NULL); -} Property changes on: head/sys/dev/nand/nand_id.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand.h =================================================================== --- head/sys/dev/nand/nand.h (revision 349351) +++ head/sys/dev/nand/nand.h (nonexistent) @@ -1,415 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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_NAND_H_ -#define _DEV_NAND_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -MALLOC_DECLARE(M_NAND); - -/* Read commands */ -#define NAND_CMD_READ 0x00 -#define NAND_CMD_CHNG_READ_COL 0x05 -#define NAND_CMD_READ_END 0x30 -#define NAND_CMD_READ_CACHE 0x31 -#define NAND_CMD_READ_CPBK 0x35 -#define NAND_CMD_READ_CACHE_END 0x3F -#define NAND_CMD_CHNG_READ_COL_END 0xE0 - -/* Erase commands */ -#define NAND_CMD_ERASE 0x60 -#define NAND_CMD_ERASE_END 0xD0 -#define NAND_CMD_ERASE_INTLV 0xD1 - -/* Program commands */ -#define NAND_CMD_PROG 0x80 -#define NAND_CMD_CHNG_WRITE_COL 0x85 -#define NAND_CMD_PROG_END 0x10 -#define NAND_CMD_PROG_INTLV 0x11 -#define NAND_CMD_PROG_CACHE 0x15 - -/* Misc commands */ -#define NAND_CMD_STATUS 0x70 -#define NAND_CMD_STATUS_ENH 0x78 -#define NAND_CMD_READ_ID 0x90 -#define NAND_CMD_READ_PARAMETER 0xec -#define NAND_CMD_READ_UNIQUE_ID 0xed -#define NAND_CMD_GET_FEATURE 0xee -#define NAND_CMD_SET_FEATURE 0xef - -/* Reset commands */ -#define NAND_CMD_SYNCH_RESET 0xfc -#define NAND_CMD_RESET 0xff - -/* Small page flash commands */ -#define NAND_CMD_SMALLA 0x00 -#define NAND_CMD_SMALLB 0x01 -#define NAND_CMD_SMALLOOB 0x50 - -#define NAND_STATUS_FAIL 0x1 -#define NAND_STATUS_FAILC 0x2 -#define NAND_STATUS_ARDY 0x20 -#define NAND_STATUS_RDY 0x40 -#define NAND_STATUS_WP 0x80 - -#define NAND_LP_OOB_COLUMN_START 0x800 -#define NAND_LP_OOBSZ 0x40 -#define NAND_SP_OOB_COLUMN_START 0x200 -#define NAND_SP_OOBSZ 0x10 - -#define PAGE_PARAM_LENGTH 0x100 -#define PAGE_PARAMETER_DEF 0x0 -#define PAGE_PARAMETER_RED_1 0x100 -#define PAGE_PARAMETER_RED_2 0x200 - -#define ONFI_SIG_ADDR 0x20 - -#define NAND_MAX_CHIPS 0x4 -#define NAND_MAX_OOBSZ 512 -#define NAND_MAX_PAGESZ 16384 - -#define NAND_SMALL_PAGE_SIZE 0x200 - -#define NAND_16_BIT 0x00000001 - -#define NAND_ECC_NONE 0x0 -#define NAND_ECC_SOFT 0x1 -#define NAND_ECC_FULLHW 0x2 -#define NAND_ECC_PARTHW 0x4 -#define NAND_ECC_MODE_MASK 0x7 - -#define ECC_OK 0 -#define ECC_CORRECTABLE 1 -#define ECC_ERROR_ECC (-1) -#define ECC_UNCORRECTABLE (-2) - -#define NAND_MAN_SAMSUNG 0xec -#define NAND_MAN_HYNIX 0xad -#define NAND_MAN_STMICRO 0x20 -#define NAND_MAN_MICRON 0x2c - -struct nand_id { - uint8_t man_id; - uint8_t dev_id; -}; - -struct nand_params { - struct nand_id id; - char *name; - uint32_t chip_size; - uint32_t page_size; - uint32_t oob_size; - uint32_t pages_per_block; - uint32_t flags; -}; - -/* nand debug levels */ -#define NDBG_NAND 0x01 -#define NDBG_CDEV 0x02 -#define NDBG_GEN 0x04 -#define NDBG_GEOM 0x08 -#define NDBG_BUS 0x10 -#define NDBG_SIM 0x20 -#define NDBG_CTRL 0x40 -#define NDBG_DRV 0x80 -#define NDBG_ECC 0x100 - -/* nand_debug_function */ -void nand_debug(int level, const char *fmt, ...); -extern int nand_debug_flag; - -/* ONFI features bit*/ -#define ONFI_FEAT_16BIT 0x01 -#define ONFI_FEAT_MULT_LUN 0x02 -#define ONFI_FEAT_INTLV_OPS 0x04 -#define ONFI_FEAT_CPBK_RESTRICT 0x08 -#define ONFI_FEAT_SRC_SYNCH 0x10 - -/* ONFI optional commands bits */ -#define ONFI_OPTCOM_PROG_CACHE 0x01 -#define ONFI_OPTCOM_READ_CACHE 0x02 -#define ONFI_OPTCOM_GETSET_FEAT 0x04 -#define ONFI_OPTCOM_STATUS_ENH 0x08 -#define ONFI_OPTCOM_COPYBACK 0x10 -#define ONFI_OPTCOM_UNIQUE_ID 0x20 - - -/* Layout of parameter page is defined in ONFI */ -struct onfi_params { - char signature[4]; - uint16_t rev; - uint16_t features; - uint16_t optional_commands; - uint8_t primary_advanced_command; - uint8_t res1; - uint16_t extended_parameter_page_length; - uint8_t parameter_page_count; - uint8_t res2[17]; - char manufacturer_name[12]; - char device_model[20]; - uint8_t manufacturer_id; - uint8_t manufacture_date_yy; - uint8_t manufacture_date_ww; - uint8_t res3[13]; - uint32_t bytes_per_page; - uint16_t spare_bytes_per_page; - uint32_t bytes_per_partial_page; - uint16_t spare_bytes_per_partial_page; - uint32_t pages_per_block; - uint32_t blocks_per_lun; - uint8_t luns; - uint8_t address_cycles; - uint8_t bits_per_cell; - uint16_t max_bad_block_per_lun; - uint16_t block_endurance; - uint8_t guaranteed_valid_blocks; - uint16_t valid_block_endurance; - uint8_t programs_per_page; - uint8_t partial_prog_attr; - uint8_t bits_of_ecc; - uint8_t interleaved_addr_bits; - uint8_t interleaved_oper_attr; - uint8_t eznand_support; - uint8_t res4[12]; - uint8_t pin_capacitance; - uint16_t asynch_timing_mode_support; - uint16_t asynch_prog_cache_timing_mode_support; - uint16_t t_prog; /* us, max page program time */ - uint16_t t_bers; /* us, max block erase time */ - uint16_t t_r; /* us, max page read time */ - uint16_t t_ccs; /* ns, min change column setup time */ - uint16_t source_synch_timing_mode_support; - uint8_t source_synch_feat; - uint16_t clk_input_capacitance; - uint16_t io_capacitance; - uint16_t input_capacitance; - uint8_t input_capacitance_max; - uint8_t driver_strength_support; - uint16_t t_r_interleaved; - uint16_t t_adl; - uint16_t t_r_eznand; - uint8_t nv_ddr2_features; - uint8_t nv_ddr2_warmup_cycles; - uint8_t res5[4]; - uint16_t vendor_rev; - uint8_t vendor_spec[88]; - uint16_t crc; -}__attribute__((packed)); -CTASSERT(sizeof(struct onfi_params) == 256); - -struct onfi_chip_params { - uint32_t blocks_per_lun; - uint32_t pages_per_block; - uint32_t bytes_per_page; - uint32_t spare_bytes_per_page; - uint16_t t_bers; - uint16_t t_prog; - uint16_t t_r; - uint16_t t_ccs; - uint16_t features; - uint8_t address_cycles; - uint8_t luns; -}; - -struct nand_ecc_data { - int eccsize; /* Number of data bytes per ECC step */ - int eccmode; - int eccbytes; /* Number of ECC bytes per step */ - - uint16_t *eccpositions; /* Positions of ecc bytes */ - uint8_t ecccalculated[NAND_MAX_OOBSZ]; - uint8_t eccread[NAND_MAX_OOBSZ]; -}; - -struct ecc_stat { - uint32_t ecc_succeded; - uint32_t ecc_corrected; - uint32_t ecc_failed; -}; - -struct page_stat { - struct ecc_stat ecc_stat; - uint32_t page_read; - uint32_t page_raw_read; - uint32_t page_written; - uint32_t page_raw_written; -}; - -struct block_stat { - uint32_t block_erased; -}; - -struct chip_geom { - uint32_t chip_size; - uint32_t block_size; - uint32_t page_size; - uint32_t oob_size; - - uint32_t luns; - uint32_t blks_per_lun; - uint32_t blks_per_chip; - uint32_t pgs_per_blk; - - uint32_t pg_mask; - uint32_t blk_mask; - uint32_t lun_mask; - uint8_t blk_shift; - uint8_t lun_shift; -}; - -struct nand_chip { - device_t dev; - struct nand_id id; - struct chip_geom chip_geom; - - uint16_t t_prog; /* us, max page program time */ - uint16_t t_bers; /* us, max block erase time */ - uint16_t t_r; /* us, max page read time */ - uint16_t t_ccs; /* ns, min change column setup time */ - uint8_t num; - uint8_t flags; - - struct page_stat *pg_stat; - struct block_stat *blk_stat; - struct nand_softc *nand; - struct nand_bbt *bbt; - struct nand_ops *ops; - struct cdev *cdev; - - struct disk *ndisk; - struct disk *rdisk; - struct bio_queue_head bioq; /* bio queue */ - struct mtx qlock; /* bioq lock */ - struct taskqueue *tq; /* private task queue for i/o request */ - struct task iotask; /* i/o processing */ - -}; - -struct nand_softc { - uint8_t flags; - - char *chip_cdev_name; - struct nand_ecc_data ecc; -}; - -/* NAND ops */ -int nand_erase_blocks(struct nand_chip *chip, off_t offset, size_t len); -int nand_prog_pages(struct nand_chip *chip, uint32_t offset, uint8_t *buf, - uint32_t len); -int nand_read_pages(struct nand_chip *chip, uint32_t offset, void *buf, - uint32_t len); -int nand_read_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf, - uint32_t len); -int nand_prog_pages_raw(struct nand_chip *chip, uint32_t offset, void *buf, - uint32_t len); -int nand_read_oob(struct nand_chip *chip, uint32_t page, void *buf, - uint32_t len); -int nand_prog_oob(struct nand_chip *chip, uint32_t page, void *buf, - uint32_t len); - -int nand_select_cs(device_t dev, uint8_t cs); - -int nand_read_parameter(struct nand_softc *nand, struct onfi_params *param); -int nand_synch_reset(struct nand_softc *nand); -int nand_chng_read_col(device_t dev, uint32_t col, void *buf, size_t len); -int nand_chng_write_col(device_t dev, uint32_t col, void *buf, size_t len); -int nand_get_feature(device_t dev, uint8_t feat, void* buf); -int nand_set_feature(device_t dev, uint8_t feat, void* buf); - - -int nand_erase_block_intlv(device_t dev, uint32_t block); -int nand_copyback_read(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len); -int nand_copyback_prog(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len); -int nand_copyback_prog_intlv(device_t dev, uint32_t page); -int nand_prog_cache(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len, uint8_t end); -int nand_prog_intlv(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len); -int nand_read_cache(device_t dev, uint32_t page, uint32_t col, - void *buf, size_t len, uint8_t end); - -int nand_write_ecc(struct nand_softc *nand, uint32_t page, uint8_t *data); -int nand_read_ecc(struct nand_softc *nand, uint32_t page, uint8_t *data); - -int nand_softecc_get(device_t dev, uint8_t *buf, int pagesize, uint8_t *ecc); -int nand_softecc_correct(device_t dev, uint8_t *buf, int pagesize, - uint8_t *readecc, uint8_t *calcecc); - -/* Chip initialization */ -void nand_init(struct nand_softc *nand, device_t dev, int ecc_mode, - int ecc_bytes, int ecc_size, uint16_t* eccposition, char* cdev_name); -void nand_detach(struct nand_softc *nand); -struct nand_params *nand_get_params(struct nand_id *id); - -void nand_onfi_set_params(struct nand_chip *chip, struct onfi_chip_params *params); -void nand_set_params(struct nand_chip *chip, struct nand_params *params); -int nand_init_stat(struct nand_chip *chip); -void nand_destroy_stat(struct nand_chip *chip); - -/* BBT */ -int nand_init_bbt(struct nand_chip *chip); -void nand_destroy_bbt(struct nand_chip *chip); -int nand_update_bbt(struct nand_chip *chip); -int nand_mark_bad_block(struct nand_chip* chip, uint32_t block_num); -int nand_check_bad_block(struct nand_chip* chip, uint32_t block_num); - -/* cdev creation/removal */ -int nand_make_dev(struct nand_chip* chip); -void nand_destroy_dev(struct nand_chip *chip); - -int create_geom_disk(struct nand_chip* chip); -int create_geom_raw_disk(struct nand_chip *chip); -void destroy_geom_disk(struct nand_chip *chip); -void destroy_geom_raw_disk(struct nand_chip *chip); - -int init_chip_geom(struct chip_geom* cg, uint32_t luns, uint32_t blks_per_lun, - uint32_t pgs_per_blk, uint32_t pg_size, uint32_t oob_size); -int nand_row_to_blkpg(struct chip_geom *cg, uint32_t row, uint32_t *lun, - uint32_t *blk, uint32_t *pg); -int page_to_row(struct chip_geom *cg, uint32_t page, uint32_t *row); -int nand_check_page_boundary(struct nand_chip *chip, uint32_t page); -void nand_get_chip_param(struct nand_chip *chip, struct chip_param_io *param); - -#endif /* _DEV_NAND_H_ */ Property changes on: head/sys/dev/nand/nand.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_chip.h =================================================================== --- head/sys/dev/nand/nandsim_chip.h (revision 349351) +++ head/sys/dev/nand/nandsim_chip.h (nonexistent) @@ -1,161 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 _NANDSIM_CHIP_H -#define _NANDSIM_CHIP_H - -#include -#include -#include -#include -#include - -MALLOC_DECLARE(M_NANDSIM); - -#define MAX_CS_NUM 4 -struct nandsim_chip; - -typedef void nandsim_evh_t(struct nandsim_chip *chip, uint32_t ev, void *data); - -enum addr_type { - ADDR_NONE, - ADDR_ID, - ADDR_ROW, - ADDR_ROWCOL -}; - -struct nandsim_softc { - struct nand_softc nand_dev; - device_t dev; - - struct nandsim_chip *chips[MAX_CS_NUM]; - struct nandsim_chip *active_chip; - - uint8_t address_cycle; - enum addr_type address_type; - int log_idx; - char *log_buff; - struct alq *alq; -}; - -struct nandsim_ev { - STAILQ_ENTRY(nandsim_ev) links; - struct nandsim_chip *chip; - uint8_t type; - void *data; -}; - -struct nandsim_data { - uint8_t *data_ptr; - uint32_t index; - uint32_t size; -}; - -struct nandsim_block_state { - int32_t wear_lev; - uint8_t is_bad; -}; - -#define NANDSIM_CHIP_ACTIVE 0x1 -#define NANDSIM_CHIP_FROZEN 0x2 -#define NANDSIM_CHIP_GET_STATUS 0x4 - -struct nandsim_chip { - struct nandsim_softc *sc; - struct thread *nandsim_td; - - STAILQ_HEAD(, nandsim_ev) nandsim_events; - nandsim_evh_t *ev_handler; - struct mtx ns_lock; - struct callout ns_callout; - - struct chip_geom cg; - struct nand_id id; - struct onfi_params params; - struct nandsim_data data; - struct nandsim_block_state *blk_state; - - struct chip_swap *swap; - - uint32_t error_ratio; - uint32_t wear_level; - uint32_t sm_state; - uint32_t sm_addr_cycle; - - uint32_t erase_delay; - uint32_t prog_delay; - uint32_t read_delay; - struct timeval delay_tv; - - uint8_t flags; - uint8_t chip_status; - uint8_t ctrl_num; - uint8_t chip_num; -}; - -struct sim_ctrl_conf { - uint8_t num; - uint8_t num_cs; - uint8_t ecc; - uint8_t running; - uint8_t created; - device_t sim_ctrl_dev; - struct sim_chip *chips[MAX_CTRL_CS]; - uint16_t ecc_layout[MAX_ECC_BYTES]; - char filename[FILENAME_SIZE]; -}; - -#define NANDSIM_STATE_IDLE 0x0 -#define NANDSIM_STATE_WAIT_ADDR_BYTE 0x1 -#define NANDSIM_STATE_WAIT_CMD 0x2 -#define NANDSIM_STATE_TIMEOUT 0x3 -#define NANDSIM_STATE_WAIT_ADDR_ROW 0x4 -#define NANDSIM_STATE_WAIT_ADDR_COL 0x5 - -#define NANDSIM_EV_START 0x1 -#define NANDSIM_EV_CMD 0x2 -#define NANDSIM_EV_ADDR 0x3 -#define NANDSIM_EV_TIMEOUT 0x4 -#define NANDSIM_EV_EXIT 0xff - -struct nandsim_chip *nandsim_chip_init(struct nandsim_softc *, - uint8_t, struct sim_chip *); -void nandsim_chip_destroy(struct nandsim_chip *); -void nandsim_chip_freeze(struct nandsim_chip *); -void nandsim_chip_timeout(struct nandsim_chip *); -int nandsim_chip_check_bad_block(struct nandsim_chip *, int); - -uint8_t nandchip_get_status(struct nandsim_chip *); - -void destroy_event(struct nandsim_ev *); -int send_event(struct nandsim_ev *); -struct nandsim_ev *create_event(struct nandsim_chip *, uint8_t, uint8_t); - -#endif /* _NANDSIM_CHIP_H */ Property changes on: head/sys/dev/nand/nandsim_chip.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nandsim_ctrl.c =================================================================== --- head/sys/dev/nand/nandsim_ctrl.c (revision 349351) +++ head/sys/dev/nand/nandsim_ctrl.c (nonexistent) @@ -1,398 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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. - */ - -/* Simulated NAND controller driver */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "nfc_if.h" - -#define ADDRESS_SIZE 5 - -extern struct sim_ctrl_conf ctrls[MAX_SIM_DEV]; - -static void byte_corrupt(struct nandsim_chip *, uint8_t *); - -static int nandsim_attach(device_t); -static int nandsim_detach(device_t); -static int nandsim_probe(device_t); - -static uint8_t nandsim_read_byte(device_t); -static uint16_t nandsim_read_word(device_t); -static int nandsim_select_cs(device_t, uint8_t); -static void nandsim_write_byte(device_t, uint8_t); -static void nandsim_write_word(device_t, uint16_t); -static void nandsim_read_buf(device_t, void *, uint32_t); -static void nandsim_write_buf(device_t, void *, uint32_t); -static int nandsim_send_command(device_t, uint8_t); -static int nandsim_send_address(device_t, uint8_t); - -static device_method_t nandsim_methods[] = { - DEVMETHOD(device_probe, nandsim_probe), - DEVMETHOD(device_attach, nandsim_attach), - DEVMETHOD(device_detach, nandsim_detach), - - DEVMETHOD(nfc_select_cs, nandsim_select_cs), - DEVMETHOD(nfc_send_command, nandsim_send_command), - DEVMETHOD(nfc_send_address, nandsim_send_address), - DEVMETHOD(nfc_read_byte, nandsim_read_byte), - DEVMETHOD(nfc_read_word, nandsim_read_word), - DEVMETHOD(nfc_write_byte, nandsim_write_byte), - DEVMETHOD(nfc_read_buf, nandsim_read_buf), - DEVMETHOD(nfc_write_buf, nandsim_write_buf), - - { 0, 0 }, -}; - -static driver_t nandsim_driver = { - "nandsim", - nandsim_methods, - sizeof(struct nandsim_softc), -}; - -static devclass_t nandsim_devclass; -DRIVER_MODULE(nandsim, nexus, nandsim_driver, nandsim_devclass, 0, 0); -DRIVER_MODULE(nandbus, nandsim, nandbus_driver, nandbus_devclass, 0, 0); - -static int -nandsim_probe(device_t dev) -{ - - device_set_desc(dev, "NAND controller simulator"); - return (BUS_PROBE_DEFAULT); -} - -static int -nandsim_attach(device_t dev) -{ - struct nandsim_softc *sc; - struct sim_ctrl_conf *params; - struct sim_chip *chip; - uint16_t *eccpos; - int i, err; - - sc = device_get_softc(dev); - params = &ctrls[device_get_unit(dev)]; - - if (strlen(params->filename) == 0) - snprintf(params->filename, FILENAME_SIZE, "ctrl%d.log", - params->num); - - nandsim_log_init(sc, params->filename); - for (i = 0; i < params->num_cs; i++) { - chip = params->chips[i]; - if (chip && chip->device_id != 0) { - sc->chips[i] = nandsim_chip_init(sc, i, chip); - if (chip->features & ONFI_FEAT_16BIT) - sc->nand_dev.flags |= NAND_16_BIT; - } - } - - if (params->ecc_layout[0] != 0xffff) - eccpos = params->ecc_layout; - else - eccpos = NULL; - - nand_init(&sc->nand_dev, dev, params->ecc, 0, 0, eccpos, "nandsim"); - - err = nandbus_create(dev); - - return (err); -} - -static int -nandsim_detach(device_t dev) -{ - struct nandsim_softc *sc; - struct sim_ctrl_conf *params; - int i; - - sc = device_get_softc(dev); - params = &ctrls[device_get_unit(dev)]; - - for (i = 0; i < params->num_cs; i++) - if (sc->chips[i] != NULL) - nandsim_chip_destroy(sc->chips[i]); - - nandsim_log_close(sc); - - return (0); -} - -static int -nandsim_select_cs(device_t dev, uint8_t cs) -{ - struct nandsim_softc *sc; - - sc = device_get_softc(dev); - - if (cs >= MAX_CS_NUM) - return (EINVAL); - - sc->active_chip = sc->chips[cs]; - - if (sc->active_chip) - nandsim_log(sc->active_chip, NANDSIM_LOG_EV, - "Select cs %d\n", cs); - - return (0); -} - -static int -nandsim_send_command(device_t dev, uint8_t command) -{ - struct nandsim_softc *sc; - struct nandsim_chip *chip; - struct nandsim_ev *ev; - - sc = device_get_softc(dev); - chip = sc->active_chip; - - if (chip == NULL) - return (0); - - nandsim_log(chip, NANDSIM_LOG_EV, "Send command %x\n", command); - - switch (command) { - case NAND_CMD_READ_ID: - case NAND_CMD_READ_PARAMETER: - sc->address_type = ADDR_ID; - break; - case NAND_CMD_ERASE: - sc->address_type = ADDR_ROW; - break; - case NAND_CMD_READ: - case NAND_CMD_PROG: - sc->address_type = ADDR_ROWCOL; - break; - default: - sc->address_type = ADDR_NONE; - break; - } - - if (command == NAND_CMD_STATUS) - chip->flags |= NANDSIM_CHIP_GET_STATUS; - else { - ev = create_event(chip, NANDSIM_EV_CMD, 1); - *(uint8_t *)ev->data = command; - send_event(ev); - } - - return (0); -} - -static int -nandsim_send_address(device_t dev, uint8_t addr) -{ - struct nandsim_ev *ev; - struct nandsim_softc *sc; - struct nandsim_chip *chip; - - sc = device_get_softc(dev); - chip = sc->active_chip; - - if (chip == NULL) - return (0); - - KASSERT((sc->address_type != ADDR_NONE), ("unexpected address")); - nandsim_log(chip, NANDSIM_LOG_EV, "Send addr %x\n", addr); - - ev = create_event(chip, NANDSIM_EV_ADDR, 1); - - *((uint8_t *)(ev->data)) = addr; - - send_event(ev); - return (0); -} - -static uint8_t -nandsim_read_byte(device_t dev) -{ - struct nandsim_softc *sc; - struct nandsim_chip *chip; - uint8_t ret = 0xff; - - sc = device_get_softc(dev); - chip = sc->active_chip; - - if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) { - if (chip->flags & NANDSIM_CHIP_GET_STATUS) { - nandsim_chip_timeout(chip); - ret = nandchip_get_status(chip); - chip->flags &= ~NANDSIM_CHIP_GET_STATUS; - } else if (chip->data.index < chip->data.size) { - ret = chip->data.data_ptr[chip->data.index++]; - byte_corrupt(chip, &ret); - } - nandsim_log(chip, NANDSIM_LOG_DATA, "read %02x\n", ret); - } - - return (ret); -} - -static uint16_t -nandsim_read_word(device_t dev) -{ - struct nandsim_softc *sc; - struct nandsim_chip *chip; - uint16_t *data_ptr; - uint16_t ret = 0xffff; - uint8_t *byte_ret = (uint8_t *)&ret; - - sc = device_get_softc(dev); - chip = sc->active_chip; - - if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) { - if (chip->data.index < chip->data.size - 1) { - data_ptr = - (uint16_t *)&(chip->data.data_ptr[chip->data.index]); - ret = *data_ptr; - chip->data.index += 2; - byte_corrupt(chip, byte_ret); - byte_corrupt(chip, byte_ret + 1); - } - nandsim_log(chip, NANDSIM_LOG_DATA, "read %04x\n", ret); - } - - return (ret); -} - -static void -nandsim_write_byte(device_t dev, uint8_t byte) -{ - struct nandsim_softc *sc; - struct nandsim_chip *chip; - - sc = device_get_softc(dev); - chip = sc->active_chip; - - if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN) && - (chip->data.index < chip->data.size)) { - byte_corrupt(chip, &byte); - chip->data.data_ptr[chip->data.index] &= byte; - chip->data.index++; - nandsim_log(chip, NANDSIM_LOG_DATA, "write %02x\n", byte); - } -} - -static void -nandsim_write_word(device_t dev, uint16_t word) -{ - struct nandsim_softc *sc; - struct nandsim_chip *chip; - uint16_t *data_ptr; - uint8_t *byte_ptr = (uint8_t *)&word; - - sc = device_get_softc(dev); - chip = sc->active_chip; - - if (chip && !(chip->flags & NANDSIM_CHIP_FROZEN)) { - if ((chip->data.index + 1) < chip->data.size) { - byte_corrupt(chip, byte_ptr); - byte_corrupt(chip, byte_ptr + 1); - data_ptr = - (uint16_t *)&(chip->data.data_ptr[chip->data.index]); - *data_ptr &= word; - chip->data.index += 2; - } - - nandsim_log(chip, NANDSIM_LOG_DATA, "write %04x\n", word); - } -} - -static void -nandsim_read_buf(device_t dev, void *buf, uint32_t len) -{ - struct nandsim_softc *sc; - uint16_t *buf16 = (uint16_t *)buf; - uint8_t *buf8 = (uint8_t *)buf; - int i; - - sc = device_get_softc(dev); - - if (sc->nand_dev.flags & NAND_16_BIT) { - for (i = 0; i < len / 2; i++) - buf16[i] = nandsim_read_word(dev); - } else { - for (i = 0; i < len; i++) - buf8[i] = nandsim_read_byte(dev); - } -} - -static void -nandsim_write_buf(device_t dev, void *buf, uint32_t len) -{ - struct nandsim_softc *sc; - uint16_t *buf16 = (uint16_t *)buf; - uint8_t *buf8 = (uint8_t *)buf; - int i; - - sc = device_get_softc(dev); - - if (sc->nand_dev.flags & NAND_16_BIT) { - for (i = 0; i < len / 2; i++) - nandsim_write_word(dev, buf16[i]); - } else { - for (i = 0; i < len; i++) - nandsim_write_byte(dev, buf8[i]); - } -} - -static void -byte_corrupt(struct nandsim_chip *chip, uint8_t *byte) -{ - uint32_t rand; - uint8_t bit; - - rand = random(); - if ((rand % 1000000) < chip->error_ratio) { - bit = rand % 8; - if (*byte & (1 << bit)) - *byte &= ~(1 << bit); - else - *byte |= (1 << bit); - } -} Property changes on: head/sys/dev/nand/nandsim_ctrl.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nand_cdev.c =================================================================== --- head/sys/dev/nand/nand_cdev.c (revision 349351) +++ head/sys/dev/nand/nand_cdev.c (nonexistent) @@ -1,454 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "nand_if.h" -#include "nandbus_if.h" - -static int nand_page_stat(struct nand_chip *, struct page_stat_io *); -static int nand_block_stat(struct nand_chip *, struct block_stat_io *); - -static d_ioctl_t nand_ioctl; -static d_open_t nand_open; -static d_strategy_t nand_strategy; - -static struct cdevsw nand_cdevsw = { - .d_version = D_VERSION, - .d_name = "nand", - .d_open = nand_open, - .d_read = physread, - .d_write = physwrite, - .d_ioctl = nand_ioctl, - .d_strategy = nand_strategy, -}; - -static int -offset_to_page(struct chip_geom *cg, uint32_t offset) -{ - - return (offset / cg->page_size); -} - -static int -offset_to_page_off(struct chip_geom *cg, uint32_t offset) -{ - - return (offset % cg->page_size); -} - -int -nand_make_dev(struct nand_chip *chip) -{ - struct nandbus_ivar *ivar; - device_t parent, nandbus; - int parent_unit, unit; - char *name; - - ivar = device_get_ivars(chip->dev); - nandbus = device_get_parent(chip->dev); - - if (ivar->chip_cdev_name) { - name = ivar->chip_cdev_name; - - /* - * If we got distinct name for chip device we can enumarete it - * based on contoller number. - */ - parent = device_get_parent(nandbus); - } else { - name = "nand"; - parent = nandbus; - } - - parent_unit = device_get_unit(parent); - unit = parent_unit * 4 + chip->num; - chip->cdev = make_dev(&nand_cdevsw, unit, UID_ROOT, GID_WHEEL, - 0666, "%s%d.%d", name, parent_unit, chip->num); - - if (chip->cdev == NULL) - return (ENXIO); - - if (bootverbose) - device_printf(chip->dev, "Created cdev %s%d.%d for chip " - "[0x%0x, 0x%0x]\n", name, parent_unit, chip->num, - ivar->man_id, ivar->dev_id); - - chip->cdev->si_drv1 = chip; - - return (0); -} - -void -nand_destroy_dev(struct nand_chip *chip) -{ - - if (chip->cdev) - destroy_dev(chip->cdev); -} - -static int -nand_open(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - - return (0); -} - -static int -nand_read(struct nand_chip *chip, uint32_t offset, void *buf, uint32_t len) -{ - struct chip_geom *cg; - device_t nandbus; - int start_page, count, off, err = 0; - uint8_t *ptr, *tmp; - - nand_debug(NDBG_CDEV, "Read from chip%d [%p] at %d\n", chip->num, - chip, offset); - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - cg = &chip->chip_geom; - start_page = offset_to_page(cg, offset); - off = offset_to_page_off(cg, offset); - count = (len > cg->page_size - off) ? cg->page_size - off : len; - - ptr = (uint8_t *)buf; - while (len > 0) { - if (len < cg->page_size) { - tmp = malloc(cg->page_size, M_NAND, M_WAITOK); - if (!tmp) { - err = ENOMEM; - break; - } - err = NAND_READ_PAGE(chip->dev, start_page, - tmp, cg->page_size, 0); - if (err) { - free(tmp, M_NAND); - break; - } - bcopy(tmp + off, ptr, count); - free(tmp, M_NAND); - } else { - err = NAND_READ_PAGE(chip->dev, start_page, - ptr, cg->page_size, 0); - if (err) - break; - } - - len -= count; - start_page++; - ptr += count; - count = (len > cg->page_size) ? cg->page_size : len; - off = 0; - } - - NANDBUS_UNLOCK(nandbus); - return (err); -} - -static int -nand_write(struct nand_chip *chip, uint32_t offset, void* buf, uint32_t len) -{ - struct chip_geom *cg; - device_t nandbus; - int off, start_page, err = 0; - uint8_t *ptr; - - nand_debug(NDBG_CDEV, "Write to chip %d [%p] at %d\n", chip->num, - chip, offset); - - nandbus = device_get_parent(chip->dev); - NANDBUS_LOCK(nandbus); - NANDBUS_SELECT_CS(device_get_parent(chip->dev), chip->num); - - cg = &chip->chip_geom; - start_page = offset_to_page(cg, offset); - off = offset_to_page_off(cg, offset); - - if (off != 0 || (len % cg->page_size) != 0) { - printf("Not aligned write start [0x%08x] size [0x%08x]\n", - off, len); - NANDBUS_UNLOCK(nandbus); - return (EINVAL); - } - - ptr = (uint8_t *)buf; - while (len > 0) { - err = NAND_PROGRAM_PAGE(chip->dev, start_page, ptr, - cg->page_size, 0); - if (err) - break; - - len -= cg->page_size; - start_page++; - ptr += cg->page_size; - } - - NANDBUS_UNLOCK(nandbus); - return (err); -} - -static void -nand_strategy(struct bio *bp) -{ - struct nand_chip *chip; - struct cdev *dev; - int err = 0; - - dev = bp->bio_dev; - chip = dev->si_drv1; - - nand_debug(NDBG_CDEV, "Strategy %s on chip %d [%p]\n", - bp->bio_cmd == BIO_READ ? "READ" : "WRITE", - chip->num, chip); - - if (bp->bio_cmd == BIO_READ) { - err = nand_read(chip, - bp->bio_offset & 0xffffffff, - bp->bio_data, bp->bio_bcount); - } else { - err = nand_write(chip, - bp->bio_offset & 0xffffffff, - bp->bio_data, bp->bio_bcount); - } - - if (err == 0) - bp->bio_resid = 0; - else { - bp->bio_error = EIO; - bp->bio_flags |= BIO_ERROR; - bp->bio_resid = bp->bio_bcount; - } - - biodone(bp); -} - -static int -nand_oob_access(struct nand_chip *chip, uint32_t page, uint32_t offset, - uint32_t len, uint8_t *data, uint8_t write) -{ - struct chip_geom *cg; - uint8_t *buf = NULL; - int ret = 0; - - cg = &chip->chip_geom; - - buf = malloc(cg->oob_size, M_NAND, M_WAITOK); - if (!buf) - return (ENOMEM); - - memset(buf, 0xff, cg->oob_size); - - if (!write) { - ret = nand_read_oob(chip, page, buf, cg->oob_size); - copyout(buf, data, len); - } else { - copyin(data, buf, len); - ret = nand_prog_oob(chip, page, buf, cg->oob_size); - } - - free(buf, M_NAND); - - return (ret); -} - -static int -nand_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, - struct thread *td) -{ - struct nand_chip *chip; - struct chip_geom *cg; - struct nand_oob_rw *oob_rw = NULL; - struct nand_raw_rw *raw_rw = NULL; - device_t nandbus; - size_t bufsize = 0, len = 0; - size_t raw_size; - off_t off; - uint8_t *buf = NULL; - int ret = 0; - uint8_t status; - - chip = (struct nand_chip *)dev->si_drv1; - cg = &chip->chip_geom; - nandbus = device_get_parent(chip->dev); - - if ((cmd == NAND_IO_RAW_READ) || (cmd == NAND_IO_RAW_PROG)) { - raw_rw = (struct nand_raw_rw *)data; - raw_size = cg->pgs_per_blk * (cg->page_size + cg->oob_size); - - /* Check if len is not bigger than chip size */ - if (raw_rw->len > raw_size) - return (EFBIG); - - /* - * Do not ask for too much memory, in case of large transfers - * read/write in 16-pages chunks - */ - bufsize = 16 * (cg->page_size + cg->oob_size); - if (raw_rw->len < bufsize) - bufsize = raw_rw->len; - - buf = malloc(bufsize, M_NAND, M_WAITOK); - len = raw_rw->len; - off = 0; - } - switch(cmd) { - case NAND_IO_ERASE: - ret = nand_erase_blocks(chip, ((off_t *)data)[0], - ((off_t *)data)[1]); - break; - - case NAND_IO_OOB_READ: - oob_rw = (struct nand_oob_rw *)data; - ret = nand_oob_access(chip, oob_rw->page, 0, - oob_rw->len, oob_rw->data, 0); - break; - - case NAND_IO_OOB_PROG: - oob_rw = (struct nand_oob_rw *)data; - ret = nand_oob_access(chip, oob_rw->page, 0, - oob_rw->len, oob_rw->data, 1); - break; - - case NAND_IO_GET_STATUS: - NANDBUS_LOCK(nandbus); - ret = NANDBUS_GET_STATUS(nandbus, &status); - if (ret == 0) - *(uint8_t *)data = status; - NANDBUS_UNLOCK(nandbus); - break; - - case NAND_IO_RAW_PROG: - while (len > 0) { - if (len < bufsize) - bufsize = len; - ret = copyin(raw_rw->data + off, buf, bufsize); - if (ret) - break; - ret = nand_prog_pages_raw(chip, raw_rw->off + off, buf, - bufsize); - if (ret) - break; - len -= bufsize; - off += bufsize; - } - break; - - case NAND_IO_RAW_READ: - while (len > 0) { - if (len < bufsize) - bufsize = len; - - ret = nand_read_pages_raw(chip, raw_rw->off + off, buf, - bufsize); - if (ret) - break; - - ret = copyout(buf, raw_rw->data + off, bufsize); - if (ret) - break; - len -= bufsize; - off += bufsize; - } - break; - - case NAND_IO_PAGE_STAT: - ret = nand_page_stat(chip, (struct page_stat_io *)data); - break; - - case NAND_IO_BLOCK_STAT: - ret = nand_block_stat(chip, (struct block_stat_io *)data); - break; - - case NAND_IO_GET_CHIP_PARAM: - nand_get_chip_param(chip, (struct chip_param_io *)data); - break; - - default: - printf("Unknown nand_ioctl request \n"); - ret = EIO; - } - - if (buf) - free(buf, M_NAND); - - return (ret); -} - -static int -nand_page_stat(struct nand_chip *chip, struct page_stat_io *page_stat) -{ - struct chip_geom *cg; - struct page_stat *stat; - int num_pages; - - cg = &chip->chip_geom; - num_pages = cg->pgs_per_blk * cg->blks_per_lun * cg->luns; - if (page_stat->page_num >= num_pages) - return (EINVAL); - - stat = &chip->pg_stat[page_stat->page_num]; - page_stat->page_read = stat->page_read; - page_stat->page_written = stat->page_written; - page_stat->page_raw_read = stat->page_raw_read; - page_stat->page_raw_written = stat->page_raw_written; - page_stat->ecc_succeded = stat->ecc_stat.ecc_succeded; - page_stat->ecc_corrected = stat->ecc_stat.ecc_corrected; - page_stat->ecc_failed = stat->ecc_stat.ecc_failed; - - return (0); -} - -static int -nand_block_stat(struct nand_chip *chip, struct block_stat_io *block_stat) -{ - struct chip_geom *cg; - uint32_t block_num = block_stat->block_num; - - cg = &chip->chip_geom; - if (block_num >= cg->blks_per_lun * cg->luns) - return (EINVAL); - - block_stat->block_erased = chip->blk_stat[block_num].block_erased; - - return (0); -} Property changes on: head/sys/dev/nand/nand_cdev.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/dev/nand/nfc_fsl.c =================================================================== --- head/sys/dev/nand/nfc_fsl.c (revision 349351) +++ head/sys/dev/nand/nfc_fsl.c (nonexistent) @@ -1,717 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2012 Juniper Networks, Inc. - * Copyright (C) 2009-2012 Semihalf - * 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. - */ -/* - * TODO : - * - * -- test support for small pages - * -- support for reading ONFI parameters - * -- support for cached and interleaving commands - * -- proper setting of AL bits in FMR - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include - -#include -#include - -#include "nfc_fsl.h" - -#include "nfc_if.h" - -#define LBC_READ(regname) lbc_read_reg(dev, (LBC85XX_ ## regname)) -#define LBC_WRITE(regname, val) lbc_write_reg(dev, (LBC85XX_ ## regname), val) - -enum addr_type { - ADDR_NONE, - ADDR_ID, - ADDR_ROW, - ADDR_ROWCOL -}; - -struct fsl_nfc_fcm { - /* Read-only after initialization */ - uint32_t reg_fmr; - - /* To be preserved across "start_command" */ - u_int buf_ofs; - u_int read_ptr; - u_int status:1; - - /* Command state -- cleared by "start_command" */ - uint32_t fcm_startzero; - uint32_t reg_fcr; - uint32_t reg_fir; - uint32_t reg_mdr; - uint32_t reg_fbcr; - uint32_t reg_fbar; - uint32_t reg_fpar; - u_int cmdnr; - u_int opnr; - u_int pg_ofs; - enum addr_type addr_type; - u_int addr_bytes; - u_int row_addr; - u_int column_addr; - u_int data_fir:8; - uint32_t fcm_endzero; -}; - -struct fsl_nand_softc { - struct nand_softc nand_dev; - device_t dev; - struct resource *res; - int rid; /* Resourceid */ - struct lbc_devinfo *dinfo; - struct fsl_nfc_fcm fcm; - uint8_t col_cycles; - uint8_t row_cycles; - uint16_t pgsz; /* Page size */ -}; - -static int fsl_nand_attach(device_t dev); -static int fsl_nand_probe(device_t dev); -static int fsl_nand_detach(device_t dev); - -static int fsl_nfc_select_cs(device_t dev, uint8_t cs); -static int fsl_nfc_read_rnb(device_t dev); -static int fsl_nfc_send_command(device_t dev, uint8_t command); -static int fsl_nfc_send_address(device_t dev, uint8_t address); -static uint8_t fsl_nfc_read_byte(device_t dev); -static int fsl_nfc_start_command(device_t dev); -static void fsl_nfc_read_buf(device_t dev, void *buf, uint32_t len); -static void fsl_nfc_write_buf(device_t dev, void *buf, uint32_t len); - -static device_method_t fsl_nand_methods[] = { - DEVMETHOD(device_probe, fsl_nand_probe), - DEVMETHOD(device_attach, fsl_nand_attach), - DEVMETHOD(device_detach, fsl_nand_detach), - - DEVMETHOD(nfc_select_cs, fsl_nfc_select_cs), - DEVMETHOD(nfc_read_rnb, fsl_nfc_read_rnb), - DEVMETHOD(nfc_start_command, fsl_nfc_start_command), - DEVMETHOD(nfc_send_command, fsl_nfc_send_command), - DEVMETHOD(nfc_send_address, fsl_nfc_send_address), - DEVMETHOD(nfc_read_byte, fsl_nfc_read_byte), - DEVMETHOD(nfc_read_buf, fsl_nfc_read_buf), - DEVMETHOD(nfc_write_buf, fsl_nfc_write_buf), - { 0, 0 }, -}; - -static driver_t fsl_nand_driver = { - "nand", - fsl_nand_methods, - sizeof(struct fsl_nand_softc), -}; - -static devclass_t fsl_nand_devclass; - -DRIVER_MODULE(fsl_nand, lbc, fsl_nand_driver, fsl_nand_devclass, - 0, 0); - -static int fsl_nand_build_address(device_t dev, uint32_t page, uint32_t column); -static int fsl_nand_chip_preprobe(device_t dev, struct nand_id *id); - -#ifdef NAND_DEBUG_TIMING -static device_t fcm_devs[8]; -#endif - -#define CMD_SHIFT(cmd_num) (24 - ((cmd_num) * 8)) -#define OP_SHIFT(op_num) (28 - ((op_num) * 4)) - -#define FSL_LARGE_PAGE_SIZE (2112) -#define FSL_SMALL_PAGE_SIZE (528) - -static void -fsl_nand_init_regs(struct fsl_nand_softc *sc) -{ - uint32_t or_v, br_v; - device_t dev; - - dev = sc->dev; - - sc->fcm.reg_fmr = (15 << FMR_CWTO_SHIFT); - - /* - * Setup 4 row cycles and hope that chip ignores superfluous address - * bytes. - */ - sc->fcm.reg_fmr |= (2 << FMR_AL_SHIFT); - - /* Reprogram BR(x) */ - br_v = lbc_read_reg(dev, LBC85XX_BR(sc->dinfo->di_bank)); - br_v &= 0xffff8000; - br_v |= 1 << 11; /* 8-bit port size */ - br_v |= 0 << 9; /* No ECC checking and generation */ - br_v |= 1 << 5; /* FCM machine */ - br_v |= 1; /* Valid */ - lbc_write_reg(dev, LBC85XX_BR(sc->dinfo->di_bank), br_v); - - /* Reprogram OR(x) */ - or_v = lbc_read_reg(dev, LBC85XX_OR(sc->dinfo->di_bank)); - or_v &= 0xfffffc00; - or_v |= 0x03AE; /* Default POR timing */ - lbc_write_reg(dev, LBC85XX_OR(sc->dinfo->di_bank), or_v); - - if (or_v & OR_FCM_PAGESIZE) { - sc->pgsz = FSL_LARGE_PAGE_SIZE; - sc->col_cycles = 2; - nand_debug(NDBG_DRV, "%s: large page NAND device at #%d", - device_get_nameunit(dev), sc->dinfo->di_bank); - } else { - sc->pgsz = FSL_SMALL_PAGE_SIZE; - sc->col_cycles = 1; - nand_debug(NDBG_DRV, "%s: small page NAND device at #%d", - device_get_nameunit(dev), sc->dinfo->di_bank); - } -} - -static int -fsl_nand_probe(device_t dev) -{ - - if (!ofw_bus_is_compatible(dev, "fsl,elbc-fcm-nand")) - return (ENXIO); - - device_set_desc(dev, "Freescale localbus FCM Controller"); - return (BUS_PROBE_DEFAULT); -} - -static int -fsl_nand_attach(device_t dev) -{ - struct fsl_nand_softc *sc; - struct nand_id id; - struct nand_params *param; - uint32_t num_pages; - - sc = device_get_softc(dev); - sc->dev = dev; - sc->dinfo = device_get_ivars(dev); - - sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid, - RF_ACTIVE); - if (sc->res == NULL) { - device_printf(dev, "could not allocate resources!\n"); - return (ENXIO); - } - - bzero(&sc->fcm, sizeof(sc->fcm)); - - /* Init register and check if HW ECC turned on */ - fsl_nand_init_regs(sc); - - /* Chip is probed, so determine number of row address cycles */ - fsl_nand_chip_preprobe(dev, &id); - param = nand_get_params(&id); - if (param != NULL) { - num_pages = (param->chip_size << 20) / param->page_size; - while(num_pages) { - sc->row_cycles++; - num_pages >>= 8; - } - - sc->fcm.reg_fmr &= ~(FMR_AL); - sc->fcm.reg_fmr |= (sc->row_cycles - 2) << FMR_AL_SHIFT; - } - - nand_init(&sc->nand_dev, dev, NAND_ECC_SOFT, 0, 0, NULL, NULL); - -#ifdef NAND_DEBUG_TIMING - fcm_devs[sc->dinfo->di_bank] = dev; -#endif - - return (nandbus_create(dev)); -} - -static int -fsl_nand_detach(device_t dev) -{ - struct fsl_nand_softc *sc; - - sc = device_get_softc(dev); - - if (sc->res != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res); - - return (0); -} - -static int -fsl_nfc_select_cs(device_t dev, uint8_t cs) -{ - - // device_printf(dev, "%s(cs=%u)\n", __func__, cs); - return ((cs > 0) ? EINVAL : 0); -} - -static int -fsl_nfc_read_rnb(device_t dev) -{ - - // device_printf(dev, "%s()\n", __func__); - return (0); -} - -static int -fsl_nfc_send_command(device_t dev, uint8_t command) -{ - struct fsl_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint8_t fir_op; - - // device_printf(dev, "%s(command=%u)\n", __func__, command); - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - if (command == NAND_CMD_PROG_END) { - fcm->reg_fir |= (FIR_OP_WB << OP_SHIFT(fcm->opnr)); - fcm->opnr++; - } - fcm->reg_fcr |= command << CMD_SHIFT(fcm->cmdnr); - fir_op = (fcm->cmdnr == 0) ? FIR_OP_CW0 : FIR_OP_CM(fcm->cmdnr); - fcm->cmdnr++; - - fcm->reg_fir |= (fir_op << OP_SHIFT(fcm->opnr)); - fcm->opnr++; - - switch (command) { - case NAND_CMD_READ_ID: - fcm->data_fir = FIR_OP_RBW; - fcm->addr_type = ADDR_ID; - break; - case NAND_CMD_SMALLOOB: - fcm->pg_ofs += 256; - /*FALLTHROUGH*/ - case NAND_CMD_SMALLB: - fcm->pg_ofs += 256; - /*FALLTHROUGH*/ - case NAND_CMD_READ: /* NAND_CMD_SMALLA */ - fcm->data_fir = FIR_OP_RBW; - fcm->addr_type = ADDR_ROWCOL; - break; - case NAND_CMD_STATUS: - fcm->data_fir = FIR_OP_RS; - fcm->status = 1; - break; - case NAND_CMD_ERASE: - fcm->addr_type = ADDR_ROW; - break; - case NAND_CMD_PROG: - fcm->addr_type = ADDR_ROWCOL; - break; - } - return (0); -} - -static int -fsl_nfc_send_address(device_t dev, uint8_t addr) -{ - struct fsl_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint32_t addr_bits; - - // device_printf(dev, "%s(address=%u)\n", __func__, addr); - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - KASSERT(fcm->addr_type != ADDR_NONE, - ("controller doesn't expect address cycle")); - - addr_bits = addr; - - if (fcm->addr_type == ADDR_ID) { - fcm->reg_fir |= (FIR_OP_UA << OP_SHIFT(fcm->opnr)); - fcm->opnr++; - - fcm->reg_fbcr = 5; - fcm->reg_fbar = 0; - fcm->reg_fpar = 0; - fcm->reg_mdr = addr_bits; - fcm->buf_ofs = 0; - fcm->read_ptr = 0; - return (0); - } - - if (fcm->addr_type == ADDR_ROW) { - addr_bits <<= fcm->addr_bytes * 8; - fcm->row_addr |= addr_bits; - fcm->addr_bytes++; - if (fcm->addr_bytes < sc->row_cycles) - return (0); - } else { - if (fcm->addr_bytes < sc->col_cycles) { - addr_bits <<= fcm->addr_bytes * 8; - fcm->column_addr |= addr_bits; - } else { - addr_bits <<= (fcm->addr_bytes - sc->col_cycles) * 8; - fcm->row_addr |= addr_bits; - } - fcm->addr_bytes++; - if (fcm->addr_bytes < (sc->row_cycles + sc->col_cycles)) - return (0); - } - - return (fsl_nand_build_address(dev, fcm->row_addr, fcm->column_addr)); -} - -static int -fsl_nand_build_address(device_t dev, uint32_t row, uint32_t column) -{ - struct fsl_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint32_t byte_count = 0; - uint32_t block_address = 0; - uint32_t page_address = 0; - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - fcm->read_ptr = 0; - fcm->buf_ofs = 0; - - if (fcm->addr_type == ADDR_ROWCOL) { - fcm->reg_fir |= (FIR_OP_CA << OP_SHIFT(fcm->opnr)); - fcm->opnr++; - - column += fcm->pg_ofs; - fcm->pg_ofs = 0; - - page_address |= column; - - if (column != 0) { - byte_count = sc->pgsz - column; - fcm->read_ptr = column; - } - } - - fcm->reg_fir |= (FIR_OP_PA << OP_SHIFT(fcm->opnr)); - fcm->opnr++; - - if (sc->pgsz == FSL_LARGE_PAGE_SIZE) { - block_address = row >> 6; - page_address |= ((row << FPAR_LP_PI_SHIFT) & FPAR_LP_PI); - fcm->buf_ofs = (row & 1) * 4096; - } else { - block_address = row >> 5; - page_address |= ((row << FPAR_SP_PI_SHIFT) & FPAR_SP_PI); - fcm->buf_ofs = (row & 7) * 1024; - } - - fcm->reg_fbcr = byte_count; - fcm->reg_fbar = block_address; - fcm->reg_fpar = page_address; - return (0); -} - -static int -fsl_nfc_start_command(device_t dev) -{ - struct fsl_nand_softc *sc; - struct fsl_nfc_fcm *fcm; - uint32_t fmr, ltesr_v; - int error, timeout; - - // device_printf(dev, "%s()\n", __func__); - - sc = device_get_softc(dev); - fcm = &sc->fcm; - - fmr = fcm->reg_fmr | FMR_OP; - - if (fcm->data_fir) - fcm->reg_fir |= (fcm->data_fir << OP_SHIFT(fcm->opnr)); - - LBC_WRITE(FIR, fcm->reg_fir); - LBC_WRITE(FCR, fcm->reg_fcr); - - LBC_WRITE(FMR, fmr); - - LBC_WRITE(FBCR, fcm->reg_fbcr); - LBC_WRITE(FBAR, fcm->reg_fbar); - LBC_WRITE(FPAR, fcm->reg_fpar); - - if (fcm->addr_type == ADDR_ID) - LBC_WRITE(MDR, fcm->reg_mdr); - - nand_debug(NDBG_DRV, "BEFORE:\nFMR=%#x, FIR=%#x, FCR=%#x", fmr, - fcm->reg_fir, fcm->reg_fcr); - nand_debug(NDBG_DRV, "MDR=%#x, FBAR=%#x, FPAR=%#x, FBCR=%#x", - LBC_READ(MDR), fcm->reg_fbar, fcm->reg_fpar, fcm->reg_fbcr); - - LBC_WRITE(LSOR, sc->dinfo->di_bank); - - timeout = (cold) ? FSL_FCM_WAIT_TIMEOUT : ~0; - error = 0; - ltesr_v = LBC_READ(LTESR); - while (!error && (ltesr_v & LTESR_CC) == 0) { - if (cold) { - DELAY(1000); - timeout--; - if (timeout < 0) - error = EWOULDBLOCK; - } else - error = tsleep(device_get_parent(sc->dev), PRIBIO, - "nfcfsl", hz); - ltesr_v = LBC_READ(LTESR); - } - if (error) - nand_debug(NDBG_DRV, "Command complete wait timeout\n"); - - nand_debug(NDBG_DRV, "AFTER:\nLTESR=%#x, LTEDR=%#x, LTEIR=%#x," - " LTEATR=%#x, LTEAR=%#x, LTECCR=%#x", ltesr_v, - LBC_READ(LTEDR), LBC_READ(LTEIR), LBC_READ(LTEATR), - LBC_READ(LTEAR), LBC_READ(LTECCR)); - - bzero(&fcm->fcm_startzero, - __rangeof(struct fsl_nfc_fcm, fcm_startzero, fcm_endzero)); - - if (fcm->status) - sc->fcm.reg_mdr = LBC_READ(MDR); - - /* Even if timeout occurred, we should perform steps below */ - LBC_WRITE(LTESR, ltesr_v); - LBC_WRITE(LTEATR, 0); - - return (error); -} - -static uint8_t -fsl_nfc_read_byte(device_t dev) -{ - struct fsl_nand_softc *sc = device_get_softc(dev); - uint32_t offset; - - // device_printf(dev, "%s()\n", __func__); - - /* - * LBC controller allows us to read status into a MDR instead of FCM - * buffer. If last operation requested before read_byte() was STATUS, - * then return MDR instead of reading a single byte from a buffer. - */ - if (sc->fcm.status) { - sc->fcm.status = 0; - return (sc->fcm.reg_mdr); - } - - KASSERT(sc->fcm.read_ptr < sc->pgsz, - ("Attempt to read beyond buffer %x %x", sc->fcm.read_ptr, - sc->pgsz)); - - offset = sc->fcm.buf_ofs + sc->fcm.read_ptr; - sc->fcm.read_ptr++; - return (bus_read_1(sc->res, offset)); -} - -static void -fsl_nfc_read_buf(device_t dev, void *buf, uint32_t len) -{ - struct fsl_nand_softc *sc = device_get_softc(dev); - uint32_t offset; - int bytesleft = 0; - - // device_printf(dev, "%s(buf=%p, len=%u)\n", __func__, buf, len); - - nand_debug(NDBG_DRV, "REQUEST OF 0x%0x B (BIB=0x%0x, NTR=0x%0x)", - len, sc->pgsz, sc->fcm.read_ptr); - - bytesleft = MIN((unsigned int)len, sc->pgsz - sc->fcm.read_ptr); - - offset = sc->fcm.buf_ofs + sc->fcm.read_ptr; - bus_read_region_1(sc->res, offset, buf, bytesleft); - sc->fcm.read_ptr += bytesleft; -} - -static void -fsl_nfc_write_buf(device_t dev, void *buf, uint32_t len) -{ - struct fsl_nand_softc *sc = device_get_softc(dev); - uint32_t offset; - int bytesleft = 0; - - // device_printf(dev, "%s(buf=%p, len=%u)\n", __func__, buf, len); - - KASSERT(len <= sc->pgsz - sc->fcm.read_ptr, - ("Attempt to write beyond buffer")); - - bytesleft = MIN((unsigned int)len, sc->pgsz - sc->fcm.read_ptr); - - nand_debug(NDBG_DRV, "REQUEST TO WRITE 0x%0x (BIB=0x%0x, NTR=0x%0x)", - bytesleft, sc->pgsz, sc->fcm.read_ptr); - - offset = sc->fcm.buf_ofs + sc->fcm.read_ptr; - bus_write_region_1(sc->res, offset, buf, bytesleft); - sc->fcm.read_ptr += bytesleft; -} - -static int -fsl_nand_chip_preprobe(device_t dev, struct nand_id *id) -{ - - if (fsl_nfc_send_command(dev, NAND_CMD_RESET) != 0) - return (ENXIO); - - if (fsl_nfc_start_command(dev) != 0) - return (ENXIO); - - DELAY(1000); - - if (fsl_nfc_send_command(dev, NAND_CMD_READ_ID)) - return (ENXIO); - - if (fsl_nfc_send_address(dev, 0)) - return (ENXIO); - - if (fsl_nfc_start_command(dev) != 0) - return (ENXIO); - - DELAY(25); - - id->man_id = fsl_nfc_read_byte(dev); - id->dev_id = fsl_nfc_read_byte(dev); - - nand_debug(NDBG_DRV, "manufacturer id: %x chip id: %x", - id->man_id, id->dev_id); - - return (0); -} - -#ifdef NAND_DEBUG_TIMING - -static SYSCTL_NODE(_debug, OID_AUTO, fcm, CTLFLAG_RD, 0, "FCM timing"); - -static u_int csct = 1; /* 22: Chip select to command time (trlx). */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, csct, CTLFLAG_RW, &csct, 1, - "Chip select to command time: determines how far in advance -LCSn is " - "asserted prior to any bus activity during a NAND Flash access handled " - "by the FCM. This helps meet chip-select setup times for slow memories."); - -static u_int cst = 1; /* 23: Command setup time (trlx). */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, cst, CTLFLAG_RW, &cst, 1, - "Command setup time: determines the delay of -LFWE assertion relative to " - "the command, address, or data change when the external memory access " - "is handled by the FCM."); - -static u_int cht = 1; /* 24: Command hold time (trlx). */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, cht, CTLFLAG_RW, &cht, 1, - "Command hold time: determines the -LFWE negation prior to the command, " - "address, or data change when the external memory access is handled by " - "the FCM."); - -static u_int scy = 2; /* 25-27: Cycle length in bus clocks */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, scy, CTLFLAG_RW, &scy, 2, - "Cycle length in bus clocks: see RM"); - -static u_int rst = 1; /* 28: Read setup time (trlx). */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, rst, CTLFLAG_RW, &rst, 1, - "Read setup time: determines the delay of -LFRE assertion relative to " - "sampling of read data when the external memory access is handled by " - "the FCM."); - -static u_int trlx = 1; /* 29: Timing relaxed. */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, trlx, CTLFLAG_RW, &trlx, 1, - "Timing relaxed: modifies the settings of timing parameters for slow " - "memories. See RM"); - -static u_int ehtr = 1; /* 30: Extended hold time on read accesses. */ -SYSCTL_UINT(_debug_fcm, OID_AUTO, ehtr, CTLFLAG_RW, &ehtr, 1, - "Extended hold time on read accesses: indicates with TRLX how many " - "cycles are inserted between a read access from the current bank and " - "the next access."); - -static u_int -fsl_nand_get_timing(void) -{ - u_int timing; - - timing = ((csct & 1) << 9) | ((cst & 1) << 8) | ((cht & 1) << 7) | - ((scy & 7) << 4) | ((rst & 1) << 3) | ((trlx & 1) << 2) | - ((ehtr & 1) << 1); - - printf("nfc_fsl: timing = %u\n", timing); - return (timing); -} - -static int -fsl_sysctl_program(SYSCTL_HANDLER_ARGS) -{ - struct fsl_nand_softc *sc; - int error, i; - device_t dev; - uint32_t or_v; - - error = sysctl_wire_old_buffer(req, sizeof(int)); - if (error == 0) { - i = 0; - error = sysctl_handle_int(oidp, &i, 0, req); - } - if (error != 0 || req->newptr == NULL) - return (error); - - for (i = 0; i < 8; i++) { - dev = fcm_devs[i]; - if (dev == NULL) - continue; - sc = device_get_softc(dev); - - /* Reprogram OR(x) */ - or_v = lbc_read_reg(dev, LBC85XX_OR(sc->dinfo->di_bank)); - or_v &= 0xfffffc00; - or_v |= fsl_nand_get_timing(); - lbc_write_reg(dev, LBC85XX_OR(sc->dinfo->di_bank), or_v); - } - return (0); -} - -SYSCTL_PROC(_debug_fcm, OID_AUTO, program, CTLTYPE_INT | CTLFLAG_RW, NULL, 0, - fsl_sysctl_program, "I", "write to program FCM with current values"); - -#endif /* NAND_DEBUG_TIMING */ Property changes on: head/sys/dev/nand/nfc_fsl.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/sys/dev/nand/nfc_if.m =================================================================== --- head/sys/dev/nand/nfc_if.m (revision 349351) +++ head/sys/dev/nand/nfc_if.m (nonexistent) @@ -1,165 +0,0 @@ -#- -# Copyright (C) 2009-2012 Semihalf -# 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$ - -# NAND controller interface description -# - -#include -#include - -INTERFACE nfc; - -CODE { - static int nfc_default_method(device_t dev) - { - return (0); - } - - static int nfc_softecc_get(device_t dev, void *buf, int pagesize, - void *ecc, int *needwrite) - { - *needwrite = 1; - return (nand_softecc_get(dev, buf, pagesize, ecc)); - } - - static int nfc_softecc_correct(device_t dev, void *buf, int pagesize, - void *readecc, void *calcecc) - { - return (nand_softecc_correct(dev, buf, pagesize, readecc, - calcecc)); - } -}; - -# Send command to a NAND chip -# -# Return values: -# 0: Success -# -METHOD int send_command { - device_t dev; - uint8_t command; -}; - -# Send address to a NAND chip -# -# Return values: -# 0: Success -# -METHOD int send_address { - device_t dev; - uint8_t address; -}; - -# Read byte -# -# Return values: -# byte read -# -METHOD uint8_t read_byte { - device_t dev; -}; - -# Write byte -# -METHOD void write_byte { - device_t dev; - uint8_t byte; -}; - -# Read word -# -# Return values: -# word read -# -METHOD uint16_t read_word { - device_t dev; -}; - -# Write word -# -METHOD void write_word { - device_t dev; - uint16_t word; -}; - -# Read buf -# -METHOD void read_buf { - device_t dev; - void *buf; - uint32_t len; -}; - -# Write buf -# -METHOD void write_buf { - device_t dev; - void *buf; - uint32_t len; -}; - -# Select CS -# -METHOD int select_cs { - device_t dev; - uint8_t cs; -}; - -# Read ready/busy signal -# -METHOD int read_rnb { - device_t dev; -}; - -# Start command -# -# Return values: -# 0: Success -# -METHOD int start_command { - device_t dev; -} DEFAULT nfc_default_method; - -# Generate ECC or get it from H/W -# -METHOD int get_ecc { - device_t dev; - void *buf; - int pagesize; - void *ecc; - int *needwrite; -} DEFAULT nfc_softecc_get; - -# Correct ECC -# -METHOD int correct_ecc { - device_t dev; - void *buf; - int pagesize; - void *readecc; - void *calcecc; -} DEFAULT nfc_softecc_correct; Property changes on: head/sys/dev/nand/nfc_if.m ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_bmap.c =================================================================== --- head/sys/fs/nandfs/nandfs_bmap.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_bmap.c (nonexistent) @@ -1,232 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "nandfs_mount.h" -#include "nandfs.h" -#include "nandfs_subr.h" -#include "bmap.h" - -nandfs_lbn_t -nandfs_get_maxfilesize(struct nandfs_device *fsdev) -{ - - return (get_maxfilesize(fsdev)); -} - -int -nandfs_bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, - nandfs_daddr_t *vblk) -{ - int error = 0; - - if (node->nn_ino == NANDFS_GC_INO && lblk >= 0) - *vblk = lblk; - else - error = bmap_lookup(node, lblk, vblk); - - DPRINTF(TRANSLATE, ("%s: error %d ino %#jx lblocknr %#jx -> %#jx\n", - __func__, error, (uintmax_t)node->nn_ino, (uintmax_t)lblk, - (uintmax_t)*vblk)); - - if (error) - nandfs_error("%s: returned %d", __func__, error); - - return (error); -} - -int -nandfs_bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, - struct buf *bp) -{ - struct nandfs_device *fsdev; - nandfs_daddr_t vblk; - int error; - - fsdev = node->nn_nandfsdev; - - vblk = 0; - if (node->nn_ino != NANDFS_DAT_INO) { - error = nandfs_vblock_alloc(fsdev, &vblk); - if (error) - return (error); - } - - nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED); - nandfs_vblk_set(bp, vblk); - - error = bmap_insert_block(node, lblk, vblk); - if (error) { - nandfs_vblock_free(fsdev, vblk); - return (error); - } - - return (0); -} - -int -nandfs_bmap_dirty_blocks(struct nandfs_node *node, struct buf *bp, int force) -{ - int error; - - error = bmap_dirty_meta(node, bp->b_lblkno, force); - if (error) - nandfs_error("%s: cannot dirty buffer %p\n", - __func__, bp); - - return (error); -} - -static int -nandfs_bmap_update_mapping(struct nandfs_node *node, nandfs_lbn_t lblk, - nandfs_daddr_t blknr) -{ - int error; - - DPRINTF(BMAP, - ("%s: node: %p ino: %#jx lblk: %#jx vblk: %#jx\n", - __func__, node, (uintmax_t)node->nn_ino, (uintmax_t)lblk, - (uintmax_t)blknr)); - - error = bmap_insert_block(node, lblk, blknr); - - return (error); -} - -int -nandfs_bmap_update_block(struct nandfs_node *node, struct buf *bp, - nandfs_lbn_t blknr) -{ - nandfs_lbn_t lblk; - int error; - - lblk = bp->b_lblkno; - nandfs_vblk_set(bp, blknr); - - DPRINTF(BMAP, ("%s: node: %p ino: %#jx bp: %p lblk: %#jx blk: %#jx\n", - __func__, node, (uintmax_t)node->nn_ino, bp, - (uintmax_t)lblk, (uintmax_t)blknr)); - - error = nandfs_bmap_update_mapping(node, lblk, blknr); - if (error) { - nandfs_error("%s: cannot update lblk:%jx to blk:%jx for " - "node:%p, error:%d\n", __func__, (uintmax_t)lblk, - (uintmax_t)blknr, node, error); - return (error); - } - - return (error); -} - -int -nandfs_bmap_update_dat(struct nandfs_node *node, nandfs_daddr_t oldblk, - struct buf *bp) -{ - struct nandfs_device *fsdev; - nandfs_daddr_t vblk = 0; - int error; - - if (node->nn_ino == NANDFS_DAT_INO) - return (0); - - if (nandfs_buf_check(bp, NANDFS_VBLK_ASSIGNED)) { - nandfs_buf_clear(bp, NANDFS_VBLK_ASSIGNED); - return (0); - } - - fsdev = node->nn_nandfsdev; - - /* First alloc new virtual block.... */ - error = nandfs_vblock_alloc(fsdev, &vblk); - if (error) - return (error); - - error = nandfs_bmap_update_block(node, bp, vblk); - if (error) - return (error); - - /* Then we can end up with old one */ - nandfs_vblock_end(fsdev, oldblk); - - DPRINTF(BMAP, - ("%s: ino %#jx block %#jx: update vblk %#jx to %#jx\n", - __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno, - (uintmax_t)oldblk, (uintmax_t)vblk)); - return (error); -} - -int -nandfs_bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t oblk, - nandfs_lbn_t nblk) -{ - nandfs_lbn_t todo; - int error; - - todo = oblk - nblk; - - DPRINTF(BMAP, ("%s: node %p oblk %jx nblk %jx truncate by %jx\n", - __func__, node, oblk, nblk, todo)); - - error = bmap_truncate_mapping(node, oblk, todo); - if (error) - return (error); - - return (error); -} Property changes on: head/sys/fs/nandfs/nandfs_bmap.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs.h =================================================================== --- head/sys/fs/nandfs/nandfs.h (revision 349351) +++ head/sys/fs/nandfs/nandfs.h (nonexistent) @@ -1,312 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs.h,v 1.1 2009/07/18 16:31:42 reinoud - * - * $FreeBSD$ - */ - -#ifndef _FS_NANDFS_NANDFS_H_ -#define _FS_NANDFS_NANDFS_H_ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include "nandfs_fs.h" - -MALLOC_DECLARE(M_NANDFSTEMP); - -/* Debug categories */ -#define NANDFS_DEBUG_VOLUMES 0x000001 -#define NANDFS_DEBUG_BLOCK 0x000004 -#define NANDFS_DEBUG_LOCKING 0x000008 -#define NANDFS_DEBUG_NODE 0x000010 -#define NANDFS_DEBUG_LOOKUP 0x000020 -#define NANDFS_DEBUG_READDIR 0x000040 -#define NANDFS_DEBUG_TRANSLATE 0x000080 -#define NANDFS_DEBUG_STRATEGY 0x000100 -#define NANDFS_DEBUG_READ 0x000200 -#define NANDFS_DEBUG_WRITE 0x000400 -#define NANDFS_DEBUG_IFILE 0x000800 -#define NANDFS_DEBUG_ATTR 0x001000 -#define NANDFS_DEBUG_EXTATTR 0x002000 -#define NANDFS_DEBUG_ALLOC 0x004000 -#define NANDFS_DEBUG_CPFILE 0x008000 -#define NANDFS_DEBUG_DIRHASH 0x010000 -#define NANDFS_DEBUG_NOTIMPL 0x020000 -#define NANDFS_DEBUG_SHEDULE 0x040000 -#define NANDFS_DEBUG_SEG 0x080000 -#define NANDFS_DEBUG_SYNC 0x100000 -#define NANDFS_DEBUG_PARANOIA 0x200000 -#define NANDFS_DEBUG_VNCALL 0x400000 -#define NANDFS_DEBUG_BUF 0x1000000 -#define NANDFS_DEBUG_BMAP 0x2000000 -#define NANDFS_DEBUG_DAT 0x4000000 -#define NANDFS_DEBUG_GENERIC 0x8000000 -#define NANDFS_DEBUG_CLEAN 0x10000000 - -extern int nandfs_verbose; - -#define DPRINTF(name, arg) { \ - if (nandfs_verbose & NANDFS_DEBUG_##name) {\ - printf arg;\ - };\ - } -#define DPRINTFIF(name, cond, arg) { \ - if (nandfs_verbose & NANDFS_DEBUG_##name) { \ - if (cond) printf arg;\ - };\ - } - -#define VFSTONANDFS(mp) ((struct nandfsmount *)((mp)->mnt_data)) -#define VTON(vp) ((struct nandfs_node *)(vp)->v_data) -#define NTOV(xp) ((xp)->nn_vnode) - -int nandfs_init(struct vfsconf *); -int nandfs_uninit(struct vfsconf *); - -extern struct vop_vector nandfs_vnodeops; -extern struct vop_vector nandfs_system_vnodeops; - -struct nandfs_node; - -/* Structure and derivatives */ -struct nandfs_mdt { - uint32_t entries_per_block; - uint32_t entries_per_group; - uint32_t blocks_per_group; - uint32_t groups_per_desc_block; /* desc is super group */ - uint32_t blocks_per_desc_block; /* desc is super group */ -}; - -struct nandfs_segment { - LIST_ENTRY(nandfs_segment) seg_link; - - struct nandfs_device *fsdev; - - TAILQ_HEAD(, buf) segsum; - TAILQ_HEAD(, buf) data; - - uint64_t seg_num; - uint64_t seg_next; - uint64_t start_block; - uint32_t num_blocks; - - uint32_t nblocks; - uint32_t nbinfos; - uint32_t segsum_blocks; - uint32_t segsum_bytes; - uint32_t bytes_left; - char *current_off; -}; - -struct nandfs_seginfo { - LIST_HEAD( ,nandfs_segment) seg_list; - struct nandfs_segment *curseg; - struct nandfs_device *fsdev; - uint32_t blocks; - uint8_t reiterate; -}; - -#define NANDFS_FSSTOR_FAILED 1 -struct nandfs_fsarea { - int offset; - int flags; - int last_used; -}; - -extern int nandfs_cleaner_enable; -extern int nandfs_cleaner_interval; -extern int nandfs_cleaner_segments; - -struct nandfs_device { - struct vnode *nd_devvp; - struct g_consumer *nd_gconsumer; - - struct thread *nd_syncer; - struct thread *nd_cleaner; - int nd_syncer_exit; - int nd_cleaner_exit; - - struct nandfs_fsarea nd_fsarea[NANDFS_NFSAREAS]; - int nd_last_fsarea; - - STAILQ_HEAD(nandfs_mnts, nandfsmount) nd_mounts; - SLIST_ENTRY(nandfs_device) nd_next_device; - - /* FS structures */ - struct nandfs_fsdata nd_fsdata; - struct nandfs_super_block nd_super; - struct nandfs_segment_summary nd_last_segsum; - struct nandfs_super_root nd_super_root; - struct nandfs_node *nd_dat_node; - struct nandfs_node *nd_cp_node; - struct nandfs_node *nd_su_node; - struct nandfs_node *nd_gc_node; - - struct nandfs_mdt nd_dat_mdt; - struct nandfs_mdt nd_ifile_mdt; - - struct timespec nd_ts; - - /* Synchronization */ - struct mtx nd_mutex; - struct mtx nd_sync_mtx; - struct cv nd_sync_cv; - struct mtx nd_clean_mtx; - struct cv nd_clean_cv; - struct lock nd_seg_const; - - struct nandfs_seginfo *nd_seginfo; - - /* FS geometry */ - uint64_t nd_devsize; - uint64_t nd_maxfilesize; - uint32_t nd_blocksize; - uint32_t nd_erasesize; - - uint32_t nd_devblocksize; - - uint32_t nd_segs_reserved; - - /* Segment usage */ - uint64_t nd_clean_segs; - uint64_t *nd_free_base; - uint64_t nd_free_count; - uint64_t nd_dirty_bufs; - - /* Running values */ - uint64_t nd_seg_sequence; - uint64_t nd_seg_num; - uint64_t nd_next_seg_num; - uint64_t nd_last_pseg; - uint64_t nd_last_cno; - uint64_t nd_last_ino; - uint64_t nd_fakevblk; - - int nd_mount_state; - int nd_refcnt; - int nd_syncing; - int nd_cleaning; -}; - -extern SLIST_HEAD(_nandfs_devices, nandfs_device) nandfs_devices; - -#define NANDFS_FORCE_SYNCER 0x1 -#define NANDFS_UMOUNT 0x2 - -#define SYNCER_UMOUNT 0x0 -#define SYNCER_VFS_SYNC 0x1 -#define SYNCER_BDFLUSH 0x2 -#define SYNCER_FFORCE 0x3 -#define SYNCER_FSYNC 0x4 -#define SYNCER_ROUPD 0x5 - -static __inline int -nandfs_writelockflags(struct nandfs_device *fsdev, int flags) -{ - int error = 0; - - if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) - error = lockmgr(&fsdev->nd_seg_const, flags | LK_SHARED, NULL); - - return (error); -} - -static __inline void -nandfs_writeunlock(struct nandfs_device *fsdev) -{ - - if (lockstatus(&fsdev->nd_seg_const) != LK_EXCLUSIVE) - lockmgr(&(fsdev)->nd_seg_const, LK_RELEASE, NULL); -} - -#define NANDFS_WRITELOCKFLAGS(fsdev, flags) nandfs_writelockflags(fsdev, flags) - -#define NANDFS_WRITELOCK(fsdev) NANDFS_WRITELOCKFLAGS(fsdev, 0) - -#define NANDFS_WRITEUNLOCK(fsdev) nandfs_writeunlock(fsdev) - -#define NANDFS_WRITEASSERT(fsdev) lockmgr_assert(&(fsdev)->nd_seg_const, KA_LOCKED) - -/* Specific mountpoint; head or a checkpoint/snapshot */ -struct nandfsmount { - STAILQ_ENTRY(nandfsmount) nm_next_mount; - - struct mount *nm_vfs_mountp; - struct nandfs_device *nm_nandfsdev; - struct nandfs_args nm_mount_args; - struct nandfs_node *nm_ifile_node; - - uint8_t nm_flags; - int8_t nm_ronly; -}; - -struct nandfs_node { - struct vnode *nn_vnode; - struct nandfsmount *nn_nmp; - struct nandfs_device *nn_nandfsdev; - struct lockf *nn_lockf; - - uint64_t nn_ino; - struct nandfs_inode nn_inode; - - uint64_t nn_diroff; - uint32_t nn_flags; -}; - -#define IN_ACCESS 0x0001 /* Inode access time update request */ -#define IN_CHANGE 0x0002 /* Inode change time update request */ -#define IN_UPDATE 0x0004 /* Inode was written to; update mtime*/ -#define IN_MODIFIED 0x0008 /* node has been modified */ -#define IN_RENAME 0x0010 /* node is being renamed. */ - -/* File permissions. */ -#define IEXEC 0000100 /* Executable. */ -#define IWRITE 0000200 /* Writeable. */ -#define IREAD 0000400 /* Readable. */ -#define ISVTX 0001000 /* Sticky bit. */ -#define ISGID 0002000 /* Set-gid. */ -#define ISUID 0004000 /* Set-uid. */ - -#define PRINT_NODE_FLAGS \ - "\10\1IN_ACCESS\2IN_CHANGE\3IN_UPDATE\4IN_MODIFIED\5IN_RENAME" - -#define NANDFS_GATHER(x) ((x)->b_flags |= B_FS_FLAG1) -#define NANDFS_UNGATHER(x) ((x)->b_flags &= ~B_FS_FLAG1) -#define NANDFS_ISGATHERED(x) ((x)->b_flags & B_FS_FLAG1) - -#endif /* !_FS_NANDFS_NANDFS_H_ */ Property changes on: head/sys/fs/nandfs/nandfs.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_fs.h =================================================================== --- head/sys/fs/nandfs/nandfs_fs.h (revision 349351) +++ head/sys/fs/nandfs/nandfs_fs.h (nonexistent) @@ -1,567 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Original definitions written by Koji Sato - * and Ryusuke Konishi - * From: NetBSD: nandfs_fs.h,v 1.1 2009/07/18 16:31:42 reinoud - * - * $FreeBSD$ - */ - -#ifndef _NANDFS_FS_H -#define _NANDFS_FS_H - -#include - -#define MNINDIR(fsdev) ((fsdev)->nd_blocksize / sizeof(nandfs_daddr_t)) - -/* - * Inode structure. There are a few dedicated inode numbers that are - * defined here first. - */ -#define NANDFS_WHT_INO 1 /* Whiteout ino */ -#define NANDFS_ROOT_INO 2 /* Root file inode */ -#define NANDFS_DAT_INO 3 /* DAT file */ -#define NANDFS_CPFILE_INO 4 /* checkpoint file */ -#define NANDFS_SUFILE_INO 5 /* segment usage file */ -#define NANDFS_IFILE_INO 6 /* ifile */ -#define NANDFS_GC_INO 7 /* Cleanerd node */ -#define NANDFS_ATIME_INO 8 /* Atime file (reserved) */ -#define NANDFS_XATTR_INO 9 /* Xattribute file (reserved) */ -#define NANDFS_SKETCH_INO 10 /* Sketch file (obsolete) */ -#define NANDFS_USER_INO 11 /* First user's file inode number */ - -#define NANDFS_SYS_NODE(ino) \ - (((ino) >= NANDFS_DAT_INO) && ((ino) <= NANDFS_GC_INO)) - -#define NANDFS_NDADDR 12 /* Direct addresses in inode. */ -#define NANDFS_NIADDR 3 /* Indirect addresses in inode. */ - -typedef int64_t nandfs_daddr_t; -typedef int64_t nandfs_lbn_t; - -struct nandfs_inode { - uint64_t i_blocks; /* 0: size in device blocks */ - uint64_t i_size; /* 8: size in bytes */ - uint64_t i_ctime; /* 16: creation time in seconds */ - uint64_t i_mtime; /* 24: modification time in seconds part*/ - uint32_t i_ctime_nsec; /* 32: creation time nanoseconds part */ - uint32_t i_mtime_nsec; /* 36: modification time in nanoseconds */ - uint32_t i_uid; /* 40: user id */ - uint32_t i_gid; /* 44: group id */ - uint16_t i_mode; /* 48: file mode */ - uint16_t i_links_count; /* 50: number of references to the inode*/ - uint32_t i_flags; /* 52: NANDFS_*_FL flags */ - nandfs_daddr_t i_special; /* 56: special */ - nandfs_daddr_t i_db[NANDFS_NDADDR]; /* 64: Direct disk blocks. */ - nandfs_daddr_t i_ib[NANDFS_NIADDR]; /* 160: Indirect disk blocks. */ - uint64_t i_xattr; /* 184: reserved for extended attributes*/ - uint32_t i_generation; /* 192: file generation for NFS */ - uint32_t i_pad[15]; /* 196: make it 64 bits aligned */ -}; - -#ifdef _KERNEL -CTASSERT(sizeof(struct nandfs_inode) == 256); -#endif - -/* - * Each checkpoint/snapshot has a super root. - * - * The super root holds the inodes of the three system files: `dat', `cp' and - * 'su' files. All other FS state is defined by those. - * - * It is CRC checksum'ed and time stamped. - */ - -struct nandfs_super_root { - uint32_t sr_sum; /* check-sum */ - uint16_t sr_bytes; /* byte count of this structure */ - uint16_t sr_flags; /* reserved for flags */ - uint64_t sr_nongc_ctime; /* timestamp, not for cleaner(?) */ - struct nandfs_inode sr_dat; /* DAT, virt->phys translation inode */ - struct nandfs_inode sr_cpfile; /* CP, checkpoints inode */ - struct nandfs_inode sr_sufile; /* SU, segment usage inode */ -}; - -#define NANDFS_SR_MDT_OFFSET(inode_size, i) \ - ((uint32_t)&((struct nandfs_super_root *)0)->sr_dat + \ - (inode_size) * (i)) - -#define NANDFS_SR_DAT_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 0) -#define NANDFS_SR_CPFILE_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 1) -#define NANDFS_SR_SUFILE_OFFSET(inode_size) NANDFS_SR_MDT_OFFSET(inode_size, 2) -#define NANDFS_SR_BYTES (sizeof(struct nandfs_super_root)) - -/* - * The superblock describes the basic structure and mount history. It also - * records some sizes of structures found on the disc for sanity checks. - * - * The superblock is stored at two places: NANDFS_SB_OFFSET_BYTES and - * NANDFS_SB2_OFFSET_BYTES. - */ - -/* File system states stored on media in superblock's sbp->s_state */ -#define NANDFS_VALID_FS 0x0001 /* cleanly unmounted and all is ok */ -#define NANDFS_ERROR_FS 0x0002 /* there were errors detected, fsck */ -#define NANDFS_RESIZE_FS 0x0004 /* resize required, XXX unknown flag*/ -#define NANDFS_MOUNT_STATE_BITS "\20\1VALID_FS\2ERROR_FS\3RESIZE_FS" - -/* - * Brief description of control structures: - * - * NANDFS_NFSAREAS first blocks contain fsdata and some amount of super blocks. - * Simple round-robin policy is used in order to choose which block will - * contain new super block. - * - * Simple case with 2 blocks: - * 1: fsdata sblock1 [sblock3 [sblock5 ..]] - * 2: fsdata sblock2 [sblock4 [sblock6 ..]] - */ -struct nandfs_fsdata { - uint16_t f_magic; - uint16_t f_bytes; - - uint32_t f_sum; /* checksum of fsdata */ - uint32_t f_rev_level; /* major disk format revision */ - - uint64_t f_ctime; /* creation time (execution time - of newfs) */ - /* Block size represented as: blocksize = 1 << (f_log_block_size + 10) */ - uint32_t f_log_block_size; - - uint16_t f_inode_size; /* size of an inode */ - uint16_t f_dat_entry_size; /* size of a dat entry */ - uint16_t f_checkpoint_size; /* size of a checkpoint */ - uint16_t f_segment_usage_size; /* size of a segment usage */ - - uint16_t f_sbbytes; /* byte count of CRC calculation - for super blocks. s_reserved - is excluded! */ - - uint16_t f_errors; /* behaviour on detecting errors */ - - uint32_t f_erasesize; - uint64_t f_nsegments; /* number of segm. in filesystem */ - nandfs_daddr_t f_first_data_block; /* 1st seg disk block number */ - uint32_t f_blocks_per_segment; /* number of blocks per segment */ - uint32_t f_r_segments_percentage; /* reserved segments percentage */ - - struct uuid f_uuid; /* 128-bit uuid for volume */ - char f_volume_name[16]; /* volume name */ - uint32_t f_pad[104]; -} __packed; - -#ifdef _KERNEL -CTASSERT(sizeof(struct nandfs_fsdata) == 512); -#endif - -struct nandfs_super_block { - uint16_t s_magic; /* magic value for identification */ - - uint32_t s_sum; /* check sum of super block */ - - uint64_t s_last_cno; /* last checkpoint number */ - uint64_t s_last_pseg; /* addr part. segm. written last */ - uint64_t s_last_seq; /* seq.number of seg written last */ - uint64_t s_free_blocks_count; /* free blocks count */ - - uint64_t s_mtime; /* mount time */ - uint64_t s_wtime; /* write time */ - uint16_t s_state; /* file system state */ - - char s_last_mounted[64]; /* directory where last mounted */ - - uint32_t s_c_interval; /* commit interval of segment */ - uint32_t s_c_block_max; /* threshold of data amount for - the segment construction */ - uint32_t s_reserved[32]; /* padding to end of the block */ -} __packed; - -#ifdef _KERNEL -CTASSERT(sizeof(struct nandfs_super_block) == 256); -#endif - -#define NANDFS_FSDATA_MAGIC 0xf8da -#define NANDFS_SUPER_MAGIC 0x8008 - -#define NANDFS_NFSAREAS 4 -#define NANDFS_DATA_OFFSET_BYTES(esize) (NANDFS_NFSAREAS * (esize)) - -#define NANDFS_SBLOCK_OFFSET_BYTES (sizeof(struct nandfs_fsdata)) - -#define NANDFS_DEF_BLOCKSIZE 4096 -#define NANDFS_MIN_BLOCKSIZE 512 - -#define NANDFS_DEF_ERASESIZE (2 << 16) - -#define NANDFS_MIN_SEGSIZE NANDFS_DEF_ERASESIZE - -#define NANDFS_CURRENT_REV 9 /* current major revision */ - -#define NANDFS_FSDATA_CRC_BYTES offsetof(struct nandfs_fsdata, f_pad) -/* Bytes count of super_block for CRC-calculation */ -#define NANDFS_SB_BYTES offsetof(struct nandfs_super_block, s_reserved) - -/* Maximal count of links to a file */ -#define NANDFS_LINK_MAX 32000 - -/* - * Structure of a directory entry. - * - * Note that they can't span blocks; the rec_len fills out. - */ - -#define NANDFS_NAME_LEN 255 -struct nandfs_dir_entry { - uint64_t inode; /* inode number */ - uint16_t rec_len; /* directory entry length */ - uint8_t name_len; /* name length */ - uint8_t file_type; - char name[NANDFS_NAME_LEN]; /* file name */ - char pad; -}; - -/* - * NANDFS_DIR_PAD defines the directory entries boundaries - * - * NOTE: It must be a multiple of 8 - */ -#define NANDFS_DIR_PAD 8 -#define NANDFS_DIR_ROUND (NANDFS_DIR_PAD - 1) -#define NANDFS_DIR_NAME_OFFSET (offsetof(struct nandfs_dir_entry, name)) -#define NANDFS_DIR_REC_LEN(name_len) \ - (((name_len) + NANDFS_DIR_NAME_OFFSET + NANDFS_DIR_ROUND) \ - & ~NANDFS_DIR_ROUND) -#define NANDFS_DIR_NAME_LEN(name_len) \ - (NANDFS_DIR_REC_LEN(name_len) - NANDFS_DIR_NAME_OFFSET) - -/* - * NiLFS/NANDFS devides the disc into fixed length segments. Each segment is - * filled with one or more partial segments of variable lengths. - * - * Each partial segment has a segment summary header followed by updates of - * files and optionally a super root. - */ - -/* - * Virtual to physical block translation information. For data blocks it maps - * logical block number bi_blkoff to virtual block nr bi_vblocknr. For non - * datablocks it is the virtual block number assigned to an indirect block - * and has no bi_blkoff. The physical block number is the next - * available data block in the partial segment after all the binfo's. - */ -struct nandfs_binfo_v { - uint64_t bi_ino; /* file's inode */ - uint64_t bi_vblocknr; /* assigned virtual block number */ - uint64_t bi_blkoff; /* for file's logical block number */ -}; - -/* - * DAT allocation. For data blocks just the logical block number that maps on - * the next available data block in the partial segment after the binfo's. - */ -struct nandfs_binfo_dat { - uint64_t bi_ino; - uint64_t bi_blkoff; /* DAT file's logical block number */ - uint8_t bi_level; /* whether this is meta block */ - uint8_t bi_pad[7]; -}; - -#ifdef _KERNEL -CTASSERT(sizeof(struct nandfs_binfo_v) == sizeof(struct nandfs_binfo_dat)); -#endif - -/* Convenience union for both types of binfo's */ -union nandfs_binfo { - struct nandfs_binfo_v bi_v; - struct nandfs_binfo_dat bi_dat; -}; - -/* Indirect buffers path */ -struct nandfs_indir { - nandfs_daddr_t in_lbn; - int in_off; -}; - -/* The (partial) segment summary */ -struct nandfs_segment_summary { - uint32_t ss_datasum; /* CRC of complete data block */ - uint32_t ss_sumsum; /* CRC of segment summary only */ - uint32_t ss_magic; /* magic to identify segment summary */ - uint16_t ss_bytes; /* size of segment summary structure */ - uint16_t ss_flags; /* NANDFS_SS_* flags */ - uint64_t ss_seq; /* sequence number of this segm. sum */ - uint64_t ss_create; /* creation timestamp in seconds */ - uint64_t ss_next; /* blocknumber of next segment */ - uint32_t ss_nblocks; /* number of blocks used by summary */ - uint32_t ss_nbinfos; /* number of binfo structures */ - uint32_t ss_sumbytes; /* total size of segment summary */ - uint32_t ss_pad; - /* stream of binfo structures */ -}; - -#define NANDFS_SEGSUM_MAGIC 0x8e680011 /* segment summary magic number */ - -/* Segment summary flags */ -#define NANDFS_SS_LOGBGN 0x0001 /* begins a logical segment */ -#define NANDFS_SS_LOGEND 0x0002 /* ends a logical segment */ -#define NANDFS_SS_SR 0x0004 /* has super root */ -#define NANDFS_SS_SYNDT 0x0008 /* includes data only updates */ -#define NANDFS_SS_GC 0x0010 /* segment written for cleaner operation */ -#define NANDFS_SS_FLAG_BITS "\20\1LOGBGN\2LOGEND\3SR\4SYNDT\5GC" - -/* Segment summary constrains */ -#define NANDFS_SEG_MIN_BLOCKS 16 /* minimum number of blocks in a - full segment */ -#define NANDFS_PSEG_MIN_BLOCKS 2 /* minimum number of blocks in a - partial segment */ -#define NANDFS_MIN_NRSVSEGS 8 /* minimum number of reserved - segments */ - -/* - * Structure of DAT/inode file. - * - * A DAT file is divided into groups. The maximum number of groups is the - * number of block group descriptors that fit into one block; this descriptor - * only gives the number of free entries in the associated group. - * - * Each group has a block sized bitmap indicating if an entry is taken or - * empty. Each bit stands for a DAT entry. - * - * The inode file has exactly the same format only the entries are inode - * entries. - */ - -struct nandfs_block_group_desc { - uint32_t bg_nfrees; /* num. free entries in block group */ -}; - -/* DAT entry in a super root's DAT file */ -struct nandfs_dat_entry { - uint64_t de_blocknr; /* block number */ - uint64_t de_start; /* valid from checkpoint */ - uint64_t de_end; /* valid till checkpoint */ - uint64_t de_rsv; /* reserved for future use */ -}; - -/* - * Structure of CP file. - * - * A snapshot is just a checkpoint only it's protected against removal by the - * cleaner. The snapshots are kept on a double linked list of checkpoints. - */ -struct nandfs_snapshot_list { - uint64_t ssl_next; /* checkpoint nr. forward */ - uint64_t ssl_prev; /* checkpoint nr. back */ -}; - -/* Checkpoint entry structure */ -struct nandfs_checkpoint { - uint32_t cp_flags; /* NANDFS_CHECKPOINT_* flags */ - uint32_t cp_checkpoints_count; /* ZERO, not used anymore? */ - struct nandfs_snapshot_list cp_snapshot_list; /* list of snapshots */ - uint64_t cp_cno; /* checkpoint number */ - uint64_t cp_create; /* creation timestamp */ - uint64_t cp_nblk_inc; /* number of blocks incremented */ - uint64_t cp_blocks_count; /* reserved (might be deleted) */ - struct nandfs_inode cp_ifile_inode; /* inode file inode */ -}; - -/* Checkpoint flags */ -#define NANDFS_CHECKPOINT_SNAPSHOT 1 -#define NANDFS_CHECKPOINT_INVALID 2 -#define NANDFS_CHECKPOINT_SKETCH 4 -#define NANDFS_CHECKPOINT_MINOR 8 -#define NANDFS_CHECKPOINT_BITS "\20\1SNAPSHOT\2INVALID\3SKETCH\4MINOR" - -/* Header of the checkpoint file */ -struct nandfs_cpfile_header { - uint64_t ch_ncheckpoints; /* number of checkpoints */ - uint64_t ch_nsnapshots; /* number of snapshots */ - struct nandfs_snapshot_list ch_snapshot_list; /* snapshot list */ -}; - -#define NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET \ - ((sizeof(struct nandfs_cpfile_header) + \ - sizeof(struct nandfs_checkpoint) - 1) / \ - sizeof(struct nandfs_checkpoint)) - - -#define NANDFS_NOSEGMENT 0xffffffff - -/* - * Structure of SU file. - * - * The segment usage file sums up how each of the segments are used. They are - * indexed by their segment number. - */ - -/* Segment usage entry */ -struct nandfs_segment_usage { - uint64_t su_lastmod; /* last modified timestamp */ - uint32_t su_nblocks; /* number of blocks in segment */ - uint32_t su_flags; /* NANDFS_SEGMENT_USAGE_* flags */ -}; - -/* Segment usage flag */ -#define NANDFS_SEGMENT_USAGE_ACTIVE 1 -#define NANDFS_SEGMENT_USAGE_DIRTY 2 -#define NANDFS_SEGMENT_USAGE_ERROR 4 -#define NANDFS_SEGMENT_USAGE_GC 8 -#define NANDFS_SEGMENT_USAGE_BITS "\20\1ACTIVE\2DIRTY\3ERROR" - -/* Header of the segment usage file */ -struct nandfs_sufile_header { - uint64_t sh_ncleansegs; /* number of segments marked clean */ - uint64_t sh_ndirtysegs; /* number of segments marked dirty */ - uint64_t sh_last_alloc; /* last allocated segment number */ -}; - -#define NANDFS_SUFILE_FIRST_SEGMENT_USAGE_OFFSET \ - ((sizeof(struct nandfs_sufile_header) + \ - sizeof(struct nandfs_segment_usage) - 1) / \ - sizeof(struct nandfs_segment_usage)) - -struct nandfs_seg_stat { - uint64_t nss_nsegs; - uint64_t nss_ncleansegs; - uint64_t nss_ndirtysegs; - uint64_t nss_ctime; - uint64_t nss_nongc_ctime; - uint64_t nss_prot_seq; -}; - -enum { - NANDFS_CHECKPOINT, - NANDFS_SNAPSHOT -}; - -#define NANDFS_CPINFO_MAX 512 - -struct nandfs_cpinfo { - uint32_t nci_flags; - uint32_t nci_pad; - uint64_t nci_cno; - uint64_t nci_create; - uint64_t nci_nblk_inc; - uint64_t nci_blocks_count; - uint64_t nci_next; -}; - -#define NANDFS_SEGMENTS_MAX 512 - -struct nandfs_suinfo { - uint64_t nsi_num; - uint64_t nsi_lastmod; - uint32_t nsi_blocks; - uint32_t nsi_flags; -}; - -#define NANDFS_VINFO_MAX 512 - -struct nandfs_vinfo { - uint64_t nvi_ino; - uint64_t nvi_vblocknr; - uint64_t nvi_start; - uint64_t nvi_end; - uint64_t nvi_blocknr; - int nvi_alive; -}; - -struct nandfs_cpmode { - uint64_t ncpm_cno; - uint32_t ncpm_mode; - uint32_t ncpm_pad; -}; - -struct nandfs_argv { - uint64_t nv_base; - uint32_t nv_nmembs; - uint16_t nv_size; - uint16_t nv_flags; - uint64_t nv_index; -}; - -struct nandfs_cpstat { - uint64_t ncp_cno; - uint64_t ncp_ncps; - uint64_t ncp_nss; -}; - -struct nandfs_period { - uint64_t p_start; - uint64_t p_end; -}; - -struct nandfs_vdesc { - uint64_t vd_ino; - uint64_t vd_cno; - uint64_t vd_vblocknr; - struct nandfs_period vd_period; - uint64_t vd_blocknr; - uint64_t vd_offset; - uint32_t vd_flags; - uint32_t vd_pad; -}; - -struct nandfs_bdesc { - uint64_t bd_ino; - uint64_t bd_oblocknr; - uint64_t bd_blocknr; - uint64_t bd_offset; - uint32_t bd_level; - uint32_t bd_alive; -}; - -#ifndef _KERNEL -#ifndef MNAMELEN -#define MNAMELEN 1024 -#endif -#endif - -struct nandfs_fsinfo { - struct nandfs_fsdata fs_fsdata; - struct nandfs_super_block fs_super; - char fs_dev[MNAMELEN]; -}; - -#define NANDFS_MAX_MOUNTS 65535 - -#define NANDFS_IOCTL_GET_SUSTAT _IOR('N', 100, struct nandfs_seg_stat) -#define NANDFS_IOCTL_CHANGE_CPMODE _IOWR('N', 101, struct nandfs_cpmode) -#define NANDFS_IOCTL_GET_CPINFO _IOWR('N', 102, struct nandfs_argv) -#define NANDFS_IOCTL_DELETE_CP _IOWR('N', 103, uint64_t[2]) -#define NANDFS_IOCTL_GET_CPSTAT _IOR('N', 104, struct nandfs_cpstat) -#define NANDFS_IOCTL_GET_SUINFO _IOWR('N', 105, struct nandfs_argv) -#define NANDFS_IOCTL_GET_VINFO _IOWR('N', 106, struct nandfs_argv) -#define NANDFS_IOCTL_GET_BDESCS _IOWR('N', 107, struct nandfs_argv) -#define NANDFS_IOCTL_GET_FSINFO _IOR('N', 108, struct nandfs_fsinfo) -#define NANDFS_IOCTL_MAKE_SNAP _IOWR('N', 109, uint64_t) -#define NANDFS_IOCTL_DELETE_SNAP _IOWR('N', 110, uint64_t) -#define NANDFS_IOCTL_SYNC _IOWR('N', 111, uint64_t) - -#endif /* _NANDFS_FS_H */ Property changes on: head/sys/fs/nandfs/nandfs_fs.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/bmap.c =================================================================== --- head/sys/fs/nandfs/bmap.c (revision 349351) +++ head/sys/fs/nandfs/bmap.c (nonexistent) @@ -1,625 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "nandfs_mount.h" -#include "nandfs.h" -#include "nandfs_subr.h" -#include "bmap.h" - -static int bmap_getlbns(struct nandfs_node *, nandfs_lbn_t, - struct nandfs_indir *, int *); - -int -bmap_lookup(struct nandfs_node *node, nandfs_lbn_t lblk, nandfs_daddr_t *vblk) -{ - struct nandfs_inode *ip; - struct nandfs_indir a[NANDFS_NIADDR + 1], *ap; - nandfs_daddr_t daddr; - struct buf *bp; - int error; - int num, *nump; - - DPRINTF(BMAP, ("%s: node %p lblk %jx enter\n", __func__, node, lblk)); - ip = &node->nn_inode; - - ap = a; - nump = # - - error = bmap_getlbns(node, lblk, ap, nump); - if (error) - return (error); - - if (num == 0) { - *vblk = ip->i_db[lblk]; - return (0); - } - - DPRINTF(BMAP, ("%s: node %p lblk=%jx trying ip->i_ib[%x]\n", __func__, - node, lblk, ap->in_off)); - daddr = ip->i_ib[ap->in_off]; - for (bp = NULL, ++ap; --num; ap++) { - if (daddr == 0) { - DPRINTF(BMAP, ("%s: node %p lblk=%jx returning with " - "vblk 0\n", __func__, node, lblk)); - *vblk = 0; - return (0); - } - if (ap->in_lbn == lblk) { - DPRINTF(BMAP, ("%s: node %p lblk=%jx ap->in_lbn=%jx " - "returning address of indirect block (%jx)\n", - __func__, node, lblk, ap->in_lbn, daddr)); - *vblk = daddr; - return (0); - } - - DPRINTF(BMAP, ("%s: node %p lblk=%jx reading block " - "ap->in_lbn=%jx\n", __func__, node, lblk, ap->in_lbn)); - - error = nandfs_bread_meta(node, ap->in_lbn, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - daddr = ((nandfs_daddr_t *)bp->b_data)[ap->in_off]; - brelse(bp); - } - - DPRINTF(BMAP, ("%s: node %p lblk=%jx returning with %jx\n", __func__, - node, lblk, daddr)); - *vblk = daddr; - - return (0); -} - -int -bmap_dirty_meta(struct nandfs_node *node, nandfs_lbn_t lblk, int force) -{ - struct nandfs_indir a[NANDFS_NIADDR+1], *ap; -#ifdef DEBUG - nandfs_daddr_t daddr; -#endif - struct buf *bp; - int error; - int num, *nump; - - DPRINTF(BMAP, ("%s: node %p lblk=%jx\n", __func__, node, lblk)); - - ap = a; - nump = # - - error = bmap_getlbns(node, lblk, ap, nump); - if (error) - return (error); - - /* - * Direct block, nothing to do - */ - if (num == 0) - return (0); - - DPRINTF(BMAP, ("%s: node %p reading blocks\n", __func__, node)); - - for (bp = NULL, ++ap; --num; ap++) { - error = nandfs_bread_meta(node, ap->in_lbn, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - -#ifdef DEBUG - daddr = ((nandfs_daddr_t *)bp->b_data)[ap->in_off]; - MPASS(daddr != 0 || node->nn_ino == 3); -#endif - - error = nandfs_dirty_buf_meta(bp, force); - if (error) - return (error); - } - - return (0); -} - -int -bmap_insert_block(struct nandfs_node *node, nandfs_lbn_t lblk, - nandfs_daddr_t vblk) -{ - struct nandfs_inode *ip; - struct nandfs_indir a[NANDFS_NIADDR+1], *ap; - struct buf *bp; - nandfs_daddr_t daddr; - int error; - int num, *nump, i; - - DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx\n", __func__, node, lblk, - vblk)); - - ip = &node->nn_inode; - - ap = a; - nump = # - - error = bmap_getlbns(node, lblk, ap, nump); - if (error) - return (error); - - DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx got num=%d\n", __func__, - node, lblk, vblk, num)); - - if (num == 0) { - DPRINTF(BMAP, ("%s: node %p lblk=%jx direct block\n", __func__, - node, lblk)); - ip->i_db[lblk] = vblk; - return (0); - } - - DPRINTF(BMAP, ("%s: node %p lblk=%jx indirect block level %d\n", - __func__, node, lblk, ap->in_off)); - - if (num == 1) { - DPRINTF(BMAP, ("%s: node %p lblk=%jx indirect block: inserting " - "%jx as vblk for indirect block %d\n", __func__, node, - lblk, vblk, ap->in_off)); - ip->i_ib[ap->in_off] = vblk; - return (0); - } - - bp = NULL; - daddr = ip->i_ib[a[0].in_off]; - for (i = 1; i < num; i++) { - if (bp) - brelse(bp); - if (daddr == 0) { - DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx create " - "block %jx %d\n", __func__, node, lblk, vblk, - a[i].in_lbn, a[i].in_off)); - error = nandfs_bcreate_meta(node, a[i].in_lbn, NOCRED, - 0, &bp); - if (error) - return (error); - } else { - DPRINTF(BMAP, ("%s: node %p lblk=%jx vblk=%jx read " - "block %jx %d\n", __func__, node, daddr, vblk, - a[i].in_lbn, a[i].in_off)); - error = nandfs_bread_meta(node, a[i].in_lbn, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - } - daddr = ((nandfs_daddr_t *)bp->b_data)[a[i].in_off]; - } - i--; - - DPRINTF(BMAP, - ("%s: bmap node %p lblk=%jx vblk=%jx inserting vblk level %d at " - "offset %d at %jx\n", __func__, node, lblk, vblk, i, a[i].in_off, - daddr)); - - if (!bp) { - nandfs_error("%s: cannot find indirect block\n", __func__); - return (-1); - } - ((nandfs_daddr_t *)bp->b_data)[a[i].in_off] = vblk; - - error = nandfs_dirty_buf_meta(bp, 0); - if (error) { - nandfs_warning("%s: dirty failed buf: %p\n", __func__, bp); - return (error); - } - DPRINTF(BMAP, ("%s: exiting node %p lblk=%jx vblk=%jx\n", __func__, - node, lblk, vblk)); - - return (error); -} - -CTASSERT(NANDFS_NIADDR <= 3); -#define SINGLE 0 /* index of single indirect block */ -#define DOUBLE 1 /* index of double indirect block */ -#define TRIPLE 2 /* index of triple indirect block */ - -static __inline nandfs_lbn_t -lbn_offset(struct nandfs_device *fsdev, int level) -{ - nandfs_lbn_t res; - - for (res = 1; level > 0; level--) - res *= MNINDIR(fsdev); - return (res); -} - -static nandfs_lbn_t -blocks_inside(struct nandfs_device *fsdev, int level, struct nandfs_indir *nip) -{ - nandfs_lbn_t blocks; - - for (blocks = 1; level >= SINGLE; level--, nip++) { - MPASS(nip->in_off >= 0 && nip->in_off < MNINDIR(fsdev)); - blocks += nip->in_off * lbn_offset(fsdev, level); - } - - return (blocks); -} - -static int -bmap_truncate_indirect(struct nandfs_node *node, int level, nandfs_lbn_t *left, - int *cleaned, struct nandfs_indir *ap, struct nandfs_indir *fp, - nandfs_daddr_t *copy) -{ - struct buf *bp; - nandfs_lbn_t i, lbn, nlbn, factor, tosub; - struct nandfs_device *fsdev; - int error, lcleaned, modified; - - DPRINTF(BMAP, ("%s: node %p level %d left %jx\n", __func__, - node, level, *left)); - - fsdev = node->nn_nandfsdev; - - MPASS(ap->in_off >= 0 && ap->in_off < MNINDIR(fsdev)); - - factor = lbn_offset(fsdev, level); - lbn = ap->in_lbn; - - error = nandfs_bread_meta(node, lbn, NOCRED, 0, &bp); - if (error) { - if (bp != NULL) - brelse(bp); - return (error); - } - - bcopy(bp->b_data, copy, fsdev->nd_blocksize); - bqrelse(bp); - - modified = 0; - - i = ap->in_off; - - if (ap != fp) - ap++; - for (nlbn = lbn + 1 - i * factor; i >= 0 && *left > 0; i--, - nlbn += factor) { - lcleaned = 0; - - DPRINTF(BMAP, - ("%s: node %p i=%jx nlbn=%jx left=%jx ap=%p vblk %jx\n", - __func__, node, i, nlbn, *left, ap, copy[i])); - - if (copy[i] == 0) { - tosub = blocks_inside(fsdev, level - 1, ap); - if (tosub > *left) - tosub = 0; - - *left -= tosub; - } else { - if (level > SINGLE) { - if (ap == fp) - ap->in_lbn = nlbn; - - error = bmap_truncate_indirect(node, level - 1, - left, &lcleaned, ap, fp, - copy + MNINDIR(fsdev)); - if (error) - return (error); - } else { - error = nandfs_bdestroy(node, copy[i]); - if (error) - return (error); - lcleaned = 1; - *left -= 1; - } - } - - if (lcleaned) { - if (level > SINGLE) { - error = nandfs_vblock_end(fsdev, copy[i]); - if (error) - return (error); - } - copy[i] = 0; - modified++; - } - - ap = fp; - } - - if (i == -1) - *cleaned = 1; - - error = nandfs_bread_meta(node, lbn, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - if (modified) - bcopy(copy, bp->b_data, fsdev->nd_blocksize); - - /* Force success even if we can't dirty the buffer metadata when freeing space */ - nandfs_dirty_buf_meta(bp, 1); - - return (0); -} - -int -bmap_truncate_mapping(struct nandfs_node *node, nandfs_lbn_t lastblk, - nandfs_lbn_t todo) -{ - struct nandfs_inode *ip; - struct nandfs_indir a[NANDFS_NIADDR + 1], f[NANDFS_NIADDR], *ap; - nandfs_daddr_t indir_lbn[NANDFS_NIADDR]; - nandfs_daddr_t *copy; - int error, level; - nandfs_lbn_t left, tosub; - struct nandfs_device *fsdev; - int cleaned, i; - int num, *nump; - - DPRINTF(BMAP, ("%s: node %p lastblk %jx truncating by %jx\n", __func__, - node, lastblk, todo)); - - ip = &node->nn_inode; - fsdev = node->nn_nandfsdev; - - ap = a; - nump = # - - error = bmap_getlbns(node, lastblk, ap, nump); - if (error) - return (error); - - indir_lbn[SINGLE] = -NANDFS_NDADDR; - indir_lbn[DOUBLE] = indir_lbn[SINGLE] - MNINDIR(fsdev) - 1; - indir_lbn[TRIPLE] = indir_lbn[DOUBLE] - MNINDIR(fsdev) - * MNINDIR(fsdev) - 1; - - for (i = 0; i < NANDFS_NIADDR; i++) { - f[i].in_off = MNINDIR(fsdev) - 1; - f[i].in_lbn = 0xdeadbeef; - } - - left = todo; - -#ifdef DEBUG - a[num].in_off = -1; -#endif - - ap++; - num -= 2; - - if (num < 0) - goto direct; - - copy = malloc(MNINDIR(fsdev) * sizeof(nandfs_daddr_t) * (num + 1), - M_NANDFSTEMP, M_WAITOK); - - for (level = num; level >= SINGLE && left > 0; level--) { - cleaned = 0; - - if (ip->i_ib[level] == 0) { - tosub = blocks_inside(fsdev, level, ap); - if (tosub > left) - left = 0; - else - left -= tosub; - } else { - if (ap == f) - ap->in_lbn = indir_lbn[level]; - error = bmap_truncate_indirect(node, level, &left, - &cleaned, ap, f, copy); - if (error) { - free(copy, M_NANDFSTEMP); - nandfs_error("%s: error %d when truncate " - "at level %d\n", __func__, error, level); - return (error); - } - } - - if (cleaned) { - nandfs_vblock_end(fsdev, ip->i_ib[level]); - ip->i_ib[level] = 0; - } - - ap = f; - } - - free(copy, M_NANDFSTEMP); - -direct: - if (num < 0) - i = lastblk; - else - i = NANDFS_NDADDR - 1; - - for (; i >= 0 && left > 0; i--) { - if (ip->i_db[i] != 0) { - error = nandfs_bdestroy(node, ip->i_db[i]); - if (error) { - nandfs_error("%s: cannot destroy " - "block %jx, error %d\n", __func__, - (uintmax_t)ip->i_db[i], error); - return (error); - } - ip->i_db[i] = 0; - } - - left--; - } - - KASSERT(left == 0, - ("truncated wrong number of blocks (%jd should be 0)", left)); - - return (error); -} - -nandfs_lbn_t -get_maxfilesize(struct nandfs_device *fsdev) -{ - struct nandfs_indir f[NANDFS_NIADDR]; - nandfs_lbn_t max; - int i; - - max = NANDFS_NDADDR; - - for (i = 0; i < NANDFS_NIADDR; i++) { - f[i].in_off = MNINDIR(fsdev) - 1; - max += blocks_inside(fsdev, i, f); - } - - max *= fsdev->nd_blocksize; - - return (max); -} - -/* - * This is ufs_getlbns with minor modifications. - */ -/* - * Create an array of logical block number/offset pairs which represent the - * path of indirect blocks required to access a data block. The first "pair" - * contains the logical block number of the appropriate single, double or - * triple indirect block and the offset into the inode indirect block array. - * Note, the logical block number of the inode single/double/triple indirect - * block appears twice in the array, once with the offset into the i_ib and - * once with the offset into the page itself. - */ -static int -bmap_getlbns(struct nandfs_node *node, nandfs_lbn_t bn, struct nandfs_indir *ap, int *nump) -{ - nandfs_daddr_t blockcnt; - nandfs_lbn_t metalbn, realbn; - struct nandfs_device *fsdev; - int i, numlevels, off; - - fsdev = node->nn_nandfsdev; - - DPRINTF(BMAP, ("%s: node %p bn=%jx mnindir=%zd enter\n", __func__, - node, bn, MNINDIR(fsdev))); - - if (nump) - *nump = 0; - numlevels = 0; - realbn = bn; - - if (bn < 0) - bn = -bn; - - /* The first NANDFS_NDADDR blocks are direct blocks. */ - if (bn < NANDFS_NDADDR) - return (0); - - /* - * Determine the number of levels of indirection. After this loop - * is done, blockcnt indicates the number of data blocks possible - * at the previous level of indirection, and NANDFS_NIADDR - i is the - * number of levels of indirection needed to locate the requested block. - */ - for (blockcnt = 1, i = NANDFS_NIADDR, bn -= NANDFS_NDADDR;; i--, bn -= blockcnt) { - DPRINTF(BMAP, ("%s: blockcnt=%jd i=%d bn=%jd\n", __func__, - blockcnt, i, bn)); - if (i == 0) - return (EFBIG); - blockcnt *= MNINDIR(fsdev); - if (bn < blockcnt) - break; - } - - /* Calculate the address of the first meta-block. */ - if (realbn >= 0) - metalbn = -(realbn - bn + NANDFS_NIADDR - i); - else - metalbn = -(-realbn - bn + NANDFS_NIADDR - i); - - /* - * At each iteration, off is the offset into the bap array which is - * an array of disk addresses at the current level of indirection. - * The logical block number and the offset in that block are stored - * into the argument array. - */ - ap->in_lbn = metalbn; - ap->in_off = off = NANDFS_NIADDR - i; - - DPRINTF(BMAP, ("%s: initial: ap->in_lbn=%jx ap->in_off=%d\n", __func__, - metalbn, off)); - - ap++; - for (++numlevels; i <= NANDFS_NIADDR; i++) { - /* If searching for a meta-data block, quit when found. */ - if (metalbn == realbn) - break; - - blockcnt /= MNINDIR(fsdev); - off = (bn / blockcnt) % MNINDIR(fsdev); - - ++numlevels; - ap->in_lbn = metalbn; - ap->in_off = off; - - DPRINTF(BMAP, ("%s: in_lbn=%jx in_off=%d\n", __func__, - ap->in_lbn, ap->in_off)); - ++ap; - - metalbn -= -1 + off * blockcnt; - } - if (nump) - *nump = numlevels; - - DPRINTF(BMAP, ("%s: numlevels=%d\n", __func__, numlevels)); - - return (0); -} Property changes on: head/sys/fs/nandfs/bmap.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_buffer.c =================================================================== --- head/sys/fs/nandfs/nandfs_buffer.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_buffer.c (nonexistent) @@ -1,85 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -struct buf * -nandfs_geteblk(int size, int flags) -{ - struct buf *bp; - - /* - * XXX - * Right now we can call geteblk with GB_NOWAIT_BD flag, which means - * it can return NULL. But we cannot afford to get NULL, hence this panic. - */ - bp = geteblk(size, flags); - if (bp == NULL) - panic("geteblk returned NULL"); - - return (bp); -} - -void -nandfs_dirty_bufs_increment(struct nandfs_device *fsdev) -{ - - mtx_lock(&fsdev->nd_mutex); - KASSERT(fsdev->nd_dirty_bufs >= 0, ("negative nd_dirty_bufs")); - fsdev->nd_dirty_bufs++; - mtx_unlock(&fsdev->nd_mutex); -} - -void -nandfs_dirty_bufs_decrement(struct nandfs_device *fsdev) -{ - - mtx_lock(&fsdev->nd_mutex); - KASSERT(fsdev->nd_dirty_bufs > 0, - ("decrementing not-positive nd_dirty_bufs")); - fsdev->nd_dirty_bufs--; - mtx_unlock(&fsdev->nd_mutex); -} Property changes on: head/sys/fs/nandfs/nandfs_buffer.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_ifile.c =================================================================== --- head/sys/fs/nandfs/nandfs_ifile.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_ifile.c (nonexistent) @@ -1,215 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -int -nandfs_node_create(struct nandfsmount *nmp, struct nandfs_node **node, - uint16_t mode) -{ - struct nandfs_alloc_request req; - struct nandfs_device *nandfsdev; - struct nandfs_mdt *mdt; - struct nandfs_node *ifile; - struct nandfs_inode *inode; - struct vnode *vp; - uint32_t entry; - int error = 0; - - nandfsdev = nmp->nm_nandfsdev; - mdt = &nandfsdev->nd_ifile_mdt; - ifile = nmp->nm_ifile_node; - vp = NTOV(ifile); - - VOP_LOCK(vp, LK_EXCLUSIVE); - /* Allocate new inode in ifile */ - req.entrynum = nandfsdev->nd_last_ino + 1; - error = nandfs_find_free_entry(mdt, ifile, &req); - if (error) { - VOP_UNLOCK(vp, 0); - return (error); - } - - error = nandfs_get_entry_block(mdt, ifile, &req, &entry, 1); - if (error) { - VOP_UNLOCK(vp, 0); - return (error); - } - - /* Inode initialization */ - inode = ((struct nandfs_inode *) req.bp_entry->b_data) + entry; - nandfs_inode_init(inode, mode); - - error = nandfs_alloc_entry(mdt, &req); - if (error) { - VOP_UNLOCK(vp, 0); - return (error); - } - - VOP_UNLOCK(vp, 0); - - nandfsdev->nd_last_ino = req.entrynum; - error = nandfs_get_node(nmp, req.entrynum, node); - DPRINTF(IFILE, ("%s: node: %p ino: %#jx\n", - __func__, node, (uintmax_t)((*node)->nn_ino))); - - return (error); -} - -int -nandfs_node_destroy(struct nandfs_node *node) -{ - struct nandfs_alloc_request req; - struct nandfsmount *nmp; - struct nandfs_mdt *mdt; - struct nandfs_node *ifile; - struct vnode *vp; - int error = 0; - - nmp = node->nn_nmp; - req.entrynum = node->nn_ino; - mdt = &nmp->nm_nandfsdev->nd_ifile_mdt; - ifile = nmp->nm_ifile_node; - vp = NTOV(ifile); - - DPRINTF(IFILE, ("%s: destroy node: %p ino: %#jx\n", - __func__, node, (uintmax_t)node->nn_ino)); - VOP_LOCK(vp, LK_EXCLUSIVE); - - error = nandfs_find_entry(mdt, ifile, &req); - if (error) { - nandfs_error("%s: finding entry error:%d node %p(%jx)", - __func__, error, node, node->nn_ino); - VOP_UNLOCK(vp, 0); - return (error); - } - - nandfs_inode_destroy(&node->nn_inode); - - error = nandfs_free_entry(mdt, &req); - if (error) { - nandfs_error("%s: freing entry error:%d node %p(%jx)", - __func__, error, node, node->nn_ino); - VOP_UNLOCK(vp, 0); - return (error); - } - - VOP_UNLOCK(vp, 0); - DPRINTF(IFILE, ("%s: freed node %p ino %#jx\n", - __func__, node, (uintmax_t)node->nn_ino)); - return (error); -} - -int -nandfs_node_update(struct nandfs_node *node) -{ - struct nandfs_alloc_request req; - struct nandfsmount *nmp; - struct nandfs_mdt *mdt; - struct nandfs_node *ifile; - struct nandfs_inode *inode; - uint32_t index; - int error = 0; - - nmp = node->nn_nmp; - ifile = nmp->nm_ifile_node; - ASSERT_VOP_LOCKED(NTOV(ifile), __func__); - - req.entrynum = node->nn_ino; - mdt = &nmp->nm_nandfsdev->nd_ifile_mdt; - - DPRINTF(IFILE, ("%s: node:%p ino:%#jx\n", - __func__, &node->nn_inode, (uintmax_t)node->nn_ino)); - - error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0); - if (error) { - printf("nandfs_get_entry_block returned with ERROR=%d\n", - error); - return (error); - } - - inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index; - memcpy(inode, &node->nn_inode, sizeof(*inode)); - error = nandfs_dirty_buf(req.bp_entry, 0); - - return (error); -} - -int -nandfs_get_node_entry(struct nandfsmount *nmp, struct nandfs_inode **inode, - uint64_t ino, struct buf **bp) -{ - struct nandfs_alloc_request req; - struct nandfs_mdt *mdt; - struct nandfs_node *ifile; - struct vnode *vp; - uint32_t index; - int error = 0; - - req.entrynum = ino; - mdt = &nmp->nm_nandfsdev->nd_ifile_mdt; - ifile = nmp->nm_ifile_node; - vp = NTOV(ifile); - - VOP_LOCK(vp, LK_EXCLUSIVE); - error = nandfs_get_entry_block(mdt, ifile, &req, &index, 0); - if (error) { - VOP_UNLOCK(vp, 0); - return (error); - } - - *inode = ((struct nandfs_inode *) req.bp_entry->b_data) + index; - *bp = req.bp_entry; - VOP_UNLOCK(vp, 0); - return (0); -} - Property changes on: head/sys/fs/nandfs/nandfs_ifile.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/bmap.h =================================================================== --- head/sys/fs/nandfs/bmap.h (revision 349351) +++ head/sys/fs/nandfs/bmap.h (nonexistent) @@ -1,42 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _BMAP_H -#define _BMAP_H - -#include "nandfs_fs.h" - -int bmap_lookup(struct nandfs_node *, nandfs_lbn_t, nandfs_daddr_t *); -int bmap_insert_block(struct nandfs_node *, nandfs_lbn_t, nandfs_daddr_t); -int bmap_truncate_mapping(struct nandfs_node *, nandfs_lbn_t, nandfs_lbn_t); -int bmap_dirty_meta(struct nandfs_node *, nandfs_lbn_t, int); - -nandfs_lbn_t get_maxfilesize(struct nandfs_device *); - -#endif /* _BMAP_H */ Property changes on: head/sys/fs/nandfs/bmap.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_subr.c =================================================================== --- head/sys/fs/nandfs/nandfs_subr.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_subr.c (nonexistent) @@ -1,1091 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include "nandfs_mount.h" -#include "nandfs.h" -#include "nandfs_subr.h" - -MALLOC_DEFINE(M_NANDFSMNT, "nandfs_mount", "NANDFS mount"); -MALLOC_DEFINE(M_NANDFSTEMP, "nandfs_tmt", "NANDFS tmp"); - -uma_zone_t nandfs_node_zone; - -void nandfs_bdflush(struct bufobj *bo, struct buf *bp); -int nandfs_bufsync(struct bufobj *bo, int waitfor); - -struct buf_ops buf_ops_nandfs = { - .bop_name = "buf_ops_nandfs", - .bop_write = bufwrite, - .bop_strategy = bufstrategy, - .bop_sync = nandfs_bufsync, - .bop_bdflush = nandfs_bdflush, -}; - -int -nandfs_bufsync(struct bufobj *bo, int waitfor) -{ - struct vnode *vp; - int error = 0; - - vp = bo2vnode(bo); - - ASSERT_VOP_LOCKED(vp, __func__); - error = nandfs_sync_file(vp); - if (error) - nandfs_warning("%s: cannot flush buffers err:%d\n", - __func__, error); - - return (error); -} - -void -nandfs_bdflush(bo, bp) - struct bufobj *bo; - struct buf *bp; -{ - struct vnode *vp; - int error; - - if (bo->bo_dirty.bv_cnt <= ((dirtybufthresh * 8) / 10)) - return; - - vp = bp->b_vp; - if (NANDFS_SYS_NODE(VTON(vp)->nn_ino)) - return; - - if (NANDFS_IS_INDIRECT(bp)) - return; - - error = nandfs_sync_file(vp); - if (error) - nandfs_warning("%s: cannot flush buffers err:%d\n", - __func__, error); -} - -int -nandfs_init(struct vfsconf *vfsp) -{ - - nandfs_node_zone = uma_zcreate("nandfs node zone", - sizeof(struct nandfs_node), NULL, NULL, NULL, NULL, 0, 0); - - return (0); -} - -int -nandfs_uninit(struct vfsconf *vfsp) -{ - - uma_zdestroy(nandfs_node_zone); - return (0); -} - -/* Basic calculators */ -uint64_t -nandfs_get_segnum_of_block(struct nandfs_device *nandfsdev, - nandfs_daddr_t blocknr) -{ - uint64_t segnum, blks_per_seg; - - MPASS(blocknr >= nandfsdev->nd_fsdata.f_first_data_block); - - blks_per_seg = nandfsdev->nd_fsdata.f_blocks_per_segment; - - segnum = blocknr / blks_per_seg; - segnum -= nandfsdev->nd_fsdata.f_first_data_block / blks_per_seg; - - DPRINTF(SYNC, ("%s: returning blocknr %jx -> segnum %jx\n", __func__, - blocknr, segnum)); - - return (segnum); -} - -void -nandfs_get_segment_range(struct nandfs_device *nandfsdev, uint64_t segnum, - uint64_t *seg_start, uint64_t *seg_end) -{ - uint64_t blks_per_seg; - - blks_per_seg = nandfsdev->nd_fsdata.f_blocks_per_segment; - *seg_start = nandfsdev->nd_fsdata.f_first_data_block + - blks_per_seg * segnum; - if (seg_end != NULL) - *seg_end = *seg_start + blks_per_seg -1; -} - -void nandfs_calc_mdt_consts(struct nandfs_device *nandfsdev, - struct nandfs_mdt *mdt, int entry_size) -{ - uint32_t blocksize = nandfsdev->nd_blocksize; - - mdt->entries_per_group = blocksize * 8; - mdt->entries_per_block = blocksize / entry_size; - - mdt->blocks_per_group = - (mdt->entries_per_group -1) / mdt->entries_per_block + 1 + 1; - mdt->groups_per_desc_block = - blocksize / sizeof(struct nandfs_block_group_desc); - mdt->blocks_per_desc_block = - mdt->groups_per_desc_block * mdt->blocks_per_group + 1; -} - -int -nandfs_dev_bread(struct nandfs_device *nandfsdev, nandfs_lbn_t blocknr, - struct ucred *cred, int flags, struct buf **bpp) -{ - int blk2dev = nandfsdev->nd_blocksize / DEV_BSIZE; - int error; - - DPRINTF(BLOCK, ("%s: read from block %jx vp %p\n", __func__, - blocknr * blk2dev, nandfsdev->nd_devvp)); - error = bread(nandfsdev->nd_devvp, blocknr * blk2dev, - nandfsdev->nd_blocksize, NOCRED, bpp); - if (error) - nandfs_error("%s: cannot read from device - blk:%jx\n", - __func__, blocknr); - return (error); -} - -/* Read on a node */ -int -nandfs_bread(struct nandfs_node *node, nandfs_lbn_t blocknr, - struct ucred *cred, int flags, struct buf **bpp) -{ - nandfs_daddr_t vblk; - int error; - - DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node), - blocknr)); - - error = bread(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize, - cred, bpp); - - KASSERT(error == 0, ("%s: vp:%p lbn:%#jx err:%d\n", __func__, - NTOV(node), blocknr, error)); - - if (!nandfs_vblk_get(*bpp) && - ((*bpp)->b_flags & B_CACHE) && node->nn_ino != NANDFS_DAT_INO) { - nandfs_bmap_lookup(node, blocknr, &vblk); - nandfs_vblk_set(*bpp, vblk); - } - return (error); -} - -int -nandfs_bread_meta(struct nandfs_node *node, nandfs_lbn_t blocknr, - struct ucred *cred, int flags, struct buf **bpp) -{ - nandfs_daddr_t vblk; - int error; - - DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node), - blocknr)); - - error = bread(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize, - cred, bpp); - - KASSERT(error == 0, ("%s: vp:%p lbn:%#jx err:%d\n", __func__, - NTOV(node), blocknr, error)); - - if (!nandfs_vblk_get(*bpp) && - ((*bpp)->b_flags & B_CACHE) && node->nn_ino != NANDFS_DAT_INO) { - nandfs_bmap_lookup(node, blocknr, &vblk); - nandfs_vblk_set(*bpp, vblk); - } - - return (error); -} - -int -nandfs_bdestroy(struct nandfs_node *node, nandfs_daddr_t vblk) -{ - int error; - - if (!NANDFS_SYS_NODE(node->nn_ino)) - NANDFS_WRITEASSERT(node->nn_nandfsdev); - - error = nandfs_vblock_end(node->nn_nandfsdev, vblk); - if (error) { - nandfs_error("%s: ending vblk: %jx failed\n", - __func__, (uintmax_t)vblk); - return (error); - } - node->nn_inode.i_blocks--; - - return (0); -} - -int -nandfs_bcreate(struct nandfs_node *node, nandfs_lbn_t blocknr, - struct ucred *cred, int flags, struct buf **bpp) -{ - int error; - - ASSERT_VOP_LOCKED(NTOV(node), __func__); - if (!NANDFS_SYS_NODE(node->nn_ino)) - NANDFS_WRITEASSERT(node->nn_nandfsdev); - - DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node), - blocknr)); - - *bpp = getblk(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize, - 0, 0, 0); - - KASSERT((*bpp), ("%s: vp:%p lbn:%#jx\n", __func__, - NTOV(node), blocknr)); - - if (*bpp) { - vfs_bio_clrbuf(*bpp); - (*bpp)->b_blkno = ~(0); /* To avoid VOP_BMAP in bdwrite */ - error = nandfs_bmap_insert_block(node, blocknr, *bpp); - if (error) { - nandfs_warning("%s: failed bmap insert node:%p" - " blk:%jx\n", __func__, node, blocknr); - brelse(*bpp); - return (error); - } - node->nn_inode.i_blocks++; - - return (0); - } - - return (-1); -} - -int -nandfs_bcreate_meta(struct nandfs_node *node, nandfs_lbn_t blocknr, - struct ucred *cred, int flags, struct buf **bpp) -{ - struct nandfs_device *fsdev; - nandfs_daddr_t vblk; - int error; - - ASSERT_VOP_LOCKED(NTOV(node), __func__); - NANDFS_WRITEASSERT(node->nn_nandfsdev); - - DPRINTF(BLOCK, ("%s: vp:%p lbn:%#jx\n", __func__, NTOV(node), - blocknr)); - - fsdev = node->nn_nandfsdev; - - *bpp = getblk(NTOV(node), blocknr, node->nn_nandfsdev->nd_blocksize, - 0, 0, 0); - - KASSERT((*bpp), ("%s: vp:%p lbn:%#jx\n", __func__, - NTOV(node), blocknr)); - - memset((*bpp)->b_data, 0, fsdev->nd_blocksize); - - vfs_bio_clrbuf(*bpp); - (*bpp)->b_blkno = ~(0); /* To avoid VOP_BMAP in bdwrite */ - - nandfs_buf_set(*bpp, NANDFS_VBLK_ASSIGNED); - - if (node->nn_ino != NANDFS_DAT_INO) { - error = nandfs_vblock_alloc(fsdev, &vblk); - if (error) { - nandfs_buf_clear(*bpp, NANDFS_VBLK_ASSIGNED); - brelse(*bpp); - return (error); - } - } else - vblk = fsdev->nd_fakevblk++; - - nandfs_vblk_set(*bpp, vblk); - - nandfs_bmap_insert_block(node, blocknr, *bpp); - return (0); -} - -/* Translate index to a file block number and an entry */ -void -nandfs_mdt_trans(struct nandfs_mdt *mdt, uint64_t index, - nandfs_lbn_t *blocknr, uint32_t *entry_in_block) -{ - uint64_t blknr; - uint64_t group, group_offset, blocknr_in_group; - uint64_t desc_block, desc_offset; - - /* Calculate our offset in the file */ - group = index / mdt->entries_per_group; - group_offset = index % mdt->entries_per_group; - desc_block = group / mdt->groups_per_desc_block; - desc_offset = group % mdt->groups_per_desc_block; - blocknr_in_group = group_offset / mdt->entries_per_block; - - /* To descgroup offset */ - blknr = 1 + desc_block * mdt->blocks_per_desc_block; - - /* To group offset */ - blknr += desc_offset * mdt->blocks_per_group; - - /* To actual file block */ - blknr += 1 + blocknr_in_group; - - *blocknr = blknr; - *entry_in_block = group_offset % mdt->entries_per_block; -} - -void -nandfs_mdt_trans_blk(struct nandfs_mdt *mdt, uint64_t index, - uint64_t *desc, uint64_t *bitmap, nandfs_lbn_t *blocknr, - uint32_t *entry_in_block) -{ - uint64_t blknr; - uint64_t group, group_offset, blocknr_in_group; - uint64_t desc_block, desc_offset; - - /* Calculate our offset in the file */ - group = index / mdt->entries_per_group; - group_offset = index % mdt->entries_per_group; - desc_block = group / mdt->groups_per_desc_block; - desc_offset = group % mdt->groups_per_desc_block; - blocknr_in_group = group_offset / mdt->entries_per_block; - - /* To descgroup offset */ - *desc = desc_block * mdt->blocks_per_desc_block; - blknr = 1 + desc_block * mdt->blocks_per_desc_block; - - /* To group offset */ - blknr += desc_offset * mdt->blocks_per_group; - *bitmap = blknr; - - /* To actual file block */ - blknr += 1 + blocknr_in_group; - - *blocknr = blknr; - *entry_in_block = group_offset % mdt->entries_per_block; - - DPRINTF(ALLOC, - ("%s: desc_buf: %jx bitmap_buf: %jx entry_buf: %jx entry: %x\n", - __func__, (uintmax_t)*desc, (uintmax_t)*bitmap, - (uintmax_t)*blocknr, *entry_in_block)); -} - -int -nandfs_vtop(struct nandfs_node *node, nandfs_daddr_t vblocknr, - nandfs_daddr_t *pblocknr) -{ - struct nandfs_node *dat_node; - struct nandfs_dat_entry *entry; - struct buf *bp; - nandfs_lbn_t ldatblknr; - uint32_t entry_in_block; - int locked, error; - - if (node->nn_ino == NANDFS_DAT_INO || node->nn_ino == NANDFS_GC_INO) { - *pblocknr = vblocknr; - return (0); - } - - /* only translate valid vblocknrs */ - if (vblocknr == 0) - return (0); - - dat_node = node->nn_nandfsdev->nd_dat_node; - nandfs_mdt_trans(&node->nn_nandfsdev->nd_dat_mdt, vblocknr, &ldatblknr, - &entry_in_block); - - locked = NANDFS_VOP_ISLOCKED(NTOV(dat_node)); - if (!locked) - VOP_LOCK(NTOV(dat_node), LK_SHARED); - error = nandfs_bread(dat_node, ldatblknr, NOCRED, 0, &bp); - if (error) { - DPRINTF(TRANSLATE, ("vtop: can't read in DAT block %#jx!\n", - (uintmax_t)ldatblknr)); - brelse(bp); - VOP_UNLOCK(NTOV(dat_node), 0); - return (error); - } - - /* Get our translation */ - entry = ((struct nandfs_dat_entry *) bp->b_data) + entry_in_block; - DPRINTF(TRANSLATE, ("\tentry %p data %p entry_in_block %x\n", - entry, bp->b_data, entry_in_block)) - DPRINTF(TRANSLATE, ("\tvblk %#jx -> %#jx for cp [%#jx-%#jx]\n", - (uintmax_t)vblocknr, (uintmax_t)entry->de_blocknr, - (uintmax_t)entry->de_start, (uintmax_t)entry->de_end)); - - *pblocknr = entry->de_blocknr; - brelse(bp); - if (!locked) - VOP_UNLOCK(NTOV(dat_node), 0); - - MPASS(*pblocknr >= node->nn_nandfsdev->nd_fsdata.f_first_data_block || - *pblocknr == 0); - - return (0); -} - -int -nandfs_segsum_valid(struct nandfs_segment_summary *segsum) -{ - - return (segsum->ss_magic == NANDFS_SEGSUM_MAGIC); -} - -int -nandfs_load_segsum(struct nandfs_device *fsdev, nandfs_daddr_t blocknr, - struct nandfs_segment_summary *segsum) -{ - struct buf *bp; - int error; - - DPRINTF(VOLUMES, ("nandfs: try segsum at block %jx\n", - (uintmax_t)blocknr)); - - error = nandfs_dev_bread(fsdev, blocknr, NOCRED, 0, &bp); - if (error) - return (error); - - memcpy(segsum, bp->b_data, sizeof(struct nandfs_segment_summary)); - brelse(bp); - - if (!nandfs_segsum_valid(segsum)) { - DPRINTF(VOLUMES, ("%s: bad magic pseg:%jx\n", __func__, - blocknr)); - return (EINVAL); - } - - return (error); -} - -static int -nandfs_load_super_root(struct nandfs_device *nandfsdev, - struct nandfs_segment_summary *segsum, uint64_t pseg) -{ - struct nandfs_super_root super_root; - struct buf *bp; - uint64_t blocknr; - uint32_t super_root_crc, comp_crc; - int off, error; - - /* Check if there is a superroot */ - if ((segsum->ss_flags & NANDFS_SS_SR) == 0) { - DPRINTF(VOLUMES, ("%s: no super root in pseg:%jx\n", __func__, - pseg)); - return (ENOENT); - } - - /* Get our super root, located at the end of the pseg */ - blocknr = pseg + segsum->ss_nblocks - 1; - DPRINTF(VOLUMES, ("%s: try at %#jx\n", __func__, (uintmax_t)blocknr)); - - error = nandfs_dev_bread(nandfsdev, blocknr, NOCRED, 0, &bp); - if (error) - return (error); - - memcpy(&super_root, bp->b_data, sizeof(struct nandfs_super_root)); - brelse(bp); - - /* Check super root CRC */ - super_root_crc = super_root.sr_sum; - off = sizeof(super_root.sr_sum); - comp_crc = crc32((uint8_t *)&super_root + off, - NANDFS_SR_BYTES - off); - - if (super_root_crc != comp_crc) { - DPRINTF(VOLUMES, ("%s: invalid crc:%#x [expect:%#x]\n", - __func__, super_root_crc, comp_crc)); - return (EINVAL); - } - - nandfsdev->nd_super_root = super_root; - DPRINTF(VOLUMES, ("%s: got valid superroot\n", __func__)); - - return (0); -} - -/* - * Search for the last super root recorded. - */ -int -nandfs_search_super_root(struct nandfs_device *nandfsdev) -{ - struct nandfs_super_block *super; - struct nandfs_segment_summary segsum; - uint64_t seg_start, seg_end, cno, seq, create, pseg; - uint64_t segnum; - int error, found; - - error = found = 0; - - /* Search for last super root */ - pseg = nandfsdev->nd_super.s_last_pseg; - segnum = nandfs_get_segnum_of_block(nandfsdev, pseg); - - cno = nandfsdev->nd_super.s_last_cno; - create = seq = 0; - DPRINTF(VOLUMES, ("%s: start in pseg %#jx\n", __func__, - (uintmax_t)pseg)); - - for (;;) { - error = nandfs_load_segsum(nandfsdev, pseg, &segsum); - if (error) - break; - - if (segsum.ss_seq < seq || segsum.ss_create < create) - break; - - /* Try to load super root */ - if (segsum.ss_flags & NANDFS_SS_SR) { - error = nandfs_load_super_root(nandfsdev, &segsum, pseg); - if (error) - break; /* confused */ - found = 1; - - super = &nandfsdev->nd_super; - nandfsdev->nd_last_segsum = segsum; - super->s_last_pseg = pseg; - super->s_last_cno = cno++; - super->s_last_seq = segsum.ss_seq; - super->s_state = NANDFS_VALID_FS; - seq = segsum.ss_seq; - create = segsum.ss_create; - } else { - seq = segsum.ss_seq; - create = segsum.ss_create; - } - - /* Calculate next partial segment location */ - pseg += segsum.ss_nblocks; - DPRINTF(VOLUMES, ("%s: next partial seg is %jx\n", __func__, - (uintmax_t)pseg)); - - /* Did we reach the end of the segment? if so, go to the next */ - nandfs_get_segment_range(nandfsdev, segnum, &seg_start, - &seg_end); - if (pseg >= seg_end) { - pseg = segsum.ss_next; - DPRINTF(VOLUMES, - (" partial seg oor next is %jx[%jx - %jx]\n", - (uintmax_t)pseg, (uintmax_t)seg_start, - (uintmax_t)seg_end)); - } - segnum = nandfs_get_segnum_of_block(nandfsdev, pseg); - } - - if (error && !found) - return (error); - - return (0); -} - -int -nandfs_get_node_raw(struct nandfs_device *nandfsdev, struct nandfsmount *nmp, - uint64_t ino, struct nandfs_inode *inode, struct nandfs_node **nodep) -{ - struct nandfs_node *node; - struct vnode *nvp; - struct mount *mp; - int error; - - *nodep = NULL; - - /* Associate with mountpoint if present */ - if (nmp) { - mp = nmp->nm_vfs_mountp; - error = getnewvnode("nandfs", mp, &nandfs_vnodeops, &nvp); - if (error) - return (error); - } else { - mp = NULL; - error = getnewvnode("snandfs", mp, &nandfs_system_vnodeops, - &nvp); - if (error) - return (error); - } - - if (mp) - NANDFS_WRITELOCK(nandfsdev); - - DPRINTF(IFILE, ("%s: ino: %#jx -> vp: %p\n", - __func__, (uintmax_t)ino, nvp)); - /* Lock node */ - lockmgr(nvp->v_vnlock, LK_EXCLUSIVE, NULL); - - if (mp) { - error = insmntque(nvp, mp); - if (error != 0) { - *nodep = NULL; - return (error); - } - } - - node = uma_zalloc(nandfs_node_zone, M_WAITOK | M_ZERO); - - /* Crosslink */ - node->nn_vnode = nvp; - nvp->v_bufobj.bo_ops = &buf_ops_nandfs; - node->nn_nmp = nmp; - node->nn_nandfsdev = nandfsdev; - nvp->v_data = node; - - /* Initiase NANDFS node */ - node->nn_ino = ino; - if (inode != NULL) - node->nn_inode = *inode; - - nandfs_vinit(nvp, ino); - - /* Return node */ - *nodep = node; - DPRINTF(IFILE, ("%s: ino:%#jx vp:%p node:%p\n", - __func__, (uintmax_t)ino, nvp, *nodep)); - - return (0); -} - -int -nandfs_get_node(struct nandfsmount *nmp, uint64_t ino, - struct nandfs_node **nodep) -{ - struct nandfs_device *nandfsdev; - struct nandfs_inode inode, *entry; - struct vnode *nvp, *vpp; - struct thread *td; - struct buf *bp; - uint64_t ivblocknr; - uint32_t entry_in_block; - int error; - - /* Look up node in hash table */ - td = curthread; - *nodep = NULL; - - if ((ino < NANDFS_ATIME_INO) && (ino != NANDFS_ROOT_INO)) { - printf("nandfs_get_node: system ino %"PRIu64" not in mount " - "point!\n", ino); - return (ENOENT); - } - - error = vfs_hash_get(nmp->nm_vfs_mountp, ino, LK_EXCLUSIVE, td, &nvp, - NULL, NULL); - if (error) - return (error); - - if (nvp != NULL) { - *nodep = (struct nandfs_node *)nvp->v_data; - return (0); - } - - /* Look up inode structure in mountpoints ifile */ - nandfsdev = nmp->nm_nandfsdev; - nandfs_mdt_trans(&nandfsdev->nd_ifile_mdt, ino, &ivblocknr, - &entry_in_block); - - VOP_LOCK(NTOV(nmp->nm_ifile_node), LK_SHARED); - error = nandfs_bread(nmp->nm_ifile_node, ivblocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - VOP_UNLOCK(NTOV(nmp->nm_ifile_node), 0); - return (ENOENT); - } - - /* Get inode entry */ - entry = (struct nandfs_inode *) bp->b_data + entry_in_block; - memcpy(&inode, entry, sizeof(struct nandfs_inode)); - brelse(bp); - VOP_UNLOCK(NTOV(nmp->nm_ifile_node), 0); - - /* Get node */ - error = nandfs_get_node_raw(nmp->nm_nandfsdev, nmp, ino, &inode, nodep); - if (error) { - *nodep = NULL; - return (error); - } - - nvp = (*nodep)->nn_vnode; - error = vfs_hash_insert(nvp, ino, 0, td, &vpp, NULL, NULL); - if (error) { - *nodep = NULL; - return (error); - } - - return (error); -} - -void -nandfs_dispose_node(struct nandfs_node **nodep) -{ - struct nandfs_node *node; - struct vnode *vp; - - /* Protect against rogue values */ - node = *nodep; - if (!node) { - return; - } - DPRINTF(NODE, ("nandfs_dispose_node: %p\n", *nodep)); - - vp = NTOV(node); - vp->v_data = NULL; - - /* Free our associated memory */ - uma_zfree(nandfs_node_zone, node); - - *nodep = NULL; -} - -int -nandfs_lookup_name_in_dir(struct vnode *dvp, const char *name, int namelen, - uint64_t *ino, int *found, uint64_t *off) -{ - struct nandfs_node *dir_node = VTON(dvp); - struct nandfs_dir_entry *ndirent; - struct buf *bp; - uint64_t file_size, diroffset, blkoff; - uint64_t blocknr; - uint32_t blocksize = dir_node->nn_nandfsdev->nd_blocksize; - uint8_t *pos, name_len; - int error; - - *found = 0; - - DPRINTF(VNCALL, ("%s: %s file\n", __func__, name)); - if (dvp->v_type != VDIR) { - return (ENOTDIR); - } - - /* Get directory filesize */ - file_size = dir_node->nn_inode.i_size; - - /* Walk the directory */ - diroffset = 0; - blocknr = 0; - blkoff = 0; - error = nandfs_bread(dir_node, blocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (EIO); - } - - while (diroffset < file_size) { - if (blkoff >= blocksize) { - blkoff = 0; blocknr++; - brelse(bp); - error = nandfs_bread(dir_node, blocknr, NOCRED, 0, - &bp); - if (error) { - brelse(bp); - return (EIO); - } - } - - /* Read in one dirent */ - pos = (uint8_t *) bp->b_data + blkoff; - ndirent = (struct nandfs_dir_entry *) pos; - name_len = ndirent->name_len; - - if ((name_len == namelen) && - (strncmp(name, ndirent->name, name_len) == 0) && - (ndirent->inode != 0)) { - *ino = ndirent->inode; - *off = diroffset; - DPRINTF(LOOKUP, ("found `%.*s` with ino %"PRIx64"\n", - name_len, ndirent->name, *ino)); - *found = 1; - break; - } - - /* Advance */ - diroffset += ndirent->rec_len; - blkoff += ndirent->rec_len; - } - brelse(bp); - - return (error); -} - -int -nandfs_get_fsinfo(struct nandfsmount *nmp, struct nandfs_fsinfo *fsinfo) -{ - struct nandfs_device *fsdev; - - fsdev = nmp->nm_nandfsdev; - - memcpy(&fsinfo->fs_fsdata, &fsdev->nd_fsdata, sizeof(fsdev->nd_fsdata)); - memcpy(&fsinfo->fs_super, &fsdev->nd_super, sizeof(fsdev->nd_super)); - snprintf(fsinfo->fs_dev, sizeof(fsinfo->fs_dev), - "%s", nmp->nm_vfs_mountp->mnt_stat.f_mntfromname); - - return (0); -} - -void -nandfs_inode_init(struct nandfs_inode *inode, uint16_t mode) -{ - struct timespec ts; - - vfs_timestamp(&ts); - - inode->i_blocks = 0; - inode->i_size = 0; - inode->i_ctime = ts.tv_sec; - inode->i_ctime_nsec = ts.tv_nsec; - inode->i_mtime = ts.tv_sec; - inode->i_mtime_nsec = ts.tv_nsec; - inode->i_mode = mode; - inode->i_links_count = 1; - if (S_ISDIR(mode)) - inode->i_links_count = 2; - inode->i_flags = 0; - - inode->i_special = 0; - memset(inode->i_db, 0, sizeof(inode->i_db)); - memset(inode->i_ib, 0, sizeof(inode->i_ib)); -} - -void -nandfs_inode_destroy(struct nandfs_inode *inode) -{ - - MPASS(inode->i_blocks == 0); - bzero(inode, sizeof(*inode)); -} - -int -nandfs_fs_full(struct nandfs_device *nffsdev) -{ - uint64_t space, bps; - - bps = nffsdev->nd_fsdata.f_blocks_per_segment; - space = (nffsdev->nd_clean_segs - 1) * bps; - - DPRINTF(BUF, ("%s: bufs:%jx space:%jx\n", __func__, - (uintmax_t)nffsdev->nd_dirty_bufs, (uintmax_t)space)); - - if (nffsdev->nd_dirty_bufs + (nffsdev->nd_segs_reserved * bps) >= space) - return (1); - - return (0); -} - -static int -_nandfs_dirty_buf(struct buf *bp, int dirty_meta, int force) -{ - struct nandfs_device *nffsdev; - struct nandfs_node *node; - uint64_t ino, bps; - - if (NANDFS_ISGATHERED(bp)) { - bqrelse(bp); - return (0); - } - if ((bp->b_flags & (B_MANAGED | B_DELWRI)) == (B_MANAGED | B_DELWRI)) { - bqrelse(bp); - return (0); - } - - node = VTON(bp->b_vp); - nffsdev = node->nn_nandfsdev; - DPRINTF(BUF, ("%s: buf:%p\n", __func__, bp)); - ino = node->nn_ino; - - if (nandfs_fs_full(nffsdev) && !NANDFS_SYS_NODE(ino) && !force) { - brelse(bp); - return (ENOSPC); - } - - bp->b_flags |= B_MANAGED; - bdwrite(bp); - - nandfs_dirty_bufs_increment(nffsdev); - - KASSERT((bp->b_vp), ("vp missing for bp")); - KASSERT((nandfs_vblk_get(bp) || ino == NANDFS_DAT_INO), - ("bp vblk is 0")); - - /* - * To maintain consistency of FS we need to force making - * meta buffers dirty, even if free space is low. - */ - if (dirty_meta && ino != NANDFS_GC_INO) - nandfs_bmap_dirty_blocks(VTON(bp->b_vp), bp, 1); - - bps = nffsdev->nd_fsdata.f_blocks_per_segment; - - if (nffsdev->nd_dirty_bufs >= (bps * nandfs_max_dirty_segs)) { - mtx_lock(&nffsdev->nd_sync_mtx); - if (nffsdev->nd_syncing == 0) { - DPRINTF(SYNC, ("%s: wakeup gc\n", __func__)); - nffsdev->nd_syncing = 1; - wakeup(&nffsdev->nd_syncing); - } - mtx_unlock(&nffsdev->nd_sync_mtx); - } - - return (0); -} - -int -nandfs_dirty_buf(struct buf *bp, int force) -{ - - return (_nandfs_dirty_buf(bp, 1, force)); -} - -int -nandfs_dirty_buf_meta(struct buf *bp, int force) -{ - - return (_nandfs_dirty_buf(bp, 0, force)); -} - -void -nandfs_undirty_buf_fsdev(struct nandfs_device *nffsdev, struct buf *bp) -{ - - BUF_ASSERT_HELD(bp); - - if (bp->b_flags & B_DELWRI) { - bp->b_flags &= ~(B_DELWRI|B_MANAGED); - nandfs_dirty_bufs_decrement(nffsdev); - } - /* - * Since it is now being written, we can clear its deferred write flag. - */ - bp->b_flags &= ~B_DEFERRED; - - brelse(bp); -} - -void -nandfs_undirty_buf(struct buf *bp) -{ - struct nandfs_node *node; - - node = VTON(bp->b_vp); - - nandfs_undirty_buf_fsdev(node->nn_nandfsdev, bp); -} - -void -nandfs_vblk_set(struct buf *bp, nandfs_daddr_t blocknr) -{ - - nandfs_daddr_t *vblk = (nandfs_daddr_t *)(&bp->b_fsprivate1); - *vblk = blocknr; -} - -nandfs_daddr_t -nandfs_vblk_get(struct buf *bp) -{ - - nandfs_daddr_t *vblk = (nandfs_daddr_t *)(&bp->b_fsprivate1); - return (*vblk); -} - -void -nandfs_buf_set(struct buf *bp, uint32_t bits) -{ - uintptr_t flags; - - flags = (uintptr_t)bp->b_fsprivate3; - flags |= (uintptr_t)bits; - bp->b_fsprivate3 = (void *)flags; -} - -void -nandfs_buf_clear(struct buf *bp, uint32_t bits) -{ - uintptr_t flags; - - flags = (uintptr_t)bp->b_fsprivate3; - flags &= ~(uintptr_t)bits; - bp->b_fsprivate3 = (void *)flags; -} - -int -nandfs_buf_check(struct buf *bp, uint32_t bits) -{ - uintptr_t flags; - - flags = (uintptr_t)bp->b_fsprivate3; - if (flags & bits) - return (1); - return (0); -} - -int -nandfs_erase(struct nandfs_device *fsdev, off_t offset, size_t size) -{ - DPRINTF(BLOCK, ("%s: performing erase at offset %jx size %zx\n", - __func__, offset, size)); - - MPASS(size % fsdev->nd_erasesize == 0); - - return (g_delete_data(fsdev->nd_gconsumer, offset, size)); -} - -int -nandfs_vop_islocked(struct vnode *vp) -{ - int islocked; - - islocked = VOP_ISLOCKED(vp); - return (islocked == LK_EXCLUSIVE || islocked == LK_SHARED); -} - -nandfs_daddr_t -nandfs_block_to_dblock(struct nandfs_device *fsdev, nandfs_lbn_t block) -{ - - return (btodb(block * fsdev->nd_blocksize)); -} Property changes on: head/sys/fs/nandfs/nandfs_subr.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_alloc.c =================================================================== --- head/sys/fs/nandfs/nandfs_alloc.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_alloc.c (nonexistent) @@ -1,366 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -static void -nandfs_get_desc_block_nr(struct nandfs_mdt *mdt, uint64_t desc, - uint64_t *desc_block) -{ - - *desc_block = desc * mdt->blocks_per_desc_block; -} - -static void -nandfs_get_group_block_nr(struct nandfs_mdt *mdt, uint64_t group, - uint64_t *group_block) -{ - uint64_t desc, group_off; - - desc = group / mdt->groups_per_desc_block; - group_off = group % mdt->groups_per_desc_block; - *group_block = desc * mdt->blocks_per_desc_block + - 1 + group_off * mdt->blocks_per_group; -} - -static void -init_desc_block(struct nandfs_mdt *mdt, uint8_t *block_data) -{ - struct nandfs_block_group_desc *desc; - uint32_t i; - - desc = (struct nandfs_block_group_desc *) block_data; - for (i = 0; i < mdt->groups_per_desc_block; i++) - desc[i].bg_nfrees = mdt->entries_per_group; -} - -int -nandfs_find_free_entry(struct nandfs_mdt *mdt, struct nandfs_node *node, - struct nandfs_alloc_request *req) -{ - nandfs_daddr_t desc, group, maxgroup, maxdesc, pos = 0; - nandfs_daddr_t start_group, start_desc; - nandfs_daddr_t desc_block, group_block; - nandfs_daddr_t file_blocks; - struct nandfs_block_group_desc *descriptors; - struct buf *bp, *bp2; - uint32_t *mask, i, mcount, msize; - int error; - - file_blocks = node->nn_inode.i_blocks; - maxgroup = 0x100000000ull / mdt->entries_per_group; - maxdesc = maxgroup / mdt->groups_per_desc_block; - start_group = req->entrynum / mdt->entries_per_group; - start_desc = start_group / mdt->groups_per_desc_block; - - bp = bp2 = NULL; -restart: - for (desc = start_desc; desc < maxdesc; desc++) { - nandfs_get_desc_block_nr(mdt, desc, &desc_block); - - if (bp) - brelse(bp); - if (desc_block < file_blocks) { - error = nandfs_bread(node, desc_block, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - } else { - error = nandfs_bcreate(node, desc_block, NOCRED, 0, - &bp); - if (error) - return (error); - file_blocks++; - init_desc_block(mdt, bp->b_data); - } - - descriptors = (struct nandfs_block_group_desc *) bp->b_data; - for (group = start_group; group < mdt->groups_per_desc_block; - group++) { - if (descriptors[group].bg_nfrees > 0) { - nandfs_get_group_block_nr(mdt, group, - &group_block); - - if (bp2) - brelse(bp2); - if (group_block < file_blocks) { - error = nandfs_bread(node, group_block, - NOCRED, 0, &bp2); - if (error) { - brelse(bp); - return (error); - } - } else { - error = nandfs_bcreate(node, - group_block, NOCRED, 0, &bp2); - if (error) - return (error); - file_blocks++; - } - mask = (uint32_t *)bp2->b_data; - msize = (sizeof(uint32_t) * __CHAR_BIT); - mcount = mdt->entries_per_group / msize; - for (i = 0; i < mcount; i++) { - if (mask[i] == UINT32_MAX) - continue; - - pos = ffs(~mask[i]) - 1; - pos += (msize * i); - pos += (group * mdt->entries_per_group); - pos += desc * group * - mdt->groups_per_desc_block * - mdt->entries_per_group; - goto found; - } - } - } - start_group = 0; - } - - if (start_desc != 0) { - maxdesc = start_desc; - start_desc = 0; - req->entrynum = 0; - goto restart; - } - - return (ENOENT); - -found: - req->entrynum = pos; - req->bp_desc = bp; - req->bp_bitmap = bp2; - DPRINTF(ALLOC, ("%s: desc: %p bitmap: %p entry: %#jx\n", - __func__, req->bp_desc, req->bp_bitmap, (uintmax_t)pos)); - - return (0); -} - -int -nandfs_find_entry(struct nandfs_mdt* mdt, struct nandfs_node *nnode, - struct nandfs_alloc_request *req) -{ - uint64_t dblock, bblock, eblock; - uint32_t offset; - int error; - - nandfs_mdt_trans_blk(mdt, req->entrynum, &dblock, &bblock, &eblock, - &offset); - - error = nandfs_bread(nnode, dblock, NOCRED, 0, &req->bp_desc); - if (error) { - brelse(req->bp_desc); - return (error); - } - - error = nandfs_bread(nnode, bblock, NOCRED, 0, &req->bp_bitmap); - if (error) { - brelse(req->bp_desc); - brelse(req->bp_bitmap); - return (error); - } - - error = nandfs_bread(nnode, eblock, NOCRED, 0, &req->bp_entry); - if (error) { - brelse(req->bp_desc); - brelse(req->bp_bitmap); - brelse(req->bp_entry); - return (error); - } - - DPRINTF(ALLOC, - ("%s: desc_buf: %p bitmap_buf %p entry_buf %p offset %x\n", - __func__, req->bp_desc, req->bp_bitmap, req->bp_entry, offset)); - - return (0); -} - -static __inline void -nandfs_calc_idx_entry(struct nandfs_mdt* mdt, uint32_t entrynum, - uint64_t *group, uint64_t *bitmap_idx, uint64_t *bitmap_off) -{ - - /* Find group_desc index */ - entrynum = entrynum % - (mdt->entries_per_group * mdt->groups_per_desc_block); - *group = entrynum / mdt->entries_per_group; - /* Find bitmap index and bit offset */ - entrynum = entrynum % mdt->entries_per_group; - *bitmap_idx = entrynum / (sizeof(uint32_t) * __CHAR_BIT); - *bitmap_off = entrynum % (sizeof(uint32_t) * __CHAR_BIT); -} - -int -nandfs_free_entry(struct nandfs_mdt* mdt, struct nandfs_alloc_request *req) -{ - struct nandfs_block_group_desc *descriptors; - uint64_t bitmap_idx, bitmap_off; - uint64_t group; - uint32_t *mask, maskrw; - - nandfs_calc_idx_entry(mdt, req->entrynum, &group, &bitmap_idx, - &bitmap_off); - - DPRINTF(ALLOC, ("nandfs_free_entry: req->entrynum=%jx bitmap_idx=%jx" - " bitmap_off=%jx group=%jx\n", (uintmax_t)req->entrynum, - (uintmax_t)bitmap_idx, (uintmax_t)bitmap_off, (uintmax_t)group)); - - /* Update counter of free entries for group */ - descriptors = (struct nandfs_block_group_desc *) req->bp_desc->b_data; - descriptors[group].bg_nfrees++; - - /* Set bit to indicate that entry is taken */ - mask = (uint32_t *)req->bp_bitmap->b_data; - maskrw = mask[bitmap_idx]; - KASSERT(maskrw & (1 << bitmap_off), ("freeing unallocated vblock")); - maskrw &= ~(1 << bitmap_off); - mask[bitmap_idx] = maskrw; - - /* Make descriptor, bitmap and entry buffer dirty */ - if (nandfs_dirty_buf(req->bp_desc, 0) == 0) { - nandfs_dirty_buf(req->bp_bitmap, 1); - nandfs_dirty_buf(req->bp_entry, 1); - } else { - brelse(req->bp_bitmap); - brelse(req->bp_entry); - return (-1); - } - - return (0); -} - -int -nandfs_alloc_entry(struct nandfs_mdt* mdt, struct nandfs_alloc_request *req) -{ - struct nandfs_block_group_desc *descriptors; - uint64_t bitmap_idx, bitmap_off; - uint64_t group; - uint32_t *mask, maskrw; - - nandfs_calc_idx_entry(mdt, req->entrynum, &group, &bitmap_idx, - &bitmap_off); - - DPRINTF(ALLOC, ("nandfs_alloc_entry: req->entrynum=%jx bitmap_idx=%jx" - " bitmap_off=%jx group=%jx\n", (uintmax_t)req->entrynum, - (uintmax_t)bitmap_idx, (uintmax_t)bitmap_off, (uintmax_t)group)); - - /* Update counter of free entries for group */ - descriptors = (struct nandfs_block_group_desc *) req->bp_desc->b_data; - descriptors[group].bg_nfrees--; - - /* Clear bit to indicate that entry is free */ - mask = (uint32_t *)req->bp_bitmap->b_data; - maskrw = mask[bitmap_idx]; - maskrw |= 1 << bitmap_off; - mask[bitmap_idx] = maskrw; - - /* Make descriptor, bitmap and entry buffer dirty */ - if (nandfs_dirty_buf(req->bp_desc, 0) == 0) { - nandfs_dirty_buf(req->bp_bitmap, 1); - nandfs_dirty_buf(req->bp_entry, 1); - } else { - brelse(req->bp_bitmap); - brelse(req->bp_entry); - return (-1); - } - - return (0); -} - -void -nandfs_abort_entry(struct nandfs_alloc_request *req) -{ - - brelse(req->bp_desc); - brelse(req->bp_bitmap); - brelse(req->bp_entry); -} - -int -nandfs_get_entry_block(struct nandfs_mdt *mdt, struct nandfs_node *node, - struct nandfs_alloc_request *req, uint32_t *entry, int create) -{ - struct buf *bp; - nandfs_lbn_t blocknr; - int error; - - /* Find buffer number for given entry */ - nandfs_mdt_trans(mdt, req->entrynum, &blocknr, entry); - DPRINTF(ALLOC, ("%s: ino %#jx entrynum:%#jx block:%#jx entry:%x\n", - __func__, (uintmax_t)node->nn_ino, (uintmax_t)req->entrynum, - (uintmax_t)blocknr, *entry)); - - /* Read entry block or create if 'create' parameter is not zero */ - bp = NULL; - - if (blocknr < node->nn_inode.i_blocks) - error = nandfs_bread(node, blocknr, NOCRED, 0, &bp); - else if (create) - error = nandfs_bcreate(node, blocknr, NOCRED, 0, &bp); - else - error = E2BIG; - - if (error) { - DPRINTF(ALLOC, ("%s: ino %#jx block %#jx entry %x error %d\n", - __func__, (uintmax_t)node->nn_ino, (uintmax_t)blocknr, - *entry, error)); - if (bp) - brelse(bp); - return (error); - } - - MPASS(nandfs_vblk_get(bp) != 0 || node->nn_ino == NANDFS_DAT_INO); - - req->bp_entry = bp; - return (0); -} Property changes on: head/sys/fs/nandfs/nandfs_alloc.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_subr.h =================================================================== --- head/sys/fs/nandfs/nandfs_subr.h (revision 349351) +++ head/sys/fs/nandfs/nandfs_subr.h (nonexistent) @@ -1,240 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_subr.h,v 1.1 2009/07/18 16:31:42 reinoud - * - * $FreeBSD$ - */ - -#ifndef _FS_NANDFS_NANDFS_SUBR_H_ -#define _FS_NANDFS_NANDFS_SUBR_H_ - -struct nandfs_mdt; - -struct nandfs_alloc_request -{ - uint64_t entrynum; - struct buf *bp_desc; - struct buf *bp_bitmap; - struct buf *bp_entry; -}; - -/* Segment creation */ -void nandfs_wakeup_wait_sync(struct nandfs_device *, int); -int nandfs_segment_constructor(struct nandfsmount *, int); -int nandfs_sync_file(struct vnode *); - -/* Basic calculators */ -uint64_t nandfs_get_segnum_of_block(struct nandfs_device *, nandfs_daddr_t); -void nandfs_get_segment_range(struct nandfs_device *, uint64_t, uint64_t *, - uint64_t *); -void nandfs_calc_mdt_consts(struct nandfs_device *, struct nandfs_mdt *, int); - -/* Log reading / volume helpers */ -int nandfs_search_super_root(struct nandfs_device *); - -/* Reading */ -int nandfs_dev_bread(struct nandfs_device *, nandfs_daddr_t, struct ucred *, - int, struct buf **); -int nandfs_bread(struct nandfs_node *, nandfs_lbn_t, struct ucred *, int, - struct buf **); -int nandfs_bread_meta(struct nandfs_node *, nandfs_lbn_t, struct ucred *, int, - struct buf **); -int nandfs_bdestroy(struct nandfs_node *, nandfs_daddr_t); -int nandfs_bcreate(struct nandfs_node *, nandfs_lbn_t, struct ucred *, int, - struct buf **); -int nandfs_bcreate_meta(struct nandfs_node *, nandfs_lbn_t, struct ucred *, - int, struct buf **); -int nandfs_bread_create(struct nandfs_node *, nandfs_lbn_t, struct ucred *, - int, struct buf **); - -/* vtop operations */ -int nandfs_vtop(struct nandfs_node *, nandfs_daddr_t, nandfs_daddr_t *); - -/* Node action implementators */ -int nandfs_vinit(struct vnode *, uint64_t); -int nandfs_get_node(struct nandfsmount *, uint64_t, struct nandfs_node **); -int nandfs_get_node_raw(struct nandfs_device *, struct nandfsmount *, uint64_t, - struct nandfs_inode *, struct nandfs_node **); -void nandfs_dispose_node(struct nandfs_node **); - -void nandfs_itimes(struct vnode *); -int nandfs_lookup_name_in_dir(struct vnode *, const char *, int, uint64_t *, - int *, uint64_t *); -int nandfs_create_node(struct vnode *, struct vnode **, struct vattr *, - struct componentname *); -void nandfs_delete_node(struct nandfs_node *); - -int nandfs_chsize(struct vnode *, u_quad_t, struct ucred *); -int nandfs_dir_detach(struct nandfsmount *, struct nandfs_node *, - struct nandfs_node *, struct componentname *); -int nandfs_dir_attach(struct nandfsmount *, struct nandfs_node *, - struct nandfs_node *, struct vattr *, struct componentname *); - -int nandfs_dirty_buf(struct buf *, int); -int nandfs_dirty_buf_meta(struct buf *, int); -int nandfs_fs_full(struct nandfs_device *); -void nandfs_undirty_buf_fsdev(struct nandfs_device *, struct buf *); -void nandfs_undirty_buf(struct buf *); - -void nandfs_clear_buf(struct buf *); -void nandfs_buf_set(struct buf *, uint32_t); -void nandfs_buf_clear(struct buf *, uint32_t); -int nandfs_buf_check(struct buf *, uint32_t); - -int nandfs_find_free_entry(struct nandfs_mdt *, struct nandfs_node *, - struct nandfs_alloc_request *); -int nandfs_find_entry(struct nandfs_mdt *, struct nandfs_node *, - struct nandfs_alloc_request *); -int nandfs_alloc_entry(struct nandfs_mdt *, struct nandfs_alloc_request *); -void nandfs_abort_entry(struct nandfs_alloc_request *); -int nandfs_free_entry(struct nandfs_mdt *, struct nandfs_alloc_request *); -int nandfs_get_entry_block(struct nandfs_mdt *, struct nandfs_node *, - struct nandfs_alloc_request *, uint32_t *, int); - -/* Inode management. */ -int nandfs_node_create(struct nandfsmount *, struct nandfs_node **, uint16_t); -int nandfs_node_destroy(struct nandfs_node *); -int nandfs_node_update(struct nandfs_node *); -int nandfs_get_node_entry(struct nandfsmount *, struct nandfs_inode **, - uint64_t, struct buf **); -void nandfs_mdt_trans_blk(struct nandfs_mdt *, uint64_t, uint64_t *, - uint64_t *, nandfs_lbn_t *, uint32_t *); - -/* vblock management */ -void nandfs_mdt_trans(struct nandfs_mdt *, uint64_t, nandfs_lbn_t *, uint32_t *); -int nandfs_vblock_alloc(struct nandfs_device *, nandfs_daddr_t *); -int nandfs_vblock_end(struct nandfs_device *, nandfs_daddr_t); -int nandfs_vblock_assign(struct nandfs_device *, nandfs_daddr_t, - nandfs_lbn_t); -int nandfs_vblock_free(struct nandfs_device *, nandfs_daddr_t); - -/* Checkpoint management */ -int nandfs_get_checkpoint(struct nandfs_device *, struct nandfs_node *, - uint64_t); -int nandfs_set_checkpoint(struct nandfs_device *, struct nandfs_node *, - uint64_t, struct nandfs_inode *, uint64_t); - -/* Segment management */ -int nandfs_alloc_segment(struct nandfs_device *, uint64_t *); -int nandfs_update_segment(struct nandfs_device *, uint64_t, uint32_t); -int nandfs_free_segment(struct nandfs_device *, uint64_t); -int nandfs_clear_segment(struct nandfs_device *, uint64_t); -int nandfs_touch_segment(struct nandfs_device *, uint64_t); -int nandfs_markgc_segment(struct nandfs_device *, uint64_t); - -int nandfs_bmap_insert_block(struct nandfs_node *, nandfs_lbn_t, struct buf *); -int nandfs_bmap_update_block(struct nandfs_node *, struct buf *, nandfs_lbn_t); -int nandfs_bmap_update_dat(struct nandfs_node *, nandfs_daddr_t, struct buf *); -int nandfs_bmap_dirty_blocks(struct nandfs_node *, struct buf *, int); -int nandfs_bmap_truncate_mapping(struct nandfs_node *, nandfs_lbn_t, - nandfs_lbn_t); -int nandfs_bmap_lookup(struct nandfs_node *, nandfs_lbn_t, nandfs_daddr_t *); - -/* dirent */ -int nandfs_add_dirent(struct vnode *, uint64_t, char *, long, uint8_t); -int nandfs_remove_dirent(struct vnode *, struct nandfs_node *, - struct componentname *); -int nandfs_update_dirent(struct vnode *, struct nandfs_node *, - struct nandfs_node *); -int nandfs_init_dir(struct vnode *, uint64_t, uint64_t); -int nandfs_update_parent_dir(struct vnode *, uint64_t); - -void nandfs_vblk_set(struct buf *, nandfs_daddr_t); -nandfs_daddr_t nandfs_vblk_get(struct buf *); - -void nandfs_inode_init(struct nandfs_inode *, uint16_t); -void nandfs_inode_destroy(struct nandfs_inode *); - -/* ioctl */ -int nandfs_get_seg_stat(struct nandfs_device *, struct nandfs_seg_stat *); -int nandfs_chng_cpmode(struct nandfs_node *, struct nandfs_cpmode *); -int nandfs_get_cpinfo_ioctl(struct nandfs_node *, struct nandfs_argv *); -int nandfs_delete_cp(struct nandfs_node *, uint64_t start, uint64_t); -int nandfs_make_snap(struct nandfs_device *, uint64_t *); -int nandfs_delete_snap(struct nandfs_device *, uint64_t); -int nandfs_get_cpstat(struct nandfs_node *, struct nandfs_cpstat *); -int nandfs_get_segment_info_ioctl(struct nandfs_device *, struct nandfs_argv *); -int nandfs_get_dat_vinfo_ioctl(struct nandfs_device *, struct nandfs_argv *); -int nandfs_get_dat_bdescs_ioctl(struct nandfs_device *, struct nandfs_argv *); -int nandfs_get_fsinfo(struct nandfsmount *, struct nandfs_fsinfo *); - -int nandfs_get_cpinfo(struct nandfs_node *, uint64_t, uint16_t, - struct nandfs_cpinfo *, uint32_t, uint32_t *); - -nandfs_lbn_t nandfs_get_maxfilesize(struct nandfs_device *); - -int nandfs_write_superblock(struct nandfs_device *); - -extern int nandfs_sync_interval; -extern int nandfs_max_dirty_segs; -extern int nandfs_cps_between_sblocks; - -struct buf *nandfs_geteblk(int, int); - -void nandfs_dirty_bufs_increment(struct nandfs_device *); -void nandfs_dirty_bufs_decrement(struct nandfs_device *); - -int nandfs_start_cleaner(struct nandfs_device *); -int nandfs_stop_cleaner(struct nandfs_device *); - -int nandfs_segsum_valid(struct nandfs_segment_summary *); -int nandfs_load_segsum(struct nandfs_device *, nandfs_daddr_t, - struct nandfs_segment_summary *); -int nandfs_get_segment_info(struct nandfs_device *, struct nandfs_suinfo *, - uint32_t, uint64_t); -int nandfs_get_segment_info_filter(struct nandfs_device *, - struct nandfs_suinfo *, uint32_t, uint64_t, uint64_t *, uint32_t, uint32_t); -int nandfs_get_dat_vinfo(struct nandfs_device *, struct nandfs_vinfo *, - uint32_t); -int nandfs_get_dat_bdescs(struct nandfs_device *, struct nandfs_bdesc *, - uint32_t); - -#define NANDFS_VBLK_ASSIGNED 1 - -#define NANDFS_IS_INDIRECT(bp) ((bp)->b_lblkno < 0) - -int nandfs_erase(struct nandfs_device *, off_t, size_t); - -#define NANDFS_VOP_ISLOCKED(vp) nandfs_vop_islocked((vp)) -int nandfs_vop_islocked(struct vnode *vp); - -nandfs_daddr_t nandfs_block_to_dblock(struct nandfs_device *, nandfs_lbn_t); - -#define DEBUG_MODE -#if defined(DEBUG_MODE) -#define nandfs_error panic -#define nandfs_warning printf -#elif defined(TEST_MODE) -#define nandfs_error printf -#define nandfs_warning printf -#else -#define nandfs_error(...) -#define nandfs_warning(...) -#endif - -#endif /* !_FS_NANDFS_NANDFS_SUBR_H_ */ Property changes on: head/sys/fs/nandfs/nandfs_subr.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_vnops.c =================================================================== --- head/sys/fs/nandfs/nandfs_vnops.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_vnops.c (nonexistent) @@ -1,2454 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_vnops.c,v 1.2 2009/08/26 03:40:48 elad - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include - -extern uma_zone_t nandfs_node_zone; -static void nandfs_read_filebuf(struct nandfs_node *, struct buf *); -static void nandfs_itimes_locked(struct vnode *); -static int nandfs_truncate(struct vnode *, uint64_t); - -static vop_pathconf_t nandfs_pathconf; - -#define UPDATE_CLOSE 0 -#define UPDATE_WAIT 0 - -static int -nandfs_inactive(struct vop_inactive_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - int error = 0; - - DPRINTF(VNCALL, ("%s: vp:%p node:%p\n", __func__, vp, node)); - - if (node == NULL) { - DPRINTF(NODE, ("%s: inactive NULL node\n", __func__)); - return (0); - } - - if (node->nn_inode.i_mode != 0 && !(node->nn_inode.i_links_count)) { - nandfs_truncate(vp, 0); - error = nandfs_node_destroy(node); - if (error) - nandfs_error("%s: destroy node: %p\n", __func__, node); - node->nn_flags = 0; - vrecycle(vp); - } - - return (error); -} - -static int -nandfs_reclaim(struct vop_reclaim_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *nandfs_node = VTON(vp); - struct nandfs_device *fsdev = nandfs_node->nn_nandfsdev; - uint64_t ino = nandfs_node->nn_ino; - - DPRINTF(VNCALL, ("%s: vp:%p node:%p\n", __func__, vp, nandfs_node)); - - /* Invalidate all entries to a particular vnode. */ - cache_purge(vp); - - /* Destroy the vm object and flush associated pages. */ - vnode_destroy_vobject(vp); - - /* Remove from vfs hash if not system vnode */ - if (!NANDFS_SYS_NODE(nandfs_node->nn_ino)) - vfs_hash_remove(vp); - - /* Dispose all node knowledge */ - nandfs_dispose_node(&nandfs_node); - - if (!NANDFS_SYS_NODE(ino)) - NANDFS_WRITEUNLOCK(fsdev); - - return (0); -} - -static int -nandfs_read(struct vop_read_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - struct nandfs_device *nandfsdev = node->nn_nandfsdev; - struct uio *uio = ap->a_uio; - struct buf *bp; - uint64_t size; - uint32_t blocksize; - off_t bytesinfile; - ssize_t toread, off; - daddr_t lbn; - ssize_t resid; - int error = 0; - - if (uio->uio_resid == 0) - return (0); - - size = node->nn_inode.i_size; - if (uio->uio_offset >= size) - return (0); - - blocksize = nandfsdev->nd_blocksize; - bytesinfile = size - uio->uio_offset; - - resid = omin(uio->uio_resid, bytesinfile); - - while (resid) { - lbn = uio->uio_offset / blocksize; - off = uio->uio_offset & (blocksize - 1); - - toread = omin(resid, blocksize - off); - - DPRINTF(READ, ("nandfs_read bn: 0x%jx toread: 0x%zx (0x%x)\n", - (uintmax_t)lbn, toread, blocksize)); - - error = nandfs_bread(node, lbn, NOCRED, 0, &bp); - if (error) { - brelse(bp); - break; - } - - error = uiomove(bp->b_data + off, toread, uio); - if (error) { - brelse(bp); - break; - } - - brelse(bp); - resid -= toread; - } - - return (error); -} - -static int -nandfs_write(struct vop_write_args *ap) -{ - struct nandfs_device *fsdev; - struct nandfs_node *node; - struct vnode *vp; - struct uio *uio; - struct buf *bp; - uint64_t file_size, vblk; - uint32_t blocksize; - ssize_t towrite, off; - daddr_t lbn; - ssize_t resid; - int error, ioflag, modified; - - vp = ap->a_vp; - uio = ap->a_uio; - ioflag = ap->a_ioflag; - node = VTON(vp); - fsdev = node->nn_nandfsdev; - - if (nandfs_fs_full(fsdev)) - return (ENOSPC); - - DPRINTF(WRITE, ("nandfs_write called %#zx at %#jx\n", - uio->uio_resid, (uintmax_t)uio->uio_offset)); - - if (uio->uio_offset < 0) - return (EINVAL); - if (uio->uio_resid == 0) - return (0); - - blocksize = fsdev->nd_blocksize; - file_size = node->nn_inode.i_size; - - switch (vp->v_type) { - case VREG: - if (ioflag & IO_APPEND) - uio->uio_offset = file_size; - break; - case VDIR: - return (EISDIR); - case VLNK: - break; - default: - panic("%s: bad file type vp: %p", __func__, vp); - } - - /* If explicitly asked to append, uio_offset can be wrong? */ - if (ioflag & IO_APPEND) - uio->uio_offset = file_size; - - resid = uio->uio_resid; - modified = error = 0; - - while (uio->uio_resid) { - lbn = uio->uio_offset / blocksize; - off = uio->uio_offset & (blocksize - 1); - - towrite = omin(uio->uio_resid, blocksize - off); - - DPRINTF(WRITE, ("%s: lbn: 0x%jd toread: 0x%zx (0x%x)\n", - __func__, (uintmax_t)lbn, towrite, blocksize)); - - error = nandfs_bmap_lookup(node, lbn, &vblk); - if (error) - break; - - DPRINTF(WRITE, ("%s: lbn: 0x%jd toread: 0x%zx (0x%x) " - "vblk=%jx\n", __func__, (uintmax_t)lbn, towrite, blocksize, - vblk)); - - if (vblk != 0) - error = nandfs_bread(node, lbn, NOCRED, 0, &bp); - else - error = nandfs_bcreate(node, lbn, NOCRED, 0, &bp); - - DPRINTF(WRITE, ("%s: vp %p bread bp %p lbn %#jx\n", __func__, - vp, bp, (uintmax_t)lbn)); - if (error) { - if (bp) - brelse(bp); - break; - } - - error = uiomove((char *)bp->b_data + off, (int)towrite, uio); - if (error) - break; - - error = nandfs_dirty_buf(bp, 0); - if (error) - break; - - modified++; - } - - /* XXX proper handling when only part of file was properly written */ - if (modified) { - if (resid > uio->uio_resid && ap->a_cred && - ap->a_cred->cr_uid != 0) - node->nn_inode.i_mode &= ~(ISUID | ISGID); - - if (file_size < uio->uio_offset + uio->uio_resid) { - node->nn_inode.i_size = uio->uio_offset + - uio->uio_resid; - node->nn_flags |= IN_CHANGE | IN_UPDATE; - vnode_pager_setsize(vp, uio->uio_offset + - uio->uio_resid); - nandfs_itimes(vp); - } - } - - DPRINTF(WRITE, ("%s: return:%d\n", __func__, error)); - - return (error); -} - -static int -nandfs_lookup(struct vop_cachedlookup_args *ap) -{ - struct vnode *dvp, **vpp; - struct componentname *cnp; - struct ucred *cred; - struct thread *td; - struct nandfs_node *dir_node, *node; - struct nandfsmount *nmp; - uint64_t ino, off; - const char *name; - int namelen, nameiop, islastcn, mounted_ro; - int error, found; - - DPRINTF(VNCALL, ("%s\n", __func__)); - - dvp = ap->a_dvp; - vpp = ap->a_vpp; - *vpp = NULL; - - cnp = ap->a_cnp; - cred = cnp->cn_cred; - td = cnp->cn_thread; - - dir_node = VTON(dvp); - nmp = dir_node->nn_nmp; - - /* Simplify/clarification flags */ - nameiop = cnp->cn_nameiop; - islastcn = cnp->cn_flags & ISLASTCN; - mounted_ro = dvp->v_mount->mnt_flag & MNT_RDONLY; - - /* - * If requesting a modify on the last path element on a read-only - * filingsystem, reject lookup; - */ - if (islastcn && mounted_ro && (nameiop == DELETE || nameiop == RENAME)) - return (EROFS); - - if (dir_node->nn_inode.i_links_count == 0) - return (ENOENT); - - /* - * Obviously, the file is not (anymore) in the namecache, we have to - * search for it. There are three basic cases: '.', '..' and others. - * - * Following the guidelines of VOP_LOOKUP manpage and tmpfs. - */ - error = 0; - if ((cnp->cn_namelen == 1) && (cnp->cn_nameptr[0] == '.')) { - DPRINTF(LOOKUP, ("\tlookup '.'\n")); - /* Special case 1 '.' */ - VREF(dvp); - *vpp = dvp; - /* Done */ - } else if (cnp->cn_flags & ISDOTDOT) { - /* Special case 2 '..' */ - DPRINTF(LOOKUP, ("\tlookup '..'\n")); - - /* Get our node */ - name = ".."; - namelen = 2; - error = nandfs_lookup_name_in_dir(dvp, name, namelen, &ino, - &found, &off); - if (error) - goto out; - if (!found) - error = ENOENT; - - /* First unlock parent */ - VOP_UNLOCK(dvp, 0); - - if (error == 0) { - DPRINTF(LOOKUP, ("\tfound '..'\n")); - /* Try to create/reuse the node */ - error = nandfs_get_node(nmp, ino, &node); - - if (!error) { - DPRINTF(LOOKUP, - ("\tnode retrieved/created OK\n")); - *vpp = NTOV(node); - } - } - - /* Try to relock parent */ - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - } else { - DPRINTF(LOOKUP, ("\tlookup file\n")); - /* All other files */ - /* Look up filename in the directory returning its inode */ - name = cnp->cn_nameptr; - namelen = cnp->cn_namelen; - error = nandfs_lookup_name_in_dir(dvp, name, namelen, - &ino, &found, &off); - if (error) - goto out; - if (!found) { - DPRINTF(LOOKUP, ("\tNOT found\n")); - /* - * UGH, didn't find name. If we're creating or - * renaming on the last name this is OK and we ought - * to return EJUSTRETURN if its allowed to be created. - */ - error = ENOENT; - if ((nameiop == CREATE || nameiop == RENAME) && - islastcn) { - error = VOP_ACCESS(dvp, VWRITE, cred, td); - if (!error) { - /* keep the component name */ - cnp->cn_flags |= SAVENAME; - error = EJUSTRETURN; - } - } - /* Done */ - } else { - if (ino == NANDFS_WHT_INO) - cnp->cn_flags |= ISWHITEOUT; - - if ((cnp->cn_flags & ISWHITEOUT) && - (nameiop == LOOKUP)) - return (ENOENT); - - if ((nameiop == DELETE) && islastcn) { - if ((cnp->cn_flags & ISWHITEOUT) && - (cnp->cn_flags & DOWHITEOUT)) { - cnp->cn_flags |= SAVENAME; - dir_node->nn_diroff = off; - return (EJUSTRETURN); - } - - error = VOP_ACCESS(dvp, VWRITE, cred, - cnp->cn_thread); - if (error) - return (error); - - /* Try to create/reuse the node */ - error = nandfs_get_node(nmp, ino, &node); - if (!error) { - *vpp = NTOV(node); - node->nn_diroff = off; - } - - if ((dir_node->nn_inode.i_mode & ISVTX) && - cred->cr_uid != 0 && - cred->cr_uid != dir_node->nn_inode.i_uid && - node->nn_inode.i_uid != cred->cr_uid) { - vput(*vpp); - *vpp = NULL; - return (EPERM); - } - } else if ((nameiop == RENAME) && islastcn) { - error = VOP_ACCESS(dvp, VWRITE, cred, - cnp->cn_thread); - if (error) - return (error); - - /* Try to create/reuse the node */ - error = nandfs_get_node(nmp, ino, &node); - if (!error) { - *vpp = NTOV(node); - node->nn_diroff = off; - } - } else { - /* Try to create/reuse the node */ - error = nandfs_get_node(nmp, ino, &node); - if (!error) { - *vpp = NTOV(node); - node->nn_diroff = off; - } - } - } - } - -out: - /* - * Store result in the cache if requested. If we are creating a file, - * the file might not be found and thus putting it into the namecache - * might be seen as negative caching. - */ - if ((cnp->cn_flags & MAKEENTRY) != 0) - cache_enter(dvp, *vpp, cnp); - - return (error); - -} - -static int -nandfs_getattr(struct vop_getattr_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vattr *vap = ap->a_vap; - struct nandfs_node *node = VTON(vp); - struct nandfs_inode *inode = &node->nn_inode; - - DPRINTF(VNCALL, ("%s: vp: %p\n", __func__, vp)); - nandfs_itimes(vp); - - /* Basic info */ - VATTR_NULL(vap); - vap->va_atime.tv_sec = inode->i_mtime; - vap->va_atime.tv_nsec = inode->i_mtime_nsec; - vap->va_mtime.tv_sec = inode->i_mtime; - vap->va_mtime.tv_nsec = inode->i_mtime_nsec; - vap->va_ctime.tv_sec = inode->i_ctime; - vap->va_ctime.tv_nsec = inode->i_ctime_nsec; - vap->va_type = IFTOVT(inode->i_mode); - vap->va_mode = inode->i_mode & ~S_IFMT; - vap->va_nlink = inode->i_links_count; - vap->va_uid = inode->i_uid; - vap->va_gid = inode->i_gid; - vap->va_rdev = inode->i_special; - vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; - vap->va_fileid = node->nn_ino; - vap->va_size = inode->i_size; - vap->va_blocksize = node->nn_nandfsdev->nd_blocksize; - vap->va_gen = 0; - vap->va_flags = inode->i_flags; - vap->va_bytes = inode->i_blocks * vap->va_blocksize; - vap->va_filerev = 0; - vap->va_vaflags = 0; - - return (0); -} - -static int -nandfs_vtruncbuf(struct vnode *vp, uint64_t nblks) -{ - struct nandfs_device *nffsdev; - struct bufobj *bo; - struct buf *bp, *nbp; - - bo = &vp->v_bufobj; - nffsdev = VTON(vp)->nn_nandfsdev; - - ASSERT_VOP_LOCKED(vp, "nandfs_truncate"); -restart: - BO_LOCK(bo); -restart_locked: - TAILQ_FOREACH_SAFE(bp, &bo->bo_clean.bv_hd, b_bobufs, nbp) { - if (bp->b_lblkno < nblks) - continue; - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) - goto restart_locked; - - bremfree(bp); - bp->b_flags |= (B_INVAL | B_RELBUF); - bp->b_flags &= ~(B_ASYNC | B_MANAGED); - BO_UNLOCK(bo); - brelse(bp); - BO_LOCK(bo); - } - - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (bp->b_lblkno < nblks) - continue; - if (BUF_LOCK(bp, - LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, - BO_LOCKPTR(bo)) == ENOLCK) - goto restart; - bp->b_flags |= (B_INVAL | B_RELBUF); - bp->b_flags &= ~(B_ASYNC | B_MANAGED); - brelse(bp); - nandfs_dirty_bufs_decrement(nffsdev); - BO_LOCK(bo); - } - - BO_UNLOCK(bo); - - return (0); -} - -static int -nandfs_truncate(struct vnode *vp, uint64_t newsize) -{ - struct nandfs_device *nffsdev; - struct nandfs_node *node; - struct nandfs_inode *inode; - struct buf *bp = NULL; - uint64_t oblks, nblks, vblk, size, rest; - int error; - - node = VTON(vp); - nffsdev = node->nn_nandfsdev; - inode = &node->nn_inode; - - /* Calculate end of file */ - size = inode->i_size; - - if (newsize == size) { - node->nn_flags |= IN_CHANGE | IN_UPDATE; - nandfs_itimes(vp); - return (0); - } - - if (newsize > size) { - inode->i_size = newsize; - vnode_pager_setsize(vp, newsize); - node->nn_flags |= IN_CHANGE | IN_UPDATE; - nandfs_itimes(vp); - return (0); - } - - nblks = howmany(newsize, nffsdev->nd_blocksize); - oblks = howmany(size, nffsdev->nd_blocksize); - rest = newsize % nffsdev->nd_blocksize; - - if (rest) { - error = nandfs_bmap_lookup(node, nblks - 1, &vblk); - if (error) - return (error); - - if (vblk != 0) - error = nandfs_bread(node, nblks - 1, NOCRED, 0, &bp); - else - error = nandfs_bcreate(node, nblks - 1, NOCRED, 0, &bp); - - if (error) { - if (bp) - brelse(bp); - return (error); - } - - bzero((char *)bp->b_data + rest, - (u_int)(nffsdev->nd_blocksize - rest)); - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - } - - DPRINTF(VNCALL, ("%s: vp %p oblks %jx nblks %jx\n", __func__, vp, oblks, - nblks)); - - error = nandfs_bmap_truncate_mapping(node, oblks - 1, nblks - 1); - if (error) { - if (bp) - nandfs_undirty_buf(bp); - return (error); - } - - error = nandfs_vtruncbuf(vp, nblks); - if (error) { - if (bp) - nandfs_undirty_buf(bp); - return (error); - } - - inode->i_size = newsize; - vnode_pager_setsize(vp, newsize); - node->nn_flags |= IN_CHANGE | IN_UPDATE; - nandfs_itimes(vp); - - return (error); -} - -static void -nandfs_itimes_locked(struct vnode *vp) -{ - struct nandfs_node *node; - struct nandfs_inode *inode; - struct timespec ts; - - ASSERT_VI_LOCKED(vp, __func__); - - node = VTON(vp); - inode = &node->nn_inode; - - if ((node->nn_flags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) == 0) - return; - - if (((vp->v_mount->mnt_kern_flag & - (MNTK_SUSPENDED | MNTK_SUSPEND)) == 0) || - (node->nn_flags & (IN_CHANGE | IN_UPDATE))) - node->nn_flags |= IN_MODIFIED; - - vfs_timestamp(&ts); - if (node->nn_flags & IN_UPDATE) { - inode->i_mtime = ts.tv_sec; - inode->i_mtime_nsec = ts.tv_nsec; - } - if (node->nn_flags & IN_CHANGE) { - inode->i_ctime = ts.tv_sec; - inode->i_ctime_nsec = ts.tv_nsec; - } - - node->nn_flags &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); -} - -void -nandfs_itimes(struct vnode *vp) -{ - - VI_LOCK(vp); - nandfs_itimes_locked(vp); - VI_UNLOCK(vp); -} - -static int -nandfs_chmod(struct vnode *vp, int mode, struct ucred *cred, struct thread *td) -{ - struct nandfs_node *node = VTON(vp); - struct nandfs_inode *inode = &node->nn_inode; - uint16_t nmode; - int error = 0; - - DPRINTF(VNCALL, ("%s: vp %p, mode %x, cred %p, td %p\n", __func__, vp, - mode, cred, td)); - /* - * To modify the permissions on a file, must possess VADMIN - * for that file. - */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) - return (error); - - /* - * Privileged processes may set the sticky bit on non-directories, - * as well as set the setgid bit on a file with a group that the - * process is not a member of. Both of these are allowed in - * jail(8). - */ - if (vp->v_type != VDIR && (mode & S_ISTXT)) { - if (priv_check_cred(cred, PRIV_VFS_STICKYFILE)) - return (EFTYPE); - } - if (!groupmember(inode->i_gid, cred) && (mode & ISGID)) { - error = priv_check_cred(cred, PRIV_VFS_SETGID); - if (error) - return (error); - } - - /* - * Deny setting setuid if we are not the file owner. - */ - if ((mode & ISUID) && inode->i_uid != cred->cr_uid) { - error = priv_check_cred(cred, PRIV_VFS_ADMIN); - if (error) - return (error); - } - - nmode = inode->i_mode; - nmode &= ~ALLPERMS; - nmode |= (mode & ALLPERMS); - inode->i_mode = nmode; - node->nn_flags |= IN_CHANGE; - - DPRINTF(VNCALL, ("%s: to mode %x\n", __func__, nmode)); - - return (error); -} - -static int -nandfs_chown(struct vnode *vp, uid_t uid, gid_t gid, struct ucred *cred, - struct thread *td) -{ - struct nandfs_node *node = VTON(vp); - struct nandfs_inode *inode = &node->nn_inode; - uid_t ouid; - gid_t ogid; - int error = 0; - - if (uid == (uid_t)VNOVAL) - uid = inode->i_uid; - if (gid == (gid_t)VNOVAL) - gid = inode->i_gid; - /* - * To modify the ownership of a file, must possess VADMIN for that - * file. - */ - if ((error = VOP_ACCESSX(vp, VWRITE_OWNER, cred, td))) - return (error); - /* - * To change the owner of a file, or change the group of a file to a - * group of which we are not a member, the caller must have - * privilege. - */ - if (((uid != inode->i_uid && uid != cred->cr_uid) || - (gid != inode->i_gid && !groupmember(gid, cred))) && - (error = priv_check_cred(cred, PRIV_VFS_CHOWN))) - return (error); - ogid = inode->i_gid; - ouid = inode->i_uid; - - inode->i_gid = gid; - inode->i_uid = uid; - - node->nn_flags |= IN_CHANGE; - if ((inode->i_mode & (ISUID | ISGID)) && - (ouid != uid || ogid != gid)) { - if (priv_check_cred(cred, PRIV_VFS_RETAINSUGID)) - inode->i_mode &= ~(ISUID | ISGID); - } - DPRINTF(VNCALL, ("%s: vp %p, cred %p, td %p - ret OK\n", __func__, vp, - cred, td)); - return (0); -} - -static int -nandfs_setattr(struct vop_setattr_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - struct nandfs_inode *inode = &node->nn_inode; - struct vattr *vap = ap->a_vap; - struct ucred *cred = ap->a_cred; - struct thread *td = curthread; - uint32_t flags; - int error = 0; - - if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || - (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || - (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || - (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { - DPRINTF(VNCALL, ("%s: unsettable attribute\n", __func__)); - return (EINVAL); - } - - if (vap->va_flags != VNOVAL) { - DPRINTF(VNCALL, ("%s: vp:%p td:%p flags:%lx\n", __func__, vp, - td, vap->va_flags)); - - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - /* - * Callers may only modify the file flags on objects they - * have VADMIN rights for. - */ - if ((error = VOP_ACCESS(vp, VADMIN, cred, td))) - return (error); - /* - * Unprivileged processes are not permitted to unset system - * flags, or modify flags if any system flags are set. - * Privileged non-jail processes may not modify system flags - * if securelevel > 0 and any existing system flags are set. - * Privileged jail processes behave like privileged non-jail - * processes if the PR_ALLOW_CHFLAGS permission bit is set; - * otherwise, they behave like unprivileged processes. - */ - - flags = inode->i_flags; - if (!priv_check_cred(cred, PRIV_VFS_SYSFLAGS)) { - if (flags & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND)) { - error = securelevel_gt(cred, 0); - if (error) - return (error); - } - /* Snapshot flag cannot be set or cleared */ - if (((vap->va_flags & SF_SNAPSHOT) != 0 && - (flags & SF_SNAPSHOT) == 0) || - ((vap->va_flags & SF_SNAPSHOT) == 0 && - (flags & SF_SNAPSHOT) != 0)) - return (EPERM); - - inode->i_flags = vap->va_flags; - } else { - if (flags & (SF_NOUNLINK | SF_IMMUTABLE | SF_APPEND) || - (vap->va_flags & UF_SETTABLE) != vap->va_flags) - return (EPERM); - - flags &= SF_SETTABLE; - flags |= (vap->va_flags & UF_SETTABLE); - inode->i_flags = flags; - } - node->nn_flags |= IN_CHANGE; - if (vap->va_flags & (IMMUTABLE | APPEND)) - return (0); - } - if (inode->i_flags & (IMMUTABLE | APPEND)) - return (EPERM); - - if (vap->va_size != (u_quad_t)VNOVAL) { - DPRINTF(VNCALL, ("%s: vp:%p td:%p size:%jx\n", __func__, vp, td, - (uintmax_t)vap->va_size)); - - switch (vp->v_type) { - case VDIR: - return (EISDIR); - case VLNK: - case VREG: - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - if ((inode->i_flags & SF_SNAPSHOT) != 0) - return (EPERM); - break; - default: - return (0); - } - - if (vap->va_size > node->nn_nandfsdev->nd_maxfilesize) - return (EFBIG); - - KASSERT((vp->v_type == VREG), ("Set size %d", vp->v_type)); - nandfs_truncate(vp, vap->va_size); - node->nn_flags |= IN_CHANGE; - - return (0); - } - - if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - DPRINTF(VNCALL, ("%s: vp:%p td:%p uid/gid %x/%x\n", __func__, - vp, td, vap->va_uid, vap->va_gid)); - error = nandfs_chown(vp, vap->va_uid, vap->va_gid, cred, td); - if (error) - return (error); - } - - if (vap->va_mode != (mode_t)VNOVAL) { - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - DPRINTF(VNCALL, ("%s: vp:%p td:%p mode %x\n", __func__, vp, td, - vap->va_mode)); - - error = nandfs_chmod(vp, (int)vap->va_mode, cred, td); - if (error) - return (error); - } - if (vap->va_atime.tv_sec != VNOVAL || - vap->va_mtime.tv_sec != VNOVAL || - vap->va_birthtime.tv_sec != VNOVAL) { - DPRINTF(VNCALL, ("%s: vp:%p td:%p time a/m/b %jx/%jx/%jx\n", - __func__, vp, td, (uintmax_t)vap->va_atime.tv_sec, - (uintmax_t)vap->va_mtime.tv_sec, - (uintmax_t)vap->va_birthtime.tv_sec)); - - if (vap->va_atime.tv_sec != VNOVAL) - node->nn_flags |= IN_ACCESS; - if (vap->va_mtime.tv_sec != VNOVAL) - node->nn_flags |= IN_CHANGE | IN_UPDATE; - if (vap->va_birthtime.tv_sec != VNOVAL) - node->nn_flags |= IN_MODIFIED; - nandfs_itimes(vp); - return (0); - } - - return (0); -} - -static int -nandfs_open(struct vop_open_args *ap) -{ - struct nandfs_node *node = VTON(ap->a_vp); - uint64_t filesize; - - DPRINTF(VNCALL, ("nandfs_open called ap->a_mode %x\n", ap->a_mode)); - - if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK) - return (EOPNOTSUPP); - - if ((node->nn_inode.i_flags & APPEND) && - (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE) - return (EPERM); - - filesize = node->nn_inode.i_size; - vnode_create_vobject(ap->a_vp, filesize, ap->a_td); - - return (0); -} - -static int -nandfs_close(struct vop_close_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - - DPRINTF(VNCALL, ("%s: vp %p node %p\n", __func__, vp, node)); - - mtx_lock(&vp->v_interlock); - if (vp->v_usecount > 1) - nandfs_itimes_locked(vp); - mtx_unlock(&vp->v_interlock); - - return (0); -} - -static int -nandfs_check_possible(struct vnode *vp, struct vattr *vap, mode_t mode) -{ - - /* Check if we are allowed to write */ - switch (vap->va_type) { - case VDIR: - case VLNK: - case VREG: - /* - * Normal nodes: check if we're on a read-only mounted - * filingsystem and bomb out if we're trying to write. - */ - if ((mode & VMODIFY_PERMS) && (vp->v_mount->mnt_flag & MNT_RDONLY)) - return (EROFS); - break; - case VBLK: - case VCHR: - case VSOCK: - case VFIFO: - /* - * Special nodes: even on read-only mounted filingsystems - * these are allowed to be written to if permissions allow. - */ - break; - default: - /* No idea what this is */ - return (EINVAL); - } - - /* No one may write immutable files */ - if ((mode & VWRITE) && (VTON(vp)->nn_inode.i_flags & IMMUTABLE)) - return (EPERM); - - return (0); -} - -static int -nandfs_check_permitted(struct vnode *vp, struct vattr *vap, mode_t mode, - struct ucred *cred) -{ - - return (vaccess(vp->v_type, vap->va_mode, vap->va_uid, vap->va_gid, mode, - cred, NULL)); -} - -static int -nandfs_advlock(struct vop_advlock_args *ap) -{ - struct nandfs_node *nvp; - quad_t size; - - nvp = VTON(ap->a_vp); - size = nvp->nn_inode.i_size; - return (lf_advlock(ap, &(nvp->nn_lockf), size)); -} - -static int -nandfs_access(struct vop_access_args *ap) -{ - struct vnode *vp = ap->a_vp; - accmode_t accmode = ap->a_accmode; - struct ucred *cred = ap->a_cred; - struct vattr vap; - int error; - - DPRINTF(VNCALL, ("%s: vp:%p mode: %x\n", __func__, vp, accmode)); - - error = VOP_GETATTR(vp, &vap, NULL); - if (error) - return (error); - - error = nandfs_check_possible(vp, &vap, accmode); - if (error) - return (error); - - error = nandfs_check_permitted(vp, &vap, accmode, cred); - - return (error); -} - -static int -nandfs_print(struct vop_print_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *nvp = VTON(vp); - - printf("\tvp=%p, nandfs_node=%p\n", vp, nvp); - printf("nandfs inode %#jx\n", (uintmax_t)nvp->nn_ino); - printf("flags = 0x%b\n", (u_int)nvp->nn_flags, PRINT_NODE_FLAGS); - - return (0); -} - -static void -nandfs_read_filebuf(struct nandfs_node *node, struct buf *bp) -{ - struct nandfs_device *nandfsdev = node->nn_nandfsdev; - struct buf *nbp; - nandfs_daddr_t vblk, pblk; - nandfs_lbn_t from; - uint32_t blocksize; - int error = 0; - int blk2dev = nandfsdev->nd_blocksize / DEV_BSIZE; - - /* - * Translate all the block sectors into a series of buffers to read - * asynchronously from the nandfs device. Note that this lookup may - * induce readin's too. - */ - - blocksize = nandfsdev->nd_blocksize; - if (bp->b_bcount / blocksize != 1) - panic("invalid b_count in bp %p\n", bp); - - from = bp->b_blkno; - - DPRINTF(READ, ("\tread in from inode %#jx blkno %#jx" - " count %#lx\n", (uintmax_t)node->nn_ino, from, - bp->b_bcount)); - - /* Get virtual block numbers for the vnode's buffer span */ - error = nandfs_bmap_lookup(node, from, &vblk); - if (error) { - bp->b_error = EINVAL; - bp->b_ioflags |= BIO_ERROR; - bufdone(bp); - return; - } - - /* Translate virtual block numbers to physical block numbers */ - error = nandfs_vtop(node, vblk, &pblk); - if (error) { - bp->b_error = EINVAL; - bp->b_ioflags |= BIO_ERROR; - bufdone(bp); - return; - } - - /* Issue translated blocks */ - bp->b_resid = bp->b_bcount; - - /* Note virtual block 0 marks not mapped */ - if (vblk == 0) { - vfs_bio_clrbuf(bp); - bufdone(bp); - return; - } - - nbp = bp; - nbp->b_blkno = pblk * blk2dev; - bp->b_iooffset = dbtob(nbp->b_blkno); - MPASS(bp->b_iooffset >= 0); - BO_STRATEGY(&nandfsdev->nd_devvp->v_bufobj, nbp); - nandfs_vblk_set(bp, vblk); - DPRINTF(READ, ("read_filebuf : ino %#jx blk %#jx -> " - "%#jx -> %#jx [bp %p]\n", (uintmax_t)node->nn_ino, - (uintmax_t)(from), (uintmax_t)vblk, - (uintmax_t)pblk, nbp)); -} - -static void -nandfs_write_filebuf(struct nandfs_node *node, struct buf *bp) -{ - struct nandfs_device *nandfsdev = node->nn_nandfsdev; - - bp->b_iooffset = dbtob(bp->b_blkno); - MPASS(bp->b_iooffset >= 0); - BO_STRATEGY(&nandfsdev->nd_devvp->v_bufobj, bp); -} - -static int -nandfs_strategy(struct vop_strategy_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct buf *bp = ap->a_bp; - struct nandfs_node *node = VTON(vp); - - - /* check if we ought to be here */ - KASSERT((vp->v_type != VBLK && vp->v_type != VCHR), - ("nandfs_strategy on type %d", vp->v_type)); - - /* Translate if needed and pass on */ - if (bp->b_iocmd == BIO_READ) { - nandfs_read_filebuf(node, bp); - return (0); - } - - /* Send to segment collector */ - nandfs_write_filebuf(node, bp); - return (0); -} - -static int -nandfs_readdir(struct vop_readdir_args *ap) -{ - struct uio *uio = ap->a_uio; - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - struct nandfs_dir_entry *ndirent; - struct dirent dirent; - struct buf *bp; - uint64_t file_size, diroffset, transoffset, blkoff; - uint64_t blocknr; - uint32_t blocksize = node->nn_nandfsdev->nd_blocksize; - uint8_t *pos, name_len; - int error; - - DPRINTF(READDIR, ("nandfs_readdir called\n")); - - if (vp->v_type != VDIR) - return (ENOTDIR); - - file_size = node->nn_inode.i_size; - DPRINTF(READDIR, ("nandfs_readdir filesize %jd resid %zd\n", - (uintmax_t)file_size, uio->uio_resid )); - - /* We are called just as long as we keep on pushing data in */ - error = 0; - if ((uio->uio_offset < file_size) && - (uio->uio_resid >= sizeof(struct dirent))) { - diroffset = uio->uio_offset; - transoffset = diroffset; - - blocknr = diroffset / blocksize; - blkoff = diroffset % blocksize; - error = nandfs_bread(node, blocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (EIO); - } - while (diroffset < file_size) { - DPRINTF(READDIR, ("readdir : offset = %"PRIu64"\n", - diroffset)); - if (blkoff >= blocksize) { - blkoff = 0; blocknr++; - brelse(bp); - error = nandfs_bread(node, blocknr, NOCRED, 0, - &bp); - if (error) { - brelse(bp); - return (EIO); - } - } - - /* Read in one dirent */ - pos = (uint8_t *)bp->b_data + blkoff; - ndirent = (struct nandfs_dir_entry *)pos; - - name_len = ndirent->name_len; - memset(&dirent, 0, sizeof(dirent)); - dirent.d_fileno = ndirent->inode; - if (dirent.d_fileno) { - dirent.d_type = ndirent->file_type; - dirent.d_namlen = name_len; - strncpy(dirent.d_name, ndirent->name, name_len); - dirent.d_reclen = GENERIC_DIRSIZ(&dirent); - /* NOTE: d_off is the offset of the *next* entry. */ - dirent.d_off = diroffset + ndirent->rec_len; - dirent_terminate(&dirent); - DPRINTF(READDIR, ("copying `%*.*s`\n", name_len, - name_len, dirent.d_name)); - } - - /* - * If there isn't enough space in the uio to return a - * whole dirent, break off read - */ - if (uio->uio_resid < GENERIC_DIRSIZ(&dirent)) - break; - - /* Transfer */ - if (dirent.d_fileno) - uiomove(&dirent, dirent.d_reclen, uio); - - /* Advance */ - diroffset += ndirent->rec_len; - blkoff += ndirent->rec_len; - - /* Remember the last entry we transferred */ - transoffset = diroffset; - } - brelse(bp); - - /* Pass on last transferred offset */ - uio->uio_offset = transoffset; - } - - if (ap->a_eofflag) - *ap->a_eofflag = (uio->uio_offset >= file_size); - - return (error); -} - -static int -nandfs_dirempty(struct vnode *dvp, uint64_t parentino, struct ucred *cred) -{ - struct nandfs_node *dnode = VTON(dvp); - struct nandfs_dir_entry *dirent; - uint64_t file_size = dnode->nn_inode.i_size; - uint64_t blockcount = dnode->nn_inode.i_blocks; - uint64_t blocknr; - uint32_t blocksize = dnode->nn_nandfsdev->nd_blocksize; - uint32_t limit; - uint32_t off; - uint8_t *pos; - struct buf *bp; - int error; - - DPRINTF(LOOKUP, ("%s: dvp %p parentino %#jx cred %p\n", __func__, dvp, - (uintmax_t)parentino, cred)); - - KASSERT((file_size != 0), ("nandfs_dirempty for NULL dir %p", dvp)); - - blocknr = 0; - while (blocknr < blockcount) { - error = nandfs_bread(dnode, blocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (0); - } - - pos = (uint8_t *)bp->b_data; - off = 0; - - if (blocknr == (blockcount - 1)) - limit = file_size % blocksize; - else - limit = blocksize; - - while (off < limit) { - dirent = (struct nandfs_dir_entry *)(pos + off); - off += dirent->rec_len; - - if (dirent->inode == 0) - continue; - - switch (dirent->name_len) { - case 0: - break; - case 1: - if (dirent->name[0] != '.') - goto notempty; - - KASSERT(dirent->inode == dnode->nn_ino, - (".'s inode does not match dir")); - break; - case 2: - if (dirent->name[0] != '.' && - dirent->name[1] != '.') - goto notempty; - - KASSERT(dirent->inode == parentino, - ("..'s inode does not match parent")); - break; - default: - goto notempty; - } - } - - brelse(bp); - blocknr++; - } - - return (1); -notempty: - brelse(bp); - return (0); -} - -static int -nandfs_link(struct vop_link_args *ap) -{ - struct vnode *tdvp = ap->a_tdvp; - struct vnode *vp = ap->a_vp; - struct componentname *cnp = ap->a_cnp; - struct nandfs_node *node = VTON(vp); - struct nandfs_inode *inode = &node->nn_inode; - int error; - - if (inode->i_links_count >= NANDFS_LINK_MAX) - return (EMLINK); - - if (inode->i_flags & (IMMUTABLE | APPEND)) - return (EPERM); - - /* Update link count */ - inode->i_links_count++; - - /* Add dir entry */ - error = nandfs_add_dirent(tdvp, node->nn_ino, cnp->cn_nameptr, - cnp->cn_namelen, IFTODT(inode->i_mode)); - if (error) { - inode->i_links_count--; - } - - node->nn_flags |= IN_CHANGE; - nandfs_itimes(vp); - DPRINTF(VNCALL, ("%s: tdvp %p vp %p cnp %p\n", - __func__, tdvp, vp, cnp)); - - return (0); -} - -static int -nandfs_create(struct vop_create_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vnode **vpp = ap->a_vpp; - struct componentname *cnp = ap->a_cnp; - uint16_t mode = MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode); - struct nandfs_node *dir_node = VTON(dvp); - struct nandfsmount *nmp = dir_node->nn_nmp; - struct nandfs_node *node; - int error; - - DPRINTF(VNCALL, ("%s: dvp %p\n", __func__, dvp)); - - if (nandfs_fs_full(dir_node->nn_nandfsdev)) - return (ENOSPC); - - /* Create new vnode/inode */ - error = nandfs_node_create(nmp, &node, mode); - if (error) - return (error); - node->nn_inode.i_gid = dir_node->nn_inode.i_gid; - node->nn_inode.i_uid = cnp->cn_cred->cr_uid; - - /* Add new dir entry */ - error = nandfs_add_dirent(dvp, node->nn_ino, cnp->cn_nameptr, - cnp->cn_namelen, IFTODT(mode)); - if (error) { - if (nandfs_node_destroy(node)) { - nandfs_error("%s: error destroying node %p\n", - __func__, node); - } - 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)); - return (0); -} - -static int -nandfs_remove(struct vop_remove_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct nandfs_node *node = VTON(vp); - struct nandfs_node *dnode = VTON(dvp); - struct componentname *cnp = ap->a_cnp; - - DPRINTF(VNCALL, ("%s: dvp %p vp %p nandnode %p ino %#jx link %d\n", - __func__, dvp, vp, node, (uintmax_t)node->nn_ino, - node->nn_inode.i_links_count)); - - if (vp->v_type == VDIR) - return (EISDIR); - - /* Files marked as immutable or append-only cannot be deleted. */ - if ((node->nn_inode.i_flags & (IMMUTABLE | APPEND | NOUNLINK)) || - (dnode->nn_inode.i_flags & APPEND)) - return (EPERM); - - nandfs_remove_dirent(dvp, node, cnp); - node->nn_inode.i_links_count--; - node->nn_flags |= IN_CHANGE; - - return (0); -} - -/* - * Check if source directory is in the path of the target directory. - * Target is supplied locked, source is unlocked. - * The target is always vput before returning. - */ -static int -nandfs_checkpath(struct nandfs_node *src, struct nandfs_node *dest, - struct ucred *cred) -{ - struct vnode *vp; - int error, rootino; - struct nandfs_dir_entry dirent; - - vp = NTOV(dest); - if (src->nn_ino == dest->nn_ino) { - error = EEXIST; - goto out; - } - rootino = NANDFS_ROOT_INO; - error = 0; - if (dest->nn_ino == rootino) - goto out; - - for (;;) { - if (vp->v_type != VDIR) { - error = ENOTDIR; - break; - } - - error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirent, - NANDFS_DIR_REC_LEN(2), (off_t)0, UIO_SYSSPACE, - IO_NODELOCKED | IO_NOMACCHECK, cred, NOCRED, - NULL, NULL); - if (error != 0) - break; - if (dirent.name_len != 2 || - dirent.name[0] != '.' || - dirent.name[1] != '.') { - error = ENOTDIR; - break; - } - if (dirent.inode == src->nn_ino) { - error = EINVAL; - break; - } - if (dirent.inode == rootino) - break; - vput(vp); - if ((error = VFS_VGET(vp->v_mount, dirent.inode, - LK_EXCLUSIVE, &vp)) != 0) { - vp = NULL; - break; - } - } - -out: - if (error == ENOTDIR) - printf("checkpath: .. not a directory\n"); - if (vp != NULL) - vput(vp); - return (error); -} - -static int -nandfs_rename(struct vop_rename_args *ap) -{ - struct vnode *tvp = ap->a_tvp; - struct vnode *tdvp = ap->a_tdvp; - struct vnode *fvp = ap->a_fvp; - struct vnode *fdvp = ap->a_fdvp; - struct componentname *tcnp = ap->a_tcnp; - struct componentname *fcnp = ap->a_fcnp; - int doingdirectory = 0, oldparent = 0, newparent = 0; - int error = 0; - - struct nandfs_node *fdnode, *fnode, *fnode1; - struct nandfs_node *tdnode = VTON(tdvp); - struct nandfs_node *tnode; - - uint32_t tdflags, fflags, fdflags; - uint16_t mode; - - DPRINTF(VNCALL, ("%s: fdvp:%p fvp:%p tdvp:%p tdp:%p\n", __func__, fdvp, - fvp, tdvp, tvp)); - - /* - * Check for cross-device rename. - */ - if ((fvp->v_mount != tdvp->v_mount) || - (tvp && (fvp->v_mount != tvp->v_mount))) { - error = EXDEV; -abortit: - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - vrele(fdvp); - vrele(fvp); - return (error); - } - - tdflags = tdnode->nn_inode.i_flags; - if (tvp && - ((VTON(tvp)->nn_inode.i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || - (tdflags & APPEND))) { - error = EPERM; - goto abortit; - } - - /* - * Renaming a file to itself has no effect. The upper layers should - * not call us in that case. Temporarily just warn if they do. - */ - if (fvp == tvp) { - printf("nandfs_rename: fvp == tvp (can't happen)\n"); - error = 0; - goto abortit; - } - - if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) - goto abortit; - - fdnode = VTON(fdvp); - fnode = VTON(fvp); - - if (fnode->nn_inode.i_links_count >= NANDFS_LINK_MAX) { - VOP_UNLOCK(fvp, 0); - error = EMLINK; - goto abortit; - } - - fflags = fnode->nn_inode.i_flags; - fdflags = fdnode->nn_inode.i_flags; - - if ((fflags & (NOUNLINK | IMMUTABLE | APPEND)) || - (fdflags & APPEND)) { - VOP_UNLOCK(fvp, 0); - error = EPERM; - goto abortit; - } - - mode = fnode->nn_inode.i_mode; - if ((mode & S_IFMT) == S_IFDIR) { - /* - * Avoid ".", "..", and aliases of "." for obvious reasons. - */ - - if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') || - (fdvp == fvp) || - ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT) || - (fnode->nn_flags & IN_RENAME)) { - VOP_UNLOCK(fvp, 0); - error = EINVAL; - goto abortit; - } - fnode->nn_flags |= IN_RENAME; - doingdirectory = 1; - DPRINTF(VNCALL, ("%s: doingdirectory dvp %p\n", __func__, - tdvp)); - oldparent = fdnode->nn_ino; - } - - vrele(fdvp); - - tnode = NULL; - if (tvp) - tnode = VTON(tvp); - - /* - * Bump link count on fvp while we are moving stuff around. If we - * crash before completing the work, the link count may be wrong - * but correctable. - */ - fnode->nn_inode.i_links_count++; - - /* Check for in path moving XXX */ - error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread); - VOP_UNLOCK(fvp, 0); - if (oldparent != tdnode->nn_ino) - newparent = tdnode->nn_ino; - if (doingdirectory && newparent) { - if (error) /* write access check above */ - goto bad; - if (tnode != NULL) - vput(tvp); - - error = nandfs_checkpath(fnode, tdnode, tcnp->cn_cred); - if (error) - goto out; - - VREF(tdvp); - error = relookup(tdvp, &tvp, tcnp); - if (error) - goto out; - vrele(tdvp); - tdnode = VTON(tdvp); - tnode = NULL; - if (tvp) - tnode = VTON(tvp); - } - - /* - * If the target doesn't exist, link the target to the source and - * unlink the source. Otherwise, rewrite the target directory to - * reference the source and remove the original entry. - */ - - if (tvp == NULL) { - /* - * Account for ".." in new directory. - */ - if (doingdirectory && fdvp != tdvp) - tdnode->nn_inode.i_links_count++; - - DPRINTF(VNCALL, ("%s: new entry in dvp:%p\n", __func__, tdvp)); - /* - * Add name in new directory. - */ - error = nandfs_add_dirent(tdvp, fnode->nn_ino, tcnp->cn_nameptr, - tcnp->cn_namelen, IFTODT(fnode->nn_inode.i_mode)); - if (error) { - if (doingdirectory && fdvp != tdvp) - tdnode->nn_inode.i_links_count--; - goto bad; - } - - vput(tdvp); - } else { - /* - * If the parent directory is "sticky", then the user must - * own the parent directory, or the destination of the rename, - * otherwise the destination may not be changed (except by - * root). This implements append-only directories. - */ - if ((tdnode->nn_inode.i_mode & S_ISTXT) && - tcnp->cn_cred->cr_uid != 0 && - tcnp->cn_cred->cr_uid != tdnode->nn_inode.i_uid && - tnode->nn_inode.i_uid != tcnp->cn_cred->cr_uid) { - error = EPERM; - goto bad; - } - /* - * Target must be empty if a directory and have no links - * to it. Also, ensure source and target are compatible - * (both directories, or both not directories). - */ - mode = tnode->nn_inode.i_mode; - if ((mode & S_IFMT) == S_IFDIR) { - if (!nandfs_dirempty(tvp, tdnode->nn_ino, - tcnp->cn_cred)) { - error = ENOTEMPTY; - goto bad; - } - if (!doingdirectory) { - error = ENOTDIR; - goto bad; - } - /* - * Update name cache since directory is going away. - */ - cache_purge(tdvp); - } else if (doingdirectory) { - error = EISDIR; - goto bad; - } - - DPRINTF(VNCALL, ("%s: update entry dvp:%p\n", __func__, tdvp)); - /* - * Change name tcnp in tdvp to point at fvp. - */ - error = nandfs_update_dirent(tdvp, fnode, tnode); - if (error) - goto bad; - - if (doingdirectory && !newparent) - tdnode->nn_inode.i_links_count--; - - vput(tdvp); - - tnode->nn_inode.i_links_count--; - vput(tvp); - tnode = NULL; - } - - /* - * Unlink the source. - */ - fcnp->cn_flags &= ~MODMASK; - fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; - VREF(fdvp); - error = relookup(fdvp, &fvp, fcnp); - if (error == 0) - vrele(fdvp); - if (fvp != NULL) { - fnode1 = VTON(fvp); - fdnode = VTON(fdvp); - } else { - /* - * From name has disappeared. - */ - if (doingdirectory) - panic("nandfs_rename: lost dir entry"); - vrele(ap->a_fvp); - return (0); - } - - DPRINTF(VNCALL, ("%s: unlink source fnode:%p\n", __func__, fnode)); - - /* - * Ensure that the directory entry still exists and has not - * changed while the new name has been entered. If the source is - * a file then the entry may have been unlinked or renamed. In - * either case there is no further work to be done. If the source - * is a directory then it cannot have been rmdir'ed; its link - * count of three would cause a rmdir to fail with ENOTEMPTY. - * The IN_RENAME flag ensures that it cannot be moved by another - * rename. - */ - if (fnode != fnode1) { - if (doingdirectory) - panic("nandfs: lost dir entry"); - } else { - /* - * If the source is a directory with a - * new parent, the link count of the old - * parent directory must be decremented - * and ".." set to point to the new parent. - */ - if (doingdirectory && newparent) { - DPRINTF(VNCALL, ("%s: new parent %#jx -> %#jx\n", - __func__, (uintmax_t) oldparent, - (uintmax_t) newparent)); - error = nandfs_update_parent_dir(fvp, newparent); - if (!error) { - fdnode->nn_inode.i_links_count--; - fdnode->nn_flags |= IN_CHANGE; - } - } - error = nandfs_remove_dirent(fdvp, fnode, fcnp); - if (!error) { - fnode->nn_inode.i_links_count--; - fnode->nn_flags |= IN_CHANGE; - } - fnode->nn_flags &= ~IN_RENAME; - } - if (fdnode) - vput(fdvp); - if (fnode) - vput(fvp); - vrele(ap->a_fvp); - return (error); - -bad: - DPRINTF(VNCALL, ("%s: error:%d\n", __func__, error)); - if (tnode) - vput(NTOV(tnode)); - vput(NTOV(tdnode)); -out: - if (doingdirectory) - fnode->nn_flags &= ~IN_RENAME; - if (vn_lock(fvp, LK_EXCLUSIVE) == 0) { - fnode->nn_inode.i_links_count--; - fnode->nn_flags |= IN_CHANGE; - fnode->nn_flags &= ~IN_RENAME; - vput(fvp); - } else - vrele(fvp); - return (error); -} - -static int -nandfs_mkdir(struct vop_mkdir_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vnode **vpp = ap->a_vpp; - struct componentname *cnp = ap->a_cnp; - struct nandfs_node *dir_node = VTON(dvp); - struct nandfs_inode *dir_inode = &dir_node->nn_inode; - struct nandfs_node *node; - struct nandfsmount *nmp = dir_node->nn_nmp; - uint16_t mode = MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode); - int error; - - DPRINTF(VNCALL, ("%s: dvp %p\n", __func__, dvp)); - - if (nandfs_fs_full(dir_node->nn_nandfsdev)) - return (ENOSPC); - - if (dir_inode->i_links_count >= NANDFS_LINK_MAX) - return (EMLINK); - - error = nandfs_node_create(nmp, &node, mode); - if (error) - return (error); - - node->nn_inode.i_gid = dir_node->nn_inode.i_gid; - node->nn_inode.i_uid = cnp->cn_cred->cr_uid; - - *vpp = NTOV(node); - - error = nandfs_add_dirent(dvp, node->nn_ino, cnp->cn_nameptr, - cnp->cn_namelen, IFTODT(mode)); - if (error) { - vput(*vpp); - return (error); - } - - dir_node->nn_inode.i_links_count++; - dir_node->nn_flags |= IN_CHANGE; - - error = nandfs_init_dir(NTOV(node), node->nn_ino, dir_node->nn_ino); - if (error) { - vput(NTOV(node)); - return (error); - } - - DPRINTF(VNCALL, ("created dir vp %p nandnode %p ino %jx\n", *vpp, node, - (uintmax_t)node->nn_ino)); - return (0); -} - -static int -nandfs_mknod(struct vop_mknod_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vnode **vpp = ap->a_vpp; - struct vattr *vap = ap->a_vap; - uint16_t mode = MAKEIMODE(vap->va_type, vap->va_mode); - struct componentname *cnp = ap->a_cnp; - struct nandfs_node *dir_node = VTON(dvp); - struct nandfsmount *nmp = dir_node->nn_nmp; - struct nandfs_node *node; - int error; - - if (nandfs_fs_full(dir_node->nn_nandfsdev)) - return (ENOSPC); - - error = nandfs_node_create(nmp, &node, mode); - if (error) - return (error); - node->nn_inode.i_gid = dir_node->nn_inode.i_gid; - node->nn_inode.i_uid = cnp->cn_cred->cr_uid; - if (vap->va_rdev != VNOVAL) - node->nn_inode.i_special = vap->va_rdev; - - *vpp = NTOV(node); - - if (nandfs_add_dirent(dvp, node->nn_ino, cnp->cn_nameptr, - cnp->cn_namelen, IFTODT(mode))) { - vput(*vpp); - return (ENOTDIR); - } - - node->nn_flags |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - - return (0); -} - -static int -nandfs_symlink(struct vop_symlink_args *ap) -{ - struct vnode **vpp = ap->a_vpp; - struct vnode *dvp = ap->a_dvp; - uint16_t mode = MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode); - struct componentname *cnp = ap->a_cnp; - struct nandfs_node *dir_node = VTON(dvp); - struct nandfsmount *nmp = dir_node->nn_nmp; - struct nandfs_node *node; - int len, error; - - if (nandfs_fs_full(dir_node->nn_nandfsdev)) - return (ENOSPC); - - error = nandfs_node_create(nmp, &node, S_IFLNK | mode); - if (error) - return (error); - node->nn_inode.i_gid = dir_node->nn_inode.i_gid; - node->nn_inode.i_uid = cnp->cn_cred->cr_uid; - - *vpp = NTOV(node); - - if (nandfs_add_dirent(dvp, node->nn_ino, cnp->cn_nameptr, - cnp->cn_namelen, IFTODT(mode))) { - vput(*vpp); - return (ENOTDIR); - } - - - len = strlen(ap->a_target); - error = vn_rdwr(UIO_WRITE, *vpp, __DECONST(void *, ap->a_target), - len, (off_t)0, UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, - cnp->cn_cred, NOCRED, NULL, NULL); - if (error) - vput(*vpp); - - return (error); -} - -static int -nandfs_readlink(struct vop_readlink_args *ap) -{ - struct vnode *vp = ap->a_vp; - - return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); -} - -static int -nandfs_rmdir(struct vop_rmdir_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct nandfs_node *node, *dnode; - uint32_t dflag, flag; - int error = 0; - - node = VTON(vp); - dnode = VTON(dvp); - - /* Files marked as immutable or append-only cannot be deleted. */ - if ((node->nn_inode.i_flags & (IMMUTABLE | APPEND | NOUNLINK)) || - (dnode->nn_inode.i_flags & APPEND)) - return (EPERM); - - DPRINTF(VNCALL, ("%s: dvp %p vp %p nandnode %p ino %#jx\n", __func__, - dvp, vp, node, (uintmax_t)node->nn_ino)); - - if (node->nn_inode.i_links_count < 2) - return (EINVAL); - - if (!nandfs_dirempty(vp, dnode->nn_ino, cnp->cn_cred)) - return (ENOTEMPTY); - - /* Files marked as immutable or append-only cannot be deleted. */ - dflag = dnode->nn_inode.i_flags; - flag = node->nn_inode.i_flags; - if ((dflag & APPEND) || - (flag & (NOUNLINK | IMMUTABLE | APPEND))) { - return (EPERM); - } - - if (vp->v_mountedhere != 0) - return (EINVAL); - - nandfs_remove_dirent(dvp, node, cnp); - dnode->nn_inode.i_links_count -= 1; - dnode->nn_flags |= IN_CHANGE; - - cache_purge(dvp); - - error = nandfs_truncate(vp, (uint64_t)0); - if (error) - return (error); - - node->nn_inode.i_links_count -= 2; - node->nn_flags |= IN_CHANGE; - - cache_purge(vp); - - return (error); -} - -static int -nandfs_fsync(struct vop_fsync_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - int locked; - - DPRINTF(VNCALL, ("%s: vp %p nandnode %p ino %#jx\n", __func__, vp, - node, (uintmax_t)node->nn_ino)); - - /* - * Start syncing vnode only if inode was modified or - * there are some dirty buffers - */ - if (VTON(vp)->nn_flags & IN_MODIFIED || - vp->v_bufobj.bo_dirty.bv_cnt) { - locked = VOP_ISLOCKED(vp); - VOP_UNLOCK(vp, 0); - nandfs_wakeup_wait_sync(node->nn_nandfsdev, SYNCER_FSYNC); - VOP_LOCK(vp, locked | LK_RETRY); - } - - return (0); -} - -static int -nandfs_bmap(struct vop_bmap_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *nnode = VTON(vp); - struct nandfs_device *nandfsdev = nnode->nn_nandfsdev; - nandfs_daddr_t l2vmap, v2pmap; - int error; - int blk2dev = nandfsdev->nd_blocksize / DEV_BSIZE; - - DPRINTF(VNCALL, ("%s: vp %p nandnode %p ino %#jx\n", __func__, vp, - nnode, (uintmax_t)nnode->nn_ino)); - - if (ap->a_bop != NULL) - *ap->a_bop = &nandfsdev->nd_devvp->v_bufobj; - if (ap->a_bnp == NULL) - return (0); - if (ap->a_runp != NULL) - *ap->a_runp = 0; - if (ap->a_runb != NULL) - *ap->a_runb = 0; - - /* - * Translate all the block sectors into a series of buffers to read - * asynchronously from the nandfs device. Note that this lookup may - * induce readin's too. - */ - - /* Get virtual block numbers for the vnode's buffer span */ - error = nandfs_bmap_lookup(nnode, ap->a_bn, &l2vmap); - if (error) - return (-1); - - /* Translate virtual block numbers to physical block numbers */ - error = nandfs_vtop(nnode, l2vmap, &v2pmap); - if (error) - return (-1); - - /* Note virtual block 0 marks not mapped */ - if (l2vmap == 0) - *ap->a_bnp = -1; - else - *ap->a_bnp = v2pmap * blk2dev; /* in DEV_BSIZE */ - - DPRINTF(VNCALL, ("%s: vp %p nandnode %p ino %#jx lblk %jx -> blk %jx\n", - __func__, vp, nnode, (uintmax_t)nnode->nn_ino, (uintmax_t)ap->a_bn, - (uintmax_t)*ap->a_bnp )); - - return (0); -} - -static void -nandfs_force_syncer(struct nandfsmount *nmp) -{ - - nmp->nm_flags |= NANDFS_FORCE_SYNCER; - nandfs_wakeup_wait_sync(nmp->nm_nandfsdev, SYNCER_FFORCE); -} - -static int -nandfs_ioctl(struct vop_ioctl_args *ap) -{ - struct vnode *vp = ap->a_vp; - u_long command = ap->a_command; - caddr_t data = ap->a_data; - struct nandfs_node *node = VTON(vp); - struct nandfs_device *nandfsdev = node->nn_nandfsdev; - struct nandfsmount *nmp = node->nn_nmp; - uint64_t *tab, *cno; - struct nandfs_seg_stat *nss; - struct nandfs_cpmode *ncpm; - struct nandfs_argv *nargv; - struct nandfs_cpstat *ncp; - int error; - - DPRINTF(VNCALL, ("%s: %x\n", __func__, (uint32_t)command)); - - error = priv_check(ap->a_td, PRIV_VFS_MOUNT); - if (error) - return (error); - - if (nmp->nm_ronly) { - switch (command) { - case NANDFS_IOCTL_GET_FSINFO: - case NANDFS_IOCTL_GET_SUSTAT: - case NANDFS_IOCTL_GET_CPINFO: - case NANDFS_IOCTL_GET_CPSTAT: - case NANDFS_IOCTL_GET_SUINFO: - case NANDFS_IOCTL_GET_VINFO: - case NANDFS_IOCTL_GET_BDESCS: - break; - default: - return (EROFS); - } - } - - switch (command) { - case NANDFS_IOCTL_GET_FSINFO: - error = nandfs_get_fsinfo(nmp, (struct nandfs_fsinfo *)data); - break; - case NANDFS_IOCTL_GET_SUSTAT: - nss = (struct nandfs_seg_stat *)data; - error = nandfs_get_seg_stat(nandfsdev, nss); - break; - case NANDFS_IOCTL_CHANGE_CPMODE: - ncpm = (struct nandfs_cpmode *)data; - error = nandfs_chng_cpmode(nandfsdev->nd_cp_node, ncpm); - nandfs_force_syncer(nmp); - break; - case NANDFS_IOCTL_GET_CPINFO: - nargv = (struct nandfs_argv *)data; - error = nandfs_get_cpinfo_ioctl(nandfsdev->nd_cp_node, nargv); - break; - case NANDFS_IOCTL_DELETE_CP: - tab = (uint64_t *)data; - error = nandfs_delete_cp(nandfsdev->nd_cp_node, tab[0], tab[1]); - nandfs_force_syncer(nmp); - break; - case NANDFS_IOCTL_GET_CPSTAT: - ncp = (struct nandfs_cpstat *)data; - error = nandfs_get_cpstat(nandfsdev->nd_cp_node, ncp); - break; - case NANDFS_IOCTL_GET_SUINFO: - nargv = (struct nandfs_argv *)data; - error = nandfs_get_segment_info_ioctl(nandfsdev, nargv); - break; - case NANDFS_IOCTL_GET_VINFO: - nargv = (struct nandfs_argv *)data; - error = nandfs_get_dat_vinfo_ioctl(nandfsdev, nargv); - break; - case NANDFS_IOCTL_GET_BDESCS: - nargv = (struct nandfs_argv *)data; - error = nandfs_get_dat_bdescs_ioctl(nandfsdev, nargv); - break; - case NANDFS_IOCTL_SYNC: - cno = (uint64_t *)data; - nandfs_force_syncer(nmp); - *cno = nandfsdev->nd_last_cno; - error = 0; - break; - case NANDFS_IOCTL_MAKE_SNAP: - cno = (uint64_t *)data; - error = nandfs_make_snap(nandfsdev, cno); - nandfs_force_syncer(nmp); - break; - case NANDFS_IOCTL_DELETE_SNAP: - cno = (uint64_t *)data; - error = nandfs_delete_snap(nandfsdev, *cno); - nandfs_force_syncer(nmp); - break; - default: - error = ENOTTY; - break; - } - - return (error); -} - -/* - * Whiteout vnode call - */ -static int -nandfs_whiteout(struct vop_whiteout_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - int error = 0; - - switch (ap->a_flags) { - case LOOKUP: - return (0); - case CREATE: - /* Create a new directory whiteout */ -#ifdef INVARIANTS - if ((cnp->cn_flags & SAVENAME) == 0) - panic("nandfs_whiteout: missing name"); -#endif - error = nandfs_add_dirent(dvp, NANDFS_WHT_INO, cnp->cn_nameptr, - cnp->cn_namelen, DT_WHT); - break; - - case DELETE: - /* Remove an existing directory whiteout */ - cnp->cn_flags &= ~DOWHITEOUT; - error = nandfs_remove_dirent(dvp, NULL, cnp); - break; - default: - panic("nandf_whiteout: unknown op: %d", ap->a_flags); - } - - return (error); -} - -static int -nandfs_pathconf(struct vop_pathconf_args *ap) -{ - int error; - - error = 0; - switch (ap->a_name) { - case _PC_LINK_MAX: - *ap->a_retval = NANDFS_LINK_MAX; - break; - case _PC_NAME_MAX: - *ap->a_retval = NANDFS_NAME_LEN; - break; - case _PC_PIPE_BUF: - if (ap->a_vp->v_type == VDIR || ap->a_vp->v_type == VFIFO) - *ap->a_retval = PIPE_BUF; - else - error = EINVAL; - break; - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - break; - case _PC_NO_TRUNC: - *ap->a_retval = 1; - break; - case _PC_ALLOC_SIZE_MIN: - *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize; - break; - case _PC_FILESIZEBITS: - *ap->a_retval = 64; - break; - case _PC_REC_INCR_XFER_SIZE: - *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; - break; - case _PC_REC_MAX_XFER_SIZE: - *ap->a_retval = -1; /* means ``unlimited'' */ - break; - case _PC_REC_MIN_XFER_SIZE: - *ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize; - break; - default: - error = vop_stdpathconf(ap); - break; - } - return (error); -} - -static int -nandfs_vnlock1(struct vop_lock1_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - int error, vi_locked; - - /* - * XXX can vnode go away while we are sleeping? - */ - vi_locked = mtx_owned(&vp->v_interlock); - if (vi_locked) - VI_UNLOCK(vp); - error = NANDFS_WRITELOCKFLAGS(node->nn_nandfsdev, - ap->a_flags & LK_NOWAIT); - if (vi_locked && !error) - VI_LOCK(vp); - if (error) - return (error); - - error = vop_stdlock(ap); - if (error) { - NANDFS_WRITEUNLOCK(node->nn_nandfsdev); - return (error); - } - - return (0); -} - -static int -nandfs_vnunlock(struct vop_unlock_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - int error; - - error = vop_stdunlock(ap); - if (error) - return (error); - - NANDFS_WRITEUNLOCK(node->nn_nandfsdev); - - return (0); -} - -/* - * Global vfs data structures - */ -struct vop_vector nandfs_vnodeops = { - .vop_default = &default_vnodeops, - .vop_access = nandfs_access, - .vop_advlock = nandfs_advlock, - .vop_bmap = nandfs_bmap, - .vop_close = nandfs_close, - .vop_create = nandfs_create, - .vop_fsync = nandfs_fsync, - .vop_getattr = nandfs_getattr, - .vop_inactive = nandfs_inactive, - .vop_cachedlookup = nandfs_lookup, - .vop_ioctl = nandfs_ioctl, - .vop_link = nandfs_link, - .vop_lookup = vfs_cache_lookup, - .vop_mkdir = nandfs_mkdir, - .vop_mknod = nandfs_mknod, - .vop_open = nandfs_open, - .vop_pathconf = nandfs_pathconf, - .vop_print = nandfs_print, - .vop_read = nandfs_read, - .vop_readdir = nandfs_readdir, - .vop_readlink = nandfs_readlink, - .vop_reclaim = nandfs_reclaim, - .vop_remove = nandfs_remove, - .vop_rename = nandfs_rename, - .vop_rmdir = nandfs_rmdir, - .vop_whiteout = nandfs_whiteout, - .vop_write = nandfs_write, - .vop_setattr = nandfs_setattr, - .vop_strategy = nandfs_strategy, - .vop_symlink = nandfs_symlink, - .vop_lock1 = nandfs_vnlock1, - .vop_unlock = nandfs_vnunlock, -}; - -struct vop_vector nandfs_system_vnodeops = { - .vop_default = &default_vnodeops, - .vop_close = nandfs_close, - .vop_inactive = nandfs_inactive, - .vop_reclaim = nandfs_reclaim, - .vop_strategy = nandfs_strategy, - .vop_fsync = nandfs_fsync, - .vop_bmap = nandfs_bmap, - .vop_access = VOP_PANIC, - .vop_advlock = VOP_PANIC, - .vop_create = VOP_PANIC, - .vop_getattr = VOP_PANIC, - .vop_cachedlookup = VOP_PANIC, - .vop_ioctl = VOP_PANIC, - .vop_link = VOP_PANIC, - .vop_lookup = VOP_PANIC, - .vop_mkdir = VOP_PANIC, - .vop_mknod = VOP_PANIC, - .vop_open = VOP_PANIC, - .vop_pathconf = VOP_PANIC, - .vop_print = VOP_PANIC, - .vop_read = VOP_PANIC, - .vop_readdir = VOP_PANIC, - .vop_readlink = VOP_PANIC, - .vop_remove = VOP_PANIC, - .vop_rename = VOP_PANIC, - .vop_rmdir = VOP_PANIC, - .vop_whiteout = VOP_PANIC, - .vop_write = VOP_PANIC, - .vop_setattr = VOP_PANIC, - .vop_symlink = VOP_PANIC, -}; - -static int -nandfsfifo_close(struct vop_close_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nandfs_node *node = VTON(vp); - - DPRINTF(VNCALL, ("%s: vp %p node %p\n", __func__, vp, node)); - - mtx_lock(&vp->v_interlock); - if (vp->v_usecount > 1) - nandfs_itimes_locked(vp); - mtx_unlock(&vp->v_interlock); - - return (fifo_specops.vop_close(ap)); -} - -struct vop_vector nandfs_fifoops = { - .vop_default = &fifo_specops, - .vop_fsync = VOP_PANIC, - .vop_access = nandfs_access, - .vop_close = nandfsfifo_close, - .vop_getattr = nandfs_getattr, - .vop_inactive = nandfs_inactive, - .vop_pathconf = nandfs_pathconf, - .vop_print = nandfs_print, - .vop_read = VOP_PANIC, - .vop_reclaim = nandfs_reclaim, - .vop_setattr = nandfs_setattr, - .vop_write = VOP_PANIC, - .vop_lock1 = nandfs_vnlock1, - .vop_unlock = nandfs_vnunlock, -}; - -int -nandfs_vinit(struct vnode *vp, uint64_t ino) -{ - struct nandfs_node *node; - - ASSERT_VOP_LOCKED(vp, __func__); - - node = VTON(vp); - - /* Check if we're fetching the root */ - if (ino == NANDFS_ROOT_INO) - vp->v_vflag |= VV_ROOT; - - if (ino != NANDFS_GC_INO) - vp->v_type = IFTOVT(node->nn_inode.i_mode); - else - vp->v_type = VREG; - - if (vp->v_type == VFIFO) - vp->v_op = &nandfs_fifoops; - - return (0); -} Property changes on: head/sys/fs/nandfs/nandfs_vnops.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_dat.c =================================================================== --- head/sys/fs/nandfs/nandfs_dat.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_dat.c (nonexistent) @@ -1,346 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -int -nandfs_vblock_alloc(struct nandfs_device *nandfsdev, nandfs_daddr_t *vblock) -{ - struct nandfs_node *dat; - struct nandfs_mdt *mdt; - struct nandfs_alloc_request req; - struct nandfs_dat_entry *dat_entry; - uint64_t start; - uint32_t entry; - int locked, error; - - dat = nandfsdev->nd_dat_node; - mdt = &nandfsdev->nd_dat_mdt; - start = nandfsdev->nd_last_cno + 1; - - locked = NANDFS_VOP_ISLOCKED(NTOV(dat)); - if (!locked) - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - req.entrynum = 0; - - /* Alloc vblock number */ - error = nandfs_find_free_entry(mdt, dat, &req); - if (error) { - nandfs_error("%s: cannot find free vblk entry\n", - __func__); - if (!locked) - VOP_UNLOCK(NTOV(dat), 0); - return (error); - } - - /* Read/create buffer */ - error = nandfs_get_entry_block(mdt, dat, &req, &entry, 1); - if (error) { - nandfs_error("%s: cannot get free vblk entry\n", - __func__); - nandfs_abort_entry(&req); - if (!locked) - VOP_UNLOCK(NTOV(dat), 0); - return (error); - } - - /* Fill out vblock data */ - dat_entry = (struct nandfs_dat_entry *) req.bp_entry->b_data; - dat_entry[entry].de_start = start; - dat_entry[entry].de_end = UINTMAX_MAX; - dat_entry[entry].de_blocknr = 0; - - /* Commit allocation */ - error = nandfs_alloc_entry(mdt, &req); - if (error) { - nandfs_error("%s: cannot get free vblk entry\n", - __func__); - if (!locked) - VOP_UNLOCK(NTOV(dat), 0); - return (error); - } - - /* Return allocated vblock */ - *vblock = req.entrynum; - DPRINTF(DAT, ("%s: allocated vblock %#jx\n", - __func__, (uintmax_t)*vblock)); - - if (!locked) - VOP_UNLOCK(NTOV(dat), 0); - return (error); -} - -int -nandfs_vblock_assign(struct nandfs_device *nandfsdev, nandfs_daddr_t vblock, - nandfs_lbn_t block) -{ - struct nandfs_node *dat; - struct nandfs_mdt *mdt; - struct nandfs_alloc_request req; - struct nandfs_dat_entry *dat_entry; - uint32_t entry; - int locked, error; - - dat = nandfsdev->nd_dat_node; - mdt = &nandfsdev->nd_dat_mdt; - - locked = NANDFS_VOP_ISLOCKED(NTOV(dat)); - if (!locked) - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - req.entrynum = vblock; - - error = nandfs_get_entry_block(mdt, dat, &req, &entry, 0); - if (!error) { - dat_entry = (struct nandfs_dat_entry *) req.bp_entry->b_data; - dat_entry[entry].de_blocknr = block; - - DPRINTF(DAT, ("%s: assing vblock %jx->%jx\n", - __func__, (uintmax_t)vblock, (uintmax_t)block)); - - /* - * It is mostly called from syncer() so - * we want to force making buf dirty - */ - error = nandfs_dirty_buf(req.bp_entry, 1); - } - - if (!locked) - VOP_UNLOCK(NTOV(dat), 0); - - return (error); -} - -int -nandfs_vblock_end(struct nandfs_device *nandfsdev, nandfs_daddr_t vblock) -{ - struct nandfs_node *dat; - struct nandfs_mdt *mdt; - struct nandfs_alloc_request req; - struct nandfs_dat_entry *dat_entry; - uint64_t end; - uint32_t entry; - int locked, error; - - dat = nandfsdev->nd_dat_node; - mdt = &nandfsdev->nd_dat_mdt; - end = nandfsdev->nd_last_cno; - - locked = NANDFS_VOP_ISLOCKED(NTOV(dat)); - if (!locked) - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - req.entrynum = vblock; - - error = nandfs_get_entry_block(mdt, dat, &req, &entry, 0); - if (!error) { - dat_entry = (struct nandfs_dat_entry *) req.bp_entry->b_data; - dat_entry[entry].de_end = end; - DPRINTF(DAT, ("%s: end vblock %#jx at checkpoint %#jx\n", - __func__, (uintmax_t)vblock, (uintmax_t)end)); - - /* - * It is mostly called from syncer() so - * we want to force making buf dirty - */ - error = nandfs_dirty_buf(req.bp_entry, 1); - } - - if (!locked) - VOP_UNLOCK(NTOV(dat), 0); - - return (error); -} - -int -nandfs_vblock_free(struct nandfs_device *nandfsdev, nandfs_daddr_t vblock) -{ - struct nandfs_node *dat; - struct nandfs_mdt *mdt; - struct nandfs_alloc_request req; - int error; - - dat = nandfsdev->nd_dat_node; - mdt = &nandfsdev->nd_dat_mdt; - - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - req.entrynum = vblock; - - error = nandfs_find_entry(mdt, dat, &req); - if (!error) { - DPRINTF(DAT, ("%s: vblk %#jx\n", __func__, (uintmax_t)vblock)); - nandfs_free_entry(mdt, &req); - } - - VOP_UNLOCK(NTOV(dat), 0); - return (error); -} - -int -nandfs_get_dat_vinfo_ioctl(struct nandfs_device *nandfsdev, struct nandfs_argv *nargv) -{ - struct nandfs_vinfo *vinfo; - size_t size; - int error; - - if (nargv->nv_nmembs > NANDFS_VINFO_MAX) - return (EINVAL); - - size = sizeof(struct nandfs_vinfo) * nargv->nv_nmembs; - vinfo = malloc(size, M_NANDFSTEMP, M_WAITOK|M_ZERO); - - error = copyin((void *)(uintptr_t)nargv->nv_base, vinfo, size); - if (error) { - free(vinfo, M_NANDFSTEMP); - return (error); - } - - error = nandfs_get_dat_vinfo(nandfsdev, vinfo, nargv->nv_nmembs); - if (error == 0) - error = copyout(vinfo, (void *)(uintptr_t)nargv->nv_base, size); - free(vinfo, M_NANDFSTEMP); - return (error); -} - -int -nandfs_get_dat_vinfo(struct nandfs_device *nandfsdev, struct nandfs_vinfo *vinfo, - uint32_t nmembs) -{ - struct nandfs_node *dat; - struct nandfs_mdt *mdt; - struct nandfs_alloc_request req; - struct nandfs_dat_entry *dat_entry; - uint32_t i, idx; - int error = 0; - - dat = nandfsdev->nd_dat_node; - mdt = &nandfsdev->nd_dat_mdt; - - DPRINTF(DAT, ("%s: nmembs %#x\n", __func__, nmembs)); - - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - - for (i = 0; i < nmembs; i++) { - req.entrynum = vinfo[i].nvi_vblocknr; - - error = nandfs_get_entry_block(mdt, dat,&req, &idx, 0); - if (error) - break; - - dat_entry = ((struct nandfs_dat_entry *) req.bp_entry->b_data); - vinfo[i].nvi_start = dat_entry[idx].de_start; - vinfo[i].nvi_end = dat_entry[idx].de_end; - vinfo[i].nvi_blocknr = dat_entry[idx].de_blocknr; - - DPRINTF(DAT, ("%s: vinfo: %jx[%jx-%jx]->%jx\n", - __func__, vinfo[i].nvi_vblocknr, vinfo[i].nvi_start, - vinfo[i].nvi_end, vinfo[i].nvi_blocknr)); - - brelse(req.bp_entry); - } - - VOP_UNLOCK(NTOV(dat), 0); - return (error); -} - -int -nandfs_get_dat_bdescs_ioctl(struct nandfs_device *nffsdev, - struct nandfs_argv *nargv) -{ - struct nandfs_bdesc *bd; - size_t size; - int error; - - size = nargv->nv_nmembs * sizeof(struct nandfs_bdesc); - bd = malloc(size, M_NANDFSTEMP, M_WAITOK); - error = copyin((void *)(uintptr_t)nargv->nv_base, bd, size); - if (error) { - free(bd, M_NANDFSTEMP); - return (error); - } - - error = nandfs_get_dat_bdescs(nffsdev, bd, nargv->nv_nmembs); - - if (error == 0) - error = copyout(bd, (void *)(uintptr_t)nargv->nv_base, size); - - free(bd, M_NANDFSTEMP); - return (error); -} - -int -nandfs_get_dat_bdescs(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd, - uint32_t nmembs) -{ - struct nandfs_node *dat_node; - uint64_t map; - uint32_t i; - int error = 0; - - dat_node = nffsdev->nd_dat_node; - - VOP_LOCK(NTOV(dat_node), LK_EXCLUSIVE); - - for (i = 0; i < nmembs; i++) { - DPRINTF(CLEAN, - ("%s: bd ino:%#jx oblk:%#jx blocknr:%#jx off:%#jx\n", - __func__, (uintmax_t)bd[i].bd_ino, - (uintmax_t)bd[i].bd_oblocknr, (uintmax_t)bd[i].bd_blocknr, - (uintmax_t)bd[i].bd_offset)); - - error = nandfs_bmap_lookup(dat_node, bd[i].bd_offset, &map); - if (error) - break; - bd[i].bd_blocknr = map; - } - - VOP_UNLOCK(NTOV(dat_node), 0); - return (error); -} Property changes on: head/sys/fs/nandfs/nandfs_dat.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_cleaner.c =================================================================== --- head/sys/fs/nandfs/nandfs_cleaner.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_cleaner.c (nonexistent) @@ -1,622 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define NANDFS_CLEANER_KILL 1 - -static void nandfs_cleaner(struct nandfs_device *); -static int nandfs_cleaner_clean_segments(struct nandfs_device *, - struct nandfs_vinfo *, uint32_t, struct nandfs_period *, uint32_t, - struct nandfs_bdesc *, uint32_t, uint64_t *, uint32_t); - -static int -nandfs_process_bdesc(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd, - uint64_t nmembs); - -static void -nandfs_wakeup_wait_cleaner(struct nandfs_device *fsdev, int reason) -{ - - mtx_lock(&fsdev->nd_clean_mtx); - if (reason == NANDFS_CLEANER_KILL) - fsdev->nd_cleaner_exit = 1; - if (fsdev->nd_cleaning == 0) { - fsdev->nd_cleaning = 1; - wakeup(&fsdev->nd_cleaning); - } - cv_wait(&fsdev->nd_clean_cv, &fsdev->nd_clean_mtx); - mtx_unlock(&fsdev->nd_clean_mtx); -} - -int -nandfs_start_cleaner(struct nandfs_device *fsdev) -{ - int error; - - MPASS(fsdev->nd_cleaner == NULL); - - fsdev->nd_cleaner_exit = 0; - - error = kthread_add((void(*)(void *))nandfs_cleaner, fsdev, NULL, - &fsdev->nd_cleaner, 0, 0, "nandfs_cleaner"); - if (error) - printf("nandfs: could not start cleaner: %d\n", error); - - return (error); -} - -int -nandfs_stop_cleaner(struct nandfs_device *fsdev) -{ - - MPASS(fsdev->nd_cleaner != NULL); - nandfs_wakeup_wait_cleaner(fsdev, NANDFS_CLEANER_KILL); - fsdev->nd_cleaner = NULL; - - DPRINTF(CLEAN, ("cleaner stopped\n")); - return (0); -} - -static int -nandfs_cleaner_finished(struct nandfs_device *fsdev) -{ - int exit; - - mtx_lock(&fsdev->nd_clean_mtx); - fsdev->nd_cleaning = 0; - if (!fsdev->nd_cleaner_exit) { - DPRINTF(CLEAN, ("%s: sleep\n", __func__)); - msleep(&fsdev->nd_cleaning, &fsdev->nd_clean_mtx, PRIBIO, "-", - hz * nandfs_cleaner_interval); - } - exit = fsdev->nd_cleaner_exit; - cv_broadcast(&fsdev->nd_clean_cv); - mtx_unlock(&fsdev->nd_clean_mtx); - if (exit) { - DPRINTF(CLEAN, ("%s: no longer active\n", __func__)); - return (1); - } - - return (0); -} - -static void -print_suinfo(struct nandfs_suinfo *suinfo, int nsegs) -{ - int i; - - for (i = 0; i < nsegs; i++) { - DPRINTF(CLEAN, ("%jx %jd %c%c%c %10u\n", - suinfo[i].nsi_num, suinfo[i].nsi_lastmod, - (suinfo[i].nsi_flags & - (NANDFS_SEGMENT_USAGE_ACTIVE) ? 'a' : '-'), - (suinfo[i].nsi_flags & - (NANDFS_SEGMENT_USAGE_DIRTY) ? 'd' : '-'), - (suinfo[i].nsi_flags & - (NANDFS_SEGMENT_USAGE_ERROR) ? 'e' : '-'), - suinfo[i].nsi_blocks)); - } -} - -static int -nandfs_cleaner_vblock_is_alive(struct nandfs_device *fsdev, - struct nandfs_vinfo *vinfo, struct nandfs_cpinfo *cp, uint32_t ncps) -{ - int64_t idx, min, max; - - if (vinfo->nvi_end >= fsdev->nd_last_cno) - return (1); - - if (ncps == 0) - return (0); - - if (vinfo->nvi_end < cp[0].nci_cno || - vinfo->nvi_start > cp[ncps - 1].nci_cno) - return (0); - - idx = min = 0; - max = ncps - 1; - while (min <= max) { - idx = (min + max) / 2; - if (vinfo->nvi_start == cp[idx].nci_cno) - return (1); - if (vinfo->nvi_start < cp[idx].nci_cno) - max = idx - 1; - else - min = idx + 1; - } - - return (vinfo->nvi_end >= cp[idx].nci_cno); -} - -static void -nandfs_cleaner_vinfo_mark_alive(struct nandfs_device *fsdev, - struct nandfs_vinfo *vinfo, uint32_t nmembs, struct nandfs_cpinfo *cp, - uint32_t ncps) -{ - uint32_t i; - - for (i = 0; i < nmembs; i++) - vinfo[i].nvi_alive = - nandfs_cleaner_vblock_is_alive(fsdev, &vinfo[i], cp, ncps); -} - -static int -nandfs_cleaner_bdesc_is_alive(struct nandfs_device *fsdev, - struct nandfs_bdesc *bdesc) -{ - int alive; - - alive = bdesc->bd_oblocknr == bdesc->bd_blocknr; - if (!alive) - MPASS(abs(bdesc->bd_oblocknr - bdesc->bd_blocknr) > 2); - - return (alive); -} - -static void -nandfs_cleaner_bdesc_mark_alive(struct nandfs_device *fsdev, - struct nandfs_bdesc *bdesc, uint32_t nmembs) -{ - uint32_t i; - - for (i = 0; i < nmembs; i++) - bdesc[i].bd_alive = nandfs_cleaner_bdesc_is_alive(fsdev, - &bdesc[i]); -} - -static void -nandfs_cleaner_iterate_psegment(struct nandfs_device *fsdev, - struct nandfs_segment_summary *segsum, union nandfs_binfo *binfo, - nandfs_daddr_t blk, struct nandfs_vinfo **vipp, struct nandfs_bdesc **bdpp) -{ - int i; - - DPRINTF(CLEAN, ("%s nbinfos %x\n", __func__, segsum->ss_nbinfos)); - for (i = 0; i < segsum->ss_nbinfos; i++) { - if (binfo[i].bi_v.bi_ino == NANDFS_DAT_INO) { - (*bdpp)->bd_oblocknr = blk + segsum->ss_nblocks - - segsum->ss_nbinfos + i; - /* - * XXX Hack - */ - if (segsum->ss_flags & NANDFS_SS_SR) - (*bdpp)->bd_oblocknr--; - (*bdpp)->bd_level = binfo[i].bi_dat.bi_level; - (*bdpp)->bd_offset = binfo[i].bi_dat.bi_blkoff; - (*bdpp)++; - } else { - (*vipp)->nvi_ino = binfo[i].bi_v.bi_ino; - (*vipp)->nvi_vblocknr = binfo[i].bi_v.bi_vblocknr; - (*vipp)++; - } - } -} - -static int -nandfs_cleaner_iterate_segment(struct nandfs_device *fsdev, uint64_t segno, - struct nandfs_vinfo **vipp, struct nandfs_bdesc **bdpp, int *select) -{ - struct nandfs_segment_summary *segsum; - union nandfs_binfo *binfo; - struct buf *bp; - uint32_t nblocks; - nandfs_daddr_t curr, start, end; - int error = 0; - - nandfs_get_segment_range(fsdev, segno, &start, &end); - - DPRINTF(CLEAN, ("%s: segno %jx start %jx end %jx\n", __func__, segno, - start, end)); - - *select = 0; - - for (curr = start; curr < end; curr += nblocks) { - error = nandfs_dev_bread(fsdev, curr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - nandfs_error("%s: couldn't load segment summary of %jx: %d\n", - __func__, segno, error); - return (error); - } - - segsum = (struct nandfs_segment_summary *)bp->b_data; - binfo = (union nandfs_binfo *)(bp->b_data + segsum->ss_bytes); - - if (!nandfs_segsum_valid(segsum)) { - brelse(bp); - nandfs_error("nandfs: invalid summary of segment %jx\n", segno); - return (error); - } - - DPRINTF(CLEAN, ("%s: %jx magic %x bytes %x nblocks %x nbinfos " - "%x\n", __func__, segno, segsum->ss_magic, segsum->ss_bytes, - segsum->ss_nblocks, segsum->ss_nbinfos)); - - nandfs_cleaner_iterate_psegment(fsdev, segsum, binfo, curr, - vipp, bdpp); - nblocks = segsum->ss_nblocks; - brelse(bp); - } - - if (error == 0) - *select = 1; - - return (error); -} - -static int -nandfs_cleaner_choose_segment(struct nandfs_device *fsdev, uint64_t **segpp, - uint64_t nsegs, uint64_t *rseg) -{ - struct nandfs_suinfo *suinfo; - uint64_t i, ssegs; - int error; - - suinfo = malloc(sizeof(*suinfo) * nsegs, M_NANDFSTEMP, - M_ZERO | M_WAITOK); - - if (*rseg >= fsdev->nd_fsdata.f_nsegments) - *rseg = 0; - -retry: - error = nandfs_get_segment_info_filter(fsdev, suinfo, nsegs, *rseg, - &ssegs, NANDFS_SEGMENT_USAGE_DIRTY, - NANDFS_SEGMENT_USAGE_ACTIVE | NANDFS_SEGMENT_USAGE_ERROR | - NANDFS_SEGMENT_USAGE_GC); - if (error) { - nandfs_error("%s:%d", __FILE__, __LINE__); - goto out; - } - if (ssegs == 0 && *rseg != 0) { - *rseg = 0; - goto retry; - } - if (ssegs > 0) { - print_suinfo(suinfo, ssegs); - - for (i = 0; i < ssegs; i++) { - (**segpp) = suinfo[i].nsi_num; - (*segpp)++; - } - *rseg = suinfo[i - 1].nsi_num + 1; - } - -out: - free(suinfo, M_NANDFSTEMP); - return (error); -} - -static int -nandfs_cleaner_body(struct nandfs_device *fsdev, uint64_t *rseg) -{ - struct nandfs_vinfo *vinfo, *vip, *vipi; - struct nandfs_bdesc *bdesc, *bdp, *bdpi; - struct nandfs_cpstat cpstat; - struct nandfs_cpinfo *cpinfo = NULL; - uint64_t *segnums, *segp; - int select, selected; - int error = 0; - int nsegs; - int i; - - nsegs = nandfs_cleaner_segments; - - vip = vinfo = malloc(sizeof(*vinfo) * - fsdev->nd_fsdata.f_blocks_per_segment * nsegs, M_NANDFSTEMP, - M_ZERO | M_WAITOK); - bdp = bdesc = malloc(sizeof(*bdesc) * - fsdev->nd_fsdata.f_blocks_per_segment * nsegs, M_NANDFSTEMP, - M_ZERO | M_WAITOK); - segp = segnums = malloc(sizeof(*segnums) * nsegs, M_NANDFSTEMP, - M_WAITOK); - - error = nandfs_cleaner_choose_segment(fsdev, &segp, nsegs, rseg); - if (error) { - nandfs_error("%s:%d", __FILE__, __LINE__); - goto out; - } - - if (segnums == segp) - goto out; - - selected = 0; - for (i = 0; i < segp - segnums; i++) { - error = nandfs_cleaner_iterate_segment(fsdev, segnums[i], &vip, - &bdp, &select); - if (error) { - /* - * XXX deselect (see below)? - */ - goto out; - } - if (!select) - segnums[i] = NANDFS_NOSEGMENT; - else { - error = nandfs_markgc_segment(fsdev, segnums[i]); - if (error) { - nandfs_error("%s:%d\n", __FILE__, __LINE__); - goto out; - } - selected++; - } - } - - if (selected == 0) { - MPASS(vinfo == vip); - MPASS(bdesc == bdp); - goto out; - } - - error = nandfs_get_cpstat(fsdev->nd_cp_node, &cpstat); - if (error) { - nandfs_error("%s:%d\n", __FILE__, __LINE__); - goto out; - } - - if (cpstat.ncp_nss != 0) { - cpinfo = malloc(sizeof(struct nandfs_cpinfo) * cpstat.ncp_nss, - M_NANDFSTEMP, M_WAITOK); - error = nandfs_get_cpinfo(fsdev->nd_cp_node, 1, NANDFS_SNAPSHOT, - cpinfo, cpstat.ncp_nss, NULL); - if (error) { - nandfs_error("%s:%d\n", __FILE__, __LINE__); - goto out_locked; - } - } - - NANDFS_WRITELOCK(fsdev); - DPRINTF(CLEAN, ("%s: got lock\n", __func__)); - - error = nandfs_get_dat_vinfo(fsdev, vinfo, vip - vinfo); - if (error) { - nandfs_error("%s:%d\n", __FILE__, __LINE__); - goto out_locked; - } - - nandfs_cleaner_vinfo_mark_alive(fsdev, vinfo, vip - vinfo, cpinfo, - cpstat.ncp_nss); - - error = nandfs_get_dat_bdescs(fsdev, bdesc, bdp - bdesc); - if (error) { - nandfs_error("%s:%d\n", __FILE__, __LINE__); - goto out_locked; - } - - nandfs_cleaner_bdesc_mark_alive(fsdev, bdesc, bdp - bdesc); - - DPRINTF(CLEAN, ("got:\n")); - for (vipi = vinfo; vipi < vip; vipi++) { - DPRINTF(CLEAN, ("v ino %jx vblocknr %jx start %jx end %jx " - "alive %d\n", vipi->nvi_ino, vipi->nvi_vblocknr, - vipi->nvi_start, vipi->nvi_end, vipi->nvi_alive)); - } - for (bdpi = bdesc; bdpi < bdp; bdpi++) { - DPRINTF(CLEAN, ("b oblocknr %jx blocknr %jx offset %jx " - "alive %d\n", bdpi->bd_oblocknr, bdpi->bd_blocknr, - bdpi->bd_offset, bdpi->bd_alive)); - } - DPRINTF(CLEAN, ("end list\n")); - - error = nandfs_cleaner_clean_segments(fsdev, vinfo, vip - vinfo, NULL, - 0, bdesc, bdp - bdesc, segnums, segp - segnums); - if (error) - nandfs_error("%s:%d\n", __FILE__, __LINE__); - -out_locked: - NANDFS_WRITEUNLOCK(fsdev); -out: - free(cpinfo, M_NANDFSTEMP); - free(segnums, M_NANDFSTEMP); - free(bdesc, M_NANDFSTEMP); - free(vinfo, M_NANDFSTEMP); - - return (error); -} - -static void -nandfs_cleaner(struct nandfs_device *fsdev) -{ - uint64_t checked_seg = 0; - int error; - - while (!nandfs_cleaner_finished(fsdev)) { - if (!nandfs_cleaner_enable || rebooting) - continue; - - DPRINTF(CLEAN, ("%s: run started\n", __func__)); - - fsdev->nd_cleaning = 1; - - error = nandfs_cleaner_body(fsdev, &checked_seg); - - DPRINTF(CLEAN, ("%s: run finished error %d\n", __func__, - error)); - } - - DPRINTF(CLEAN, ("%s: exiting\n", __func__)); - kthread_exit(); -} - -static int -nandfs_cleaner_clean_segments(struct nandfs_device *nffsdev, - struct nandfs_vinfo *vinfo, uint32_t nvinfo, - struct nandfs_period *pd, uint32_t npd, - struct nandfs_bdesc *bdesc, uint32_t nbdesc, - uint64_t *segments, uint32_t nsegs) -{ - struct nandfs_node *gc; - struct buf *bp; - uint32_t i; - int error = 0; - - gc = nffsdev->nd_gc_node; - - DPRINTF(CLEAN, ("%s: enter\n", __func__)); - - VOP_LOCK(NTOV(gc), LK_EXCLUSIVE); - for (i = 0; i < nvinfo; i++) { - if (!vinfo[i].nvi_alive) - continue; - DPRINTF(CLEAN, ("%s: read vblknr:%#jx blk:%#jx\n", - __func__, (uintmax_t)vinfo[i].nvi_vblocknr, - (uintmax_t)vinfo[i].nvi_blocknr)); - error = nandfs_bread(nffsdev->nd_gc_node, vinfo[i].nvi_blocknr, - NULL, 0, &bp); - if (error) { - nandfs_error("%s:%d", __FILE__, __LINE__); - VOP_UNLOCK(NTOV(gc), 0); - goto out; - } - nandfs_vblk_set(bp, vinfo[i].nvi_vblocknr); - nandfs_buf_set(bp, NANDFS_VBLK_ASSIGNED); - nandfs_dirty_buf(bp, 1); - } - VOP_UNLOCK(NTOV(gc), 0); - - /* Delete checkpoints */ - for (i = 0; i < npd; i++) { - DPRINTF(CLEAN, ("delete checkpoint: %jx\n", - (uintmax_t)pd[i].p_start)); - error = nandfs_delete_cp(nffsdev->nd_cp_node, pd[i].p_start, - pd[i].p_end); - if (error) { - nandfs_error("%s:%d", __FILE__, __LINE__); - goto out; - } - } - - /* Update vblocks */ - for (i = 0; i < nvinfo; i++) { - if (vinfo[i].nvi_alive) - continue; - DPRINTF(CLEAN, ("freeing vblknr: %jx\n", vinfo[i].nvi_vblocknr)); - error = nandfs_vblock_free(nffsdev, vinfo[i].nvi_vblocknr); - if (error) { - nandfs_error("%s:%d", __FILE__, __LINE__); - goto out; - } - } - - error = nandfs_process_bdesc(nffsdev, bdesc, nbdesc); - if (error) { - nandfs_error("%s:%d", __FILE__, __LINE__); - goto out; - } - - /* Add segments to clean */ - if (nffsdev->nd_free_count) { - nffsdev->nd_free_base = realloc(nffsdev->nd_free_base, - (nffsdev->nd_free_count + nsegs) * sizeof(uint64_t), - M_NANDFSTEMP, M_WAITOK | M_ZERO); - memcpy(&nffsdev->nd_free_base[nffsdev->nd_free_count], segments, - nsegs * sizeof(uint64_t)); - nffsdev->nd_free_count += nsegs; - } else { - nffsdev->nd_free_base = malloc(nsegs * sizeof(uint64_t), - M_NANDFSTEMP, M_WAITOK|M_ZERO); - memcpy(nffsdev->nd_free_base, segments, - nsegs * sizeof(uint64_t)); - nffsdev->nd_free_count = nsegs; - } - -out: - - DPRINTF(CLEAN, ("%s: exit error %d\n", __func__, error)); - - return (error); -} - -static int -nandfs_process_bdesc(struct nandfs_device *nffsdev, struct nandfs_bdesc *bd, - uint64_t nmembs) -{ - struct nandfs_node *dat_node; - struct buf *bp; - uint64_t i; - int error; - - dat_node = nffsdev->nd_dat_node; - - VOP_LOCK(NTOV(dat_node), LK_EXCLUSIVE); - - for (i = 0; i < nmembs; i++) { - if (!bd[i].bd_alive) - continue; - DPRINTF(CLEAN, ("%s: idx %jx offset %jx\n", - __func__, i, bd[i].bd_offset)); - if (bd[i].bd_level) { - error = nandfs_bread_meta(dat_node, bd[i].bd_offset, - NULL, 0, &bp); - if (error) { - nandfs_error("%s: cannot read dat node " - "level:%d\n", __func__, bd[i].bd_level); - brelse(bp); - VOP_UNLOCK(NTOV(dat_node), 0); - return (error); - } - nandfs_dirty_buf_meta(bp, 1); - nandfs_bmap_dirty_blocks(VTON(bp->b_vp), bp, 1); - } else { - error = nandfs_bread(dat_node, bd[i].bd_offset, NULL, - 0, &bp); - if (error) { - nandfs_error("%s: cannot read dat node\n", - __func__); - brelse(bp); - VOP_UNLOCK(NTOV(dat_node), 0); - return (error); - } - nandfs_dirty_buf(bp, 1); - } - DPRINTF(CLEAN, ("%s: bp: %p\n", __func__, bp)); - } - - VOP_UNLOCK(NTOV(dat_node), 0); - - return (0); -} Property changes on: head/sys/fs/nandfs/nandfs_cleaner.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_cpfile.c =================================================================== --- head/sys/fs/nandfs/nandfs_cpfile.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_cpfile.c (nonexistent) @@ -1,778 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "nandfs_mount.h" -#include "nandfs.h" -#include "nandfs_subr.h" - - -static int -nandfs_checkpoint_size(struct nandfs_device *fsdev) -{ - - return (fsdev->nd_fsdata.f_checkpoint_size); -} - -static int -nandfs_checkpoint_blk_offset(struct nandfs_device *fsdev, uint64_t cn, - uint64_t *blk, uint64_t *offset) -{ - uint64_t off; - uint16_t cp_size, cp_per_blk; - - KASSERT((cn), ("checkpoing cannot be zero")); - - cp_size = fsdev->nd_fsdata.f_checkpoint_size; - cp_per_blk = fsdev->nd_blocksize / cp_size; - off = roundup(sizeof(struct nandfs_cpfile_header), cp_size) / cp_size; - off += (cn - 1); - - *blk = off / cp_per_blk; - *offset = (off % cp_per_blk) * cp_size; - - return (0); -} - -static int -nandfs_checkpoint_blk_remaining(struct nandfs_device *fsdev, uint64_t cn, - uint64_t blk, uint64_t offset) -{ - uint16_t cp_size, cp_remaining; - - cp_size = fsdev->nd_fsdata.f_checkpoint_size; - cp_remaining = (fsdev->nd_blocksize - offset) / cp_size; - - return (cp_remaining); -} - -int -nandfs_get_checkpoint(struct nandfs_device *fsdev, struct nandfs_node *cp_node, - uint64_t cn) -{ - struct buf *bp; - uint64_t blk, offset; - int error; - - if (cn != fsdev->nd_last_cno && cn != (fsdev->nd_last_cno + 1)) { - return (-1); - } - - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (-1); - } - - error = nandfs_dirty_buf(bp, 0); - if (error) - return (-1); - - - nandfs_checkpoint_blk_offset(fsdev, cn, &blk, &offset); - - if (blk != 0) { - if (blk < cp_node->nn_inode.i_blocks) - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - else - error = nandfs_bcreate(cp_node, blk, NOCRED, 0, &bp); - if (error) { - if (bp) - brelse(bp); - return (-1); - } - - nandfs_dirty_buf(bp, 1); - } - - DPRINTF(CPFILE, ("%s: cn:%#jx entry block:%#jx offset:%#jx\n", - __func__, (uintmax_t)cn, (uintmax_t)blk, (uintmax_t)offset)); - - return (0); -} - -int -nandfs_set_checkpoint(struct nandfs_device *fsdev, struct nandfs_node *cp_node, - uint64_t cn, struct nandfs_inode *ifile_inode, uint64_t nblocks) -{ - struct nandfs_cpfile_header *cnh; - struct nandfs_checkpoint *cnp; - struct buf *bp; - uint64_t blk, offset; - int error; - - if (cn != fsdev->nd_last_cno && cn != (fsdev->nd_last_cno + 1)) { - nandfs_error("%s: trying to set invalid chekpoint %jx - %jx\n", - __func__, cn, fsdev->nd_last_cno); - return (-1); - } - - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return error; - } - - cnh = (struct nandfs_cpfile_header *) bp->b_data; - cnh->ch_ncheckpoints++; - - nandfs_checkpoint_blk_offset(fsdev, cn, &blk, &offset); - - if(blk != 0) { - brelse(bp); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return error; - } - } - - cnp = (struct nandfs_checkpoint *)((uint8_t *)bp->b_data + offset); - cnp->cp_flags = 0; - cnp->cp_checkpoints_count = 1; - memset(&cnp->cp_snapshot_list, 0, sizeof(struct nandfs_snapshot_list)); - cnp->cp_cno = cn; - cnp->cp_create = fsdev->nd_ts.tv_sec; - cnp->cp_nblk_inc = nblocks; - cnp->cp_blocks_count = 0; - memcpy (&cnp->cp_ifile_inode, ifile_inode, sizeof(cnp->cp_ifile_inode)); - - DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx nblk:%#jx\n", - __func__, (uintmax_t)cn, (uintmax_t)cnp->cp_create, - (uintmax_t)nblocks)); - - brelse(bp); - return (0); -} - -static int -nandfs_cp_mounted(struct nandfs_device *nandfsdev, uint64_t cno) -{ - struct nandfsmount *nmp; - int mounted = 0; - - mtx_lock(&nandfsdev->nd_mutex); - /* No double-mounting of the same checkpoint */ - STAILQ_FOREACH(nmp, &nandfsdev->nd_mounts, nm_next_mount) { - if (nmp->nm_mount_args.cpno == cno) { - mounted = 1; - break; - } - } - mtx_unlock(&nandfsdev->nd_mutex); - - return (mounted); -} - -static int -nandfs_cp_set_snapshot(struct nandfs_node *cp_node, uint64_t cno) -{ - struct nandfs_device *fsdev; - struct nandfs_cpfile_header *cnh; - struct nandfs_checkpoint *cnp; - struct nandfs_snapshot_list *list; - struct buf *bp; - uint64_t blk, prev_blk, offset; - uint64_t curr, prev; - int error; - - fsdev = cp_node->nn_nandfsdev; - - /* Get snapshot data */ - nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - if (cnp->cp_flags & NANDFS_CHECKPOINT_INVALID) { - brelse(bp); - return (ENOENT); - } - if ((cnp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT)) { - brelse(bp); - return (EINVAL); - } - - brelse(bp); - /* Get list from header */ - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - cnh = (struct nandfs_cpfile_header *) bp->b_data; - list = &cnh->ch_snapshot_list; - prev = list->ssl_prev; - brelse(bp); - prev_blk = ~(0); - curr = 0; - while (prev > cno) { - curr = prev; - nandfs_checkpoint_blk_offset(fsdev, prev, &prev_blk, &offset); - error = nandfs_bread(cp_node, prev_blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - prev = list->ssl_prev; - brelse(bp); - } - - if (curr == 0) { - nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - cnh = (struct nandfs_cpfile_header *) bp->b_data; - list = &cnh->ch_snapshot_list; - } else { - nandfs_checkpoint_blk_offset(fsdev, curr, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - } - - list->ssl_prev = cno; - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - - - /* Update snapshot for cno */ - nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - list->ssl_prev = prev; - list->ssl_next = curr; - cnp->cp_flags |= NANDFS_CHECKPOINT_SNAPSHOT; - nandfs_dirty_buf(bp, 1); - - if (prev == 0) { - nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - cnh = (struct nandfs_cpfile_header *) bp->b_data; - list = &cnh->ch_snapshot_list; - } else { - /* Update snapshot list for prev */ - nandfs_checkpoint_blk_offset(fsdev, prev, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - } - list->ssl_next = cno; - nandfs_dirty_buf(bp, 1); - - /* Update header */ - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnh = (struct nandfs_cpfile_header *) bp->b_data; - cnh->ch_nsnapshots++; - nandfs_dirty_buf(bp, 1); - - return (0); -} - -static int -nandfs_cp_clr_snapshot(struct nandfs_node *cp_node, uint64_t cno) -{ - struct nandfs_device *fsdev; - struct nandfs_cpfile_header *cnh; - struct nandfs_checkpoint *cnp; - struct nandfs_snapshot_list *list; - struct buf *bp; - uint64_t blk, offset, snapshot_cnt; - uint64_t next, prev; - int error; - - fsdev = cp_node->nn_nandfsdev; - - /* Get snapshot data */ - nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - if (cnp->cp_flags & NANDFS_CHECKPOINT_INVALID) { - brelse(bp); - return (ENOENT); - } - if (!(cnp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT)) { - brelse(bp); - return (EINVAL); - } - - list = &cnp->cp_snapshot_list; - next = list->ssl_next; - prev = list->ssl_prev; - brelse(bp); - - /* Get previous snapshot */ - if (prev != 0) { - nandfs_checkpoint_blk_offset(fsdev, prev, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - } else { - nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - cnh = (struct nandfs_cpfile_header *) bp->b_data; - list = &cnh->ch_snapshot_list; - } - - list->ssl_next = next; - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - - /* Get next snapshot */ - if (next != 0) { - nandfs_checkpoint_blk_offset(fsdev, next, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - } else { - nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - cnh = (struct nandfs_cpfile_header *) bp->b_data; - list = &cnh->ch_snapshot_list; - } - list->ssl_prev = prev; - nandfs_dirty_buf(bp, 1); - - /* Update snapshot list for cno */ - nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset); - error = nandfs_bread(cp_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - list = &cnp->cp_snapshot_list; - list->ssl_prev = 0; - list->ssl_next = 0; - cnp->cp_flags &= !NANDFS_CHECKPOINT_SNAPSHOT; - nandfs_dirty_buf(bp, 1); - - /* Update header */ - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnh = (struct nandfs_cpfile_header *) bp->b_data; - snapshot_cnt = cnh->ch_nsnapshots; - snapshot_cnt--; - cnh->ch_nsnapshots = snapshot_cnt; - nandfs_dirty_buf(bp, 1); - - return (0); -} - -int -nandfs_chng_cpmode(struct nandfs_node *node, struct nandfs_cpmode *ncpm) -{ - struct nandfs_device *fsdev; - uint64_t cno = ncpm->ncpm_cno; - int mode = ncpm->ncpm_mode; - int ret; - - fsdev = node->nn_nandfsdev; - VOP_LOCK(NTOV(node), LK_EXCLUSIVE); - switch (mode) { - case NANDFS_CHECKPOINT: - if (nandfs_cp_mounted(fsdev, cno)) { - ret = EBUSY; - } else - ret = nandfs_cp_clr_snapshot(node, cno); - break; - case NANDFS_SNAPSHOT: - ret = nandfs_cp_set_snapshot(node, cno); - break; - default: - ret = EINVAL; - break; - } - VOP_UNLOCK(NTOV(node), 0); - - return (ret); -} - -static void -nandfs_cpinfo_fill(struct nandfs_checkpoint *cnp, struct nandfs_cpinfo *nci) -{ - - nci->nci_flags = cnp->cp_flags; - nci->nci_pad = 0; - nci->nci_cno = cnp->cp_cno; - nci->nci_create = cnp->cp_create; - nci->nci_nblk_inc = cnp->cp_nblk_inc; - nci->nci_blocks_count = cnp->cp_blocks_count; - nci->nci_next = cnp->cp_snapshot_list.ssl_next; - DPRINTF(CPFILE, ("%s: cn:%#jx ctime:%#jx\n", - __func__, (uintmax_t)cnp->cp_cno, - (uintmax_t)cnp->cp_create)); -} - -static int -nandfs_get_cpinfo_cp(struct nandfs_node *node, uint64_t cno, - struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs) -{ - struct nandfs_device *fsdev; - struct buf *bp; - uint64_t blk, offset, last_cno, i; - uint16_t remaining; - int error; -#ifdef INVARIANTS - uint64_t testblk, testoffset; -#endif - - if (cno == 0) { - return (ENOENT); - } - - if (mnmembs < 1) { - return (EINVAL); - } - - fsdev = node->nn_nandfsdev; - last_cno = fsdev->nd_last_cno; - DPRINTF(CPFILE, ("%s: cno:%#jx mnmembs: %#jx last:%#jx\n", __func__, - (uintmax_t)cno, (uintmax_t)mnmembs, - (uintmax_t)fsdev->nd_last_cno)); - - /* - * do { - * get block - * read checkpoints until we hit last checkpoint, end of block or - * requested number - * } while (last read checkpoint <= last checkpoint on fs && - * read checkpoints < request number); - */ - *nmembs = i = 0; - do { - nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset); - remaining = nandfs_checkpoint_blk_remaining(fsdev, cno, - blk, offset); - error = nandfs_bread(node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - while (cno <= last_cno && i < mnmembs && remaining) { -#ifdef INVARIANTS - nandfs_checkpoint_blk_offset(fsdev, cno, &testblk, - &testoffset); - KASSERT(testblk == blk, ("testblk != blk")); - KASSERT(testoffset == offset, ("testoffset != offset")); -#endif - DPRINTF(CPFILE, ("%s: cno %#jx\n", __func__, - (uintmax_t)cno)); - - nandfs_cpinfo_fill((struct nandfs_checkpoint *) - (bp->b_data + offset), nci); - offset += nandfs_checkpoint_size(fsdev); - i++; - nci++; - cno++; - (*nmembs)++; - remaining--; - } - brelse(bp); - } while (cno <= last_cno && i < mnmembs); - - return (0); -} - -static int -nandfs_get_cpinfo_sp(struct nandfs_node *node, uint64_t cno, - struct nandfs_cpinfo *nci, uint32_t mnmembs, uint32_t *nmembs) -{ - struct nandfs_checkpoint *cnp; - struct nandfs_cpfile_header *cnh; - struct nandfs_device *fsdev; - struct buf *bp = NULL; - uint64_t curr = 0; - uint64_t blk, offset, curr_cno; - uint32_t flag; - int i, error; - - if (cno == 0 || cno == ~(0)) - return (ENOENT); - - fsdev = node->nn_nandfsdev; - curr_cno = cno; - - if (nmembs) - *nmembs = 0; - if (curr_cno == 1) { - /* Get list from header */ - error = nandfs_bread(node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - cnh = (struct nandfs_cpfile_header *) bp->b_data; - curr_cno = cnh->ch_snapshot_list.ssl_next; - brelse(bp); - bp = NULL; - - /* No snapshots */ - if (curr_cno == 0) - return (0); - } - - for (i = 0; i < mnmembs; i++, nci++) { - nandfs_checkpoint_blk_offset(fsdev, curr_cno, &blk, &offset); - if (i == 0 || curr != blk) { - if (bp) - brelse(bp); - error = nandfs_bread(node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (ENOENT); - } - curr = blk; - } - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - flag = cnp->cp_flags; - if (!(flag & NANDFS_CHECKPOINT_SNAPSHOT) || - (flag & NANDFS_CHECKPOINT_INVALID)) - break; - - nci->nci_flags = flag; - nci->nci_pad = 0; - nci->nci_cno = cnp->cp_cno; - nci->nci_create = cnp->cp_create; - nci->nci_nblk_inc = cnp->cp_nblk_inc; - nci->nci_blocks_count = cnp->cp_blocks_count; - nci->nci_next = cnp->cp_snapshot_list.ssl_next; - if (nmembs) - (*nmembs)++; - - curr_cno = nci->nci_next; - if (!curr_cno) - break; - } - - brelse(bp); - - return (0); -} - -int -nandfs_get_cpinfo(struct nandfs_node *node, uint64_t cno, uint16_t flags, - struct nandfs_cpinfo *nci, uint32_t nmembs, uint32_t *nnmembs) -{ - int error; - - VOP_LOCK(NTOV(node), LK_EXCLUSIVE); - switch (flags) { - case NANDFS_CHECKPOINT: - error = nandfs_get_cpinfo_cp(node, cno, nci, nmembs, nnmembs); - break; - case NANDFS_SNAPSHOT: - error = nandfs_get_cpinfo_sp(node, cno, nci, nmembs, nnmembs); - break; - default: - error = EINVAL; - break; - } - VOP_UNLOCK(NTOV(node), 0); - - return (error); -} - -int -nandfs_get_cpinfo_ioctl(struct nandfs_node *node, struct nandfs_argv *nargv) -{ - struct nandfs_cpinfo *nci; - uint64_t cno = nargv->nv_index; - void *buf = (void *)((uintptr_t)nargv->nv_base); - uint16_t flags = nargv->nv_flags; - uint32_t nmembs = 0; - int error; - - if (nargv->nv_nmembs > NANDFS_CPINFO_MAX) - return (EINVAL); - - nci = malloc(sizeof(struct nandfs_cpinfo) * nargv->nv_nmembs, - M_NANDFSTEMP, M_WAITOK | M_ZERO); - - error = nandfs_get_cpinfo(node, cno, flags, nci, nargv->nv_nmembs, &nmembs); - - if (error == 0) { - nargv->nv_nmembs = nmembs; - error = copyout(nci, buf, - sizeof(struct nandfs_cpinfo) * nmembs); - } - - free(nci, M_NANDFSTEMP); - return (error); -} - -int -nandfs_delete_cp(struct nandfs_node *node, uint64_t start, uint64_t end) -{ - struct nandfs_checkpoint *cnp; - struct nandfs_device *fsdev; - struct buf *bp; - uint64_t cno = start, blk, offset; - int error; - - DPRINTF(CPFILE, ("%s: delete cno %jx-%jx\n", __func__, start, end)); - VOP_LOCK(NTOV(node), LK_EXCLUSIVE); - fsdev = node->nn_nandfsdev; - for (cno = start; cno <= end; cno++) { - if (!cno) - continue; - - nandfs_checkpoint_blk_offset(fsdev, cno, &blk, &offset); - error = nandfs_bread(node, blk, NOCRED, 0, &bp); - if (error) { - VOP_UNLOCK(NTOV(node), 0); - brelse(bp); - return (error); - } - - cnp = (struct nandfs_checkpoint *)(bp->b_data + offset); - if (cnp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT) { - brelse(bp); - VOP_UNLOCK(NTOV(node), 0); - return (0); - } - - cnp->cp_flags |= NANDFS_CHECKPOINT_INVALID; - - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - } - VOP_UNLOCK(NTOV(node), 0); - - return (0); -} - -int -nandfs_make_snap(struct nandfs_device *fsdev, uint64_t *cno) -{ - struct nandfs_cpmode cpm; - int error; - - *cno = cpm.ncpm_cno = fsdev->nd_last_cno; - cpm.ncpm_mode = NANDFS_SNAPSHOT; - error = nandfs_chng_cpmode(fsdev->nd_cp_node, &cpm); - return (error); -} - -int -nandfs_delete_snap(struct nandfs_device *fsdev, uint64_t cno) -{ - struct nandfs_cpmode cpm; - int error; - - cpm.ncpm_cno = cno; - cpm.ncpm_mode = NANDFS_CHECKPOINT; - error = nandfs_chng_cpmode(fsdev->nd_cp_node, &cpm); - return (error); -} - -int nandfs_get_cpstat(struct nandfs_node *cp_node, struct nandfs_cpstat *ncp) -{ - struct nandfs_device *fsdev; - struct nandfs_cpfile_header *cnh; - struct buf *bp; - int error; - - VOP_LOCK(NTOV(cp_node), LK_EXCLUSIVE); - fsdev = cp_node->nn_nandfsdev; - - /* Get header */ - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - return (error); - } - cnh = (struct nandfs_cpfile_header *) bp->b_data; - ncp->ncp_cno = fsdev->nd_last_cno; - ncp->ncp_ncps = cnh->ch_ncheckpoints; - ncp->ncp_nss = cnh->ch_nsnapshots; - DPRINTF(CPFILE, ("%s: cno:%#jx ncps:%#jx nss:%#jx\n", - __func__, ncp->ncp_cno, ncp->ncp_ncps, ncp->ncp_nss)); - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - - return (0); -} Property changes on: head/sys/fs/nandfs/nandfs_cpfile.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_mount.h =================================================================== --- head/sys/fs/nandfs/nandfs_mount.h (revision 349351) +++ head/sys/fs/nandfs/nandfs_mount.h (nonexistent) @@ -1,52 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-4-Clause - * - * Copyright (c) 2008, 2009 Reinoud Zandijk - * 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. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed for the - * NetBSD Project. See http://www.NetBSD.org/ for - * information about NetBSD. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_mount.h,v 1.1 2009/07/18 16:31:42 reinoud - * - * $FreeBSD$ - */ - -#ifndef _FS_NANDFS_NANDFS_MOUNT_H_ -#define _FS_NANDFS_NANDFS_MOUNT_H_ - -/* - * Arguments to mount NANDFS filingsystem. - */ - -struct nandfs_args { - char *fspec; /* mount specifier */ - int64_t cpno; /* checkpoint number */ -}; - -#endif /* !_FS_NANDFS_NANDFS_MOUNT_H_ */ - Property changes on: head/sys/fs/nandfs/nandfs_mount.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_sufile.c =================================================================== --- head/sys/fs/nandfs/nandfs_sufile.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_sufile.c (nonexistent) @@ -1,571 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define SU_USAGE_OFF(bp, offset) \ - ((struct nandfs_segment_usage *)((bp)->b_data + offset)) - -static int -nandfs_seg_usage_blk_offset(struct nandfs_device *fsdev, uint64_t seg, - uint64_t *blk, uint64_t *offset) -{ - uint64_t off; - uint16_t seg_size; - - seg_size = fsdev->nd_fsdata.f_segment_usage_size; - - off = roundup(sizeof(struct nandfs_sufile_header), seg_size); - off += (seg * seg_size); - - *blk = off / fsdev->nd_blocksize; - *offset = off % fsdev->nd_blocksize; - return (0); -} - -/* Alloc new segment */ -int -nandfs_alloc_segment(struct nandfs_device *fsdev, uint64_t *seg) -{ - struct nandfs_node *su_node; - struct nandfs_sufile_header *su_header; - struct nandfs_segment_usage *su_usage; - struct buf *bp_header, *bp; - uint64_t blk, vblk, offset, i, rest, nsegments; - uint16_t seg_size; - int error, found; - - seg_size = fsdev->nd_fsdata.f_segment_usage_size; - nsegments = fsdev->nd_fsdata.f_nsegments; - - su_node = fsdev->nd_su_node; - ASSERT_VOP_LOCKED(NTOV(su_node), __func__); - - /* Read header buffer */ - error = nandfs_bread(su_node, 0, NOCRED, 0, &bp_header); - if (error) { - brelse(bp_header); - return (error); - } - - su_header = (struct nandfs_sufile_header *)bp_header->b_data; - - /* Get last allocated segment */ - i = su_header->sh_last_alloc + 1; - - found = 0; - bp = NULL; - while (!found) { - nandfs_seg_usage_blk_offset(fsdev, i, &blk, &offset); - if(blk != 0) { - error = nandfs_bmap_lookup(su_node, blk, &vblk); - if (error) { - nandfs_error("%s: cannot find vblk for blk " - "blk:%jx\n", __func__, blk); - return (error); - } - if (vblk) - error = nandfs_bread(su_node, blk, NOCRED, 0, - &bp); - else - error = nandfs_bcreate(su_node, blk, NOCRED, 0, - &bp); - if (error) { - nandfs_error("%s: cannot create/read " - "vblk:%jx\n", __func__, vblk); - if (bp) - brelse(bp); - return (error); - } - - su_usage = SU_USAGE_OFF(bp, offset); - } else { - su_usage = SU_USAGE_OFF(bp_header, offset); - bp = bp_header; - } - - rest = (fsdev->nd_blocksize - offset) / seg_size; - /* Go through all su usage in block */ - while (rest) { - /* When last check start from beginning */ - if (i == nsegments) - break; - - if (!su_usage->su_flags) { - su_usage->su_flags = 1; - found = 1; - break; - } - su_usage++; - i++; - - /* If all checked return error */ - if (i == su_header->sh_last_alloc) { - DPRINTF(SEG, ("%s: cannot allocate segment \n", - __func__)); - brelse(bp_header); - if (blk != 0) - brelse(bp); - return (1); - } - rest--; - } - if (!found) { - /* Otherwise read another block */ - if (blk != 0) - brelse(bp); - if (i == nsegments) { - blk = 0; - i = 0; - } else - blk++; - offset = 0; - } - } - - if (found) { - *seg = i; - su_header->sh_last_alloc = i; - su_header->sh_ncleansegs--; - su_header->sh_ndirtysegs++; - - fsdev->nd_super.s_free_blocks_count = su_header->sh_ncleansegs * - fsdev->nd_fsdata.f_blocks_per_segment; - fsdev->nd_clean_segs--; - - /* - * It is mostly called from syncer() so we want to force - * making buf dirty. - */ - error = nandfs_dirty_buf(bp_header, 1); - if (error) { - if (bp && bp != bp_header) - brelse(bp); - return (error); - } - if (bp && bp != bp_header) - nandfs_dirty_buf(bp, 1); - - DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)i)); - - return (0); - } - - DPRINTF(SEG, ("%s: failed\n", __func__)); - - return (1); -} - -/* - * Make buffer dirty, it will be updated soon but first it need to be - * gathered by syncer. - */ -int -nandfs_touch_segment(struct nandfs_device *fsdev, uint64_t seg) -{ - struct nandfs_node *su_node; - struct buf *bp; - uint64_t blk, offset; - int error; - - su_node = fsdev->nd_su_node; - ASSERT_VOP_LOCKED(NTOV(su_node), __func__); - - nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset); - - error = nandfs_bread(su_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - nandfs_error("%s: cannot preallocate new segment\n", __func__); - return (error); - } else - nandfs_dirty_buf(bp, 1); - - DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg)); - return (error); -} - -/* Update block count of segment */ -int -nandfs_update_segment(struct nandfs_device *fsdev, uint64_t seg, uint32_t nblks) -{ - struct nandfs_node *su_node; - struct nandfs_segment_usage *su_usage; - struct buf *bp; - uint64_t blk, offset; - int error; - - su_node = fsdev->nd_su_node; - ASSERT_VOP_LOCKED(NTOV(su_node), __func__); - - nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset); - - error = nandfs_bread(su_node, blk, NOCRED, 0, &bp); - if (error) { - nandfs_error("%s: read block:%jx to update\n", - __func__, blk); - brelse(bp); - return (error); - } - - su_usage = SU_USAGE_OFF(bp, offset); - su_usage->su_lastmod = fsdev->nd_ts.tv_sec; - su_usage->su_flags = NANDFS_SEGMENT_USAGE_DIRTY; - su_usage->su_nblocks += nblks; - - DPRINTF(SEG, ("%s: seg:%#jx inc:%#x cur:%#x\n", __func__, - (uintmax_t)seg, nblks, su_usage->su_nblocks)); - - nandfs_dirty_buf(bp, 1); - - return (0); -} - -/* Make segment free */ -int -nandfs_free_segment(struct nandfs_device *fsdev, uint64_t seg) -{ - struct nandfs_node *su_node; - struct nandfs_sufile_header *su_header; - struct nandfs_segment_usage *su_usage; - struct buf *bp_header, *bp; - uint64_t blk, offset; - int error; - - su_node = fsdev->nd_su_node; - ASSERT_VOP_LOCKED(NTOV(su_node), __func__); - - /* Read su header */ - error = nandfs_bread(su_node, 0, NOCRED, 0, &bp_header); - if (error) { - brelse(bp_header); - return (error); - } - - su_header = (struct nandfs_sufile_header *)bp_header->b_data; - nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset); - - /* Read su usage block if other than su header block */ - if (blk != 0) { - error = nandfs_bread(su_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - brelse(bp_header); - return (error); - } - } else - bp = bp_header; - - /* Reset su usage data */ - su_usage = SU_USAGE_OFF(bp, offset); - su_usage->su_lastmod = fsdev->nd_ts.tv_sec; - su_usage->su_nblocks = 0; - su_usage->su_flags = 0; - - /* Update clean/dirty counter in header */ - su_header->sh_ncleansegs++; - su_header->sh_ndirtysegs--; - - /* - * Make buffers dirty, called by cleaner - * so force dirty even if no much space left - * on device - */ - nandfs_dirty_buf(bp_header, 1); - if (bp != bp_header) - nandfs_dirty_buf(bp, 1); - - /* Update free block count */ - fsdev->nd_super.s_free_blocks_count = su_header->sh_ncleansegs * - fsdev->nd_fsdata.f_blocks_per_segment; - fsdev->nd_clean_segs++; - - DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg)); - - return (0); -} - -static int -nandfs_bad_segment(struct nandfs_device *fsdev, uint64_t seg) -{ - struct nandfs_node *su_node; - struct nandfs_segment_usage *su_usage; - struct buf *bp; - uint64_t blk, offset; - int error; - - su_node = fsdev->nd_su_node; - ASSERT_VOP_LOCKED(NTOV(su_node), __func__); - - nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset); - - error = nandfs_bread(su_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - su_usage = SU_USAGE_OFF(bp, offset); - su_usage->su_lastmod = fsdev->nd_ts.tv_sec; - su_usage->su_flags = NANDFS_SEGMENT_USAGE_ERROR; - - DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg)); - - nandfs_dirty_buf(bp, 1); - - return (0); -} - -int -nandfs_markgc_segment(struct nandfs_device *fsdev, uint64_t seg) -{ - struct nandfs_node *su_node; - struct nandfs_segment_usage *su_usage; - struct buf *bp; - uint64_t blk, offset; - int error; - - su_node = fsdev->nd_su_node; - - VOP_LOCK(NTOV(su_node), LK_EXCLUSIVE); - - nandfs_seg_usage_blk_offset(fsdev, seg, &blk, &offset); - - error = nandfs_bread(su_node, blk, NOCRED, 0, &bp); - if (error) { - brelse(bp); - VOP_UNLOCK(NTOV(su_node), 0); - return (error); - } - - su_usage = SU_USAGE_OFF(bp, offset); - MPASS((su_usage->su_flags & NANDFS_SEGMENT_USAGE_GC) == 0); - su_usage->su_flags |= NANDFS_SEGMENT_USAGE_GC; - - brelse(bp); - VOP_UNLOCK(NTOV(su_node), 0); - - DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg)); - - return (0); -} - -int -nandfs_clear_segment(struct nandfs_device *fsdev, uint64_t seg) -{ - uint64_t offset, segsize; - uint32_t bps, bsize; - int error = 0; - - bps = fsdev->nd_fsdata.f_blocks_per_segment; - bsize = fsdev->nd_blocksize; - segsize = bsize * bps; - nandfs_get_segment_range(fsdev, seg, &offset, NULL); - offset *= bsize; - - DPRINTF(SEG, ("%s: seg:%#jx\n", __func__, (uintmax_t)seg)); - - /* Erase it and mark it bad when fail */ - if (nandfs_erase(fsdev, offset, segsize)) - error = nandfs_bad_segment(fsdev, seg); - - if (error) - return (error); - - /* Mark it free */ - error = nandfs_free_segment(fsdev, seg); - - return (error); -} - -int -nandfs_get_seg_stat(struct nandfs_device *nandfsdev, - struct nandfs_seg_stat *nss) -{ - struct nandfs_sufile_header *suhdr; - struct nandfs_node *su_node; - struct buf *bp; - int err; - - su_node = nandfsdev->nd_su_node; - - NANDFS_WRITELOCK(nandfsdev); - VOP_LOCK(NTOV(su_node), LK_SHARED); - err = nandfs_bread(nandfsdev->nd_su_node, 0, NOCRED, 0, &bp); - if (err) { - brelse(bp); - VOP_UNLOCK(NTOV(su_node), 0); - NANDFS_WRITEUNLOCK(nandfsdev); - return (-1); - } - - suhdr = (struct nandfs_sufile_header *)bp->b_data; - nss->nss_nsegs = nandfsdev->nd_fsdata.f_nsegments; - nss->nss_ncleansegs = suhdr->sh_ncleansegs; - nss->nss_ndirtysegs = suhdr->sh_ndirtysegs; - nss->nss_ctime = 0; - nss->nss_nongc_ctime = nandfsdev->nd_ts.tv_sec; - nss->nss_prot_seq = nandfsdev->nd_seg_sequence; - - brelse(bp); - VOP_UNLOCK(NTOV(su_node), 0); - - NANDFS_WRITEUNLOCK(nandfsdev); - - return (0); -} - -int -nandfs_get_segment_info_ioctl(struct nandfs_device *fsdev, - struct nandfs_argv *nargv) -{ - struct nandfs_suinfo *nsi; - int error; - - if (nargv->nv_nmembs > NANDFS_SEGMENTS_MAX) - return (EINVAL); - - nsi = malloc(sizeof(struct nandfs_suinfo) * nargv->nv_nmembs, - M_NANDFSTEMP, M_WAITOK | M_ZERO); - - error = nandfs_get_segment_info(fsdev, nsi, nargv->nv_nmembs, - nargv->nv_index); - - if (error == 0) - error = copyout(nsi, (void *)(uintptr_t)nargv->nv_base, - sizeof(struct nandfs_suinfo) * nargv->nv_nmembs); - - free(nsi, M_NANDFSTEMP); - return (error); -} - -int -nandfs_get_segment_info(struct nandfs_device *fsdev, struct nandfs_suinfo *nsi, - uint32_t nmembs, uint64_t segment) -{ - - return (nandfs_get_segment_info_filter(fsdev, nsi, nmembs, segment, - NULL, 0, 0)); -} - -int -nandfs_get_segment_info_filter(struct nandfs_device *fsdev, - struct nandfs_suinfo *nsi, uint32_t nmembs, uint64_t segment, - uint64_t *nsegs, uint32_t filter, uint32_t nfilter) -{ - struct nandfs_segment_usage *su; - struct nandfs_node *su_node; - struct buf *bp; - uint64_t curr, blocknr, blockoff, i; - uint32_t flags; - int err = 0; - - curr = ~(0); - - lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL); - su_node = fsdev->nd_su_node; - - VOP_LOCK(NTOV(su_node), LK_SHARED); - - bp = NULL; - if (nsegs != NULL) - *nsegs = 0; - for (i = 0; i < nmembs; segment++) { - if (segment == fsdev->nd_fsdata.f_nsegments) - break; - - nandfs_seg_usage_blk_offset(fsdev, segment, &blocknr, - &blockoff); - - if (i == 0 || curr != blocknr) { - if (bp != NULL) - brelse(bp); - err = nandfs_bread(su_node, blocknr, NOCRED, - 0, &bp); - if (err) { - goto out; - } - curr = blocknr; - } - - su = SU_USAGE_OFF(bp, blockoff); - flags = su->su_flags; - if (segment == fsdev->nd_seg_num || - segment == fsdev->nd_next_seg_num) - flags |= NANDFS_SEGMENT_USAGE_ACTIVE; - - if (nfilter != 0 && (flags & nfilter) != 0) - continue; - if (filter != 0 && (flags & filter) == 0) - continue; - - nsi->nsi_num = segment; - nsi->nsi_lastmod = su->su_lastmod; - nsi->nsi_blocks = su->su_nblocks; - nsi->nsi_flags = flags; - nsi++; - i++; - if (nsegs != NULL) - (*nsegs)++; - } - -out: - if (bp != NULL) - brelse(bp); - VOP_UNLOCK(NTOV(su_node), 0); - lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL); - - return (err); -} Property changes on: head/sys/fs/nandfs/nandfs_sufile.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_segment.c =================================================================== --- head/sys/fs/nandfs/nandfs_segment.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_segment.c (nonexistent) @@ -1,1314 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_ddb.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -static int -nandfs_new_segment(struct nandfs_device *fsdev) -{ - int error = 0; - uint64_t new; - - error = nandfs_alloc_segment(fsdev, &new); - if (!error) { - fsdev->nd_seg_num = fsdev->nd_next_seg_num; - fsdev->nd_next_seg_num = new; - } - DPRINTF(SYNC, ("%s: new segment %jx next %jx error %d\n", - __func__, (uintmax_t)fsdev->nd_seg_num, (uintmax_t)new, error)); - if (error) - nandfs_error("%s: cannot create segment error %d\n", - __func__, error); - - return (error); -} - -static int -create_segment(struct nandfs_seginfo *seginfo) -{ - struct nandfs_segment *seg; - struct nandfs_device *fsdev; - struct nandfs_segment *prev; - struct buf *bp; - uint64_t start_block, curr; - uint32_t blks_per_seg, nblocks; - int error; - - fsdev = seginfo->fsdev; - prev = seginfo->curseg; - blks_per_seg = fsdev->nd_fsdata.f_blocks_per_segment; - nblocks = fsdev->nd_last_segsum.ss_nblocks; - - if (!prev) { - vfs_timestamp(&fsdev->nd_ts); - /* Touch current segment */ - error = nandfs_touch_segment(fsdev, fsdev->nd_seg_num); - if (error) { - nandfs_error("%s: cannot preallocate segment %jx\n", - __func__, fsdev->nd_seg_num); - return (error); - } - error = nandfs_touch_segment(fsdev, 0); - if (error) { - nandfs_error("%s: cannot dirty block with segment 0\n", - __func__); - return (error); - } - start_block = fsdev->nd_last_pseg + (uint64_t)nblocks; - /* - * XXX Hack - */ - if (blks_per_seg - (start_block % blks_per_seg) - 1 == 0) - start_block++; - curr = nandfs_get_segnum_of_block(fsdev, start_block); - /* Allocate new segment if last one is full */ - if (fsdev->nd_seg_num != curr) { - error = nandfs_new_segment(fsdev); - if (error) { - nandfs_error("%s: cannot create new segment\n", - __func__); - return (error); - } - /* - * XXX Hack - */ - nandfs_get_segment_range(fsdev, fsdev->nd_seg_num, &start_block, NULL); - } - } else { - nandfs_get_segment_range(fsdev, fsdev->nd_next_seg_num, - &start_block, NULL); - - /* Touch current segment and allocate and touch new one */ - error = nandfs_new_segment(fsdev); - if (error) { - nandfs_error("%s: cannot create next segment\n", - __func__); - return (error); - } - - /* Reiterate in case new buf is dirty */ - seginfo->reiterate = 1; - } - - /* Allocate and initialize nandfs_segment structure */ - seg = malloc(sizeof(*seg), M_DEVBUF, M_WAITOK|M_ZERO); - TAILQ_INIT(&seg->segsum); - TAILQ_INIT(&seg->data); - seg->fsdev = fsdev; - seg->start_block = start_block; - seg->num_blocks = blks_per_seg - (start_block % blks_per_seg) - 1; - seg->seg_num = fsdev->nd_seg_num; - seg->seg_next = fsdev->nd_next_seg_num; - seg->segsum_blocks = 1; - seg->bytes_left = fsdev->nd_blocksize - - sizeof(struct nandfs_segment_summary); - seg->segsum_bytes = sizeof(struct nandfs_segment_summary); - - /* Allocate buffer for segment summary */ - bp = getblk(fsdev->nd_devvp, nandfs_block_to_dblock(fsdev, - seg->start_block), fsdev->nd_blocksize, 0, 0, 0); - bzero(bp->b_data, seginfo->fsdev->nd_blocksize); - bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj; - bp->b_flags |= B_MANAGED; - - /* Add buffer to segment */ - TAILQ_INSERT_TAIL(&seg->segsum, bp, b_cluster.cluster_entry); - seg->current_off = bp->b_data + sizeof(struct nandfs_segment_summary); - - DPRINTF(SYNC, ("%s: seg %p : initial settings: start %#jx size :%#x\n", - __func__, seg, (uintmax_t)seg->start_block, seg->num_blocks)); - DPRINTF(SYNC, ("%s: seg->seg_num %#jx cno %#jx next %#jx\n", __func__, - (uintmax_t)seg->seg_num, (uintmax_t)(fsdev->nd_last_cno + 1), - (uintmax_t)seg->seg_next)); - - if (!prev) - LIST_INSERT_HEAD(&seginfo->seg_list, seg, seg_link); - else - LIST_INSERT_AFTER(prev, seg, seg_link); - - seginfo->curseg = seg; - - return (0); -} - -static int -delete_segment(struct nandfs_seginfo *seginfo) -{ - struct nandfs_segment *seg, *tseg; - struct buf *bp, *tbp; - - LIST_FOREACH_SAFE(seg, &seginfo->seg_list, seg_link, tseg) { - TAILQ_FOREACH_SAFE(bp, &seg->segsum, b_cluster.cluster_entry, - tbp) { - TAILQ_REMOVE(&seg->segsum, bp, b_cluster.cluster_entry); - bp->b_flags &= ~B_MANAGED; - brelse(bp); - } - - LIST_REMOVE(seg, seg_link); - free(seg, M_DEVBUF); - } - - return (0); -} - -static int -create_seginfo(struct nandfs_device *fsdev, struct nandfs_seginfo **seginfo) -{ - struct nandfs_seginfo *info; - - info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK); - - LIST_INIT(&info->seg_list); - info->fsdev = fsdev; - info->curseg = NULL; - info->blocks = 0; - *seginfo = info; - fsdev->nd_seginfo = info; - return (0); -} - -static int -delete_seginfo(struct nandfs_seginfo *seginfo) -{ - struct nandfs_device *nffsdev; - - nffsdev = seginfo->fsdev; - delete_segment(seginfo); - nffsdev->nd_seginfo = NULL; - free(seginfo, M_DEVBUF); - - return (0); -} - -static int -nandfs_create_superroot_block(struct nandfs_seginfo *seginfo, - struct buf **newbp) -{ - struct buf *bp; - int error; - - bp = nandfs_geteblk(seginfo->fsdev->nd_blocksize, GB_NOWAIT_BD); - - bzero(bp->b_data, seginfo->fsdev->nd_blocksize); - bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj; - bp->b_flags |= B_MANAGED; - - if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) { - error = create_segment(seginfo); - if (error) { - brelse(bp); - nandfs_error("%s: no segment for superroot\n", - __func__); - return (error); - } - } - - TAILQ_INSERT_TAIL(&seginfo->curseg->data, bp, b_cluster.cluster_entry); - - seginfo->curseg->nblocks++; - seginfo->curseg->num_blocks--; - seginfo->blocks++; - - *newbp = bp; - return (0); -} - -static int -nandfs_add_superroot(struct nandfs_seginfo *seginfo) -{ - struct nandfs_device *fsdev; - struct nandfs_super_root *sr; - struct buf *bp = NULL; - uint64_t crc_skip; - uint32_t crc_calc; - int error; - - fsdev = seginfo->fsdev; - - error = nandfs_create_superroot_block(seginfo, &bp); - if (error) { - nandfs_error("%s: cannot add superroot\n", __func__); - return (error); - } - - sr = (struct nandfs_super_root *)bp->b_data; - /* Save superroot CRC */ - sr->sr_bytes = NANDFS_SR_BYTES; - sr->sr_flags = 0; - sr->sr_nongc_ctime = 0; - - memcpy(&sr->sr_dat, &fsdev->nd_dat_node->nn_inode, - sizeof(struct nandfs_inode)); - memcpy(&sr->sr_cpfile, &fsdev->nd_cp_node->nn_inode, - sizeof(struct nandfs_inode)); - memcpy(&sr->sr_sufile, &fsdev->nd_su_node->nn_inode, - sizeof(struct nandfs_inode)); - - crc_skip = sizeof(sr->sr_sum); - crc_calc = crc32((uint8_t *)sr + crc_skip, NANDFS_SR_BYTES - crc_skip); - - sr->sr_sum = crc_calc; - - bp->b_flags |= B_MANAGED; - bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj; - - bp->b_flags &= ~B_INVAL; - nandfs_dirty_bufs_increment(fsdev); - DPRINTF(SYNC, ("%s: bp:%p\n", __func__, bp)); - - return (0); -} - -static int -nandfs_add_segsum_block(struct nandfs_seginfo *seginfo, struct buf **newbp) -{ - struct nandfs_device *fsdev; - nandfs_daddr_t blk; - struct buf *bp; - int error; - - if (!(seginfo->curseg) || seginfo->curseg->num_blocks <= 1) { - error = create_segment(seginfo); - if (error) { - nandfs_error("%s: error:%d when creating segment\n", - __func__, error); - return (error); - } - *newbp = TAILQ_FIRST(&seginfo->curseg->segsum); - return (0); - } - - fsdev = seginfo->fsdev; - blk = nandfs_block_to_dblock(fsdev, seginfo->curseg->start_block + - seginfo->curseg->segsum_blocks); - - bp = getblk(fsdev->nd_devvp, blk, fsdev->nd_blocksize, 0, 0, 0); - - bzero(bp->b_data, seginfo->fsdev->nd_blocksize); - bp->b_bufobj = &seginfo->fsdev->nd_devvp->v_bufobj; - bp->b_flags |= B_MANAGED; - - TAILQ_INSERT_TAIL(&seginfo->curseg->segsum, bp, - b_cluster.cluster_entry); - seginfo->curseg->num_blocks--; - - seginfo->curseg->segsum_blocks++; - seginfo->curseg->bytes_left = seginfo->fsdev->nd_blocksize; - seginfo->curseg->current_off = bp->b_data; - seginfo->blocks++; - - *newbp = bp; - - DPRINTF(SYNC, ("%s: bp %p\n", __func__, bp)); - - return (0); -} - -static int -nandfs_add_blocks(struct nandfs_seginfo *seginfo, struct nandfs_node *node, - struct buf *bp) -{ - union nandfs_binfo *binfo; - struct buf *seg_bp; - int error; - - if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) { - error = create_segment(seginfo); - if (error) { - nandfs_error("%s: error:%d when creating segment\n", - __func__, error); - return (error); - } - } - - if (seginfo->curseg->bytes_left < sizeof(union nandfs_binfo)) { - error = nandfs_add_segsum_block(seginfo, &seg_bp); - if (error) { - nandfs_error("%s: error:%d when adding segsum\n", - __func__, error); - return (error); - } - } - binfo = (union nandfs_binfo *)seginfo->curseg->current_off; - - if (node->nn_ino != NANDFS_DAT_INO) { - binfo->bi_v.bi_blkoff = bp->b_lblkno; - binfo->bi_v.bi_ino = node->nn_ino; - } else { - binfo->bi_dat.bi_blkoff = bp->b_lblkno; - binfo->bi_dat.bi_ino = node->nn_ino; - if (NANDFS_IS_INDIRECT(bp)) - binfo->bi_dat.bi_level = 1; - else - binfo->bi_dat.bi_level = 0; - } - binfo++; - - seginfo->curseg->bytes_left -= sizeof(union nandfs_binfo); - seginfo->curseg->segsum_bytes += sizeof(union nandfs_binfo); - seginfo->curseg->current_off = (char *)binfo; - - TAILQ_INSERT_TAIL(&seginfo->curseg->data, bp, b_cluster.cluster_entry); - - seginfo->curseg->nbinfos++; - seginfo->curseg->nblocks++; - seginfo->curseg->num_blocks--; - seginfo->blocks++; - - DPRINTF(SYNC, ("%s: bp (%p) number %x (left %x)\n", - __func__, bp, seginfo->curseg->nblocks, - seginfo->curseg->num_blocks)); - return (0); -} - -static int -nandfs_iterate_dirty_buf(struct vnode *vp, struct nandfs_seginfo *seginfo, - uint8_t hold) -{ - struct buf *bp, *tbd; - struct bufobj *bo; - struct nandfs_node *node; - int error; - - node = VTON(vp); - bo = &vp->v_bufobj; - - ASSERT_VOP_ELOCKED(vp, __func__); - - /* Iterate dirty data bufs */ - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, tbd) { - DPRINTF(SYNC, ("%s: vp (%p): bp (%p) with lblkno %jx ino %jx " - "add buf\n", __func__, vp, bp, bp->b_lblkno, node->nn_ino)); - - if (!(NANDFS_ISGATHERED(bp))) { - error = nandfs_bmap_update_dat(node, - nandfs_vblk_get(bp), bp); - if (error) - return (error); - NANDFS_GATHER(bp); - nandfs_add_blocks(seginfo, node, bp); - } - } - - return (0); -} - -static int -nandfs_iterate_system_vnode(struct nandfs_node *node, - struct nandfs_seginfo *seginfo) -{ - struct vnode *vp; - int nblocks; - uint8_t hold = 0; - - if (node->nn_ino != NANDFS_IFILE_INO) - hold = 1; - - vp = NTOV(node); - - nblocks = vp->v_bufobj.bo_dirty.bv_cnt; - DPRINTF(SYNC, ("%s: vp (%p): nblocks %x ino %jx\n", - __func__, vp, nblocks, node->nn_ino)); - - if (nblocks) - nandfs_iterate_dirty_buf(vp, seginfo, hold); - - return (0); -} - -static int -nandfs_iterate_dirty_vnodes(struct mount *mp, struct nandfs_seginfo *seginfo) -{ - struct nandfs_node *nandfs_node; - struct vnode *vp, *mvp; - struct thread *td; - struct bufobj *bo; - int error, update; - - td = curthread; - - MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) { - update = 0; - - if (mp->mnt_syncer == vp || VOP_ISLOCKED(vp)) { - VI_UNLOCK(vp); - continue; - } - if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT, td) != 0) - continue; - - nandfs_node = VTON(vp); - if (nandfs_node->nn_flags & IN_MODIFIED) { - nandfs_node->nn_flags &= ~(IN_MODIFIED); - update = 1; - } - - bo = &vp->v_bufobj; - BO_LOCK(bo); - if (vp->v_bufobj.bo_dirty.bv_cnt) { - error = nandfs_iterate_dirty_buf(vp, seginfo, 0); - if (error) { - nandfs_error("%s: cannot iterate vnode:%p " - "err:%d\n", __func__, vp, error); - vput(vp); - BO_UNLOCK(bo); - return (error); - } - update = 1; - } else - vput(vp); - BO_UNLOCK(bo); - - if (update) - nandfs_node_update(nandfs_node); - } - - return (0); -} - -static int -nandfs_update_phys_block(struct nandfs_device *fsdev, struct buf *bp, - uint64_t phys_blknr, union nandfs_binfo *binfo) -{ - struct nandfs_node *node, *dat; - struct vnode *vp; - uint64_t new_blknr; - int error; - - vp = bp->b_vp; - node = VTON(vp); - new_blknr = nandfs_vblk_get(bp); - dat = fsdev->nd_dat_node; - - DPRINTF(BMAP, ("%s: ino %#jx lblk %#jx: vblk %#jx -> %#jx\n", - __func__, (uintmax_t)node->nn_ino, (uintmax_t)bp->b_lblkno, - (uintmax_t)new_blknr, (uintmax_t)phys_blknr)); - - if (node->nn_ino != NANDFS_DAT_INO) { - KASSERT((new_blknr != 0), ("vblk for bp %p is 0", bp)); - - nandfs_vblock_assign(fsdev, new_blknr, phys_blknr); - binfo->bi_v.bi_vblocknr = new_blknr; - binfo->bi_v.bi_blkoff = bp->b_lblkno; - binfo->bi_v.bi_ino = node->nn_ino; - } else { - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - error = nandfs_bmap_update_block(node, bp, phys_blknr); - if (error) { - nandfs_error("%s: error updating block:%jx for bp:%p\n", - __func__, (uintmax_t)phys_blknr, bp); - VOP_UNLOCK(NTOV(dat), 0); - return (error); - } - VOP_UNLOCK(NTOV(dat), 0); - binfo->bi_dat.bi_blkoff = bp->b_lblkno; - binfo->bi_dat.bi_ino = node->nn_ino; - if (NANDFS_IS_INDIRECT(bp)) - binfo->bi_dat.bi_level = 1; - else - binfo->bi_dat.bi_level = 0; - } - - return (0); -} - -#define NBINFO(off) ((off) + sizeof(union nandfs_binfo)) -static int -nandfs_segment_assign_pblk(struct nandfs_segment *nfsseg) -{ - struct nandfs_device *fsdev; - union nandfs_binfo *binfo; - struct buf *bp, *seg_bp; - uint64_t blocknr; - uint32_t curr_off, blocksize; - int error; - - fsdev = nfsseg->fsdev; - blocksize = fsdev->nd_blocksize; - - blocknr = nfsseg->start_block + nfsseg->segsum_blocks; - seg_bp = TAILQ_FIRST(&nfsseg->segsum); - DPRINTF(SYNC, ("%s: seg:%p segsum bp:%p data:%p\n", - __func__, nfsseg, seg_bp, seg_bp->b_data)); - - binfo = (union nandfs_binfo *)(seg_bp->b_data + - sizeof(struct nandfs_segment_summary)); - curr_off = sizeof(struct nandfs_segment_summary); - - TAILQ_FOREACH(bp, &nfsseg->data, b_cluster.cluster_entry) { - KASSERT((bp->b_vp), ("bp %p has not vp", bp)); - - DPRINTF(BMAP, ("\n\n%s: assign buf %p for ino %#jx next %p\n", - __func__, bp, (uintmax_t)VTON(bp->b_vp)->nn_ino, - TAILQ_NEXT(bp, b_cluster.cluster_entry))); - - if (NBINFO(curr_off) > blocksize) { - seg_bp = TAILQ_NEXT(seg_bp, b_cluster.cluster_entry); - binfo = (union nandfs_binfo *)seg_bp->b_data; - curr_off = 0; - DPRINTF(SYNC, ("%s: next segsum %p data %p\n", - __func__, seg_bp, seg_bp->b_data)); - } - - error = nandfs_update_phys_block(fsdev, bp, blocknr, binfo); - if (error) { - nandfs_error("%s: err:%d when updatinng phys block:%jx" - " for bp:%p and binfo:%p\n", __func__, error, - (uintmax_t)blocknr, bp, binfo); - return (error); - } - binfo++; - curr_off = NBINFO(curr_off); - - blocknr++; - } - - return (0); -} - -static int -nandfs_seginfo_assign_pblk(struct nandfs_seginfo *seginfo) -{ - struct nandfs_segment *nfsseg; - int error = 0; - - LIST_FOREACH(nfsseg, &seginfo->seg_list, seg_link) { - error = nandfs_segment_assign_pblk(nfsseg); - if (error) - break; - } - - return (error); -} - -static struct nandfs_segment_summary * -nandfs_fill_segsum(struct nandfs_segment *seg, int has_sr) -{ - struct nandfs_segment_summary *ss; - struct nandfs_device *fsdev; - struct buf *bp; - uint32_t rest, segsum_size, blocksize, crc_calc; - uint16_t flags; - uint8_t *crc_area, crc_skip; - - DPRINTF(SYNC, ("%s: seg %#jx nblocks %#x sumbytes %#x\n", - __func__, (uintmax_t) seg->seg_num, - seg->nblocks + seg->segsum_blocks, - seg->segsum_bytes)); - - fsdev = seg->fsdev; - - flags = NANDFS_SS_LOGBGN | NANDFS_SS_LOGEND; - if (has_sr) - flags |= NANDFS_SS_SR; - - bp = TAILQ_FIRST(&seg->segsum); - ss = (struct nandfs_segment_summary *) bp->b_data; - ss->ss_magic = NANDFS_SEGSUM_MAGIC; - ss->ss_bytes = sizeof(struct nandfs_segment_summary); - ss->ss_flags = flags; - ss->ss_seq = ++(fsdev->nd_seg_sequence); - ss->ss_create = fsdev->nd_ts.tv_sec; - nandfs_get_segment_range(fsdev, seg->seg_next, &ss->ss_next, NULL); - ss->ss_nblocks = seg->nblocks + seg->segsum_blocks; - ss->ss_nbinfos = seg->nbinfos; - ss->ss_sumbytes = seg->segsum_bytes; - - crc_skip = sizeof(ss->ss_datasum) + sizeof(ss->ss_sumsum); - blocksize = seg->fsdev->nd_blocksize; - - segsum_size = seg->segsum_bytes - crc_skip; - rest = min(seg->segsum_bytes, blocksize) - crc_skip; - crc_area = (uint8_t *)ss + crc_skip; - crc_calc = ~0U; - while (segsum_size > 0) { - crc_calc = crc32_raw(crc_area, rest, crc_calc); - segsum_size -= rest; - if (!segsum_size) - break; - bp = TAILQ_NEXT(bp, b_cluster.cluster_entry); - crc_area = (uint8_t *)bp->b_data; - rest = segsum_size <= blocksize ? segsum_size : blocksize; - } - ss->ss_sumsum = crc_calc ^ ~0U; - - return (ss); - -} - -static int -nandfs_save_buf(struct buf *bp, uint64_t blocknr, struct nandfs_device *fsdev) -{ - struct bufobj *bo; - int error; - - bo = &fsdev->nd_devvp->v_bufobj; - - bp->b_blkno = nandfs_block_to_dblock(fsdev, blocknr); - bp->b_iooffset = dbtob(bp->b_blkno); - - KASSERT(bp->b_bufobj != NULL, ("no bufobj for %p", bp)); - if (bp->b_bufobj != bo) { - BO_LOCK(bp->b_bufobj); - BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, - BO_LOCKPTR(bp->b_bufobj)); - KASSERT(BUF_ISLOCKED(bp), ("Problem with locking buffer")); - } - - DPRINTF(SYNC, ("%s: buf: %p offset %#jx blk %#jx size %#x\n", - __func__, bp, (uintmax_t)bp->b_offset, (uintmax_t)blocknr, - fsdev->nd_blocksize)); - - NANDFS_UNGATHER(bp); - nandfs_buf_clear(bp, 0xffffffff); - bp->b_flags &= ~(B_ASYNC|B_INVAL|B_MANAGED); - error = bwrite(bp); - if (error) { - nandfs_error("%s: error:%d when writing buffer:%p\n", - __func__, error, bp); - return (error); - } - return (error); -} - -static void -nandfs_clean_buf(struct nandfs_device *fsdev, struct buf *bp) -{ - - DPRINTF(SYNC, ("%s: buf: %p\n", __func__, bp)); - - NANDFS_UNGATHER(bp); - nandfs_buf_clear(bp, 0xffffffff); - bp->b_flags &= ~(B_ASYNC|B_INVAL|B_MANAGED); - nandfs_undirty_buf_fsdev(fsdev, bp); -} - -static void -nandfs_clean_segblocks(struct nandfs_segment *seg, uint8_t unlock) -{ - struct nandfs_device *fsdev = seg->fsdev; - struct nandfs_segment *next_seg; - struct buf *bp, *tbp, *next_bp; - struct vnode *vp, *next_vp; - - VOP_LOCK(fsdev->nd_devvp, LK_EXCLUSIVE); - TAILQ_FOREACH_SAFE(bp, &seg->segsum, b_cluster.cluster_entry, tbp) { - TAILQ_REMOVE(&seg->segsum, bp, b_cluster.cluster_entry); - nandfs_clean_buf(fsdev, bp); - } - - TAILQ_FOREACH_SAFE(bp, &seg->data, b_cluster.cluster_entry, tbp) { - TAILQ_REMOVE(&seg->data, bp, b_cluster.cluster_entry); - - /* - * If bp is not super-root and vnode is not currently - * locked lock it. - */ - vp = bp->b_vp; - next_vp = NULL; - next_bp = TAILQ_NEXT(bp, b_cluster.cluster_entry); - if (!next_bp) { - next_seg = LIST_NEXT(seg, seg_link); - if (next_seg) - next_bp = TAILQ_FIRST(&next_seg->data); - } - - if (next_bp) - next_vp = next_bp->b_vp; - - nandfs_clean_buf(fsdev, bp); - - if (unlock && vp != NULL && next_vp != vp && - !NANDFS_SYS_NODE(VTON(vp)->nn_ino)) - vput(vp); - - nandfs_dirty_bufs_decrement(fsdev); - } - - VOP_UNLOCK(fsdev->nd_devvp, 0); -} - -static int -nandfs_save_segblocks(struct nandfs_segment *seg, uint8_t unlock) -{ - struct nandfs_device *fsdev = seg->fsdev; - struct nandfs_segment *next_seg; - struct buf *bp, *tbp, *next_bp; - struct vnode *vp, *next_vp; - uint64_t blocknr; - uint32_t i = 0; - int error = 0; - - VOP_LOCK(fsdev->nd_devvp, LK_EXCLUSIVE); - TAILQ_FOREACH_SAFE(bp, &seg->segsum, b_cluster.cluster_entry, tbp) { - TAILQ_REMOVE(&seg->segsum, bp, b_cluster.cluster_entry); - blocknr = seg->start_block + i; - error = nandfs_save_buf(bp, blocknr, fsdev); - if (error) { - nandfs_error("%s: error saving buf: %p blocknr:%jx\n", - __func__, bp, (uintmax_t)blocknr); - goto out; - } - i++; - } - - i = 0; - TAILQ_FOREACH_SAFE(bp, &seg->data, b_cluster.cluster_entry, tbp) { - TAILQ_REMOVE(&seg->data, bp, b_cluster.cluster_entry); - - blocknr = seg->start_block + seg->segsum_blocks + i; - /* - * If bp is not super-root and vnode is not currently - * locked lock it. - */ - vp = bp->b_vp; - next_vp = NULL; - next_bp = TAILQ_NEXT(bp, b_cluster.cluster_entry); - if (!next_bp) { - next_seg = LIST_NEXT(seg, seg_link); - if (next_seg) - next_bp = TAILQ_FIRST(&next_seg->data); - } - - if (next_bp) - next_vp = next_bp->b_vp; - - error = nandfs_save_buf(bp, blocknr, fsdev); - if (error) { - nandfs_error("%s: error saving buf: %p blknr: %jx\n", - __func__, bp, (uintmax_t)blocknr); - if (unlock && vp != NULL && next_vp != vp && - !NANDFS_SYS_NODE(VTON(vp)->nn_ino)) - vput(vp); - goto out; - } - - if (unlock && vp != NULL && next_vp != vp && - !NANDFS_SYS_NODE(VTON(vp)->nn_ino)) - vput(vp); - - i++; - nandfs_dirty_bufs_decrement(fsdev); - } -out: - if (error) { - nandfs_clean_segblocks(seg, unlock); - VOP_UNLOCK(fsdev->nd_devvp, 0); - return (error); - } - - VOP_UNLOCK(fsdev->nd_devvp, 0); - return (error); -} - - -static void -clean_seginfo(struct nandfs_seginfo *seginfo, uint8_t unlock) -{ - struct nandfs_segment *seg; - - DPRINTF(SYNC, ("%s: seginfo %p\n", __func__, seginfo)); - - LIST_FOREACH(seg, &seginfo->seg_list, seg_link) { - nandfs_clean_segblocks(seg, unlock); - } -} - -static int -save_seginfo(struct nandfs_seginfo *seginfo, uint8_t unlock) -{ - struct nandfs_segment *seg; - struct nandfs_device *fsdev; - struct nandfs_segment_summary *ss; - int error = 0; - - fsdev = seginfo->fsdev; - - DPRINTF(SYNC, ("%s: seginfo %p\n", __func__, seginfo)); - - LIST_FOREACH(seg, &seginfo->seg_list, seg_link) { - if (LIST_NEXT(seg, seg_link)) { - nandfs_fill_segsum(seg, 0); - error = nandfs_save_segblocks(seg, unlock); - if (error) { - nandfs_error("%s: error:%d saving seg:%p\n", - __func__, error, seg); - goto out; - } - } else { - ss = nandfs_fill_segsum(seg, 1); - fsdev->nd_last_segsum = *ss; - error = nandfs_save_segblocks(seg, unlock); - if (error) { - nandfs_error("%s: error:%d saving seg:%p\n", - __func__, error, seg); - goto out; - } - fsdev->nd_last_cno++; - fsdev->nd_last_pseg = seg->start_block; - } - } -out: - if (error) - clean_seginfo(seginfo, unlock); - return (error); -} - -static void -nandfs_invalidate_bufs(struct nandfs_device *fsdev, uint64_t segno) -{ - uint64_t start, end; - struct buf *bp, *tbd; - struct bufobj *bo; - - nandfs_get_segment_range(fsdev, segno, &start, &end); - - bo = &NTOV(fsdev->nd_gc_node)->v_bufobj; - - BO_LOCK(bo); -restart_locked_gc: - TAILQ_FOREACH_SAFE(bp, &bo->bo_clean.bv_hd, b_bobufs, tbd) { - if (!(bp->b_lblkno >= start && bp->b_lblkno <= end)) - continue; - - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) - goto restart_locked_gc; - - bremfree(bp); - bp->b_flags |= (B_INVAL | B_RELBUF); - bp->b_flags &= ~(B_ASYNC | B_MANAGED); - BO_UNLOCK(bo); - brelse(bp); - BO_LOCK(bo); - } - BO_UNLOCK(bo); -} - -/* Process segments marks to free by cleaner */ -static void -nandfs_process_segments(struct nandfs_device *fsdev) -{ - uint64_t saved_segment; - int i; - - if (fsdev->nd_free_base) { - saved_segment = nandfs_get_segnum_of_block(fsdev, - fsdev->nd_super.s_last_pseg); - for (i = 0; i < fsdev->nd_free_count; i++) { - if (fsdev->nd_free_base[i] == NANDFS_NOSEGMENT) - continue; - /* Update superblock if clearing segment point by it */ - if (fsdev->nd_free_base[i] == saved_segment) { - nandfs_write_superblock(fsdev); - saved_segment = nandfs_get_segnum_of_block( - fsdev, fsdev->nd_super.s_last_pseg); - } - nandfs_invalidate_bufs(fsdev, fsdev->nd_free_base[i]); - nandfs_clear_segment(fsdev, fsdev->nd_free_base[i]); - } - - free(fsdev->nd_free_base, M_NANDFSTEMP); - fsdev->nd_free_base = NULL; - fsdev->nd_free_count = 0; - } -} - -/* Collect and write dirty buffers */ -int -nandfs_sync_file(struct vnode *vp) -{ - struct nandfs_device *fsdev; - struct nandfs_node *nandfs_node; - struct nandfsmount *nmp; - struct nandfs_node *dat, *su, *ifile, *cp; - struct nandfs_seginfo *seginfo = NULL; - struct nandfs_segment *seg; - int update, error; - int cno_changed; - - ASSERT_VOP_LOCKED(vp, __func__); - DPRINTF(SYNC, ("%s: START\n", __func__)); - - error = 0; - nmp = VFSTONANDFS(vp->v_mount); - fsdev = nmp->nm_nandfsdev; - - dat = fsdev->nd_dat_node; - su = fsdev->nd_su_node; - cp = fsdev->nd_cp_node; - ifile = nmp->nm_ifile_node; - - NANDFS_WRITEASSERT(fsdev); - if (lockmgr(&fsdev->nd_seg_const, LK_UPGRADE, NULL) != 0) { - DPRINTF(SYNC, ("%s: lost shared lock\n", __func__)); - if (lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL) != 0) - panic("couldn't lock exclusive"); - } - DPRINTF(SYNC, ("%s: got lock\n", __func__)); - - VOP_LOCK(NTOV(su), LK_EXCLUSIVE); - create_seginfo(fsdev, &seginfo); - - update = 0; - - nandfs_node = VTON(vp); - if (nandfs_node->nn_flags & IN_MODIFIED) { - nandfs_node->nn_flags &= ~(IN_MODIFIED); - update = 1; - } - - if (vp->v_bufobj.bo_dirty.bv_cnt) { - error = nandfs_iterate_dirty_buf(vp, seginfo, 0); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - VOP_UNLOCK(NTOV(su), 0); - lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL); - nandfs_error("%s: err:%d iterating dirty bufs vp:%p", - __func__, error, vp); - return (error); - } - update = 1; - } - - if (update) { - VOP_LOCK(NTOV(ifile), LK_EXCLUSIVE); - error = nandfs_node_update(nandfs_node); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - VOP_UNLOCK(NTOV(ifile), 0); - VOP_UNLOCK(NTOV(su), 0); - lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL); - nandfs_error("%s: err:%d updating vp:%p", - __func__, error, vp); - return (error); - } - VOP_UNLOCK(NTOV(ifile), 0); - } - - cno_changed = 0; - if (seginfo->blocks) { - VOP_LOCK(NTOV(cp), LK_EXCLUSIVE); - cno_changed = 1; - /* Create new checkpoint */ - error = nandfs_get_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - VOP_UNLOCK(NTOV(cp), 0); - VOP_UNLOCK(NTOV(su), 0); - lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL); - nandfs_error("%s: err:%d getting cp:%jx", - __func__, error, fsdev->nd_last_cno + 1); - return (error); - } - - /* Reiterate all blocks and assign physical block number */ - nandfs_seginfo_assign_pblk(seginfo); - - /* Fill checkpoint data */ - error = nandfs_set_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1, - &ifile->nn_inode, seginfo->blocks); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - VOP_UNLOCK(NTOV(cp), 0); - VOP_UNLOCK(NTOV(su), 0); - lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL); - nandfs_error("%s: err:%d setting cp:%jx", - __func__, error, fsdev->nd_last_cno + 1); - return (error); - } - - VOP_UNLOCK(NTOV(cp), 0); - LIST_FOREACH(seg, &seginfo->seg_list, seg_link) - nandfs_update_segment(fsdev, seg->seg_num, - seg->nblocks + seg->segsum_blocks); - - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - error = save_seginfo(seginfo, 0); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - VOP_UNLOCK(NTOV(dat), 0); - VOP_UNLOCK(NTOV(su), 0); - lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL); - nandfs_error("%s: err:%d updating seg", - __func__, error); - return (error); - } - VOP_UNLOCK(NTOV(dat), 0); - } - - VOP_UNLOCK(NTOV(su), 0); - - delete_seginfo(seginfo); - lockmgr(&fsdev->nd_seg_const, LK_DOWNGRADE, NULL); - - if (cno_changed && !error) { - if (nandfs_cps_between_sblocks != 0 && - fsdev->nd_last_cno % nandfs_cps_between_sblocks == 0) - nandfs_write_superblock(fsdev); - } - - ASSERT_VOP_LOCKED(vp, __func__); - DPRINTF(SYNC, ("%s: END error %d\n", __func__, error)); - return (error); -} - -int -nandfs_segment_constructor(struct nandfsmount *nmp, int flags) -{ - struct nandfs_device *fsdev; - struct nandfs_seginfo *seginfo = NULL; - struct nandfs_segment *seg; - struct nandfs_node *dat, *su, *ifile, *cp, *gc; - int cno_changed, error; - - DPRINTF(SYNC, ("%s: START\n", __func__)); - fsdev = nmp->nm_nandfsdev; - - lockmgr(&fsdev->nd_seg_const, LK_EXCLUSIVE, NULL); - DPRINTF(SYNC, ("%s: git lock\n", __func__)); -again: - create_seginfo(fsdev, &seginfo); - - dat = fsdev->nd_dat_node; - su = fsdev->nd_su_node; - cp = fsdev->nd_cp_node; - gc = fsdev->nd_gc_node; - ifile = nmp->nm_ifile_node; - - VOP_LOCK(NTOV(su), LK_EXCLUSIVE); - VOP_LOCK(NTOV(ifile), LK_EXCLUSIVE); - VOP_LOCK(NTOV(gc), LK_EXCLUSIVE); - VOP_LOCK(NTOV(cp), LK_EXCLUSIVE); - - nandfs_iterate_system_vnode(gc, seginfo); - nandfs_iterate_dirty_vnodes(nmp->nm_vfs_mountp, seginfo); - nandfs_iterate_system_vnode(ifile, seginfo); - nandfs_iterate_system_vnode(su, seginfo); - - cno_changed = 0; - if (seginfo->blocks || flags) { - cno_changed = 1; - /* Create new checkpoint */ - error = nandfs_get_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - goto error_locks; - } - - /* Collect blocks from system files */ - nandfs_iterate_system_vnode(cp, seginfo); - nandfs_iterate_system_vnode(su, seginfo); - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - nandfs_iterate_system_vnode(dat, seginfo); - VOP_UNLOCK(NTOV(dat), 0); -reiterate: - seginfo->reiterate = 0; - nandfs_iterate_system_vnode(su, seginfo); - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - nandfs_iterate_system_vnode(dat, seginfo); - VOP_UNLOCK(NTOV(dat), 0); - if (seginfo->reiterate) - goto reiterate; - if (!(seginfo->curseg) || !seginfo->curseg->num_blocks) { - error = create_segment(seginfo); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - goto error_locks; - } - goto reiterate; - } - - /* Reiterate all blocks and assign physical block number */ - nandfs_seginfo_assign_pblk(seginfo); - - /* Fill superroot */ - error = nandfs_add_superroot(seginfo); - if (error) { - clean_seginfo(seginfo, 0); - delete_seginfo(seginfo); - goto error_locks; - } - KASSERT(!(seginfo->reiterate), ("reiteration after superroot")); - - /* Fill checkpoint data */ - nandfs_set_checkpoint(fsdev, cp, fsdev->nd_last_cno + 1, - &ifile->nn_inode, seginfo->blocks); - - LIST_FOREACH(seg, &seginfo->seg_list, seg_link) - nandfs_update_segment(fsdev, seg->seg_num, - seg->nblocks + seg->segsum_blocks); - - VOP_LOCK(NTOV(dat), LK_EXCLUSIVE); - error = save_seginfo(seginfo, 1); - if (error) { - clean_seginfo(seginfo, 1); - delete_seginfo(seginfo); - goto error_dat; - } - VOP_UNLOCK(NTOV(dat), 0); - } - - VOP_UNLOCK(NTOV(cp), 0); - VOP_UNLOCK(NTOV(gc), 0); - VOP_UNLOCK(NTOV(ifile), 0); - - nandfs_process_segments(fsdev); - - VOP_UNLOCK(NTOV(su), 0); - - delete_seginfo(seginfo); - - /* - * XXX: a hack, will go away soon - */ - if ((NTOV(dat)->v_bufobj.bo_dirty.bv_cnt != 0 || - NTOV(cp)->v_bufobj.bo_dirty.bv_cnt != 0 || - NTOV(gc)->v_bufobj.bo_dirty.bv_cnt != 0 || - NTOV(ifile)->v_bufobj.bo_dirty.bv_cnt != 0 || - NTOV(su)->v_bufobj.bo_dirty.bv_cnt != 0) && - (flags & NANDFS_UMOUNT)) { - DPRINTF(SYNC, ("%s: RERUN\n", __func__)); - goto again; - } - - MPASS(fsdev->nd_free_base == NULL); - - lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL); - - if (cno_changed) { - if ((nandfs_cps_between_sblocks != 0 && - fsdev->nd_last_cno % nandfs_cps_between_sblocks == 0) || - flags & NANDFS_UMOUNT) - nandfs_write_superblock(fsdev); - } - - DPRINTF(SYNC, ("%s: END\n", __func__)); - return (0); -error_dat: - VOP_UNLOCK(NTOV(dat), 0); -error_locks: - VOP_UNLOCK(NTOV(cp), 0); - VOP_UNLOCK(NTOV(gc), 0); - VOP_UNLOCK(NTOV(ifile), 0); - VOP_UNLOCK(NTOV(su), 0); - lockmgr(&fsdev->nd_seg_const, LK_RELEASE, NULL); - - return (error); -} - -#ifdef DDB -/* - * Show details about the given NANDFS mount point. - */ -DB_SHOW_COMMAND(nandfs, db_show_nandfs) -{ - struct mount *mp; - struct nandfs_device *nffsdev; - struct nandfs_segment *seg; - struct nandfsmount *nmp; - struct buf *bp; - struct vnode *vp; - - if (!have_addr) { - db_printf("\nUsage: show nandfs \n"); - return; - } - - mp = (struct mount *)addr; - db_printf("%p %s on %s (%s)\n", mp, mp->mnt_stat.f_mntfromname, - mp->mnt_stat.f_mntonname, mp->mnt_stat.f_fstypename); - - - nmp = (struct nandfsmount *)(mp->mnt_data); - nffsdev = nmp->nm_nandfsdev; - db_printf("dev vnode:%p\n", nffsdev->nd_devvp); - db_printf("blocksize:%jx last cno:%jx last pseg:%jx seg num:%jx\n", - (uintmax_t)nffsdev->nd_blocksize, (uintmax_t)nffsdev->nd_last_cno, - (uintmax_t)nffsdev->nd_last_pseg, (uintmax_t)nffsdev->nd_seg_num); - db_printf("system nodes: dat:%p cp:%p su:%p ifile:%p gc:%p\n", - nffsdev->nd_dat_node, nffsdev->nd_cp_node, nffsdev->nd_su_node, - nmp->nm_ifile_node, nffsdev->nd_gc_node); - - if (nffsdev->nd_seginfo != NULL) { - LIST_FOREACH(seg, &nffsdev->nd_seginfo->seg_list, seg_link) { - db_printf("seg: %p\n", seg); - TAILQ_FOREACH(bp, &seg->segsum, - b_cluster.cluster_entry) - db_printf("segbp %p\n", bp); - TAILQ_FOREACH(bp, &seg->data, - b_cluster.cluster_entry) { - vp = bp->b_vp; - db_printf("bp:%p bp->b_vp:%p ino:%jx\n", bp, vp, - (uintmax_t)(vp ? VTON(vp)->nn_ino : 0)); - } - } - } -} -#endif Property changes on: head/sys/fs/nandfs/nandfs_segment.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_dir.c =================================================================== --- head/sys/fs/nandfs/nandfs_dir.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_dir.c (nonexistent) @@ -1,316 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_subr.c,v 1.4 2009/07/29 17:06:57 reinoud - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "nandfs_mount.h" -#include "nandfs.h" -#include "nandfs_subr.h" - -int -nandfs_add_dirent(struct vnode *dvp, uint64_t ino, char *nameptr, long namelen, - uint8_t type) -{ - struct nandfs_node *dir_node = VTON(dvp); - struct nandfs_dir_entry *dirent, *pdirent; - uint32_t blocksize = dir_node->nn_nandfsdev->nd_blocksize; - uint64_t filesize = dir_node->nn_inode.i_size; - uint64_t inode_blks = dir_node->nn_inode.i_blocks; - uint32_t off, rest; - uint8_t *pos; - struct buf *bp; - int error; - - pdirent = NULL; - bp = NULL; - if (inode_blks) { - error = nandfs_bread(dir_node, inode_blks - 1, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - pos = bp->b_data; - off = 0; - while (off < blocksize) { - pdirent = (struct nandfs_dir_entry *) (pos + off); - if (!pdirent->rec_len) { - pdirent = NULL; - break; - } - off += pdirent->rec_len; - } - - if (pdirent) - rest = pdirent->rec_len - - NANDFS_DIR_REC_LEN(pdirent->name_len); - else - rest = blocksize; - - if (rest < NANDFS_DIR_REC_LEN(namelen)) { - /* Do not update pdirent as new block is created */ - pdirent = NULL; - brelse(bp); - /* Set to NULL to create new */ - bp = NULL; - filesize += rest; - } - } - - /* If no bp found create new */ - if (!bp) { - error = nandfs_bcreate(dir_node, inode_blks, NOCRED, 0, &bp); - if (error) - return (error); - off = 0; - pos = bp->b_data; - } - - /* Modify pdirent if exists */ - if (pdirent) { - DPRINTF(LOOKUP, ("modify pdirent %p\n", pdirent)); - /* modify last de */ - off -= pdirent->rec_len; - pdirent->rec_len = - NANDFS_DIR_REC_LEN(pdirent->name_len); - off += pdirent->rec_len; - } - - /* Create new dirent */ - dirent = (struct nandfs_dir_entry *) (pos + off); - dirent->rec_len = blocksize - off; - dirent->inode = ino; - dirent->name_len = namelen; - memset(dirent->name, 0, NANDFS_DIR_NAME_LEN(namelen)); - memcpy(dirent->name, nameptr, namelen); - dirent->file_type = type; - - filesize += NANDFS_DIR_REC_LEN(dirent->name_len); - - DPRINTF(LOOKUP, ("create dir_entry '%.*s' at %p with size %x " - "new filesize: %jx\n", - (int)namelen, dirent->name, dirent, dirent->rec_len, - (uintmax_t)filesize)); - - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - - dir_node->nn_inode.i_size = filesize; - dir_node->nn_flags |= IN_CHANGE | IN_UPDATE; - vnode_pager_setsize(dvp, filesize); - - return (0); -} - -int -nandfs_remove_dirent(struct vnode *dvp, struct nandfs_node *node, - struct componentname *cnp) -{ - struct nandfs_node *dir_node; - struct nandfs_dir_entry *dirent, *pdirent; - struct buf *bp; - uint64_t filesize, blocknr, ino, offset; - uint32_t blocksize, limit, off; - uint16_t newsize; - uint8_t *pos; - int error, found; - - dir_node = VTON(dvp); - filesize = dir_node->nn_inode.i_size; - if (!filesize) - return (0); - - if (node) { - offset = node->nn_diroff; - ino = node->nn_ino; - } else { - offset = dir_node->nn_diroff; - ino = NANDFS_WHT_INO; - } - - dirent = pdirent = NULL; - blocksize = dir_node->nn_nandfsdev->nd_blocksize; - blocknr = offset / blocksize; - - DPRINTF(LOOKUP, ("rm direntry dvp %p node %p ino %#jx at off %#jx\n", - dvp, node, (uintmax_t)ino, (uintmax_t)offset)); - - error = nandfs_bread(dir_node, blocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - pos = bp->b_data; - off = 0; - found = 0; - limit = offset % blocksize; - pdirent = (struct nandfs_dir_entry *) bp->b_data; - while (off <= limit) { - dirent = (struct nandfs_dir_entry *) (pos + off); - - if ((off == limit) && - (dirent->inode == ino)) { - found = 1; - break; - } - if (dirent->inode != 0) - pdirent = dirent; - off += dirent->rec_len; - } - - if (!found) { - nandfs_error("cannot find entry to remove"); - brelse(bp); - return (error); - } - DPRINTF(LOOKUP, - ("rm dirent ino %#jx at %#x with size %#x\n", - (uintmax_t)dirent->inode, off, dirent->rec_len)); - - newsize = (uintptr_t)dirent - (uintptr_t)pdirent; - newsize += dirent->rec_len; - pdirent->rec_len = newsize; - dirent->inode = 0; - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - - dir_node->nn_flags |= IN_CHANGE | IN_UPDATE; - /* If last one modify filesize */ - if ((offset + NANDFS_DIR_REC_LEN(dirent->name_len)) == filesize) { - filesize = blocknr * blocksize + - ((uintptr_t)pdirent - (uintptr_t)pos) + - NANDFS_DIR_REC_LEN(pdirent->name_len); - dir_node->nn_inode.i_size = filesize; - } - - return (0); -} - -int -nandfs_update_parent_dir(struct vnode *dvp, uint64_t newparent) -{ - struct nandfs_dir_entry *dirent; - struct nandfs_node *dir_node; - struct buf *bp; - int error; - - dir_node = VTON(dvp); - error = nandfs_bread(dir_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - dirent = (struct nandfs_dir_entry *)bp->b_data; - dirent->inode = newparent; - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - - return (0); -} - -int -nandfs_update_dirent(struct vnode *dvp, struct nandfs_node *fnode, - struct nandfs_node *tnode) -{ - struct nandfs_node *dir_node; - struct nandfs_dir_entry *dirent; - struct buf *bp; - uint64_t file_size, blocknr; - uint32_t blocksize, off; - uint8_t *pos; - int error; - - dir_node = VTON(dvp); - file_size = dir_node->nn_inode.i_size; - if (!file_size) - return (0); - - DPRINTF(LOOKUP, - ("chg direntry dvp %p ino %#jx to in %#jx at off %#jx\n", - dvp, (uintmax_t)tnode->nn_ino, (uintmax_t)fnode->nn_ino, - (uintmax_t)tnode->nn_diroff)); - - blocksize = dir_node->nn_nandfsdev->nd_blocksize; - blocknr = tnode->nn_diroff / blocksize; - off = tnode->nn_diroff % blocksize; - error = nandfs_bread(dir_node, blocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - return (error); - } - - pos = bp->b_data; - dirent = (struct nandfs_dir_entry *) (pos + off); - KASSERT((dirent->inode == tnode->nn_ino), - ("direntry mismatch")); - - dirent->inode = fnode->nn_ino; - error = nandfs_dirty_buf(bp, 0); - if (error) - return (error); - - return (0); -} - -int -nandfs_init_dir(struct vnode *dvp, uint64_t ino, uint64_t parent_ino) -{ - - if (nandfs_add_dirent(dvp, parent_ino, "..", 2, DT_DIR) || - nandfs_add_dirent(dvp, ino, ".", 1, DT_DIR)) { - nandfs_error("%s: cannot initialize dir ino:%jd(pino:%jd)\n", - __func__, ino, parent_ino); - return (-1); - } - return (0); -} Property changes on: head/sys/fs/nandfs/nandfs_dir.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/nandfs/nandfs_vfsops.c =================================================================== --- head/sys/fs/nandfs/nandfs_vfsops.c (revision 349351) +++ head/sys/fs/nandfs/nandfs_vfsops.c (nonexistent) @@ -1,1601 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf - * Copyright (c) 2008, 2009 Reinoud Zandijk - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * From: NetBSD: nilfs_vfsops.c,v 1.1 2009/07/18 16:31:42 reinoud Exp - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include - -static MALLOC_DEFINE(M_NANDFSMNT, "nandfs_mount", "NANDFS mount structure"); - -#define NANDFS_SET_SYSTEMFILE(vp) { \ - (vp)->v_vflag |= VV_SYSTEM; \ - vref(vp); \ - vput(vp); } - -#define NANDFS_UNSET_SYSTEMFILE(vp) { \ - VOP_LOCK(vp, LK_EXCLUSIVE); \ - MPASS(vp->v_bufobj.bo_dirty.bv_cnt == 0); \ - (vp)->v_vflag &= ~VV_SYSTEM; \ - vgone(vp); \ - vput(vp); } - -/* Globals */ -struct _nandfs_devices nandfs_devices; - -/* Parameters */ -int nandfs_verbose = 0; - -static void -nandfs_tunable_init(void *arg) -{ - - TUNABLE_INT_FETCH("vfs.nandfs.verbose", &nandfs_verbose); -} -SYSINIT(nandfs_tunables, SI_SUB_VFS, SI_ORDER_ANY, nandfs_tunable_init, NULL); - -static SYSCTL_NODE(_vfs, OID_AUTO, nandfs, CTLFLAG_RD, 0, "NAND filesystem"); -static SYSCTL_NODE(_vfs_nandfs, OID_AUTO, mount, CTLFLAG_RD, 0, - "NANDFS mountpoints"); -SYSCTL_INT(_vfs_nandfs, OID_AUTO, verbose, CTLFLAG_RW, &nandfs_verbose, 0, ""); - -#define NANDFS_CONSTR_INTERVAL 5 -int nandfs_sync_interval = NANDFS_CONSTR_INTERVAL; /* sync every 5 seconds */ -SYSCTL_UINT(_vfs_nandfs, OID_AUTO, sync_interval, CTLFLAG_RW, - &nandfs_sync_interval, 0, ""); - -#define NANDFS_MAX_DIRTY_SEGS 5 -int nandfs_max_dirty_segs = NANDFS_MAX_DIRTY_SEGS; /* sync when 5 dirty seg */ -SYSCTL_UINT(_vfs_nandfs, OID_AUTO, max_dirty_segs, CTLFLAG_RW, - &nandfs_max_dirty_segs, 0, ""); - -#define NANDFS_CPS_BETWEEN_SBLOCKS 5 -int nandfs_cps_between_sblocks = NANDFS_CPS_BETWEEN_SBLOCKS; /* write superblock every 5 checkpoints */ -SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cps_between_sblocks, CTLFLAG_RW, - &nandfs_cps_between_sblocks, 0, ""); - -#define NANDFS_CLEANER_ENABLE 1 -int nandfs_cleaner_enable = NANDFS_CLEANER_ENABLE; -SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cleaner_enable, CTLFLAG_RW, - &nandfs_cleaner_enable, 0, ""); - -#define NANDFS_CLEANER_INTERVAL 5 -int nandfs_cleaner_interval = NANDFS_CLEANER_INTERVAL; -SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cleaner_interval, CTLFLAG_RW, - &nandfs_cleaner_interval, 0, ""); - -#define NANDFS_CLEANER_SEGMENTS 5 -int nandfs_cleaner_segments = NANDFS_CLEANER_SEGMENTS; -SYSCTL_UINT(_vfs_nandfs, OID_AUTO, cleaner_segments, CTLFLAG_RW, - &nandfs_cleaner_segments, 0, ""); - -static int nandfs_mountfs(struct vnode *devvp, struct mount *mp); -static vfs_mount_t nandfs_mount; -static vfs_root_t nandfs_root; -static vfs_statfs_t nandfs_statfs; -static vfs_unmount_t nandfs_unmount; -static vfs_vget_t nandfs_vget; -static vfs_sync_t nandfs_sync; -static const char *nandfs_opts[] = { - "snap", "from", "noatime", NULL -}; - -/* System nodes */ -static int -nandfs_create_system_nodes(struct nandfs_device *nandfsdev) -{ - int error; - - error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_DAT_INO, - &nandfsdev->nd_super_root.sr_dat, &nandfsdev->nd_dat_node); - if (error) - goto errorout; - - error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_CPFILE_INO, - &nandfsdev->nd_super_root.sr_cpfile, &nandfsdev->nd_cp_node); - if (error) - goto errorout; - - error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_SUFILE_INO, - &nandfsdev->nd_super_root.sr_sufile, &nandfsdev->nd_su_node); - if (error) - goto errorout; - - error = nandfs_get_node_raw(nandfsdev, NULL, NANDFS_GC_INO, - NULL, &nandfsdev->nd_gc_node); - if (error) - goto errorout; - - NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_dat_node)); - NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_cp_node)); - NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_su_node)); - NANDFS_SET_SYSTEMFILE(NTOV(nandfsdev->nd_gc_node)); - - DPRINTF(VOLUMES, ("System vnodes: dat: %p cp: %p su: %p\n", - NTOV(nandfsdev->nd_dat_node), NTOV(nandfsdev->nd_cp_node), - NTOV(nandfsdev->nd_su_node))); - return (0); - -errorout: - nandfs_dispose_node(&nandfsdev->nd_gc_node); - nandfs_dispose_node(&nandfsdev->nd_dat_node); - nandfs_dispose_node(&nandfsdev->nd_cp_node); - nandfs_dispose_node(&nandfsdev->nd_su_node); - - return (error); -} - -static void -nandfs_release_system_nodes(struct nandfs_device *nandfsdev) -{ - - if (!nandfsdev) - return; - if (nandfsdev->nd_refcnt > 0) - return; - - if (nandfsdev->nd_gc_node) - NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_gc_node)); - if (nandfsdev->nd_dat_node) - NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_dat_node)); - if (nandfsdev->nd_cp_node) - NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_cp_node)); - if (nandfsdev->nd_su_node) - NANDFS_UNSET_SYSTEMFILE(NTOV(nandfsdev->nd_su_node)); -} - -static int -nandfs_check_fsdata_crc(struct nandfs_fsdata *fsdata) -{ - uint32_t fsdata_crc, comp_crc; - - if (fsdata->f_magic != NANDFS_FSDATA_MAGIC) - return (0); - - /* Preserve CRC */ - fsdata_crc = fsdata->f_sum; - - /* Calculate */ - fsdata->f_sum = (0); - comp_crc = crc32((uint8_t *)fsdata, fsdata->f_bytes); - - /* Restore */ - fsdata->f_sum = fsdata_crc; - - /* Check CRC */ - return (fsdata_crc == comp_crc); -} - -static int -nandfs_check_superblock_crc(struct nandfs_fsdata *fsdata, - struct nandfs_super_block *super) -{ - uint32_t super_crc, comp_crc; - - /* Check super block magic */ - if (super->s_magic != NANDFS_SUPER_MAGIC) - return (0); - - /* Preserve CRC */ - super_crc = super->s_sum; - - /* Calculate */ - super->s_sum = (0); - comp_crc = crc32((uint8_t *)super, fsdata->f_sbbytes); - - /* Restore */ - super->s_sum = super_crc; - - /* Check CRC */ - return (super_crc == comp_crc); -} - -static void -nandfs_calc_superblock_crc(struct nandfs_fsdata *fsdata, - struct nandfs_super_block *super) -{ - uint32_t comp_crc; - - /* Calculate */ - super->s_sum = 0; - comp_crc = crc32((uint8_t *)super, fsdata->f_sbbytes); - - /* Restore */ - super->s_sum = comp_crc; -} - -static int -nandfs_is_empty(u_char *area, int size) -{ - int i; - - for (i = 0; i < size; i++) - if (area[i] != 0xff) - return (0); - - return (1); -} - -static __inline int -nandfs_sblocks_in_esize(struct nandfs_device *fsdev) -{ - - return ((fsdev->nd_erasesize - NANDFS_SBLOCK_OFFSET_BYTES) / - sizeof(struct nandfs_super_block)); -} - -static __inline int -nandfs_max_sblocks(struct nandfs_device *fsdev) -{ - - return (NANDFS_NFSAREAS * nandfs_sblocks_in_esize(fsdev)); -} - -static __inline int -nandfs_sblocks_in_block(struct nandfs_device *fsdev) -{ - - return (fsdev->nd_devblocksize / sizeof(struct nandfs_super_block)); -} - -#if 0 -static __inline int -nandfs_sblocks_in_first_block(struct nandfs_device *fsdev) -{ - int n; - - n = nandfs_sblocks_in_block(fsdev) - - NANDFS_SBLOCK_OFFSET_BYTES / sizeof(struct nandfs_super_block); - if (n < 0) - n = 0; - - return (n); -} -#endif - -static int -nandfs_write_superblock_at(struct nandfs_device *fsdev, - struct nandfs_fsarea *fstp) -{ - struct nandfs_super_block *super, *supert; - struct buf *bp; - int sb_per_sector, sbs_in_fsd, read_block; - int index, pos, error; - off_t offset; - - DPRINTF(SYNC, ("%s: last_used %d nandfs_sblocks_in_esize %d\n", - __func__, fstp->last_used, nandfs_sblocks_in_esize(fsdev))); - if (fstp->last_used == nandfs_sblocks_in_esize(fsdev) - 1) - index = 0; - else - index = fstp->last_used + 1; - - super = &fsdev->nd_super; - supert = NULL; - - sb_per_sector = nandfs_sblocks_in_block(fsdev); - sbs_in_fsd = sizeof(struct nandfs_fsdata) / - sizeof(struct nandfs_super_block); - index += sbs_in_fsd; - offset = fstp->offset; - - DPRINTF(SYNC, ("%s: offset %#jx s_last_pseg %#jx s_last_cno %#jx " - "s_last_seq %#jx wtime %jd index %d\n", __func__, offset, - super->s_last_pseg, super->s_last_cno, super->s_last_seq, - super->s_wtime, index)); - - read_block = btodb(offset + rounddown(index, sb_per_sector) * - sizeof(struct nandfs_super_block)); - - DPRINTF(SYNC, ("%s: read_block %#x\n", __func__, read_block)); - - if (index == sbs_in_fsd) { - error = nandfs_erase(fsdev, offset, fsdev->nd_erasesize); - if (error) - return (error); - - error = bread(fsdev->nd_devvp, btodb(offset), - fsdev->nd_devblocksize, NOCRED, &bp); - if (error) { - printf("NANDFS: couldn't read initial data: %d\n", - error); - brelse(bp); - return (error); - } - memcpy(bp->b_data, &fsdev->nd_fsdata, sizeof(fsdev->nd_fsdata)); - /* - * 0xff-out the rest. This bp could be cached, so potentially - * b_data contains stale super blocks. - * - * We don't mind cached bp since most of the time we just add - * super blocks to already 0xff-out b_data and don't need to - * perform actual read. - */ - if (fsdev->nd_devblocksize > sizeof(fsdev->nd_fsdata)) - memset(bp->b_data + sizeof(fsdev->nd_fsdata), 0xff, - fsdev->nd_devblocksize - sizeof(fsdev->nd_fsdata)); - error = bwrite(bp); - if (error) { - printf("NANDFS: cannot rewrite initial data at %jx\n", - offset); - return (error); - } - } - - error = bread(fsdev->nd_devvp, read_block, fsdev->nd_devblocksize, - NOCRED, &bp); - if (error) { - brelse(bp); - return (error); - } - - supert = (struct nandfs_super_block *)(bp->b_data); - pos = index % sb_per_sector; - - DPRINTF(SYNC, ("%s: storing at %d\n", __func__, pos)); - memcpy(&supert[pos], super, sizeof(struct nandfs_super_block)); - - /* - * See comment above in code that performs erase. - */ - if (pos == 0) - memset(&supert[1], 0xff, - (sb_per_sector - 1) * sizeof(struct nandfs_super_block)); - - error = bwrite(bp); - if (error) { - printf("NANDFS: cannot update superblock at %jx\n", offset); - return (error); - } - - DPRINTF(SYNC, ("%s: fstp->last_used %d -> %d\n", __func__, - fstp->last_used, index - sbs_in_fsd)); - fstp->last_used = index - sbs_in_fsd; - - return (0); -} - -int -nandfs_write_superblock(struct nandfs_device *fsdev) -{ - struct nandfs_super_block *super; - struct timespec ts; - int error; - int i, j; - - vfs_timestamp(&ts); - - super = &fsdev->nd_super; - - super->s_last_pseg = fsdev->nd_last_pseg; - super->s_last_cno = fsdev->nd_last_cno; - super->s_last_seq = fsdev->nd_seg_sequence; - super->s_wtime = ts.tv_sec; - - nandfs_calc_superblock_crc(&fsdev->nd_fsdata, super); - - error = 0; - for (i = 0, j = fsdev->nd_last_fsarea; i < NANDFS_NFSAREAS; - i++, j = (j + 1 % NANDFS_NFSAREAS)) { - if (fsdev->nd_fsarea[j].flags & NANDFS_FSSTOR_FAILED) { - DPRINTF(SYNC, ("%s: skipping %d\n", __func__, j)); - continue; - } - error = nandfs_write_superblock_at(fsdev, &fsdev->nd_fsarea[j]); - if (error) { - printf("NANDFS: writing superblock at offset %d failed:" - "%d\n", j * fsdev->nd_erasesize, error); - fsdev->nd_fsarea[j].flags |= NANDFS_FSSTOR_FAILED; - } else - break; - } - - if (i == NANDFS_NFSAREAS) { - printf("NANDFS: superblock was not written\n"); - /* - * TODO: switch to read-only? - */ - return (error); - } else - fsdev->nd_last_fsarea = (j + 1) % NANDFS_NFSAREAS; - - return (0); -} - -static int -nandfs_select_fsdata(struct nandfs_device *fsdev, - struct nandfs_fsdata *fsdatat, struct nandfs_fsdata **fsdata, int nfsds) -{ - int i; - - *fsdata = NULL; - for (i = 0; i < nfsds; i++) { - DPRINTF(VOLUMES, ("%s: i %d f_magic %x f_crc %x\n", __func__, - i, fsdatat[i].f_magic, fsdatat[i].f_sum)); - if (!nandfs_check_fsdata_crc(&fsdatat[i])) - continue; - *fsdata = &fsdatat[i]; - break; - } - - return (*fsdata != NULL ? 0 : EINVAL); -} - -static int -nandfs_select_sb(struct nandfs_device *fsdev, - struct nandfs_super_block *supert, struct nandfs_super_block **super, - int nsbs) -{ - int i; - - *super = NULL; - for (i = 0; i < nsbs; i++) { - if (!nandfs_check_superblock_crc(&fsdev->nd_fsdata, &supert[i])) - continue; - DPRINTF(SYNC, ("%s: i %d s_last_cno %jx s_magic %x " - "s_wtime %jd\n", __func__, i, supert[i].s_last_cno, - supert[i].s_magic, supert[i].s_wtime)); - if (*super == NULL || supert[i].s_last_cno > - (*super)->s_last_cno) - *super = &supert[i]; - } - - return (*super != NULL ? 0 : EINVAL); -} - -static int -nandfs_read_structures_at(struct nandfs_device *fsdev, - struct nandfs_fsarea *fstp, struct nandfs_fsdata *fsdata, - struct nandfs_super_block *super) -{ - struct nandfs_super_block *tsuper, *tsuperd; - struct buf *bp; - int error, read_size; - int i; - int offset; - - offset = fstp->offset; - - if (fsdev->nd_erasesize > MAXBSIZE) - read_size = MAXBSIZE; - else - read_size = fsdev->nd_erasesize; - - error = bread(fsdev->nd_devvp, btodb(offset), read_size, NOCRED, &bp); - if (error) { - printf("couldn't read: %d\n", error); - brelse(bp); - fstp->flags |= NANDFS_FSSTOR_FAILED; - return (error); - } - - tsuper = super; - - memcpy(fsdata, bp->b_data, sizeof(struct nandfs_fsdata)); - memcpy(tsuper, (bp->b_data + sizeof(struct nandfs_fsdata)), - read_size - sizeof(struct nandfs_fsdata)); - brelse(bp); - - tsuper += (read_size - sizeof(struct nandfs_fsdata)) / - sizeof(struct nandfs_super_block); - - for (i = 1; i < fsdev->nd_erasesize / read_size; i++) { - error = bread(fsdev->nd_devvp, btodb(offset + i * read_size), - read_size, NOCRED, &bp); - if (error) { - printf("couldn't read: %d\n", error); - brelse(bp); - fstp->flags |= NANDFS_FSSTOR_FAILED; - return (error); - } - memcpy(tsuper, bp->b_data, read_size); - tsuper += read_size / sizeof(struct nandfs_super_block); - brelse(bp); - } - - tsuper -= 1; - fstp->last_used = nandfs_sblocks_in_esize(fsdev) - 1; - for (tsuperd = super - 1; (tsuper != tsuperd); tsuper -= 1) { - if (nandfs_is_empty((u_char *)tsuper, sizeof(*tsuper))) - fstp->last_used--; - else - break; - } - - DPRINTF(VOLUMES, ("%s: last_used %d\n", __func__, fstp->last_used)); - - return (0); -} - -static int -nandfs_read_structures(struct nandfs_device *fsdev) -{ - struct nandfs_fsdata *fsdata, *fsdatat; - struct nandfs_super_block *sblocks, *ssblock; - u_int nsbs, nfsds, i; - int error = 0; - int nrsbs; - - nfsds = NANDFS_NFSAREAS; - nsbs = nandfs_max_sblocks(fsdev); - - fsdatat = malloc(sizeof(struct nandfs_fsdata) * nfsds, M_NANDFSTEMP, - M_WAITOK | M_ZERO); - sblocks = malloc(sizeof(struct nandfs_super_block) * nsbs, M_NANDFSTEMP, - M_WAITOK | M_ZERO); - - nrsbs = 0; - for (i = 0; i < NANDFS_NFSAREAS; i++) { - fsdev->nd_fsarea[i].offset = i * fsdev->nd_erasesize; - error = nandfs_read_structures_at(fsdev, &fsdev->nd_fsarea[i], - &fsdatat[i], sblocks + nrsbs); - if (error) - continue; - nrsbs += (fsdev->nd_fsarea[i].last_used + 1); - if (fsdev->nd_fsarea[fsdev->nd_last_fsarea].last_used > - fsdev->nd_fsarea[i].last_used) - fsdev->nd_last_fsarea = i; - } - - if (nrsbs == 0) { - printf("nandfs: no valid superblocks found\n"); - error = EINVAL; - goto out; - } - - error = nandfs_select_fsdata(fsdev, fsdatat, &fsdata, nfsds); - if (error) - goto out; - memcpy(&fsdev->nd_fsdata, fsdata, sizeof(struct nandfs_fsdata)); - - error = nandfs_select_sb(fsdev, sblocks, &ssblock, nsbs); - if (error) - goto out; - - memcpy(&fsdev->nd_super, ssblock, sizeof(struct nandfs_super_block)); -out: - free(fsdatat, M_NANDFSTEMP); - free(sblocks, M_NANDFSTEMP); - - if (error == 0) - DPRINTF(VOLUMES, ("%s: selected sb with w_time %jd " - "last_pseg %#jx\n", __func__, fsdev->nd_super.s_wtime, - fsdev->nd_super.s_last_pseg)); - - return (error); -} - -static void -nandfs_unmount_base(struct nandfs_device *nandfsdev) -{ - int error; - - if (!nandfsdev) - return; - - /* Remove all our information */ - error = vinvalbuf(nandfsdev->nd_devvp, V_SAVE, 0, 0); - if (error) { - /* - * Flushing buffers failed when fs was umounting, can't do - * much now, just printf error and continue with umount. - */ - nandfs_error("%s(): error:%d when umounting FS\n", - __func__, error); - } - - /* Release the device's system nodes */ - nandfs_release_system_nodes(nandfsdev); -} - -static void -nandfs_get_ncleanseg(struct nandfs_device *nandfsdev) -{ - struct nandfs_seg_stat nss; - - nandfs_get_seg_stat(nandfsdev, &nss); - nandfsdev->nd_clean_segs = nss.nss_ncleansegs; - DPRINTF(VOLUMES, ("nandfs_mount: clean segs: %jx\n", - (uintmax_t)nandfsdev->nd_clean_segs)); -} - - -static int -nandfs_mount_base(struct nandfs_device *nandfsdev, struct mount *mp, - struct nandfs_args *args) -{ - uint32_t log_blocksize; - int error; - - /* Flush out any old buffers remaining from a previous use. */ - if ((error = vinvalbuf(nandfsdev->nd_devvp, V_SAVE, 0, 0))) - return (error); - - error = nandfs_read_structures(nandfsdev); - if (error) { - printf("nandfs: could not get valid filesystem structures\n"); - return (error); - } - - if (nandfsdev->nd_fsdata.f_rev_level != NANDFS_CURRENT_REV) { - printf("nandfs: unsupported file system revision: %d " - "(supported is %d).\n", nandfsdev->nd_fsdata.f_rev_level, - NANDFS_CURRENT_REV); - return (EINVAL); - } - - if (nandfsdev->nd_fsdata.f_erasesize != nandfsdev->nd_erasesize) { - printf("nandfs: erasesize mismatch (device %#x, fs %#x)\n", - nandfsdev->nd_erasesize, nandfsdev->nd_fsdata.f_erasesize); - return (EINVAL); - } - - /* Get our blocksize */ - log_blocksize = nandfsdev->nd_fsdata.f_log_block_size; - nandfsdev->nd_blocksize = (uint64_t) 1 << (log_blocksize + 10); - DPRINTF(VOLUMES, ("%s: blocksize:%x\n", __func__, - nandfsdev->nd_blocksize)); - - DPRINTF(VOLUMES, ("%s: accepted super block with cp %#jx\n", __func__, - (uintmax_t)nandfsdev->nd_super.s_last_cno)); - - /* Calculate dat structure parameters */ - nandfs_calc_mdt_consts(nandfsdev, &nandfsdev->nd_dat_mdt, - nandfsdev->nd_fsdata.f_dat_entry_size); - nandfs_calc_mdt_consts(nandfsdev, &nandfsdev->nd_ifile_mdt, - nandfsdev->nd_fsdata.f_inode_size); - - /* Search for the super root and roll forward when needed */ - if (nandfs_search_super_root(nandfsdev)) { - printf("Cannot find valid SuperRoot\n"); - return (EINVAL); - } - - nandfsdev->nd_mount_state = nandfsdev->nd_super.s_state; - if (nandfsdev->nd_mount_state != NANDFS_VALID_FS) { - printf("FS is seriously damaged, needs repairing\n"); - printf("aborting mount\n"); - return (EINVAL); - } - - /* - * FS should be ok now. The superblock and the last segsum could be - * updated from the repair so extract running values again. - */ - nandfsdev->nd_last_pseg = nandfsdev->nd_super.s_last_pseg; - nandfsdev->nd_seg_sequence = nandfsdev->nd_super.s_last_seq; - nandfsdev->nd_seg_num = nandfs_get_segnum_of_block(nandfsdev, - nandfsdev->nd_last_pseg); - nandfsdev->nd_next_seg_num = nandfs_get_segnum_of_block(nandfsdev, - nandfsdev->nd_last_segsum.ss_next); - nandfsdev->nd_ts.tv_sec = nandfsdev->nd_last_segsum.ss_create; - nandfsdev->nd_last_cno = nandfsdev->nd_super.s_last_cno; - nandfsdev->nd_fakevblk = 1; - /* - * FIXME: bogus calculation. Should use actual number of usable segments - * instead of total amount. - */ - nandfsdev->nd_segs_reserved = - nandfsdev->nd_fsdata.f_nsegments * - nandfsdev->nd_fsdata.f_r_segments_percentage / 100; - nandfsdev->nd_last_ino = NANDFS_USER_INO; - DPRINTF(VOLUMES, ("%s: last_pseg %#jx last_cno %#jx last_seq %#jx\n" - "fsdev: last_seg: seq %#jx num %#jx, next_seg_num %#jx " - "segs_reserved %#jx\n", - __func__, (uintmax_t)nandfsdev->nd_last_pseg, - (uintmax_t)nandfsdev->nd_last_cno, - (uintmax_t)nandfsdev->nd_seg_sequence, - (uintmax_t)nandfsdev->nd_seg_sequence, - (uintmax_t)nandfsdev->nd_seg_num, - (uintmax_t)nandfsdev->nd_next_seg_num, - (uintmax_t)nandfsdev->nd_segs_reserved)); - - DPRINTF(VOLUMES, ("nandfs_mount: accepted super root\n")); - - /* Create system vnodes for DAT, CP and SEGSUM */ - error = nandfs_create_system_nodes(nandfsdev); - if (error) - nandfs_unmount_base(nandfsdev); - - nandfs_get_ncleanseg(nandfsdev); - - return (error); -} - -static void -nandfs_unmount_device(struct nandfs_device *nandfsdev) -{ - - /* Is there anything? */ - if (nandfsdev == NULL) - return; - - /* Remove the device only if we're the last reference */ - nandfsdev->nd_refcnt--; - if (nandfsdev->nd_refcnt >= 1) - return; - - MPASS(nandfsdev->nd_syncer == NULL); - MPASS(nandfsdev->nd_cleaner == NULL); - MPASS(nandfsdev->nd_free_base == NULL); - - /* Unmount our base */ - nandfs_unmount_base(nandfsdev); - - /* Remove from our device list */ - SLIST_REMOVE(&nandfs_devices, nandfsdev, nandfs_device, nd_next_device); - - DROP_GIANT(); - g_topology_lock(); - g_vfs_close(nandfsdev->nd_gconsumer); - g_topology_unlock(); - PICKUP_GIANT(); - - DPRINTF(VOLUMES, ("closing device\n")); - - /* Clear our mount reference and release device node */ - vrele(nandfsdev->nd_devvp); - - dev_rel(nandfsdev->nd_devvp->v_rdev); - - /* Free our device info */ - cv_destroy(&nandfsdev->nd_sync_cv); - mtx_destroy(&nandfsdev->nd_sync_mtx); - cv_destroy(&nandfsdev->nd_clean_cv); - mtx_destroy(&nandfsdev->nd_clean_mtx); - mtx_destroy(&nandfsdev->nd_mutex); - lockdestroy(&nandfsdev->nd_seg_const); - free(nandfsdev, M_NANDFSMNT); -} - -static int -nandfs_check_mounts(struct nandfs_device *nandfsdev, struct mount *mp, - struct nandfs_args *args) -{ - struct nandfsmount *nmp; - uint64_t last_cno; - - /* no double-mounting of the same checkpoint */ - STAILQ_FOREACH(nmp, &nandfsdev->nd_mounts, nm_next_mount) { - if (nmp->nm_mount_args.cpno == args->cpno) - return (EBUSY); - } - - /* Allow readonly mounts without questioning here */ - if (mp->mnt_flag & MNT_RDONLY) - return (0); - - /* Read/write mount */ - STAILQ_FOREACH(nmp, &nandfsdev->nd_mounts, nm_next_mount) { - /* Only one RW mount on this device! */ - if ((nmp->nm_vfs_mountp->mnt_flag & MNT_RDONLY)==0) - return (EROFS); - /* RDONLY on last mountpoint is device busy */ - last_cno = nmp->nm_nandfsdev->nd_super.s_last_cno; - if (nmp->nm_mount_args.cpno == last_cno) - return (EBUSY); - } - - /* OK for now */ - return (0); -} - -static int -nandfs_mount_device(struct vnode *devvp, struct mount *mp, - struct nandfs_args *args, struct nandfs_device **nandfsdev_p) -{ - struct nandfs_device *nandfsdev; - struct g_provider *pp; - struct g_consumer *cp; - struct cdev *dev; - uint32_t erasesize; - int error, size; - int ronly; - - DPRINTF(VOLUMES, ("Mounting NANDFS device\n")); - - ronly = (mp->mnt_flag & MNT_RDONLY) != 0; - - /* Look up device in our nandfs_mountpoints */ - *nandfsdev_p = NULL; - SLIST_FOREACH(nandfsdev, &nandfs_devices, nd_next_device) - if (nandfsdev->nd_devvp == devvp) - break; - - if (nandfsdev) { - DPRINTF(VOLUMES, ("device already mounted\n")); - error = nandfs_check_mounts(nandfsdev, mp, args); - if (error) - return error; - nandfsdev->nd_refcnt++; - *nandfsdev_p = nandfsdev; - - if (!ronly) { - DROP_GIANT(); - g_topology_lock(); - error = g_access(nandfsdev->nd_gconsumer, 0, 1, 0); - g_topology_unlock(); - PICKUP_GIANT(); - } - return (error); - } - - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); - dev = devvp->v_rdev; - dev_ref(dev); - DROP_GIANT(); - g_topology_lock(); - error = g_vfs_open(devvp, &cp, "nandfs", ronly ? 0 : 1); - pp = g_dev_getprovider(dev); - g_topology_unlock(); - PICKUP_GIANT(); - VOP_UNLOCK(devvp, 0); - if (error) { - dev_rel(dev); - return (error); - } - - nandfsdev = malloc(sizeof(struct nandfs_device), M_NANDFSMNT, M_WAITOK | M_ZERO); - - /* Initialise */ - nandfsdev->nd_refcnt = 1; - nandfsdev->nd_devvp = devvp; - nandfsdev->nd_syncing = 0; - nandfsdev->nd_cleaning = 0; - nandfsdev->nd_gconsumer = cp; - cv_init(&nandfsdev->nd_sync_cv, "nandfssync"); - mtx_init(&nandfsdev->nd_sync_mtx, "nffssyncmtx", NULL, MTX_DEF); - cv_init(&nandfsdev->nd_clean_cv, "nandfsclean"); - mtx_init(&nandfsdev->nd_clean_mtx, "nffscleanmtx", NULL, MTX_DEF); - mtx_init(&nandfsdev->nd_mutex, "nandfsdev lock", NULL, MTX_DEF); - lockinit(&nandfsdev->nd_seg_const, PVFS, "nffssegcon", VLKTIMEOUT, - LK_CANRECURSE); - STAILQ_INIT(&nandfsdev->nd_mounts); - - nandfsdev->nd_devsize = pp->mediasize; - nandfsdev->nd_devblocksize = pp->sectorsize; - - size = sizeof(erasesize); - error = g_io_getattr("NAND::blocksize", nandfsdev->nd_gconsumer, &size, - &erasesize); - if (error) { - DPRINTF(VOLUMES, ("couldn't get erasesize: %d\n", error)); - - if (error == ENOIOCTL || error == EOPNOTSUPP) { - /* - * We conclude that this is not NAND storage - */ - erasesize = NANDFS_DEF_ERASESIZE; - } else { - DROP_GIANT(); - g_topology_lock(); - g_vfs_close(nandfsdev->nd_gconsumer); - g_topology_unlock(); - PICKUP_GIANT(); - dev_rel(dev); - free(nandfsdev, M_NANDFSMNT); - return (error); - } - } - nandfsdev->nd_erasesize = erasesize; - - DPRINTF(VOLUMES, ("%s: erasesize %x\n", __func__, - nandfsdev->nd_erasesize)); - - /* Register nandfs_device in list */ - SLIST_INSERT_HEAD(&nandfs_devices, nandfsdev, nd_next_device); - - error = nandfs_mount_base(nandfsdev, mp, args); - if (error) { - /* Remove all our information */ - nandfs_unmount_device(nandfsdev); - return (EINVAL); - } - - nandfsdev->nd_maxfilesize = nandfs_get_maxfilesize(nandfsdev); - - *nandfsdev_p = nandfsdev; - DPRINTF(VOLUMES, ("NANDFS device mounted ok\n")); - - return (0); -} - -static int -nandfs_mount_checkpoint(struct nandfsmount *nmp) -{ - struct nandfs_cpfile_header *cphdr; - struct nandfs_checkpoint *cp; - struct nandfs_inode ifile_inode; - struct nandfs_node *cp_node; - struct buf *bp; - uint64_t ncp, nsn, cpno, fcpno, blocknr, last_cno; - uint32_t off, dlen; - int cp_per_block, error; - - cpno = nmp->nm_mount_args.cpno; - if (cpno == 0) - cpno = nmp->nm_nandfsdev->nd_super.s_last_cno; - - DPRINTF(VOLUMES, ("%s: trying to mount checkpoint number %"PRIu64"\n", - __func__, cpno)); - - cp_node = nmp->nm_nandfsdev->nd_cp_node; - - VOP_LOCK(NTOV(cp_node), LK_SHARED); - /* Get cpfile header from 1st block of cp file */ - error = nandfs_bread(cp_node, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - return (error); - } - - cphdr = (struct nandfs_cpfile_header *) bp->b_data; - ncp = cphdr->ch_ncheckpoints; - nsn = cphdr->ch_nsnapshots; - - brelse(bp); - - DPRINTF(VOLUMES, ("mount_nandfs: checkpoint header read in\n")); - DPRINTF(VOLUMES, ("\tNumber of checkpoints %"PRIu64"\n", ncp)); - DPRINTF(VOLUMES, ("\tNumber of snapshots %"PRIu64"\n", nsn)); - - /* Read in our specified checkpoint */ - dlen = nmp->nm_nandfsdev->nd_fsdata.f_checkpoint_size; - cp_per_block = nmp->nm_nandfsdev->nd_blocksize / dlen; - - fcpno = cpno + NANDFS_CPFILE_FIRST_CHECKPOINT_OFFSET - 1; - blocknr = fcpno / cp_per_block; - off = (fcpno % cp_per_block) * dlen; - error = nandfs_bread(cp_node, blocknr, NOCRED, 0, &bp); - if (error) { - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - printf("mount_nandfs: couldn't read cp block %"PRIu64"\n", - fcpno); - return (EINVAL); - } - - /* Needs to be a valid checkpoint */ - cp = (struct nandfs_checkpoint *) ((uint8_t *) bp->b_data + off); - if (cp->cp_flags & NANDFS_CHECKPOINT_INVALID) { - printf("mount_nandfs: checkpoint marked invalid\n"); - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - return (EINVAL); - } - - /* Is this really the checkpoint we want? */ - if (cp->cp_cno != cpno) { - printf("mount_nandfs: checkpoint file corrupt? " - "expected cpno %"PRIu64", found cpno %"PRIu64"\n", - cpno, cp->cp_cno); - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - return (EINVAL); - } - - /* Check if it's a snapshot ! */ - last_cno = nmp->nm_nandfsdev->nd_super.s_last_cno; - if (cpno != last_cno) { - /* Only allow snapshots if not mounting on the last cp */ - if ((cp->cp_flags & NANDFS_CHECKPOINT_SNAPSHOT) == 0) { - printf( "mount_nandfs: checkpoint %"PRIu64" is not a " - "snapshot\n", cpno); - brelse(bp); - VOP_UNLOCK(NTOV(cp_node), 0); - return (EINVAL); - } - } - - ifile_inode = cp->cp_ifile_inode; - brelse(bp); - - /* Get ifile inode */ - error = nandfs_get_node_raw(nmp->nm_nandfsdev, NULL, NANDFS_IFILE_INO, - &ifile_inode, &nmp->nm_ifile_node); - if (error) { - printf("mount_nandfs: can't read ifile node\n"); - VOP_UNLOCK(NTOV(cp_node), 0); - return (EINVAL); - } - - NANDFS_SET_SYSTEMFILE(NTOV(nmp->nm_ifile_node)); - VOP_UNLOCK(NTOV(cp_node), 0); - /* Get root node? */ - - return (0); -} - -static void -free_nandfs_mountinfo(struct mount *mp) -{ - struct nandfsmount *nmp = VFSTONANDFS(mp); - - if (nmp == NULL) - return; - - free(nmp, M_NANDFSMNT); -} - -void -nandfs_wakeup_wait_sync(struct nandfs_device *nffsdev, int reason) -{ - char *reasons[] = { - "umount", - "vfssync", - "bdflush", - "fforce", - "fsync", - "ro_upd" - }; - - DPRINTF(SYNC, ("%s: %s\n", __func__, reasons[reason])); - mtx_lock(&nffsdev->nd_sync_mtx); - if (nffsdev->nd_syncing) - cv_wait(&nffsdev->nd_sync_cv, &nffsdev->nd_sync_mtx); - if (reason == SYNCER_UMOUNT) - nffsdev->nd_syncer_exit = 1; - nffsdev->nd_syncing = 1; - wakeup(&nffsdev->nd_syncing); - cv_wait(&nffsdev->nd_sync_cv, &nffsdev->nd_sync_mtx); - - mtx_unlock(&nffsdev->nd_sync_mtx); -} - -static void -nandfs_gc_finished(struct nandfs_device *nffsdev, int exit) -{ - int error; - - mtx_lock(&nffsdev->nd_sync_mtx); - nffsdev->nd_syncing = 0; - DPRINTF(SYNC, ("%s: cleaner finish\n", __func__)); - cv_broadcast(&nffsdev->nd_sync_cv); - mtx_unlock(&nffsdev->nd_sync_mtx); - if (!exit) { - error = tsleep(&nffsdev->nd_syncing, PRIBIO, "-", - hz * nandfs_sync_interval); - DPRINTF(SYNC, ("%s: cleaner waked up: %d\n", - __func__, error)); - } -} - -static void -nandfs_syncer(struct nandfsmount *nmp) -{ - struct nandfs_device *nffsdev; - struct mount *mp; - int flags, error; - - mp = nmp->nm_vfs_mountp; - nffsdev = nmp->nm_nandfsdev; - tsleep(&nffsdev->nd_syncing, PRIBIO, "-", hz * nandfs_sync_interval); - - while (!nffsdev->nd_syncer_exit) { - DPRINTF(SYNC, ("%s: syncer run\n", __func__)); - nffsdev->nd_syncing = 1; - - flags = (nmp->nm_flags & (NANDFS_FORCE_SYNCER | NANDFS_UMOUNT)); - - error = nandfs_segment_constructor(nmp, flags); - if (error) - nandfs_error("%s: error:%d when creating segments\n", - __func__, error); - - nmp->nm_flags &= ~flags; - - nandfs_gc_finished(nffsdev, 0); - } - - MPASS(nffsdev->nd_cleaner == NULL); - error = nandfs_segment_constructor(nmp, - NANDFS_FORCE_SYNCER | NANDFS_UMOUNT); - if (error) - nandfs_error("%s: error:%d when creating segments\n", - __func__, error); - nandfs_gc_finished(nffsdev, 1); - nffsdev->nd_syncer = NULL; - MPASS(nffsdev->nd_free_base == NULL); - - DPRINTF(SYNC, ("%s: exiting\n", __func__)); - kthread_exit(); -} - -static int -start_syncer(struct nandfsmount *nmp) -{ - int error; - - MPASS(nmp->nm_nandfsdev->nd_syncer == NULL); - - DPRINTF(SYNC, ("%s: start syncer\n", __func__)); - - nmp->nm_nandfsdev->nd_syncer_exit = 0; - - error = kthread_add((void(*)(void *))nandfs_syncer, nmp, NULL, - &nmp->nm_nandfsdev->nd_syncer, 0, 0, "nandfs_syncer"); - - if (error) - printf("nandfs: could not start syncer: %d\n", error); - - return (error); -} - -static int -stop_syncer(struct nandfsmount *nmp) -{ - - MPASS(nmp->nm_nandfsdev->nd_syncer != NULL); - - nandfs_wakeup_wait_sync(nmp->nm_nandfsdev, SYNCER_UMOUNT); - - DPRINTF(SYNC, ("%s: stop syncer\n", __func__)); - return (0); -} - -/* - * Mount null layer - */ -static int -nandfs_mount(struct mount *mp) -{ - struct nandfsmount *nmp; - struct vnode *devvp; - struct nameidata nd; - struct vfsoptlist *opts; - struct thread *td; - char *from; - int error = 0, flags; - - DPRINTF(VOLUMES, ("%s: mp = %p\n", __func__, (void *)mp)); - - td = curthread; - opts = mp->mnt_optnew; - - if (vfs_filteropt(opts, nandfs_opts)) - return (EINVAL); - - /* - * Update is a no-op - */ - if (mp->mnt_flag & MNT_UPDATE) { - nmp = VFSTONANDFS(mp); - if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) { - return (error); - } - if (!(nmp->nm_ronly) && vfs_flagopt(opts, "ro", NULL, 0)) { - vn_start_write(NULL, &mp, V_WAIT); - error = VFS_SYNC(mp, MNT_WAIT); - if (error) - return (error); - vn_finished_write(mp); - - flags = WRITECLOSE; - if (mp->mnt_flag & MNT_FORCE) - flags |= FORCECLOSE; - - nandfs_wakeup_wait_sync(nmp->nm_nandfsdev, - SYNCER_ROUPD); - error = vflush(mp, 0, flags, td); - if (error) - return (error); - - nandfs_stop_cleaner(nmp->nm_nandfsdev); - stop_syncer(nmp); - DROP_GIANT(); - g_topology_lock(); - g_access(nmp->nm_nandfsdev->nd_gconsumer, 0, -1, 0); - g_topology_unlock(); - PICKUP_GIANT(); - MNT_ILOCK(mp); - mp->mnt_flag |= MNT_RDONLY; - MNT_IUNLOCK(mp); - nmp->nm_ronly = 1; - - } else if ((nmp->nm_ronly) && - !vfs_flagopt(opts, "ro", NULL, 0)) { - /* - * Don't allow read-write snapshots. - */ - if (nmp->nm_mount_args.cpno != 0) - return (EROFS); - /* - * If upgrade to read-write by non-root, then verify - * that user has necessary permissions on the device. - */ - devvp = nmp->nm_nandfsdev->nd_devvp; - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_ACCESS(devvp, VREAD | VWRITE, - td->td_ucred, td); - if (error) { - error = priv_check(td, PRIV_VFS_MOUNT_PERM); - if (error) { - VOP_UNLOCK(devvp, 0); - return (error); - } - } - - VOP_UNLOCK(devvp, 0); - DROP_GIANT(); - g_topology_lock(); - error = g_access(nmp->nm_nandfsdev->nd_gconsumer, 0, 1, - 0); - g_topology_unlock(); - PICKUP_GIANT(); - if (error) - return (error); - - MNT_ILOCK(mp); - mp->mnt_flag &= ~MNT_RDONLY; - MNT_IUNLOCK(mp); - error = start_syncer(nmp); - if (error == 0) - error = nandfs_start_cleaner(nmp->nm_nandfsdev); - if (error) { - DROP_GIANT(); - g_topology_lock(); - g_access(nmp->nm_nandfsdev->nd_gconsumer, 0, -1, - 0); - g_topology_unlock(); - PICKUP_GIANT(); - return (error); - } - - nmp->nm_ronly = 0; - } - return (0); - } - - from = vfs_getopts(opts, "from", &error); - if (error) - return (error); - - /* - * Find device node - */ - NDINIT(&nd, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, from, curthread); - error = namei(&nd); - if (error) - return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); - - devvp = nd.ni_vp; - - if (!vn_isdisk(devvp, &error)) { - vput(devvp); - return (error); - } - - /* Check the access rights on the mount device */ - error = VOP_ACCESS(devvp, VREAD, curthread->td_ucred, curthread); - if (error) - error = priv_check(curthread, PRIV_VFS_MOUNT_PERM); - if (error) { - vput(devvp); - return (error); - } - - vfs_getnewfsid(mp); - - error = nandfs_mountfs(devvp, mp); - if (error) - return (error); - vfs_mountedfrom(mp, from); - - return (0); -} - -static int -nandfs_mountfs(struct vnode *devvp, struct mount *mp) -{ - struct nandfsmount *nmp = NULL; - struct nandfs_args *args = NULL; - struct nandfs_device *nandfsdev; - char *from; - int error, ronly; - char *cpno; - - ronly = (mp->mnt_flag & MNT_RDONLY) != 0; - - if (devvp->v_rdev->si_iosize_max != 0) - mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max; - VOP_UNLOCK(devvp, 0); - - if (mp->mnt_iosize_max > MAXPHYS) - mp->mnt_iosize_max = MAXPHYS; - - from = vfs_getopts(mp->mnt_optnew, "from", &error); - if (error) - goto error; - - error = vfs_getopt(mp->mnt_optnew, "snap", (void **)&cpno, NULL); - if (error == ENOENT) - cpno = NULL; - else if (error) - goto error; - - args = (struct nandfs_args *)malloc(sizeof(struct nandfs_args), - M_NANDFSMNT, M_WAITOK | M_ZERO); - - if (cpno != NULL) - args->cpno = strtoul(cpno, (char **)NULL, 10); - else - args->cpno = 0; - args->fspec = from; - - if (args->cpno != 0 && !ronly) { - error = EROFS; - goto error; - } - - printf("WARNING: NANDFS is considered to be a highly experimental " - "feature in FreeBSD.\n"); - - error = nandfs_mount_device(devvp, mp, args, &nandfsdev); - if (error) - goto error; - - nmp = (struct nandfsmount *) malloc(sizeof(struct nandfsmount), - M_NANDFSMNT, M_WAITOK | M_ZERO); - - mp->mnt_data = nmp; - nmp->nm_vfs_mountp = mp; - nmp->nm_ronly = ronly; - MNT_ILOCK(mp); - mp->mnt_flag |= MNT_LOCAL; - mp->mnt_kern_flag |= MNTK_USES_BCACHE; - MNT_IUNLOCK(mp); - nmp->nm_nandfsdev = nandfsdev; - /* Add our mountpoint */ - STAILQ_INSERT_TAIL(&nandfsdev->nd_mounts, nmp, nm_next_mount); - - if (args->cpno > nandfsdev->nd_last_cno) { - printf("WARNING: supplied checkpoint number (%jd) is greater " - "than last known checkpoint on filesystem (%jd). Mounting" - " checkpoint %jd\n", (uintmax_t)args->cpno, - (uintmax_t)nandfsdev->nd_last_cno, - (uintmax_t)nandfsdev->nd_last_cno); - args->cpno = nandfsdev->nd_last_cno; - } - - /* Setting up other parameters */ - nmp->nm_mount_args = *args; - free(args, M_NANDFSMNT); - error = nandfs_mount_checkpoint(nmp); - if (error) { - nandfs_unmount(mp, MNT_FORCE); - goto unmounted; - } - - if (!ronly) { - error = start_syncer(nmp); - if (error == 0) - error = nandfs_start_cleaner(nmp->nm_nandfsdev); - if (error) - nandfs_unmount(mp, MNT_FORCE); - } - - return (0); - -error: - if (args != NULL) - free(args, M_NANDFSMNT); - - if (nmp != NULL) { - free(nmp, M_NANDFSMNT); - mp->mnt_data = NULL; - } -unmounted: - return (error); -} - -static int -nandfs_unmount(struct mount *mp, int mntflags) -{ - struct nandfs_device *nandfsdev; - struct nandfsmount *nmp; - int error; - int flags = 0; - - DPRINTF(VOLUMES, ("%s: mp = %p\n", __func__, (void *)mp)); - - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - - nmp = mp->mnt_data; - nandfsdev = nmp->nm_nandfsdev; - - error = vflush(mp, 0, flags | SKIPSYSTEM, curthread); - if (error) - return (error); - - if (!(nmp->nm_ronly)) { - nandfs_stop_cleaner(nandfsdev); - stop_syncer(nmp); - } - - if (nmp->nm_ifile_node) - NANDFS_UNSET_SYSTEMFILE(NTOV(nmp->nm_ifile_node)); - - /* Remove our mount point */ - STAILQ_REMOVE(&nandfsdev->nd_mounts, nmp, nandfsmount, nm_next_mount); - - /* Unmount the device itself when we're the last one */ - nandfs_unmount_device(nandfsdev); - - free_nandfs_mountinfo(mp); - - /* - * Finally, throw away the null_mount structure - */ - mp->mnt_data = 0; - MNT_ILOCK(mp); - mp->mnt_flag &= ~MNT_LOCAL; - MNT_IUNLOCK(mp); - - return (0); -} - -static int -nandfs_statfs(struct mount *mp, struct statfs *sbp) -{ - struct nandfsmount *nmp; - struct nandfs_device *nandfsdev; - struct nandfs_fsdata *fsdata; - struct nandfs_super_block *sb; - struct nandfs_block_group_desc *groups; - struct nandfs_node *ifile; - struct nandfs_mdt *mdt; - struct buf *bp; - int i, error; - uint32_t entries_per_group; - uint64_t files = 0; - - nmp = mp->mnt_data; - nandfsdev = nmp->nm_nandfsdev; - fsdata = &nandfsdev->nd_fsdata; - sb = &nandfsdev->nd_super; - ifile = nmp->nm_ifile_node; - mdt = &nandfsdev->nd_ifile_mdt; - entries_per_group = mdt->entries_per_group; - - VOP_LOCK(NTOV(ifile), LK_SHARED); - error = nandfs_bread(ifile, 0, NOCRED, 0, &bp); - if (error) { - brelse(bp); - VOP_UNLOCK(NTOV(ifile), 0); - return (error); - } - - groups = (struct nandfs_block_group_desc *)bp->b_data; - - for (i = 0; i < mdt->groups_per_desc_block; i++) - files += (entries_per_group - groups[i].bg_nfrees); - - brelse(bp); - VOP_UNLOCK(NTOV(ifile), 0); - - sbp->f_bsize = nandfsdev->nd_blocksize; - sbp->f_iosize = sbp->f_bsize; - sbp->f_blocks = fsdata->f_blocks_per_segment * fsdata->f_nsegments; - sbp->f_bfree = sb->s_free_blocks_count; - sbp->f_bavail = sbp->f_bfree; - sbp->f_files = files; - sbp->f_ffree = 0; - return (0); -} - -static int -nandfs_root(struct mount *mp, int flags, struct vnode **vpp) -{ - struct nandfsmount *nmp = VFSTONANDFS(mp); - struct nandfs_node *node; - int error; - - error = nandfs_get_node(nmp, NANDFS_ROOT_INO, &node); - if (error) - return (error); - - KASSERT(NTOV(node)->v_vflag & VV_ROOT, - ("root_vp->v_vflag & VV_ROOT")); - - *vpp = NTOV(node); - - return (error); -} - -static int -nandfs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) -{ - struct nandfsmount *nmp = VFSTONANDFS(mp); - struct nandfs_node *node; - int error; - - error = nandfs_get_node(nmp, ino, &node); - if (node) - *vpp = NTOV(node); - - return (error); -} - -static int -nandfs_sync(struct mount *mp, int waitfor) -{ - struct nandfsmount *nmp = VFSTONANDFS(mp); - - DPRINTF(SYNC, ("%s: mp %p waitfor %d\n", __func__, mp, waitfor)); - - /* - * XXX: A hack to be removed soon - */ - if (waitfor == MNT_LAZY) - return (0); - if (waitfor == MNT_SUSPEND) - return (0); - nandfs_wakeup_wait_sync(nmp->nm_nandfsdev, SYNCER_VFS_SYNC); - return (0); -} - -static struct vfsops nandfs_vfsops = { - .vfs_init = nandfs_init, - .vfs_mount = nandfs_mount, - .vfs_root = nandfs_root, - .vfs_statfs = nandfs_statfs, - .vfs_uninit = nandfs_uninit, - .vfs_unmount = nandfs_unmount, - .vfs_vget = nandfs_vget, - .vfs_sync = nandfs_sync, -}; - -VFS_SET(nandfs_vfsops, nandfs, VFCF_LOOPBACK); Property changes on: head/sys/fs/nandfs/nandfs_vfsops.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/fs/smbfs/smbfs_io.c =================================================================== --- head/sys/fs/smbfs/smbfs_io.c (revision 349351) +++ head/sys/fs/smbfs/smbfs_io.c (revision 349352) @@ -1,676 +1,680 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2000-2001 Boris Popov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* #include */ #include #include #include #include #include #include /*#define SMBFS_RWGENERIC*/ extern uma_zone_t smbfs_pbuf_zone; static int smbfs_fastlookup = 1; SYSCTL_DECL(_vfs_smbfs); SYSCTL_INT(_vfs_smbfs, OID_AUTO, fastlookup, CTLFLAG_RW, &smbfs_fastlookup, 0, ""); #define DE_SIZE (sizeof(struct dirent)) static int smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred) { struct dirent de; struct componentname cn; struct smb_cred *scred; struct smbfs_fctx *ctx; struct vnode *newvp; struct smbnode *np = VTOSMB(vp); int error/*, *eofflag = ap->a_eofflag*/; long offset, limit; np = VTOSMB(vp); SMBVDEBUG("dirname='%s'\n", np->n_name); scred = smbfs_malloc_scred(); smb_makescred(scred, uio->uio_td, cred); offset = uio->uio_offset / DE_SIZE; /* offset in the directory */ limit = uio->uio_resid / DE_SIZE; if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) { error = EINVAL; goto out; } while (limit && offset < 2) { limit--; bzero((caddr_t)&de, DE_SIZE); de.d_reclen = DE_SIZE; de.d_fileno = (offset == 0) ? np->n_ino : (np->n_parent ? np->n_parentino : 2); if (de.d_fileno == 0) de.d_fileno = 0x7ffffffd + offset; de.d_namlen = offset + 1; de.d_name[0] = '.'; de.d_name[1] = '.'; de.d_type = DT_DIR; dirent_terminate(&de); error = uiomove(&de, DE_SIZE, uio); if (error) goto out; offset++; uio->uio_offset += DE_SIZE; } if (limit == 0) { error = 0; goto out; } if (offset != np->n_dirofs || np->n_dirseq == NULL) { SMBVDEBUG("Reopening search %ld:%ld\n", offset, np->n_dirofs); if (np->n_dirseq) { smbfs_findclose(np->n_dirseq, scred); np->n_dirseq = NULL; } np->n_dirofs = 2; error = smbfs_findopen(np, "*", 1, SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, scred, &ctx); if (error) { SMBVDEBUG("can not open search, error = %d", error); goto out; } np->n_dirseq = ctx; } else ctx = np->n_dirseq; while (np->n_dirofs < offset) { error = smbfs_findnext(ctx, offset - np->n_dirofs++, scred); if (error) { smbfs_findclose(np->n_dirseq, scred); np->n_dirseq = NULL; error = ENOENT ? 0 : error; goto out; } } error = 0; for (; limit; limit--, offset++) { error = smbfs_findnext(ctx, limit, scred); if (error) break; np->n_dirofs++; bzero((caddr_t)&de, DE_SIZE); de.d_reclen = DE_SIZE; de.d_fileno = ctx->f_attr.fa_ino; de.d_type = (ctx->f_attr.fa_attr & SMB_FA_DIR) ? DT_DIR : DT_REG; de.d_namlen = ctx->f_nmlen; bcopy(ctx->f_name, de.d_name, de.d_namlen); dirent_terminate(&de); if (smbfs_fastlookup) { error = smbfs_nget(vp->v_mount, vp, ctx->f_name, ctx->f_nmlen, &ctx->f_attr, &newvp); if (!error) { cn.cn_nameptr = de.d_name; cn.cn_namelen = de.d_namlen; cache_enter(vp, newvp, &cn); vput(newvp); } } error = uiomove(&de, DE_SIZE, uio); if (error) break; } if (error == ENOENT) error = 0; uio->uio_offset = offset * DE_SIZE; out: smbfs_free_scred(scred); return error; } int smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred) { struct smbmount *smp = VFSTOSMBFS(vp->v_mount); struct smbnode *np = VTOSMB(vp); struct thread *td; struct vattr vattr; struct smb_cred *scred; int error, lks; /* * Protect against method which is not supported for now */ if (uiop->uio_segflg == UIO_NOCOPY) return EOPNOTSUPP; if (vp->v_type != VREG && vp->v_type != VDIR) { SMBFSERR("vn types other than VREG or VDIR are unsupported !\n"); return EIO; } if (uiop->uio_resid == 0) return 0; if (uiop->uio_offset < 0) return EINVAL; /* if (uiop->uio_offset + uiop->uio_resid > smp->nm_maxfilesize) return EFBIG;*/ td = uiop->uio_td; if (vp->v_type == VDIR) { lks = LK_EXCLUSIVE; /* lockstatus(vp->v_vnlock); */ if (lks == LK_SHARED) vn_lock(vp, LK_UPGRADE | LK_RETRY); error = smbfs_readvdir(vp, uiop, cred); if (lks == LK_SHARED) vn_lock(vp, LK_DOWNGRADE | LK_RETRY); return error; } /* biosize = SSTOCN(smp->sm_share)->sc_txmax;*/ if (np->n_flag & NMODIFIED) { smbfs_attr_cacheremove(vp); error = VOP_GETATTR(vp, &vattr, cred); if (error) return error; np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; } else { error = VOP_GETATTR(vp, &vattr, cred); if (error) return error; if (np->n_mtime.tv_sec != vattr.va_mtime.tv_sec) { error = smbfs_vinvalbuf(vp, td); if (error) return error; np->n_mtime.tv_sec = vattr.va_mtime.tv_sec; } } scred = smbfs_malloc_scred(); smb_makescred(scred, td, cred); error = smb_read(smp->sm_share, np->n_fid, uiop, scred); smbfs_free_scred(scred); return (error); } int smbfs_writevnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, int ioflag) { struct smbmount *smp = VTOSMBFS(vp); struct smbnode *np = VTOSMB(vp); struct smb_cred *scred; struct thread *td; int error = 0; if (vp->v_type != VREG) { SMBERROR("vn types other than VREG unsupported !\n"); return EIO; } SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset, uiop->uio_resid); if (uiop->uio_offset < 0) return EINVAL; /* if (uiop->uio_offset + uiop->uio_resid > smp->nm_maxfilesize) return (EFBIG);*/ td = uiop->uio_td; if (ioflag & (IO_APPEND | IO_SYNC)) { if (np->n_flag & NMODIFIED) { smbfs_attr_cacheremove(vp); error = smbfs_vinvalbuf(vp, td); if (error) return error; } if (ioflag & IO_APPEND) { #ifdef notyet /* * File size can be changed by another client */ smbfs_attr_cacheremove(vp); error = VOP_GETATTR(vp, &vattr, cred); if (error) return (error); #endif uiop->uio_offset = np->n_size; } } if (uiop->uio_resid == 0) return 0; if (vn_rlimit_fsize(vp, uiop, td)) return (EFBIG); scred = smbfs_malloc_scred(); smb_makescred(scred, td, cred); error = smb_write(smp->sm_share, np->n_fid, uiop, scred); smbfs_free_scred(scred); SMBVDEBUG("after: ofs=%jd,resid=%zd\n", (intmax_t)uiop->uio_offset, uiop->uio_resid); if (!error) { if (uiop->uio_offset > np->n_size) { np->n_size = uiop->uio_offset; vnode_pager_setsize(vp, np->n_size); } } return error; } /* * Do an I/O operation to/from a cache block. */ int smbfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td) { struct smbmount *smp = VFSTOSMBFS(vp->v_mount); struct smbnode *np = VTOSMB(vp); struct uio *uiop; struct iovec io; struct smb_cred *scred; int error = 0; uiop = malloc(sizeof(struct uio), M_SMBFSDATA, M_WAITOK); uiop->uio_iov = &io; uiop->uio_iovcnt = 1; uiop->uio_segflg = UIO_SYSSPACE; uiop->uio_td = td; scred = smbfs_malloc_scred(); smb_makescred(scred, td, cr); if (bp->b_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; error = smb_read(smp->sm_share, np->n_fid, uiop, scred); if (error) break; if (uiop->uio_resid) { int left = uiop->uio_resid; int nread = bp->b_bcount - left; if (left > 0) bzero((char *)bp->b_data + nread, left); } break; default: printf("smbfs_doio: type %x unexpected\n",vp->v_type); break; } if (error) { bp->b_error = error; bp->b_ioflags |= BIO_ERROR; } } else { /* write */ if (((bp->b_blkno * DEV_BSIZE) + bp->b_dirtyend) > np->n_size) bp->b_dirtyend = np->n_size - (bp->b_blkno * DEV_BSIZE); 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; error = smb_write(smp->sm_share, np->n_fid, uiop, scred); /* * 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 (error == EINTR || (!error && (bp->b_flags & B_NEEDCOMMIT))) { + int s; + + s = splbio(); bp->b_flags &= ~(B_INVAL|B_NOCACHE); if ((bp->b_flags & B_ASYNC) == 0) bp->b_flags |= B_EINTR; if ((bp->b_flags & B_PAGING) == 0) { bdirty(bp); bp->b_flags &= ~B_DONE; } if ((bp->b_flags & B_ASYNC) == 0) bp->b_flags |= B_EINTR; + splx(s); } else { if (error) { bp->b_ioflags |= BIO_ERROR; bp->b_error = error; } bp->b_dirtyoff = bp->b_dirtyend = 0; } } else { bp->b_resid = 0; bufdone(bp); free(uiop, M_SMBFSDATA); smbfs_free_scred(scred); return 0; } } bp->b_resid = uiop->uio_resid; bufdone(bp); free(uiop, M_SMBFSDATA); smbfs_free_scred(scred); return error; } /* * Vnode op for VM getpages. * Wish wish .... get rid from multiple IO routines */ int smbfs_getpages(ap) struct vop_getpages_args /* { struct vnode *a_vp; vm_page_t *a_m; int a_count; int a_reqpage; } */ *ap; { #ifdef SMBFS_RWGENERIC return vop_stdgetpages(ap); #else int i, error, nextoff, size, toff, npages, count; struct uio uio; struct iovec iov; vm_offset_t kva; struct buf *bp; struct vnode *vp; struct thread *td; struct ucred *cred; struct smbmount *smp; struct smbnode *np; struct smb_cred *scred; vm_object_t object; vm_page_t *pages; vp = ap->a_vp; if ((object = vp->v_object) == NULL) { printf("smbfs_getpages: called with non-merged cache vnode??\n"); return VM_PAGER_ERROR; } td = curthread; /* XXX */ cred = td->td_ucred; /* XXX */ np = VTOSMB(vp); smp = VFSTOSMBFS(vp->v_mount); pages = ap->a_m; npages = ap->a_count; /* * 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. * * XXXGL: is that true for SMB filesystem? */ VM_OBJECT_WLOCK(object); if (pages[npages - 1]->valid != 0 && --npages == 0) goto out; VM_OBJECT_WUNLOCK(object); scred = smbfs_malloc_scred(); smb_makescred(scred, td, cred); bp = uma_zalloc(smbfs_pbuf_zone, M_WAITOK); kva = (vm_offset_t) bp->b_data; pmap_qenter(kva, pages, npages); VM_CNT_INC(v_vnodein); VM_CNT_ADD(v_vnodepgsin, npages); count = npages << PAGE_SHIFT; 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 = smb_read(smp->sm_share, np->n_fid, &uio, scred); smbfs_free_scred(scred); pmap_qremove(kva, npages); uma_zfree(smbfs_pbuf_zone, bp); if (error && (uio.uio_resid == count)) { printf("smbfs_getpages: error %d\n",error); return VM_PAGER_ERROR; } 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, ("smbfs_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, ("smbfs_getpages: page %p is dirty", m)); } else { /* * Read operation was short. If no error occurred * we may have hit a zero-fill section. We simply * leave valid set to 0. */ ; } } out: VM_OBJECT_WUNLOCK(object); if (ap->a_rbehind) *ap->a_rbehind = 0; if (ap->a_rahead) *ap->a_rahead = 0; return (VM_PAGER_OK); #endif /* SMBFS_RWGENERIC */ } /* * Vnode op for VM putpages. * possible bug: all IO done in sync mode * Note that vop_close always invalidate pages before close, so it's * not necessary to open vnode. */ int smbfs_putpages(ap) struct vop_putpages_args /* { struct vnode *a_vp; vm_page_t *a_m; int a_count; int a_sync; int *a_rtvals; } */ *ap; { int error; struct vnode *vp = ap->a_vp; struct thread *td; struct ucred *cred; #ifdef SMBFS_RWGENERIC td = curthread; /* XXX */ cred = td->td_ucred; /* XXX */ VOP_OPEN(vp, FWRITE, cred, td, NULL); error = vop_stdputpages(ap); VOP_CLOSE(vp, FWRITE, cred, td); return error; #else struct uio uio; struct iovec iov; vm_offset_t kva; struct buf *bp; int i, npages, count; int *rtvals; struct smbmount *smp; struct smbnode *np; struct smb_cred *scred; vm_page_t *pages; td = curthread; /* XXX */ cred = td->td_ucred; /* XXX */ /* VOP_OPEN(vp, FWRITE, cred, td, NULL);*/ np = VTOSMB(vp); smp = VFSTOSMBFS(vp->v_mount); pages = ap->a_m; count = ap->a_count; rtvals = ap->a_rtvals; npages = btoc(count); for (i = 0; i < npages; i++) { rtvals[i] = VM_PAGER_ERROR; } bp = uma_zalloc(smbfs_pbuf_zone, M_WAITOK); kva = (vm_offset_t) bp->b_data; pmap_qenter(kva, pages, npages); VM_CNT_INC(v_vnodeout); VM_CNT_ADD(v_vnodepgsout, count); 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_WRITE; uio.uio_td = td; SMBVDEBUG("ofs=%jd,resid=%zd\n", (intmax_t)uio.uio_offset, uio.uio_resid); scred = smbfs_malloc_scred(); smb_makescred(scred, td, cred); error = smb_write(smp->sm_share, np->n_fid, &uio, scred); smbfs_free_scred(scred); /* VOP_CLOSE(vp, FWRITE, cred, td);*/ SMBVDEBUG("paged write done: %d\n", error); pmap_qremove(kva, npages); uma_zfree(smbfs_pbuf_zone, bp); if (error == 0) { vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid, npages * PAGE_SIZE, npages * PAGE_SIZE); } return (rtvals[0]); #endif /* SMBFS_RWGENERIC */ } /* * Flush and invalidate all dirty buffers. If another process is already * doing the flush, just wait for completion. */ int smbfs_vinvalbuf(struct vnode *vp, struct thread *td) { struct smbnode *np = VTOSMB(vp); int error = 0; if (vp->v_iflag & VI_DOOMED) return 0; while (np->n_flag & NFLUSHINPROG) { np->n_flag |= NFLUSHWANT; error = tsleep(&np->n_flag, PRIBIO + 2, "smfsvinv", 2 * hz); error = smb_td_intr(td); if (error == EINTR) return EINTR; } np->n_flag |= NFLUSHINPROG; if (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); } error = vinvalbuf(vp, V_SAVE, PCATCH, 0); while (error) { if (error == ERESTART || error == EINTR) { np->n_flag &= ~NFLUSHINPROG; if (np->n_flag & NFLUSHWANT) { np->n_flag &= ~NFLUSHWANT; wakeup(&np->n_flag); } return EINTR; } error = vinvalbuf(vp, V_SAVE, PCATCH, 0); } np->n_flag &= ~(NMODIFIED | NFLUSHINPROG); if (np->n_flag & NFLUSHWANT) { np->n_flag &= ~NFLUSHWANT; wakeup(&np->n_flag); } return (error); } Index: head/sys/geom/geom_flashmap.c =================================================================== --- head/sys/geom/geom_flashmap.c (revision 349351) +++ head/sys/geom/geom_flashmap.c (revision 349352) @@ -1,252 +1,228 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2012 Semihalf * Copyright (c) 2009 Jakub Klama * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include -#include - struct g_flashmap_slice { off_t sl_start; off_t sl_end; const char *sl_name; STAILQ_ENTRY(g_flashmap_slice) sl_link; }; STAILQ_HEAD(g_flashmap_head, g_flashmap_slice); static struct { const char *type; flash_slicer_t slicer; } g_flashmap_slicers[] = { { "NAND::device", NULL }, { "CFI::device", NULL }, { "SPI::device", NULL }, { "MMC::device", NULL } }; -static g_ioctl_t g_flashmap_ioctl; static g_taste_t g_flashmap_taste; static int g_flashmap_load(device_t dev, struct g_provider *pp, flash_slicer_t slicer, struct g_flashmap_head *head); static int g_flashmap_modify(struct g_flashmap *gfp, struct g_geom *gp, const char *devname, int secsize, struct g_flashmap_head *slices); static void g_flashmap_print(struct g_flashmap_slice *slice); MALLOC_DECLARE(M_FLASHMAP); MALLOC_DEFINE(M_FLASHMAP, "geom_flashmap", "GEOM flash memory slicer class"); static void g_flashmap_print(struct g_flashmap_slice *slice) { printf("%08jx-%08jx: %s (%juKB)\n", (uintmax_t)slice->sl_start, (uintmax_t)slice->sl_end, slice->sl_name, (uintmax_t)(slice->sl_end - slice->sl_start) / 1024); } static int g_flashmap_modify(struct g_flashmap *gfp, struct g_geom *gp, const char *devname, int secsize, struct g_flashmap_head *slices) { struct g_flashmap_slice *slice; int i, error; g_topology_assert(); i = 0; STAILQ_FOREACH(slice, slices, sl_link) { if (bootverbose) { printf("%s: slice ", devname); g_flashmap_print(slice); } error = g_slice_config(gp, i++, G_SLICE_CONFIG_CHECK, slice->sl_start, slice->sl_end - slice->sl_start + 1, secsize, FLASH_SLICES_FMT, gp->name, slice->sl_name); if (error) return (error); } i = 0; STAILQ_FOREACH(slice, slices, sl_link) { free(__DECONST(void *, gfp->labels[i]), M_FLASHMAP); gfp->labels[i] = strdup(slice->sl_name, M_FLASHMAP); error = g_slice_config(gp, i++, G_SLICE_CONFIG_SET, slice->sl_start, slice->sl_end - slice->sl_start + 1, secsize, "%ss.%s", gp->name, slice->sl_name); if (error) return (error); } return (0); } -static int -g_flashmap_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, - struct thread *td) -{ - struct g_consumer *cp; - struct g_geom *gp; - - if (cmd != NAND_IO_GET_CHIP_PARAM) - return (ENOIOCTL); - - cp = LIST_FIRST(&pp->geom->consumer); - if (cp == NULL) - return (ENOIOCTL); - gp = cp->provider->geom; - if (gp->ioctl == NULL) - return (ENOIOCTL); - - return (gp->ioctl(cp->provider, cmd, data, fflag, td)); -} - static struct g_geom * g_flashmap_taste(struct g_class *mp, struct g_provider *pp, int flags) { struct g_geom *gp; struct g_consumer *cp; struct g_flashmap_head head; struct g_flashmap_slice *slice, *slice_temp; struct g_flashmap *gfp; flash_slicer_t slicer; device_t dev; int i, size; g_trace(G_T_TOPOLOGY, "flashmap_taste(%s,%s)", mp->name, pp->name); g_topology_assert(); if (flags == G_TF_NORMAL && strcmp(pp->geom->class->name, G_DISK_CLASS_NAME) != 0) return (NULL); gp = g_slice_new(mp, FLASH_SLICES_MAX_NUM, pp, &cp, (void**)&gfp, sizeof(struct g_flashmap), NULL); if (gp == NULL) return (NULL); STAILQ_INIT(&head); do { slicer = NULL; for (i = 0; i < nitems(g_flashmap_slicers); i++) { size = sizeof(device_t); if (g_io_getattr(g_flashmap_slicers[i].type, cp, &size, &dev) == 0) { slicer = g_flashmap_slicers[i].slicer; break; } } if (slicer == NULL) break; if (g_flashmap_load(dev, pp, slicer, &head) == 0) break; g_flashmap_modify(gfp, gp, cp->provider->name, cp->provider->sectorsize, &head); } while (0); g_access(cp, -1, 0, 0); STAILQ_FOREACH_SAFE(slice, &head, sl_link, slice_temp) free(slice, M_FLASHMAP); if (LIST_EMPTY(&gp->provider)) { g_slice_spoiled(cp); return (NULL); } return (gp); } static int g_flashmap_load(device_t dev, struct g_provider *pp, flash_slicer_t slicer, struct g_flashmap_head *head) { struct flash_slice *slices; struct g_flashmap_slice *slice; int i, nslices = 0; slices = malloc(sizeof(struct flash_slice) * FLASH_SLICES_MAX_NUM, M_FLASHMAP, M_WAITOK | M_ZERO); if (slicer(dev, pp->name, slices, &nslices) == 0) { for (i = 0; i < nslices; i++) { slice = malloc(sizeof(struct g_flashmap_slice), M_FLASHMAP, M_WAITOK); slice->sl_name = slices[i].label; slice->sl_start = slices[i].base; slice->sl_end = slices[i].base + slices[i].size - 1; STAILQ_INSERT_TAIL(head, slice, sl_link); } } free(slices, M_FLASHMAP); return (nslices); } void flash_register_slicer(flash_slicer_t slicer, u_int type, bool force) { g_topology_lock(); if (g_flashmap_slicers[type].slicer == NULL || force == TRUE) g_flashmap_slicers[type].slicer = slicer; g_topology_unlock(); } static struct g_class g_flashmap_class = { .name = FLASHMAP_CLASS_NAME, .version = G_VERSION, .taste = g_flashmap_taste, - .ioctl = g_flashmap_ioctl, }; DECLARE_GEOM_CLASS(g_flashmap_class, g_flashmap); MODULE_VERSION(g_flashmap, 0); Index: head/sys/modules/Makefile =================================================================== --- head/sys/modules/Makefile (revision 349351) +++ head/sys/modules/Makefile (revision 349352) @@ -1,809 +1,802 @@ # $FreeBSD$ SYSDIR?=${SRCTOP}/sys .include "${SYSDIR}/conf/kern.opts.mk" SUBDIR_PARALLEL= # Modules that include binary-only blobs of microcode should be selectable by # MK_SOURCELESS_UCODE option (see below). .if defined(MODULES_OVERRIDE) && !defined(ALL_MODULES) SUBDIR=${MODULES_OVERRIDE} .else SUBDIR= \ ${_3dfx} \ ${_3dfx_linux} \ ${_aac} \ ${_aacraid} \ accf_data \ accf_dns \ accf_http \ acl_nfs4 \ acl_posix1e \ ${_acpi} \ ae \ ${_aesni} \ age \ ${_agp} \ ahci \ aic7xxx \ alc \ ale \ alq \ ${_amd_ecc_inject} \ ${_amdgpio} \ ${_amdsbwd} \ ${_amdsmn} \ ${_amdtemp} \ amr \ ${_an} \ ${_aout} \ ${_apm} \ ${_arcmsr} \ ${_allwinner} \ ${_armv8crypto} \ ${_asmc} \ ata \ ath \ ath_dfs \ ath_hal \ ath_hal_ar5210 \ ath_hal_ar5211 \ ath_hal_ar5212 \ ath_hal_ar5416 \ ath_hal_ar9300 \ ath_main \ ath_rate \ ath_pci \ ${_autofs} \ ${_auxio} \ ${_bce} \ ${_bcm283x_clkman} \ ${_bcm283x_pwm} \ bfe \ bge \ bhnd \ ${_bxe} \ ${_bios} \ ${_bktr} \ ${_blake2} \ bnxt \ bridgestp \ bwi \ bwn \ ${_bytgpio} \ ${_chvgpio} \ cam \ ${_cardbus} \ ${_carp} \ cas \ ${_cbb} \ cc \ ${_ccp} \ cd9660 \ cd9660_iconv \ ${_ce} \ ${_cfi} \ ${_chromebook_platform} \ ${_ciss} \ cloudabi \ ${_cloudabi32} \ ${_cloudabi64} \ ${_cmx} \ ${_coretemp} \ ${_cp} \ ${_cpsw} \ ${_cpuctl} \ ${_cpufreq} \ ${_crypto} \ ${_cryptodev} \ ${_ctau} \ ctl \ ${_cxgb} \ ${_cxgbe} \ dc \ dcons \ dcons_crom \ ${_dpms} \ dummynet \ ${_efirt} \ ${_em} \ ${_ena} \ ${_epic} \ esp \ ${_et} \ evdev \ ${_exca} \ ext2fs \ fdc \ fdescfs \ ${_ffec} \ filemon \ firewire \ firmware \ fusefs \ ${_fxp} \ gem \ geom \ ${_glxiic} \ ${_glxsb} \ gpio \ hifn \ hme \ ${_hpt27xx} \ ${_hptiop} \ ${_hptmv} \ ${_hptnr} \ ${_hptrr} \ hwpmc \ ${_hwpmc_mips24k} \ ${_hwpmc_mips74k} \ ${_hyperv} \ i2c \ ${_iavf} \ ${_ibcore} \ ${_ichwd} \ ${_ida} \ if_bridge \ if_disc \ if_edsc \ ${_if_enc} \ if_epair \ ${_if_gif} \ ${_if_gre} \ ${_if_me} \ if_lagg \ ${_if_ndis} \ ${_if_stf} \ if_tuntap \ if_vlan \ if_vxlan \ iflib \ ${_iir} \ imgact_binmisc \ ${_intelspi} \ ${_io} \ ${_ioat} \ ${_ipoib} \ ${_ipdivert} \ ${_ipfilter} \ ${_ipfw} \ ipfw_nat \ ${_ipfw_nat64} \ ${_ipfw_nptv6} \ ${_ipfw_pmod} \ ${_ipmi} \ ip6_mroute_mod \ ip_mroute_mod \ ${_ips} \ ${_ipsec} \ ${_ipw} \ ${_ipwfw} \ ${_isci} \ ${_iser} \ isp \ ${_ispfw} \ ${_iwi} \ ${_iwifw} \ ${_iwm} \ ${_iwmfw} \ ${_iwn} \ ${_iwnfw} \ ${_ix} \ ${_ixv} \ ${_ixl} \ jme \ kbdmux \ kgssapi \ kgssapi_krb5 \ khelp \ krpc \ ksyms \ le \ lge \ libalias \ libiconv \ libmchain \ lindebugfs \ ${_linux} \ ${_linux_common} \ ${_linux64} \ linuxkpi \ ${_lio} \ lpt \ mac_biba \ mac_bsdextended \ mac_ifoff \ mac_lomac \ mac_mls \ mac_none \ mac_ntpd \ mac_partition \ mac_portacl \ mac_seeotheruids \ mac_stub \ mac_test \ malo \ md \ mdio \ mem \ mfi \ mii \ mlx \ mlxfw \ ${_mlx4} \ ${_mlx4ib} \ ${_mlx4en} \ ${_mlx5} \ ${_mlx5en} \ ${_mlx5ib} \ ${_mly} \ mmc \ mmcsd \ ${_mpr} \ ${_mps} \ mpt \ mqueue \ mrsas \ msdosfs \ msdosfs_iconv \ msk \ ${_mthca} \ mvs \ mwl \ ${_mwlfw} \ mxge \ my \ - ${_nandfs} \ - ${_nandsim} \ ${_nctgpio} \ ${_ndis} \ ${_netgraph} \ ${_nfe} \ nfscl \ nfscommon \ nfsd \ nfslock \ nfslockd \ nfssvc \ nge \ nmdm \ nullfs \ ${_ntb} \ ${_nvd} \ ${_nvdimm} \ ${_nvme} \ ${_nvram} \ oce \ ${_ocs_fc} \ otus \ ${_otusfw} \ ow \ ${_padlock} \ ${_padlock_rng} \ ${_pccard} \ ${_pcfclock} \ ${_pf} \ ${_pflog} \ ${_pfsync} \ plip \ ${_pms} \ ppbus \ ppc \ ppi \ pps \ procfs \ proto \ pseudofs \ ${_pst} \ pty \ puc \ pwm \ ${_qlxge} \ ${_qlxgb} \ ${_qlxgbe} \ ${_qlnx} \ ral \ ${_ralfw} \ ${_random_fortuna} \ ${_random_other} \ rc4 \ ${_rdma} \ ${_rdrand_rng} \ re \ rl \ ${_rockchip} \ rtwn \ rtwn_pci \ rtwn_usb \ ${_rtwnfw} \ ${_s3} \ ${_safe} \ ${_sbni} \ scc \ sdhci \ ${_sdhci_acpi} \ sdhci_pci \ sdio \ sem \ send \ ${_sfxge} \ sge \ ${_sgx} \ ${_sgx_linux} \ siftr \ siis \ sis \ sk \ ${_smartpqi} \ smbfs \ snp \ sound \ ${_speaker} \ spi \ ${_splash} \ ${_sppp} \ ste \ stge \ ${_sym} \ ${_syscons} \ sysvipc \ tcp \ ${_ti} \ tmpfs \ ${_toecore} \ ${_tpm} \ trm \ ${_twa} \ twe \ tws \ uart \ ubsec \ udf \ udf_iconv \ ufs \ uinput \ unionfs \ usb \ ${_vesa} \ ${_virtio} \ vge \ ${_viawd} \ videomode \ vkbd \ ${_vmm} \ ${_vmware} \ ${_vpo} \ vr \ vte \ ${_wbwd} \ ${_wi} \ wlan \ wlan_acl \ wlan_amrr \ wlan_ccmp \ wlan_rssadapt \ wlan_tkip \ wlan_wep \ wlan_xauth \ ${_wpi} \ ${_wpifw} \ ${_x86bios} \ xl \ xz \ zlib .if ${MK_AUTOFS} != "no" || defined(ALL_MODULES) _autofs= autofs .endif .if ${MK_CDDL} != "no" || defined(ALL_MODULES) .if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv[67]*} != "") && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_CPUARCH} != "sparc64" SUBDIR+= dtrace .endif SUBDIR+= opensolaris .endif .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) .if exists(${SRCTOP}/sys/opencrypto) _crypto= crypto _cryptodev= cryptodev _random_fortuna=random_fortuna _random_other= random_other .endif .endif .if ${MK_CUSE} != "no" || defined(ALL_MODULES) SUBDIR+= cuse .endif .if (${MK_INET_SUPPORT} != "no" || ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _carp= carp _toecore= toecore _if_enc= if_enc _if_gif= if_gif _if_gre= if_gre _ipfw_pmod= ipfw_pmod .if ${MK_IPSEC_SUPPORT} != "no" _ipsec= ipsec .endif .endif .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _if_stf= if_stf .endif .if ${MK_INET_SUPPORT} != "no" || defined(ALL_MODULES) _if_me= if_me _ipdivert= ipdivert _ipfw= ipfw .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nat64= ipfw_nat64 .endif .endif .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES) _ipfw_nptv6= ipfw_nptv6 .endif .if ${MK_IPFILTER} != "no" || defined(ALL_MODULES) _ipfilter= ipfilter .endif .if ${MK_ISCSI} != "no" || defined(ALL_MODULES) SUBDIR+= cfiscsi SUBDIR+= iscsi SUBDIR+= iscsi_initiator .endif .if !empty(OPT_FDT) SUBDIR+= fdt .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "i386" SUBDIR+= linprocfs SUBDIR+= linsysfs _ena= ena .if ${MK_OFED} != "no" || defined(ALL_MODULES) _ibcore= ibcore _ipoib= ipoib _iser= iser .endif _mlx4= mlx4 _mlx5= mlx5 .if (${MK_INET_SUPPORT} != "no" && ${MK_INET6_SUPPORT} != "no") || \ defined(ALL_MODULES) _mlx4en= mlx4en _mlx5en= mlx5en .endif .if ${MK_OFED} != "no" || defined(ALL_MODULES) _mthca= mthca _mlx4ib= mlx4ib _mlx5ib= mlx5ib .endif -.endif - -.if ${MK_NAND} != "no" || defined(ALL_MODULES) -_nandfs= nandfs -_nandsim= nandsim .endif .if ${MK_NETGRAPH} != "no" || defined(ALL_MODULES) _netgraph= netgraph .endif .if (${MK_PF} != "no" && (${MK_INET_SUPPORT} != "no" || \ ${MK_INET6_SUPPORT} != "no")) || defined(ALL_MODULES) _pf= pf _pflog= pflog .if ${MK_INET_SUPPORT} != "no" _pfsync= pfsync .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" _bce= bce _fxp= fxp _ispfw= ispfw _ti= ti .if ${MACHINE_CPUARCH} != "mips" _mwlfw= mwlfw _otusfw= otusfw _ralfw= ralfw _rtwnfw= rtwnfw .endif .endif .if ${MK_SOURCELESS_UCODE} != "no" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && \ ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ ${MACHINE_CPUARCH} != "riscv" _cxgbe= cxgbe .endif # These rely on 64bit atomics .if ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ ${MACHINE_CPUARCH} != "mips" _mps= mps _mpr= mpr .endif .if ${MK_TESTS} != "no" || defined(ALL_MODULES) SUBDIR+= tests .endif .if ${MK_ZFS} != "no" || defined(ALL_MODULES) SUBDIR+= zfs .endif .if (${MACHINE_CPUARCH} == "mips" && ${MACHINE_ARCH:Mmips64} == "") _hwpmc_mips24k= hwpmc_mips24k _hwpmc_mips74k= hwpmc_mips74k .endif .if ${MACHINE_CPUARCH} != "aarch64" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && ${MACHINE_CPUARCH} != "powerpc" && \ ${MACHINE_CPUARCH} != "riscv" _syscons= syscons _vpo= vpo .endif .if ${MACHINE_CPUARCH} != "mips" # no BUS_SPACE_UNSPECIFIED # No barrier instruction support (specific to this driver) _sym= sym # intr_disable() is a macro, causes problems .if ${MK_SOURCELESS_UCODE} != "no" _cxgb= cxgb .endif .endif .if ${MACHINE_CPUARCH} == "aarch64" _allwinner= allwinner _armv8crypto= armv8crypto _efirt= efirt _em= em _rockchip= rockchip .endif .if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64" _agp= agp _an= an _aout= aout _bios= bios _bktr= bktr .if ${MK_SOURCELESS_UCODE} != "no" _bxe= bxe .endif _cardbus= cardbus _cbb= cbb _cpuctl= cpuctl _cpufreq= cpufreq _dpms= dpms _em= em _et= et _exca= exca _if_ndis= if_ndis _io= io _ix= ix _ixv= ixv _linux= linux .if ${MK_SOURCELESS_UCODE} != "no" _lio= lio .endif _nctgpio= nctgpio _ndis= ndis _ocs_fc= ocs_fc _pccard= pccard .if ${MK_OFED} != "no" || defined(ALL_MODULES) _rdma= rdma .endif _safe= safe _speaker= speaker _splash= splash _sppp= sppp _vmware= vmware _wbwd= wbwd _wi= wi _aac= aac _aacraid= aacraid _acpi= acpi .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) .if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} > 40201 _aesni= aesni .endif .endif _amd_ecc_inject=amd_ecc_inject _amdsbwd= amdsbwd _amdsmn= amdsmn _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _blake2= blake2 .endif _bytgpio= bytgpio _chvgpio= chvgpio _ciss= ciss _chromebook_platform= chromebook_platform _cmx= cmx _coretemp= coretemp .if ${MK_SOURCELESS_HOST} != "no" _hpt27xx= hpt27xx .endif _hptiop= hptiop .if ${MK_SOURCELESS_HOST} != "no" _hptmv= hptmv _hptnr= hptnr _hptrr= hptrr .endif _hyperv= hyperv _ichwd= ichwd _ida= ida _iir= iir _intelspi= intelspi _ipmi= ipmi _ips= ips _isci= isci _ipw= ipw _iwi= iwi _iwm= iwm _iwn= iwn .if ${MK_SOURCELESS_UCODE} != "no" _ipwfw= ipwfw _iwifw= iwifw _iwmfw= iwmfw _iwnfw= iwnfw .endif _mly= mly _nfe= nfe _nvd= nvd _nvme= nvme _nvram= nvram .if ${MK_CRYPT} != "no" || defined(ALL_MODULES) _padlock= padlock _padlock_rng= padlock_rng _rdrand_rng= rdrand_rng .endif _s3= s3 _sdhci_acpi= sdhci_acpi _tpm= tpm _twa= twa _vesa= vesa _viawd= viawd _virtio= virtio _wpi= wpi .if ${MK_SOURCELESS_UCODE} != "no" _wpifw= wpifw .endif _x86bios= x86bios .endif .if ${MACHINE_CPUARCH} == "amd64" _amdgpio= amdgpio _ccp= ccp _efirt= efirt _iavf= iavf _ioat= ioat _ixl= ixl _linux64= linux64 _linux_common= linux_common _ntb= ntb _nvdimm= nvdimm _pms= pms _qlxge= qlxge _qlxgb= qlxgb .if ${MK_SOURCELESS_UCODE} != "no" _qlxgbe= qlxgbe _qlnx= qlnx .endif _sfxge= sfxge _sgx= sgx _sgx_linux= sgx_linux _smartpqi= smartpqi .if ${MK_BHYVE} != "no" || defined(ALL_MODULES) _vmm= vmm .endif .endif .if ${MACHINE_CPUARCH} == "i386" # XXX some of these can move to the general case when de-i386'ed # XXX some of these can move now, but are untested on other architectures. _3dfx= 3dfx _3dfx_linux= 3dfx_linux _apm= apm .if ${MK_SOURCELESS_UCODE} != "no" _ce= ce .endif .if ${MK_SOURCELESS_UCODE} != "no" _cp= cp .endif _glxiic= glxiic _glxsb= glxsb _pcfclock= pcfclock _pst= pst _sbni= sbni .if ${MK_SOURCELESS_UCODE} != "no" _ctau= ctau .endif .endif .if ${MACHINE_CPUARCH} == "arm" _cfi= cfi _cpsw= cpsw .endif .if ${MACHINE_CPUARCH} == "powerpc" _agp= agp _an= an _cardbus= cardbus _cbb= cbb _cfi= cfi _cpufreq= cpufreq _exca= exca _ffec= ffec _nvd= nvd _nvme= nvme _pccard= pccard _wi= wi .endif .if ${MACHINE_ARCH} == "powerpc64" _ipmi= ipmi .endif .if ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "powerpc" # Don't build powermac_nvram for powerpcspe, it's never supported. _nvram= powermac_nvram .endif .if ${MACHINE_CPUARCH} == "sparc64" _auxio= auxio _em= em _epic= epic .endif .if (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "i386") _cloudabi32= cloudabi32 .endif .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" _cloudabi64= cloudabi64 .endif .endif .if ${MACHINE_ARCH:Marmv[67]*} != "" || ${MACHINE_CPUARCH} == "aarch64" _bcm283x_clkman= bcm283x_clkman _bcm283x_pwm= bcm283x_pwm .endif SUBDIR+=${MODULES_EXTRA} .for reject in ${WITHOUT_MODULES} SUBDIR:= ${SUBDIR:N${reject}} .endfor # Calling kldxref(8) for each module is expensive. .if !defined(NO_XREF) .MAKEFLAGS+= -DNO_XREF afterinstall: .PHONY @if type kldxref >/dev/null 2>&1; then \ ${ECHO} ${KLDXREF_CMD} ${DESTDIR}${KMODDIR}; \ ${KLDXREF_CMD} ${DESTDIR}${KMODDIR}; \ fi .endif .include "${SYSDIR}/conf/config.mk" SUBDIR:= ${SUBDIR:u:O} .include Index: head/sys/modules/nand/Makefile =================================================================== --- head/sys/modules/nand/Makefile (revision 349351) +++ head/sys/modules/nand/Makefile (nonexistent) @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/nand - -KMOD = nand -SRCS= nand.c nand_bbt.c nand_cdev.c nand_generic.c nand_geom.c \ - nand_id.c nandbus.c nandbus_if.c nand_if.c nfc_if.c \ - nand_if.h device_if.h bus_if.h nfc_if.h nandbus_if.h - -.include Property changes on: head/sys/modules/nand/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/modules/nandfs/Makefile =================================================================== --- head/sys/modules/nandfs/Makefile (revision 349351) +++ head/sys/modules/nandfs/Makefile (nonexistent) @@ -1,12 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/fs/nandfs - -KMOD= nandfs -SRCS= vnode_if.h opt_ddb.h \ - bmap.c nandfs_bmap.c nandfs_dir.c nandfs_subr.c nandfs_vfsops.c \ - nandfs_vnops.c nandfs_alloc.c nandfs_cpfile.c nandfs_dat.c \ - nandfs_ifile.c nandfs_segment.c nandfs_sufile.c nandfs_buffer.c \ - nandfs_cleaner.c - -.include Property changes on: head/sys/modules/nandfs/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/modules/nandsim/Makefile =================================================================== --- head/sys/modules/nandsim/Makefile (revision 349351) +++ head/sys/modules/nandsim/Makefile (nonexistent) @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/nand - -KMOD= nandsim -SRCS= nandsim.c nandsim_chip.c nandsim_swap.c nandsim_ctrl.c nandsim_log.c\ - bus_if.h device_if.h vnode_if.h nfc_if.h nand_if.h - -.include Property changes on: head/sys/modules/nandsim/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/sys/sys/param.h =================================================================== --- head/sys/sys/param.h (revision 349351) +++ head/sys/sys/param.h (revision 349352) @@ -1,367 +1,367 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed * to the University of California by American Telephone and Telegraph * Co. or Unix System Laboratories, Inc. and are reproduced herein with * the permission of UNIX System Laboratories, 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * 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. * * @(#)param.h 8.3 (Berkeley) 4/4/95 * $FreeBSD$ */ #ifndef _SYS_PARAM_H_ #define _SYS_PARAM_H_ #include #define BSD 199506 /* System version (year & month). */ #define BSD4_3 1 #define BSD4_4 1 /* * __FreeBSD_version numbers are documented in the Porter's Handbook. * If you bump the version for any reason, you should update the documentation * there. * Currently this lives here in the doc/ repository: * * head/en_US.ISO8859-1/books/porters-handbook/versions/chapter.xml * * scheme is: Rxx * 'R' is in the range 0 to 4 if this is a release branch or * X.0-CURRENT before releng/X.0 is created, otherwise 'R' is * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300033 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300034 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, * which by definition is always true on FreeBSD. This macro is also defined * on other systems that use the kernel of FreeBSD, such as GNU/kFreeBSD. * * It is tempting to use this macro in userland code when we want to enable * kernel-specific routines, and in fact it's fine to do this in code that * is part of FreeBSD itself. However, be aware that as presence of this * macro is still not widespread (e.g. older FreeBSD versions, 3rd party * compilers, etc), it is STRONGLY DISCOURAGED to check for this macro in * external applications without also checking for __FreeBSD__ as an * alternative. */ #undef __FreeBSD_kernel__ #define __FreeBSD_kernel__ #if defined(_KERNEL) || defined(IN_RTLD) #define P_OSREL_SIGWAIT 700000 #define P_OSREL_SIGSEGV 700004 #define P_OSREL_MAP_ANON 800104 #define P_OSREL_MAP_FSTRICT 1100036 #define P_OSREL_SHUTDOWN_ENOTCONN 1100077 #define P_OSREL_MAP_GUARD 1200035 #define P_OSREL_WRFSBASE 1200041 #define P_OSREL_CK_CYLGRP 1200046 #define P_OSREL_VMTOTAL64 1200054 #define P_OSREL_CK_SUPERBLOCK 1300000 #define P_OSREL_CK_INODE 1300005 #define P_OSREL_MAJOR(x) ((x) / 100000) #endif #ifndef LOCORE #include #endif /* * Machine-independent constants (some used in following include files). * Redefined constants are from POSIX 1003.1 limits file. * * MAXCOMLEN should be >= sizeof(ac_comm) (see ) */ #include #define MAXCOMLEN 19 /* max command name remembered */ #define MAXINTERP PATH_MAX /* max interpreter file name length */ #define MAXLOGNAME 33 /* max login name length (incl. NUL) */ #define MAXUPRC CHILD_MAX /* max simultaneous processes */ #define NCARGS ARG_MAX /* max bytes for an exec function */ #define NGROUPS (NGROUPS_MAX+1) /* max number groups */ #define NOFILE OPEN_MAX /* max open files per process */ #define NOGROUP 65535 /* marker for empty group set member */ #define MAXHOSTNAMELEN 256 /* max hostname size */ #define SPECNAMELEN 255 /* max length of devicename */ /* More types and definitions used throughout the kernel. */ #ifdef _KERNEL #include #include #ifndef LOCORE #include #include #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif #ifndef _KERNEL /* Signals. */ #include #endif /* Machine type dependent parameters. */ #include #ifndef _KERNEL #include #endif #ifndef DEV_BSHIFT #define DEV_BSHIFT 9 /* log2(DEV_BSIZE) */ #endif #define DEV_BSIZE (1<>PAGE_SHIFT) #endif /* * btodb() is messy and perhaps slow because `bytes' may be an off_t. We * want to shift an unsigned type to avoid sign extension and we don't * want to widen `bytes' unnecessarily. Assume that the result fits in * a daddr_t. */ #ifndef btodb #define btodb(bytes) /* calculates (bytes / DEV_BSIZE) */ \ (sizeof (bytes) > sizeof(long) \ ? (daddr_t)((unsigned long long)(bytes) >> DEV_BSHIFT) \ : (daddr_t)((unsigned long)(bytes) >> DEV_BSHIFT)) #endif #ifndef dbtob #define dbtob(db) /* calculates (db * DEV_BSIZE) */ \ ((off_t)(db) << DEV_BSHIFT) #endif #define PRIMASK 0x0ff #define PCATCH 0x100 /* OR'd with pri for tsleep to check signals */ #define PDROP 0x200 /* OR'd with pri to stop re-entry of interlock mutex */ #define NZERO 0 /* default "nice" */ #define NBBY 8 /* number of bits in a byte */ #define NBPW sizeof(int) /* number of bytes per word (integer) */ #define CMASK 022 /* default file mask: S_IWGRP|S_IWOTH */ #define NODEV (dev_t)(-1) /* non-existent device */ /* * File system parameters and macros. * * MAXBSIZE - Filesystems are made out of blocks of at most MAXBSIZE bytes * per block. MAXBSIZE may be made larger without effecting * any existing filesystems as long as it does not exceed MAXPHYS, * and may be made smaller at the risk of not being able to use * filesystems which require a block size exceeding MAXBSIZE. * * MAXBCACHEBUF - Maximum size of a buffer in the buffer cache. This must * be >= MAXBSIZE and can be set differently for different * architectures by defining it in . * Making this larger allows NFS to do larger reads/writes. * * BKVASIZE - Nominal buffer space per buffer, in bytes. BKVASIZE is the * minimum KVM memory reservation the kernel is willing to make. * Filesystems can of course request smaller chunks. Actual * backing memory uses a chunk size of a page (PAGE_SIZE). * The default value here can be overridden on a per-architecture * basis by defining it in . * * If you make BKVASIZE too small you risk seriously fragmenting * the buffer KVM map which may slow things down a bit. If you * make it too big the kernel will not be able to optimally use * the KVM memory reserved for the buffer cache and will wind * up with too-few buffers. * * The default is 16384, roughly 2x the block size used by a * normal UFS filesystem. */ #define MAXBSIZE 65536 /* must be power of 2 */ #ifndef MAXBCACHEBUF #define MAXBCACHEBUF MAXBSIZE /* must be a power of 2 >= MAXBSIZE */ #endif #ifndef BKVASIZE #define BKVASIZE 16384 /* must be power of 2 */ #endif #define BKVAMASK (BKVASIZE-1) /* * MAXPATHLEN defines the longest permissible path length after expanding * symbolic links. It is used to allocate a temporary buffer from the buffer * pool in which to do the name expansion, hence should be a power of two, * and must be less than or equal to MAXBSIZE. MAXSYMLINKS defines the * maximum number of symbolic links that may be expanded in a path name. * It should be set high enough to allow all legitimate uses, but halt * infinite loops reasonably quickly. */ #define MAXPATHLEN PATH_MAX #define MAXSYMLINKS 32 /* Bit map related macros. */ #define setbit(a,i) (((unsigned char *)(a))[(i)/NBBY] |= 1<<((i)%NBBY)) #define clrbit(a,i) (((unsigned char *)(a))[(i)/NBBY] &= ~(1<<((i)%NBBY))) #define isset(a,i) \ (((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) #define isclr(a,i) \ ((((const unsigned char *)(a))[(i)/NBBY] & (1<<((i)%NBBY))) == 0) /* Macros for counting and rounding. */ #ifndef howmany #define howmany(x, y) (((x)+((y)-1))/(y)) #endif #define nitems(x) (sizeof((x)) / sizeof((x)[0])) #define rounddown(x, y) (((x)/(y))*(y)) #define rounddown2(x, y) ((x)&(~((y)-1))) /* if y is power of two */ #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */ #define powerof2(x) ((((x)-1)&(x))==0) /* Macros for min/max. */ #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) #ifdef _KERNEL /* * Basic byte order function prototypes for non-inline functions. */ #ifndef LOCORE #ifndef _BYTEORDER_PROTOTYPED #define _BYTEORDER_PROTOTYPED __BEGIN_DECLS __uint32_t htonl(__uint32_t); __uint16_t htons(__uint16_t); __uint32_t ntohl(__uint32_t); __uint16_t ntohs(__uint16_t); __END_DECLS #endif #endif #ifndef _BYTEORDER_FUNC_DEFINED #define _BYTEORDER_FUNC_DEFINED #define htonl(x) __htonl(x) #define htons(x) __htons(x) #define ntohl(x) __ntohl(x) #define ntohs(x) __ntohs(x) #endif /* !_BYTEORDER_FUNC_DEFINED */ #endif /* _KERNEL */ /* * Scale factor for scaled integers used to count %cpu time and load avgs. * * The number of CPU `tick's that map to a unique `%age' can be expressed * by the formula (1 / (2 ^ (FSHIFT - 11))). The maximum load average that * can be calculated (assuming 32 bits) can be closely approximated using * the formula (2 ^ (2 * (16 - FSHIFT))) for (FSHIFT < 15). * * For the scheduler to maintain a 1:1 mapping of CPU `tick' to `%age', * FSHIFT must be at least 11; this gives us a maximum load avg of ~1024. */ #define FSHIFT 11 /* bits to right of fixed binary point */ #define FSCALE (1<> (PAGE_SHIFT - DEV_BSHIFT)) #define ctodb(db) /* calculates pages to devblks */ \ ((db) << (PAGE_SHIFT - DEV_BSHIFT)) /* * Old spelling of __containerof(). */ #define member2struct(s, m, x) \ ((struct s *)(void *)((char *)(x) - offsetof(struct s, m))) /* * Access a variable length array that has been declared as a fixed * length array. */ #define __PAST_END(array, offset) (((__typeof__(*(array)) *)(array))[offset]) #endif /* _SYS_PARAM_H_ */ Index: head/targets/pseudo/userland/Makefile.depend =================================================================== --- head/targets/pseudo/userland/Makefile.depend (revision 349351) +++ head/targets/pseudo/userland/Makefile.depend (revision 349352) @@ -1,880 +1,871 @@ # $FreeBSD$ # This file is not autogenerated - take care! .include DIRDEPS= DIRDEPS+= \ bin/cat \ bin/chflags \ bin/chio \ bin/chmod \ bin/cp \ bin/csh \ bin/date \ bin/dd \ bin/df \ bin/domainname \ bin/echo \ bin/ed \ bin/expr \ bin/freebsd-version \ bin/getfacl \ bin/hostname \ bin/kenv \ bin/kill \ bin/ln \ bin/ls \ bin/mkdir \ bin/mv \ bin/pax \ bin/pkill \ bin/ps \ bin/pwait \ bin/pwd \ bin/rcp \ bin/realpath \ bin/rm \ bin/rmail \ bin/rmdir \ bin/setfacl \ bin/sh \ bin/sleep \ bin/stty \ bin/sync \ bin/test \ bin/uuidgen \ sbin/adjkerntz \ sbin/atacontrol \ sbin/atm/atmconfig \ sbin/camcontrol \ sbin/ccdconfig \ sbin/clri \ sbin/comcontrol \ sbin/conscontrol \ sbin/decryptcore \ sbin/ddb \ sbin/devd \ sbin/devfs \ sbin/dhclient \ sbin/dmesg \ sbin/dump \ sbin/dumpfs \ sbin/dumpon \ sbin/etherswitchcfg \ sbin/ffsinfo \ sbin/fsck \ sbin/fsck_ffs \ sbin/fsck_msdosfs \ sbin/fsdb \ sbin/fsirand \ sbin/gbde \ sbin/geom/core \ sbin/ggate/ggatec \ sbin/ggate/ggated \ sbin/ggate/ggatel \ sbin/growfs \ sbin/gvinum \ sbin/hastctl \ sbin/hastd \ sbin/ifconfig \ sbin/init \ sbin/ipf/ipf \ sbin/ipf/ipfs \ sbin/ipf/ipfstat \ sbin/ipf/ipmon \ sbin/ipf/ipnat \ sbin/ipf/ippool \ sbin/ipf/libipf \ sbin/ipfw \ sbin/iscontrol \ sbin/kldconfig \ sbin/kldload \ sbin/kldstat \ sbin/kldunload \ sbin/ldconfig \ sbin/md5 \ sbin/mdconfig \ sbin/mdmfs \ sbin/mknod \ sbin/mksnap_ffs \ sbin/mount \ sbin/mount_cd9660 \ sbin/mount_fusefs \ sbin/mount_msdosfs \ sbin/mount_nfs \ sbin/mount_nullfs \ sbin/mount_udf \ sbin/mount_unionfs \ sbin/natd \ sbin/newfs \ sbin/newfs_msdos \ sbin/nfsiod \ sbin/nos-tun \ sbin/pfctl \ sbin/pflogd \ sbin/ping \ sbin/ping6 \ sbin/quotacheck \ sbin/rcorder \ sbin/reboot \ sbin/recoverdisk \ sbin/resolvconf \ sbin/restore \ sbin/route \ sbin/routed \ sbin/routed/rtquery \ sbin/rtsol \ sbin/savecore \ sbin/setkey \ sbin/shutdown \ sbin/spppcontrol \ sbin/swapon \ sbin/sysctl \ sbin/tunefs \ sbin/umount \ usr.bin/alias \ usr.bin/apply \ usr.bin/ar \ usr.bin/asa \ usr.bin/at \ usr.bin/atf/atf-config \ usr.bin/atf/atf-report \ usr.bin/atf/atf-run \ usr.bin/atf/atf-version \ usr.bin/atm/sscop \ usr.bin/awk \ usr.bin/banner \ usr.bin/basename \ usr.bin/bc \ usr.bin/biff \ usr.bin/bluetooth/bthost \ usr.bin/bluetooth/btsockstat \ usr.bin/bluetooth/rfcomm_sppd \ usr.bin/bmake \ usr.bin/brandelf \ usr.bin/bsdiff/bsdiff \ usr.bin/bsdiff/bspatch \ usr.bin/bsdcat \ usr.bin/bzip2 \ usr.bin/bzip2recover \ usr.bin/c89 \ usr.bin/c99 \ usr.bin/calendar \ usr.bin/cap_mkdb \ usr.bin/chat \ usr.bin/checknr \ usr.bin/chkey \ usr.bin/chpass \ usr.bin/cksum \ usr.bin/cmp \ usr.bin/col \ usr.bin/colcrt \ usr.bin/colldef \ usr.bin/colrm \ usr.bin/column \ usr.bin/comm \ usr.bin/compile_et \ usr.bin/compress \ usr.bin/cpio \ usr.bin/cpuset \ usr.bin/csplit \ usr.bin/ctags \ usr.bin/ctlstat \ usr.bin/cut \ usr.bin/dc \ usr.bin/dig \ usr.bin/dirname \ usr.bin/dpv \ usr.bin/drill \ usr.bin/du \ usr.bin/ee \ usr.bin/elf2aout \ usr.bin/elfdump \ usr.bin/enigma \ usr.bin/env \ usr.bin/expand \ usr.bin/false \ usr.bin/fetch \ usr.bin/file \ usr.bin/file2c \ usr.bin/find \ usr.bin/finger \ usr.bin/fmt \ usr.bin/fold \ usr.bin/from \ usr.bin/fstat \ usr.bin/fsync \ usr.bin/ftp \ usr.bin/gcore \ usr.bin/gencat \ usr.bin/getaddrinfo \ usr.bin/getconf \ usr.bin/getent \ usr.bin/getopt \ usr.bin/gprof \ usr.bin/grep \ usr.bin/gzip \ usr.bin/head \ usr.bin/hexdump \ usr.bin/host \ usr.bin/iconv \ usr.bin/id \ usr.bin/ident \ usr.bin/indent \ usr.bin/ipcrm \ usr.bin/ipcs \ usr.bin/iscsictl \ usr.bin/join \ usr.bin/jot \ usr.bin/kdump \ usr.bin/keylogin \ usr.bin/keylogout \ usr.bin/killall \ usr.bin/ktrace \ usr.bin/ktrdump \ usr.bin/lam \ usr.bin/last \ usr.bin/lastcomm \ usr.bin/lex \ usr.bin/ldd \ usr.bin/leave \ usr.bin/less \ usr.bin/lessecho \ usr.bin/lesskey \ usr.bin/lex/lib \ usr.bin/limits \ usr.bin/locale \ usr.bin/localedef \ usr.bin/locate/bigram \ usr.bin/locate/code \ usr.bin/locate/locate \ usr.bin/lock \ usr.bin/lockf \ usr.bin/logger \ usr.bin/login \ usr.bin/logins \ usr.bin/logname \ usr.bin/look \ usr.bin/lorder \ usr.bin/lsvfs \ usr.bin/lzmainfo \ usr.bin/m4 \ usr.bin/mail \ usr.bin/man \ usr.bin/mandoc \ usr.bin/mesg \ usr.bin/minigzip \ usr.bin/ministat \ usr.bin/mkcsmapper \ usr.bin/mkdep \ usr.bin/mkesdb \ usr.bin/mkfifo \ usr.bin/mkimg \ usr.bin/mklocale \ usr.bin/mkstr \ usr.bin/mktemp \ usr.bin/mkuzip \ usr.bin/msgs \ usr.bin/mt \ usr.bin/nc \ usr.bin/ncal \ usr.bin/netstat \ usr.bin/newgrp \ usr.bin/newkey \ usr.bin/nfsstat \ usr.bin/nice \ usr.bin/nl \ usr.bin/nohup \ usr.bin/opieinfo \ usr.bin/opiekey \ usr.bin/opiepasswd \ usr.bin/pagesize \ usr.bin/passwd \ usr.bin/paste \ usr.bin/patch \ usr.bin/pathchk \ usr.bin/perror \ usr.bin/pr \ usr.bin/printenv \ usr.bin/printf \ usr.bin/proccontrol \ usr.bin/procstat \ usr.bin/protect \ usr.bin/quota \ usr.bin/rctl \ usr.bin/renice \ usr.bin/resizewin \ usr.bin/rev \ usr.bin/revoke \ usr.bin/rlogin \ usr.bin/rpcgen \ usr.bin/rpcinfo \ usr.bin/rs \ usr.bin/rsh \ usr.bin/rup \ usr.bin/ruptime \ usr.bin/rusers \ usr.bin/rwall \ usr.bin/rwho \ usr.bin/script \ usr.bin/sdiff \ usr.bin/sed \ usr.bin/seq \ usr.bin/shar \ usr.bin/showmount \ usr.bin/smbutil \ usr.bin/sockstat \ usr.bin/soelim \ usr.bin/sort \ usr.bin/split \ usr.bin/ssh-copy-id \ usr.bin/stat \ usr.bin/stdbuf \ usr.bin/su \ usr.bin/svn/svn \ usr.bin/svn/svnadmin \ usr.bin/svn/svnbench \ usr.bin/svn/svndumpfilter \ usr.bin/svn/svnfsfs \ usr.bin/svn/svnlook \ usr.bin/svn/svnmucc \ usr.bin/svn/svnrdump \ usr.bin/svn/svnserve \ usr.bin/svn/svnsync \ usr.bin/svn/svnversion \ usr.bin/systat \ usr.bin/tabs \ usr.bin/tail \ usr.bin/talk \ usr.bin/tar \ usr.bin/tcopy \ usr.bin/tee \ usr.bin/telnet \ usr.bin/tftp \ usr.bin/time \ usr.bin/timeout \ usr.bin/tip/tip \ usr.bin/top \ usr.bin/touch \ usr.bin/tput \ usr.bin/tr \ usr.bin/true \ usr.bin/truncate \ usr.bin/truss \ usr.bin/tset \ usr.bin/tsort \ usr.bin/tty \ usr.bin/ul \ usr.bin/uname \ usr.bin/unexpand \ usr.bin/unifdef \ usr.bin/uniq \ usr.bin/units \ usr.bin/unvis \ usr.bin/unzip \ usr.bin/usbhidaction \ usr.bin/usbhidctl \ usr.bin/users \ usr.bin/uudecode \ usr.bin/uuencode \ usr.bin/vacation \ usr.bin/vgrind \ usr.bin/vi \ usr.bin/vi/catalog \ usr.bin/vis \ usr.bin/vmstat \ usr.bin/vtfontcvt \ usr.bin/w \ usr.bin/wall \ usr.bin/wc \ usr.bin/what \ usr.bin/whereis \ usr.bin/which \ usr.bin/who \ usr.bin/whois \ usr.bin/write \ usr.bin/xargs \ usr.bin/xinstall \ usr.bin/xo \ usr.bin/xstr \ usr.bin/xz \ usr.bin/xzdec \ usr.bin/yacc \ usr.bin/yes \ usr.bin/ypcat \ usr.bin/ypmatch \ usr.bin/ypwhich \ usr.bin/zstd \ usr.sbin/IPXrouted \ usr.sbin/ac \ usr.sbin/accton \ usr.sbin/adduser \ usr.sbin/amd/amd \ usr.sbin/amd/amq \ usr.sbin/amd/doc \ usr.sbin/amd/fixmount \ usr.sbin/amd/fsinfo \ usr.sbin/amd/hlfsd \ usr.sbin/amd/include \ usr.sbin/amd/libamu \ usr.sbin/amd/mk-amd-map \ usr.sbin/amd/pawd \ usr.sbin/amd/scripts \ usr.sbin/amd/wire-test \ usr.sbin/ancontrol \ usr.sbin/apm \ usr.sbin/arp \ usr.sbin/arpaname \ usr.sbin/audit \ usr.sbin/auditd \ usr.sbin/auditdistd \ usr.sbin/auditreduce \ usr.sbin/authpf \ usr.sbin/autofs \ usr.sbin/binmiscctl \ usr.sbin/bluetooth/ath3kfw \ usr.sbin/bluetooth/bcmfw \ usr.sbin/bluetooth/bt3cfw \ usr.sbin/bluetooth/bthidcontrol \ usr.sbin/bluetooth/bthidd \ usr.sbin/bluetooth/btpand \ usr.sbin/bluetooth/hccontrol \ usr.sbin/bluetooth/hcsecd \ usr.sbin/bluetooth/hcseriald \ usr.sbin/bluetooth/l2control \ usr.sbin/bluetooth/l2ping \ usr.sbin/bluetooth/rfcomm_pppd \ usr.sbin/bluetooth/sdpcontrol \ usr.sbin/bluetooth/sdpd \ usr.sbin/bootparamd/bootparamd \ usr.sbin/bootparamd/callbootd \ usr.sbin/bsdconfig \ usr.sbin/bsdconfig/console \ usr.sbin/bsdconfig/console/include \ usr.sbin/bsdconfig/diskmgmt \ usr.sbin/bsdconfig/diskmgmt/include \ usr.sbin/bsdconfig/docsinstall \ usr.sbin/bsdconfig/docsinstall/include \ usr.sbin/bsdconfig/dot \ usr.sbin/bsdconfig/dot/include \ usr.sbin/bsdconfig/examples \ usr.sbin/bsdconfig/include \ usr.sbin/bsdconfig/includes \ usr.sbin/bsdconfig/includes/include \ usr.sbin/bsdconfig/mouse \ usr.sbin/bsdconfig/mouse/include \ usr.sbin/bsdconfig/networking \ usr.sbin/bsdconfig/networking/include \ usr.sbin/bsdconfig/networking/share \ usr.sbin/bsdconfig/packages \ usr.sbin/bsdconfig/packages/include \ usr.sbin/bsdconfig/password \ usr.sbin/bsdconfig/password/include \ usr.sbin/bsdconfig/password/share \ usr.sbin/bsdconfig/security \ usr.sbin/bsdconfig/security/include \ usr.sbin/bsdconfig/share \ usr.sbin/bsdconfig/share/media \ usr.sbin/bsdconfig/share/packages \ usr.sbin/bsdconfig/startup \ usr.sbin/bsdconfig/startup/include \ usr.sbin/bsdconfig/startup/share \ usr.sbin/bsdconfig/timezone \ usr.sbin/bsdconfig/timezone/include \ usr.sbin/bsdconfig/timezone/share \ usr.sbin/bsdconfig/ttys \ usr.sbin/bsdconfig/ttys/include \ usr.sbin/bsdconfig/usermgmt \ usr.sbin/bsdconfig/usermgmt/include \ usr.sbin/bsdconfig/usermgmt/share \ usr.sbin/bsdinstall/distextract \ usr.sbin/bsdinstall/distfetch \ usr.sbin/bsdinstall/partedit \ usr.sbin/bsdinstall/scripts \ usr.sbin/bsnmpd/bsnmpd \ usr.sbin/bsnmpd/gensnmptree \ usr.sbin/bsnmpd/modules/snmp_atm \ usr.sbin/bsnmpd/modules/snmp_bridge \ usr.sbin/bsnmpd/modules/snmp_hast \ usr.sbin/bsnmpd/modules/snmp_hostres \ usr.sbin/bsnmpd/modules/snmp_lm75 \ usr.sbin/bsnmpd/modules/snmp_mibII \ usr.sbin/bsnmpd/modules/snmp_netgraph \ usr.sbin/bsnmpd/modules/snmp_pf \ usr.sbin/bsnmpd/modules/snmp_target \ usr.sbin/bsnmpd/modules/snmp_usm \ usr.sbin/bsnmpd/modules/snmp_vacm \ usr.sbin/bsnmpd/modules/snmp_wlan \ usr.sbin/bsnmpd/tools/bsnmptools \ usr.sbin/bsnmpd/tools/libbsnmptools \ usr.sbin/cdcontrol \ usr.sbin/chkgrp \ usr.sbin/chown \ usr.sbin/chroot \ usr.sbin/ckdist \ usr.sbin/clear_locks \ usr.sbin/config \ usr.sbin/crashinfo \ usr.sbin/cron/cron \ usr.sbin/cron/crontab \ usr.sbin/cron/lib \ usr.sbin/crunch/crunchgen \ usr.sbin/crunch/crunchide \ usr.sbin/ctladm \ usr.sbin/ctld \ usr.sbin/ctm/ctm \ usr.sbin/ctm/ctm_dequeue \ usr.sbin/ctm/ctm_rmail \ usr.sbin/ctm/ctm_smail \ usr.sbin/daemon \ usr.sbin/dconschat \ usr.sbin/ddns-confgen \ usr.sbin/devctl \ usr.sbin/devinfo \ usr.sbin/digictl \ usr.sbin/diskinfo \ usr.sbin/dnssec-dsfromkey \ usr.sbin/dnssec-keyfromlabel \ usr.sbin/dnssec-keygen \ usr.sbin/dnssec-revoke \ usr.sbin/dnssec-settime \ usr.sbin/dnssec-signzone \ usr.sbin/dumpcis \ usr.sbin/editmap \ usr.sbin/edquota \ usr.sbin/etcupdate \ usr.sbin/extattr \ usr.sbin/extattrctl \ usr.sbin/fdcontrol \ usr.sbin/fdformat \ usr.sbin/fdread \ usr.sbin/fdwrite \ usr.sbin/fifolog/fifolog_create \ usr.sbin/fifolog/fifolog_reader \ usr.sbin/fifolog/fifolog_writer \ usr.sbin/fifolog/lib \ usr.sbin/flowctl \ usr.sbin/fmtree \ usr.sbin/freebsd-update \ usr.sbin/fstyp \ usr.sbin/ftp-proxy \ usr.sbin/fwcontrol \ usr.sbin/genrandom \ usr.sbin/getfmac \ usr.sbin/getpmac \ usr.sbin/gpioctl \ usr.sbin/gssd \ usr.sbin/gstat \ usr.sbin/i2c \ usr.sbin/ifmcstat \ usr.sbin/inetd \ usr.sbin/iostat \ usr.sbin/iovctl \ usr.sbin/ip6addrctl \ usr.sbin/ipfwpcap \ usr.sbin/isc-hmac-fixup \ usr.sbin/iscsid \ usr.sbin/isfctl \ usr.sbin/jail \ usr.sbin/jexec \ usr.sbin/jls \ usr.sbin/kbdcontrol \ usr.sbin/kbdmap \ usr.sbin/keyserv \ usr.sbin/kldxref \ usr.sbin/lastlogin \ usr.sbin/lmcconfig \ usr.sbin/lpr/chkprintcap \ usr.sbin/lpr/common_source \ usr.sbin/lpr/filters \ usr.sbin/lpr/filters.ru/koi2855 \ usr.sbin/lpr/filters.ru/koi2alt \ usr.sbin/lpr/lp \ usr.sbin/lpr/lpc \ usr.sbin/lpr/lpd \ usr.sbin/lpr/lpq \ usr.sbin/lpr/lpr \ usr.sbin/lpr/lprm \ usr.sbin/lpr/lptest \ usr.sbin/lpr/pac \ usr.sbin/mailstats \ usr.sbin/mailwrapper \ usr.sbin/makefs \ usr.sbin/makemap \ usr.sbin/manctl \ usr.sbin/memcontrol \ usr.sbin/mergemaster \ usr.sbin/mfiutil \ usr.sbin/mixer \ usr.sbin/mld6query \ usr.sbin/mlxcontrol \ usr.sbin/mount_smbfs \ usr.sbin/mountd \ usr.sbin/moused \ usr.sbin/mpsutil \ usr.sbin/mptutil \ usr.sbin/mtest \ usr.sbin/named \ usr.sbin/named-checkconf \ usr.sbin/named-checkzone \ usr.sbin/named-journalprint \ usr.sbin/ndp \ usr.sbin/newsyslog \ usr.sbin/nfscbd \ usr.sbin/nfsd \ usr.sbin/nfsdumpstate \ usr.sbin/nfsrevoke \ usr.sbin/nfsuserd \ usr.sbin/ngctl \ usr.sbin/nghook \ usr.sbin/nmtree \ usr.sbin/nologin \ usr.sbin/nscd \ usr.sbin/nsec3hash \ usr.sbin/ntp/doc \ usr.sbin/ntp/doc/drivers/icons \ usr.sbin/ntp/doc/drivers/scripts \ usr.sbin/ntp/doc/drivers \ usr.sbin/ntp/doc/hints \ usr.sbin/ntp/doc/icons \ usr.sbin/ntp/doc/pic \ usr.sbin/ntp/doc/scripts \ usr.sbin/ntp/libntp \ usr.sbin/ntp/libopts \ usr.sbin/ntp/libparse \ usr.sbin/ntp/ntp-keygen \ usr.sbin/ntp/ntpd \ usr.sbin/ntp/ntpdate \ usr.sbin/ntp/ntpdc \ usr.sbin/ntp/ntpq \ usr.sbin/ntp/ntptime \ usr.sbin/ntp/sntp \ usr.sbin/pc-sysinstall/backend \ usr.sbin/pc-sysinstall/backend-partmanager \ usr.sbin/pc-sysinstall/backend-query \ usr.sbin/pc-sysinstall/conf \ usr.sbin/pc-sysinstall/doc \ usr.sbin/pc-sysinstall/examples \ usr.sbin/pc-sysinstall/pc-sysinstall \ usr.sbin/pciconf \ usr.sbin/periodic \ usr.sbin/pkg \ usr.sbin/pmcannotate \ usr.sbin/pmccontrol \ usr.sbin/pmcstat \ usr.sbin/pmcstudy \ usr.sbin/portsnap/make_index \ usr.sbin/portsnap/phttpget \ usr.sbin/portsnap/portsnap \ usr.sbin/powerd \ usr.sbin/ppp \ usr.sbin/pppctl \ usr.sbin/praliases \ usr.sbin/praudit \ usr.sbin/prometheus_sysctl_exporter \ usr.sbin/pstat \ usr.sbin/pw \ usr.sbin/pwd_mkdb \ usr.sbin/quot \ usr.sbin/quotaon \ usr.sbin/rarpd \ usr.sbin/repquota \ usr.sbin/rip6query \ usr.sbin/rmt \ usr.sbin/rndc \ usr.sbin/rndc-confgen \ usr.sbin/route6d \ usr.sbin/rpc.lockd \ usr.sbin/rpc.statd \ usr.sbin/rpc.umntall \ usr.sbin/rpc.yppasswdd \ usr.sbin/rpc.ypupdated \ usr.sbin/rpc.ypxfrd \ usr.sbin/rpcbind \ usr.sbin/rrenumd \ usr.sbin/rtadvctl \ usr.sbin/rtadvd \ usr.sbin/rtprio \ usr.sbin/rtsold \ usr.sbin/rwhod \ usr.sbin/sa \ usr.sbin/sendmail \ usr.sbin/service \ usr.sbin/services_mkdb \ usr.sbin/sesutil \ usr.sbin/setfib \ usr.sbin/setfmac \ usr.sbin/setpmac \ usr.sbin/smbmsg \ usr.sbin/snapinfo \ usr.sbin/spray \ usr.sbin/syslogd \ usr.sbin/sysrc \ usr.sbin/tcpdchk \ usr.sbin/tcpdmatch \ usr.sbin/tcpdrop \ usr.sbin/tcpdump/tcpdump \ usr.sbin/timed/timed \ usr.sbin/timed/timedc \ usr.sbin/traceroute \ usr.sbin/traceroute6 \ usr.sbin/trpt \ usr.sbin/tzsetup \ usr.sbin/uathload \ usr.sbin/uefisign \ usr.sbin/ugidfw \ usr.sbin/uhsoctl \ usr.sbin/unbound/anchor \ usr.sbin/unbound/checkconf \ usr.sbin/unbound/control \ usr.sbin/unbound/daemon \ usr.sbin/unbound/local-setup \ usr.sbin/usbconfig \ usr.sbin/usbdump \ usr.sbin/utx \ usr.sbin/vidcontrol \ usr.sbin/vigr \ usr.sbin/vipw \ usr.sbin/wake \ usr.sbin/watch \ usr.sbin/watchdogd \ usr.sbin/wlandebug \ usr.sbin/wpa/hostapd \ usr.sbin/wpa/hostapd_cli \ usr.sbin/wpa/ndis_events \ usr.sbin/wpa/wpa_cli \ usr.sbin/wpa/wpa_passphrase \ usr.sbin/wpa/wpa_supplicant \ usr.sbin/yp_mkdb \ usr.sbin/ypbind \ usr.sbin/ypldap \ usr.sbin/yppoll \ usr.sbin/yppush \ usr.sbin/ypserv \ usr.sbin/ypset \ usr.sbin/zic/zdump \ usr.sbin/zic/zic \ usr.sbin/zonectl \ ${DEP_RELDIR}/cddl \ ${DEP_RELDIR}/gnu \ ${DEP_RELDIR}/include \ ${DEP_RELDIR}/kerberos5 \ ${DEP_RELDIR}/lib \ ${DEP_RELDIR}/libexec \ ${DEP_RELDIR}/misc \ ${DEP_RELDIR}/secure \ ${DEP_RELDIR}/share \ .if ${MK_EFI} != "no" DIRDEPS+= usr.sbin/efidp .endif -.if ${MK_NAND} != "no" -DIRDEPS+= \ - sbin/nandfs \ - sbin/newfs_nandfs \ - usr.sbin/nandsim \ - usr.sbin/nandtool \ - -.endif - DIRDEPS.amd64= \ sbin/bsdlabel \ sbin/fdisk \ sbin/nvmecontrol \ usr.sbin/acpi/acpiconf \ usr.sbin/acpi/acpidb \ usr.sbin/acpi/acpidump \ usr.sbin/acpi/iasl \ usr.sbin/apm \ usr.sbin/bhyve \ usr.sbin/bhyvectl \ usr.sbin/bhyveload \ usr.sbin/boot0cfg \ usr.sbin/btxld \ usr.sbin/camdd \ usr.sbin/cpucontrol \ usr.sbin/hyperv/tools \ usr.sbin/hyperv/tools/kvp \ usr.sbin/hyperv/tools/vss \ usr.sbin/kgmon \ usr.sbin/lptcontrol \ usr.sbin/mptable \ usr.sbin/ndiscvt \ usr.sbin/spkrtest \ usr.sbin/sade \ usr.sbin/zzz DIRDEPS.arm= \ sbin/bsdlabel \ sbin/fdisk \ usr.sbin/ofwdump \ usr.sbin/kgmon DIRDEPS.i386= \ sbin/bsdlabel \ sbin/fdisk \ sbin/nvmecontrol \ sbin/sconfig \ usr.sbin/apm \ usr.sbin/apmd \ usr.sbin/btxld \ usr.sbin/cpucontrol \ usr.sbin/hyperv/tools \ usr.sbin/hyperv/tools/kvp \ usr.sbin/hyperv/tools/vss \ usr.sbin/kgmon \ usr.sbin/lptcontrol \ usr.sbin/mptable \ usr.sbin/ndiscvt \ usr.sbin/pnpinfo \ usr.sbin/sade \ usr.sbin/spkrtest \ usr.sbin/zzz \ usr.sbin/acpi \ usr.sbin/boot0cfg DIRDEPS.arm64= \ usr.sbin/acpi \ usr.sbin/ofwdump DIRDEPS.mips= \ sbin/bsdlabel \ sbin/fdisk DIRDEPS.sparc64= \ sbin/bsdlabel \ sbin/sunlabel \ usr.sbin/eeprom \ usr.sbin/ofwdump \ usr.sbin/sade DIRDEPS.powerpc= \ usr.sbin/nvram \ usr.sbin/ofwdump .if ${MK_BLACKLIST_SUPPORT} != "no" DIRDEPS+= \ usr.sbin/blacklistctl \ usr.sbin/blacklistd .endif .if ${MK_CXGBETOOL} != "no" DIRDEPS+= usr.sbin/cxgbetool .endif .if ${MK_MLX5TOOL} != "no" DIRDEPS+= usr.sbin/mlx5tool .endif .if ${MK_GPL_DTC} != "yes" DIRDEPS+= usr.bin/dtc .endif DIRDEPS+= ${DIRDEPS.${MACHINE}:U} .include Index: head/targets/pseudo/userland/lib/Makefile.depend =================================================================== --- head/targets/pseudo/userland/lib/Makefile.depend (revision 349351) +++ head/targets/pseudo/userland/lib/Makefile.depend (revision 349352) @@ -1,261 +1,257 @@ # $FreeBSD$ # This file is not autogenerated - take care! .include DIRDEPS = \ lib/${CSU_DIR} \ lib/atf/libatf-c \ lib/atf/libatf-c++ \ lib/geom/cache \ lib/geom/concat \ lib/geom/eli \ lib/geom/journal \ lib/geom/label \ lib/geom/mirror \ lib/geom/mountver \ lib/geom/multipath \ lib/geom/nop \ lib/geom/part \ lib/geom/raid \ lib/geom/raid3 \ lib/geom/sched \ lib/geom/shsec \ lib/geom/stripe \ lib/geom/virstor \ lib/lib80211 \ lib/libalias/libalias \ lib/libalias/modules/cuseeme \ lib/libalias/modules/dummy \ lib/libalias/modules/ftp \ lib/libalias/modules/irc \ lib/libalias/modules/nbt \ lib/libalias/modules/pptp \ lib/libalias/modules/skinny \ lib/libalias/modules/smedia \ lib/libarchive \ lib/libauditd \ lib/libbegemot \ lib/libblocksruntime \ lib/libbluetooth \ lib/libbsdstat \ lib/libbsm \ lib/libbsnmp/libbsnmp \ lib/libbz2 \ lib/libc \ lib/libc_nonshared \ lib/libc++ \ lib/libc++experimental \ lib/libcalendar \ lib/libcam \ lib/libcapsicum \ lib/libcom_err/doc \ lib/libcompat \ lib/libcompiler_rt \ lib/libcrypt \ lib/libcuse \ lib/libcxxrt \ lib/libdevctl \ lib/libdevdctl \ lib/libdevinfo \ lib/libdevstat \ lib/libdl \ lib/libdwarf \ lib/libedit/edit/readline \ lib/libelf \ lib/libelftc \ lib/libevent \ lib/libexecinfo \ lib/libexpat \ lib/libfetch \ lib/libfigpar \ lib/libgeom \ lib/libgssapi \ lib/libiconv_modules/BIG5 \ lib/libiconv_modules/DECHanyu \ lib/libiconv_modules/EUC \ lib/libiconv_modules/EUCTW \ lib/libiconv_modules/GBK2K \ lib/libiconv_modules/HZ \ lib/libiconv_modules/ISO2022 \ lib/libiconv_modules/JOHAB \ lib/libiconv_modules/MSKanji \ lib/libiconv_modules/UES \ lib/libiconv_modules/UTF1632 \ lib/libiconv_modules/UTF7 \ lib/libiconv_modules/UTF8 \ lib/libiconv_modules/VIQR \ lib/libiconv_modules/ZW \ lib/libiconv_modules/iconv_none \ lib/libiconv_modules/iconv_std \ lib/libiconv_modules/mapper_646 \ lib/libiconv_modules/mapper_none \ lib/libiconv_modules/mapper_parallel \ lib/libiconv_modules/mapper_serial \ lib/libiconv_modules/mapper_std \ lib/libiconv_modules/mapper_zone \ lib/libifconfig \ lib/libipsec \ lib/libipx \ lib/libjail \ lib/libkiconv \ lib/libkvm \ lib/libldns \ lib/liblzma \ lib/libmagic \ lib/libmandoc \ lib/libmd \ lib/libmemstat \ lib/libmilter \ lib/libmp \ lib/libnetgraph \ lib/libngatm \ lib/libnv \ lib/libopie \ lib/libpam/libpam \ lib/libpam/modules/pam_chroot \ lib/libpam/modules/pam_deny \ lib/libpam/modules/pam_echo \ lib/libpam/modules/pam_exec \ lib/libpam/modules/pam_ftpusers \ lib/libpam/modules/pam_group \ lib/libpam/modules/pam_guest \ lib/libpam/modules/pam_krb5 \ lib/libpam/modules/pam_ksu \ lib/libpam/modules/pam_lastlog \ lib/libpam/modules/pam_login_access \ lib/libpam/modules/pam_nologin \ lib/libpam/modules/pam_opie \ lib/libpam/modules/pam_opieaccess \ lib/libpam/modules/pam_passwdqc \ lib/libpam/modules/pam_permit \ lib/libpam/modules/pam_radius \ lib/libpam/modules/pam_rhosts \ lib/libpam/modules/pam_rootok \ lib/libpam/modules/pam_securetty \ lib/libpam/modules/pam_self \ lib/libpam/modules/pam_ssh \ lib/libpam/modules/pam_tacplus \ lib/libpam/modules/pam_unix \ lib/libpam/static_libpam \ lib/libpathconv \ lib/libpcap \ lib/libpe \ lib/libpjdlog \ lib/libproc \ lib/libprocstat \ lib/libradius \ lib/librpcsec_gss \ lib/librpcsvc \ lib/librss \ lib/librt \ lib/librtld_db \ lib/libsa \ lib/libsbuf \ lib/libsdp \ lib/libsm \ lib/libsmb \ lib/libsmdb \ lib/libsmutil \ lib/libsqlite3 \ lib/libstdbuf \ lib/libstdthreads \ lib/libsysdecode \ lib/libtacplus \ lib/libtelnet \ lib/libthr \ lib/libthread_db \ lib/libucl \ lib/libufs \ lib/libugidfw \ lib/libulog \ lib/libunbound \ lib/libusb \ lib/libusbhid \ lib/libutil \ lib/libvgl \ lib/libvmmapi \ lib/libwrap \ lib/liby \ lib/libyaml \ lib/libypclnt \ lib/libz \ lib/libzstd \ lib/msun \ lib/ncurses/form \ lib/ncurses/formw \ lib/ncurses/menu \ lib/ncurses/menuw \ lib/ncurses/ncurses \ lib/ncurses/ncursesw \ lib/ncurses/panel \ lib/ncurses/panelw \ .if ${MK_CLANG} != "no" && \ (${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "arm" || ${MACHINE_CPUARCH} == "i386") DIRDEPS+= \ lib/libclang_rt/asan-preinit \ lib/libclang_rt/asan \ lib/libclang_rt/asan_dynamic \ lib/libclang_rt/asan_cxx \ lib/libclang_rt/include \ lib/libclang_rt/profile \ lib/libclang_rt/safestack \ lib/libclang_rt/stats \ lib/libclang_rt/stats_client \ lib/libclang_rt/ubsan_standalone \ lib/libclang_rt/ubsan_standalone_cxx \ .endif .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || \ ${MACHINE_CPUARCH} == "powerpc" DIRDEPS+= stand/libsa32 .endif -.if ${MK_NAND} != "no" -DIRDEPS+= lib/libnandfs -.endif - .if ${MK_CASPER} != "no" DIRDEPS+= \ lib/libcasper/libcasper \ lib/libcasper/services/cap_dns \ lib/libcasper/services/cap_grp \ lib/libcasper/services/cap_pwd \ lib/libcasper/services/cap_random \ lib/libcasper/services/cap_sysctl \ .endif .if ${MK_DIALOG} != "no" DIRDEPS+= lib/libdpv .endif .if ${MK_GPIO} != "no" DIRDEPS+= lib/libgpio .endif .if ${MK_EFI} != "no" DIRDEPS+= lib/libefivar .endif .if ${MK_LLVM_LIBUNWIND} != "no" DIRDEPS+= \ lib/libgcc_eh \ lib/libgcc_s .endif .if ${MK_PMC} != "no" DIRDEPS+= \ lib/libpmc \ lib/libpmcstat .endif .if ${MK_BLACKLIST_SUPPORT} != "no" DIRDEPS+= lib/libblacklist .endif .include Index: head/usr.bin/vtfontcvt/vtfontcvt.c =================================================================== --- head/usr.bin/vtfontcvt/vtfontcvt.c (revision 349351) +++ head/usr.bin/vtfontcvt/vtfontcvt.c (revision 349352) @@ -1,763 +1,760 @@ /*- * Copyright (c) 2009, 2014 The FreeBSD Foundation * All rights reserved. * * This software was developed by Ed Schouten under sponsorship from the * FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #define VFNT_MAPS 4 #define VFNT_MAP_NORMAL 0 #define VFNT_MAP_NORMAL_RH 1 #define VFNT_MAP_BOLD 2 #define VFNT_MAP_BOLD_RH 3 #define VFNT_MAXGLYPHS 131072 #define VFNT_MAXDIMENSION 128 static unsigned int width = 8, wbytes, height = 16; struct glyph { TAILQ_ENTRY(glyph) g_list; SLIST_ENTRY(glyph) g_hash; uint8_t *g_data; unsigned int g_index; }; #define FONTCVT_NHASH 4096 TAILQ_HEAD(glyph_list, glyph); static SLIST_HEAD(, glyph) glyph_hash[FONTCVT_NHASH]; static struct glyph_list glyphs[VFNT_MAPS] = { TAILQ_HEAD_INITIALIZER(glyphs[0]), TAILQ_HEAD_INITIALIZER(glyphs[1]), TAILQ_HEAD_INITIALIZER(glyphs[2]), TAILQ_HEAD_INITIALIZER(glyphs[3]), }; static unsigned int glyph_total, glyph_count[4], glyph_unique, glyph_dupe; struct mapping { TAILQ_ENTRY(mapping) m_list; unsigned int m_char; unsigned int m_length; struct glyph *m_glyph; }; TAILQ_HEAD(mapping_list, mapping); static struct mapping_list maps[VFNT_MAPS] = { TAILQ_HEAD_INITIALIZER(maps[0]), TAILQ_HEAD_INITIALIZER(maps[1]), TAILQ_HEAD_INITIALIZER(maps[2]), TAILQ_HEAD_INITIALIZER(maps[3]), }; static unsigned int mapping_total, map_count[4], map_folded_count[4], mapping_unique, mapping_dupe; static void usage(void) { (void)fprintf(stderr, "usage: vtfontcvt [-w width] [-h height] [-v] normal.bdf [bold.bdf] out.fnt\n"); exit(1); } static void * xmalloc(size_t size) { void *m; if ((m = calloc(1, size)) == NULL) errx(1, "memory allocation failure"); return (m); } static int add_mapping(struct glyph *gl, unsigned int c, unsigned int map_idx) { struct mapping *mp, *mp_temp; struct mapping_list *ml; mapping_total++; mp = xmalloc(sizeof *mp); mp->m_char = c; mp->m_glyph = gl; mp->m_length = 0; ml = &maps[map_idx]; if (TAILQ_LAST(ml, mapping_list) == NULL || TAILQ_LAST(ml, mapping_list)->m_char < c) { /* Common case: empty list or new char at end of list. */ TAILQ_INSERT_TAIL(ml, mp, m_list); } else { /* Find insertion point for char; cannot be at end. */ TAILQ_FOREACH(mp_temp, ml, m_list) { if (mp_temp->m_char >= c) { TAILQ_INSERT_BEFORE(mp_temp, mp, m_list); break; } } } map_count[map_idx]++; mapping_unique++; return (0); } static int dedup_mapping(unsigned int map_idx) { struct mapping *mp_bold, *mp_normal, *mp_temp; unsigned normal_map_idx = map_idx - VFNT_MAP_BOLD; assert(map_idx == VFNT_MAP_BOLD || map_idx == VFNT_MAP_BOLD_RH); mp_normal = TAILQ_FIRST(&maps[normal_map_idx]); TAILQ_FOREACH_SAFE(mp_bold, &maps[map_idx], m_list, mp_temp) { while (mp_normal->m_char < mp_bold->m_char) mp_normal = TAILQ_NEXT(mp_normal, m_list); if (mp_bold->m_char != mp_normal->m_char) errx(1, "Character %u not in normal font!", mp_bold->m_char); if (mp_bold->m_glyph != mp_normal->m_glyph) continue; /* No mapping is needed if it's equal to the normal mapping. */ TAILQ_REMOVE(&maps[map_idx], mp_bold, m_list); free(mp_bold); mapping_dupe++; } return (0); } static struct glyph * add_glyph(const uint8_t *bytes, unsigned int map_idx, int fallback) { struct glyph *gl; int hash; glyph_total++; glyph_count[map_idx]++; /* Return existing glyph if we have an identical one. */ hash = fnv_32_buf(bytes, wbytes * height, FNV1_32_INIT) % FONTCVT_NHASH; SLIST_FOREACH(gl, &glyph_hash[hash], g_hash) { if (memcmp(gl->g_data, bytes, wbytes * height) == 0) { glyph_dupe++; return (gl); } } /* Allocate new glyph. */ gl = xmalloc(sizeof *gl); gl->g_data = xmalloc(wbytes * height); memcpy(gl->g_data, bytes, wbytes * height); if (fallback) TAILQ_INSERT_HEAD(&glyphs[map_idx], gl, g_list); else TAILQ_INSERT_TAIL(&glyphs[map_idx], gl, g_list); SLIST_INSERT_HEAD(&glyph_hash[hash], gl, g_hash); glyph_unique++; if (glyph_unique > VFNT_MAXGLYPHS) errx(1, "too many glyphs (%u)", glyph_unique); return (gl); } static int add_char(unsigned curchar, unsigned map_idx, uint8_t *bytes, uint8_t *bytes_r) { struct glyph *gl; /* Prevent adding two glyphs for 0xFFFD */ if (curchar == 0xFFFD) { if (map_idx < VFNT_MAP_BOLD) gl = add_glyph(bytes, 0, 1); } else if (curchar >= 0x20) { gl = add_glyph(bytes, map_idx, 0); if (add_mapping(gl, curchar, map_idx) != 0) return (1); if (bytes_r != NULL) { gl = add_glyph(bytes_r, map_idx + 1, 0); if (add_mapping(gl, curchar, map_idx + 1) != 0) return (1); } } return (0); } /* * Right-shift glyph row by _shift_ bits. Row _len_ bits wide, _size_ bytes. */ static int rshift_row(uint8_t *line, size_t size, size_t len, size_t shift) { size_t d, s, i; uint16_t t; assert(size > 0 && len > 0); assert(size * 8 >= len); if (shift == 0) return (0); d = shift / 8; s = 8 - shift % 8; i = howmany(len, 8); while (i > 0) { i--; t = *(line + i); *(line + i) = 0; t <<= s; if (i + d + 1 < size) *(line + i + d + 1) |= (uint8_t)t; if (i + d < size) *(line + i + d) = t >> 8; } return (0); } /* * Split double-width characters into left and right half. Single-width * characters in _left_ only. */ static int split_row(uint8_t *left, uint8_t *right, uint8_t *line, size_t w) { size_t s, i; s = wbytes * 8 - width; memcpy(left, line, wbytes); *(left + wbytes - 1) &= 0xFF << s; if (w > width) { /* Double-width character. */ uint8_t t; for (i = 0; i < wbytes; i++) { t = *(line + wbytes + i - 1); t <<= 8 - s; t |= *(line + wbytes + i) >> s; *(right + i) = t; } *(right + wbytes - 1) &= 0xFF << s; } return (0); } static void set_height(int h) { if (h <= 0 || h > VFNT_MAXDIMENSION) errx(1, "invalid height %d", h); height = h; } static void set_width(int w) { if (w <= 0 || w > VFNT_MAXDIMENSION) errx(1, "invalid width %d", w); width = w; wbytes = howmany(width, 8); } static int parse_bdf(FILE *fp, unsigned int map_idx) { char *line, *ln, *p; size_t length; uint8_t *bytes, *bytes_r; unsigned int curchar = 0, i, j, linenum = 0, bbwbytes; int bbw, bbh, bbox, bboy; /* Glyph bounding box. */ int fbbw = 0, fbbh, fbbox, fbboy; /* Font bounding box. */ int dwidth = 0, dwy = 0; int rv = -1; char spc = '\0'; /* * Step 1: Parse FONT logical font descriptor and FONTBOUNDINGBOX * bounding box. */ while ((ln = fgetln(fp, &length)) != NULL) { linenum++; ln[length - 1] = '\0'; if (strncmp(ln, "FONT ", 5) == 0) { p = ln + 5; i = 0; while ((p = strchr(p, '-')) != NULL) { p++; i++; if (i == 11) { spc = *p; break; } } - } else if (strncmp(ln, "FONTBOUNDINGBOX ", 16) == 0) { - if (sscanf(ln + 16, "%d %d %d %d", &fbbw, &fbbh, &fbbox, - &fbboy) != 4) - errx(1, "invalid FONTBOUNDINGBOX at line %u", - linenum); + } else if (strncmp(ln, "FONTBOUNDINGBOX ", 16) == 0 && + sscanf(ln + 16, "%d %d %d %d", &fbbw, &fbbh, &fbbox, + &fbboy) == 4) { set_width(fbbw); set_height(fbbh); break; } } if (fbbw == 0) errx(1, "broken font header"); if (spc != 'c' && spc != 'C') errx(1, "font spacing \"C\" (character cell) required"); /* Step 2: Validate DWIDTH (Device Width) of all glyphs. */ while ((ln = fgetln(fp, &length)) != NULL) { linenum++; ln[length - 1] = '\0'; - if (strncmp(ln, "DWIDTH ", 7) == 0) { - if (sscanf(ln + 7, "%d %d", &dwidth, &dwy) != 2) - errx(1, "invalid DWIDTH at line %u", linenum); + if (strncmp(ln, "DWIDTH ", 7) == 0 && + sscanf(ln + 7, "%d %d", &dwidth, &dwy) == 2) { if (dwy != 0 || (dwidth != fbbw && dwidth * 2 != fbbw)) errx(1, "bitmap with unsupported DWIDTH %d %d at line %u", dwidth, dwy, linenum); if (dwidth < fbbw) set_width(dwidth); } } /* Step 3: Restart at the beginning of the file and read glyph data. */ dwidth = bbw = bbh = 0; rewind(fp); linenum = 0; bbwbytes = 0; /* GCC 4.2.1 "may be used uninitialized" workaround. */ bytes = xmalloc(wbytes * height); bytes_r = xmalloc(wbytes * height); line = xmalloc(wbytes * 2); while ((ln = fgetln(fp, &length)) != NULL) { linenum++; ln[length - 1] = '\0'; if (strncmp(ln, "ENCODING ", 9) == 0) { curchar = atoi(ln + 9); } else if (strncmp(ln, "DWIDTH ", 7) == 0) { dwidth = atoi(ln + 7); } else if (strncmp(ln, "BBX ", 4) == 0) { if (sscanf(ln + 4, "%d %d %d %d", &bbw, &bbh, &bbox, &bboy) != 4) errx(1, "invalid BBX at line %u", linenum); if (bbw < 1 || bbh < 1 || bbw > fbbw || bbh > fbbh || bbox < fbbox || bboy < fbboy || bbh + bboy > fbbh + fbboy) errx(1, "broken bitmap with BBX %d %d %d %d at line %u", bbw, bbh, bbox, bboy, linenum); bbwbytes = howmany(bbw, 8); } else if (strncmp(ln, "BITMAP", 6) == 0 && (ln[6] == ' ' || ln[6] == '\0')) { if (dwidth == 0 || bbw == 0 || bbh == 0) errx(1, "broken char header at line %u!", linenum); memset(bytes, 0, wbytes * height); memset(bytes_r, 0, wbytes * height); /* * Assume that the next _bbh_ lines are bitmap data. * ENDCHAR is allowed to terminate the bitmap * early but is not otherwise checked; any extra data * is ignored. */ for (i = (fbbh + fbboy) - (bbh + bboy); i < (unsigned int)((fbbh + fbboy) - bboy); i++) { if ((ln = fgetln(fp, &length)) == NULL) errx(1, "unexpected EOF"); linenum++; ln[length - 1] = '\0'; if (strcmp(ln, "ENDCHAR") == 0) break; if (strlen(ln) < bbwbytes * 2) errx(1, "broken bitmap at line %u", linenum); memset(line, 0, wbytes * 2); for (j = 0; j < bbwbytes; j++) { unsigned int val; if (sscanf(ln + j * 2, "%2x", &val) == 0) break; *(line + j) = (uint8_t)val; } rv = rshift_row(line, wbytes * 2, bbw, bbox - fbbox); if (rv != 0) goto out; rv = split_row(bytes + i * wbytes, bytes_r + i * wbytes, line, dwidth); if (rv != 0) goto out; } rv = add_char(curchar, map_idx, bytes, dwidth > (int)width ? bytes_r : NULL); if (rv != 0) goto out; dwidth = bbw = bbh = 0; } } out: free(bytes); free(bytes_r); free(line); return (rv); } static int parse_hex(FILE *fp, unsigned int map_idx) { char *ln, *p; size_t length; uint8_t *bytes = NULL, *bytes_r = NULL, *line = NULL; unsigned curchar = 0, gwidth, gwbytes, i, j, chars_per_row; int rv = 0; while ((ln = fgetln(fp, &length)) != NULL) { ln[length - 1] = '\0'; if (strncmp(ln, "# Height: ", 10) == 0) { if (bytes != NULL) errx(1, "malformed input: Height tag after font data"); set_height(atoi(ln + 10)); } else if (strncmp(ln, "# Width: ", 9) == 0) { if (bytes != NULL) errx(1, "malformed input: Width tag after font data"); set_width(atoi(ln + 9)); } else if (sscanf(ln, "%6x:", &curchar)) { if (bytes == NULL) { bytes = xmalloc(wbytes * height); bytes_r = xmalloc(wbytes * height); line = xmalloc(wbytes * 2); } /* ln is guaranteed to have a colon here. */ p = strchr(ln, ':') + 1; chars_per_row = strlen(p) / height; if (chars_per_row < wbytes * 2) errx(1, "malformed input: broken bitmap, character %06x", curchar); gwidth = width * 2; gwbytes = howmany(gwidth, 8); if (chars_per_row < gwbytes * 2 || gwidth <= 8) { gwidth = width; /* Single-width character. */ gwbytes = wbytes; } for (i = 0; i < height; i++) { for (j = 0; j < gwbytes; j++) { unsigned int val; if (sscanf(p + j * 2, "%2x", &val) == 0) break; *(line + j) = (uint8_t)val; } rv = split_row(bytes + i * wbytes, bytes_r + i * wbytes, line, gwidth); if (rv != 0) goto out; p += gwbytes * 2; } rv = add_char(curchar, map_idx, bytes, gwidth != width ? bytes_r : NULL); if (rv != 0) goto out; } } out: free(bytes); free(bytes_r); free(line); return (rv); } static int parse_file(const char *filename, unsigned int map_idx) { FILE *fp; size_t len; int rv; fp = fopen(filename, "r"); if (fp == NULL) { perror(filename); return (1); } len = strlen(filename); if (len > 4 && strcasecmp(filename + len - 4, ".hex") == 0) rv = parse_hex(fp, map_idx); else rv = parse_bdf(fp, map_idx); fclose(fp); return (rv); } static void number_glyphs(void) { struct glyph *gl; unsigned int i, idx = 0; for (i = 0; i < VFNT_MAPS; i++) TAILQ_FOREACH(gl, &glyphs[i], g_list) gl->g_index = idx++; } static int write_glyphs(FILE *fp) { struct glyph *gl; unsigned int i; for (i = 0; i < VFNT_MAPS; i++) { TAILQ_FOREACH(gl, &glyphs[i], g_list) if (fwrite(gl->g_data, wbytes * height, 1, fp) != 1) return (1); } return (0); } static void fold_mappings(unsigned int map_idx) { struct mapping_list *ml = &maps[map_idx]; struct mapping *mn, *mp, *mbase; mp = mbase = TAILQ_FIRST(ml); for (mp = mbase = TAILQ_FIRST(ml); mp != NULL; mp = mn) { mn = TAILQ_NEXT(mp, m_list); if (mn != NULL && mn->m_char == mp->m_char + 1 && mn->m_glyph->g_index == mp->m_glyph->g_index + 1) continue; mbase->m_length = mp->m_char - mbase->m_char + 1; mbase = mp = mn; map_folded_count[map_idx]++; } } struct file_mapping { uint32_t source; uint16_t destination; uint16_t length; } __packed; static int write_mappings(FILE *fp, unsigned int map_idx) { struct mapping_list *ml = &maps[map_idx]; struct mapping *mp; struct file_mapping fm; unsigned int i = 0, j = 0; TAILQ_FOREACH(mp, ml, m_list) { j++; if (mp->m_length > 0) { i += mp->m_length; fm.source = htobe32(mp->m_char); fm.destination = htobe16(mp->m_glyph->g_index); fm.length = htobe16(mp->m_length - 1); if (fwrite(&fm, sizeof fm, 1, fp) != 1) return (1); } } assert(i == j); return (0); } struct file_header { uint8_t magic[8]; uint8_t width; uint8_t height; uint16_t pad; uint32_t glyph_count; uint32_t map_count[4]; } __packed; static int write_fnt(const char *filename) { FILE *fp; struct file_header fh = { .magic = "VFNT0002", }; fp = fopen(filename, "wb"); if (fp == NULL) { perror(filename); return (1); } fh.width = width; fh.height = height; fh.glyph_count = htobe32(glyph_unique); fh.map_count[0] = htobe32(map_folded_count[0]); fh.map_count[1] = htobe32(map_folded_count[1]); fh.map_count[2] = htobe32(map_folded_count[2]); fh.map_count[3] = htobe32(map_folded_count[3]); if (fwrite(&fh, sizeof fh, 1, fp) != 1) { perror(filename); fclose(fp); return (1); } if (write_glyphs(fp) != 0 || write_mappings(fp, VFNT_MAP_NORMAL) != 0 || write_mappings(fp, VFNT_MAP_NORMAL_RH) != 0 || write_mappings(fp, VFNT_MAP_BOLD) != 0 || write_mappings(fp, VFNT_MAP_BOLD_RH) != 0) { perror(filename); fclose(fp); return (1); } fclose(fp); return (0); } static void print_font_info(void) { printf( "Statistics:\n" "- width: %6u\n" "- height: %6u\n" "- glyph_total: %6u\n" "- glyph_normal: %6u\n" "- glyph_normal_right: %6u\n" "- glyph_bold: %6u\n" "- glyph_bold_right: %6u\n" "- glyph_unique: %6u\n" "- glyph_dupe: %6u\n" "- mapping_total: %6u\n" "- mapping_normal: %6u\n" "- mapping_normal_folded: %6u\n" "- mapping_normal_right: %6u\n" "- mapping_normal_right_folded: %6u\n" "- mapping_bold: %6u\n" "- mapping_bold_folded: %6u\n" "- mapping_bold_right: %6u\n" "- mapping_bold_right_folded: %6u\n" "- mapping_unique: %6u\n" "- mapping_dupe: %6u\n", width, height, glyph_total, glyph_count[0], glyph_count[1], glyph_count[2], glyph_count[3], glyph_unique, glyph_dupe, mapping_total, map_count[0], map_folded_count[0], map_count[1], map_folded_count[1], map_count[2], map_folded_count[2], map_count[3], map_folded_count[3], mapping_unique, mapping_dupe); } int main(int argc, char *argv[]) { int ch, verbose = 0; assert(sizeof(struct file_header) == 32); assert(sizeof(struct file_mapping) == 8); while ((ch = getopt(argc, argv, "h:vw:")) != -1) { switch (ch) { case 'h': height = atoi(optarg); break; case 'v': verbose = 1; break; case 'w': width = atoi(optarg); break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < 2 || argc > 3) usage(); set_width(width); set_height(height); if (parse_file(argv[0], VFNT_MAP_NORMAL) != 0) return (1); argc--; argv++; if (argc == 2) { if (parse_file(argv[0], VFNT_MAP_BOLD) != 0) return (1); argc--; argv++; } number_glyphs(); dedup_mapping(VFNT_MAP_BOLD); dedup_mapping(VFNT_MAP_BOLD_RH); fold_mappings(0); fold_mappings(1); fold_mappings(2); fold_mappings(3); if (write_fnt(argv[0]) != 0) return (1); if (verbose) print_font_info(); return (0); } Index: head/usr.sbin/Makefile =================================================================== --- head/usr.sbin/Makefile (revision 349351) +++ head/usr.sbin/Makefile (revision 349352) @@ -1,225 +1,223 @@ # From: @(#)Makefile 5.20 (Berkeley) 6/12/93 # $FreeBSD$ .include SUBDIR= adduser \ arp \ binmiscctl \ camdd \ cdcontrol \ chkgrp \ chown \ chroot \ ckdist \ clear_locks \ crashinfo \ cron \ ctladm \ ctld \ daemon \ dconschat \ devctl \ devinfo \ diskinfo \ dumpcis \ etcupdate \ extattr \ extattrctl \ fifolog \ fstyp \ fwcontrol \ getfmac \ getpmac \ gstat \ i2c \ ifmcstat \ iostat \ iovctl \ kldxref \ mailwrapper \ makefs \ memcontrol \ mergemaster \ mfiutil \ mixer \ mlxcontrol \ mountd \ mount_smbfs \ mpsutil \ mptutil \ mtest \ newsyslog \ nfscbd \ nfsd \ nfsdumpstate \ nfsrevoke \ nfsuserd \ nmtree \ nologin \ pciconf \ periodic \ pnfsdscopymr \ pnfsdsfile \ pnfsdskill \ powerd \ prometheus_sysctl_exporter \ pstat \ pw \ pwd_mkdb \ pwm \ quot \ rarpd \ rmt \ rpcbind \ rpc.lockd \ rpc.statd \ rpc.umntall \ rtprio \ rwhod \ service \ services_mkdb \ sesutil \ setfib \ setfmac \ setpmac \ smbmsg \ snapinfo \ spi \ spray \ syslogd \ sysrc \ tcpdrop \ tcpdump \ traceroute \ trim \ trpt \ tzsetup \ ugidfw \ vigr \ vipw \ wake \ watch \ watchdogd \ zic \ zonectl # NB: keep these sorted by MK_* knobs SUBDIR.${MK_ACCT}+= accton SUBDIR.${MK_ACCT}+= sa SUBDIR.${MK_AMD}+= amd SUBDIR.${MK_AUDIT}+= audit SUBDIR.${MK_AUDIT}+= auditd .if ${MK_OPENSSL} != "no" SUBDIR.${MK_AUDIT}+= auditdistd .endif SUBDIR.${MK_AUDIT}+= auditreduce SUBDIR.${MK_AUDIT}+= praudit SUBDIR.${MK_AUTHPF}+= authpf SUBDIR.${MK_AUTOFS}+= autofs SUBDIR.${MK_BLACKLIST}+= blacklistctl SUBDIR.${MK_BLACKLIST}+= blacklistd SUBDIR.${MK_BLUETOOTH}+= bluetooth SUBDIR.${MK_BOOTPARAMD}+= bootparamd SUBDIR.${MK_BSDINSTALL}+= bsdinstall SUBDIR.${MK_BSNMP}+= bsnmpd SUBDIR.${MK_CXGBETOOL}+= cxgbetool SUBDIR.${MK_DIALOG}+= bsdconfig SUBDIR.${MK_EFI}+= efivar efidp efibootmgr .if ${MK_OPENSSL} != "no" SUBDIR.${MK_EFI}+= uefisign .endif SUBDIR.${MK_FLOPPY}+= fdcontrol SUBDIR.${MK_FLOPPY}+= fdformat SUBDIR.${MK_FLOPPY}+= fdread SUBDIR.${MK_FLOPPY}+= fdwrite SUBDIR.${MK_FMTREE}+= fmtree SUBDIR.${MK_FREEBSD_UPDATE}+= freebsd-update SUBDIR.${MK_GSSAPI}+= gssd SUBDIR.${MK_GPIO}+= gpioctl SUBDIR.${MK_INET6}+= ip6addrctl SUBDIR.${MK_INET6}+= mld6query SUBDIR.${MK_INET6}+= ndp SUBDIR.${MK_INET6}+= rip6query SUBDIR.${MK_INET6}+= route6d SUBDIR.${MK_INET6}+= rrenumd SUBDIR.${MK_INET6}+= rtadvctl SUBDIR.${MK_INET6}+= rtadvd SUBDIR.${MK_INET6}+= rtsold SUBDIR.${MK_INET6}+= traceroute6 SUBDIR.${MK_INETD}+= inetd SUBDIR.${MK_IPFW}+= ipfwpcap SUBDIR.${MK_ISCSI}+= iscsid SUBDIR.${MK_JAIL}+= jail SUBDIR.${MK_JAIL}+= jexec SUBDIR.${MK_JAIL}+= jls # XXX MK_SYSCONS SUBDIR.${MK_LEGACY_CONSOLE}+= kbdcontrol SUBDIR.${MK_LEGACY_CONSOLE}+= kbdmap SUBDIR.${MK_LEGACY_CONSOLE}+= moused SUBDIR.${MK_LEGACY_CONSOLE}+= vidcontrol .if ${MK_LIBTHR} != "no" || ${MK_LIBPTHREAD} != "no" SUBDIR.${MK_PPP}+= pppctl SUBDIR.${MK_NS_CACHING}+= nscd .endif SUBDIR.${MK_LPR}+= lpr SUBDIR.${MK_MAN_UTILS}+= manctl SUBDIR.${MK_MLX5TOOL}+= mlx5tool -SUBDIR.${MK_NAND}+= nandsim -SUBDIR.${MK_NAND}+= nandtool SUBDIR.${MK_NETGRAPH}+= flowctl SUBDIR.${MK_NETGRAPH}+= ngctl SUBDIR.${MK_NETGRAPH}+= nghook SUBDIR.${MK_NIS}+= rpc.yppasswdd SUBDIR.${MK_NIS}+= rpc.ypupdated SUBDIR.${MK_NIS}+= rpc.ypxfrd SUBDIR.${MK_NIS}+= ypbind SUBDIR.${MK_NIS}+= ypldap SUBDIR.${MK_NIS}+= yp_mkdb SUBDIR.${MK_NIS}+= yppoll SUBDIR.${MK_NIS}+= yppush SUBDIR.${MK_NIS}+= ypserv SUBDIR.${MK_NIS}+= ypset SUBDIR.${MK_NTP}+= ntp SUBDIR.${MK_OPENSSL}+= keyserv SUBDIR.${MK_PC_SYSINSTALL}+= pc-sysinstall SUBDIR.${MK_PF}+= ftp-proxy SUBDIR.${MK_PKGBOOTSTRAP}+= pkg .if ${COMPILER_FEATURES:Mc++11} SUBDIR.${MK_PMC}+= pmc .endif SUBDIR.${MK_PMC}+= pmcannotate pmccontrol pmcstat pmcstudy SUBDIR.${MK_PORTSNAP}+= portsnap SUBDIR.${MK_PPP}+= ppp SUBDIR.${MK_QUOTAS}+= edquota SUBDIR.${MK_QUOTAS}+= quotaon SUBDIR.${MK_QUOTAS}+= repquota SUBDIR.${MK_SENDMAIL}+= editmap SUBDIR.${MK_SENDMAIL}+= mailstats SUBDIR.${MK_SENDMAIL}+= makemap SUBDIR.${MK_SENDMAIL}+= praliases SUBDIR.${MK_SENDMAIL}+= sendmail SUBDIR.${MK_TCP_WRAPPERS}+= tcpdchk SUBDIR.${MK_TCP_WRAPPERS}+= tcpdmatch SUBDIR.${MK_TOOLCHAIN}+= config SUBDIR.${MK_TOOLCHAIN}+= crunch SUBDIR.${MK_UNBOUND}+= unbound SUBDIR.${MK_USB}+= uathload SUBDIR.${MK_USB}+= uhsoctl SUBDIR.${MK_USB}+= usbconfig SUBDIR.${MK_USB}+= usbdump SUBDIR.${MK_UTMPX}+= ac SUBDIR.${MK_UTMPX}+= lastlogin SUBDIR.${MK_UTMPX}+= utx SUBDIR.${MK_WIRELESS}+= ancontrol SUBDIR.${MK_WIRELESS}+= wlandebug SUBDIR.${MK_WIRELESS}+= wpa SUBDIR.${MK_TESTS}+= tests .include SUBDIR_PARALLEL= .include Index: head/usr.sbin/bhyve/hda_codec.c =================================================================== --- head/usr.sbin/bhyve/hda_codec.c (revision 349351) +++ head/usr.sbin/bhyve/hda_codec.c (nonexistent) @@ -1,950 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include "pci_hda.h" -#include "audio.h" - -/* - * HDA Codec defines - */ -#define INTEL_VENDORID 0x8086 - -#define HDA_CODEC_SUBSYSTEM_ID ((INTEL_VENDORID << 16) | 0x01) -#define HDA_CODEC_ROOT_NID 0x00 -#define HDA_CODEC_FG_NID 0x01 -#define HDA_CODEC_AUDIO_OUTPUT_NID 0x02 -#define HDA_CODEC_PIN_OUTPUT_NID 0x03 -#define HDA_CODEC_AUDIO_INPUT_NID 0x04 -#define HDA_CODEC_PIN_INPUT_NID 0x05 - -#define HDA_CODEC_STREAMS_COUNT 0x02 -#define HDA_CODEC_STREAM_OUTPUT 0x00 -#define HDA_CODEC_STREAM_INPUT 0x01 - -#define HDA_CODEC_PARAMS_COUNT 0x14 -#define HDA_CODEC_CONN_LIST_COUNT 0x01 -#define HDA_CODEC_RESPONSE_EX_UNSOL 0x10 -#define HDA_CODEC_RESPONSE_EX_SOL 0x00 -#define HDA_CODEC_AMP_NUMSTEPS 0x4a - -#define HDA_CODEC_SUPP_STREAM_FORMATS_PCM \ - (1 << HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT) - -#define HDA_CODEC_FMT_BASE_MASK (0x01 << 14) - -#define HDA_CODEC_FMT_MULT_MASK (0x07 << 11) -#define HDA_CODEC_FMT_MULT_2 (0x01 << 11) -#define HDA_CODEC_FMT_MULT_3 (0x02 << 11) -#define HDA_CODEC_FMT_MULT_4 (0x03 << 11) - -#define HDA_CODEC_FMT_DIV_MASK 0x07 -#define HDA_CODEC_FMT_DIV_SHIFT 8 - -#define HDA_CODEC_FMT_BITS_MASK (0x07 << 4) -#define HDA_CODEC_FMT_BITS_8 (0x00 << 4) -#define HDA_CODEC_FMT_BITS_16 (0x01 << 4) -#define HDA_CODEC_FMT_BITS_24 (0x03 << 4) -#define HDA_CODEC_FMT_BITS_32 (0x04 << 4) - -#define HDA_CODEC_FMT_CHAN_MASK (0x0f << 0) - -#define HDA_CODEC_AUDIO_WCAP_OUTPUT \ - (0x00 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_INPUT \ - (0x01 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_PIN \ - (0x04 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_CONN_LIST \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_FORMAT_OVR \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_AMP_OVR \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_OUT_AMP \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_IN_AMP \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_STEREO \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT) - -#define HDA_CODEC_PIN_CAP_OUTPUT \ - (1 << HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT) -#define HDA_CODEC_PIN_CAP_INPUT \ - (1 << HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT) -#define HDA_CODEC_PIN_CAP_PRESENCE_DETECT \ - (1 << HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT) - -#define HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP \ - (1 << HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT) -#define HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE \ - (0x03 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) -#define HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS \ - (HDA_CODEC_AMP_NUMSTEPS << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) -#define HDA_CODEC_OUTPUT_AMP_CAP_OFFSET \ - (HDA_CODEC_AMP_NUMSTEPS << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT) - -#define HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE 0x80 -#define HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK 0x7f - -#define HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED (1 << 31) -#define HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE \ - (1 << HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT) -#define HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE \ - (1 << HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT) - -#define HDA_CONFIG_DEFAULTCONF_COLOR_BLACK \ - (0x01 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_COLOR_RED \ - (0x05 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) - -#define HDA_CODEC_BUF_SIZE HDA_FIFO_SIZE - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - - -/* - * HDA Audio Context data structures - */ - -typedef void (*transfer_func_t)(void *arg); -typedef int (*setup_func_t)(void *arg); - -struct hda_audio_ctxt { - char name[64]; - uint8_t run; - uint8_t started; - void *priv; - pthread_t tid; - pthread_mutex_t mtx; - pthread_cond_t cond; - setup_func_t do_setup; - transfer_func_t do_transfer; -}; - -/* - * HDA Audio Context module function declarations - */ - -static void *hda_audio_ctxt_thr(void *arg); -static int hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, - transfer_func_t do_transfer, setup_func_t do_setup, void *priv); -static int hda_audio_ctxt_start(struct hda_audio_ctxt *actx); -static int hda_audio_ctxt_stop(struct hda_audio_ctxt *actx); - -/* - * HDA Codec data structures - */ - -struct hda_codec_softc; - -typedef uint32_t (*verb_func_t)(struct hda_codec_softc *sc, uint16_t verb, - uint16_t payload); - -struct hda_codec_stream { - uint8_t buf[HDA_CODEC_BUF_SIZE]; - uint8_t channel; - uint16_t fmt; - uint8_t stream; - - uint8_t left_gain; - uint8_t right_gain; - uint8_t left_mute; - uint8_t right_mute; - - struct audio *aud; - struct hda_audio_ctxt actx; -}; - -struct hda_codec_softc { - uint32_t no_nodes; - uint32_t subsystem_id; - const uint32_t (*get_parameters)[HDA_CODEC_PARAMS_COUNT]; - const uint8_t (*conn_list)[HDA_CODEC_CONN_LIST_COUNT]; - const uint32_t *conf_default; - const uint8_t *pin_ctrl_default; - const verb_func_t *verb_handlers; - - struct hda_codec_inst *hci; - struct hda_codec_stream streams[HDA_CODEC_STREAMS_COUNT]; -}; - -/* - * HDA Codec module function declarations - */ -static int hda_codec_init(struct hda_codec_inst *hci, const char *play, - const char *rec, const char *opts); -static int hda_codec_reset(struct hda_codec_inst *hci); -static int hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data); -static int hda_codec_notify(struct hda_codec_inst *hci, uint8_t run, - uint8_t stream, uint8_t dir); - -static int hda_codec_parse_format(uint16_t fmt, struct audio_params *params); - -static uint32_t hda_codec_audio_output_nid(struct hda_codec_softc *sc, - uint16_t verb, uint16_t payload); -static void hda_codec_audio_output_do_transfer(void *arg); -static int hda_codec_audio_output_do_setup(void *arg); -static uint32_t hda_codec_audio_input_nid(struct hda_codec_softc *sc, - uint16_t verb, uint16_t payload); -static void hda_codec_audio_input_do_transfer(void *arg); -static int hda_codec_audio_input_do_setup(void *arg); - -static uint32_t hda_codec_audio_inout_nid(struct hda_codec_stream *st, - uint16_t verb, uint16_t payload); - -/* - * HDA Codec global data - */ - -#define HDA_CODEC_ROOT_DESC \ - [HDA_CODEC_ROOT_NID] = { \ - [HDA_PARAM_VENDOR_ID] = INTEL_VENDORID, \ - [HDA_PARAM_REVISION_ID] = 0xffff, \ - /* 1 Subnode, StartNid = 1 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00010001, \ - }, \ - -#define HDA_CODEC_FG_COMMON_DESC \ - [HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO,\ - /* B8 - B32, 8.0 - 192.0kHz */ \ - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, \ - [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM,\ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_GPIO_COUNT] = 0x00, \ - -#define HDA_CODEC_FG_OUTPUT_DESC \ - [HDA_CODEC_FG_NID] = { \ - /* 2 Subnodes, StartNid = 2 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00020002, \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - -#define HDA_CODEC_FG_INPUT_DESC \ - [HDA_CODEC_FG_NID] = { \ - /* 2 Subnodes, StartNid = 4 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00040002, \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - -#define HDA_CODEC_FG_DUPLEX_DESC \ - [HDA_CODEC_FG_NID] = { \ - /* 4 Subnodes, StartNid = 2 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00020004, \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - -#define HDA_CODEC_OUTPUT_DESC \ - [HDA_CODEC_AUDIO_OUTPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_OUTPUT | \ - HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | \ - HDA_CODEC_AUDIO_WCAP_AMP_OVR | \ - HDA_CODEC_AUDIO_WCAP_OUT_AMP | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - /* B16, 16.0 - 192.0kHz */ \ - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, \ - [HDA_PARAM_SUPP_STREAM_FORMATS] = \ - HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, \ - [HDA_PARAM_OUTPUT_AMP_CAP] = \ - HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | \ - HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | \ - HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | \ - HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, \ - }, \ - [HDA_CODEC_PIN_OUTPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_PIN | \ - HDA_CODEC_AUDIO_WCAP_CONN_LIST | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_OUTPUT | \ - HDA_CODEC_PIN_CAP_PRESENCE_DETECT,\ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - }, \ - -#define HDA_CODEC_INPUT_DESC \ - [HDA_CODEC_AUDIO_INPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_INPUT | \ - HDA_CODEC_AUDIO_WCAP_CONN_LIST | \ - HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | \ - HDA_CODEC_AUDIO_WCAP_AMP_OVR | \ - HDA_CODEC_AUDIO_WCAP_IN_AMP | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - /* B16, 16.0 - 192.0kHz */ \ - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, \ - [HDA_PARAM_SUPP_STREAM_FORMATS] = \ - HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, \ - [HDA_PARAM_INPUT_AMP_CAP] = \ - HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | \ - HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | \ - HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | \ - HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, \ - }, \ - [HDA_CODEC_PIN_INPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_PIN | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_INPUT | \ - HDA_CODEC_PIN_CAP_PRESENCE_DETECT, \ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - }, \ - -static const uint32_t -hda_codec_output_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_OUTPUT_DESC - HDA_CODEC_OUTPUT_DESC -}; - -static const uint32_t -hda_codec_input_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_INPUT_DESC - HDA_CODEC_INPUT_DESC -}; - -static const uint32_t -hda_codec_duplex_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_DUPLEX_DESC - HDA_CODEC_OUTPUT_DESC - HDA_CODEC_INPUT_DESC -}; - -#define HDA_CODEC_NODES_COUNT (ARRAY_SIZE(hda_codec_duplex_parameters)) - -static const uint8_t -hda_codec_conn_list[HDA_CODEC_NODES_COUNT][HDA_CODEC_CONN_LIST_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = {HDA_CODEC_AUDIO_OUTPUT_NID}, - [HDA_CODEC_AUDIO_INPUT_NID] = {HDA_CODEC_PIN_INPUT_NID}, -}; - -static const uint32_t -hda_codec_conf_default[HDA_CODEC_NODES_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = \ - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK | - HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT | - HDA_CONFIG_DEFAULTCONF_COLOR_BLACK | - (0x01 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT), - [HDA_CODEC_PIN_INPUT_NID] = HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK | - HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN | - HDA_CONFIG_DEFAULTCONF_COLOR_RED | - (0x02 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT), -}; - -static const uint8_t -hda_codec_pin_ctrl_default[HDA_CODEC_NODES_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE, - [HDA_CODEC_PIN_INPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE, -}; - -static const -verb_func_t hda_codec_verb_handlers[HDA_CODEC_NODES_COUNT] = { - [HDA_CODEC_AUDIO_OUTPUT_NID] = hda_codec_audio_output_nid, - [HDA_CODEC_AUDIO_INPUT_NID] = hda_codec_audio_input_nid, -}; - -/* - * HDA Codec module function definitions - */ - -static int -hda_codec_init(struct hda_codec_inst *hci, const char *play, - const char *rec, const char *opts) -{ - struct hda_codec_softc *sc = NULL; - struct hda_codec_stream *st = NULL; - int err; - - if (!(play || rec)) - return (-1); - - DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts); - - sc = calloc(1, sizeof(*sc)); - if (!sc) - return (-1); - - if (play && rec) - sc->get_parameters = hda_codec_duplex_parameters; - else { - if (play) - sc->get_parameters = hda_codec_output_parameters; - else - sc->get_parameters = hda_codec_input_parameters; - } - sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID; - sc->no_nodes = HDA_CODEC_NODES_COUNT; - sc->conn_list = hda_codec_conn_list; - sc->conf_default = hda_codec_conf_default; - sc->pin_ctrl_default = hda_codec_pin_ctrl_default; - sc->verb_handlers = hda_codec_verb_handlers; - DPRINTF("HDA Codec nodes: %d\n", sc->no_nodes); - - /* - * Initialize the Audio Output stream - */ - if (play) { - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - - err = hda_audio_ctxt_init(&st->actx, "hda-audio-output", - hda_codec_audio_output_do_transfer, - hda_codec_audio_output_do_setup, sc); - assert(!err); - - st->aud = audio_init(play, 1); - if (!st->aud) { - DPRINTF("Fail to init the output audio player\n"); - return (-1); - } - } - - /* - * Initialize the Audio Input stream - */ - if (rec) { - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - - err = hda_audio_ctxt_init(&st->actx, "hda-audio-input", - hda_codec_audio_input_do_transfer, - hda_codec_audio_input_do_setup, sc); - assert(!err); - - st->aud = audio_init(rec, 0); - if (!st->aud) { - DPRINTF("Fail to init the input audio player\n"); - return (-1); - } - } - - sc->hci = hci; - hci->priv = sc; - - return (0); -} - -static int -hda_codec_reset(struct hda_codec_inst *hci) -{ - struct hda_ops *hops = NULL; - struct hda_codec_softc *sc = NULL; - struct hda_codec_stream *st = NULL; - int i; - - assert(hci); - - hops = hci->hops; - assert(hops); - - sc = (struct hda_codec_softc *)hci->priv; - assert(sc); - - for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) { - st = &sc->streams[i]; - st->left_gain = HDA_CODEC_AMP_NUMSTEPS; - st->right_gain = HDA_CODEC_AMP_NUMSTEPS; - st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - } - - DPRINTF("cad: 0x%x\n", hci->cad); - - if (!hops->signal) { - DPRINTF("The controller ops does not implement \ - the signal function\n"); - return (-1); - } - - return (hops->signal(hci)); -} - -static int -hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data) -{ - struct hda_codec_softc *sc = NULL; - struct hda_ops *hops = NULL; - uint8_t cad = 0, nid = 0; - uint16_t verb = 0, payload = 0; - uint32_t res = 0; - - /* 4 bits */ - cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f; - /* 8 bits */ - nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff; - - if ((cmd_data & 0x70000) == 0x70000) { - /* 12 bits */ - verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff; - /* 8 bits */ - payload = cmd_data & 0xff; - } else { - /* 4 bits */ - verb = (cmd_data >> HDA_CMD_VERB_4BIT_SHIFT) & 0x0f; - /* 16 bits */ - payload = cmd_data & 0xffff; - } - - assert(cad == hci->cad); - assert(hci); - - hops = hci->hops; - assert(hops); - - sc = (struct hda_codec_softc *)hci->priv; - assert(sc); - - assert(nid < sc->no_nodes); - - if (!hops->response) { - DPRINTF("The controller ops does not implement \ - the response function\n"); - return (-1); - } - - switch (verb) { - case HDA_CMD_VERB_GET_PARAMETER: - res = sc->get_parameters[nid][payload]; - break; - case HDA_CMD_VERB_GET_CONN_LIST_ENTRY: - res = sc->conn_list[nid][0]; - break; - case HDA_CMD_VERB_GET_PIN_WIDGET_CTRL: - res = sc->pin_ctrl_default[nid]; - break; - case HDA_CMD_VERB_GET_PIN_SENSE: - res = HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED; - break; - case HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT: - res = sc->conf_default[nid]; - break; - case HDA_CMD_VERB_GET_SUBSYSTEM_ID: - res = sc->subsystem_id; - break; - default: - assert(sc->verb_handlers); - if (sc->verb_handlers[nid]) - res = sc->verb_handlers[nid](sc, verb, payload); - else - DPRINTF("Unknown VERB: 0x%x\n", verb); - break; - } - - DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x\n", - cad, nid, verb, payload, res); - - return (hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL)); -} - -static int -hda_codec_notify(struct hda_codec_inst *hci, uint8_t run, - uint8_t stream, uint8_t dir) -{ - struct hda_codec_softc *sc = NULL; - struct hda_codec_stream *st = NULL; - struct hda_audio_ctxt *actx = NULL; - int i; - int err; - - assert(hci); - assert(stream); - - sc = (struct hda_codec_softc *)hci->priv; - assert(sc); - - i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT; - st = &sc->streams[i]; - - DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d\n", - run, stream, st->stream, dir); - - if (stream != st->stream) { - DPRINTF("Stream not found\n"); - return (0); - } - - actx = &st->actx; - - if (run) - err = hda_audio_ctxt_start(actx); - else - err = hda_audio_ctxt_stop(actx); - - return (err); -} - -static int -hda_codec_parse_format(uint16_t fmt, struct audio_params *params) -{ - uint8_t div = 0; - - assert(params); - - /* Compute the Sample Rate */ - params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000; - - switch (fmt & HDA_CODEC_FMT_MULT_MASK) { - case HDA_CODEC_FMT_MULT_2: - params->rate *= 2; - break; - case HDA_CODEC_FMT_MULT_3: - params->rate *= 3; - break; - case HDA_CODEC_FMT_MULT_4: - params->rate *= 4; - break; - } - - div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK; - params->rate /= (div + 1); - - /* Compute the Bits per Sample */ - switch (fmt & HDA_CODEC_FMT_BITS_MASK) { - case HDA_CODEC_FMT_BITS_8: - params->format = AFMT_U8; - break; - case HDA_CODEC_FMT_BITS_16: - params->format = AFMT_S16_LE; - break; - case HDA_CODEC_FMT_BITS_24: - params->format = AFMT_S24_LE; - break; - case HDA_CODEC_FMT_BITS_32: - params->format = AFMT_S32_LE; - break; - default: - DPRINTF("Unknown format bits: 0x%x\n", - fmt & HDA_CODEC_FMT_BITS_MASK); - return (-1); - } - - /* Compute the Number of Channels */ - params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1; - - return (0); -} - -static uint32_t -hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb, - uint16_t payload) -{ - struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - int res; - - res = hda_codec_audio_inout_nid(st, verb, payload); - - return (res); -} - -static void -hda_codec_audio_output_do_transfer(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - int err; - - hci = sc->hci; - assert(hci); - - hops = hci->hops; - assert(hops); - - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - aud = st->aud; - - err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf)); - if (err) - return; - - err = audio_playback(aud, st->buf, sizeof(st->buf)); - assert(!err); -} - -static int -hda_codec_audio_output_do_setup(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - struct audio_params params; - int err; - - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - aud = st->aud; - - err = hda_codec_parse_format(st->fmt, ¶ms); - if (err) - return (-1); - - DPRINTF("rate: %d, channels: %d, format: 0x%x\n", - params.rate, params.channels, params.format); - - return (audio_set_params(aud, ¶ms)); -} - -static uint32_t -hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb, - uint16_t payload) -{ - struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - int res; - - res = hda_codec_audio_inout_nid(st, verb, payload); - - return (res); -} - -static void -hda_codec_audio_input_do_transfer(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - int err; - - hci = sc->hci; - assert(hci); - - hops = hci->hops; - assert(hops); - - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - aud = st->aud; - - err = audio_record(aud, st->buf, sizeof(st->buf)); - assert(!err); - - hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf)); -} - -static int -hda_codec_audio_input_do_setup(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - struct audio_params params; - int err; - - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - aud = st->aud; - - err = hda_codec_parse_format(st->fmt, ¶ms); - if (err) - return (-1); - - DPRINTF("rate: %d, channels: %d, format: 0x%x\n", - params.rate, params.channels, params.format); - - return (audio_set_params(aud, ¶ms)); -} - -static uint32_t -hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb, - uint16_t payload) -{ - uint32_t res = 0; - uint8_t mute = 0; - uint8_t gain = 0; - - DPRINTF("%s verb: 0x%x, payload, 0x%x\n", st->actx.name, verb, payload); - - switch (verb) { - case HDA_CMD_VERB_GET_CONV_FMT: - res = st->fmt; - break; - case HDA_CMD_VERB_SET_CONV_FMT: - st->fmt = payload; - break; - case HDA_CMD_VERB_GET_AMP_GAIN_MUTE: - if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) { - res = st->left_gain | st->left_mute; - DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x\n", res); - } else { - res = st->right_gain | st->right_mute; - DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x\n", res); - } - break; - case HDA_CMD_VERB_SET_AMP_GAIN_MUTE: - mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK; - - if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_LEFT) { - st->left_mute = mute; - st->left_gain = gain; - DPRINTF("SET_AMP_GAIN_MUTE_LEFT: \ - mute: 0x%x gain: 0x%x\n", mute, gain); - } - - if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT) { - st->right_mute = mute; - st->right_gain = gain; - DPRINTF("SET_AMP_GAIN_MUTE_RIGHT: \ - mute: 0x%x gain: 0x%x\n", mute, gain); - } - break; - case HDA_CMD_VERB_GET_CONV_STREAM_CHAN: - res = (st->stream << 4) | st->channel; - break; - case HDA_CMD_VERB_SET_CONV_STREAM_CHAN: - st->channel = payload & 0x0f; - st->stream = (payload >> 4) & 0x0f; - DPRINTF("st->channel: 0x%x st->stream: 0x%x\n", - st->channel, st->stream); - if (!st->stream) - hda_audio_ctxt_stop(&st->actx); - break; - default: - DPRINTF("Unknown VERB: 0x%x\n", verb); - break; - } - - return (res); -} - -struct hda_codec_class hda_codec = { - .name = "hda_codec", - .init = hda_codec_init, - .reset = hda_codec_reset, - .command = hda_codec_command, - .notify = hda_codec_notify, -}; - -HDA_EMUL_SET(hda_codec); - - -/* - * HDA Audio Context module function definitions - */ - -static void * -hda_audio_ctxt_thr(void *arg) -{ - struct hda_audio_ctxt *actx = arg; - - DPRINTF("Start Thread: %s\n", actx->name); - - pthread_mutex_lock(&actx->mtx); - while (1) { - while (!actx->run) - pthread_cond_wait(&actx->cond, &actx->mtx); - - actx->do_transfer(actx->priv); - } - pthread_mutex_unlock(&actx->mtx); - - pthread_exit(NULL); - return (NULL); -} - -static int -hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, - transfer_func_t do_transfer, setup_func_t do_setup, void *priv) -{ - int err; - - assert(actx); - assert(tname); - assert(do_transfer); - assert(do_setup); - assert(priv); - - memset(actx, 0, sizeof(*actx)); - - actx->run = 0; - actx->do_transfer = do_transfer; - actx->do_setup = do_setup; - actx->priv = priv; - if (strlen(tname) < sizeof(actx->name)) - memcpy(actx->name, tname, strlen(tname) + 1); - else - strcpy(actx->name, "unknown"); - - err = pthread_mutex_init(&actx->mtx, NULL); - assert(!err); - - err = pthread_cond_init(&actx->cond, NULL); - assert(!err); - - err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx); - assert(!err); - - pthread_set_name_np(actx->tid, tname); - - actx->started = 1; - - return (0); -} - -static int -hda_audio_ctxt_start(struct hda_audio_ctxt *actx) -{ - int err = 0; - - assert(actx); - assert(actx->started); - - /* The stream is supposed to be stopped */ - if (actx->run) - return (-1); - - pthread_mutex_lock(&actx->mtx); - err = (* actx->do_setup)(actx->priv); - if (!err) { - actx->run = 1; - pthread_cond_signal(&actx->cond); - } - pthread_mutex_unlock(&actx->mtx); - - return (err); -} - -static int -hda_audio_ctxt_stop(struct hda_audio_ctxt *actx) -{ - actx->run = 0; - return (0); -} Property changes on: head/usr.sbin/bhyve/hda_codec.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/pci_hda.c =================================================================== --- head/usr.sbin/bhyve/pci_hda.c (revision 349351) +++ head/usr.sbin/bhyve/pci_hda.c (nonexistent) @@ -1,1330 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include "pci_hda.h" -#include "bhyverun.h" -#include "pci_emul.h" -#include "hdac_reg.h" - -/* - * HDA defines - */ -#define PCIR_HDCTL 0x40 -#define INTEL_VENDORID 0x8086 -#define HDA_INTEL_82801G 0x27d8 - -#define HDA_IOSS_NO 0x08 -#define HDA_OSS_NO 0x04 -#define HDA_ISS_NO 0x04 -#define HDA_CODEC_MAX 0x0f -#define HDA_LAST_OFFSET \ - (0x2084 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20)) -#define HDA_SET_REG_TABLE_SZ \ - (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20)) -#define HDA_CORB_ENTRY_LEN 0x04 -#define HDA_RIRB_ENTRY_LEN 0x08 -#define HDA_BDL_ENTRY_LEN 0x10 -#define HDA_DMA_PIB_ENTRY_LEN 0x08 -#define HDA_STREAM_TAGS_CNT 0x10 -#define HDA_STREAM_REGS_BASE 0x80 -#define HDA_STREAM_REGS_LEN 0x20 - -#define HDA_DMA_ACCESS_LEN (sizeof(uint32_t)) -#define HDA_BDL_MAX_LEN 0x0100 - -#define HDAC_SDSTS_FIFORDY (1 << 5) - -#define HDA_RIRBSTS_IRQ_MASK (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS) -#define HDA_STATESTS_IRQ_MASK ((1 << HDA_CODEC_MAX) - 1) -#define HDA_SDSTS_IRQ_MASK \ - (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS) - -/* - * HDA data structures - */ - -struct hda_softc; - -typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset, - uint32_t old); - -struct hda_bdle { - uint32_t addrh; - uint32_t addrl; - uint32_t ioc; - uint32_t len; -} __packed; - -struct hda_bdle_desc { - void *addr; - uint8_t ioc; - uint32_t len; -}; - -struct hda_codec_cmd_ctl { - char *name; - void *dma_vaddr; - uint8_t run; - uint16_t rp; - uint16_t size; - uint16_t wp; -}; - -struct hda_stream_desc { - uint8_t dir; - uint8_t run; - uint8_t stream; - - /* bp is the no. of bytes transferred in the current bdle */ - uint32_t bp; - /* be is the no. of bdles transferred in the bdl */ - uint32_t be; - - uint32_t bdl_cnt; - struct hda_bdle_desc bdl[HDA_BDL_MAX_LEN]; -}; - -struct hda_softc { - struct pci_devinst *pci_dev; - uint32_t regs[HDA_LAST_OFFSET]; - - uint8_t lintr; - uint8_t rirb_cnt; - uint64_t wall_clock_start; - - struct hda_codec_cmd_ctl corb; - struct hda_codec_cmd_ctl rirb; - - uint8_t codecs_no; - struct hda_codec_inst *codecs[HDA_CODEC_MAX]; - - /* Base Address of the DMA Position Buffer */ - void *dma_pib_vaddr; - - struct hda_stream_desc streams[HDA_IOSS_NO]; - /* 2 tables for output and input */ - uint8_t stream_map[2][HDA_STREAM_TAGS_CNT]; -}; - -/* - * HDA module function declarations - */ -static inline void hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, - uint32_t value); -static inline uint32_t hda_get_reg_by_offset(struct hda_softc *sc, - uint32_t offset); -static inline void hda_set_field_by_offset(struct hda_softc *sc, - uint32_t offset, uint32_t mask, uint32_t value); - -static uint8_t hda_parse_config(const char *opts, const char *key, char *val); -static struct hda_softc *hda_init(const char *opts); -static void hda_update_intr(struct hda_softc *sc); -static void hda_response_interrupt(struct hda_softc *sc); -static int hda_codec_constructor(struct hda_softc *sc, - struct hda_codec_class *codec, const char *play, const char *rec, - const char *opts); -static struct hda_codec_class *hda_find_codec_class(const char *name); - -static int hda_send_command(struct hda_softc *sc, uint32_t verb); -static int hda_notify_codecs(struct hda_softc *sc, uint8_t run, - uint8_t stream, uint8_t dir); -static void hda_reset(struct hda_softc *sc); -static void hda_reset_regs(struct hda_softc *sc); -static void hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind); -static int hda_stream_start(struct hda_softc *sc, uint8_t stream_ind); -static int hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind); -static uint32_t hda_read(struct hda_softc *sc, uint32_t offset); -static int hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, - uint32_t value); - -static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p); -static int hda_corb_start(struct hda_softc *sc); -static int hda_corb_run(struct hda_softc *sc); -static int hda_rirb_start(struct hda_softc *sc); - -static void *hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, - size_t len); -static void hda_dma_st_dword(void *dma_vaddr, uint32_t data); -static uint32_t hda_dma_ld_dword(void *dma_vaddr); - -static inline uint8_t hda_get_stream_by_offsets(uint32_t offset, - uint8_t reg_offset); -static inline uint32_t hda_get_offset_stream(uint8_t stream_ind); - -static void hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_statests(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old); - -static int hda_signal_state_change(struct hda_codec_inst *hci); -static int hda_response(struct hda_codec_inst *hci, uint32_t response, - uint8_t unsol); -static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream, - uint8_t dir, void *buf, size_t count); - -static void hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib); -static uint64_t hda_get_clock_ns(void); - -/* - * PCI HDA function declarations - */ -static int pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts); -static void pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value); -static uint64_t pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size); -/* - * HDA global data - */ - -static const hda_set_reg_handler hda_set_reg_table[] = { - [HDAC_GCTL] = hda_set_gctl, - [HDAC_STATESTS] = hda_set_statests, - [HDAC_CORBWP] = hda_set_corbwp, - [HDAC_CORBCTL] = hda_set_corbctl, - [HDAC_RIRBCTL] = hda_set_rirbctl, - [HDAC_RIRBSTS] = hda_set_rirbsts, - [HDAC_DPIBLBASE] = hda_set_dpiblbase, - -#define HDAC_ISTREAM(n, iss, oss) \ - [_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl, \ - [_HDAC_ISDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \ - [_HDAC_ISDSTS(n, iss, oss)] = hda_set_sdsts, \ - -#define HDAC_OSTREAM(n, iss, oss) \ - [_HDAC_OSDCTL(n, iss, oss)] = hda_set_sdctl, \ - [_HDAC_OSDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \ - [_HDAC_OSDSTS(n, iss, oss)] = hda_set_sdsts, \ - - HDAC_ISTREAM(0, HDA_ISS_NO, HDA_OSS_NO) - HDAC_ISTREAM(1, HDA_ISS_NO, HDA_OSS_NO) - HDAC_ISTREAM(2, HDA_ISS_NO, HDA_OSS_NO) - HDAC_ISTREAM(3, HDA_ISS_NO, HDA_OSS_NO) - - HDAC_OSTREAM(0, HDA_ISS_NO, HDA_OSS_NO) - HDAC_OSTREAM(1, HDA_ISS_NO, HDA_OSS_NO) - HDAC_OSTREAM(2, HDA_ISS_NO, HDA_OSS_NO) - HDAC_OSTREAM(3, HDA_ISS_NO, HDA_OSS_NO) - - [HDA_SET_REG_TABLE_SZ] = NULL, -}; - -static const uint16_t hda_corb_sizes[] = { - [HDAC_CORBSIZE_CORBSIZE_2] = 2, - [HDAC_CORBSIZE_CORBSIZE_16] = 16, - [HDAC_CORBSIZE_CORBSIZE_256] = 256, - [HDAC_CORBSIZE_CORBSIZE_MASK] = 0, -}; - -static const uint16_t hda_rirb_sizes[] = { - [HDAC_RIRBSIZE_RIRBSIZE_2] = 2, - [HDAC_RIRBSIZE_RIRBSIZE_16] = 16, - [HDAC_RIRBSIZE_RIRBSIZE_256] = 256, - [HDAC_RIRBSIZE_RIRBSIZE_MASK] = 0, -}; - -static struct hda_ops hops = { - .signal = hda_signal_state_change, - .response = hda_response, - .transfer = hda_transfer, -}; - -struct pci_devemu pci_de_hda = { - .pe_emu = "hda", - .pe_init = pci_hda_init, - .pe_barwrite = pci_hda_write, - .pe_barread = pci_hda_read -}; - -PCI_EMUL_SET(pci_de_hda); - -SET_DECLARE(hda_codec_class_set, struct hda_codec_class); - -#if DEBUG_HDA == 1 -FILE *dbg; -#endif - -/* - * HDA module function definitions - */ - -static inline void -hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value) -{ - assert(offset < HDA_LAST_OFFSET); - sc->regs[offset] = value; -} - -static inline uint32_t -hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset) -{ - assert(offset < HDA_LAST_OFFSET); - return sc->regs[offset]; -} - -static inline void -hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, - uint32_t mask, uint32_t value) -{ - uint32_t reg_value = 0; - - reg_value = hda_get_reg_by_offset(sc, offset); - - reg_value &= ~mask; - reg_value |= (value & mask); - - hda_set_reg_by_offset(sc, offset, reg_value); -} - -static uint8_t -hda_parse_config(const char *opts, const char *key, char *val) -{ - char buf[64]; - char *s = buf; - char *tmp = NULL; - int len; - int i; - - if (!opts) - return (0); - - len = strlen(opts); - - if (len >= 64) { - DPRINTF("Opts too big\n"); - return (0); - } - - DPRINTF("opts: %s\n", opts); - - strcpy(buf, opts); - - for (i = 0; i < len; i++) - if (buf[i] == ',') { - buf[i] = 0; - tmp = buf + i + 1; - break; - } - - if (!memcmp(s, key, strlen(key))) { - strncpy(val, s + strlen(key), 64); - return (1); - } - - if (!tmp) - return (0); - - s = tmp; - if (!memcmp(s, key, strlen(key))) { - strncpy(val, s + strlen(key), 64); - return (1); - } - - return (0); -} - -static struct hda_softc * -hda_init(const char *opts) -{ - struct hda_softc *sc = NULL; - struct hda_codec_class *codec = NULL; - char play[64]; - char rec[64]; - int err, p, r; - -#if DEBUG_HDA == 1 - dbg = fopen("/tmp/bhyve_hda.log", "w+"); -#endif - - DPRINTF("opts: %s\n", opts); - - sc = calloc(1, sizeof(*sc)); - if (!sc) - return (NULL); - - hda_reset_regs(sc); - - /* - * TODO search all the codecs declared in opts - * For now we play with one single codec - */ - codec = hda_find_codec_class("hda_codec"); - if (codec) { - p = hda_parse_config(opts, "play=", play); - r = hda_parse_config(opts, "rec=", rec); - DPRINTF("play: %s rec: %s\n", play, rec); - if (p | r) { - err = hda_codec_constructor(sc, codec, p ? \ - play : NULL, r ? rec : NULL, NULL); - assert(!err); - } - } - - return (sc); -} - -static void -hda_update_intr(struct hda_softc *sc) -{ - struct pci_devinst *pi = sc->pci_dev; - uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL); - uint32_t intsts = 0; - uint32_t sdsts = 0; - uint32_t rirbsts = 0; - uint32_t wakeen = 0; - uint32_t statests = 0; - uint32_t off = 0; - int i; - - /* update the CIS bits */ - rirbsts = hda_get_reg_by_offset(sc, HDAC_RIRBSTS); - if (rirbsts & (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS)) - intsts |= HDAC_INTSTS_CIS; - - wakeen = hda_get_reg_by_offset(sc, HDAC_WAKEEN); - statests = hda_get_reg_by_offset(sc, HDAC_STATESTS); - if (statests & wakeen) - intsts |= HDAC_INTSTS_CIS; - - /* update the SIS bits */ - for (i = 0; i < HDA_IOSS_NO; i++) { - off = hda_get_offset_stream(i); - sdsts = hda_get_reg_by_offset(sc, off + HDAC_SDSTS); - if (sdsts & HDAC_SDSTS_BCIS) - intsts |= (1 << i); - } - - /* update the GIS bit */ - if (intsts) - intsts |= HDAC_INTSTS_GIS; - - hda_set_reg_by_offset(sc, HDAC_INTSTS, intsts); - - if ((intctl & HDAC_INTCTL_GIE) && ((intsts & \ - ~HDAC_INTSTS_GIS) & intctl)) { - if (!sc->lintr) { - pci_lintr_assert(pi); - sc->lintr = 1; - } - } else { - if (sc->lintr) { - pci_lintr_deassert(pi); - sc->lintr = 0; - } - } -} - -static void -hda_response_interrupt(struct hda_softc *sc) -{ - uint8_t rirbctl = hda_get_reg_by_offset(sc, HDAC_RIRBCTL); - - if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) { - sc->rirb_cnt = 0; - hda_set_field_by_offset(sc, HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL, - HDAC_RIRBSTS_RINTFL); - hda_update_intr(sc); - } -} - -static int -hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec, - const char *play, const char *rec, const char *opts) -{ - struct hda_codec_inst *hci = NULL; - - if (sc->codecs_no >= HDA_CODEC_MAX) - return (-1); - - hci = calloc(1, sizeof(struct hda_codec_inst)); - if (!hci) - return (-1); - - hci->hda = sc; - hci->hops = &hops; - hci->cad = sc->codecs_no; - hci->codec = codec; - - sc->codecs[sc->codecs_no++] = hci; - - if (!codec->init) { - DPRINTF("This codec does not implement the init function\n"); - return (-1); - } - - return (codec->init(hci, play, rec, opts)); -} - -static struct hda_codec_class * -hda_find_codec_class(const char *name) -{ - struct hda_codec_class **pdpp = NULL, *pdp = NULL; - - SET_FOREACH(pdpp, hda_codec_class_set) { - pdp = *pdpp; - if (!strcmp(pdp->name, name)) { - return (pdp); - } - } - - return (NULL); -} - -static int -hda_send_command(struct hda_softc *sc, uint32_t verb) -{ - struct hda_codec_inst *hci = NULL; - struct hda_codec_class *codec = NULL; - uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f; - - hci = sc->codecs[cad]; - if (!hci) - return (-1); - - DPRINTF("cad: 0x%x verb: 0x%x\n", cad, verb); - - codec = hci->codec; - assert(codec); - - if (!codec->command) { - DPRINTF("This codec does not implement the command function\n"); - return (-1); - } - - return (codec->command(hci, verb)); -} - -static int -hda_notify_codecs(struct hda_softc *sc, uint8_t run, uint8_t stream, - uint8_t dir) -{ - struct hda_codec_inst *hci = NULL; - struct hda_codec_class *codec = NULL; - int err; - int i; - - /* Notify each codec */ - for (i = 0; i < sc->codecs_no; i++) { - hci = sc->codecs[i]; - assert(hci); - - codec = hci->codec; - assert(codec); - - if (codec->notify) { - err = codec->notify(hci, run, stream, dir); - if (!err) - break; - } - } - - return (i == sc->codecs_no ? (-1) : 0); -} - -static void -hda_reset(struct hda_softc *sc) -{ - int i; - struct hda_codec_inst *hci = NULL; - struct hda_codec_class *codec = NULL; - - hda_reset_regs(sc); - - /* Reset each codec */ - for (i = 0; i < sc->codecs_no; i++) { - hci = sc->codecs[i]; - assert(hci); - - codec = hci->codec; - assert(codec); - - if (codec->reset) - codec->reset(hci); - } - - sc->wall_clock_start = hda_get_clock_ns(); -} - -static void -hda_reset_regs(struct hda_softc *sc) -{ - uint32_t off = 0; - uint8_t i; - - DPRINTF("Reset the HDA controller registers ...\n"); - - memset(sc->regs, 0, sizeof(sc->regs)); - - hda_set_reg_by_offset(sc, HDAC_GCAP, - HDAC_GCAP_64OK | - (HDA_ISS_NO << HDAC_GCAP_ISS_SHIFT) | - (HDA_OSS_NO << HDAC_GCAP_OSS_SHIFT)); - hda_set_reg_by_offset(sc, HDAC_VMAJ, 0x01); - hda_set_reg_by_offset(sc, HDAC_OUTPAY, 0x3c); - hda_set_reg_by_offset(sc, HDAC_INPAY, 0x1d); - hda_set_reg_by_offset(sc, HDAC_CORBSIZE, - HDAC_CORBSIZE_CORBSZCAP_256 | HDAC_CORBSIZE_CORBSIZE_256); - hda_set_reg_by_offset(sc, HDAC_RIRBSIZE, - HDAC_RIRBSIZE_RIRBSZCAP_256 | HDAC_RIRBSIZE_RIRBSIZE_256); - - for (i = 0; i < HDA_IOSS_NO; i++) { - off = hda_get_offset_stream(i); - hda_set_reg_by_offset(sc, off + HDAC_SDFIFOS, HDA_FIFO_SIZE); - } -} - -static void -hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind) -{ - struct hda_stream_desc *st = &sc->streams[stream_ind]; - uint32_t off = hda_get_offset_stream(stream_ind); - - DPRINTF("Reset the HDA stream: 0x%x\n", stream_ind); - - /* Reset the Stream Descriptor registers */ - memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN); - - /* Reset the Stream Descriptor */ - memset(st, 0, sizeof(*st)); - - hda_set_field_by_offset(sc, off + HDAC_SDSTS, - HDAC_SDSTS_FIFORDY, HDAC_SDSTS_FIFORDY); - hda_set_field_by_offset(sc, off + HDAC_SDCTL0, - HDAC_SDCTL_SRST, HDAC_SDCTL_SRST); -} - -static int -hda_stream_start(struct hda_softc *sc, uint8_t stream_ind) -{ - struct hda_stream_desc *st = &sc->streams[stream_ind]; - struct hda_bdle_desc *bdle_desc = NULL; - struct hda_bdle *bdle = NULL; - uint32_t lvi = 0; - uint32_t bdl_cnt = 0; - uint64_t bdpl = 0; - uint64_t bdpu = 0; - uint64_t bdl_paddr = 0; - void *bdl_vaddr = NULL; - uint32_t bdle_sz = 0; - uint64_t bdle_addrl = 0; - uint64_t bdle_addrh = 0; - uint64_t bdle_paddr = 0; - void *bdle_vaddr = NULL; - uint32_t off = hda_get_offset_stream(stream_ind); - uint32_t sdctl = 0; - uint8_t strm = 0; - uint8_t dir = 0; - int i; - - assert(!st->run); - - lvi = hda_get_reg_by_offset(sc, off + HDAC_SDLVI); - bdpl = hda_get_reg_by_offset(sc, off + HDAC_SDBDPL); - bdpu = hda_get_reg_by_offset(sc, off + HDAC_SDBDPU); - - bdl_cnt = lvi + 1; - assert(bdl_cnt <= HDA_BDL_MAX_LEN); - - bdl_paddr = bdpl | (bdpu << 32); - bdl_vaddr = hda_dma_get_vaddr(sc, bdl_paddr, - HDA_BDL_ENTRY_LEN * bdl_cnt); - if (!bdl_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx\n", - stream_ind, bdl_cnt, bdl_paddr); - - st->bdl_cnt = bdl_cnt; - - bdle = (struct hda_bdle *)bdl_vaddr; - for (i = 0; i < bdl_cnt; i++, bdle++) { - bdle_sz = bdle->len; - assert(!(bdle_sz % HDA_DMA_ACCESS_LEN)); - - bdle_addrl = bdle->addrl; - bdle_addrh = bdle->addrh; - - bdle_paddr = bdle_addrl | (bdle_addrh << 32); - bdle_vaddr = hda_dma_get_vaddr(sc, bdle_paddr, bdle_sz); - if (!bdle_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - bdle_desc = &st->bdl[i]; - bdle_desc->addr = bdle_vaddr; - bdle_desc->len = bdle_sz; - bdle_desc->ioc = bdle->ioc; - - DPRINTF("bdle: 0x%x bdle_sz: 0x%x\n", i, bdle_sz); - } - - sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0); - strm = (sdctl >> 20) & 0x0f; - dir = stream_ind >= HDA_ISS_NO; - - DPRINTF("strm: 0x%x, dir: 0x%x\n", strm, dir); - - sc->stream_map[dir][strm] = stream_ind; - st->stream = strm; - st->dir = dir; - st->bp = 0; - st->be = 0; - - hda_set_pib(sc, stream_ind, 0); - - st->run = 1; - - hda_notify_codecs(sc, 1, strm, dir); - - return (0); -} - -static int -hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind) -{ - struct hda_stream_desc *st = &sc->streams[stream_ind]; - uint8_t strm = st->stream; - uint8_t dir = st->dir; - - DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x\n", stream_ind, strm, dir); - - st->run = 0; - - hda_notify_codecs(sc, 0, strm, dir); - - return (0); -} - -static uint32_t -hda_read(struct hda_softc *sc, uint32_t offset) -{ - if (offset == HDAC_WALCLK) - return (24 * (hda_get_clock_ns() - \ - sc->wall_clock_start) / 1000); - - return (hda_get_reg_by_offset(sc, offset)); -} - -static int -hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value) -{ - uint32_t old = hda_get_reg_by_offset(sc, offset); - uint32_t masks[] = {0x00000000, 0x000000ff, 0x0000ffff, - 0x00ffffff, 0xffffffff}; - hda_set_reg_handler set_reg_handler = hda_set_reg_table[offset]; - - hda_set_field_by_offset(sc, offset, masks[size], value); - - if (set_reg_handler) - set_reg_handler(sc, offset, old); - - return (0); -} - -static inline void -hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p) -{ -#if DEBUG_HDA == 1 - char *name = p->name; -#endif - DPRINTF("%s size: %d\n", name, p->size); - DPRINTF("%s dma_vaddr: %p\n", name, p->dma_vaddr); - DPRINTF("%s wp: 0x%x\n", name, p->wp); - DPRINTF("%s rp: 0x%x\n", name, p->rp); -} - -static int -hda_corb_start(struct hda_softc *sc) -{ - struct hda_codec_cmd_ctl *corb = &sc->corb; - uint8_t corbsize = 0; - uint64_t corblbase = 0; - uint64_t corbubase = 0; - uint64_t corbpaddr = 0; - - corb->name = "CORB"; - - corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) & \ - HDAC_CORBSIZE_CORBSIZE_MASK; - corb->size = hda_corb_sizes[corbsize]; - - if (!corb->size) { - DPRINTF("Invalid corb size\n"); - return (-1); - } - - corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE); - corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE); - - corbpaddr = corblbase | (corbubase << 32); - DPRINTF("CORB dma_paddr: %p\n", (void *)corbpaddr); - - corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr, - HDA_CORB_ENTRY_LEN * corb->size); - if (!corb->dma_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); - corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP); - - corb->run = 1; - - hda_print_cmd_ctl_data(corb); - - return (0); -} - -static int -hda_corb_run(struct hda_softc *sc) -{ - struct hda_codec_cmd_ctl *corb = &sc->corb; - uint32_t verb = 0; - int err; - - corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); - - while (corb->rp != corb->wp && corb->run) { - corb->rp++; - corb->rp %= corb->size; - - verb = hda_dma_ld_dword(corb->dma_vaddr + \ - HDA_CORB_ENTRY_LEN * corb->rp); - - err = hda_send_command(sc, verb); - assert(!err); - } - - hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp); - - if (corb->run) - hda_response_interrupt(sc); - - return (0); -} - -static int -hda_rirb_start(struct hda_softc *sc) -{ - struct hda_codec_cmd_ctl *rirb = &sc->rirb; - uint8_t rirbsize = 0; - uint64_t rirblbase = 0; - uint64_t rirbubase = 0; - uint64_t rirbpaddr = 0; - - rirb->name = "RIRB"; - - rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) & \ - HDAC_RIRBSIZE_RIRBSIZE_MASK; - rirb->size = hda_rirb_sizes[rirbsize]; - - if (!rirb->size) { - DPRINTF("Invalid rirb size\n"); - return (-1); - } - - rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE); - rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE); - - rirbpaddr = rirblbase | (rirbubase << 32); - DPRINTF("RIRB dma_paddr: %p\n", (void *)rirbpaddr); - - rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr, - HDA_RIRB_ENTRY_LEN * rirb->size); - if (!rirb->dma_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP); - rirb->rp = 0x0000; - - rirb->run = 1; - - hda_print_cmd_ctl_data(rirb); - - return (0); -} - -static void * -hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len) -{ - struct pci_devinst *pi = sc->pci_dev; - - assert(pi); - - return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len)); -} - -static void -hda_dma_st_dword(void *dma_vaddr, uint32_t data) -{ - *(uint32_t*)dma_vaddr = data; -} - -static uint32_t -hda_dma_ld_dword(void *dma_vaddr) -{ - return (*(uint32_t*)dma_vaddr); -} - -static inline uint8_t -hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset) -{ - uint8_t stream_ind = (offset - reg_offset) >> 5; - - assert(stream_ind < HDA_IOSS_NO); - - return (stream_ind); -} - -static inline uint32_t -hda_get_offset_stream(uint8_t stream_ind) -{ - return (stream_ind << 5); -} - -static void -hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - if (!(value & HDAC_GCTL_CRST)) { - hda_reset(sc); - } -} - -static void -hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_reg_by_offset(sc, offset, old); - - /* clear the corresponding bits written by the software (guest) */ - hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0); - - hda_update_intr(sc); -} - -static void -hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - hda_corb_run(sc); -} - -static void -hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - int err; - struct hda_codec_cmd_ctl *corb = NULL; - - if (value & HDAC_CORBCTL_CORBRUN) { - if (!(old & HDAC_CORBCTL_CORBRUN)) { - err = hda_corb_start(sc); - assert(!err); - } - } else { - corb = &sc->corb; - memset(corb, 0, sizeof(*corb)); - } - - hda_corb_run(sc); -} - -static void -hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - int err; - struct hda_codec_cmd_ctl *rirb = NULL; - - if (value & HDAC_RIRBCTL_RIRBDMAEN) { - err = hda_rirb_start(sc); - assert(!err); - } else { - rirb = &sc->rirb; - memset(rirb, 0, sizeof(*rirb)); - } -} - -static void -hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_reg_by_offset(sc, offset, old); - - /* clear the corresponding bits written by the software (guest) */ - hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0); - - hda_update_intr(sc); -} - -static void -hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - uint64_t dpiblbase = 0; - uint64_t dpibubase = 0; - uint64_t dpibpaddr = 0; - - if ((value & HDAC_DPLBASE_DPLBASE_DMAPBE) != (old & \ - HDAC_DPLBASE_DPLBASE_DMAPBE)) { - if (value & HDAC_DPLBASE_DPLBASE_DMAPBE) { - dpiblbase = value & HDAC_DPLBASE_DPLBASE_MASK; - dpibubase = hda_get_reg_by_offset(sc, HDAC_DPIBUBASE); - - dpibpaddr = dpiblbase | (dpibubase << 32); - DPRINTF("DMA Position In Buffer dma_paddr: %p\n", - (void *)dpibpaddr); - - sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr, - HDA_DMA_PIB_ENTRY_LEN * HDA_IOSS_NO); - if (!sc->dma_pib_vaddr) { - DPRINTF("Fail to get the guest \ - virtual address\n"); - assert(0); - } - } else { - DPRINTF("DMA Position In Buffer Reset\n"); - sc->dma_pib_vaddr = NULL; - } - } -} - -static void -hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0); - uint32_t value = hda_get_reg_by_offset(sc, offset); - int err; - - DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x\n", - stream_ind, old, value); - - if (value & HDAC_SDCTL_SRST) { - hda_stream_reset(sc, stream_ind); - } - - if ((value & HDAC_SDCTL_RUN) != (old & HDAC_SDCTL_RUN)) { - if (value & HDAC_SDCTL_RUN) { - err = hda_stream_start(sc, stream_ind); - assert(!err); - } else { - err = hda_stream_stop(sc, stream_ind); - assert(!err); - } - } -} - -static void -hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16); -} - -static void -hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_reg_by_offset(sc, offset, old); - - /* clear the corresponding bits written by the software (guest) */ - hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0); - - hda_update_intr(sc); -} - -static int -hda_signal_state_change(struct hda_codec_inst *hci) -{ - struct hda_softc *sc = NULL; - uint32_t sdiwake = 0; - - assert(hci); - assert(hci->hda); - - DPRINTF("cad: 0x%x\n", hci->cad); - - sc = hci->hda; - sdiwake = 1 << hci->cad; - - hda_set_field_by_offset(sc, HDAC_STATESTS, sdiwake, sdiwake); - hda_update_intr(sc); - - return (0); -} - -static int -hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol) -{ - struct hda_softc *sc = NULL; - struct hda_codec_cmd_ctl *rirb = NULL; - uint32_t response_ex = 0; - uint8_t rintcnt = 0; - - assert(hci); - assert(hci->cad <= HDA_CODEC_MAX); - - response_ex = hci->cad | unsol; - - sc = hci->hda; - assert(sc); - - rirb = &sc->rirb; - - if (rirb->run) { - rirb->wp++; - rirb->wp %= rirb->size; - - hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \ - rirb->wp, response); - hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \ - rirb->wp + 0x04, response_ex); - - hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp); - - sc->rirb_cnt++; - } - - rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT); - if (sc->rirb_cnt == rintcnt) - hda_response_interrupt(sc); - - return (0); -} - -static int -hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir, - void *buf, size_t count) -{ - struct hda_softc *sc = NULL; - struct hda_stream_desc *st = NULL; - struct hda_bdle_desc *bdl = NULL; - struct hda_bdle_desc *bdle_desc = NULL; - uint8_t stream_ind = 0; - uint32_t lpib = 0; - uint32_t off = 0; - size_t left = 0; - uint8_t irq = 0; - - assert(hci); - assert(hci->hda); - assert(buf); - assert(!(count % HDA_DMA_ACCESS_LEN)); - - if (!stream) { - DPRINTF("Invalid stream\n"); - return (-1); - } - - sc = hci->hda; - - assert(stream < HDA_STREAM_TAGS_CNT); - stream_ind = sc->stream_map[dir][stream]; - - if (!dir) - assert(stream_ind < HDA_ISS_NO); - else - assert(stream_ind >= HDA_ISS_NO && stream_ind < HDA_IOSS_NO); - - st = &sc->streams[stream_ind]; - if (!st->run) { - DPRINTF("Stream 0x%x stopped\n", stream); - return (-1); - } - - assert(st->stream == stream); - - off = hda_get_offset_stream(stream_ind); - - lpib = hda_get_reg_by_offset(sc, off + HDAC_SDLPIB); - - bdl = st->bdl; - - assert(st->be < st->bdl_cnt); - assert(st->bp < bdl[st->be].len); - - left = count; - while (left) { - bdle_desc = &bdl[st->be]; - - if (dir) - *(uint32_t *)buf = \ - hda_dma_ld_dword(bdle_desc->addr + st->bp); - else - hda_dma_st_dword(bdle_desc->addr + st->bp, - *(uint32_t *)buf); - - buf += HDA_DMA_ACCESS_LEN; - st->bp += HDA_DMA_ACCESS_LEN; - lpib += HDA_DMA_ACCESS_LEN; - left -= HDA_DMA_ACCESS_LEN; - - if (st->bp == bdle_desc->len) { - st->bp = 0; - if (bdle_desc->ioc) - irq = 1; - st->be++; - if (st->be == st->bdl_cnt) { - st->be = 0; - lpib = 0; - } - bdle_desc = &bdl[st->be]; - } - } - - hda_set_pib(sc, stream_ind, lpib); - - if (irq) { - hda_set_field_by_offset(sc, off + HDAC_SDSTS, - HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS); - hda_update_intr(sc); - } - - return (0); -} - -static void -hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib) -{ - uint32_t off = hda_get_offset_stream(stream_ind); - - hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, pib); - /* LPIB Alias */ - hda_set_reg_by_offset(sc, 0x2000 + off + HDAC_SDLPIB, pib); - if (sc->dma_pib_vaddr) - *(uint32_t *)(sc->dma_pib_vaddr + stream_ind * \ - HDA_DMA_PIB_ENTRY_LEN) = pib; -} - -static uint64_t hda_get_clock_ns(void) -{ - struct timespec ts; - int err; - - err = clock_gettime(CLOCK_MONOTONIC, &ts); - assert(!err); - - return (ts.tv_sec * 1000000000LL + ts.tv_nsec); -} - -/* - * PCI HDA function definitions - */ -static int -pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) -{ - struct hda_softc *sc = NULL; - - assert(ctx != NULL); - assert(pi != NULL); - - pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID); - pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G); - - pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_MULTIMEDIA_HDA); - pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_MULTIMEDIA); - - /* select the Intel HDA mode */ - pci_set_cfgdata8(pi, PCIR_HDCTL, 0x01); - - /* allocate one BAR register for the Memory address offsets */ - pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, HDA_LAST_OFFSET); - - /* allocate an IRQ pin for our slot */ - pci_lintr_request(pi); - - sc = hda_init(opts); - if (!sc) - return (-1); - - sc->pci_dev = pi; - pi->pi_arg = sc; - - return (0); -} - -static void -pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) -{ - struct hda_softc *sc = pi->pi_arg; - int err; - - assert(sc); - assert(baridx == 0); - assert(size <= 4); - - DPRINTF("offset: 0x%lx value: 0x%lx\n", offset, value); - - err = hda_write(sc, offset, size, value); - assert(!err); -} - -static uint64_t -pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) -{ - struct hda_softc *sc = pi->pi_arg; - uint64_t value = 0; - - assert(sc); - assert(baridx == 0); - assert(size <= 4); - - value = hda_read(sc, offset); - - DPRINTF("offset: 0x%lx value: 0x%lx\n", offset, value); - - return (value); -} Property changes on: head/usr.sbin/bhyve/pci_hda.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/pci_hda.h =================================================================== --- head/usr.sbin/bhyve/pci_hda.h (revision 349351) +++ head/usr.sbin/bhyve/pci_hda.h (nonexistent) @@ -1,90 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 _HDA_EMUL_H_ -#define _HDA_EMUL_H_ - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "hda_reg.h" - -/* - * HDA Debug Log - */ -#define DEBUG_HDA 1 -#if DEBUG_HDA == 1 -extern FILE *dbg; -#define DPRINTF(fmt, arg...) \ -do {fprintf(dbg, "%s-%d: " fmt, __func__, __LINE__, ##arg); \ -fflush(dbg); } while (0) -#else -#define DPRINTF(fmt, arg...) -#endif - -#define HDA_FIFO_SIZE 0x100 - -struct hda_softc; -struct hda_codec_class; - -struct hda_codec_inst { - uint8_t cad; - struct hda_codec_class *codec; - struct hda_softc *hda; - struct hda_ops *hops; - void *priv; -}; - -struct hda_codec_class { - char *name; - int (*init)(struct hda_codec_inst *hci, const char *play, - const char *rec, const char *opts); - int (*reset)(struct hda_codec_inst *hci); - int (*command)(struct hda_codec_inst *hci, uint32_t cmd_data); - int (*notify)(struct hda_codec_inst *hci, uint8_t run, uint8_t stream, - uint8_t dir); -}; - -struct hda_ops { - int (*signal)(struct hda_codec_inst *hci); - int (*response)(struct hda_codec_inst *hci, uint32_t response, - uint8_t unsol); - int (*transfer)(struct hda_codec_inst *hci, uint8_t stream, - uint8_t dir, void *buf, size_t count); -}; - -#define HDA_EMUL_SET(x) DATA_SET(hda_codec_class_set, x); - -#endif /* _HDA_EMUL_H_ */ Property changes on: head/usr.sbin/bhyve/pci_hda.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/audio.c =================================================================== --- head/usr.sbin/bhyve/audio.c (revision 349351) +++ head/usr.sbin/bhyve/audio.c (nonexistent) @@ -1,282 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#ifndef WITHOUT_CAPSICUM -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "audio.h" -#include "pci_hda.h" - -/* - * Audio Player internal data structures - */ - -struct audio { - int fd; - uint8_t dir; - uint8_t inited; - char dev_name[64]; -}; - -/* - * Audio Player module function definitions - */ - -/* - * audio_init - initialize an instance of audio player - * @dev_name - the backend sound device used to play / capture - * @dir - dir = 1 for write mode, dir = 0 for read mode - */ -struct audio * -audio_init(const char *dev_name, uint8_t dir) -{ - struct audio *aud = NULL; -#ifndef WITHOUT_CAPSICUM - cap_rights_t rights; - cap_ioctl_t cmds[] = { - SNDCTL_DSP_RESET, SNDCTL_DSP_SETFMT, SNDCTL_DSP_CHANNELS, - SNDCTL_DSP_SPEED, -#ifdef DEBUG_HDA - SNDCTL_DSP_GETOSPACE, SNDCTL_DSP_GETISPACE, -#endif - }; -#endif - - assert(dev_name); - - aud = calloc(1, sizeof(*aud)); - if (!aud) - return NULL; - - if (strlen(dev_name) < sizeof(aud->dev_name)) - memcpy(aud->dev_name, dev_name, strlen(dev_name) + 1); - else { - DPRINTF("dev_name too big\n"); - free(aud); - return NULL; - } - - aud->dir = dir; - - aud->fd = open(aud->dev_name, aud->dir ? O_WRONLY : O_RDONLY, 0); - if (aud->fd == -1) { - DPRINTF("Failed to open dev: %s, errno: %d\n", - aud->dev_name, errno); - return (NULL); - } - -#ifndef WITHOUT_CAPSICUM - cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_WRITE); - if (caph_rights_limit(aud->fd, &rights) == -1) - errx(EX_OSERR, "Unable to apply rights for sandbox"); - if (caph_ioctls_limit(aud->fd, cmds, nitems(cmds)) == -1) - errx(EX_OSERR, "Unable to limit ioctl rights for sandbox"); -#endif - - return aud; -} - -/* - * audio_set_params - reset the sound device and set the audio params - * @aud - the audio player to be configured - * @params - the audio parameters to be set - */ -int -audio_set_params(struct audio *aud, struct audio_params *params) -{ - int audio_fd; - int format, channels, rate; - int err; -#if DEBUG_HDA == 1 - audio_buf_info info; -#endif - - assert(aud); - assert(params); - - if ((audio_fd = aud->fd) < 0) { - DPRINTF("Incorrect audio device descriptor for %s\n", - aud->dev_name); - return (-1); - } - - /* Reset the device if it was previously opened */ - if (aud->inited) { - err = ioctl(audio_fd, SNDCTL_DSP_RESET, NULL); - if (err == -1) { - DPRINTF("Failed to reset fd: %d, errno: %d\n", - aud->fd, errno); - return (-1); - } - } else - aud->inited = 1; - - /* Set the Format (Bits per Sample) */ - format = params->format; - err = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); - if (err == -1) { - DPRINTF("Fail to set fmt: 0x%x errno: %d\n", - params->format, errno); - return -1; - } - - /* The device does not support the requested audio format */ - if (format != params->format) { - DPRINTF("Mismatch format: 0x%x params->format: 0x%x\n", - format, params->format); - return -1; - } - - /* Set the Number of Channels */ - channels = params->channels; - err = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels); - if (err == -1) { - DPRINTF("Fail to set channels: %d errno: %d\n", - params->channels, errno); - return -1; - } - - /* The device does not support the requested no. of channels */ - if (channels != params->channels) { - DPRINTF("Mismatch channels: %d params->channels: %d\n", - channels, params->channels); - return -1; - } - - /* Set the Sample Rate / Speed */ - rate = params->rate; - err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); - if (err == -1) { - DPRINTF("Fail to set speed: %d errno: %d\n", - params->rate, errno); - return -1; - } - - /* The device does not support the requested rate / speed */ - if (rate != params->rate) { - DPRINTF("Mismatch rate: %d params->rate: %d\n", - rate, params->rate); - return -1; - } - -#if DEBUG_HDA == 1 - err = ioctl(audio_fd, aud->dir ? SNDCTL_DSP_GETOSPACE : - SNDCTL_DSP_GETISPACE, &info); - if (err == -1) { - DPRINTF("Fail to get audio buf info errno: %d\n", errno); - return -1; - } - DPRINTF("fragstotal: 0x%x fragsize: 0x%x\n", - info.fragstotal, info.fragsize); -#endif - return 0; -} - -/* - * audio_playback - plays samples to the sound device using blocking operations - * @aud - the audio player used to play the samples - * @buf - the buffer containing the samples - * @count - the number of bytes in buffer - */ -int -audio_playback(struct audio *aud, const void *buf, size_t count) -{ - int audio_fd = -1; - ssize_t len = 0, total = 0; - - assert(aud); - assert(aud->dir); - assert(buf); - - audio_fd = aud->fd; - assert(audio_fd != -1); - - total = 0; - while (total < count) { - len = write(audio_fd, buf + total, count - total); - if (len == -1) { - DPRINTF("Fail to write to fd: %d, errno: %d\n", - audio_fd, errno); - return -1; - } - - total += len; - } - - return 0; -} - -/* - * audio_record - records samples from the sound device using - * blocking operations. - * @aud - the audio player used to capture the samples - * @buf - the buffer to receive the samples - * @count - the number of bytes to capture in buffer - * Returns -1 on error and 0 on success - */ -int -audio_record(struct audio *aud, void *buf, size_t count) -{ - int audio_fd = -1; - ssize_t len = 0, total = 0; - - assert(aud); - assert(!aud->dir); - assert(buf); - - audio_fd = aud->fd; - assert(audio_fd != -1); - - total = 0; - while (total < count) { - len = read(audio_fd, buf + total, count - total); - if (len == -1) { - DPRINTF("Fail to write to fd: %d, errno: %d\n", - audio_fd, errno); - return -1; - } - - total += len; - } - - return 0; -} Property changes on: head/usr.sbin/bhyve/audio.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/audio.h =================================================================== --- head/usr.sbin/bhyve/audio.h (revision 349351) +++ head/usr.sbin/bhyve/audio.h (nonexistent) @@ -1,86 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 _AUDIO_EMUL_H_ -#define _AUDIO_EMUL_H_ - -#include -#include - -/* - * Audio Player data structures - */ - -struct audio; - -struct audio_params { - int channels; - int format; - int rate; -}; - -/* - * Audio Player API - */ - -/* - * audio_init - initialize an instance of audio player - * @dev_name - the backend sound device used to play / capture - * @dir - dir = 1 for write mode, dir = 0 for read mode - * Returns NULL on error and the address of the audio player instance - */ -struct audio *audio_init(const char *dev_name, uint8_t dir); - -/* - * audio_set_params - reset the sound device and set the audio params - * @aud - the audio player to be configured - * @params - the audio parameters to be set - * Returns -1 on error and 0 on success - */ -int audio_set_params(struct audio *aud, struct audio_params *params); - -/* - * audio_playback - plays samples to the sound device using blocking operations - * @aud - the audio player used to play the samples - * @buf - the buffer containing the samples - * @count - the number of bytes in buffer - * Returns -1 on error and 0 on success - */ -int audio_playback(struct audio *aud, const void *buf, size_t count); - -/* - * audio_record - records samples from the sound device using blocking - * operations. - * @aud - the audio player used to capture the samples - * @buf - the buffer to receive the samples - * @count - the number of bytes to capture in buffer - * Returns -1 on error and 0 on success - */ -int audio_record(struct audio *aud, void *buf, size_t count); - -#endif /* _AUDIO_EMUL_H_ */ Property changes on: head/usr.sbin/bhyve/audio.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/hdac_reg.h =================================================================== --- head/usr.sbin/bhyve/hdac_reg.h (revision 349351) +++ head/usr.sbin/bhyve/hdac_reg.h (nonexistent) @@ -1,269 +0,0 @@ -/*- - * Copyright (c) 2006 Stephane E. Potvin - * 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 _HDAC_REG_H_ -#define _HDAC_REG_H_ - -/**************************************************************************** - * HDA Controller Register Set - ****************************************************************************/ -#define HDAC_GCAP 0x00 /* 2 - Global Capabilities*/ -#define HDAC_VMIN 0x02 /* 1 - Minor Version */ -#define HDAC_VMAJ 0x03 /* 1 - Major Version */ -#define HDAC_OUTPAY 0x04 /* 2 - Output Payload Capability */ -#define HDAC_INPAY 0x06 /* 2 - Input Payload Capability */ -#define HDAC_GCTL 0x08 /* 4 - Global Control */ -#define HDAC_WAKEEN 0x0c /* 2 - Wake Enable */ -#define HDAC_STATESTS 0x0e /* 2 - State Change Status */ -#define HDAC_GSTS 0x10 /* 2 - Global Status */ -#define HDAC_OUTSTRMPAY 0x18 /* 2 - Output Stream Payload Capability */ -#define HDAC_INSTRMPAY 0x1a /* 2 - Input Stream Payload Capability */ -#define HDAC_INTCTL 0x20 /* 4 - Interrupt Control */ -#define HDAC_INTSTS 0x24 /* 4 - Interrupt Status */ -#define HDAC_WALCLK 0x30 /* 4 - Wall Clock Counter */ -#define HDAC_SSYNC 0x38 /* 4 - Stream Synchronization */ -#define HDAC_CORBLBASE 0x40 /* 4 - CORB Lower Base Address */ -#define HDAC_CORBUBASE 0x44 /* 4 - CORB Upper Base Address */ -#define HDAC_CORBWP 0x48 /* 2 - CORB Write Pointer */ -#define HDAC_CORBRP 0x4a /* 2 - CORB Read Pointer */ -#define HDAC_CORBCTL 0x4c /* 1 - CORB Control */ -#define HDAC_CORBSTS 0x4d /* 1 - CORB Status */ -#define HDAC_CORBSIZE 0x4e /* 1 - CORB Size */ -#define HDAC_RIRBLBASE 0x50 /* 4 - RIRB Lower Base Address */ -#define HDAC_RIRBUBASE 0x54 /* 4 - RIRB Upper Base Address */ -#define HDAC_RIRBWP 0x58 /* 2 - RIRB Write Pointer */ -#define HDAC_RINTCNT 0x5a /* 2 - Response Interrupt Count */ -#define HDAC_RIRBCTL 0x5c /* 1 - RIRB Control */ -#define HDAC_RIRBSTS 0x5d /* 1 - RIRB Status */ -#define HDAC_RIRBSIZE 0x5e /* 1 - RIRB Size */ -#define HDAC_ICOI 0x60 /* 4 - Immediate Command Output Interface */ -#define HDAC_ICII 0x64 /* 4 - Immediate Command Input Interface */ -#define HDAC_ICIS 0x68 /* 2 - Immediate Command Status */ -#define HDAC_DPIBLBASE 0x70 /* 4 - DMA Position Buffer Lower Base */ -#define HDAC_DPIBUBASE 0x74 /* 4 - DMA Position Buffer Upper Base */ -#define HDAC_SDCTL0 0x80 /* 3 - Stream Descriptor Control */ -#define HDAC_SDCTL1 0x81 /* 3 - Stream Descriptor Control */ -#define HDAC_SDCTL2 0x82 /* 3 - Stream Descriptor Control */ -#define HDAC_SDSTS 0x83 /* 1 - Stream Descriptor Status */ -#define HDAC_SDLPIB 0x84 /* 4 - Link Position in Buffer */ -#define HDAC_SDCBL 0x88 /* 4 - Cyclic Buffer Length */ -#define HDAC_SDLVI 0x8C /* 2 - Last Valid Index */ -#define HDAC_SDFIFOS 0x90 /* 2 - FIFOS */ -#define HDAC_SDFMT 0x92 /* 2 - fmt */ -#define HDAC_SDBDPL 0x98 /* 4 - Buffer Descriptor Pointer Lower Base */ -#define HDAC_SDBDPU 0x9C /* 4 - Buffer Descriptor Pointer Upper Base */ - -#define _HDAC_ISDOFFSET(n, iss, oss) (0x80 + ((n) * 0x20)) -#define _HDAC_ISDCTL(n, iss, oss) (0x00 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDSTS(n, iss, oss) (0x03 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDPICB(n, iss, oss) (0x04 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDCBL(n, iss, oss) (0x08 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDLVI(n, iss, oss) (0x0c + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDFIFOD(n, iss, oss) (0x10 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDFMT(n, iss, oss) (0x12 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDBDPL(n, iss, oss) (0x18 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDBDPU(n, iss, oss) (0x1c + _HDAC_ISDOFFSET(n, iss, oss)) - -#define _HDAC_OSDOFFSET(n, iss, oss) (0x80 + ((iss) * 0x20) + ((n) * 0x20)) -#define _HDAC_OSDCTL(n, iss, oss) (0x00 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDSTS(n, iss, oss) (0x03 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDPICB(n, iss, oss) (0x04 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDCBL(n, iss, oss) (0x08 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDLVI(n, iss, oss) (0x0c + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDFIFOD(n, iss, oss) (0x10 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDFMT(n, iss, oss) (0x12 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDBDPL(n, iss, oss) (0x18 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDBDPU(n, iss, oss) (0x1c + _HDAC_OSDOFFSET(n, iss, oss)) - -#define _HDAC_BSDOFFSET(n, iss, oss) \ - (0x80 + ((iss) * 0x20) + ((oss) * 0x20) + ((n) * 0x20)) -#define _HDAC_BSDCTL(n, iss, oss) (0x00 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDSTS(n, iss, oss) (0x03 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDPICB(n, iss, oss) (0x04 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDCBL(n, iss, oss) (0x08 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDLVI(n, iss, oss) (0x0c + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDFIFOD(n, iss, oss) (0x10 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDFMT(n, iss, oss) (0x12 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDBDPL(n, iss, oss) (0x18 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDBDBU(n, iss, oss) (0x1c + _HDAC_BSDOFFSET(n, iss, oss)) - -/**************************************************************************** - * HDA Controller Register Fields - ****************************************************************************/ - -/* GCAP - Global Capabilities */ -#define HDAC_GCAP_64OK 0x0001 -#define HDAC_GCAP_NSDO_MASK 0x0006 -#define HDAC_GCAP_NSDO_SHIFT 1 -#define HDAC_GCAP_BSS_MASK 0x00f8 -#define HDAC_GCAP_BSS_SHIFT 3 -#define HDAC_GCAP_ISS_MASK 0x0f00 -#define HDAC_GCAP_ISS_SHIFT 8 -#define HDAC_GCAP_OSS_MASK 0xf000 -#define HDAC_GCAP_OSS_SHIFT 12 - -#define HDAC_GCAP_NSDO_1SDO 0x00 -#define HDAC_GCAP_NSDO_2SDO 0x02 -#define HDAC_GCAP_NSDO_4SDO 0x04 - -#define HDAC_GCAP_BSS(gcap) \ - (((gcap) & HDAC_GCAP_BSS_MASK) >> HDAC_GCAP_BSS_SHIFT) -#define HDAC_GCAP_ISS(gcap) \ - (((gcap) & HDAC_GCAP_ISS_MASK) >> HDAC_GCAP_ISS_SHIFT) -#define HDAC_GCAP_OSS(gcap) \ - (((gcap) & HDAC_GCAP_OSS_MASK) >> HDAC_GCAP_OSS_SHIFT) -#define HDAC_GCAP_NSDO(gcap) \ - (((gcap) & HDAC_GCAP_NSDO_MASK) >> HDAC_GCAP_NSDO_SHIFT) - -/* GCTL - Global Control */ -#define HDAC_GCTL_CRST 0x00000001 -#define HDAC_GCTL_FCNTRL 0x00000002 -#define HDAC_GCTL_UNSOL 0x00000100 - -/* WAKEEN - Wake Enable */ -#define HDAC_WAKEEN_SDIWEN_MASK 0x7fff -#define HDAC_WAKEEN_SDIWEN_SHIFT 0 - -/* STATESTS - State Change Status */ -#define HDAC_STATESTS_SDIWAKE_MASK 0x7fff -#define HDAC_STATESTS_SDIWAKE_SHIFT 0 - -#define HDAC_STATESTS_SDIWAKE(statests, n) \ - (((((statests) & HDAC_STATESTS_SDIWAKE_MASK) >> \ - HDAC_STATESTS_SDIWAKE_SHIFT) >> (n)) & 0x0001) - -/* GSTS - Global Status */ -#define HDAC_GSTS_FSTS 0x0002 - -/* INTCTL - Interrut Control */ -#define HDAC_INTCTL_SIE_MASK 0x3fffffff -#define HDAC_INTCTL_SIE_SHIFT 0 -#define HDAC_INTCTL_CIE 0x40000000 -#define HDAC_INTCTL_GIE 0x80000000 - -/* INTSTS - Interrupt Status */ -#define HDAC_INTSTS_SIS_MASK 0x3fffffff -#define HDAC_INTSTS_SIS_SHIFT 0 -#define HDAC_INTSTS_CIS 0x40000000 -#define HDAC_INTSTS_GIS 0x80000000 - -/* SSYNC - Stream Synchronization */ -#define HDAC_SSYNC_SSYNC_MASK 0x3fffffff -#define HDAC_SSYNC_SSYNC_SHIFT 0 - -/* CORBWP - CORB Write Pointer */ -#define HDAC_CORBWP_CORBWP_MASK 0x00ff -#define HDAC_CORBWP_CORBWP_SHIFT 0 - -/* CORBRP - CORB Read Pointer */ -#define HDAC_CORBRP_CORBRP_MASK 0x00ff -#define HDAC_CORBRP_CORBRP_SHIFT 0 -#define HDAC_CORBRP_CORBRPRST 0x8000 - -/* CORBCTL - CORB Control */ -#define HDAC_CORBCTL_CMEIE 0x01 -#define HDAC_CORBCTL_CORBRUN 0x02 - -/* CORBSTS - CORB Status */ -#define HDAC_CORBSTS_CMEI 0x01 - -/* CORBSIZE - CORB Size */ -#define HDAC_CORBSIZE_CORBSIZE_MASK 0x03 -#define HDAC_CORBSIZE_CORBSIZE_SHIFT 0 -#define HDAC_CORBSIZE_CORBSZCAP_MASK 0xf0 -#define HDAC_CORBSIZE_CORBSZCAP_SHIFT 4 - -#define HDAC_CORBSIZE_CORBSIZE_2 0x00 -#define HDAC_CORBSIZE_CORBSIZE_16 0x01 -#define HDAC_CORBSIZE_CORBSIZE_256 0x02 - -#define HDAC_CORBSIZE_CORBSZCAP_2 0x10 -#define HDAC_CORBSIZE_CORBSZCAP_16 0x20 -#define HDAC_CORBSIZE_CORBSZCAP_256 0x40 - -#define HDAC_CORBSIZE_CORBSIZE(corbsize) \ - (((corbsize) & HDAC_CORBSIZE_CORBSIZE_MASK) >> HDAC_CORBSIZE_CORBSIZE_SHIFT) - -/* RIRBWP - RIRB Write Pointer */ -#define HDAC_RIRBWP_RIRBWP_MASK 0x00ff -#define HDAC_RIRBWP_RIRBWP_SHIFT 0 -#define HDAC_RIRBWP_RIRBWPRST 0x8000 - -/* RINTCTN - Response Interrupt Count */ -#define HDAC_RINTCNT_MASK 0x00ff -#define HDAC_RINTCNT_SHIFT 0 - -/* RIRBCTL - RIRB Control */ -#define HDAC_RIRBCTL_RINTCTL 0x01 -#define HDAC_RIRBCTL_RIRBDMAEN 0x02 -#define HDAC_RIRBCTL_RIRBOIC 0x04 - -/* RIRBSTS - RIRB Status */ -#define HDAC_RIRBSTS_RINTFL 0x01 -#define HDAC_RIRBSTS_RIRBOIS 0x04 - -/* RIRBSIZE - RIRB Size */ -#define HDAC_RIRBSIZE_RIRBSIZE_MASK 0x03 -#define HDAC_RIRBSIZE_RIRBSIZE_SHIFT 0 -#define HDAC_RIRBSIZE_RIRBSZCAP_MASK 0xf0 -#define HDAC_RIRBSIZE_RIRBSZCAP_SHIFT 4 - -#define HDAC_RIRBSIZE_RIRBSIZE_2 0x00 -#define HDAC_RIRBSIZE_RIRBSIZE_16 0x01 -#define HDAC_RIRBSIZE_RIRBSIZE_256 0x02 - -#define HDAC_RIRBSIZE_RIRBSZCAP_2 0x10 -#define HDAC_RIRBSIZE_RIRBSZCAP_16 0x20 -#define HDAC_RIRBSIZE_RIRBSZCAP_256 0x40 - -#define HDAC_RIRBSIZE_RIRBSIZE(rirbsize) \ - (((rirbsize) & HDAC_RIRBSIZE_RIRBSIZE_MASK) >> HDAC_RIRBSIZE_RIRBSIZE_SHIFT) - -/* DPLBASE - DMA Position Lower Base Address */ -#define HDAC_DPLBASE_DPLBASE_MASK 0xffffff80 -#define HDAC_DPLBASE_DPLBASE_SHIFT 7 -#define HDAC_DPLBASE_DPLBASE_DMAPBE 0x00000001 - -/* SDCTL - Stream Descriptor Control */ -#define HDAC_SDCTL_SRST 0x000001 -#define HDAC_SDCTL_RUN 0x000002 -#define HDAC_SDCTL_IOCE 0x000004 -#define HDAC_SDCTL_FEIE 0x000008 -#define HDAC_SDCTL_DEIE 0x000010 -#define HDAC_SDCTL2_STRIPE_MASK 0x03 -#define HDAC_SDCTL2_STRIPE_SHIFT 0 -#define HDAC_SDCTL2_TP 0x04 -#define HDAC_SDCTL2_DIR 0x08 -#define HDAC_SDCTL2_STRM_MASK 0xf0 -#define HDAC_SDCTL2_STRM_SHIFT 4 - -#define HDAC_SDSTS_DESE (1 << 4) -#define HDAC_SDSTS_FIFOE (1 << 3) -#define HDAC_SDSTS_BCIS (1 << 2) - -#endif /* _HDAC_REG_H_ */ Property changes on: head/usr.sbin/bhyve/hdac_reg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/hda_reg.h =================================================================== --- head/usr.sbin/bhyve/hda_reg.h (revision 349351) +++ head/usr.sbin/bhyve/hda_reg.h (nonexistent) @@ -1,1367 +0,0 @@ -/*- - * Copyright (c) 2006 Stephane E. Potvin - * 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 _HDA_REG_H_ -#define _HDA_REG_H_ - -/**************************************************************************** - * HDA Device Verbs - ****************************************************************************/ - -/* HDA Command */ -#define HDA_CMD_VERB_MASK 0x000fffff -#define HDA_CMD_VERB_SHIFT 0 -#define HDA_CMD_NID_MASK 0x0ff00000 -#define HDA_CMD_NID_SHIFT 20 -#define HDA_CMD_CAD_MASK 0xf0000000 -#define HDA_CMD_CAD_SHIFT 28 - -#define HDA_CMD_VERB_4BIT_SHIFT 16 -#define HDA_CMD_VERB_12BIT_SHIFT 8 - -#define HDA_CMD_VERB_4BIT(verb, payload) \ - (((verb) << HDA_CMD_VERB_4BIT_SHIFT) | (payload)) -#define HDA_CMD_4BIT(cad, nid, verb, payload) \ - (((cad) << HDA_CMD_CAD_SHIFT) | \ - ((nid) << HDA_CMD_NID_SHIFT) | \ - (HDA_CMD_VERB_4BIT((verb), (payload)))) - -#define HDA_CMD_VERB_12BIT(verb, payload) \ - (((verb) << HDA_CMD_VERB_12BIT_SHIFT) | (payload)) -#define HDA_CMD_12BIT(cad, nid, verb, payload) \ - (((cad) << HDA_CMD_CAD_SHIFT) | \ - ((nid) << HDA_CMD_NID_SHIFT) | \ - (HDA_CMD_VERB_12BIT((verb), (payload)))) - -/* Get Parameter */ -#define HDA_CMD_VERB_GET_PARAMETER 0xf00 - -#define HDA_CMD_GET_PARAMETER(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PARAMETER, (payload))) - -/* Connection Select Control */ -#define HDA_CMD_VERB_GET_CONN_SELECT_CONTROL 0xf01 -#define HDA_CMD_VERB_SET_CONN_SELECT_CONTROL 0x701 - -#define HDA_CMD_GET_CONN_SELECT_CONTROL(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONN_SELECT_CONTROL, 0x0)) -#define HDA_CMD_SET_CONNECTION_SELECT_CONTROL(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONN_SELECT_CONTROL, (payload))) - -/* Connection List Entry */ -#define HDA_CMD_VERB_GET_CONN_LIST_ENTRY 0xf02 - -#define HDA_CMD_GET_CONN_LIST_ENTRY(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONN_LIST_ENTRY, (payload))) - -#define HDA_CMD_GET_CONN_LIST_ENTRY_SIZE_SHORT 1 -#define HDA_CMD_GET_CONN_LIST_ENTRY_SIZE_LONG 2 - -/* Processing State */ -#define HDA_CMD_VERB_GET_PROCESSING_STATE 0xf03 -#define HDA_CMD_VERB_SET_PROCESSING_STATE 0x703 - -#define HDA_CMD_GET_PROCESSING_STATE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PROCESSING_STATE, 0x0)) -#define HDA_CMD_SET_PROCESSING_STATE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PROCESSING_STATE, (payload))) - -#define HDA_CMD_GET_PROCESSING_STATE_STATE_OFF 0x00 -#define HDA_CMD_GET_PROCESSING_STATE_STATE_ON 0x01 -#define HDA_CMD_GET_PROCESSING_STATE_STATE_BENIGN 0x02 - -/* Coefficient Index */ -#define HDA_CMD_VERB_GET_COEFF_INDEX 0xd -#define HDA_CMD_VERB_SET_COEFF_INDEX 0x5 - -#define HDA_CMD_GET_COEFF_INDEX(cad, nid) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_COEFF_INDEX, 0x0)) -#define HDA_CMD_SET_COEFF_INDEX(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_COEFF_INDEX, (payload))) - -/* Processing Coefficient */ -#define HDA_CMD_VERB_GET_PROCESSING_COEFF 0xc -#define HDA_CMD_VERB_SET_PROCESSING_COEFF 0x4 - -#define HDA_CMD_GET_PROCESSING_COEFF(cad, nid) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PROCESSING_COEFF, 0x0)) -#define HDA_CMD_SET_PROCESSING_COEFF(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PROCESSING_COEFF, (payload))) - -/* Amplifier Gain/Mute */ -#define HDA_CMD_VERB_GET_AMP_GAIN_MUTE 0xb -#define HDA_CMD_VERB_SET_AMP_GAIN_MUTE 0x3 - -#define HDA_CMD_GET_AMP_GAIN_MUTE(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_AMP_GAIN_MUTE, (payload))) -#define HDA_CMD_SET_AMP_GAIN_MUTE(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_AMP_GAIN_MUTE, (payload))) - -#define HDA_CMD_GET_AMP_GAIN_MUTE_INPUT 0x0000 -#define HDA_CMD_GET_AMP_GAIN_MUTE_OUTPUT 0x8000 -#define HDA_CMD_GET_AMP_GAIN_MUTE_RIGHT 0x0000 -#define HDA_CMD_GET_AMP_GAIN_MUTE_LEFT 0x2000 - -#define HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_MASK 0x00000008 -#define HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_SHIFT 7 -#define HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_MASK 0x00000007 -#define HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_SHIFT 0 - -#define HDA_CMD_GET_AMP_GAIN_MUTE_MUTE(rsp) \ - (((rsp) & HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_MASK) >> \ - HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_SHIFT) -#define HDA_CMD_GET_AMP_GAIN_MUTE_GAIN(rsp) \ - (((rsp) & HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_MASK) >> \ - HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_SHIFT) - -#define HDA_CMD_SET_AMP_GAIN_MUTE_OUTPUT 0x8000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_INPUT 0x4000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_LEFT 0x2000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT 0x1000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_MASK 0x0f00 -#define HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_SHIFT 8 -#define HDA_CMD_SET_AMP_GAIN_MUTE_MUTE 0x0080 -#define HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_MASK 0x0007 -#define HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_SHIFT 0 - -#define HDA_CMD_SET_AMP_GAIN_MUTE_INDEX(index) \ - (((index) << HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_SHIFT) & \ - HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_MASK) -#define HDA_CMD_SET_AMP_GAIN_MUTE_GAIN(index) \ - (((index) << HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_SHIFT) & \ - HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_MASK) - -/* Converter format */ -#define HDA_CMD_VERB_GET_CONV_FMT 0xa -#define HDA_CMD_VERB_SET_CONV_FMT 0x2 - -#define HDA_CMD_GET_CONV_FMT(cad, nid) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONV_FMT, 0x0)) -#define HDA_CMD_SET_CONV_FMT(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONV_FMT, (payload))) - -/* Digital Converter Control */ -#define HDA_CMD_VERB_GET_DIGITAL_CONV_FMT1 0xf0d -#define HDA_CMD_VERB_GET_DIGITAL_CONV_FMT2 0xf0e -#define HDA_CMD_VERB_SET_DIGITAL_CONV_FMT1 0x70d -#define HDA_CMD_VERB_SET_DIGITAL_CONV_FMT2 0x70e - -#define HDA_CMD_GET_DIGITAL_CONV_FMT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_DIGITAL_CONV_FMT1, 0x0)) -#define HDA_CMD_SET_DIGITAL_CONV_FMT1(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_DIGITAL_CONV_FMT1, (payload))) -#define HDA_CMD_SET_DIGITAL_CONV_FMT2(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_DIGITAL_CONV_FMT2, (payload))) - -#define HDA_CMD_GET_DIGITAL_CONV_FMT_CC_MASK 0x7f00 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_CC_SHIFT 8 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_L_MASK 0x0080 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_L_SHIFT 7 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_MASK 0x0040 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_SHIFT 6 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_MASK 0x0020 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_SHIFT 5 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_MASK 0x0010 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_SHIFT 4 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_MASK 0x0008 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_SHIFT 3 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_MASK 0x0004 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_SHIFT 2 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_V_MASK 0x0002 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_V_SHIFT 1 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_MASK 0x0001 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_SHIFT 0 - -#define HDA_CMD_GET_DIGITAL_CONV_FMT_CC(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_CC_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_CC_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_L(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_L_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_L_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRO(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_COPY(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRE(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_V(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_V_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_V_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_SHIFT) - -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_L 0x80 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_PRO 0x40 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_NAUDIO 0x20 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_COPY 0x10 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_PRE 0x08 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_VCFG 0x04 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_V 0x02 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_DIGEN 0x01 - -/* Power State */ -#define HDA_CMD_VERB_GET_POWER_STATE 0xf05 -#define HDA_CMD_VERB_SET_POWER_STATE 0x705 - -#define HDA_CMD_GET_POWER_STATE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_POWER_STATE, 0x0)) -#define HDA_CMD_SET_POWER_STATE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_POWER_STATE, (payload))) - -#define HDA_CMD_POWER_STATE_D0 0x00 -#define HDA_CMD_POWER_STATE_D1 0x01 -#define HDA_CMD_POWER_STATE_D2 0x02 -#define HDA_CMD_POWER_STATE_D3 0x03 - -#define HDA_CMD_POWER_STATE_ACT_MASK 0x000000f0 -#define HDA_CMD_POWER_STATE_ACT_SHIFT 4 -#define HDA_CMD_POWER_STATE_SET_MASK 0x0000000f -#define HDA_CMD_POWER_STATE_SET_SHIFT 0 - -#define HDA_CMD_GET_POWER_STATE_ACT(rsp) \ - (((rsp) & HDA_CMD_POWER_STATE_ACT_MASK) >> \ - HDA_CMD_POWER_STATE_ACT_SHIFT) -#define HDA_CMD_GET_POWER_STATE_SET(rsp) \ - (((rsp) & HDA_CMD_POWER_STATE_SET_MASK) >> \ - HDA_CMD_POWER_STATE_SET_SHIFT) - -#define HDA_CMD_SET_POWER_STATE_ACT(ps) \ - (((ps) << HDA_CMD_POWER_STATE_ACT_SHIFT) & \ - HDA_CMD_POWER_STATE_ACT_MASK) -#define HDA_CMD_SET_POWER_STATE_SET(ps) \ - (((ps) << HDA_CMD_POWER_STATE_SET_SHIFT) & \ - HDA_CMD_POWER_STATE_ACT_MASK) - -/* Converter Stream, Channel */ -#define HDA_CMD_VERB_GET_CONV_STREAM_CHAN 0xf06 -#define HDA_CMD_VERB_SET_CONV_STREAM_CHAN 0x706 - -#define HDA_CMD_GET_CONV_STREAM_CHAN(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONV_STREAM_CHAN, 0x0)) -#define HDA_CMD_SET_CONV_STREAM_CHAN(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONV_STREAM_CHAN, (payload))) - -#define HDA_CMD_CONV_STREAM_CHAN_STREAM_MASK 0x000000f0 -#define HDA_CMD_CONV_STREAM_CHAN_STREAM_SHIFT 4 -#define HDA_CMD_CONV_STREAM_CHAN_CHAN_MASK 0x0000000f -#define HDA_CMD_CONV_STREAM_CHAN_CHAN_SHIFT 0 - -#define HDA_CMD_GET_CONV_STREAM_CHAN_STREAM(rsp) \ - (((rsp) & HDA_CMD_CONV_STREAM_CHAN_STREAM_MASK) >> \ - HDA_CMD_CONV_STREAM_CHAN_STREAM_SHIFT) -#define HDA_CMD_GET_CONV_STREAM_CHAN_CHAN(rsp) \ - (((rsp) & HDA_CMD_CONV_STREAM_CHAN_CHAN_MASK) >> \ - HDA_CMD_CONV_STREAM_CHAN_CHAN_SHIFT) - -#define HDA_CMD_SET_CONV_STREAM_CHAN_STREAM(param) \ - (((param) << HDA_CMD_CONV_STREAM_CHAN_STREAM_SHIFT) & \ - HDA_CMD_CONV_STREAM_CHAN_STREAM_MASK) -#define HDA_CMD_SET_CONV_STREAM_CHAN_CHAN(param) \ - (((param) << HDA_CMD_CONV_STREAM_CHAN_CHAN_SHIFT) & \ - HDA_CMD_CONV_STREAM_CHAN_CHAN_MASK) - -/* Input Converter SDI Select */ -#define HDA_CMD_VERB_GET_INPUT_CONVERTER_SDI_SELECT 0xf04 -#define HDA_CMD_VERB_SET_INPUT_CONVERTER_SDI_SELECT 0x704 - -#define HDA_CMD_GET_INPUT_CONVERTER_SDI_SELECT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_INPUT_CONVERTER_SDI_SELECT, 0x0)) -#define HDA_CMD_SET_INPUT_CONVERTER_SDI_SELECT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_INPUT_CONVERTER_SDI_SELECT, (payload))) - -/* Pin Widget Control */ -#define HDA_CMD_VERB_GET_PIN_WIDGET_CTRL 0xf07 -#define HDA_CMD_VERB_SET_PIN_WIDGET_CTRL 0x707 - -#define HDA_CMD_GET_PIN_WIDGET_CTRL(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PIN_WIDGET_CTRL, 0x0)) -#define HDA_CMD_SET_PIN_WIDGET_CTRL(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PIN_WIDGET_CTRL, (payload))) - -#define HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_MASK 0x00000080 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_SHIFT 7 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_MASK 0x00000040 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT 6 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_MASK 0x00000020 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT 5 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK 0x00000007 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT 0 - -#define HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_MASK) >> \ - HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_SHIFT) -#define HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_MASK) >> \ - HDA_GET_CMD_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT) -#define HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_MASK) >> \ - HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT) -#define HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) >> \ - HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT) - -#define HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE 0x80 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE 0x40 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE 0x20 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK 0x07 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT 0 - -#define HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(param) \ - (((param) << HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT) & \ - HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) - -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_HIZ 0 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50 1 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_GROUND 2 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80 4 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100 5 - -/* Unsolicited Response */ -#define HDA_CMD_VERB_GET_UNSOLICITED_RESPONSE 0xf08 -#define HDA_CMD_VERB_SET_UNSOLICITED_RESPONSE 0x708 - -#define HDA_CMD_GET_UNSOLICITED_RESPONSE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_UNSOLICITED_RESPONSE, 0x0)) -#define HDA_CMD_SET_UNSOLICITED_RESPONSE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_UNSOLICITED_RESPONSE, (payload))) - -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_MASK 0x00000080 -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_SHIFT 7 -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_MASK 0x0000001f -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_SHIFT 0 - -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_MASK) >> \ - HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_SHIFT) -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG(rsp) \ - (((rsp) & HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_MASK) >> \ - HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_SHIFT) - -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE 0x80 -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK 0x3f -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_SHIFT 0 - -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG(param) \ - (((param) << HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_SHIFT) & \ - HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK) - -/* Pin Sense */ -#define HDA_CMD_VERB_GET_PIN_SENSE 0xf09 -#define HDA_CMD_VERB_SET_PIN_SENSE 0x709 - -#define HDA_CMD_GET_PIN_SENSE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PIN_SENSE, 0x0)) -#define HDA_CMD_SET_PIN_SENSE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PIN_SENSE, (payload))) - -#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT 0x80000000 -#define HDA_CMD_GET_PIN_SENSE_ELD_VALID 0x40000000 -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK 0x7fffffff -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT 0 - -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK) >> \ - HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT) - -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_INVALID 0x7fffffff - -#define HDA_CMD_SET_PIN_SENSE_LEFT_CHANNEL 0x00 -#define HDA_CMD_SET_PIN_SENSE_RIGHT_CHANNEL 0x01 - -/* EAPD/BTL Enable */ -#define HDA_CMD_VERB_GET_EAPD_BTL_ENABLE 0xf0c -#define HDA_CMD_VERB_SET_EAPD_BTL_ENABLE 0x70c - -#define HDA_CMD_GET_EAPD_BTL_ENABLE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_EAPD_BTL_ENABLE, 0x0)) -#define HDA_CMD_SET_EAPD_BTL_ENABLE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_EAPD_BTL_ENABLE, (payload))) - -#define HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_MASK 0x00000004 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_SHIFT 2 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_MASK 0x00000002 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_SHIFT 1 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_MASK 0x00000001 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_SHIFT 0 - -#define HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP(rsp) \ - (((rsp) & HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_MASK) >> \ - HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_SHIFT) -#define HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD(rsp) \ - (((rsp) & HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_MASK) >> \ - HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_SHIFT) -#define HDA_CMD_GET_EAPD_BTL_ENABLE_BTL(rsp) \ - (((rsp) & HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_MASK) >> \ - HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_SHIFT) - -#define HDA_CMD_SET_EAPD_BTL_ENABLE_LR_SWAP 0x04 -#define HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD 0x02 -#define HDA_CMD_SET_EAPD_BTL_ENABLE_BTL 0x01 - -/* GPI Data */ -#define HDA_CMD_VERB_GET_GPI_DATA 0xf10 -#define HDA_CMD_VERB_SET_GPI_DATA 0x710 - -#define HDA_CMD_GET_GPI_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_DATA, 0x0)) -#define HDA_CMD_SET_GPI_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_DATA, (payload))) - -/* GPI Wake Enable Mask */ -#define HDA_CMD_VERB_GET_GPI_WAKE_ENABLE_MASK 0xf11 -#define HDA_CMD_VERB_SET_GPI_WAKE_ENABLE_MASK 0x711 - -#define HDA_CMD_GET_GPI_WAKE_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_WAKE_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPI_WAKE_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_WAKE_ENABLE_MASK, (payload))) - -/* GPI Unsolicited Enable Mask */ -#define HDA_CMD_VERB_GET_GPI_UNSOLICITED_ENABLE_MASK 0xf12 -#define HDA_CMD_VERB_SET_GPI_UNSOLICITED_ENABLE_MASK 0x712 - -#define HDA_CMD_GET_GPI_UNSOLICITED_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_UNSOLICITED_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPI_UNSOLICITED_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_UNSOLICITED_ENABLE_MASK, (payload))) - -/* GPI Sticky Mask */ -#define HDA_CMD_VERB_GET_GPI_STICKY_MASK 0xf13 -#define HDA_CMD_VERB_SET_GPI_STICKY_MASK 0x713 - -#define HDA_CMD_GET_GPI_STICKY_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_STICKY_MASK, 0x0)) -#define HDA_CMD_SET_GPI_STICKY_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_STICKY_MASK, (payload))) - -/* GPO Data */ -#define HDA_CMD_VERB_GET_GPO_DATA 0xf14 -#define HDA_CMD_VERB_SET_GPO_DATA 0x714 - -#define HDA_CMD_GET_GPO_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPO_DATA, 0x0)) -#define HDA_CMD_SET_GPO_DATA(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPO_DATA, (payload))) - -/* GPIO Data */ -#define HDA_CMD_VERB_GET_GPIO_DATA 0xf15 -#define HDA_CMD_VERB_SET_GPIO_DATA 0x715 - -#define HDA_CMD_GET_GPIO_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_DATA, 0x0)) -#define HDA_CMD_SET_GPIO_DATA(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_DATA, (payload))) - -/* GPIO Enable Mask */ -#define HDA_CMD_VERB_GET_GPIO_ENABLE_MASK 0xf16 -#define HDA_CMD_VERB_SET_GPIO_ENABLE_MASK 0x716 - -#define HDA_CMD_GET_GPIO_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_ENABLE_MASK, (payload))) - -/* GPIO Direction */ -#define HDA_CMD_VERB_GET_GPIO_DIRECTION 0xf17 -#define HDA_CMD_VERB_SET_GPIO_DIRECTION 0x717 - -#define HDA_CMD_GET_GPIO_DIRECTION(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_DIRECTION, 0x0)) -#define HDA_CMD_SET_GPIO_DIRECTION(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_DIRECTION, (payload))) - -/* GPIO Wake Enable Mask */ -#define HDA_CMD_VERB_GET_GPIO_WAKE_ENABLE_MASK 0xf18 -#define HDA_CMD_VERB_SET_GPIO_WAKE_ENABLE_MASK 0x718 - -#define HDA_CMD_GET_GPIO_WAKE_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_WAKE_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_WAKE_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_WAKE_ENABLE_MASK, (payload))) - -/* GPIO Unsolicited Enable Mask */ -#define HDA_CMD_VERB_GET_GPIO_UNSOLICITED_ENABLE_MASK 0xf19 -#define HDA_CMD_VERB_SET_GPIO_UNSOLICITED_ENABLE_MASK 0x719 - -#define HDA_CMD_GET_GPIO_UNSOLICITED_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_UNSOLICITED_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_UNSOLICITED_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_UNSOLICITED_ENABLE_MASK, (payload))) - -/* GPIO_STICKY_MASK */ -#define HDA_CMD_VERB_GET_GPIO_STICKY_MASK 0xf1a -#define HDA_CMD_VERB_SET_GPIO_STICKY_MASK 0x71a - -#define HDA_CMD_GET_GPIO_STICKY_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_STICKY_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_STICKY_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_STICKY_MASK, (payload))) - -/* Beep Generation */ -#define HDA_CMD_VERB_GET_BEEP_GENERATION 0xf0a -#define HDA_CMD_VERB_SET_BEEP_GENERATION 0x70a - -#define HDA_CMD_GET_BEEP_GENERATION(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_BEEP_GENERATION, 0x0)) -#define HDA_CMD_SET_BEEP_GENERATION(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_BEEP_GENERATION, (payload))) - -/* Volume Knob */ -#define HDA_CMD_VERB_GET_VOLUME_KNOB 0xf0f -#define HDA_CMD_VERB_SET_VOLUME_KNOB 0x70f - -#define HDA_CMD_GET_VOLUME_KNOB(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_VOLUME_KNOB, 0x0)) -#define HDA_CMD_SET_VOLUME_KNOB(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_VOLUME_KNOB, (payload))) - -/* Subsystem ID */ -#define HDA_CMD_VERB_GET_SUBSYSTEM_ID 0xf20 -#define HDA_CMD_VERB_SET_SUSBYSTEM_ID1 0x720 -#define HDA_CMD_VERB_SET_SUBSYSTEM_ID2 0x721 -#define HDA_CMD_VERB_SET_SUBSYSTEM_ID3 0x722 -#define HDA_CMD_VERB_SET_SUBSYSTEM_ID4 0x723 - -#define HDA_CMD_GET_SUBSYSTEM_ID(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_SUBSYSTEM_ID, 0x0)) -#define HDA_CMD_SET_SUBSYSTEM_ID1(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID1, (payload))) -#define HDA_CMD_SET_SUBSYSTEM_ID2(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID2, (payload))) -#define HDA_CMD_SET_SUBSYSTEM_ID3(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID3, (payload))) -#define HDA_CMD_SET_SUBSYSTEM_ID4(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID4, (payload))) - -/* Configuration Default */ -#define HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT 0xf1c -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT1 0x71c -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT2 0x71d -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT3 0x71e -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT4 0x71f - -#define HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT, 0x0)) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT1(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT1, (payload))) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT2(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT2, (payload))) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT3(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT3, (payload))) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT4(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT4, (payload))) - -/* Stripe Control */ -#define HDA_CMD_VERB_GET_STRIPE_CONTROL 0xf24 -#define HDA_CMD_VERB_SET_STRIPE_CONTROL 0x724 - -#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_STRIPE_CONTROL, 0x0)) -#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_STRIPE_CONTROL, (payload))) - -/* Channel Count Control */ -#define HDA_CMD_VERB_GET_CONV_CHAN_COUNT 0xf2d -#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT 0x72d - -#define HDA_CMD_GET_CONV_CHAN_COUNT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONV_CHAN_COUNT, 0x0)) -#define HDA_CMD_SET_CONV_CHAN_COUNT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE 0xf2e - -#define HDA_CMD_GET_HDMI_DIP_SIZE(cad, nid, arg) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_SIZE, (arg))) - -#define HDA_CMD_VERB_GET_HDMI_ELDD 0xf2f - -#define HDA_CMD_GET_HDMI_ELDD(cad, nid, off) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_ELDD, (off))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX 0xf30 -#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX 0x730 - -#define HDA_CMD_GET_HDMI_DIP_INDEX(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_INDEX, 0x0)) -#define HDA_CMD_SET_HDMI_DIP_INDEX(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_DIP_INDEX, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_DATA 0xf31 -#define HDA_CMD_VERB_SET_HDMI_DIP_DATA 0x731 - -#define HDA_CMD_GET_HDMI_DIP_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_DATA, 0x0)) -#define HDA_CMD_SET_HDMI_DIP_DATA(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_DIP_DATA, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT 0xf32 -#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT 0x732 - -#define HDA_CMD_GET_HDMI_DIP_XMIT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_XMIT, 0x0)) -#define HDA_CMD_SET_HDMI_DIP_XMIT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_DIP_XMIT, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_CP_CTRL 0xf33 -#define HDA_CMD_VERB_SET_HDMI_CP_CTRL 0x733 - -#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT 0xf34 -#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT 0x734 - -#define HDA_CMD_GET_HDMI_CHAN_SLOT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_CHAN_SLOT, 0x0)) -#define HDA_CMD_SET_HDMI_CHAN_SLOT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_CHAN_SLOT, (payload))) - -#define HDA_HDMI_CODING_TYPE_REF_STREAM_HEADER 0 -#define HDA_HDMI_CODING_TYPE_LPCM 1 -#define HDA_HDMI_CODING_TYPE_AC3 2 -#define HDA_HDMI_CODING_TYPE_MPEG1 3 -#define HDA_HDMI_CODING_TYPE_MP3 4 -#define HDA_HDMI_CODING_TYPE_MPEG2 5 -#define HDA_HDMI_CODING_TYPE_AACLC 6 -#define HDA_HDMI_CODING_TYPE_DTS 7 -#define HDA_HDMI_CODING_TYPE_ATRAC 8 -#define HDA_HDMI_CODING_TYPE_SACD 9 -#define HDA_HDMI_CODING_TYPE_EAC3 10 -#define HDA_HDMI_CODING_TYPE_DTS_HD 11 -#define HDA_HDMI_CODING_TYPE_MLP 12 -#define HDA_HDMI_CODING_TYPE_DST 13 -#define HDA_HDMI_CODING_TYPE_WMAPRO 14 -#define HDA_HDMI_CODING_TYPE_REF_CTX 15 - -/* Function Reset */ -#define HDA_CMD_VERB_FUNCTION_RESET 0x7ff - -#define HDA_CMD_FUNCTION_RESET(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_FUNCTION_RESET, 0x0)) - - -/**************************************************************************** - * HDA Device Parameters - ****************************************************************************/ - -/* Vendor ID */ -#define HDA_PARAM_VENDOR_ID 0x00 - -#define HDA_PARAM_VENDOR_ID_VENDOR_ID_MASK 0xffff0000 -#define HDA_PARAM_VENDOR_ID_VENDOR_ID_SHIFT 16 -#define HDA_PARAM_VENDOR_ID_DEVICE_ID_MASK 0x0000ffff -#define HDA_PARAM_VENDOR_ID_DEVICE_ID_SHIFT 0 - -#define HDA_PARAM_VENDOR_ID_VENDOR_ID(param) \ - (((param) & HDA_PARAM_VENDOR_ID_VENDOR_ID_MASK) >> \ - HDA_PARAM_VENDOR_ID_VENDOR_ID_SHIFT) -#define HDA_PARAM_VENDOR_ID_DEVICE_ID(param) \ - (((param) & HDA_PARAM_VENDOR_ID_DEVICE_ID_MASK) >> \ - HDA_PARAM_VENDOR_ID_DEVICE_ID_SHIFT) - -/* Revision ID */ -#define HDA_PARAM_REVISION_ID 0x02 - -#define HDA_PARAM_REVISION_ID_MAJREV_MASK 0x00f00000 -#define HDA_PARAM_REVISION_ID_MAJREV_SHIFT 20 -#define HDA_PARAM_REVISION_ID_MINREV_MASK 0x000f0000 -#define HDA_PARAM_REVISION_ID_MINREV_SHIFT 16 -#define HDA_PARAM_REVISION_ID_REVISION_ID_MASK 0x0000ff00 -#define HDA_PARAM_REVISION_ID_REVISION_ID_SHIFT 8 -#define HDA_PARAM_REVISION_ID_STEPPING_ID_MASK 0x000000ff -#define HDA_PARAM_REVISION_ID_STEPPING_ID_SHIFT 0 - -#define HDA_PARAM_REVISION_ID_MAJREV(param) \ - (((param) & HDA_PARAM_REVISION_ID_MAJREV_MASK) >> \ - HDA_PARAM_REVISION_ID_MAJREV_SHIFT) -#define HDA_PARAM_REVISION_ID_MINREV(param) \ - (((param) & HDA_PARAM_REVISION_ID_MINREV_MASK) >> \ - HDA_PARAM_REVISION_ID_MINREV_SHIFT) -#define HDA_PARAM_REVISION_ID_REVISION_ID(param) \ - (((param) & HDA_PARAM_REVISION_ID_REVISION_ID_MASK) >> \ - HDA_PARAM_REVISION_ID_REVISION_ID_SHIFT) -#define HDA_PARAM_REVISION_ID_STEPPING_ID(param) \ - (((param) & HDA_PARAM_REVISION_ID_STEPPING_ID_MASK) >> \ - HDA_PARAM_REVISION_ID_STEPPING_ID_SHIFT) - -/* Subordinate Node Cound */ -#define HDA_PARAM_SUB_NODE_COUNT 0x04 - -#define HDA_PARAM_SUB_NODE_COUNT_START_MASK 0x00ff0000 -#define HDA_PARAM_SUB_NODE_COUNT_START_SHIFT 16 -#define HDA_PARAM_SUB_NODE_COUNT_TOTAL_MASK 0x000000ff -#define HDA_PARAM_SUB_NODE_COUNT_TOTAL_SHIFT 0 - -#define HDA_PARAM_SUB_NODE_COUNT_START(param) \ - (((param) & HDA_PARAM_SUB_NODE_COUNT_START_MASK) >> \ - HDA_PARAM_SUB_NODE_COUNT_START_SHIFT) -#define HDA_PARAM_SUB_NODE_COUNT_TOTAL(param) \ - (((param) & HDA_PARAM_SUB_NODE_COUNT_TOTAL_MASK) >> \ - HDA_PARAM_SUB_NODE_COUNT_TOTAL_SHIFT) - -/* Function Group Type */ -#define HDA_PARAM_FCT_GRP_TYPE 0x05 - -#define HDA_PARAM_FCT_GRP_TYPE_UNSOL_MASK 0x00000100 -#define HDA_PARAM_FCT_GRP_TYPE_UNSOL_SHIFT 8 -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MASK 0x000000ff -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_SHIFT 0 - -#define HDA_PARAM_FCT_GRP_TYPE_UNSOL(param) \ - (((param) & HDA_PARAM_FCT_GRP_TYPE_UNSOL_MASK) >> \ - HDA_PARAM_FCT_GROUP_TYPE_UNSOL_SHIFT) -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE(param) \ - (((param) & HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MASK) >> \ - HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_SHIFT) - -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO 0x01 -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MODEM 0x02 - -/* Audio Function Group Capabilities */ -#define HDA_PARAM_AUDIO_FCT_GRP_CAP 0x08 - -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_MASK 0x00010000 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_SHIFT 16 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_MASK 0x00000f00 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_SHIFT 8 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_MASK 0x0000000f -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_SHIFT 0 - -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN(param) \ - (((param) & HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_MASK) >> \ - HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_SHIFT) -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY(param) \ - (((param) & HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_MASK) >> \ - HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_SHIFT) -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY(param) \ - (((param) & HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_MASK) >> \ - HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_SHIFT) - -/* Audio Widget Capabilities */ -#define HDA_PARAM_AUDIO_WIDGET_CAP 0x09 - -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK 0x00f00000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT 20 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK 0x000f0000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT 16 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK 0x0000e000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT 13 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK 0x00001000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT 12 -#define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK 0x00000800 -#define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT 11 -#define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK 0x00000400 -#define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_SHIFT 10 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK 0x00000200 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_SHIFT 9 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_MASK 0x00000100 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT 8 -#define HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_MASK 0x00000080 -#define HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_SHIFT 7 -#define HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_MASK 0x00000040 -#define HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_SHIFT 6 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_MASK 0x00000020 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_SHIFT 5 -#define HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_MASK 0x00000010 -#define HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT 4 -#define HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_MASK 0x00000008 -#define HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT 3 -#define HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_MASK 0x00000004 -#define HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT 2 -#define HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_MASK 0x00000002 -#define HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT 1 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK 0x00000001 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT 0 - -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_CC(param) \ - ((((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK) >> \ - (HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT - 1)) | \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT)) -#define HDA_PARAM_AUDIO_WIDGET_CAP_CP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT) - -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT 0x0 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT 0x1 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER 0x2 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR 0x3 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX 0x4 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET 0x5 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET 0x6 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET 0x7 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET 0xf - -/* Supported PCM Size, Rates */ - -#define HDA_PARAM_SUPP_PCM_SIZE_RATE 0x0a - -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_MASK 0x00100000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_SHIFT 20 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_MASK 0x00080000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_SHIFT 19 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_MASK 0x00040000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_SHIFT 18 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_MASK 0x00020000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_SHIFT 17 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_MASK 0x00010000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_SHIFT 16 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_MASK 0x00000001 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_SHIFT 0 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_MASK 0x00000002 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_SHIFT 1 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_MASK 0x00000004 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_SHIFT 2 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_MASK 0x00000008 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_SHIFT 3 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_MASK 0x00000010 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_SHIFT 4 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_MASK 0x00000020 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_SHIFT 5 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_MASK 0x00000040 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_SHIFT 6 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_MASK 0x00000080 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_SHIFT 7 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_MASK 0x00000100 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_SHIFT 8 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_MASK 0x00000200 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_SHIFT 9 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_MASK 0x00000400 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_SHIFT 10 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_MASK 0x00000800 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_SHIFT 11 - -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_SHIFT) - -/* Supported Stream Formats */ -#define HDA_PARAM_SUPP_STREAM_FORMATS 0x0b - -#define HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK 0x00000004 -#define HDA_PARAM_SUPP_STREAM_FORMATS_AC3_SHIFT 2 -#define HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_MASK 0x00000002 -#define HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_SHIFT 1 -#define HDA_PARAM_SUPP_STREAM_FORMATS_PCM_MASK 0x00000001 -#define HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT 0 - -#define HDA_PARAM_SUPP_STREAM_FORMATS_AC3(param) \ - (((param) & HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK) >> \ - HDA_PARAM_SUPP_STREAM_FORMATS_AC3_SHIFT) -#define HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(param) \ - (((param) & HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_MASK) >> \ - HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_SHIFT) -#define HDA_PARAM_SUPP_STREAM_FORMATS_PCM(param) \ - (((param) & HDA_PARAM_SUPP_STREAM_FORMATS_PCM_MASK) >> \ - HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT) - -/* Pin Capabilities */ -#define HDA_PARAM_PIN_CAP 0x0c - -#define HDA_PARAM_PIN_CAP_HBR_MASK 0x08000000 -#define HDA_PARAM_PIN_CAP_HBR_SHIFT 27 -#define HDA_PARAM_PIN_CAP_DP_MASK 0x01000000 -#define HDA_PARAM_PIN_CAP_DP_SHIFT 24 -#define HDA_PARAM_PIN_CAP_EAPD_CAP_MASK 0x00010000 -#define HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT 16 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_MASK 0x0000ff00 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_SHIFT 8 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK 0x00002000 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_100_SHIFT 13 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK 0x00001000 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_80_SHIFT 12 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_MASK 0x00000400 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_SHIFT 10 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK 0x00000200 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT 9 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK 0x00000100 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT 8 -#define HDA_PARAM_PIN_CAP_HDMI_MASK 0x00000080 -#define HDA_PARAM_PIN_CAP_HDMI_SHIFT 7 -#define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK 0x00000040 -#define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT 6 -#define HDA_PARAM_PIN_CAP_INPUT_CAP_MASK 0x00000020 -#define HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT 5 -#define HDA_PARAM_PIN_CAP_OUTPUT_CAP_MASK 0x00000010 -#define HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT 4 -#define HDA_PARAM_PIN_CAP_HEADPHONE_CAP_MASK 0x00000008 -#define HDA_PARAM_PIN_CAP_HEADPHONE_CAP_SHIFT 3 -#define HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_MASK 0x00000004 -#define HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT 2 -#define HDA_PARAM_PIN_CAP_TRIGGER_REQD_MASK 0x00000002 -#define HDA_PARAM_PIN_CAP_TRIGGER_REQD_SHIFT 1 -#define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK 0x00000001 -#define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT 0 - -#define HDA_PARAM_PIN_CAP_HBR(param) \ - (((param) & HDA_PARAM_PIN_CAP_HBR_MASK) >> \ - HDA_PARAM_PIN_CAP_HBR_SHIFT) -#define HDA_PARAM_PIN_CAP_DP(param) \ - (((param) & HDA_PARAM_PIN_CAP_DP_MASK) >> \ - HDA_PARAM_PIN_CAP_DP_SHIFT) -#define HDA_PARAM_PIN_CAP_EAPD_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_EAPD_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_100(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_100_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_80(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_80_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_50(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT) -#define HDA_PARAM_PIN_CAP_HDMI(param) \ - (((param) & HDA_PARAM_PIN_CAP_HDMI_MASK) >> \ - HDA_PARAM_PIN_CAP_HDMI_SHIFT) -#define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(param) \ - (((param) & HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK) >> \ - HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT) -#define HDA_PARAM_PIN_CAP_INPUT_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_INPUT_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_OUTPUT_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_OUTPUT_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_HEADPHONE_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_HEADPHONE_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_HEADPHONE_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_TRIGGER_REQD(param) \ - (((param) & HDA_PARAM_PIN_CAP_TRIGGER_REQD_MASK) >> \ - HDA_PARAM_PIN_CAP_TRIGGER_REQD_SHIFT) -#define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT) - -/* Input Amplifier Capabilities */ -#define HDA_PARAM_INPUT_AMP_CAP 0x0d - -#define HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_MASK 0x80000000 -#define HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_SHIFT 31 -#define HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_MASK 0x007f0000 -#define HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_SHIFT 16 -#define HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_MASK 0x00007f00 -#define HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_SHIFT 8 -#define HDA_PARAM_INPUT_AMP_CAP_OFFSET_MASK 0x0000007f -#define HDA_PARAM_INPUT_AMP_CAP_OFFSET_SHIFT 0 - -#define HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_SHIFT) -#define HDA_PARAM_INPUT_AMP_CAP_STEPSIZE(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_SHIFT) -#define HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_SHIFT) -#define HDA_PARAM_INPUT_AMP_CAP_OFFSET(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_OFFSET_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_OFFSET_SHIFT) - -/* Output Amplifier Capabilities */ -#define HDA_PARAM_OUTPUT_AMP_CAP 0x12 - -#define HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_MASK 0x80000000 -#define HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT 31 -#define HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_MASK 0x007f0000 -#define HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT 16 -#define HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_MASK 0x00007f00 -#define HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT 8 -#define HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_MASK 0x0000007f -#define HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT 0 - -#define HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT) -#define HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) -#define HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) -#define HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT) - -/* Connection List Length */ -#define HDA_PARAM_CONN_LIST_LENGTH 0x0e - -#define HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_MASK 0x00000080 -#define HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_SHIFT 7 -#define HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_MASK 0x0000007f -#define HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_SHIFT 0 - -#define HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM(param) \ - (((param) & HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_MASK) >> \ - HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_SHIFT) -#define HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH(param) \ - (((param) & HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_MASK) >> \ - HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_SHIFT) - -/* Supported Power States */ -#define HDA_PARAM_SUPP_POWER_STATES 0x0f - -#define HDA_PARAM_SUPP_POWER_STATES_D3_MASK 0x00000008 -#define HDA_PARAM_SUPP_POWER_STATES_D3_SHIFT 3 -#define HDA_PARAM_SUPP_POWER_STATES_D2_MASK 0x00000004 -#define HDA_PARAM_SUPP_POWER_STATES_D2_SHIFT 2 -#define HDA_PARAM_SUPP_POWER_STATES_D1_MASK 0x00000002 -#define HDA_PARAM_SUPP_POWER_STATES_D1_SHIFT 1 -#define HDA_PARAM_SUPP_POWER_STATES_D0_MASK 0x00000001 -#define HDA_PARAM_SUPP_POWER_STATES_D0_SHIFT 0 - -#define HDA_PARAM_SUPP_POWER_STATES_D3(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D3_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D3_SHIFT) -#define HDA_PARAM_SUPP_POWER_STATES_D2(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D2_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D2_SHIFT) -#define HDA_PARAM_SUPP_POWER_STATES_D1(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D1_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D1_SHIFT) -#define HDA_PARAM_SUPP_POWER_STATES_D0(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D0_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D0_SHIFT) - -/* Processing Capabilities */ -#define HDA_PARAM_PROCESSING_CAP 0x10 - -#define HDA_PARAM_PROCESSING_CAP_NUMCOEFF_MASK 0x0000ff00 -#define HDA_PARAM_PROCESSING_CAP_NUMCOEFF_SHIFT 8 -#define HDA_PARAM_PROCESSING_CAP_BENIGN_MASK 0x00000001 -#define HDA_PARAM_PROCESSING_CAP_BENIGN_SHIFT 0 - -#define HDA_PARAM_PROCESSING_CAP_NUMCOEFF(param) \ - (((param) & HDA_PARAM_PROCESSING_CAP_NUMCOEFF_MASK) >> \ - HDA_PARAM_PROCESSING_CAP_NUMCOEFF_SHIFT) -#define HDA_PARAM_PROCESSING_CAP_BENIGN(param) \ - (((param) & HDA_PARAM_PROCESSING_CAP_BENIGN_MASK) >> \ - HDA_PARAM_PROCESSING_CAP_BENIGN_SHIFT) - -/* GPIO Count */ -#define HDA_PARAM_GPIO_COUNT 0x11 - -#define HDA_PARAM_GPIO_COUNT_GPI_WAKE_MASK 0x80000000 -#define HDA_PARAM_GPIO_COUNT_GPI_WAKE_SHIFT 31 -#define HDA_PARAM_GPIO_COUNT_GPI_UNSOL_MASK 0x40000000 -#define HDA_PARAM_GPIO_COUNT_GPI_UNSOL_SHIFT 30 -#define HDA_PARAM_GPIO_COUNT_NUM_GPI_MASK 0x00ff0000 -#define HDA_PARAM_GPIO_COUNT_NUM_GPI_SHIFT 16 -#define HDA_PARAM_GPIO_COUNT_NUM_GPO_MASK 0x0000ff00 -#define HDA_PARAM_GPIO_COUNT_NUM_GPO_SHIFT 8 -#define HDA_PARAM_GPIO_COUNT_NUM_GPIO_MASK 0x000000ff -#define HDA_PARAM_GPIO_COUNT_NUM_GPIO_SHIFT 0 - -#define HDA_PARAM_GPIO_COUNT_GPI_WAKE(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_GPI_WAKE_MASK) >> \ - HDA_PARAM_GPIO_COUNT_GPI_WAKE_SHIFT) -#define HDA_PARAM_GPIO_COUNT_GPI_UNSOL(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_GPI_UNSOL_MASK) >> \ - HDA_PARAM_GPIO_COUNT_GPI_UNSOL_SHIFT) -#define HDA_PARAM_GPIO_COUNT_NUM_GPI(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_NUM_GPI_MASK) >> \ - HDA_PARAM_GPIO_COUNT_NUM_GPI_SHIFT) -#define HDA_PARAM_GPIO_COUNT_NUM_GPO(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_NUM_GPO_MASK) >> \ - HDA_PARAM_GPIO_COUNT_NUM_GPO_SHIFT) -#define HDA_PARAM_GPIO_COUNT_NUM_GPIO(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_NUM_GPIO_MASK) >> \ - HDA_PARAM_GPIO_COUNT_NUM_GPIO_SHIFT) - -/* Volume Knob Capabilities */ -#define HDA_PARAM_VOLUME_KNOB_CAP 0x13 - -#define HDA_PARAM_VOLUME_KNOB_CAP_DELTA_MASK 0x00000080 -#define HDA_PARAM_VOLUME_KNOB_CAP_DELTA_SHIFT 7 -#define HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_MASK 0x0000007f -#define HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_SHIFT 0 - -#define HDA_PARAM_VOLUME_KNOB_CAP_DELTA(param) \ - (((param) & HDA_PARAM_VOLUME_KNOB_CAP_DELTA_MASK) >> \ - HDA_PARAM_VOLUME_KNOB_CAP_DELTA_SHIFT) -#define HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS(param) \ - (((param) & HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_MASK) >> \ - HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_SHIFT) - - -#define HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK 0x0000000f -#define HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT 0 -#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK 0x000000f0 -#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT 4 -#define HDA_CONFIG_DEFAULTCONF_MISC_MASK 0x00000f00 -#define HDA_CONFIG_DEFAULTCONF_MISC_SHIFT 8 -#define HDA_CONFIG_DEFAULTCONF_COLOR_MASK 0x0000f000 -#define HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT 12 -#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK 0x000f0000 -#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT 16 -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MASK 0x00f00000 -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT 20 -#define HDA_CONFIG_DEFAULTCONF_LOCATION_MASK 0x3f000000 -#define HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT 24 -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK 0xc0000000 -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT 30 - -#define HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_MISC(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_MISC_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_MISC_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_COLOR(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_COLOR_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_DEVICE(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_LOCATION(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_LOCATION_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT) - -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK (0<<30) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE (1<<30) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED (2<<30) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_BOTH (3<<30) - -#define HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT (0<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER (1<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT (2<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_CD (3<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT (4<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT (5<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_LINE (6<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_HANDSET (7<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN (8<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_AUX (9<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN (10<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_TELEPHONY (11<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN (12<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN (13<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_OTHER (15<<20) - -#endif /* _HDA_REG_H_ */ Property changes on: head/usr.sbin/bhyve/hda_reg.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/bhyve/Makefile =================================================================== --- head/usr.sbin/bhyve/Makefile (revision 349351) +++ head/usr.sbin/bhyve/Makefile (revision 349352) @@ -1,100 +1,97 @@ # # $FreeBSD$ # .include CFLAGS+=-I${SRCTOP}/sys .PATH: ${SRCTOP}/sys/cam/ctl PROG= bhyve PACKAGE= bhyve MAN= bhyve.8 BHYVE_SYSDIR?=${SRCTOP} SRCS= \ atkbdc.c \ acpi.c \ - audio.c \ bhyvegc.c \ bhyverun.c \ block_if.c \ bootrom.c \ console.c \ consport.c \ ctl_util.c \ ctl_scsi_all.c \ dbgport.c \ fwctl.c \ gdb.c \ - hda_codec.c \ inout.c \ ioapic.c \ mem.c \ mevent.c \ mptbl.c \ net_utils.c \ pci_ahci.c \ pci_e82545.c \ pci_emul.c \ - pci_hda.c \ pci_fbuf.c \ pci_hostbridge.c \ pci_irq.c \ pci_lpc.c \ pci_nvme.c \ pci_passthru.c \ pci_virtio_block.c \ pci_virtio_console.c \ pci_virtio_net.c \ pci_virtio_rnd.c \ pci_virtio_scsi.c \ pci_uart.c \ pci_xhci.c \ pm.c \ post.c \ ps2kbd.c \ ps2mouse.c \ rfb.c \ rtc.c \ smbiostbl.c \ sockstream.c \ task_switch.c \ uart_emul.c \ usb_emul.c \ usb_mouse.c \ virtio.c \ vga.c \ xmsr.c \ spinup_ap.c \ iov.c .PATH: ${BHYVE_SYSDIR}/sys/amd64/vmm SRCS+= vmm_instruction_emul.c LIBADD= vmmapi md pthread z util sbuf cam .if ${MK_INET_SUPPORT} != "no" CFLAGS+=-DINET .endif .if ${MK_INET6_SUPPORT} != "no" CFLAGS+=-DINET6 .endif .if ${MK_OPENSSL} == "no" CFLAGS+=-DNO_OPENSSL .else LIBADD+= crypto .endif CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/e1000 CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/mii CFLAGS+= -I${BHYVE_SYSDIR}/sys/dev/usb/controller .ifdef GDB_LOG CFLAGS+=-DGDB_LOG .endif WARNS?= 2 .include Index: head/usr.sbin/bhyve/bhyve.8 =================================================================== --- head/usr.sbin/bhyve/bhyve.8 (revision 349351) +++ head/usr.sbin/bhyve/bhyve.8 (revision 349352) @@ -1,650 +1,638 @@ .\" Copyright (c) 2013 Peter Grehan .\" 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd June 24, 2019 +.Dd December 11, 2018 .Dt BHYVE 8 .Os .Sh NAME .Nm bhyve .Nd "run a guest operating system inside a virtual machine" .Sh SYNOPSIS .Nm .Op Fl abehuwxACHPSWY .Oo .Fl c\~ Ns .Oo .Op Ar cpus= Ns .Ar numcpus Ns .Oc Ns .Op Ar ,sockets=n Ns .Op Ar ,cores=n Ns .Op Ar ,threads=n .Oc .Op Fl g Ar gdbport .Op Fl l Ar help|lpcdev Ns Op , Ns Ar conf .Op Fl m Ar memsize Ns Op Ar K|k|M|m|G|g|T|t .Op Fl p Ar vcpu:hostcpu .Op Fl s Ar help|slot,emulation Ns Op , Ns Ar conf .Op Fl G Ar port .Op Fl U Ar uuid .Ar vmname .Sh DESCRIPTION .Nm is a hypervisor that runs guest operating systems inside a virtual machine. .Pp Parameters such as the number of virtual CPUs, amount of guest memory, and I/O connectivity can be specified with command-line parameters. .Pp If not using a boot ROM, the guest operating system must be loaded with .Xr bhyveload 8 or a similar boot loader before running .Nm , otherwise, it is enough to run .Nm with a boot ROM of choice. .Pp .Nm runs until the guest operating system reboots or an unhandled hypervisor exit is detected. .Sh OPTIONS .Bl -tag -width 10n .It Fl a The guest's local APIC is configured in xAPIC mode. The xAPIC mode is the default setting so this option is redundant. It will be deprecated in a future version. .It Fl A Generate ACPI tables. Required for .Fx Ns /amd64 guests. .It Fl b Enable a low-level console device supported by .Fx kernels compiled with .Cd "device bvmconsole" . This option will be deprecated in a future version. .It Fl c Op Ar setting ... Number of guest virtual CPUs and/or the CPU topology. The default value for each of .Ar numcpus , .Ar sockets , .Ar cores , and .Ar threads is 1. The current maximum number of guest virtual CPUs is 16. If .Ar numcpus is not specified then it will be calculated from the other arguments. The topology must be consistent in that the .Ar numcpus must equal the product of .Ar sockets , .Ar cores , and .Ar threads . If a .Ar setting is specified more than once the last one has precedence. .It Fl C Include guest memory in core file. .It Fl e Force .Nm to exit when a guest issues an access to an I/O port that is not emulated. This is intended for debug purposes. .It Fl g Ar gdbport For .Fx kernels compiled with .Cd "device bvmdebug" , allow a remote kernel kgdb to be relayed to the guest kernel gdb stub via a local IPv4 address and this port. This option will be deprecated in a future version. .It Fl G Ar port Start a debug server that uses the GDB protocol to export guest state to a debugger. An IPv4 TCP socket will be bound to the supplied .Ar port to listen for debugger connections. Only a single debugger may be attached to the debug server at a time. If .Ar port begins with .Sq w , .Nm will pause execution at the first instruction waiting for a debugger to attach. .It Fl h Print help message and exit. .It Fl H Yield the virtual CPU thread when a HLT instruction is detected. If this option is not specified, virtual CPUs will use 100% of a host CPU. .It Fl l Op Ar help|lpcdev Ns Op , Ns Ar conf Allow devices behind the LPC PCI-ISA bridge to be configured. The only supported devices are the TTY-class devices .Ar com1 and .Ar com2 and the boot ROM device .Ar bootrom . .Pp .Ar help print a list of supported LPC devices. .It Fl m Ar memsize Ns Op Ar K|k|M|m|G|g|T|t Guest physical memory size in bytes. This must be the same size that was given to .Xr bhyveload 8 . .Pp The size argument may be suffixed with one of K, M, G or T (either upper or lower case) to indicate a multiple of kilobytes, megabytes, gigabytes, or terabytes. If no suffix is given, the value is assumed to be in megabytes. .Pp .Ar memsize defaults to 256M. .It Fl p Ar vcpu:hostcpu Pin guest's virtual CPU .Em vcpu to .Em hostcpu . .It Fl P Force the guest virtual CPU to exit when a PAUSE instruction is detected. .It Fl s Op Ar help|slot,emulation Ns Op , Ns Ar conf Configure a virtual PCI slot and function. .Pp .Nm provides PCI bus emulation and virtual devices that can be attached to slots on the bus. There are 32 available slots, with the option of providing up to 8 functions per slot. .Bl -tag -width 10n .It Ar help print a list of supported PCI devices. .It Ar slot .Ar pcislot[:function] .Ar bus:pcislot:function .Pp The .Ar pcislot value is 0 to 31. The optional .Ar function value is 0 to 7. The optional .Ar bus value is 0 to 255. If not specified, the .Ar function value defaults to 0. If not specified, the .Ar bus value defaults to 0. .It Ar emulation .Bl -tag -width 10n .It Li hostbridge | Li amd_hostbridge .Pp Provide a simple host bridge. This is usually configured at slot 0, and is required by most guest operating systems. The .Li amd_hostbridge emulation is identical but uses a PCI vendor ID of .Li AMD . .It Li passthru PCI pass-through device. .It Li virtio-net Virtio network interface. .It Li virtio-blk Virtio block storage interface. .It Li virtio-scsi Virtio SCSI interface. .It Li virtio-rnd Virtio RNG interface. .It Li virtio-console Virtio console interface, which exposes multiple ports to the guest in the form of simple char devices for simple IO between the guest and host userspaces. .It Li ahci AHCI controller attached to arbitrary devices. .It Li ahci-cd AHCI controller attached to an ATAPI CD/DVD. .It Li ahci-hd AHCI controller attached to a SATA hard-drive. .It Li e1000 Intel e82545 network interface. .It Li uart PCI 16550 serial device. .It Li lpc LPC PCI-ISA bridge with COM1 and COM2 16550 serial ports and a boot ROM. The LPC bridge emulation can only be configured on bus 0. .It Li fbuf Raw framebuffer device attached to VNC server. .It Li xhci eXtensible Host Controller Interface (xHCI) USB controller. .It Li nvme NVM Express (NVMe) controller. -.It Li hda -High Definition Audio Controller. .El .It Op Ar conf This optional parameter describes the backend for device emulations. If .Ar conf is not specified, the device emulation has no backend and can be considered unconnected. .Pp Network devices: .Bl -tag -width 10n .It Ar tapN Ns Op , Ns Ar mac=xx:xx:xx:xx:xx:xx .It Ar vmnetN Ns Op , Ns Ar mac=xx:xx:xx:xx:xx:xx .Pp If .Ar mac is not specified, the MAC address is derived from a fixed OUI and the remaining bytes from an MD5 hash of the slot and function numbers and the device name. .Pp The MAC address is an ASCII string in .Xr ethers 5 format. .El .Pp Block storage devices: .Bl -tag -width 10n .It Pa /filename Ns Oo , Ns Ar block-device-options Oc .It Pa /dev/xxx Ns Oo , Ns Ar block-device-options Oc .El .Pp The .Ar block-device-options are: .Bl -tag -width 8n .It Li nocache Open the file with .Dv O_DIRECT . .It Li direct Open the file using .Dv O_SYNC . .It Li ro Force the file to be opened read-only. .It Li sectorsize= Ns Ar logical Ns Oo / Ns Ar physical Oc Specify the logical and physical sector sizes of the emulated disk. The physical sector size is optional and is equal to the logical sector size if not explicitly specified. .El .Pp SCSI devices: .Bl -tag -width 10n .It Pa /dev/cam/ctl Ns Oo Ar pp . Ns Ar vp Oc Ns Oo , Ns Ar scsi-device-options Oc .El .Pp The .Ar scsi-device-options are: .Bl -tag -width 10n .It Li iid= Ns Ar IID Initiator ID to use when sending requests to specified CTL port. The default value is 0. .El .Pp TTY devices: .Bl -tag -width 10n .It Li stdio Connect the serial port to the standard input and output of the .Nm process. .It Pa /dev/xxx Use the host TTY device for serial port I/O. .El .Pp Boot ROM device: .Bl -tag -width 10n .It Pa romfile Map .Ar romfile in the guest address space reserved for boot firmware. .El .Pp Pass-through devices: .Bl -tag -width 10n .It Ns Ar slot Ns / Ns Ar bus Ns / Ns Ar function Connect to a PCI device on the host at the selector described by .Ar slot , .Ar bus , and .Ar function numbers. .El .Pp Guest memory must be wired using the .Fl S option when a pass-through device is configured. .Pp The host device must have been reserved at boot-time using the .Va pptdev loader variable as described in .Xr vmm 4 . .Pp Virtio console devices: .Bl -tag -width 10n .It Li port1= Ns Pa /path/to/port1.sock Ns ,anotherport= Ns Pa ... A maximum of 16 ports per device can be created. Every port is named and corresponds to a Unix domain socket created by .Nm . .Nm accepts at most one connection per port at a time. .Pp Limitations: .Bl -bullet -offset 2n .It Due to lack of destructors in .Nm , sockets on the filesystem must be cleaned up manually after .Nm exits. .It There is no way to use the "console port" feature, nor the console port resize at present. .It Emergency write is advertised, but no-op at present. .El .El .Pp Framebuffer devices: .Bl -tag -width 10n .It Xo .Oo rfb= Ns Oo Ar IP\&: Oc Ns Ar port Oc Ns Oo ,w= Ns Ar width Oc Ns Oo ,h= Ns .Ar height Oc Ns Oo ,vga= Ns Ar vgaconf Oc Ns Oo Ns ,wait Oc Ns Oo ,password= Ns .Ar password Oc .Xc .Bl -tag -width 8n .It Ar IPv4:port No or Ar [IPv6%zone]:port An .Ar IP address and a .Ar port VNC should listen on. The default is to listen on localhost IPv4 address and default VNC port 5900. An IPv6 address must be enclosed in square brackets and may contain an optional zone identifier. .It Ar width No and Ar height A display resolution, width and height, respectively. If not specified, a default resolution of 1024x768 pixels will be used. Minimal supported resolution is 640x480 pixels, and maximum is 1920x1200 pixels. .It Ar vgaconf Possible values for this option are .Dq io (default), .Dq on , and .Dq off . PCI graphics cards have a dual personality in that they are standard PCI devices with BAR addressing, but may also implicitly decode legacy VGA I/O space .Pq Ad 0x3c0-3df and memory space .Pq 64KB at Ad 0xA0000 . The default .Dq io option should be used for guests that attempt to issue BIOS calls which result in I/O port queries, and fail to boot if I/O decode is disabled. .Pp The .Dq on option should be used along with the CSM BIOS capability in UEFI to boot traditional BIOS guests that require the legacy VGA I/O and memory regions to be available. .Pp The .Dq off option should be used for the UEFI guests that assume that VGA adapter is present if they detect the I/O ports. An example of such a guest is .Ox in UEFI mode. .Pp Please refer to the .Nm .Fx wiki page .Pq Lk https://wiki.freebsd.org/bhyve for configuration notes of particular guests. .It wait Instruct .Nm to only boot upon the initiation of a VNC connection, simplifying the installation of operating systems that require immediate keyboard input. This can be removed for post-installation use. .It password This type of authentication is known to be cryptographically weak and is not intended for use on untrusted networks. Many implementations will want to use stronger security, such as running the session over an encrypted channel provided by IPsec or SSH. .El .El .Pp xHCI USB devices: .Bl -tag -width 10n .It Li tablet A USB tablet device which provides precise cursor synchronization when using VNC. .El .Pp NVMe devices: .Bl -tag -width 10n .It Li devpath Accepted device paths are: .Ar /dev/blockdev or .Ar /path/to/image or .Ar ram=size_in_MiB . .It Li maxq Max number of queues. .It Li qsz Max elements in each queue. .It Li ioslots Max number of concurrent I/O requests. .It Li sectsz Sector size (defaults to blockif sector size). .It Li ser Serial number with maximum 20 characters. -.El -.Pp -HD Audio devices: -.Bl -tag -width 10n -.It Li play -Playback device, typically -.Ar /dev/dsp0 . -.It Li rec -Recording device, typically -.Ar /dev/dsp0 . .El .El .It Fl S Wire guest memory. .It Fl u RTC keeps UTC time. .It Fl U Ar uuid Set the universally unique identifier .Pq UUID in the guest's System Management BIOS System Information structure. By default a UUID is generated from the host's hostname and .Ar vmname . .It Fl w Ignore accesses to unimplemented Model Specific Registers (MSRs). This is intended for debug purposes. .It Fl W Force virtio PCI device emulations to use MSI interrupts instead of MSI-X interrupts. .It Fl x The guest's local APIC is configured in x2APIC mode. .It Fl Y Disable MPtable generation. .It Ar vmname Alphanumeric name of the guest. This should be the same as that created by .Xr bhyveload 8 . .El .Sh DEBUG SERVER The current debug server provides limited support for debuggers. .Ss Registers Each virtual CPU is exposed to the debugger as a thread. .Pp General purpose registers can be queried for each virtual CPU, but other registers such as floating-point and system registers cannot be queried. .Ss Memory Memory (including memory mapped I/O regions) can be read by the debugger, but not written. Memory operations use virtual addresses that are resolved to physical addresses via the current virtual CPU's active address translation. .Ss Control The running guest can be interrupted by the debugger at any time .Pq for example, by pressing Ctrl-C in the debugger . .Pp Single stepping is only supported on Intel CPUs supporting the MTRAP VM exit. .Pp Breakpoints are not supported. .Sh SIGNAL HANDLING .Nm deals with the following signals: .Pp .Bl -tag -width indent -compact .It SIGTERM Trigger ACPI poweroff for a VM .El .Sh EXIT STATUS Exit status indicates how the VM was terminated: .Pp .Bl -tag -width indent -compact .It 0 rebooted .It 1 powered off .It 2 halted .It 3 triple fault .It 4 exited due to an error .El .Sh EXAMPLES If not using a boot ROM, the guest operating system must have been loaded with .Xr bhyveload 8 or a similar boot loader before .Xr bhyve 4 can be run. Otherwise, the boot loader is not needed. .Pp To run a virtual machine with 1GB of memory, two virtual CPUs, a virtio block device backed by the .Pa /my/image filesystem image, and a serial port for the console: .Bd -literal -offset indent bhyve -c 2 -s 0,hostbridge -s 1,lpc -s 2,virtio-blk,/my/image \\ -l com1,stdio -A -H -P -m 1G vm1 .Ed .Pp Run a 24GB single-CPU virtual machine with three network ports, one of which has a MAC address specified: .Bd -literal -offset indent bhyve -s 0,hostbridge -s 1,lpc -s 2:0,virtio-net,tap0 \\ -s 2:1,virtio-net,tap1 \\ -s 2:2,virtio-net,tap2,mac=00:be:fa:76:45:00 \\ -s 3,virtio-blk,/my/image -l com1,stdio \\ -A -H -P -m 24G bigvm .Ed .Pp Run an 8GB quad-CPU virtual machine with 8 AHCI SATA disks, an AHCI ATAPI CD-ROM, a single virtio network port, an AMD hostbridge, and the console port connected to an .Xr nmdm 4 null-modem device. .Bd -literal -offset indent bhyve -c 4 \\ -s 0,amd_hostbridge -s 1,lpc \\ -s 1:0,ahci,hd:/images/disk.1,hd:/images/disk.2,\\ hd:/images/disk.3,hd:/images/disk.4,\\ hd:/images/disk.5,hd:/images/disk.6,\\ hd:/images/disk.7,hd:/images/disk.8,\\ cd:/images/install.iso \\ -s 3,virtio-net,tap0 \\ -l com1,/dev/nmdm0A \\ -A -H -P -m 8G .Ed .Pp Run a UEFI virtual machine with a display resolution of 800 by 600 pixels that can be accessed via VNC at: 0.0.0.0:5900. .Bd -literal -offset indent bhyve -c 2 -m 4G -w -H \\ -s 0,hostbridge \\ -s 3,ahci-cd,/path/to/uefi-OS-install.iso \\ -s 4,ahci-hd,disk.img \\ -s 5,virtio-net,tap0 \\ -s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \\ -s 30,xhci,tablet \\ -s 31,lpc -l com1,stdio \\ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\ uefivm .Ed .Pp Run a UEFI virtual machine with a VNC display that is bound to all IPv6 addresses on port 5900. .Bd -literal -offset indent bhyve -c 2 -m 4G -w -H \\ -s 0,hostbridge \\ -s 4,ahci-hd,disk.img \\ -s 5,virtio-net,tap0 \\ -s 29,fbuf,tcp=[::]:5900,w=800,h=600 \\ -s 30,xhci,tablet \\ -s 31,lpc -l com1,stdio \\ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\ uefivm .Ed .Sh SEE ALSO .Xr bhyve 4 , .Xr nmdm 4 , .Xr vmm 4 , .Xr ethers 5 , .Xr bhyvectl 8 , .Xr bhyveload 8 .Pp .Rs .%A Intel .%B 64 and IA-32 Architectures Software Developer’s Manual .%V Volume 3 .Re .Sh HISTORY .Nm first appeared in .Fx 10.0 . .Sh AUTHORS .An Neel Natu Aq Mt neel@freebsd.org .An Peter Grehan Aq Mt grehan@freebsd.org Index: head/usr.sbin/nandsim/nandsim.c =================================================================== --- head/usr.sbin/nandsim/nandsim.c (revision 349351) +++ head/usr.sbin/nandsim/nandsim.c (nonexistent) @@ -1,1399 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 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. - */ - -/* - * Control application for the NAND simulator. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nandsim_cfgparse.h" - -#define SIMDEVICE "/dev/nandsim.ioctl" - -#define error(fmt, args...) do { \ - printf("ERROR: " fmt "\n", ##args); } while (0) - -#define warn(fmt, args...) do { \ - printf("WARNING: " fmt "\n", ##args); } while (0) - -#define DEBUG -#undef DEBUG - -#ifdef DEBUG -#define debug(fmt, args...) do { \ - printf("NANDSIM_CONF:" fmt "\n", ##args); } while (0) -#else -#define debug(fmt, args...) do {} while(0) -#endif - -#define NANDSIM_RAM_LOG_SIZE 16384 - -#define MSG_NOTRUNNING "Controller#%d is not running.Please start" \ - " it first." -#define MSG_RUNNING "Controller#%d is already running!" -#define MSG_CTRLCHIPNEEDED "You have to specify ctrl_no:cs_no pair!" -#define MSG_STATUSACQCTRLCHIP "Could not acquire status for ctrl#%d chip#%d" -#define MSG_STATUSACQCTRL "Could not acquire status for ctrl#%d" -#define MSG_NOCHIP "There is no such chip configured (chip#%d "\ - "at ctrl#%d)!" - -#define MSG_NOCTRL "Controller#%d is not configured!" -#define MSG_NOTCONFIGDCTRLCHIP "Chip connected to ctrl#%d at cs#%d " \ - "is not configured." - -typedef int (commandfunc_t)(int , char **); - -static struct nandsim_command *getcommand(char *); -static int parse_devstring(char *, int *, int *); -static void printchip(struct sim_chip *, uint8_t); -static void printctrl(struct sim_ctrl *); -static int opendev(int *); -static commandfunc_t cmdstatus; -static commandfunc_t cmdconf; -static commandfunc_t cmdstart; -static commandfunc_t cmdstop; -static commandfunc_t cmdmod; -static commandfunc_t cmderror; -static commandfunc_t cmdbb; -static commandfunc_t cmdfreeze; -static commandfunc_t cmdlog; -static commandfunc_t cmdstats; -static commandfunc_t cmddump; -static commandfunc_t cmdrestore; -static commandfunc_t cmddestroy; -static commandfunc_t cmdhelp; -static int checkusage(int, int, char **); -static int is_chip_created(int, int, int *); -static int is_ctrl_created(int, int *); -static int is_ctrl_running(int, int *); -static int assert_chip_connected(int , int); -static int printstats(int, int, uint32_t, int); - -struct nandsim_command { - const char *cmd_name; /* Command name */ - commandfunc_t *commandfunc; /* Ptr to command function */ - uint8_t req_argc; /* Mandatory arguments count */ - const char *usagestring; /* Usage string */ -}; - -static struct nandsim_command commands[] = { - {"status", cmdstatus, 1, - "status [-v]\n" }, - {"conf", cmdconf, 1, - "conf \n" }, - {"start", cmdstart, 1, - "start \n" }, - {"mod", cmdmod, 2, - "mod [-l ] | [-p ]\n" - "\t[-e ] [-r ]\n" - "\t[-E ] | [-h]\n" }, - {"stop", cmdstop, 1, - "stop \n" }, - {"error", cmderror, 5, - "error \n" }, - {"bb", cmdbb, 2, - "bb [blk_num1,blk_num2,..] [-U] [-L]\n" }, - {"freeze", cmdfreeze, 1, - "freeze [ctrl_no]\n" }, - {"log", cmdlog, 1, - "log \n" }, - {"stats", cmdstats, 2, - "stats \n" }, - {"dump", cmddump, 2, - "dump \n" }, - {"restore", cmdrestore, 2, - "restore \n" }, - {"destroy", cmddestroy, 1, - "destroy \n" }, - {"help", cmdhelp, 0, - "help [-v]" }, - {NULL, NULL, 0, NULL}, -}; - - -/* Parse command name, and start appropriate function */ -static struct nandsim_command* -getcommand(char *arg) -{ - struct nandsim_command *opts; - - for (opts = commands; (opts != NULL) && - (opts->cmd_name != NULL); opts++) { - if (strcmp(opts->cmd_name, arg) == 0) - return (opts); - } - return (NULL); -} - -/* - * Parse given string in format :, if possible -- set - * ctrl and/or cs, and return 0 (success) or 1 (in case of error). - * - * ctrl == 0xff && chip == 0xff : '--all' flag specified - * ctrl != 0xff && chip != 0xff : both ctrl & chip were specified - * ctrl != 0xff && chip == 0xff : only ctrl was specified - */ -static int -parse_devstring(char *str, int *ctrl, int *cs) -{ - char *tmpstr; - unsigned int num = 0; - - /* Ignore white spaces at the beginning */ - while (isspace(*str) && (*str != '\0')) - str++; - - *ctrl = 0xff; - *cs = 0xff; - if (strcmp(str, "--all") == 0 || - strcmp(str, "-a") == 0) { - /* If --all or -a is specified, ctl==chip==0xff */ - debug("CTRL=%d CHIP=%d\n", *ctrl, *cs); - return (0); - } - /* Separate token and try to convert it to int */ - tmpstr = (char *)strtok(str, ":"); - if ((tmpstr != NULL) && (*tmpstr != '\0')) { - if (convert_arguint(tmpstr, &num) != 0) - return (1); - - if (num > MAX_SIM_DEV - 1) { - error("Invalid ctrl_no supplied: %s. Valid ctrl_no " - "value must lie between 0 and 3!", tmpstr); - return (1); - } - - *ctrl = num; - tmpstr = (char *)strtok(NULL, ":"); - - if ((tmpstr != NULL) && (*tmpstr != '\0')) { - if (convert_arguint(tmpstr, &num) != 0) - return (1); - - /* Check if chip_no is valid */ - if (num > MAX_CTRL_CS - 1) { - error("Invalid chip_no supplied: %s. Valid " - "chip_no value must lie between 0 and 3!", - tmpstr); - return (1); - } - *cs = num; - } - } else - /* Empty devstring supplied */ - return (1); - - debug("CTRL=%d CHIP=%d\n", *ctrl, *cs); - return (0); -} - -static int -opendev(int *fd) -{ - - *fd = open(SIMDEVICE, O_RDWR); - if (*fd == -1) { - error("Could not open simulator device file (%s)!", - SIMDEVICE); - return (EX_OSFILE); - } - return (EX_OK); -} - -static int -opencdev(int *cdevd, int ctrl, int chip) -{ - char fname[255]; - - sprintf(fname, "/dev/nandsim%d.%d", ctrl, chip); - *cdevd = open(fname, O_RDWR); - if (*cdevd == -1) - return (EX_NOINPUT); - - return (EX_OK); -} - -/* - * Check if given arguments count match requirements. If no, or - * --help (-h) flag is specified -- return 1 (print usage) - */ -static int -checkusage(int gargc, int argsreqd, char **gargv) -{ - - if (gargc < argsreqd + 2 || (gargc >= (argsreqd + 2) && - (strcmp(gargv[1], "--help") == 0 || - strcmp(gargv[1], "-h") == 0))) - return (1); - - return (0); -} - -static int -cmdstatus(int gargc, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, idx, idx2, start, stop; - uint8_t verbose = 0; - struct sim_ctrl ctrlconf; - struct sim_chip chipconf; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) { - return (EX_USAGE); - } else if (ctl == 0xff) { - /* Every controller */ - start = 0; - stop = MAX_SIM_DEV-1; - } else { - /* Specified controller only */ - start = ctl; - stop = ctl; - } - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - for (idx = 0; idx < gargc; idx ++) - if (strcmp(gargv[idx], "-v") == 0 || - strcmp(gargv[idx], "--verbose") == 0) - verbose = 1; - - for (idx = start; idx <= stop; idx++) { - ctrlconf.num = idx; - err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrlconf); - if (err) { - err = EX_SOFTWARE; - error(MSG_STATUSACQCTRL, idx); - continue; - } - - printctrl(&ctrlconf); - - for (idx2 = 0; idx2 < MAX_CTRL_CS; idx2++) { - chipconf.num = idx2; - chipconf.ctrl_num = idx; - - err = ioctl(fd, NANDSIM_STATUS_CHIP, &chipconf); - if (err) { - err = EX_SOFTWARE; - error(MSG_STATUSACQCTRL, idx); - continue; - } - - printchip(&chipconf, verbose); - } - } - close(fd); - return (err); -} - -static int -cmdconf(int gargc __unused, char **gargv) -{ - int err; - - err = parse_config(gargv[2], SIMDEVICE); - if (err) - return (EX_DATAERR); - - return (EX_OK); -} - -static int -cmdstart(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, running, state; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - err = is_ctrl_created(ctl, &state); - if (err) { - return (EX_SOFTWARE); - } else if (state == 0) { - error(MSG_NOCTRL, ctl); - return (EX_SOFTWARE); - } - - err = is_ctrl_running(ctl, &running); - if (err) - return (EX_SOFTWARE); - - if (running) { - warn(MSG_RUNNING, ctl); - } else { - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_START_CTRL, &ctl); - close(fd); - if (err) { - error("Cannot start controller#%d", ctl); - err = EX_SOFTWARE; - } - } - return (err); -} - -static int -cmdstop(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, running; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - err = is_ctrl_running(ctl, &running); - if (err) - return (EX_SOFTWARE); - - if (!running) { - error(MSG_NOTRUNNING, ctl); - } else { - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STOP_CTRL, &ctl); - close(fd); - if (err) { - error("Cannot stop controller#%d", ctl); - err = EX_SOFTWARE; - } - } - - return (err); -} - -static int -cmdmod(int gargc __unused, char **gargv) -{ - int chip, ctl, err = 0, fd = -1, i; - struct sim_mod mods; - - if (gargc >= 4) { - if (strcmp(gargv[2], "--loglevel") == 0 || strcmp(gargv[2], - "-l") == 0) { - /* Set loglevel (ctrl:chip pair independent) */ - mods.field = SIM_MOD_LOG_LEVEL; - - if (convert_arguint(gargv[3], &mods.new_value) != 0) - return (EX_SOFTWARE); - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_MODIFY, &mods); - if (err) { - error("simulator parameter %s could not be " - "modified !", gargv[3]); - close(fd); - return (EX_SOFTWARE); - } - - debug("request : loglevel = %d\n", mods.new_value); - close(fd); - return (EX_OK); - } - } - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - else if (chip == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - /* Find out which flags were passed */ - for (i = 3; i < gargc; i++) { - - if (convert_arguint(gargv[i + 1], &mods.new_value) != 0) - continue; - - if (strcmp(gargv[i], "--prog-time") == 0 || - strcmp(gargv[i], "-p") == 0) { - - mods.field = SIM_MOD_PROG_TIME; - debug("request : progtime = %d\n", mods.new_value); - - } else if (strcmp(gargv[i], "--erase-time") == 0 || - strcmp(gargv[i], "-e") == 0) { - - mods.field = SIM_MOD_ERASE_TIME; - debug("request : eraseime = %d\n", mods.new_value); - - } else if (strcmp(gargv[i], "--read-time") == 0 || - strcmp(gargv[i], "-r") == 0) { - - mods.field = SIM_MOD_READ_TIME; - debug("request : read_time = %d\n", mods.new_value); - - } else if (strcmp(gargv[i], "--error-ratio") == 0 || - strcmp(gargv[i], "-E") == 0) { - - mods.field = SIM_MOD_ERROR_RATIO; - debug("request : error_ratio = %d\n", mods.new_value); - - } else { - /* Flag not recognized, or nothing specified. */ - error("Unrecognized flag:%s\n", gargv[i]); - if (fd >= 0) - close(fd); - return (EX_USAGE); - } - - mods.chip_num = chip; - mods.ctrl_num = ctl; - - /* Call appropriate ioctl */ - err = ioctl(fd, NANDSIM_MODIFY, &mods); - if (err) { - error("simulator parameter %s could not be modified! ", - gargv[i]); - continue; - } - i++; - } - close(fd); - return (EX_OK); -} - -static int -cmderror(int gargc __unused, char **gargv) -{ - uint32_t page, column, len, pattern; - int chip = 0, ctl = 0, err = 0, fd; - struct sim_error sim_err; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - if (chip == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (convert_arguint(gargv[3], &page) || - convert_arguint(gargv[4], &column) || - convert_arguint(gargv[5], &len) || - convert_arguint(gargv[6], &pattern)) - return (EX_SOFTWARE); - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - sim_err.page_num = page; - sim_err.column = column; - sim_err.len = len; - sim_err.pattern = pattern; - sim_err.ctrl_num = ctl; - sim_err.chip_num = chip; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_INJECT_ERROR, &sim_err); - - close(fd); - if (err) { - error("Could not inject error !"); - return (EX_SOFTWARE); - } - return (EX_OK); -} - -static int -cmdbb(int gargc, char **gargv) -{ - struct sim_block_state bs; - struct chip_param_io cparams; - uint32_t blkidx; - int c, cdevd, chip = 0, ctl = 0, err = 0, fd, idx; - uint8_t flagL = 0, flagU = 0; - int *badblocks = NULL; - - /* Check for --list/-L or --unmark/-U flags */ - for (idx = 3; idx < gargc; idx++) { - if (strcmp(gargv[idx], "--list") == 0 || - strcmp(gargv[idx], "-L") == 0) - flagL = idx; - if (strcmp(gargv[idx], "--unmark") == 0 || - strcmp(gargv[idx], "-U") == 0) - flagU = idx; - } - - if (flagL == 2 || flagU == 2 || flagU == 3) - return (EX_USAGE); - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) { - return (EX_USAGE); - } - if (chip == 0xff || ctl == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - bs.ctrl_num = ctl; - bs.chip_num = chip; - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opencdev(&cdevd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = ioctl(cdevd, NAND_IO_GET_CHIP_PARAM, &cparams); - if (err) - return (EX_SOFTWARE); - - close(cdevd); - - bs.ctrl_num = ctl; - bs.chip_num = chip; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - if (flagL != 3) { - /* - * Flag -L was specified either after blocklist or was not - * specified at all. - */ - c = parse_intarray(gargv[3], &badblocks); - - for (idx = 0; idx < c; idx++) { - bs.block_num = badblocks[idx]; - /* Do not change wearout */ - bs.wearout = -1; - bs.state = (flagU == 0) ? NANDSIM_BAD_BLOCK : - NANDSIM_GOOD_BLOCK; - - err = ioctl(fd, NANDSIM_SET_BLOCK_STATE, &bs); - if (err) { - error("Could not set bad block(%d) for " - "controller (%d)!", - badblocks[idx], ctl); - err = EX_SOFTWARE; - break; - } - } - } - if (flagL != 0) { - /* If flag -L was specified (anywhere) */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - bs.block_num = blkidx; - /* Do not change the wearout */ - bs.wearout = -1; - err = ioctl(fd, NANDSIM_GET_BLOCK_STATE, &bs); - if (err) { - error("Could not acquire block state"); - err = EX_SOFTWARE; - continue; - } - printf("Block#%d: wear count: %d %s\n", blkidx, - bs.wearout, - (bs.state == NANDSIM_BAD_BLOCK) ? "BAD":"GOOD"); - } - } - close(fd); - return (err); -} - -static int -cmdfreeze(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, i, start = 0, state, stop = 0; - struct sim_ctrl_chip ctrlchip; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - if (ctl == 0xff) { - error("You have to specify at least controller number"); - return (EX_USAGE); - } - - if (ctl != 0xff && chip == 0xff) { - start = 0; - stop = MAX_CTRL_CS - 1; - } else { - start = chip; - stop = chip; - } - - ctrlchip.ctrl_num = ctl; - - err = is_ctrl_running(ctl, &state); - if (err) - return (EX_SOFTWARE); - if (state == 0) { - error(MSG_NOTRUNNING, ctl); - return (EX_SOFTWARE); - } - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - for (i = start; i <= stop; i++) { - err = is_chip_created(ctl, i, &state); - if (err) - return (EX_SOFTWARE); - else if (state == 0) { - continue; - } - - ctrlchip.chip_num = i; - err = ioctl(fd, NANDSIM_FREEZE, &ctrlchip); - if (err) { - error("Could not freeze ctrl#%d chip#%d", ctl, i); - close(fd); - return (EX_SOFTWARE); - } - } - close(fd); - return (EX_OK); -} - -static int -cmdlog(int gargc __unused, char **gargv) -{ - struct sim_log log; - int chip = 0, ctl = 0, err = 0, fd, idx, start = 0, stop = 0; - char *logbuf; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - logbuf = (char *)malloc(sizeof(char) * NANDSIM_RAM_LOG_SIZE); - if (logbuf == NULL) { - error("Not enough memory to create log buffer"); - return (EX_SOFTWARE); - } - - memset(logbuf, 0, NANDSIM_RAM_LOG_SIZE); - log.log = logbuf; - log.len = NANDSIM_RAM_LOG_SIZE; - - if (ctl == 0xff) { - start = 0; - stop = MAX_SIM_DEV-1; - } else { - start = ctl; - stop = ctl; - } - - if (opendev(&fd) != EX_OK) { - free(logbuf); - return (EX_OSFILE); - } - - /* Print logs for selected controller(s) */ - for (idx = start; idx <= stop; idx++) { - log.ctrl_num = idx; - - err = ioctl(fd, NANDSIM_PRINT_LOG, &log); - if (err) { - error("Could not get log for controller %d!", idx); - continue; - } - - printf("Logs for controller#%d:\n%s\n", idx, logbuf); - } - - free(logbuf); - close(fd); - return (EX_OK); -} - -static int -cmdstats(int gargc __unused, char **gargv) -{ - int cdevd, chip = 0, ctl = 0, err = 0; - uint32_t pageno = 0; - - err = parse_devstring(gargv[2], &ctl, &chip); - - if (err) - return (EX_USAGE); - - if (chip == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (convert_arguint(gargv[3], &pageno) != 0) - return (EX_USAGE); - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opencdev(&cdevd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = printstats(ctl, chip, pageno, cdevd); - if (err) { - close(cdevd); - return (EX_SOFTWARE); - } - close(cdevd); - return (EX_OK); -} - -static int -cmddump(int gargc __unused, char **gargv) -{ - struct sim_dump dump; - struct sim_block_state bs; - struct chip_param_io cparams; - int chip = 0, ctl = 0, err = EX_OK, fd, dumpfd; - uint32_t blkidx, bwritten = 0, totalwritten = 0; - void *buf; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - if (chip == 0xff || ctl == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opencdev(&fd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NAND_IO_GET_CHIP_PARAM, &cparams); - if (err) { - error("Cannot get parameters for chip %d:%d", ctl, chip); - close(fd); - return (EX_SOFTWARE); - } - close(fd); - - dump.ctrl_num = ctl; - dump.chip_num = chip; - - dump.len = cparams.pages_per_block * (cparams.page_size + - cparams.oob_size); - - buf = malloc(dump.len); - if (buf == NULL) { - error("Could not allocate memory!"); - return (EX_SOFTWARE); - } - dump.data = buf; - - errno = 0; - dumpfd = open(gargv[3], O_WRONLY | O_CREAT, 0666); - if (dumpfd == -1) { - error("Cannot create dump file."); - free(buf); - return (EX_SOFTWARE); - } - - if (opendev(&fd)) { - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - - bs.ctrl_num = ctl; - bs.chip_num = chip; - - /* First uint32_t in file shall contain block count */ - if (write(dumpfd, &cparams, sizeof(cparams)) < (int)sizeof(cparams)) { - error("Error writing to dumpfile!"); - close(fd); - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - - /* - * First loop acquires blocks states and writes them to - * the dump file. - */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - bs.block_num = blkidx; - err = ioctl(fd, NANDSIM_GET_BLOCK_STATE, &bs); - if (err) { - error("Could not get bad block(%d) for " - "controller (%d)!", blkidx, ctl); - close(fd); - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - - bwritten = write(dumpfd, &bs, sizeof(bs)); - if (bwritten != sizeof(bs)) { - error("Error writing to dumpfile"); - close(fd); - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - } - - /* Second loop dumps the data */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - debug("Block#%d...", blkidx); - dump.block_num = blkidx; - - err = ioctl(fd, NANDSIM_DUMP, &dump); - if (err) { - error("Could not dump ctrl#%d chip#%d " - "block#%d", ctl, chip, blkidx); - err = EX_SOFTWARE; - break; - } - - bwritten = write(dumpfd, dump.data, dump.len); - if (bwritten != dump.len) { - error("Error writing to dumpfile"); - err = EX_SOFTWARE; - break; - } - debug("OK!\n"); - totalwritten += bwritten; - } - printf("%d out of %d B written.\n", totalwritten, dump.len * blkidx); - - close(fd); - close(dumpfd); - free(buf); - return (err); -} - -static int -cmdrestore(int gargc __unused, char **gargv) -{ - struct sim_dump dump; - struct sim_block_state bs; - struct stat filestat; - int chip = 0, ctl = 0, err = 0, fd, dumpfd = -1; - uint32_t blkidx, blksz, fsize = 0, expfilesz; - void *buf; - struct chip_param_io cparams, dumpcparams; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - else if (ctl == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - /* Get chip geometry */ - if (opencdev(&fd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NAND_IO_GET_CHIP_PARAM, &cparams); - if (err) { - error("Cannot get parameters for chip %d:%d", ctl, chip); - close(fd); - return (err); - } - close(fd); - - /* Obtain dump file size */ - errno = 0; - if (stat(gargv[3], &filestat) != 0) { - error("Could not acquire file size! : %s", - strerror(errno)); - return (EX_IOERR); - } - - fsize = filestat.st_size; - blksz = cparams.pages_per_block * (cparams.page_size + - cparams.oob_size); - - /* Expected dump file size for chip */ - expfilesz = cparams.blocks * (blksz + sizeof(bs)) + sizeof(cparams); - - if (fsize != expfilesz) { - error("File size does not match chip geometry (file size: %d" - ", dump size: %d)", fsize, expfilesz); - return (EX_SOFTWARE); - } - - dumpfd = open(gargv[3], O_RDONLY); - if (dumpfd == -1) { - error("Could not open dump file!"); - return (EX_IOERR); - } - - /* Read chip params saved in dumpfile */ - read(dumpfd, &dumpcparams, sizeof(dumpcparams)); - - /* XXX */ - if (bcmp(&dumpcparams, &cparams, sizeof(cparams)) != 0) { - error("Supplied dump is created for a chip with different " - "chip configuration!"); - close(dumpfd); - return (EX_SOFTWARE); - } - - if (opendev(&fd) != EX_OK) { - close(dumpfd); - return (EX_OSFILE); - } - - buf = malloc(blksz); - if (buf == NULL) { - error("Could not allocate memory for block buffer"); - close(dumpfd); - close(fd); - return (EX_SOFTWARE); - } - - dump.ctrl_num = ctl; - dump.chip_num = chip; - dump.data = buf; - /* Restore block states and wearouts */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - dump.block_num = blkidx; - if (read(dumpfd, &bs, sizeof(bs)) != sizeof(bs)) { - error("Error reading dumpfile"); - close(dumpfd); - close(fd); - free(buf); - return (EX_SOFTWARE); - } - bs.ctrl_num = ctl; - bs.chip_num = chip; - debug("BLKIDX=%d BLOCKS=%d CTRL=%d CHIP=%d STATE=%d\n" - "WEAROUT=%d BS.CTRL_NUM=%d BS.CHIP_NUM=%d\n", - blkidx, cparams.blocks, dump.ctrl_num, dump.chip_num, - bs.state, bs.wearout, bs.ctrl_num, bs.chip_num); - - err = ioctl(fd, NANDSIM_SET_BLOCK_STATE, &bs); - if (err) { - error("Could not set bad block(%d) for " - "controller: %d, chip: %d!", blkidx, ctl, chip); - close(dumpfd); - close(fd); - free(buf); - return (EX_SOFTWARE); - } - } - /* Restore data */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - errno = 0; - dump.len = read(dumpfd, buf, blksz); - if (errno) { - error("Failed to read block#%d from dumpfile.", blkidx); - err = EX_SOFTWARE; - break; - } - dump.block_num = blkidx; - err = ioctl(fd, NANDSIM_RESTORE, &dump); - if (err) { - error("Could not restore block#%d of ctrl#%d chip#%d" - ": %s", blkidx, ctl, chip, strerror(errno)); - err = EX_SOFTWARE; - break; - } - } - - free(buf); - close(dumpfd); - close(fd); - return (err); - -} - -static int -cmddestroy(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, idx, idx2, state; - int chipstart, chipstop, ctrlstart, ctrlstop; - struct sim_chip_destroy chip_destroy; - - err = parse_devstring(gargv[2], &ctl, &chip); - - if (err) - return (EX_USAGE); - - if (ctl == 0xff) { - /* Every chip at every controller */ - ctrlstart = chipstart = 0; - ctrlstop = MAX_SIM_DEV - 1; - chipstop = MAX_CTRL_CS - 1; - } else { - ctrlstart = ctrlstop = ctl; - if (chip == 0xff) { - /* Every chip at selected controller */ - chipstart = 0; - chipstop = MAX_CTRL_CS - 1; - } else - /* Selected chip at selected controller */ - chipstart = chipstop = chip; - } - debug("CTRLSTART=%d CTRLSTOP=%d CHIPSTART=%d CHIPSTOP=%d\n", - ctrlstart, ctrlstop, chipstart, chipstop); - for (idx = ctrlstart; idx <= ctrlstop; idx++) { - err = is_ctrl_created(idx, &state); - if (err) { - error("Could not acquire ctrl#%d state. Cannot " - "destroy controller.", idx); - return (EX_SOFTWARE); - } - if (state == 0) { - continue; - } - err = is_ctrl_running(idx, &state); - if (err) { - error(MSG_STATUSACQCTRL, idx); - return (EX_SOFTWARE); - } - if (state != 0) { - error(MSG_RUNNING, ctl); - return (EX_SOFTWARE); - } - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - for (idx2 = chipstart; idx2 <= chipstop; idx2++) { - err = is_chip_created(idx, idx2, &state); - if (err) { - error(MSG_STATUSACQCTRLCHIP, idx2, idx); - continue; - } - if (state == 0) - /* There is no such chip running */ - continue; - chip_destroy.ctrl_num = idx; - chip_destroy.chip_num = idx2; - ioctl(fd, NANDSIM_DESTROY_CHIP, - &chip_destroy); - } - /* If chip isn't explicitly specified -- destroy ctrl */ - if (chip == 0xff) { - err = ioctl(fd, NANDSIM_DESTROY_CTRL, &idx); - if (err) { - error("Could not destroy ctrl#%d", idx); - continue; - } - } - close(fd); - } - return (err); -} - -int -main(int argc, char **argv) -{ - struct nandsim_command *cmdopts; - int retcode = 0; - - if (argc < 2) { - cmdhelp(argc, argv); - retcode = EX_USAGE; - } else { - cmdopts = getcommand(argv[1]); - if (cmdopts != NULL && cmdopts->commandfunc != NULL) { - if (checkusage(argc, cmdopts->req_argc, argv) == 1) { - /* Print command specific usage */ - printf("nandsim %s", cmdopts->usagestring); - return (EX_USAGE); - } - retcode = cmdopts->commandfunc(argc, argv); - - if (retcode == EX_USAGE) { - /* Print command-specific usage */ - printf("nandsim %s", cmdopts->usagestring); - } else if (retcode == EX_OSFILE) { - error("Could not open device file"); - } - - } else { - error("Unknown command!"); - retcode = EX_USAGE; - } - } - return (retcode); -} - -static int -cmdhelp(int gargc __unused, char **gargv __unused) -{ - struct nandsim_command *opts; - - printf("usage: nandsim [command params] [params]\n\n"); - - for (opts = commands; (opts != NULL) && - (opts->cmd_name != NULL); opts++) - printf("nandsim %s", opts->usagestring); - - printf("\n"); - return (EX_OK); -} - -static void -printchip(struct sim_chip *chip, uint8_t verbose) -{ - - if (chip->created == 0) - return; - if (verbose > 0) { - printf("\n[Chip info]\n"); - printf("num= %d\nctrl_num=%d\ndevice_id=%02x" - "\tmanufacturer_id=%02x\ndevice_model=%s\nmanufacturer=" - "%s\ncol_addr_cycles=%d\nrow_addr_cycles=%d" - "\npage_size=%d\noob_size=%d\npages_per_block=%d\n" - "blocks_per_lun=%d\nluns=%d\n\nprog_time=%d\n" - "erase_time=%d\nread_time=%d\n" - "error_ratio=%d\nwear_level=%d\nwrite_protect=%c\n" - "chip_width=%db\n", chip->num, chip->ctrl_num, - chip->device_id, chip->manufact_id,chip->device_model, - chip->manufacturer, chip->col_addr_cycles, - chip->row_addr_cycles, chip->page_size, - chip->oob_size, chip->pgs_per_blk, chip->blks_per_lun, - chip->luns,chip->prog_time, chip->erase_time, - chip->read_time, chip->error_ratio, chip->wear_level, - (chip->is_wp == 0) ? 'N':'Y', chip->width); - } else { - printf("[Chip info]\n"); - printf("\tnum=%d\n\tdevice_model=%s\n\tmanufacturer=%s\n" - "\tpage_size=%d\n\twrite_protect=%s\n", - chip->num, chip->device_model, chip->manufacturer, - chip->page_size, (chip->is_wp == 0) ? "NO":"YES"); - } -} - -static void -printctrl(struct sim_ctrl *ctrl) -{ - int i; - - if (ctrl->created == 0) { - printf(MSG_NOCTRL "\n", ctrl->num); - return; - } - printf("\n[Controller info]\n"); - printf("\trunning: %s\n", ctrl->running ? "yes" : "no"); - printf("\tnum cs: %d\n", ctrl->num_cs); - printf("\tecc: %d\n", ctrl->ecc); - printf("\tlog_filename: %s\n", ctrl->filename); - printf("\tecc_layout:"); - for (i = 0; i < MAX_ECC_BYTES; i++) { - if (ctrl->ecc_layout[i] == 0xffff) - break; - else - printf("%c%d", i%16 ? ' ' : '\n', - ctrl->ecc_layout[i]); - } - printf("\n"); -} - -static int -is_ctrl_running(int ctrl_no, int *running) -{ - struct sim_ctrl ctrl; - int err, fd; - - ctrl.num = ctrl_no; - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrl); - if (err) { - error(MSG_STATUSACQCTRL, ctrl_no); - close(fd); - return (err); - } - *running = ctrl.running; - close(fd); - return (0); -} - -static int -is_ctrl_created(int ctrl_no, int *created) -{ - struct sim_ctrl ctrl; - int err, fd; - - ctrl.num = ctrl_no; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrl); - if (err) { - error("Could not acquire conf for ctrl#%d", ctrl_no); - close(fd); - return (err); - } - *created = ctrl.created; - close(fd); - return (0); -} - -static int -is_chip_created(int ctrl_no, int chip_no, int *created) -{ - struct sim_chip chip; - int err, fd; - - chip.ctrl_num = ctrl_no; - chip.num = chip_no; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STATUS_CHIP, &chip); - if (err) { - error("Could not acquire conf for chip#%d", chip_no); - close(fd); - return (err); - } - *created = chip.created; - close(fd); - return (0); -} - -static int -assert_chip_connected(int ctrl_no, int chip_no) -{ - int created, running; - - if (is_ctrl_created(ctrl_no, &created)) - return (0); - - if (!created) { - error(MSG_NOCTRL, ctrl_no); - return (0); - } - - if (is_chip_created(ctrl_no, chip_no, &created)) - return (0); - - if (!created) { - error(MSG_NOTCONFIGDCTRLCHIP, ctrl_no, chip_no); - return (0); - } - - if (is_ctrl_running(ctrl_no, &running)) - return (0); - - if (!running) { - error(MSG_NOTRUNNING, ctrl_no); - return (0); - } - - return (1); -} - -static int -printstats(int ctrlno, int chipno, uint32_t pageno, int cdevd) -{ - struct page_stat_io pstats; - struct block_stat_io bstats; - struct chip_param_io cparams; - uint32_t blkidx; - int err; - - /* Gather information about chip */ - err = ioctl(cdevd, NAND_IO_GET_CHIP_PARAM, &cparams); - - if (err) { - error("Could not acquire chip info for chip attached to cs#" - "%d, ctrl#%d", chipno, ctrlno); - return (EX_SOFTWARE); - } - - blkidx = (pageno / cparams.pages_per_block); - bstats.block_num = blkidx; - - err = ioctl(cdevd, NAND_IO_BLOCK_STAT, &bstats); - if (err) { - error("Could not acquire block#%d statistics!", blkidx); - return (ENXIO); - } - - printf("Block #%d erased: %d\n", blkidx, bstats.block_erased); - pstats.page_num = pageno; - - err = ioctl(cdevd, NAND_IO_PAGE_STAT, &pstats); - if (err) { - error("Could not acquire page statistics!"); - return (ENXIO); - } - - debug("BLOCKIDX = %d PAGENO (REL. TO BLK) = %d\n", blkidx, - pstats.page_num); - - printf("Page#%d : reads:%d writes:%d \n\traw reads:%d raw writes:%d " - "\n\tecc_succeeded:%d ecc_corrected:%d ecc_failed:%d\n", - pstats.page_num, pstats.page_read, pstats.page_written, - pstats.page_raw_read, pstats.page_raw_written, - pstats.ecc_succeded, pstats.ecc_corrected, pstats.ecc_failed); - return (0); -} Property changes on: head/usr.sbin/nandsim/nandsim.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/nandsim_cfgparse.h =================================================================== --- head/usr.sbin/nandsim/nandsim_cfgparse.h (revision 349351) +++ head/usr.sbin/nandsim/nandsim_cfgparse.h (nonexistent) @@ -1,88 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 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 _NANDSIM_CONFPARSER_H_ -#define _NANDSIM_CONFPARSER_H_ - -#define VALUE_UINT 0x08 -#define VALUE_INT 0x10 -#define VALUE_UINTARRAY 0x18 -#define VALUE_INTARRAY 0x20 -#define VALUE_STRING 0x28 -#define VALUE_CHAR 0x40 -#define VALUE_BOOL 0x48 - -#define SIZE_8 0x01 -#define SIZE_16 0x02 -#define SIZE_32 0x04 - -#include "nandsim_rcfile.h" - -/* - * keyname = name of a key, - * mandatory = is key mandatory in section belonging to, 0=false 1=true - * valuetype = what kind of value is assigned to that key, e.g. - * VALUE_UINT | SIZE_8 -- unsigned uint size 8 bits; - * VALUE_UINTARRAY | SIZE_8 -- array of uints 8-bit long; - * VALUE_BOOL -- 'on', 'off','true','false','yes' or 'no' - * literals; - * VALUE_STRING -- strings - * field = ptr to the field that should hold value for parsed value - * maxlength = contains maximum length of an array (used only with either - * VALUE_STRING or VALUE_(U)INTARRAY value types. - */ -struct nandsim_key { - const char *keyname; - uint8_t mandatory; - uint8_t valuetype; - void *field; - uint32_t maxlength; -}; -struct nandsim_section { - const char *name; - struct nandsim_key *keys; -}; - -struct nandsim_config { - struct sim_param **simparams; - struct sim_chip **simchips; - struct sim_ctrl **simctrls; - int chipcnt; - int ctrlcnt; -}; - -int parse_intarray(char *, int **); -int parse_config(char *, const char *); -int parse_section(struct rcfile *, const char *, int); -int compare_configs(struct nandsim_config *, struct nandsim_config *); -int convert_argint(char *, int *); -int convert_arguint(char *, unsigned int *); - -#endif /* _NANDSIM_CONFPARSER_H_ */ Property changes on: head/usr.sbin/nandsim/nandsim_cfgparse.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/Makefile.depend =================================================================== --- head/usr.sbin/nandsim/Makefile.depend (revision 349351) +++ head/usr.sbin/nandsim/Makefile.depend (nonexistent) @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Property changes on: head/usr.sbin/nandsim/Makefile.depend ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/nandsim.8 =================================================================== --- head/usr.sbin/nandsim/nandsim.8 (revision 349351) +++ head/usr.sbin/nandsim/nandsim.8 (nonexistent) @@ -1,229 +0,0 @@ -.\" Copyright (c) 2010 Semihalf -.\" 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 August 10, 2010 -.Dt NANDSIM 8 -.Os -.Sh NAME -.Nm nandsim -.Nd NAND simulator control program -.Sh SYNOPSIS -.Nm -.Ic status -.Aq ctrl_no | Fl -all | Fl a -.Op Fl v -.Nm -.Ic conf -.Aq filename -.Nm -.Ic start -.Aq ctrl_no -.Nm -.Ic mod -.Aq ctrl_no:cs_no | Fl l Aq loglevel -.Op Fl p Aq prog_time -.Op Fl e Aq erase_time -.Op Fl r Aq read_time -.Op Fl E Aq error_ratio -.Op Fl h -.Nm -.Ic stop -.Aq ctrl_no -.Nm -.Ic error -.Aq ctrl_no:cs_no -.Aq page_num -.Aq column -.Aq length -.Aq pattern -.Nm -.Ic bb -.Aq ctrl_no:cs_no -.Op blk_num,blk_num2,... -.Op Fl U -.Op Fl L -.Nm -.Ic freeze -.Op ctrl_no -.Nm -.Ic log -.Aq ctrl_no | Fl -all | Fl a -.Nm -.Ic stats -.Aq ctrl_no:cs_no -.Aq page_num -.Nm -.Ic dump -.Aq ctrl_no:cs_no -.Aq filename -.Nm -.Ic restore -.Aq ctrl_no:chip_no -.Aq filename -.Nm -.Ic destroy -.Aq ctrl_no[:cs_no] | Fl -all | Fl a -.Nm -.Ic help -.Op Fl v -.Sh COMMAND DESCRIPTION -Controllers and chips are arranged into a simple hierarchy. -There can be up to 4 controllers configured, each with 4 chip select (CS) lines. -A given chip is connected to one of the chip selects. -.Pp -Controllers are specified as -.Aq ctrl_no ; -chip selects are specified as -.Aq cs_no . -.Bl -tag -width periphlist -.It Ic status -Gets controller(s) status. If -.Fl a -or -.Fl -all -flag is specified - command will print status of every controller -currently available. -Optional flag -.Fl v -causes printing complete information about the controller, and all -chips attached to it. -.It Ic conf -Reads simulator configuration from a specified file (this includes -the simulation "layout" i.e. controllers-chips assignments). -Configuration changes for an already started simulation require a -full stop-start cycle in order to take effect i.e.: -.Bl -column -.It nandsim stop ... -.It nandsim destroy ... -.Pp -.It << edit config file >> -.Pp -.It nandsim conf ... -.It nandsim start ... -.El -.It Ic mod -Alters simulator parameters on-the-fly. -If controller number and CS pair is not specified, the general -simulator parameters (not specific to a controller or a chip) will be modified. -Changing chip's parameters requires specifying both controller number and CS -to which the given chip is connected. -Parameters which can be altered: -.Pp -General simulator related: -.Bl -tag -width flag -.It Fl l Aq log_level -change logging level to -.Aq log_level -.El -.Pp -Chip related: -.Bl -tag -width flag -.It Fl p Aq prog_time -change prog time for specified chip to -.Aq prog_time -.It Fl e Aq erase_time -change erase time for specified chip to -.Aq erase_time -.It Fl r Aq read_time -change read time for specified chip to -.Aq read_time -.It Fl E Aq error_ratio -change error ratio for specified chip to -.Aq error_ratio . -Error ratio is a number of errors per million read/write bytes. -.El -.Pp -Additionally, flag -.Fl h -will list parameters which can be altered. -.El -.Bl -tag -width periphlist -.It Ic bb -Marks/unmarks a specified block as bad. -To mark/unmark the bad condition an a block, the following parameters -have to be supplied: controller number, CS number, and at least one -block number. -It is possible to specify multiple blocks, by separating blocks numbers -with a comma. -The following options can be used for the 'bb' command: -.Bl -tag -width flag -.It Fl U -unmark the bad previously marked block as bad. -.It Fl L -list all blocks marked as bad on a given chip. -.El -.It Ic log -Prints activity log of the specified controller to stdout; if -controller number is not specified, logs for all available -controllers are printed. -.It Ic stats -Print statistics of the selected controller, chip and page. -Statistics includes read count, write count, raw read count, raw -write count, ECC stats (succeeded corrections, failed correction). -.It Ic dump -Dumps a snaphot of a single chip (including data and bad blocks -information, wearout level) into the file. -.It Ic restore -Restores chip state from a dump-file snapshot (produced previously -with the 'dump' command). -.It Ic start -Starts a controller i.e. the simulation. -.It Ic stop -Stops an already started controller; if the controller number is not -supplied, attempts to stop all currently working controllers. -.It Ic destroy -Removes existing active chip/controller and its configuration from -memory and releases the resources. -Specifying flag -.Fl a -or -.Fl -all -causes removal of every chip and controller. -Controller must be stopped in order to be destroyed. -.It Ic error -Directly overwrites a certain number of bytes in the specified page -at a given offset with a supplied pattern (which mimics the -corruption of flash contents). -.It Ic help -Prints synopsis, -.Fl v -gives more verbose output. -.It Ic freeze -Stops simulation of given controller (simulates power-loss). -All commands issues to any chip on this controller are ignored. -.El -.Sh SEE ALSO -.Xr nand 4 , -.Xr nandsim 4 , -.Xr nandsim.conf 5 -.Sh HISTORY -The -.Nm -utility first appeared in -.Fx 10.0 . -.Sh AUTHORS -This utility was written by -.An Lukasz Wojcik . Property changes on: head/usr.sbin/nandsim/nandsim.8 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/nandsim_rcfile.c =================================================================== --- head/usr.sbin/nandsim/nandsim_rcfile.c (revision 349351) +++ head/usr.sbin/nandsim/nandsim_rcfile.c (nonexistent) @@ -1,442 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1999, Boris Popov - * 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 author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - * - * from: FreeBSD: src/lib/libncp/ncpl_rcfile.c,v 1.5 2007/01/09 23:27:39 imp Exp - */ - -#include -__FBSDID("$FreeBSD$"); -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nandsim_rcfile.h" - -SLIST_HEAD(rcfile_head, rcfile); -static struct rcfile_head pf_head = {NULL}; -static struct rcsection *rc_findsect(struct rcfile *rcp, - const char *sectname, int sect_id); -static struct rcsection *rc_addsect(struct rcfile *rcp, - const char *sectname); -static int rc_sect_free(struct rcsection *rsp); -static struct rckey *rc_sect_findkey(struct rcsection *rsp, - const char *keyname); -static struct rckey *rc_sect_addkey(struct rcsection *rsp, const char *name, - char *value); -static void rc_key_free(struct rckey *p); -static void rc_parse(struct rcfile *rcp); - -static struct rcfile* rc_find(const char *filename); - -/* - * open rcfile and load its content, if already open - return previous handle - */ -int -rc_open(const char *filename, const char *mode,struct rcfile **rcfile) -{ - struct rcfile *rcp; - FILE *f; - rcp = rc_find(filename); - if (rcp) { - *rcfile = rcp; - return (0); - } - f = fopen (filename, mode); - if (f == NULL) - return errno; - rcp = malloc(sizeof(struct rcfile)); - if (rcp == NULL) { - fclose(f); - return ENOMEM; - } - bzero(rcp, sizeof(struct rcfile)); - rcp->rf_name = strdup(filename); - rcp->rf_f = f; - SLIST_INSERT_HEAD(&pf_head, rcp, rf_next); - rc_parse(rcp); - *rcfile = rcp; - return (0); -} - -int -rc_close(struct rcfile *rcp) -{ - struct rcsection *p,*n; - - fclose(rcp->rf_f); - for (p = SLIST_FIRST(&rcp->rf_sect); p; ) { - n = p; - p = SLIST_NEXT(p,rs_next); - rc_sect_free(n); - } - free(rcp->rf_name); - SLIST_REMOVE(&pf_head, rcp, rcfile, rf_next); - free(rcp); - return (0); -} - -static struct rcfile* -rc_find(const char *filename) -{ - struct rcfile *p; - - SLIST_FOREACH(p, &pf_head, rf_next) - if (strcmp (filename, p->rf_name) == 0) - return (p); - return (0); -} - -/* Find section with given name and id */ -static struct rcsection * -rc_findsect(struct rcfile *rcp, const char *sectname, int sect_id) -{ - struct rcsection *p; - - SLIST_FOREACH(p, &rcp->rf_sect, rs_next) - if (strcmp(p->rs_name, sectname) == 0 && p->rs_id == sect_id) - return (p); - return (NULL); -} - -static struct rcsection * -rc_addsect(struct rcfile *rcp, const char *sectname) -{ - struct rcsection *p; - int id = 0; - p = rc_findsect(rcp, sectname, 0); - if (p) { - /* - * If section with that name already exists -- add one more, - * same named, but with different id (higher by one) - */ - while (p != NULL) { - id = p->rs_id + 1; - p = rc_findsect(rcp, sectname, id); - } - } - p = malloc(sizeof(*p)); - if (!p) - return (NULL); - p->rs_name = strdup(sectname); - p->rs_id = id; - SLIST_INIT(&p->rs_keys); - SLIST_INSERT_HEAD(&rcp->rf_sect, p, rs_next); - return (p); -} - -static int -rc_sect_free(struct rcsection *rsp) -{ - struct rckey *p,*n; - - for (p = SLIST_FIRST(&rsp->rs_keys); p; ) { - n = p; - p = SLIST_NEXT(p,rk_next); - rc_key_free(n); - } - free(rsp->rs_name); - free(rsp); - return (0); -} - -static struct rckey * -rc_sect_findkey(struct rcsection *rsp, const char *keyname) -{ - struct rckey *p; - - SLIST_FOREACH(p, &rsp->rs_keys, rk_next) - if (strcmp(p->rk_name, keyname)==0) - return (p); - return (NULL); -} - -static struct rckey * -rc_sect_addkey(struct rcsection *rsp, const char *name, char *value) -{ - struct rckey *p; - p = rc_sect_findkey(rsp, name); - if (p) { - free(p->rk_value); - } else { - p = malloc(sizeof(*p)); - if (!p) - return (NULL); - SLIST_INSERT_HEAD(&rsp->rs_keys, p, rk_next); - p->rk_name = strdup(name); - } - p->rk_value = value ? strdup(value) : strdup(""); - return (p); -} - -static void -rc_key_free(struct rckey *p) -{ - free(p->rk_value); - free(p->rk_name); - free(p); -} - -enum { stNewLine, stHeader, stSkipToEOL, stGetKey, stGetValue}; - -static void -rc_parse(struct rcfile *rcp) -{ - FILE *f = rcp->rf_f; - int state = stNewLine, c; - struct rcsection *rsp = NULL; - struct rckey *rkp = NULL; - char buf[2048]; - char *next = buf, *last = &buf[sizeof(buf)-1]; - - while ((c = getc (f)) != EOF) { - if (c == '\r') - continue; - if (state == stNewLine) { - next = buf; - if (isspace(c)) - continue; /* skip leading junk */ - if (c == '[') { - state = stHeader; - rsp = NULL; - continue; - } - if (c == '#' || c == ';') { - state = stSkipToEOL; - } else { /* something meaningful */ - state = stGetKey; - } - } - if (state == stSkipToEOL || next == last) {/* ignore long lines */ - if (c == '\n') { - state = stNewLine; - next = buf; - } - continue; - } - if (state == stHeader) { - if (c == ']') { - *next = 0; - next = buf; - rsp = rc_addsect(rcp, buf); - state = stSkipToEOL; - } else - *next++ = c; - continue; - } - if (state == stGetKey) { - if (c == ' ' || c == '\t')/* side effect: 'key name='*/ - continue; /* become 'keyname=' */ - if (c == '\n') { /* silently ignore ... */ - state = stNewLine; - continue; - } - if (c != '=') { - *next++ = c; - continue; - } - *next = 0; - if (rsp == NULL) { - fprintf(stderr, "Key '%s' defined before " - "section\n", buf); - state = stSkipToEOL; - continue; - } - rkp = rc_sect_addkey(rsp, buf, NULL); - next = buf; - state = stGetValue; - continue; - } - /* only stGetValue left */ - if (state != stGetValue) { - fprintf(stderr, "Well, I can't parse file " - "'%s'\n",rcp->rf_name); - state = stSkipToEOL; - } - if (c != '\n') { - *next++ = c; - continue; - } - *next = 0; - rkp->rk_value = strdup(buf); - state = stNewLine; - rkp = NULL; - } /* while */ - if (c == EOF && state == stGetValue) { - *next = 0; - rkp->rk_value = strdup(buf); - } -} - -int -rc_getstringptr(struct rcfile *rcp, const char *section, int sect_id, - const char *key, char **dest) -{ - struct rcsection *rsp; - struct rckey *rkp; - - *dest = NULL; - rsp = rc_findsect(rcp, section, sect_id); - if (!rsp) - return (ENOENT); - rkp = rc_sect_findkey(rsp,key); - if (!rkp) - return (ENOENT); - *dest = rkp->rk_value; - return (0); -} - -int -rc_getstring(struct rcfile *rcp, const char *section, int sect_id, - const char *key, unsigned int maxlen, char *dest) -{ - char *value; - int error; - - error = rc_getstringptr(rcp, section, sect_id, key, &value); - if (error) - return (error); - if (strlen(value) >= maxlen) { - fprintf(stderr, "line too long for key '%s' in section '%s'," - "max = %d\n",key, section, maxlen); - return (EINVAL); - } - strcpy(dest,value); - return (0); -} - -int -rc_getint(struct rcfile *rcp, const char *section, int sect_id, - const char *key, int *value) -{ - struct rcsection *rsp; - struct rckey *rkp; - - rsp = rc_findsect(rcp, section, sect_id); - if (!rsp) - return (ENOENT); - rkp = rc_sect_findkey(rsp,key); - if (!rkp) - return (ENOENT); - errno = 0; - *value = strtol(rkp->rk_value,NULL,0); - if (errno) { - fprintf(stderr, "invalid int value '%s' for key '%s' in " - "section '%s'\n",rkp->rk_value,key,section); - return (errno); - } - return (0); -} - -/* - * 1,yes,true - * 0,no,false - */ -int -rc_getbool(struct rcfile *rcp, const char *section, int sect_id, - const char *key, int *value) -{ - struct rcsection *rsp; - struct rckey *rkp; - char *p; - - rsp = rc_findsect(rcp, section, sect_id); - if (!rsp) - return (ENOENT); - rkp = rc_sect_findkey(rsp,key); - if (!rkp) - return (ENOENT); - p = rkp->rk_value; - while (*p && isspace(*p)) p++; - if (*p == '0' || strcasecmp(p,"no") == 0 || - strcasecmp(p, "false") == 0 || - strcasecmp(p, "off") == 0) { - *value = 0; - return (0); - } - if (*p == '1' || strcasecmp(p,"yes") == 0 || - strcasecmp(p, "true") == 0 || - strcasecmp(p, "on") == 0) { - *value = 1; - return (0); - } - fprintf(stderr, "invalid boolean value '%s' for key '%s' in section " - "'%s' \n",p, key, section); - return (EINVAL); -} - -/* Count how many sections with given name exists in configuration. */ -int rc_getsectionscount(struct rcfile *f, const char *sectname) -{ - struct rcsection *p; - int count = 0; - - p = rc_findsect(f, sectname, 0); - if (p) { - while (p != NULL) { - count = p->rs_id + 1; - p = rc_findsect(f, sectname, count); - } - return (count); - } else - return (0); -} - -char ** -rc_getkeys(struct rcfile *rcp, const char *sectname, int sect_id) -{ - struct rcsection *rsp; - struct rckey *p; - char **names_tbl; - int i = 0, count = 0; - - rsp = rc_findsect(rcp, sectname, sect_id); - if (rsp == NULL) - return (NULL); - - SLIST_FOREACH(p, &rsp->rs_keys, rk_next) - count++; - - names_tbl = malloc(sizeof(char *) * (count + 1)); - if (names_tbl == NULL) - return (NULL); - - SLIST_FOREACH(p, &rsp->rs_keys, rk_next) - names_tbl[i++] = p->rk_name; - - names_tbl[i] = NULL; - return (names_tbl); -} - Property changes on: head/usr.sbin/nandsim/nandsim_rcfile.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/nandsim_rcfile.h =================================================================== --- head/usr.sbin/nandsim/nandsim_rcfile.h (revision 349351) +++ head/usr.sbin/nandsim/nandsim_rcfile.h (nonexistent) @@ -1,72 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1999, Boris Popov - * 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 author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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$ - * - * from: FreeBSD: src/lib/libncp/ncpl_rcfile.c,v 1.5 2007/01/09 23:27:39 imp Exp - */ - -#ifndef _SIMRC_H_ -#define _SIMRC_H_ - -#include - -struct rckey { - SLIST_ENTRY(rckey) rk_next; - char *rk_name; /* key name */ - char *rk_value; /* key value */ -}; - -struct rcsection { - SLIST_ENTRY(rcsection) rs_next; - SLIST_HEAD(rckey_head,rckey) rs_keys; /* key list */ - char *rs_name; /* section name */ - int rs_id; /* allow few same named */ -}; - -struct rcfile { - SLIST_ENTRY(rcfile) rf_next; - SLIST_HEAD(rcsec_head, rcsection) rf_sect; /* sections list */ - char *rf_name; /* file name */ - FILE *rf_f; /* file desc */ -}; - -int rc_open(const char *, const char *,struct rcfile **); -int rc_close(struct rcfile *); -int rc_getstringptr(struct rcfile *, const char *, int, const char *, - char **); -int rc_getstring(struct rcfile *, const char *, int, const char *, - unsigned int, char *); -int rc_getint(struct rcfile *, const char *, int, const char *, int *); -int rc_getbool(struct rcfile *, const char *, int, const char *, int *); -int rc_getsectionscount(struct rcfile *, const char *); -char **rc_getkeys(struct rcfile *, const char *, int); - -#endif /* _SIMRC_H_ */ Property changes on: head/usr.sbin/nandsim/nandsim_rcfile.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/Makefile =================================================================== --- head/usr.sbin/nandsim/Makefile (revision 349351) +++ head/usr.sbin/nandsim/Makefile (nonexistent) @@ -1,8 +0,0 @@ -# $FreeBSD$ - -PROG= nandsim -SRCS= nandsim.c nandsim_rcfile.c nandsim_cfgparse.c -BINDIR= /usr/sbin -MAN= nandsim.8 - -.include Property changes on: head/usr.sbin/nandsim/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/nandsim_cfgparse.c =================================================================== --- head/usr.sbin/nandsim/nandsim_cfgparse.c (revision 349351) +++ head/usr.sbin/nandsim/nandsim_cfgparse.c (nonexistent) @@ -1,961 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * 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 AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "nandsim_cfgparse.h" - -#define warn(fmt, args...) do { \ - printf("WARNING: " fmt "\n", ##args); } while (0) - -#define error(fmt, args...) do { \ - printf("ERROR: " fmt "\n", ##args); } while (0) - -#define MSG_MANDATORYKEYMISSING "mandatory key \"%s\" value belonging to " \ - "section \"%s\" is missing!\n" - -#define DEBUG -#undef DEBUG - -#ifdef DEBUG -#define debug(fmt, args...) do { \ - printf("NANDSIM_CONF:" fmt "\n", ##args); } while (0) -#else -#define debug(fmt, args...) do {} while(0) -#endif - -#define STRBUFSIZ 2000 - -/* Macros extracts type and type size */ -#define TYPE(x) ((x) & 0xf8) -#define SIZE(x) (((x) & 0x07)) - -/* Erase/Prog/Read time max and min values */ -#define DELAYTIME_MIN 10000 -#define DELAYTIME_MAX 10000000 - -/* Structure holding configuration for controller. */ -static struct sim_ctrl ctrl_conf; -/* Structure holding configuration for chip. */ -static struct sim_chip chip_conf; - -static struct nandsim_key nandsim_ctrl_keys[] = { - {"num_cs", 1, VALUE_UINT | SIZE_8, (void *)&ctrl_conf.num_cs, 0}, - {"ctrl_num", 1, VALUE_UINT | SIZE_8, (void *)&ctrl_conf.num, 0}, - - {"ecc_layout", 1, VALUE_UINTARRAY | SIZE_16, - (void *)&ctrl_conf.ecc_layout, MAX_ECC_BYTES}, - - {"filename", 0, VALUE_STRING, - (void *)&ctrl_conf.filename, FILENAME_SIZE}, - - {"ecc", 0, VALUE_BOOL, (void *)&ctrl_conf.ecc, 0}, - {NULL, 0, 0, NULL, 0}, -}; - -static struct nandsim_key nandsim_chip_keys[] = { - {"chip_cs", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.num, 0}, - {"chip_ctrl", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.ctrl_num, - 0}, - {"device_id", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.device_id, - 0}, - {"manufacturer_id", 1, VALUE_UINT | SIZE_8, - (void *)&chip_conf.manufact_id, 0}, - {"model", 0, VALUE_STRING, (void *)&chip_conf.device_model, - DEV_MODEL_STR_SIZE}, - {"manufacturer", 0, VALUE_STRING, (void *)&chip_conf.manufacturer, - MAN_STR_SIZE}, - {"page_size", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.page_size, - 0}, - {"oob_size", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.oob_size, - 0}, - {"pages_per_block", 1, VALUE_UINT | SIZE_32, - (void *)&chip_conf.pgs_per_blk, 0}, - {"blocks_per_lun", 1, VALUE_UINT | SIZE_32, - (void *)&chip_conf.blks_per_lun, 0}, - {"luns", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.luns, 0}, - {"column_addr_cycle", 1,VALUE_UINT | SIZE_8, - (void *)&chip_conf.col_addr_cycles, 0}, - {"row_addr_cycle", 1, VALUE_UINT | SIZE_8, - (void *)&chip_conf.row_addr_cycles, 0}, - {"program_time", 0, VALUE_UINT | SIZE_32, - (void *)&chip_conf.prog_time, 0}, - {"erase_time", 0, VALUE_UINT | SIZE_32, - (void *)&chip_conf.erase_time, 0}, - {"read_time", 0, VALUE_UINT | SIZE_32, - (void *)&chip_conf.read_time, 0}, - {"width", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.width, 0}, - {"wear_out", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.wear_level, - 0}, - {"bad_block_map", 0, VALUE_UINTARRAY | SIZE_32, - (void *)&chip_conf.bad_block_map, MAX_BAD_BLOCKS}, - {NULL, 0, 0, NULL, 0}, -}; - -static struct nandsim_section sections[] = { - {"ctrl", (struct nandsim_key *)&nandsim_ctrl_keys}, - {"chip", (struct nandsim_key *)&nandsim_chip_keys}, - {NULL, NULL}, -}; - -static uint8_t logoutputtoint(char *, int *); -static uint8_t validate_chips(struct sim_chip *, int, struct sim_ctrl *, int); -static uint8_t validate_ctrls(struct sim_ctrl *, int); -static int configure_sim(const char *, struct rcfile *); -static int create_ctrls(struct rcfile *, struct sim_ctrl **, int *); -static int create_chips(struct rcfile *, struct sim_chip **, int *); -static void destroy_ctrls(struct sim_ctrl *); -static void destroy_chips(struct sim_chip *); -static int validate_section_config(struct rcfile *, const char *, int); - -int -convert_argint(char *arg, int *value) -{ - - if (arg == NULL || value == NULL) - return (EINVAL); - - errno = 0; - *value = (int)strtol(arg, NULL, 0); - if (*value == 0 && errno != 0) { - error("Cannot convert to number argument \'%s\'", arg); - return (EINVAL); - } - return (0); -} - -int -convert_arguint(char *arg, unsigned int *value) -{ - - if (arg == NULL || value == NULL) - return (EINVAL); - - errno = 0; - *value = (unsigned int)strtol(arg, NULL, 0); - if (*value == 0 && errno != 0) { - error("Cannot convert to number argument \'%s\'", arg); - return (EINVAL); - } - return (0); -} - -/* Parse given ',' separated list of bytes into buffer. */ -int -parse_intarray(char *array, int **buffer) -{ - char *tmp, *tmpstr, *origstr; - unsigned int currbufp = 0, i; - unsigned int count = 0, from = 0, to = 0; - - /* Remove square braces */ - if (array[0] == '[') - array ++; - if (array[strlen(array)-1] == ']') - array[strlen(array)-1] = ','; - - from = strlen(array); - origstr = (char *)malloc(sizeof(char) * from); - strcpy(origstr, array); - - tmpstr = (char *)strtok(array, ","); - /* First loop checks for how big int array we need to allocate */ - while (tmpstr != NULL) { - errno = 0; - if ((tmp = strchr(tmpstr, '-')) != NULL) { - *tmp = ' '; - if (convert_arguint(tmpstr, &from) || - convert_arguint(tmp, &to)) { - free(origstr); - return (EINVAL); - } - - count += to - from + 1; - } else { - if (convert_arguint(tmpstr, &from)) { - free(origstr); - return (EINVAL); - } - count++; - } - tmpstr = (char *)strtok(NULL, ","); - } - - if (count == 0) - goto out; - - /* Allocate buffer of ints */ - tmpstr = (char *)strtok(origstr, ","); - *buffer = malloc(count * sizeof(int)); - - /* Second loop is just inserting converted values into int array */ - while (tmpstr != NULL) { - errno = 0; - if ((tmp = strchr(tmpstr, '-')) != NULL) { - *tmp = ' '; - from = strtol(tmpstr, NULL, 0); - to = strtol(tmp, NULL, 0); - tmpstr = strtok(NULL, ","); - for (i = from; i <= to; i ++) - (*buffer)[currbufp++] = i; - continue; - } - errno = 0; - from = (int)strtol(tmpstr, NULL, 0); - (*buffer)[currbufp++] = from; - tmpstr = (char *)strtok(NULL, ","); - } -out: - free(origstr); - return (count); -} - -/* Convert logoutput strings literals into appropriate ints. */ -static uint8_t -logoutputtoint(char *logoutput, int *output) -{ - int out; - - if (strcmp(logoutput, "file") == 0) - out = NANDSIM_OUTPUT_FILE; - - else if (strcmp(logoutput, "console") == 0) - out = NANDSIM_OUTPUT_CONSOLE; - - else if (strcmp(logoutput, "ram") == 0) - out = NANDSIM_OUTPUT_RAM; - - else if (strcmp(logoutput, "none") == 0) - out = NANDSIM_OUTPUT_NONE; - else - out = -1; - - *output = out; - - if (out == -1) - return (EINVAL); - else - return (0); -} - -static int -configure_sim(const char *devfname, struct rcfile *f) -{ - struct sim_param sim_conf; - char buf[255]; - int err, tmpv, fd; - - err = rc_getint(f, "sim", 0, "log_level", &tmpv); - - if (tmpv < 0 || tmpv > 255 || err) { - error("Bad log level specified (%d)\n", tmpv); - return (ENOTSUP); - } else - sim_conf.log_level = tmpv; - - rc_getstring(f, "sim", 0, "log_output", 255, (char *)&buf); - - tmpv = -1; - err = logoutputtoint((char *)&buf, &tmpv); - if (err) { - error("Log output specified in config file does not seem to " - "be valid (%s)!", (char *)&buf); - return (ENOTSUP); - } - - sim_conf.log_output = tmpv; - - fd = open(devfname, O_RDWR); - if (fd == -1) { - error("could not open simulator device file (%s)!", - devfname); - return (EX_OSFILE); - } - - err = ioctl(fd, NANDSIM_SIM_PARAM, &sim_conf); - if (err) { - error("simulator parameters could not be modified: %s", - strerror(errno)); - close(fd); - return (ENXIO); - } - - close(fd); - return (EX_OK); -} - -static int -create_ctrls(struct rcfile *f, struct sim_ctrl **ctrls, int *cnt) -{ - int count, i; - struct sim_ctrl *ctrlsptr; - - count = rc_getsectionscount(f, "ctrl"); - if (count > MAX_SIM_DEV) { - error("Too many CTRL sections specified(%d)", count); - return (ENOTSUP); - } else if (count == 0) { - error("No ctrl sections specified"); - return (ENOENT); - } - - ctrlsptr = (struct sim_ctrl *)malloc(sizeof(struct sim_ctrl) * count); - if (ctrlsptr == NULL) { - error("Could not allocate memory for ctrl configuration"); - return (ENOMEM); - } - - for (i = 0; i < count; i++) { - bzero((void *)&ctrl_conf, sizeof(ctrl_conf)); - - /* - * ECC layout have to end up with 0xffff, so - * we're filling buffer with 0xff. If ecc_layout is - * defined in config file, values will be overridden. - */ - memset((void *)&ctrl_conf.ecc_layout, 0xff, - sizeof(ctrl_conf.ecc_layout)); - - if (validate_section_config(f, "ctrl", i) != 0) { - free(ctrlsptr); - return (EINVAL); - } - - if (parse_section(f, "ctrl", i) != 0) { - free(ctrlsptr); - return (EINVAL); - } - - memcpy(&ctrlsptr[i], &ctrl_conf, sizeof(ctrl_conf)); - /* Try to create ctrl with config parsed */ - debug("NUM=%d\nNUM_CS=%d\nECC=%d\nFILENAME=%s\nECC_LAYOUT[0]" - "=%d\nECC_LAYOUT[1]=%d\n\n", - ctrlsptr[i].num, ctrlsptr[i].num_cs, ctrlsptr[i].ecc, - ctrlsptr[i].filename, ctrlsptr[i].ecc_layout[0], - ctrlsptr[i].ecc_layout[1]); - } - *cnt = count; - *ctrls = ctrlsptr; - return (0); -} - -static void -destroy_ctrls(struct sim_ctrl *ctrls) -{ - - free(ctrls); -} - -static int -create_chips(struct rcfile *f, struct sim_chip **chips, int *cnt) -{ - struct sim_chip *chipsptr; - int count, i; - - count = rc_getsectionscount(f, "chip"); - if (count > (MAX_CTRL_CS * MAX_SIM_DEV)) { - error("Too many chip sections specified(%d)", count); - return (ENOTSUP); - } else if (count == 0) { - error("No chip sections specified"); - return (ENOENT); - } - - chipsptr = (struct sim_chip *)malloc(sizeof(struct sim_chip) * count); - if (chipsptr == NULL) { - error("Could not allocate memory for chip configuration"); - return (ENOMEM); - } - - for (i = 0; i < count; i++) { - bzero((void *)&chip_conf, sizeof(chip_conf)); - - /* - * Bad block map have to end up with 0xffff, so - * we're filling array with 0xff. If bad block map is - * defined in config file, values will be overridden. - */ - memset((void *)&chip_conf.bad_block_map, 0xff, - sizeof(chip_conf.bad_block_map)); - - if (validate_section_config(f, "chip", i) != 0) { - free(chipsptr); - return (EINVAL); - } - - if (parse_section(f, "chip", i) != 0) { - free(chipsptr); - return (EINVAL); - } - - memcpy(&chipsptr[i], &chip_conf, sizeof(chip_conf)); - - /* Try to create chip with config parsed */ - debug("CHIP:\nNUM=%d\nCTRL_NUM=%d\nDEVID=%d\nMANID=%d\n" - "PAGE_SZ=%d\nOOBSZ=%d\nREAD_T=%d\nDEVMODEL=%s\n" - "MAN=%s\nCOLADDRCYCLES=%d\nROWADDRCYCLES=%d\nCHWIDTH=%d\n" - "PGS/BLK=%d\nBLK/LUN=%d\nLUNS=%d\nERR_RATIO=%d\n" - "WEARLEVEL=%d\nISWP=%d\n\n\n\n", - chipsptr[i].num, chipsptr[i].ctrl_num, - chipsptr[i].device_id, chipsptr[i].manufact_id, - chipsptr[i].page_size, chipsptr[i].oob_size, - chipsptr[i].read_time, chipsptr[i].device_model, - chipsptr[i].manufacturer, chipsptr[i].col_addr_cycles, - chipsptr[i].row_addr_cycles, chipsptr[i].width, - chipsptr[i].pgs_per_blk, chipsptr[i].blks_per_lun, - chipsptr[i].luns, chipsptr[i].error_ratio, - chipsptr[i].wear_level, chipsptr[i].is_wp); - } - *cnt = count; - *chips = chipsptr; - return (0); -} - -static void -destroy_chips(struct sim_chip *chips) -{ - - free(chips); -} - -int -parse_config(char *cfgfname, const char *devfname) -{ - int err = 0, fd; - unsigned int chipsectionscnt, ctrlsectionscnt, i; - struct rcfile *f; - struct sim_chip *chips; - struct sim_ctrl *ctrls; - - err = rc_open(cfgfname, "r", &f); - if (err) { - error("could not open configuration file (%s)", cfgfname); - return (EX_NOINPUT); - } - - /* First, try to configure simulator itself. */ - if (configure_sim(devfname, f) != EX_OK) { - rc_close(f); - return (EINVAL); - } - - debug("SIM CONFIGURED!\n"); - /* Then create controllers' configs */ - if (create_ctrls(f, &ctrls, &ctrlsectionscnt) != 0) { - rc_close(f); - return (ENXIO); - } - debug("CTRLS CONFIG READ!\n"); - - /* Then create chips' configs */ - if (create_chips(f, &chips, &chipsectionscnt) != 0) { - destroy_ctrls(ctrls); - rc_close(f); - return (ENXIO); - } - debug("CHIPS CONFIG READ!\n"); - - if (validate_ctrls(ctrls, ctrlsectionscnt) != 0) { - destroy_ctrls(ctrls); - destroy_chips(chips); - rc_close(f); - return (EX_SOFTWARE); - } - if (validate_chips(chips, chipsectionscnt, ctrls, - ctrlsectionscnt) != 0) { - destroy_ctrls(ctrls); - destroy_chips(chips); - rc_close(f); - return (EX_SOFTWARE); - } - - /* Open device */ - fd = open(devfname, O_RDWR); - if (fd == -1) { - error("could not open simulator device file (%s)!", - devfname); - rc_close(f); - destroy_chips(chips); - destroy_ctrls(ctrls); - return (EX_OSFILE); - } - - debug("SIM CONFIG STARTED!\n"); - - /* At this stage, both ctrls' and chips' configs should be valid */ - for (i = 0; i < ctrlsectionscnt; i++) { - err = ioctl(fd, NANDSIM_CREATE_CTRL, &ctrls[i]); - if (err) { - if (err == EEXIST) - error("Controller#%d already created\n", - ctrls[i].num); - else if (err == EINVAL) - error("Incorrect controller number (%d)\n", - ctrls[i].num); - else - error("Could not created controller#%d\n", - ctrls[i].num); - /* Errors during controller creation stops parsing */ - close(fd); - rc_close(f); - destroy_ctrls(ctrls); - destroy_chips(chips); - return (ENXIO); - } - debug("CTRL#%d CONFIG STARTED!\n", i); - } - - for (i = 0; i < chipsectionscnt; i++) { - err = ioctl(fd, NANDSIM_CREATE_CHIP, &chips[i]); - if (err) { - if (err == EEXIST) - error("Chip#%d for controller#%d already " - "created\n", chips[i].num, - chips[i].ctrl_num); - else if (err == EINVAL) - error("Incorrect chip number (%d:%d)\n", - chips[i].num, chips[i].ctrl_num); - else - error("Could not create chip (%d:%d)\n", - chips[i].num, chips[i].ctrl_num); - error("Could not start chip#%d\n", i); - destroy_chips(chips); - destroy_ctrls(ctrls); - close(fd); - rc_close(f); - return (ENXIO); - } - } - debug("CHIPS CONFIG STARTED!\n"); - - close(fd); - rc_close(f); - destroy_chips(chips); - destroy_ctrls(ctrls); - return (0); -} - -/* - * Function tries to get appropriate value for given key, convert it to - * array of ints (of given size), and perform all the necessary checks and - * conversions. - */ -static int -get_argument_intarray(const char *sect_name, int sectno, - struct nandsim_key *key, struct rcfile *f) -{ - char strbuf[STRBUFSIZ]; - int *intbuf; - int getres; - uint32_t cnt, i = 0; - - getres = rc_getstring(f, sect_name, sectno, key->keyname, STRBUFSIZ, - (char *)&strbuf); - - if (getres != 0) { - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - return (EINVAL); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - cnt = parse_intarray((char *)&strbuf, &intbuf); - cnt = (cnt <= key->maxlength) ? cnt : key->maxlength; - - for (i = 0; i < cnt; i++) { - if (SIZE(key->valuetype) == SIZE_8) - *((uint8_t *)(key->field) + i) = - (uint8_t)intbuf[i]; - else if (SIZE(key->valuetype) == SIZE_16) - *((uint16_t *)(key->field) + i) = - (uint16_t)intbuf[i]; - else - *((uint32_t *)(key->field) + i) = - (uint32_t)intbuf[i]; - } - free(intbuf); - return (0); -} - -/* - * Function tries to get appropriate value for given key, convert it to - * int of certain length. - */ -static int -get_argument_int(const char *sect_name, int sectno, struct nandsim_key *key, - struct rcfile *f) -{ - int getres; - uint32_t val; - - getres = rc_getint(f, sect_name, sectno, key->keyname, &val); - if (getres != 0) { - - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - - return (EINVAL); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - if (SIZE(key->valuetype) == SIZE_8) - *(uint8_t *)(key->field) = (uint8_t)val; - else if (SIZE(key->valuetype) == SIZE_16) - *(uint16_t *)(key->field) = (uint16_t)val; - else - *(uint32_t *)(key->field) = (uint32_t)val; - return (0); -} - -/* Function tries to get string value for given key */ -static int -get_argument_string(const char *sect_name, int sectno, - struct nandsim_key *key, struct rcfile *f) -{ - char strbuf[STRBUFSIZ]; - int getres; - - getres = rc_getstring(f, sect_name, sectno, key->keyname, STRBUFSIZ, - strbuf); - - if (getres != 0) { - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - return (1); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - strncpy(key->field, (char *)&strbuf, (size_t)(key->maxlength - 1)); - return (0); -} - -/* Function tries to get on/off value for given key */ -static int -get_argument_bool(const char *sect_name, int sectno, struct nandsim_key *key, - struct rcfile *f) -{ - int getres, val; - - getres = rc_getbool(f, sect_name, sectno, key->keyname, &val); - if (getres != 0) { - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - return (1); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - *(uint8_t *)key->field = (uint8_t)val; - return (0); -} - -int -parse_section(struct rcfile *f, const char *sect_name, int sectno) -{ - struct nandsim_key *key; - struct nandsim_section *sect = (struct nandsim_section *)§ions; - int getres = 0; - - while (1) { - if (sect == NULL) - return (EINVAL); - - if (strcmp(sect->name, sect_name) == 0) - break; - else - sect++; - } - key = sect->keys; - do { - debug("->Section: %s, Key: %s, type: %d, size: %d", - sect_name, key->keyname, TYPE(key->valuetype), - SIZE(key->valuetype)/2); - - switch (TYPE(key->valuetype)) { - case VALUE_UINT: - /* Single int value */ - getres = get_argument_int(sect_name, sectno, key, f); - - if (getres != 0) - return (getres); - - break; - case VALUE_UINTARRAY: - /* Array of ints */ - getres = get_argument_intarray(sect_name, - sectno, key, f); - - if (getres != 0) - return (getres); - - break; - case VALUE_STRING: - /* Array of chars */ - getres = get_argument_string(sect_name, sectno, key, - f); - - if (getres != 0) - return (getres); - - break; - case VALUE_BOOL: - /* Boolean value (true/false/on/off/yes/no) */ - getres = get_argument_bool(sect_name, sectno, key, - f); - - if (getres != 0) - return (getres); - - break; - } - } while ((++key)->keyname != NULL); - - return (0); -} - -static uint8_t -validate_chips(struct sim_chip *chips, int chipcnt, - struct sim_ctrl *ctrls, int ctrlcnt) -{ - int cchipcnt, i, width, j, id, max; - - cchipcnt = chipcnt; - for (chipcnt -= 1; chipcnt >= 0; chipcnt--) { - if (chips[chipcnt].num >= MAX_CTRL_CS) { - error("chip no. too high (%d)!!\n", - chips[chipcnt].num); - return (EINVAL); - } - - if (chips[chipcnt].ctrl_num >= MAX_SIM_DEV) { - error("controller no. too high (%d)!!\n", - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - if (chips[chipcnt].width != 8 && - chips[chipcnt].width != 16) { - error("invalid width:%d for chip#%d", - chips[chipcnt].width, chips[chipcnt].num); - return (EINVAL); - } - - /* Check if page size is > 512 and if its power of 2 */ - if (chips[chipcnt].page_size < 512 || - (chips[chipcnt].page_size & - (chips[chipcnt].page_size - 1)) != 0) { - error("invalid page size:%d for chip#%d at ctrl#%d!!" - "\n", chips[chipcnt].page_size, - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - /* Check if controller no. ctrl_num is configured */ - for (i = 0, id = -1; i < ctrlcnt && id == -1; i++) - if (ctrls[i].num == chips[chipcnt].ctrl_num) - id = i; - - if (i == ctrlcnt && id == -1) { - error("Missing configuration for controller %d" - " (at least one chip is connected to it)", - chips[chipcnt].ctrl_num); - return (EINVAL); - } else { - /* - * Controller is configured -> check oob_size - * validity - */ - i = 0; - max = ctrls[id].ecc_layout[0]; - while (i < MAX_ECC_BYTES && - ctrls[id].ecc_layout[i] != 0xffff) { - - if (ctrls[id].ecc_layout[i] > max) - max = ctrls[id].ecc_layout[i]; - i++; - } - - if (chips[chipcnt].oob_size < (unsigned)i) { - error("OOB size for chip#%d at ctrl#%d is " - "smaller than ecc layout length!", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - exit(EINVAL); - } - - if (chips[chipcnt].oob_size < (unsigned)max) { - error("OOB size for chip#%d at ctrl#%d is " - "smaller than maximal ecc position in " - "defined layout!", chips[chipcnt].num, - chips[chipcnt].ctrl_num); - exit(EINVAL); - } - - - } - - if ((chips[chipcnt].erase_time < DELAYTIME_MIN || - chips[chipcnt].erase_time > DELAYTIME_MAX) && - chips[chipcnt].erase_time != 0) { - error("Invalid erase time value for chip#%d at " - "ctrl#%d", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - if ((chips[chipcnt].prog_time < DELAYTIME_MIN || - chips[chipcnt].prog_time > DELAYTIME_MAX) && - chips[chipcnt].prog_time != 0) { - error("Invalid prog time value for chip#%d at " - "ctr#%d!", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - if ((chips[chipcnt].read_time < DELAYTIME_MIN || - chips[chipcnt].read_time > DELAYTIME_MAX) && - chips[chipcnt].read_time != 0) { - error("Invalid read time value for chip#%d at " - "ctrl#%d!", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - } - /* Check if chips attached to the same controller, have same width */ - for (i = 0; i < ctrlcnt; i++) { - width = -1; - for (j = 0; j < cchipcnt; j++) { - if (chips[j].ctrl_num == i) { - if (width == -1) { - width = chips[j].width; - } else { - if (width != chips[j].width) { - error("Chips attached to " - "ctrl#%d have different " - "widths!\n", i); - return (EINVAL); - } - } - } - } - } - - return (0); -} - -static uint8_t -validate_ctrls(struct sim_ctrl *ctrl, int ctrlcnt) -{ - for (ctrlcnt -= 1; ctrlcnt >= 0; ctrlcnt--) { - if (ctrl[ctrlcnt].num > MAX_SIM_DEV) { - error("Controller no. too high (%d)!!\n", - ctrl[ctrlcnt].num); - return (EINVAL); - } - if (ctrl[ctrlcnt].num_cs > MAX_CTRL_CS) { - error("Too many CS (%d)!!\n", ctrl[ctrlcnt].num_cs); - return (EINVAL); - } - if (ctrl[ctrlcnt].ecc != 0 && ctrl[ctrlcnt].ecc != 1) { - error("ECC is set to neither 0 nor 1 !\n"); - return (EINVAL); - } - } - - return (0); -} - -static int validate_section_config(struct rcfile *f, const char *sect_name, - int sectno) -{ - struct nandsim_key *key; - struct nandsim_section *sect; - char **keys_tbl; - int i, match; - - for (match = 0, sect = (struct nandsim_section *)§ions; - sect != NULL; sect++) { - if (strcmp(sect->name, sect_name) == 0) { - match = 1; - break; - } - } - - if (match == 0) - return (EINVAL); - - keys_tbl = rc_getkeys(f, sect_name, sectno); - if (keys_tbl == NULL) - return (ENOMEM); - - for (i = 0; keys_tbl[i] != NULL; i++) { - key = sect->keys; - match = 0; - do { - if (strcmp(keys_tbl[i], key->keyname) == 0) { - match = 1; - break; - } - } while ((++key)->keyname != NULL); - - if (match == 0) { - error("Invalid key in config file: %s\n", keys_tbl[i]); - free(keys_tbl); - return (EINVAL); - } - } - - free(keys_tbl); - return (0); -} Property changes on: head/usr.sbin/nandsim/nandsim_cfgparse.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandsim/sample.conf =================================================================== --- head/usr.sbin/nandsim/sample.conf (revision 349351) +++ head/usr.sbin/nandsim/sample.conf (nonexistent) @@ -1,174 +0,0 @@ -#- -# Copyright (C) 2009-2012 Semihalf -# 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$ - -# -# Sample NANDsim configuration file. -# - -############################################################################# -# -# [sim] General (common) simulator configuration section. -# -[sim] -# log_level=0..255 -log_level=11 - -# log_output=[none, console, ram, file] -# -# When log_output=file is specified, each [ctrl] section must have a -# corresponding 'log_filename' field provided, which specifies log file name -# to be used. -log_output=none - -############################################################################# -# -# [ctrl] Controller configuration section. -# -# There can be a number of controllers defined for simulation, each has a -# dedicated [ctrl] section. With a given controller there are associated -# subordinate NAND chips, which are tied to chip select lines. -# -[ctrl] -# The number of this controller. -# ctrl_num=0..3 -ctrl_num=0 - -# The number of chip selects available at this controller. -# num_cs=1..4 -num_cs=1 - -# ECC enable flag. -# ecc=[on|off] -ecc=on - -# ECC layout. This is the list of byte offsets within OOB area, which comprise -# the ECC contents set. -# -# ecc_layout=[byte1, byte2-byte3, ..byten] -ecc_layout=[0-53] - -# Absolute path to the log file for this controller. -#log_filename=/var/log/nandsim-ctl0.log - - -############################################################################# -# -# [chip] Chip configuration section. -# -# There can be a number of individual NAND chip devices defined for -# simulation, and each has a dedicated [chip] section. -# -# A particular chip needs to be associated with its parent NAND controller by -# specifying the following fields: controller number (chip_ctrl) and the chip -# select line it is connected to (chip_cs). The chip can be connected to only -# a single (and unique) controller:cs pair. -# -[chip] -# The number of parent controller. This has to fit one of the controller -# instance number (ctrl_num from [ctrl] section). -# chip_ctrl=0..3 -chip_ctrl=0 - -# Chip select line. -# chip_cs=0..3 -chip_cs=0 - -# ONFI device identifier. -# device_id=0x00..0xff -device_id=0xd3 - -# ONFI manufacturer identifier. -# manufacturer_id=0x00..0xff -manufacturer_id=0xec - -# Textual description of the chip. -# model="model_name" -model="k9xxg08uxM:1GiB 3,3V 8-bit" - -# Textual name of the chip manufacturer. -# manufacturer="manufacturer name" -manufacturer="SAMSUNG" - -# page_size=[must be power of 2 and >= 512] (in bytes) -page_size=2048 -# oob_size=[>0] -oob_size=64 -# pages_per_block=n*32 -pages_per_block=64 -# blocks_per_lun=[>0] -blocks_per_lun=4096 -# luns=1..N -luns=1 -# column_addr_cycle=[1,2] -column_addr_cycle=2 -# row_addr_cycle=[1,2,3] -row_addr_cycle=3 - -# program_time= (in us) -program_time=0 -# erase_time= (in us) -erase_time=0 -# read_time= (in us) -read_time=0 -# ccs_time= (in us) -#ccs_time=200 - -# Simulate write-protect on the chip. -# write_protect=[yes|no] -#write_protect=no - -# Blocks wear-out threshold. Each block has a counter of program-erase cycles; -# when this counter reaches 'wear_out' value a given block is treated as a bad -# block (access will report error). -# -# Setting wear_out to 0 means that blocks will never wear out. -# -# wear_out=0..100000 -wear_out=50000 - -# Errors per million read/write bytes. This simulates an accidental read/write -# block error, which can happen in real devices with certain probability. Note -# this isn't a bad block condition i.e. the block at which the read/write -# operation is simulated to fail here remains usable, only the operation has -# not succeeded (this is where ECC comes into play and is supposed to correct -# such problems). -# -# error_ratio=0..1000000 -#error_ratio=50 - -# Chip data bus width. All chips connected to the same controller must have -# the same bus width. -# -# width=[8|16] -width=8 - -# Bad block map. NANDsim emulates bad block behavior upon accessing a block -# with number from the specified list. -# -# bad_block_map=[bad_block1, bad_block2-bad_block3, ..bad_blockn] -bad_block_map=[100-200] - Property changes on: head/usr.sbin/nandsim/sample.conf ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/usage.h =================================================================== --- head/usr.sbin/nandtool/usage.h (revision 349351) +++ head/usr.sbin/nandtool/usage.h (nonexistent) @@ -1,114 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * 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 __USAGE_H -#define __USAGE_H - -static const char nand_help_usage[] = - "Usage: %s help topic=\n" - "\n" - "Arguments:\n" - "\tcmd\t- [help|read|write|erase|readoob|writeoob|info]\n" - "\n"; - -static const char nand_read_usage[] = - "Usage: %s read dev= (block|page|pos)=n [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tblock\t- starting block or\n" - "\tpage\t- starting page or\n" - "\tpos\t- starting position (in bytes, must be page-aligned)\n" - "\tout\t- output file (hexdump to stdout if not supplied)\n" - "\n" - "Note that you can only specify only one of: 'block', 'page', 'pos'\n" - "parameters at once. 'count' parameter is meaningful in terms of used\n" - "unit (page, block or byte).\n"; - -static const char nand_write_usage[] = - "Usage: %s write dev= in= (block|page|pos)=n [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tin\t- path to input file which be writed to gnand\n" - "\tblock\t- starting block or\n" - "\tpage\t- starting page or\n" - "\tpos\t- starting position (in bytes, must be page-aligned)\n" - "\tcount\t- byte/page/block count\n" - "\n" - ""; - -static const char nand_erase_usage[] = - "Usage: %s erase dev= (block|page|pos)=n [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tblock\t- starting block or\n" - "\tpage\t- starting page or\n" - "\tpos\t- starting position (in bytes, muse be block-aligned)\n" - "\tcount\t- byte/page/block count\n" - "\n" - "NOTE: position and count for erase operation MUST be block-aligned\n"; - -static const char nand_read_oob_usage[] = - "Usage: %s readoob dev= page=n [out=file] [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tpage\t- page (page) number\n" - "\tout\t- outut file (hexdump to stdout if not supplied)\n" - "\tcount\t- page count (default is 1)\n" - "\n" - "If you supply count parameter with value other than 1, data will be\n" - "read from subsequent page's OOB areas\n"; - -static const char nand_write_oob_usage[] = - "Usage: %s writeoob dev= in= page=n [count=n]\n" - "\n" - "\tdev\t- path to gnand device node\n" - "\tin\t- path to file containing data which will be written\n" - "\tpage\t- page (page) number\n" - "\n" - "If you supply count parameter with value other than 1, data will be\n" - "written to subsequent page's OOB areas\n"; - -static const char nand_info_usage[] = - "Usage: %s info dev=\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n"; - -static const char nand_stats_usage[] = - "Usage: %s stats dev= (page|block)=\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n"; - -#endif /* __USAGE_H */ Property changes on: head/usr.sbin/nandtool/usage.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nandtool.c =================================================================== --- head/usr.sbin/nandtool/nandtool.c (revision 349351) +++ head/usr.sbin/nandtool/nandtool.c (nonexistent) @@ -1,285 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" -#include "usage.h" - -int usage(struct cmd_param *); - -static const struct { - const char *name; - const char *usage; - int (*handler)(struct cmd_param *); -} commands[] = { - { "help", nand_help_usage, usage }, - { "read", nand_read_usage, nand_read }, - { "write", nand_write_usage, nand_write }, - { "erase", nand_erase_usage, nand_erase }, - { "readoob", nand_read_oob_usage, nand_read_oob }, - { "writeoob", nand_write_oob_usage, nand_write_oob }, - { "info", nand_info_usage, nand_info }, - { NULL, NULL, NULL }, -}; - -static char * -_param_get_stringx(struct cmd_param *params, const char *name, int doexit) -{ - int i; - - for (i = 0; params[i].name[0] != '\0'; i++) { - if (!strcmp(params[i].name, name)) - return params[i].value; - } - - if (doexit) { - perrorf("Missing parameter %s", name); - exit(1); - } - return (NULL); -} - -char * -param_get_string(struct cmd_param *params, const char *name) -{ - - return (_param_get_stringx(params, name, 0)); -} - -static int -_param_get_intx(struct cmd_param *params, const char *name, int doexit) -{ - int ret; - char *str = _param_get_stringx(params, name, doexit); - - if (!str) - return (-1); - - errno = 0; - ret = (int)strtol(str, (char **)NULL, 10); - if (errno) { - if (doexit) { - perrorf("Invalid value for parameter %s", name); - exit(1); - } - return (-1); - } - - return (ret); -} - -int -param_get_intx(struct cmd_param *params, const char *name) -{ - - return (_param_get_intx(params, name, 1)); -} - -int -param_get_int(struct cmd_param *params, const char *name) -{ - - return (_param_get_intx(params, name, 0)); -} - -int -param_get_boolean(struct cmd_param *params, const char *name) -{ - char *str = param_get_string(params, name); - - if (!str) - return (0); - - if (!strcmp(str, "true") || !strcmp(str, "yes")) - return (1); - - return (0); -} - -int -param_has_value(struct cmd_param *params, const char *name) -{ - int i; - - for (i = 0; params[i].name[0] != '\0'; i++) { - if (!strcmp(params[i].name, name)) - return (1); - } - - return (0); -} - -int -param_get_count(struct cmd_param *params) -{ - int i; - - for (i = 0; params[i].name[0] != '\0'; i++); - - return (i); -} - -void -hexdumpoffset(uint8_t *buf, int length, int off) -{ - int i, j; - for (i = 0; i < length; i += 16) { - printf("%08x: ", off + i); - - for (j = 0; j < 16; j++) - printf("%02x ", buf[i+j]); - - printf("| "); - - for (j = 0; j < 16; j++) { - printf("%c", isalnum(buf[i+j]) - ? buf[i+j] - : '.'); - } - - printf("\n"); - } -} - -void -hexdump(uint8_t *buf, int length) -{ - - hexdumpoffset(buf, length, 0); -} - -void * -xmalloc(size_t len) -{ - void *ret = malloc(len); - - if (!ret) { - fprintf(stderr, "Cannot allocate buffer of %zd bytes. " - "Exiting.\n", len); - exit(EX_OSERR); - } - - return (ret); -} - -void -perrorf(const char *format, ...) -{ - va_list args; - - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, ": %s\n", strerror(errno)); -} - -int -usage(struct cmd_param *params) -{ - int i; - - if (!params || !param_get_count(params)) { - fprintf(stderr, "Usage: nandtool [arguments...]\n"); - fprintf(stderr, "Arguments are in form 'name=value'.\n\n"); - fprintf(stderr, "Available commands:\n"); - - for (i = 0; commands[i].name != NULL; i++) - fprintf(stderr, "\t%s\n", commands[i].name); - - fprintf(stderr, "\n"); - fprintf(stderr, "For information about particular command, " - "type:\n"); - fprintf(stderr, "'nandtool help topic='\n"); - } else if (param_has_value(params, "topic")) { - for (i = 0; commands[i].name != NULL; i++) { - if (!strcmp(param_get_string(params, "topic"), - commands[i].name)) { - fprintf(stderr, commands[i].usage, "nandtool"); - return (0); - } - } - - fprintf(stderr, "No such command\n"); - return (EX_SOFTWARE); - } else { - fprintf(stderr, "Wrong arguments given. Try: 'nandtool help'\n"); - } - - return (EX_USAGE); -} - -int -main(int argc, const char *argv[]) -{ - struct cmd_param *params; - int i, ret, idx; - - if (argc < 2) { - usage(NULL); - return (0); - } - - params = malloc(sizeof(struct cmd_param) * (argc - 1)); - - for (i = 2, idx = 0; i < argc; i++, idx++) { - if (sscanf(argv[i], "%63[^=]=%63s", params[idx].name, - params[idx].value) < 2) { - fprintf(stderr, "Syntax error in argument %d. " - "Argument should be in form 'name=value'.\n", i); - free(params); - return (-1); - } - } - - params[idx].name[0] = '\0'; - params[idx].value[0] = '\0'; - - for (i = 0; commands[i].name != NULL; i++) { - if (!strcmp(commands[i].name, argv[1])) { - ret = commands[i].handler(params); - free(params); - return (ret); - } - } - - free(params); - fprintf(stderr, "Unknown command. Try '%s help'\n", argv[0]); - - return (-1); -} - Property changes on: head/usr.sbin/nandtool/nandtool.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nand_readoob.c =================================================================== --- head/usr.sbin/nandtool/nand_readoob.c (revision 349351) +++ head/usr.sbin/nandtool/nand_readoob.c (nonexistent) @@ -1,113 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" - -int nand_read_oob(struct cmd_param *params) -{ - struct chip_param_io chip_params; - struct nand_oob_rw req; - char *dev, *out; - int fd = -1, fd_out = -1, ret = 0; - int page; - uint8_t *buf = NULL; - - if ((page = param_get_int(params, "page")) < 0) { - fprintf(stderr, "You must supply valid 'page' argument.\n"); - return (1); - } - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "You must supply 'dev' argument.\n"); - return (1); - } - - if ((out = param_get_string(params, "out"))) { - if ((fd_out = open(out, O_WRONLY | O_CREAT, 0666)) == -1) { - perrorf("Cannot open %s", out); - ret = 1; - goto out; - } - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - buf = malloc(chip_params.oob_size); - if (buf == NULL) { - perrorf("Cannot allocate %d bytes\n", chip_params.oob_size); - ret = 1; - goto out; - } - - req.page = page; - req.len = chip_params.oob_size; - req.data = buf; - - if (ioctl(fd, NAND_IO_OOB_READ, &req) == -1) { - perrorf("Cannot read OOB from %s", dev); - ret = 1; - goto out; - } - - if (fd_out != -1) - write(fd_out, buf, chip_params.oob_size); - else - hexdump(buf, chip_params.oob_size); - -out: - close(fd_out); - - if (fd != -1) - g_close(fd); - if (buf) - free(buf); - - return (ret); -} - Property changes on: head/usr.sbin/nandtool/nand_readoob.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/Makefile.depend =================================================================== --- head/usr.sbin/nandtool/Makefile.depend (revision 349351) +++ head/usr.sbin/nandtool/Makefile.depend (nonexistent) @@ -1,20 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libexpat \ - lib/libgeom \ - lib/libsbuf \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif Property changes on: head/usr.sbin/nandtool/Makefile.depend ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nandtool.8 =================================================================== --- head/usr.sbin/nandtool/nandtool.8 (revision 349351) +++ head/usr.sbin/nandtool/nandtool.8 (nonexistent) @@ -1,184 +0,0 @@ -.\" Copyright (c) 2010 Semihalf -.\" 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 April 10, 2012 -.Dt NANDTOOL 8 -.Os -.Sh NAME -.Nm nandtool -.Nd NAND devices swiss army knife -.Sh SYNOPSIS -.Nm -.Ar command -.Op Ar operands ... -.Sh DESCRIPTION -The -.Nm -utility can be used to perform various operations on -.Xr gnand 4 -devices (read, write, erase, -read and write OOB area and to get info about NAND flash chip). -.Pp -The following commands are available: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm read Ns -Read pages from NAND device. -.It Cm write Ns -Write pages to NAND device. -.It Cm erase Ns -Erase blocks. -Requires offset aligned to block granularity. -.It Cm info Ns -Get information about NAND chip (page size, block size, OOB area size, chip size -and media size) -.It Cm readoob Ns -Read OOB area from specified page. -.It Cm writeoob Ns -Write OOB area bound to specified page. -.It Cm help Ns -Get usage info. -.El -.Sh COMMAND read -The following operands are available for -.Nm -.Cm read -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar -Path to a -.Xr gnand 4 -device node, required for all operations. -.It Cm out Ns = Ns Ar -Output file path. If not specified, page contents -will be dumped to stdout in format similar to -.Xr hexdump 1 -.It Cm page Ns = Ns Ar -Offset on device, expressed as page number. -.It Cm block Ns = Ns Ar -Offset on device, expressed as block number. -.It Cm pos Ns = Ns Ar -Offset on device, expressed in bytes (however, must be aligned -to page granularity). -.It Cm count Ns = Ns Ar -Count of objects (pages, blocks, bytes). -.El -.Sh COMMAND readoob -The following operands are available for -.Nm -.Cm readoob -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar -Path to NAND device node. -.It Cm page Ns = Ns Ar -Offset on device, expressed as page number. -.It Cm out Ns = Ns Ar -Output file path, optional. -.El -.Sh COMMAND write -The following operands are available for -.Nm -.Cm write -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar -Path to NAND device node. -.It Cm page Ns = Ns Ar -Offset on device, expressed as page number. -.It Cm block Ns = Ns Ar -Offset on device, expressed as block number. -.It Cm pos Ns = Ns Ar -Offset on device, expressed in bytes (however, must be aligned -to page granularity). -.It Cm in Ns = Ns Ar -Input file path. -.El -.Sh COMMAND writeoob -The following operands are available for -.Nm -.Cm writeoob -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar -Path to NAND device node. -.It Cm page Ns = Ns Ar -Offset on device, expressed as page number. -.It Cm in Ns = Ns Ar -Input file path. -.El -.Sh COMMAND erase -The following operands are available for -.Nm -.Cm erase -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar -Path to NAND device node. -.It Cm page Ns = Ns Ar -Offset on device, expressed as page number. -.It Cm block Ns = Ns Ar -Offset on device, expressed as block number. -.It Cm pos Ns = Ns Ar -Offset on device, epressed in bytes (however, must be aligned -to block granularity). -.It Cm count Ns = Ns Ar -Count of objects (pages, blocks, bytes). -.El -.Pp -WARNING: The only required parameter for the \fBerase\fP command is -.Ar dev . -When no other arguments are provided the whole device is erased! -.Sh COMMAND info -There is only one operand available for -.Nm -.Cm info -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar -Path to NAND device node. -.El -.Sh COMMAND help -There is only one operand available for -.Nm -.Cm help -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm topic Ns = Ns Ar -Help topic. -.El -.Sh EXIT STATUS -.Ex -std -If the supplied argument -.Ar dev -points to a device node other than gnand or gnand.raw both -.Nm -.Cm readoob -and -.Nm -.Cm writeoob -return error. -.Sh SEE ALSO -.Xr gnand 4 Property changes on: head/usr.sbin/nandtool/nandtool.8 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nandtool.h =================================================================== --- head/usr.sbin/nandtool/nandtool.h (revision 349351) +++ head/usr.sbin/nandtool/nandtool.h (nonexistent) @@ -1,59 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * 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 __UTILS_H -#define __UTILS_H - -struct cmd_param -{ - char name[64]; - char value[64]; -}; - -char *param_get_string(struct cmd_param *, const char *); -int param_get_int(struct cmd_param *, const char *); -int param_get_intx(struct cmd_param *, const char *); -int param_get_boolean(struct cmd_param *, const char *); -int param_has_value(struct cmd_param *, const char *); -int param_get_count(struct cmd_param *); -void perrorf(const char *, ...); -void hexdumpoffset(uint8_t *, int, int); -void hexdump(uint8_t *, int); -void *xmalloc(size_t); - -/* Command handlers */ -int nand_read(struct cmd_param *); -int nand_write(struct cmd_param *); -int nand_read_oob(struct cmd_param *); -int nand_write_oob(struct cmd_param *); -int nand_erase(struct cmd_param *); -int nand_info(struct cmd_param *); - -#endif /* __UTILS_H */ Property changes on: head/usr.sbin/nandtool/nandtool.h ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nand_erase.c =================================================================== --- head/usr.sbin/nandtool/nand_erase.c (revision 349351) +++ head/usr.sbin/nandtool/nand_erase.c (nonexistent) @@ -1,116 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" - -int nand_erase(struct cmd_param *params) -{ - struct chip_param_io chip_params; - char *dev; - int fd = -1, ret = 0; - off_t pos, count; - off_t start, nblocks, i; - int block_size, mult; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "Please supply valid 'dev' parameter.\n"); - return (1); - } - - if (param_has_value(params, "count")) - count = param_get_intx(params, "count"); - else - count = 1; - - if ((fd = g_open(dev, 1)) < 0) { - perrorf("Cannot open %s", dev); - return (1); - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - - if (param_has_value(params, "page")) { - pos = chip_params.page_size * param_get_intx(params, "page"); - mult = chip_params.page_size; - } else if (param_has_value(params, "block")) { - pos = block_size * param_get_intx(params, "block"); - mult = block_size; - } else if (param_has_value(params, "pos")) { - pos = param_get_intx(params, "pos"); - mult = 1; - } else { - /* Erase whole chip */ - if (ioctl(fd, DIOCGMEDIASIZE, &count) == -1) { - ret = 1; - goto out; - } - - pos = 0; - mult = 1; - } - - if (pos % block_size) { - fprintf(stderr, "Position must be block-size aligned!\n"); - ret = 1; - goto out; - } - - count *= mult; - start = pos / block_size; - nblocks = count / block_size; - - for (i = 0; i < nblocks; i++) { - if (g_delete(fd, (start + i) * block_size, block_size) == -1) { - perrorf("Cannot erase block %d - probably a bad block", - start + i); - ret = 1; - } - } - -out: - g_close(fd); - - return (ret); -} - Property changes on: head/usr.sbin/nandtool/nand_erase.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nand_write.c =================================================================== --- head/usr.sbin/nandtool/nand_write.c (revision 349351) +++ head/usr.sbin/nandtool/nand_write.c (nonexistent) @@ -1,145 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" - -int nand_write(struct cmd_param *params) -{ - struct chip_param_io chip_params; - char *dev, *file; - int in_fd = -1, ret = 0, done = 0; - int fd, block_size, mult, pos, count; - uint8_t *buf = NULL; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "Please supply 'dev' argument.\n"); - return (1); - } - - if (!(file = param_get_string(params, "in"))) { - fprintf(stderr, "Please supply 'in' argument.\n"); - return (1); - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - return (1); - } - - if ((in_fd = open(file, O_RDONLY)) == -1) { - perrorf("Cannot open file %s", file); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - - if (param_has_value(params, "page")) { - pos = chip_params.page_size * param_get_int(params, "page"); - mult = chip_params.page_size; - } else if (param_has_value(params, "block")) { - pos = block_size * param_get_int(params, "block"); - mult = block_size; - } else if (param_has_value(params, "pos")) { - pos = param_get_int(params, "pos"); - mult = 1; - if (pos % chip_params.page_size) { - fprintf(stderr, "Position must be page-size " - "aligned!\n"); - ret = 1; - goto out; - } - } else { - fprintf(stderr, "You must specify one of: 'block', 'page'," - "'pos' arguments\n"); - ret = 1; - goto out; - } - - if (!(param_has_value(params, "count"))) - count = mult; - else - count = param_get_int(params, "count") * mult; - - if (!(buf = malloc(chip_params.page_size))) { - perrorf("Cannot allocate buffer [size %x]", - chip_params.page_size); - ret = 1; - goto out; - } - - lseek(fd, pos, SEEK_SET); - - while (done < count) { - if ((ret = read(in_fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - if (ret > 0) { - /* End of file ahead, truncate here */ - break; - } else { - perrorf("Cannot read from %s", file); - ret = 1; - goto out; - } - } - - if ((ret = write(fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - ret = 1; - goto out; - } - - done += ret; - } - -out: - g_close(fd); - if (in_fd != -1) - close(in_fd); - if (buf) - free(buf); - - return (ret); -} - Property changes on: head/usr.sbin/nandtool/nand_write.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nand_info.c =================================================================== --- head/usr.sbin/nandtool/nand_info.c (revision 349351) +++ head/usr.sbin/nandtool/nand_info.c (nonexistent) @@ -1,88 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" - -int nand_info(struct cmd_param *params) -{ - struct chip_param_io chip_params; - int fd = -1, ret = 0; - int block_size; - off_t chip_size, media_size; - const char *dev; - - if ((dev = param_get_string(params, "dev")) == NULL) { - fprintf(stderr, "Please supply 'dev' parameter, eg. " - "'dev=/dev/gnand0'\n"); - return (1); - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - return (1); - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - if (ioctl(fd, DIOCGMEDIASIZE, &media_size) == -1) { - perrorf("Cannot ioctl(DIOCGMEDIASIZE)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - chip_size = block_size * chip_params.blocks; - - printf("Device:\t\t\t%s\n", dev); - printf("Page size:\t\t%d bytes\n", chip_params.page_size); - printf("Block size:\t\t%d bytes (%d KB)\n", block_size, - block_size / 1024); - printf("OOB size per page:\t%d bytes\n", chip_params.oob_size); - printf("Chip size:\t\t%jd MB\n", (uintmax_t)(chip_size / 1024 / 1024)); - printf("Slice size:\t\t%jd MB\n", - (uintmax_t)(media_size / 1024 / 1024)); - -out: - g_close(fd); - - return (ret); -} Property changes on: head/usr.sbin/nandtool/nand_info.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nand_read.c =================================================================== --- head/usr.sbin/nandtool/nand_read.c (revision 349351) +++ head/usr.sbin/nandtool/nand_read.c (nonexistent) @@ -1,141 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" - -int nand_read(struct cmd_param *params) -{ - struct chip_param_io chip_params; - int fd = -1, out_fd = -1, done = 0, ret = 0; - char *dev, *out; - int pos, count, mult, block_size; - uint8_t *buf = NULL; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "You must specify 'dev' parameter\n"); - return (1); - } - - if ((out = param_get_string(params, "out"))) { - out_fd = open(out, O_WRONLY|O_CREAT, 0666); - if (out_fd == -1) { - perrorf("Cannot open %s for writing", out); - return (1); - } - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - - if (param_has_value(params, "page")) { - pos = chip_params.page_size * param_get_int(params, "page"); - mult = chip_params.page_size; - } else if (param_has_value(params, "block")) { - pos = block_size * param_get_int(params, "block"); - mult = block_size; - } else if (param_has_value(params, "pos")) { - pos = param_get_int(params, "pos"); - mult = 1; - if (pos % chip_params.page_size) { - fprintf(stderr, "Position must be page-size aligned!\n"); - ret = 1; - goto out; - } - } else { - fprintf(stderr, "You must specify one of: 'block', 'page'," - "'pos' arguments\n"); - ret = 1; - goto out; - } - - if (!(param_has_value(params, "count"))) - count = mult; - else - count = param_get_int(params, "count") * mult; - - if (!(buf = malloc(chip_params.page_size))) { - perrorf("Cannot allocate buffer [size %x]", - chip_params.page_size); - ret = 1; - goto out; - } - - lseek(fd, pos, SEEK_SET); - - while (done < count) { - if ((ret = read(fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - perrorf("read error (read %d bytes)", ret); - goto out; - } - - if (out_fd != -1) { - done += ret; - if ((ret = write(out_fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - perrorf("write error (written %d bytes)", ret); - ret = 1; - goto out; - } - } else { - hexdumpoffset(buf, chip_params.page_size, done); - done += ret; - } - } - -out: - g_close(fd); - if (out_fd != -1) - close(out_fd); - if (buf) - free(buf); - - return (ret); -} - Property changes on: head/usr.sbin/nandtool/nand_read.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/nand_writeoob.c =================================================================== --- head/usr.sbin/nandtool/nand_writeoob.c (revision 349351) +++ head/usr.sbin/nandtool/nand_writeoob.c (nonexistent) @@ -1,115 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include "nandtool.h" - -int nand_write_oob(struct cmd_param *params) -{ - struct chip_param_io chip_params; - struct nand_oob_rw req; - char *dev, *in; - int fd = -1, fd_in = -1, ret = 0; - uint8_t *buf = NULL; - int page; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "Please supply valid 'dev' parameter.\n"); - return (1); - } - - if (!(in = param_get_string(params, "in"))) { - fprintf(stderr, "Please supply valid 'in' parameter.\n"); - return (1); - } - - if ((page = param_get_int(params, "page")) < 0) { - fprintf(stderr, "Please supply valid 'page' parameter.\n"); - return (1); - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - return (1); - } - - if ((fd_in = open(in, O_RDONLY)) == -1) { - perrorf("Cannot open %s", in); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - buf = malloc(chip_params.oob_size); - if (buf == NULL) { - perrorf("Cannot allocate %d bytes\n", chip_params.oob_size); - ret = 1; - goto out; - } - - if (read(fd_in, buf, chip_params.oob_size) == -1) { - perrorf("Cannot read from %s", in); - ret = 1; - goto out; - } - - req.page = page; - req.len = chip_params.oob_size; - req.data = buf; - - if (ioctl(fd, NAND_IO_OOB_PROG, &req) == -1) { - perrorf("Cannot write OOB to %s", dev); - ret = 1; - goto out; - } - -out: - g_close(fd); - if (fd_in != -1) - close(fd_in); - if (buf) - free(buf); - - return (ret); -} - - Property changes on: head/usr.sbin/nandtool/nand_writeoob.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: head/usr.sbin/nandtool/Makefile =================================================================== --- head/usr.sbin/nandtool/Makefile (revision 349351) +++ head/usr.sbin/nandtool/Makefile (nonexistent) @@ -1,10 +0,0 @@ -# $FreeBSD$ - -PROG= nandtool -SRCS= nandtool.c nand_read.c nand_write.c nand_erase.c nand_info.c -SRCS+= nand_readoob.c nand_writeoob.c -BINDIR= /usr/sbin -LIBADD= geom -MAN= nandtool.8 - -.include Property changes on: head/usr.sbin/nandtool/Makefile ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property